From 08c222e3fa2eecedb5a110aee92b0c532e2918ec Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 15 Aug 2025 22:56:42 +0100 Subject: [PATCH] x86/traps: Don't configure Supervisor Shadow Stack tokens in FRED mode FRED doesn't use Supervisor Shadow Stack tokens. This means that: 1) memguard_guard_stack() should not write Supervisor Shadow Stack Tokens. 2) cpu_has_bug_shstk_fracture is no longer relevant when deciding whether to enable Shadow Stacks or not. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich (cherry picked from commit 7634f5662551864a4976d5f0022263a056efd14d) --- xen/arch/x86/mm.c | 14 +++++++++++--- xen/arch/x86/setup.c | 16 ++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index b929d15d00..2b23bf2e7a 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -129,6 +129,7 @@ #include #include #include +#include #include #include @@ -6441,8 +6442,15 @@ static void write_sss_token(unsigned long *ptr) void memguard_guard_stack(void *p) { - /* IST Shadow stacks. 4x 1k in stack page 0. */ - if ( IS_ENABLED(CONFIG_XEN_SHSTK) ) + ASSERT(opt_fred >= 0); /* Confirm that FRED-ness has been resolved */ + + /* + * IST Shadow stacks. 4x 1k in stack page 0. + * + * With IDT delivery, we need Supervisor Shadow Stack tokens at the base + * of each stack. With FRED delivery, these no longer exist. + */ + if ( IS_ENABLED(CONFIG_XEN_SHSTK) && !opt_fred ) { write_sss_token(p + (IST_MCE * IST_SHSTK_SIZE) - 8); write_sss_token(p + (IST_NMI * IST_SHSTK_SIZE) - 8); @@ -6453,7 +6461,7 @@ void memguard_guard_stack(void *p) /* Primary Shadow Stack. 1x 4k in stack page 5. */ p += PRIMARY_SHSTK_SLOT * PAGE_SIZE; - if ( IS_ENABLED(CONFIG_XEN_SHSTK) ) + if ( IS_ENABLED(CONFIG_XEN_SHSTK) && !opt_fred ) write_sss_token(p + PAGE_SIZE - 8); map_pages_to_xen((unsigned long)p, virt_to_mfn(p), 1, PAGE_HYPERVISOR_SHSTK); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index c2827fec00..14c28ba8e7 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1412,15 +1412,19 @@ void asmlinkage __init noreturn __start_xen(void) boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && !boot_cpu_has(X86_FEATURE_CET_SSS); + ASSERT(opt_fred >= 0); /* Confirm that FRED-ness has been resolved */ + /* - * On bare metal, assume that Xen won't be impacted by shstk - * fracturing problems. Under virt, be more conservative and disable - * shstk by default. + * If FRED is in use, Supervisor Shadow Stack tokens are not used and + * shstk fracturing is of no consequence. Otherwise: + * - On bare metal, assume that Xen won't be impacted by shstk + * fracturing problems. + * - Under virt, be more conservative and disable shstk by default. */ if ( opt_xen_shstk == -1 ) opt_xen_shstk = - cpu_has_hypervisor ? !cpu_has_bug_shstk_fracture - : true; + opt_fred || (cpu_has_hypervisor ? !cpu_has_bug_shstk_fracture + : true); if ( opt_xen_shstk ) { @@ -1925,7 +1929,7 @@ void asmlinkage __init noreturn __start_xen(void) system_state = SYS_STATE_boot; - bsp_stack = cpu_alloc_stack(0); + bsp_stack = cpu_alloc_stack(0); /* Needs to know IDT vs FRED */ if ( !bsp_stack ) panic("No memory for BSP stack\n");