diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-10-12 04:00:49 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-10-12 04:00:49 +0000 |
| commit | c22f60e6e55f1bf300dd76d2222a93911f3b2bb2 (patch) | |
| tree | ef665e7018377f53612ac2751dcaea35a1c587b6 /5ece8ac4-x86-load_system_tables-NMI-MC-safe.patch | |
| parent | 39a4763249cd6289e5019acfe0c98dbb169f5f2e (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.patch | 91 |
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. */ + |
