[PATCH v4 06/14] x86/traps: Don't configure Supervisor Shadow Stack tokens in FRED mode

Andrew Cooper posted 14 patches 3 days, 4 hours ago
[PATCH v4 06/14] x86/traps: Don't configure Supervisor Shadow Stack tokens in FRED mode
Posted by Andrew Cooper 3 days, 4 hours ago
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 or
    not to enable Shadow Stacks in the first place.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>

v4:
 * Adjust for cpu_has_bug_shstk_fracture.
 * Reworked entirely in light of the prior 3 patches.

The SDM explicitly points out the shstk fracture vs FRED case, yet PTL
enumerates CET-SSS (immunity to shstk fracture).  I can only assume that there
are other Intel CPUs with FRED but without CET-SSS.
---
 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 0d0d5292953b..4c404b6c134f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -129,6 +129,7 @@
 #include <asm/shadow.h>
 #include <asm/shared.h>
 #include <asm/trampoline.h>
+#include <asm/traps.h>
 #include <asm/x86_emulate.h>
 
 #include <public/memory.h>
@@ -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 0816a713e1c8..8e59c9801afe 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");
 
-- 
2.39.5


Re: [PATCH v4 06/14] x86/traps: Don't configure Supervisor Shadow Stack tokens in FRED mode
Posted by Jan Beulich 12 hours ago
On 28.02.2026 00:16, Andrew Cooper wrote:
> 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 or
>     not to enable Shadow Stacks in the first place.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

> The SDM explicitly points out the shstk fracture vs FRED case, yet PTL
> enumerates CET-SSS (immunity to shstk fracture).  I can only assume that there
> are other Intel CPUs with FRED but without CET-SSS.

Isn't CET-SSS still relevant to OSes not using FRED (much like you do for
the fred=no case)?

Jan
Re: [PATCH v4 06/14] x86/traps: Don't configure Supervisor Shadow Stack tokens in FRED mode
Posted by Andrew Cooper 11 hours ago
On 02/03/2026 2:50 pm, Jan Beulich wrote:
> On 28.02.2026 00:16, Andrew Cooper wrote:
>> 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 or
>>     not to enable Shadow Stacks in the first place.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>

Thanks.

>> The SDM explicitly points out the shstk fracture vs FRED case, yet PTL
>> enumerates CET-SSS (immunity to shstk fracture).  I can only assume that there
>> are other Intel CPUs with FRED but without CET-SSS.
> Isn't CET-SSS still relevant to OSes not using FRED (much like you do for
> the fred=no case)?

Yes, CET-SSS is relevant outside of FRED mode.

I just don't see the point of the note if all FRED systems will
enumerate CET-SSS.

~Andrew