Message ID | 20200527191847.17207-14-andrew.cooper3@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86: Support for CET Supervisor Shadow Stacks | expand |
On 27.05.2020 21:18, Andrew Cooper wrote: > See code for details > > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> > --- > CC: Jan Beulich <JBeulich@suse.com> > CC: Wei Liu <wl@xen.org> > CC: Roger Pau Monné <roger.pau@citrix.com> > > Semi-RFC - I can't actually test this path. Currently attempting to arrange > for someone else to. Nevertheless Reviewed-by: Jan Beulich <jbeulich@suse.com> with one question, just for my understanding: > @@ -48,6 +58,51 @@ ENTRY(s3_resume) > pushq %rax > lretq > 1: > +#ifdef CONFIG_XEN_SHSTK > + /* > + * Restoring SSP is a little complicated, because we are intercepting > + * an in-use shadow stack. Write a temporary token under the stack, > + * so SETSSBSY will successfully load a value useful for us, then > + * reset MSR_PL0_SSP to its usual value and pop the temporary token. > + */ > + mov saved_rsp(%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 > + > + /* Load it into MSR_PL0_SSP. */ > + mov $MSR_PL0_SSP, %ecx > + mov %rdi, %rdx > + shr $32, %rdx > + 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 Does this imply NMI or #MC are fatal between here and there? Jan
On 29/05/2020 13:52, Jan Beulich wrote: > On 27.05.2020 21:18, Andrew Cooper wrote: >> See code for details >> >> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> >> --- >> CC: Jan Beulich <JBeulich@suse.com> >> CC: Wei Liu <wl@xen.org> >> CC: Roger Pau Monné <roger.pau@citrix.com> >> >> Semi-RFC - I can't actually test this path. Currently attempting to arrange >> for someone else to. > Nevertheless > Reviewed-by: Jan Beulich <jbeulich@suse.com> > with one question, just for my understanding: > >> @@ -48,6 +58,51 @@ ENTRY(s3_resume) >> pushq %rax >> lretq >> 1: >> +#ifdef CONFIG_XEN_SHSTK >> + /* >> + * Restoring SSP is a little complicated, because we are intercepting >> + * an in-use shadow stack. Write a temporary token under the stack, >> + * so SETSSBSY will successfully load a value useful for us, then >> + * reset MSR_PL0_SSP to its usual value and pop the temporary token. >> + */ >> + mov saved_rsp(%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 >> + >> + /* Load it into MSR_PL0_SSP. */ >> + mov $MSR_PL0_SSP, %ecx >> + mov %rdi, %rdx >> + shr $32, %rdx >> + 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 > Does this imply NMI or #MC are fatal between here and there? Yes, but that is always the case during CPU bringup. Only a few instructions ago, we didn't have an IDT, and we don't have yet have an established %tr, so can't get the regular IST pointer either. ~Andrew
diff --git a/xen/arch/x86/acpi/wakeup_prot.S b/xen/arch/x86/acpi/wakeup_prot.S index 4dba6020a7..dcc7e2327d 100644 --- a/xen/arch/x86/acpi/wakeup_prot.S +++ b/xen/arch/x86/acpi/wakeup_prot.S @@ -1,3 +1,7 @@ +#include <asm/msr-index.h> +#include <asm/page.h> +#include <asm/processor.h> + .file __FILE__ .text .code64 @@ -15,6 +19,12 @@ ENTRY(do_suspend_lowlevel) mov %cr0, %rax mov %rax, saved_cr0(%rip) +#ifdef CONFIG_XEN_SHSTK + mov $1, %eax + rdsspq %rax + mov %rax, saved_ssp(%rip) +#endif + /* enter sleep state physically */ mov $3, %edi call acpi_enter_sleep_state @@ -48,6 +58,51 @@ ENTRY(s3_resume) pushq %rax lretq 1: +#ifdef CONFIG_XEN_SHSTK + /* + * Restoring SSP is a little complicated, because we are intercepting + * an in-use shadow stack. Write a temporary token under the stack, + * so SETSSBSY will successfully load a value useful for us, then + * reset MSR_PL0_SSP to its usual value and pop the temporary token. + */ + mov saved_rsp(%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 + + /* Load it into MSR_PL0_SSP. */ + mov $MSR_PL0_SSP, %ecx + mov %rdi, %rdx + shr $32, %rdx + 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 + + /* Reset MSR_PL0_SSP back to its normal value. */ + and $~(STACK_SIZE - 1), %eax + or $(PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8, %eax + wrmsr + + /* Pop the temporary token off the stack. */ + mov $2, %eax + incsspd %eax +.L_shstk_done: +#endif call load_system_tables @@ -65,6 +120,9 @@ ENTRY(s3_resume) saved_rsp: .quad 0 saved_cr0: .quad 0 +#ifdef CONFIG_XEN_SHSTK +saved_ssp: .quad 0 +#endif GLOBAL(saved_magic) .long 0x9abcdef0 diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h index 85c5f20b76..cdfb7b047b 100644 --- a/xen/include/asm-x86/msr-index.h +++ b/xen/include/asm-x86/msr-index.h @@ -68,6 +68,9 @@ #define MSR_U_CET 0x000006a0 #define MSR_S_CET 0x000006a2 +#define CET_SHSTK_EN (_AC(1, ULL) << 0) +#define CET_WRSS_EN (_AC(1, ULL) << 1) + #define MSR_PL0_SSP 0x000006a4 #define MSR_PL1_SSP 0x000006a5 #define MSR_PL2_SSP 0x000006a6 diff --git a/xen/include/asm-x86/x86-defns.h b/xen/include/asm-x86/x86-defns.h index 5366e2d018..072c87042c 100644 --- a/xen/include/asm-x86/x86-defns.h +++ b/xen/include/asm-x86/x86-defns.h @@ -73,6 +73,7 @@ #define X86_CR4_SMEP 0x00100000 /* enable SMEP */ #define X86_CR4_SMAP 0x00200000 /* enable SMAP */ #define X86_CR4_PKE 0x00400000 /* enable PKE */ +#define X86_CR4_CET 0x00800000 /* Control-flow Enforcement Technology */ /* * XSTATE component flags in XCR0
See code for details Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> --- CC: Jan Beulich <JBeulich@suse.com> CC: Wei Liu <wl@xen.org> CC: Roger Pau Monné <roger.pau@citrix.com> Semi-RFC - I can't actually test this path. Currently attempting to arrange for someone else to. v2: * New, split out of "x86/shstk: Activate Supervisor Shadow Stacks" * Drop asm/config.h include * Fix order of operations to avoid multiple crashes. --- xen/arch/x86/acpi/wakeup_prot.S | 58 +++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/msr-index.h | 3 +++ xen/include/asm-x86/x86-defns.h | 1 + 3 files changed, 62 insertions(+)