Merge tag 'sunxi-fixes-for-4.3' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-drm-fsl-dcu.git] / arch / x86 / entry / entry_64.S
index d3033183ed7038ffae691c6784f10a994a0eb765..055a01de7c8da6e052cfdebe0be8447b14933c87 100644 (file)
@@ -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