[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 16/16] x86/shstk: Activate Supervisor Shadow Stacks
On 02.05.2020 00:58, Andrew Cooper wrote: > --- a/xen/arch/x86/acpi/wakeup_prot.S > +++ b/xen/arch/x86/acpi/wakeup_prot.S > @@ -1,3 +1,8 @@ > +#include <asm/config.h> Why is this needed? Afaics assembly files, just like C ones, get xen/config.h included from the compiler command line. > @@ -48,6 +59,48 @@ ENTRY(s3_resume) > pushq %rax > lretq > 1: > +#ifdef CONFIG_XEN_SHSTK > + /* > + * Restoring SSP is a little convoluted, because we are intercepting > + * the middle of an in-use shadow stack. Write a temporary > supervisor > + * token under the stack, so SETSSBSY takes us where we want, then > + * reset MSR_PL0_SSP to its usual value and pop the temporary token. What do you mean by "takes us where we want"? I take it "us" is really SSP here? > + */ > + mov saved_rsp(%rip), %rdi > + cmpq $1, %rdi > + je .L_shstk_done > + > + /* Write a supervisor token under SSP. */ > + sub $8, %rdi > + mov %rdi, (%rdi) > + > + /* Load it into MSR_PL0_SSP. */ > + mov $MSR_PL0_SSP, %ecx > + mov %rdi, %rdx > + shr $32, %rdx > + mov %edi, %eax > + > + /* Enable CET. */ > + mov $MSR_S_CET, %ecx > + xor %edx, %edx > + mov $CET_SHSTK_EN | CET_WRSS_EN, %eax > + wrmsr > + > + /* Activate our temporary token. */ > + mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ebx > + mov %rbx, %cr4 > + setssbsy > + > + /* Reset MSR_PL0_SSP back to its expected value. */ > + and $~(STACK_SIZE - 1), %eax > + or $0x5ff8, %eax > + wrmsr Ahead of this WRMSR neither %ecx nor %edx look to have their intended values anymore. Also there is a again a magic 0x5ff8 here (and at least one more further down). > --- a/xen/arch/x86/boot/x86_64.S > +++ b/xen/arch/x86/boot/x86_64.S > @@ -28,8 +28,36 @@ ENTRY(__high_start) > lretq > 1: > test %ebx,%ebx > - jnz start_secondary > + jz .L_bsp > > + /* APs. Set up shadow stacks before entering C. */ > + > + testl $cpufeat_mask(X86_FEATURE_XEN_SHSTK), \ > + CPUINFO_FEATURE_OFFSET(X86_FEATURE_XEN_SHSTK) + > boot_cpu_data(%rip) > + je .L_ap_shstk_done > + > + mov $MSR_S_CET, %ecx > + xor %edx, %edx > + mov $CET_SHSTK_EN | CET_WRSS_EN, %eax > + wrmsr > + > + mov $MSR_PL0_SSP, %ecx > + mov %rsp, %rdx > + shr $32, %rdx > + mov %esp, %eax > + and $~(STACK_SIZE - 1), %eax > + or $0x5ff8, %eax > + wrmsr > + > + mov $XEN_MINIMAL_CR4 | X86_CR4_CET, %ecx > + mov %rcx, %cr4 > + setssbsy Since the token doesn't get written here, could you make the comment say where this happens? I have to admit that I had to go through earlier patches to find it again. > +.L_ap_shstk_done: > + call start_secondary > + BUG /* start_secondary() shouldn't return. */ This conversion from a jump to CALL is unrelated and hence would better be mentioned in the description imo. > --- a/xen/arch/x86/cpu/common.c > +++ b/xen/arch/x86/cpu/common.c > @@ -323,6 +323,11 @@ void __init early_cpu_init(void) > x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86, > c->x86_model, c->x86_model, c->x86_mask, eax); > > + if (c->cpuid_level >= 7) { > + cpuid_count(7, 0, &eax, &ebx, &ecx, &edx); > + c->x86_capability[cpufeat_word(X86_FEATURE_CET_SS)] = ecx; > + } How about moving the leaf 7 code from generic_identify() here as a whole? > --- a/xen/arch/x86/setup.c > +++ b/xen/arch/x86/setup.c > @@ -664,6 +664,13 @@ static void __init noreturn reinit_bsp_stack(void) > stack_base[0] = stack; > memguard_guard_stack(stack); > > + if ( cpu_has_xen_shstk ) > + { > + wrmsrl(MSR_PL0_SSP, (unsigned long)stack + 0x5ff8); > + wrmsrl(MSR_S_CET, CET_SHSTK_EN | CET_WRSS_EN); > + asm volatile ("setssbsy" ::: "memory"); > + } Same as for APs - a brief comment pointing at where the token was written would seem helpful. Could you also have the patch description say a word on the choice of enabling CET_WRSS_EN uniformly and globally? > @@ -985,6 +992,21 @@ void __init noreturn __start_xen(unsigned long mbi_p) > /* This must come before e820 code because it sets paddr_bits. */ > early_cpu_init(); > > + /* Choose shadow stack early, to set infrastructure up appropriately. */ > + if ( opt_xen_shstk && boot_cpu_has(X86_FEATURE_CET_SS) ) > + { > + printk("Enabling Supervisor Shadow Stacks\n"); > + > + setup_force_cpu_cap(X86_FEATURE_XEN_SHSTK); > +#ifdef CONFIG_PV32 > + if ( opt_pv32 ) > + { > + opt_pv32 = 0; > + printk(" - Disabling PV32 due to Shadow Stacks\n"); > + } > +#endif I think this deserves an explanation, either in a comment or in the patch description. > @@ -1721,6 +1743,10 @@ void __init noreturn __start_xen(unsigned long mbi_p) > > alternative_branches(); > > + /* Defer CR4.CET until alternatives have finished playing with CR4.WP */ > + if ( cpu_has_xen_shstk ) > + set_in_cr4(X86_CR4_CET); Nit: CR0.WP (in the comment) Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |