summaryrefslogtreecommitdiff
path: root/5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-10-12 04:00:49 +0000
committerCoprDistGit <infra@openeuler.org>2023-10-12 04:00:49 +0000
commitc22f60e6e55f1bf300dd76d2222a93911f3b2bb2 (patch)
treeef665e7018377f53612ac2751dcaea35a1c587b6 /5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch
parent39a4763249cd6289e5019acfe0c98dbb169f5f2e (diff)
automatic import of xenopeneuler22.03_LTS
Diffstat (limited to '5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch')
-rw-r--r--5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch91
1 files changed, 91 insertions, 0 deletions
diff --git a/5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch b/5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch
new file mode 100644
index 0000000..c043307
--- /dev/null
+++ b/5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch
@@ -0,0 +1,91 @@
+# Commit 9f3e9139fa6c3d620eb08dff927518fc88200b8d
+# Date 2020-05-27 16:44:04 +0100
+# Author Andrew Cooper <andrew.cooper3@citrix.com>
+# Committer Andrew Cooper <andrew.cooper3@citrix.com>
+x86/boot: Fix load_system_tables() to be NMI/#MC-safe
+
+During boot, load_system_tables() is used in reinit_bsp_stack() to switch the
+virtual addresses used from their .data/.bss alias, to their directmap alias.
+
+The structure assignment is implemented as a memset() to zero first, then a
+copy-in of the new data. This causes the NMI/#MC stack pointers to
+transiently become 0, at a point where we may have an NMI watchdog running.
+
+Rewrite the logic using a volatile tss pointer (equivalent to, but more
+readable than, using ACCESS_ONCE() for all writes).
+
+This does drop the zeroing side effect for holes in the structure, but the
+backing memory for the TSS is fully zeroed anyway, and architecturally, they
+are all reserved.
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+
+--- a/xen/arch/x86/cpu/common.c
++++ b/xen/arch/x86/cpu/common.c
+@@ -729,11 +729,12 @@ static cpumask_t cpu_initialized;
+ */
+ void load_system_tables(void)
+ {
+- unsigned int cpu = smp_processor_id();
++ unsigned int i, cpu = smp_processor_id();
+ unsigned long stack_bottom = get_stack_bottom(),
+ stack_top = stack_bottom & ~(STACK_SIZE - 1);
+
+- struct tss64 *tss = &this_cpu(tss_page).tss;
++ /* The TSS may be live. Disuade any clever optimisations. */
++ volatile struct tss64 *tss = &this_cpu(tss_page).tss;
+ seg_desc_t *gdt =
+ this_cpu(gdt) - FIRST_RESERVED_GDT_ENTRY;
+ seg_desc_t *compat_gdt =
+@@ -748,30 +749,26 @@ void load_system_tables(void)
+ .limit = (IDT_ENTRIES * sizeof(idt_entry_t)) - 1,
+ };
+
+- *tss = (struct tss64){
+- /* Main stack for interrupts/exceptions. */
+- .rsp0 = stack_bottom,
+-
+- /* Ring 1 and 2 stacks poisoned. */
+- .rsp1 = 0x8600111111111111ul,
+- .rsp2 = 0x8600111111111111ul,
+-
+- /*
+- * MCE, NMI and Double Fault handlers get their own stacks.
+- * All others poisoned.
+- */
+- .ist = {
+- [IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE,
+- [IST_DF - 1] = stack_top + IST_DF * PAGE_SIZE,
+- [IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE,
+- [IST_DB - 1] = stack_top + IST_DB * PAGE_SIZE,
+-
+- [IST_MAX ... ARRAY_SIZE(tss->ist) - 1] =
+- 0x8600111111111111ul,
+- },
+-
+- .bitmap = IOBMP_INVALID_OFFSET,
+- };
++ /*
++ * Set up the TSS. Warning - may be live, and the NMI/#MC must remain
++ * valid on every instruction boundary. (Note: these are all
++ * semantically ACCESS_ONCE() due to tss's volatile qualifier.)
++ *
++ * rsp0 refers to the primary stack. #MC, #DF, NMI and #DB handlers
++ * each get their own stacks. No IO Bitmap.
++ */
++ tss->rsp0 = stack_bottom;
++ tss->ist[IST_MCE - 1] = stack_top + IST_MCE * PAGE_SIZE;
++ tss->ist[IST_DF - 1] = stack_top + IST_DF * PAGE_SIZE;
++ tss->ist[IST_NMI - 1] = stack_top + IST_NMI * PAGE_SIZE;
++ tss->ist[IST_DB - 1] = stack_top + IST_DB * PAGE_SIZE;
++ tss->bitmap = IOBMP_INVALID_OFFSET;
++
++ /* All other stack pointers poisioned. */
++ for ( i = IST_MAX; i < ARRAY_SIZE(tss->ist); ++i )
++ tss->ist[i] = 0x8600111111111111ul;
++ tss->rsp1 = 0x8600111111111111ul;
++ tss->rsp2 = 0x8600111111111111ul;
+
+ BUILD_BUG_ON(sizeof(*tss) <= 0x67); /* Mandated by the architecture. */
+