FRED and IDT differ by a Supervisor Token on the base of the shstk. This
means that the value they load into MSR_PL0_SSP differs by 8.
s3_resume() in particular has logic which is otherwise invariant of FRED mode,
and must not clobber a FRED MSR_PL0_SSP with an IDT one.
This also simplifies the AP path too. Updating reinit_bsp_stack() is deferred
until later.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
v2:
* Extend comment about clearing the busy bit.
* Move reinit_bsp_stack() hunk into this patch.
---
xen/arch/x86/acpi/wakeup_prot.S | 9 ---------
xen/arch/x86/boot/x86_64.S | 12 +++---------
xen/arch/x86/setup.c | 2 --
xen/arch/x86/traps-setup.c | 2 ++
4 files changed, 5 insertions(+), 20 deletions(-)
diff --git a/xen/arch/x86/acpi/wakeup_prot.S b/xen/arch/x86/acpi/wakeup_prot.S
index fceb4ca353f7..ba0bd77806b8 100644
--- a/xen/arch/x86/acpi/wakeup_prot.S
+++ b/xen/arch/x86/acpi/wakeup_prot.S
@@ -104,15 +104,6 @@ LABEL(s3_resume)
*/
mov saved_ssp(%rip), %rdi
- /* Calculate MSR_PL0_SSP from SSP. */
- mov $MSR_PL0_SSP, %ecx
- mov %rdi, %rdx
- shr $32, %rdx
- mov %edi, %eax
- and $~(STACK_SIZE - 1), %eax
- or $(PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8, %eax
- wrmsr
-
/*
* A Restore Token's value is &token + 8 + 64BIT (bit 0).
* We want to put this on the shstk at SSP - 8.
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 3a5ad2764448..11a7e9d3bd23 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -65,17 +65,11 @@ ENTRY(__high_start)
or $(PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8, %rdx
/*
- * Write a new supervisor token. Doesn't matter on boot, but for S3
- * resume this clears the busy bit.
+ * Write a new Supervisor Token. It doesn't matter the first time a
+ * CPU boots, but for S3 resume or hotplug this clears the busy bit so
+ * SETSSBSY can set it again.
*/
wrssq %rdx, (%rdx)
-
- /* Point MSR_PL0_SSP at the token. */
- mov $MSR_PL0_SSP, %ecx
- mov %edx, %eax
- shr $32, %rdx
- wrmsr
-
setssbsy
#endif /* CONFIG_XEN_SHSTK */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 6c81841426a4..a810bdf6d352 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -907,8 +907,6 @@ static void __init noreturn reinit_bsp_stack(void)
if ( cpu_has_xen_shstk )
{
- wrmsrl(MSR_PL0_SSP,
- (unsigned long)stack + (PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8);
wrmsrl(MSR_S_CET, xen_msr_s_cet_value());
asm volatile ("setssbsy" ::: "memory");
}
diff --git a/xen/arch/x86/traps-setup.c b/xen/arch/x86/traps-setup.c
index 6e2af58ba0a5..d77be8f83921 100644
--- a/xen/arch/x86/traps-setup.c
+++ b/xen/arch/x86/traps-setup.c
@@ -92,6 +92,7 @@ static void load_system_tables(void)
{
volatile uint64_t *ist_ssp = tss_page->ist_ssp;
unsigned long
+ ssp = stack_top + (PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8,
mce_ssp = stack_top + (IST_MCE * IST_SHSTK_SIZE) - 8,
nmi_ssp = stack_top + (IST_NMI * IST_SHSTK_SIZE) - 8,
db_ssp = stack_top + (IST_DB * IST_SHSTK_SIZE) - 8,
@@ -118,6 +119,7 @@ static void load_system_tables(void)
}
wrmsrns(MSR_ISST, (unsigned long)ist_ssp);
+ wrmsrns(MSR_PL0_SSP, (unsigned long)ssp);
}
_set_tssldt_desc(gdt + TSS_ENTRY, (unsigned long)tss,
--
2.39.5