|
@@ -1128,7 +1128,18 @@ END(error_exit)
|
|
|
|
|
|
/* Runs on exception stack */
|
|
|
ENTRY(nmi)
|
|
|
+ /*
|
|
|
+ * Fix up the exception frame if we're on Xen.
|
|
|
+ * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most
|
|
|
+ * one value to the stack on native, so it may clobber the rdx
|
|
|
+ * scratch slot, but it won't clobber any of the important
|
|
|
+ * slots past it.
|
|
|
+ *
|
|
|
+ * Xen is a different story, because the Xen frame itself overlaps
|
|
|
+ * the "NMI executing" variable.
|
|
|
+ */
|
|
|
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
|
|
+
|
|
|
/*
|
|
|
* We allow breakpoints in NMIs. If a breakpoint occurs, then
|
|
|
* the iretq it performs will take us out of NMI context.
|
|
@@ -1179,9 +1190,12 @@ ENTRY(nmi)
|
|
|
* we don't want to enable interrupts, because then we'll end
|
|
|
* up in an awkward situation in which IRQs are on but NMIs
|
|
|
* are off.
|
|
|
+ *
|
|
|
+ * We also must not push anything to the stack before switching
|
|
|
+ * stacks lest we corrupt the "NMI executing" variable.
|
|
|
*/
|
|
|
|
|
|
- SWAPGS
|
|
|
+ SWAPGS_UNSAFE_STACK
|
|
|
cld
|
|
|
movq %rsp, %rdx
|
|
|
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|