lkml.org 
[lkml]   [2022]   [Mar]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: [PATCH v4 24/45] x86/ibt: Add IBT feature, MSR and #CP handling
Date
On 08/03/2022 15:30, Peter Zijlstra wrote:
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -592,6 +594,24 @@ static __init int setup_disable_pku(char
> __setup("nopku", setup_disable_pku);
> #endif /* CONFIG_X86_64 */
>
> +static __always_inline void setup_cet(struct cpuinfo_x86 *c)
> +{
> + u64 msr = CET_ENDBR_EN;
> +
> + if (!HAS_KERNEL_IBT ||
> + !cpu_feature_enabled(X86_FEATURE_IBT))
> + return;
> +
> + wrmsrl(MSR_IA32_S_CET, msr);
> + cr4_set_bits(X86_CR4_CET);
> +
> + if (!ibt_selftest()) {
> + pr_err("IBT selftest: Failed!\n");
> + setup_clear_cpu_cap(X86_FEATURE_IBT);

This path wants to clear CR4.CET or MSR_S_CET, or both.

> + return;
> + }
> +}
> +
> /*
> * Some CPU features depend on higher CPUID levels, which may not always
> * be available due to CPUID level capping or broken virtualization
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -210,6 +210,80 @@ DEFINE_IDTENTRY(exc_overflow)
> do_error_trap(regs, 0, "overflow", X86_TRAP_OF, SIGSEGV, 0, NULL);
> }
>
> +#ifdef CONFIG_X86_KERNEL_IBT
> +
> +static __ro_after_init bool ibt_fatal = true;
> +
> +void ibt_selftest_ip(void); /* code label defined in asm below */
> +
> +enum cp_error_code {
> + CP_EC = (1 << 15) - 1,
> +
> + CP_RET = 1,
> + CP_IRET = 2,
> + CP_ENDBR = 3,
> + CP_RSTRORSSP = 4,
> + CP_SETSSBSY = 5,
> +
> + CP_ENCL = 1 << 15,
> +};
> +
> +DEFINE_IDTENTRY_ERRORCODE(exc_control_protection)
> +{
> + if (!cpu_feature_enabled(X86_FEATURE_IBT)) {
> + pr_err("Unexpected #CP\n");
> + BUG();
> + }
> +
> + if (WARN_ON_ONCE(user_mode(regs) || (error_code & CP_EC) != CP_ENDBR))
> + return;

Is this wise?  #CP is a fault, so this will livelock.

user_mode() wants to turn into an oops.  Kernel probably wants to fold
into the Unexpected #CP path, but definitely print the error code.

~Andrew

> +
> + if (unlikely(regs->ip == (unsigned long)ibt_selftest_ip)) {
> + regs->ax = 0;
> + return;
> + }
> +
> + pr_err("Missing ENDBR: %pS\n", (void *)instruction_pointer(regs));
> + if (!ibt_fatal) {
> + printk(KERN_DEFAULT CUT_HERE);
> + __warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL);
> + return;
> + }
> + BUG();
> +}
> +
> +bool ibt_selftest(void)
> +{
> + unsigned long ret;
> +
> + asm (" lea ibt_selftest_ip(%%rip), %%rax\n\t"
> + ANNOTATE_RETPOLINE_SAFE
> + " jmp *%%rax\n\t"
> + "ibt_selftest_ip:\n\t"
> + UNWIND_HINT_FUNC
> + ANNOTATE_NOENDBR
> + " nop\n\t"
> +
> + : "=a" (ret) : : "memory");
> +
> + return !ret;
> +}
> +
> +static int __init ibt_setup(char *str)
> +{
> + if (!strcmp(str, "off"))
> + setup_clear_cpu_cap(X86_FEATURE_IBT);
> +
> + if (!strcmp(str, "warn"))
> + ibt_fatal = false;
> +
> + return 1;
> +}
> +
> +__setup("ibt=", ibt_setup);
> +
> +#endif /* CONFIG_X86_KERNEL_IBT */
> +
> #ifdef CONFIG_X86_F00F_BUG
> void handle_invalid_op(struct pt_regs *regs)
> #else
>
>

\
 
 \ /
  Last update: 2022-03-09 14:58    [W:0.570 / U:1.588 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site