x86/setup: Rework MSR_S_CET handling for CET-IBT

CET-SS and CET-IBT can be independently controlled, so the configuration of
MSR_S_CET can't be constant any more.

Introduce xen_msr_s_cet_value(), mostly because I don't fancy
writing/maintaining that logic in assembly.  Use this in the 3 paths which
alter MSR_S_CET when both features are potentially active.

To active CET-IBT, we only need CR4.CET and MSR_S_CET.ENDBR_EN.  This is
common with the CET-SS setup, so reorder the operations to set up CR4 and
MSR_S_CET for any nonzero result from xen_msr_s_cet_value(), and set up
MSR_PL0_SSP and SSP if SHSTK_EN was also set.

Adjust the crash path to disable CET-IBT too.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2022-02-23 15:33:43 +00:00
1 parent e702e36d1d
commit 311434bfc9
5 files changed
+61 -29

No files matched your search

+23 -15
View File
@@ -63,7 +63,26 @@ ENTRY(s3_resume)
pushq %rax
lretq
1:
#ifdef CONFIG_XEN_SHSTK
#if defined(CONFIG_XEN_SHSTK) || defined(CONFIG_XEN_IBT)
call xen_msr_s_cet_value
test %eax, %eax
jz .L_cet_done
/* Set up MSR_S_CET. */
mov $MSR_S_CET, %ecx
xor %edx, %edx
wrmsr
/* Enable CR4.CET. */
mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ecx
mov %rcx, %cr4
/* WARNING! call/ret now fatal (iff SHSTK) until SETSSBSY loads SSP */
#if defined(CONFIG_XEN_SHSTK)
test $CET_SHSTK_EN, %al
jz .L_cet_done
/*
* Restoring SSP is a little complicated, because we are intercepting
* an in-use shadow stack. Write a temporary token under the stack,
@@ -71,14 +90,6 @@ ENTRY(s3_resume)
* reset MSR_PL0_SSP to its usual value and pop the temporary token.
*/
mov saved_ssp(%rip), %rdi
cmpq $1, %rdi
je .L_shstk_done
/* Set up MSR_S_CET. */
mov $MSR_S_CET, %ecx
xor %edx, %edx
mov $CET_SHSTK_EN | CET_WRSS_EN, %eax
wrmsr
/* Construct the temporary supervisor token under SSP. */
sub $8, %rdi
@@ -90,10 +101,6 @@ ENTRY(s3_resume)
mov %edi, %eax
wrmsr
/* Enable CET. MSR_INTERRUPT_SSP_TABLE is set up later in load_system_tables(). */
mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ebx
mov %rbx, %cr4
/* Write the temporary token onto the shadow stack, and activate it. */
wrssq %rdi, (%rdi)
setssbsy
@@ -106,8 +113,9 @@ ENTRY(s3_resume)
/* Pop the temporary token off the stack. */
mov $2, %eax
incsspd %eax
.L_shstk_done:
#endif
#endif /* CONFIG_XEN_SHSTK */
.L_cet_done:
#endif /* CONFIG_XEN_SHSTK || CONFIG_XEN_IBT */
call load_system_tables
+19 -11
View File
@@ -30,18 +30,27 @@ ENTRY(__high_start)
test %ebx,%ebx
jz .L_bsp
/* APs. Set up shadow stacks before entering C. */
#ifdef CONFIG_XEN_SHSTK
testl $cpufeat_mask(X86_FEATURE_XEN_SHSTK), \
CPUINFO_FEATURE_OFFSET(X86_FEATURE_XEN_SHSTK) + boot_cpu_data(%rip)
je .L_ap_shstk_done
/* APs. Set up CET before entering C properly. */
#if defined(CONFIG_XEN_SHSTK) || defined(CONFIG_XEN_IBT)
call xen_msr_s_cet_value
test %eax, %eax
jz .L_ap_cet_done
/* Set up MSR_S_CET. */
mov $MSR_S_CET, %ecx
xor %edx, %edx
mov $CET_SHSTK_EN | CET_WRSS_EN, %eax
wrmsr
/* Enable CR4.CET. */
mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ecx
mov %rcx, %cr4
/* WARNING! call/ret now fatal (iff SHSTK) until SETSSBSY loads SSP */
#if defined(CONFIG_XEN_SHSTK)
test $CET_SHSTK_EN, %al
jz .L_ap_cet_done
/* Derive MSR_PL0_SSP from %rsp (token written when stack is allocated). */
mov $MSR_PL0_SSP, %ecx
mov %rsp, %rdx
@@ -51,13 +60,12 @@ ENTRY(__high_start)
or $(PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8, %eax
wrmsr
/* Enable CET. MSR_INTERRUPT_SSP_TABLE is set up later in load_system_tables(). */
mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ecx
mov %rcx, %cr4
setssbsy
#endif
.L_ap_shstk_done:
#endif /* CONFIG_XEN_SHSTK */
.L_ap_cet_done:
#endif /* CONFIG_XEN_SHSTK || CONFIG_XEN_IBT */
call start_secondary
BUG /* start_secondary() shouldn't return. */
+2 -2
View File
@@ -190,8 +190,8 @@ void machine_crash_shutdown(void)
/* Reset CPUID masking and faulting to the host's default. */
ctxt_switch_levelling(NULL);
/* Disable shadow stacks. */
if ( cpu_has_xen_shstk )
/* Disable CET. */
if ( cpu_has_xen_shstk || cpu_has_xen_ibt )
{
wrmsrl(MSR_S_CET, 0);
write_cr4(read_cr4() & ~X86_CR4_CET);
+1
View File
@@ -117,6 +117,7 @@
#define MSR_S_CET 0x000006a2
#define CET_SHSTK_EN (_AC(1, ULL) << 0)
#define CET_WRSS_EN (_AC(1, ULL) << 1)
#define CET_ENDBR_EN (_AC(1, ULL) << 2)
#define MSR_PL0_SSP 0x000006a4
#define MSR_PL1_SSP 0x000006a5
+16 -1
View File
@@ -670,6 +670,21 @@ static void noreturn init_done(void)
startup_cpu_idle_loop();
}
#if defined(CONFIG_XEN_SHSTK) || defined(CONFIG_XEN_IBT)
/*
* Used by AP and S3 asm code to calcualte the appropriate MSR_S_CET setting.
* Do not use on the BSP before reinit_bsp_stack(), or it may turn SHSTK on
* too early.
*/
unsigned int xen_msr_s_cet_value(void)
{
return ((cpu_has_xen_shstk ? CET_SHSTK_EN | CET_WRSS_EN : 0) |
(cpu_has_xen_ibt ? CET_ENDBR_EN : 0));
}
#else
unsigned int xen_msr_s_cet_value(void); /* To avoid ifdefary */
#endif
/* Reinitalise all state referring to the old virtual address of the stack. */
static void __init noreturn reinit_bsp_stack(void)
{
@@ -693,7 +708,7 @@ static void __init noreturn reinit_bsp_stack(void)
{
wrmsrl(MSR_PL0_SSP,
(unsigned long)stack + (PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8);
wrmsrl(MSR_S_CET, CET_SHSTK_EN | CET_WRSS_EN);
wrmsrl(MSR_S_CET, xen_msr_s_cet_value());
asm volatile ("setssbsy" ::: "memory");
}
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.