Skip to content

Commit

Permalink
x86/S3: Save and restore Shadow Stack configuration
Browse files Browse the repository at this point in the history
See code for details.

Signed-off-by: Andrew Cooper <[email protected]>
Reviewed-by: Jan Beulich <[email protected]>
  • Loading branch information
andyhhp committed May 29, 2020
1 parent 43b98e7 commit 633ecc4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
58 changes: 58 additions & 0 deletions xen/arch/x86/acpi/wakeup_prot.S
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#include <asm/msr-index.h>
#include <asm/page.h>
#include <asm/processor.h>

.file __FILE__
.text
.code64
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
3 changes: 3 additions & 0 deletions xen/include/asm-x86/msr-index.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions xen/include/asm-x86/x86-defns.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 633ecc4

Please sign in to comment.