+#include <asm/msr-index.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
.file __FILE__
.text
.code64
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
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
saved_rsp: .quad 0
saved_cr0: .quad 0
+#ifdef CONFIG_XEN_SHSTK
+saved_ssp: .quad 0
+#endif
GLOBAL(saved_magic)
.long 0x9abcdef0
#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
#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