Skip to content

Commit 0dc2a76

Browse files
rpedgecohansendc
authored andcommitted
x86/cpufeatures: Enable CET CR4 bit for shadow stack
Setting CR4.CET is a prerequisite for utilizing any CET features, most of which also require setting MSRs. Kernel IBT already enables the CET CR4 bit when it detects IBT HW support and is configured with kernel IBT. However, future patches that enable userspace shadow stack support will need the bit set as well. So change the logic to enable it in either case. Clear MSR_IA32_U_CET in cet_disable() so that it can't live to see userspace in a new kexec-ed kernel that has CR4.CET set from kernel IBT. Co-developed-by: Yu-cheng Yu <[email protected]> Signed-off-by: Yu-cheng Yu <[email protected]> Signed-off-by: Rick Edgecombe <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Kees Cook <[email protected]> Acked-by: Mike Rapoport (IBM) <[email protected]> Tested-by: Pengfei Xu <[email protected]> Tested-by: John Allen <[email protected]> Tested-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/all/20230613001108.3040476-39-rick.p.edgecombe%40intel.com
1 parent 488af8e commit 0dc2a76

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

arch/x86/kernel/cpu/common.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -588,27 +588,43 @@ __noendbr void ibt_restore(u64 save)
588588

589589
static __always_inline void setup_cet(struct cpuinfo_x86 *c)
590590
{
591-
u64 msr = CET_ENDBR_EN;
591+
bool user_shstk, kernel_ibt;
592592

593-
if (!HAS_KERNEL_IBT ||
594-
!cpu_feature_enabled(X86_FEATURE_IBT))
593+
if (!IS_ENABLED(CONFIG_X86_CET))
595594
return;
596595

597-
wrmsrl(MSR_IA32_S_CET, msr);
596+
kernel_ibt = HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT);
597+
user_shstk = cpu_feature_enabled(X86_FEATURE_SHSTK) &&
598+
IS_ENABLED(CONFIG_X86_USER_SHADOW_STACK);
599+
600+
if (!kernel_ibt && !user_shstk)
601+
return;
602+
603+
if (user_shstk)
604+
set_cpu_cap(c, X86_FEATURE_USER_SHSTK);
605+
606+
if (kernel_ibt)
607+
wrmsrl(MSR_IA32_S_CET, CET_ENDBR_EN);
608+
else
609+
wrmsrl(MSR_IA32_S_CET, 0);
610+
598611
cr4_set_bits(X86_CR4_CET);
599612

600-
if (!ibt_selftest()) {
613+
if (kernel_ibt && !ibt_selftest()) {
601614
pr_err("IBT selftest: Failed!\n");
602615
wrmsrl(MSR_IA32_S_CET, 0);
603616
setup_clear_cpu_cap(X86_FEATURE_IBT);
604-
return;
605617
}
606618
}
607619

608620
__noendbr void cet_disable(void)
609621
{
610-
if (cpu_feature_enabled(X86_FEATURE_IBT))
611-
wrmsrl(MSR_IA32_S_CET, 0);
622+
if (!(cpu_feature_enabled(X86_FEATURE_IBT) ||
623+
cpu_feature_enabled(X86_FEATURE_SHSTK)))
624+
return;
625+
626+
wrmsrl(MSR_IA32_S_CET, 0);
627+
wrmsrl(MSR_IA32_U_CET, 0);
612628
}
613629

614630
/*
@@ -1470,6 +1486,9 @@ static void __init cpu_parse_early_param(void)
14701486
if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
14711487
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
14721488

1489+
if (cmdline_find_option_bool(boot_command_line, "nousershstk"))
1490+
setup_clear_cpu_cap(X86_FEATURE_USER_SHSTK);
1491+
14731492
arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
14741493
if (arglen <= 0)
14751494
return;

0 commit comments

Comments
 (0)