x86/boot: Use RSTORSSP to establish SSP

Under FRED, SETSSBSY is disallowed, and we want to be setting up FRED prior to
setting up shadow stacks.  As we still need Supervisor Tokens in IDT mode, we
need mode-specific logic to establish SSP.

In FRED mode, write a Restore Token, RSTORSSP it, and discard the resulting
Previous-SSP token.

No change outside of FRED mode.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2025-12-05 23:00:32 +00:00
1 parent 42a0709f37
commit 3037d8b7eb
2 files changed
+45 -3

No files matched your search

+21 -2
View File
@@ -53,17 +53,21 @@ ENTRY(__high_start)
mov %rcx, STACK_CPUINFO_FIELD(cr4)(%r15)
mov %rcx, %cr4
/* WARNING! call/ret now fatal (iff SHSTK) until SETSSBSY loads SSP */
/* WARNING! CALL/RET now fatal (iff SHSTK) until SETSSBSY/RSTORSSP loads SSP */
#if defined(CONFIG_XEN_SHSTK)
test $CET_SHSTK_EN, %al
jz .L_ap_cet_done
/* Derive the supervisor token address from %rsp. */
/* Derive the token address from %rsp. */
mov %rsp, %rdx
and $~(STACK_SIZE - 1), %rdx
or $(PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8, %rdx
/* Establishing SSP differs between IDT or FRED mode. */
bt $32 /* ilog2(X86_CR4_FRED) */, %rcx
jc .L_fred_shstk
/*
* Write a new Supervisor Token. It doesn't matter the first time a
* CPU boots, but for S3 resume or hotplug this clears the busy bit so
@@ -71,6 +75,21 @@ ENTRY(__high_start)
*/
wrssq %rdx, (%rdx)
setssbsy
jmp .L_ap_cet_done
.L_fred_shstk:
/*
* Write a Restore Token, value: &token + 8 + 64BIT (bit 0) at the
* base of the shstk (which isn't in use yet).
*/
lea 9(%rdx), %rdi
wrssq %rdi, (%rdx)
rstorssp (%rdx)
/* Discard the Previous-SSP Token from the shstk. */
mov $2, %edx
incsspd %edx
#endif /* CONFIG_XEN_SHSTK */
.L_ap_cet_done:
+24 -1
View File
@@ -49,6 +49,7 @@
#include <asm/prot-key.h>
#include <asm/pv/domain.h>
#include <asm/setup.h>
#include <asm/shstk.h>
#include <asm/smp.h>
#include <asm/spec_ctrl.h>
#include <asm/stubs.h>
@@ -908,7 +909,29 @@ static void __init noreturn reinit_bsp_stack(void)
if ( cpu_has_xen_shstk )
{
wrmsrl(MSR_S_CET, xen_msr_s_cet_value());
asm volatile ("setssbsy" ::: "memory");
/*
* IDT and FRED differ by a Supervisor Token on the shadow stack.
*
* In IDT mode, we use SETSSBSY (itself using MSR_PL0_SSP, configured
* previously) to mark the Supervisor Token as Busy. In FRED mode,
* there is no token, so we need to create a temporary Restore Token
* to establish SSP.
*/
if ( opt_fred )
{
unsigned long *token =
(void *)stack + (PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8;
wrss((unsigned long)token + 9, token);
asm volatile ( "rstorssp %0" : "+m" (*token) );
/*
* We need to discard the resulting Previous-SSP Token, but
* reset_stack_and_jump() will do that for us.
*/
}
else
asm volatile ( "setssbsy" ::: "memory" );
}
reset_stack_and_jump(init_done);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.