25242-x86_64-hotplug-compat-m2p.patch 25247-SVM-no-rdtsc-intercept.patch 25267-x86-text-unlikely.patch 25269-x86-vMCE-addr-misc-write.patch 25271-x86_64-IST-index.patch 25327-pvdrv-no-asm-system-h.patch - Upstream patches from Jan 25168-x86-memset-size.patch 25191-x86-tdt-delta-calculation.patch 25195-x86-cpuidle-C2-no-flush-or-bm-check.patch 25196-x86-HAP-PAT-sr.patch 25200-x86_64-trap-bounce-flags.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=189
58 lines
2.5 KiB
Diff
58 lines
2.5 KiB
Diff
# HG changeset patch
|
|
# User Andrew Cooper <andrew.cooper3@citrix.com>
|
|
# Date 1336644272 -3600
|
|
# Node ID 54da0329e259c11b63afe3312c9fa6cc1cb7cc9d
|
|
# Parent b059c62449fb490074d85c00aa03c38fb34a0e80
|
|
x86_64: Fix off-by-one error setting up the Interrupt Stack Tables
|
|
|
|
The Interrupt Stack Table entries in a 64bit TSS are a 1 based data
|
|
structure as far as hardware is concerned. As a result, the code
|
|
setting up stacks in subarch_percpu_traps_init() fills in the wrong
|
|
IST entries.
|
|
|
|
The result is that the MCE handler executes on the stack set up for
|
|
NMIs; the NMI handler executes on a stack set up for Double Faults,
|
|
and Double Faults are executed with a stack pointer set to 0.
|
|
|
|
Once the #DF handler starts to execute, it will usually take a page
|
|
fault looking up the address at 0xfffffffffffffff8, which will cause a
|
|
triple fault. If a guest has mapped a page in that location, then it
|
|
will have some state overwritten, but as the #DF handler always calls
|
|
panic(), this is not a problem the guest will have time to care about.
|
|
|
|
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
Committed-by: Keir Fraser <keir@xen.org>
|
|
|
|
--- a/xen/arch/x86/x86_64/traps.c
|
|
+++ b/xen/arch/x86/x86_64/traps.c
|
|
@@ -389,13 +389,13 @@ void __devinit subarch_percpu_traps_init
|
|
BUILD_BUG_ON((IST_MAX + 2) * PAGE_SIZE + PRIMARY_STACK_SIZE > STACK_SIZE);
|
|
|
|
/* Machine Check handler has its own per-CPU 4kB stack. */
|
|
- this_cpu(init_tss).ist[IST_MCE] = (unsigned long)&stack[IST_MCE * PAGE_SIZE];
|
|
+ this_cpu(init_tss).ist[IST_MCE-1] = (unsigned long)&stack[IST_MCE * PAGE_SIZE];
|
|
|
|
/* Double-fault handler has its own per-CPU 4kB stack. */
|
|
- this_cpu(init_tss).ist[IST_DF] = (unsigned long)&stack[IST_DF * PAGE_SIZE];
|
|
+ this_cpu(init_tss).ist[IST_DF-1] = (unsigned long)&stack[IST_DF * PAGE_SIZE];
|
|
|
|
/* NMI handler has its own per-CPU 4kB stack. */
|
|
- this_cpu(init_tss).ist[IST_NMI] = (unsigned long)&stack[IST_NMI * PAGE_SIZE];
|
|
+ this_cpu(init_tss).ist[IST_NMI-1] = (unsigned long)&stack[IST_NMI * PAGE_SIZE];
|
|
|
|
/* Trampoline for SYSCALL entry from long mode. */
|
|
stack = &stack[IST_MAX * PAGE_SIZE]; /* Skip the IST stacks. */
|
|
--- a/xen/include/asm-x86/processor.h
|
|
+++ b/xen/include/asm-x86/processor.h
|
|
@@ -427,7 +427,9 @@ struct tss_struct {
|
|
union { u64 rsp1, esp1; };
|
|
union { u64 rsp2, esp2; };
|
|
u64 reserved1;
|
|
- u64 ist[7];
|
|
+ u64 ist[7]; /* Interrupt Stack Table is 1-based so tss->ist[0]
|
|
+ * corresponds to an IST value of 1 in an Interrupt
|
|
+ * Descriptor */
|
|
u64 reserved2;
|
|
u16 reserved3;
|
|
#else
|