x86: Don't clobber top of pt_regs in nested NMI
[deliverable/linux.git] / arch / x86 / kernel / entry_64.S
index b51b2c7ee51fcbc3738ed8bd05fb4fd67d9fe1ab..811795db4fc621851a6319e3155d6b136903db23 100644 (file)
@@ -1699,9 +1699,10 @@ nested_nmi:
 
 1:
        /* Set up the interrupted NMIs stack to jump to repeat_nmi */
-       leaq -6*8(%rsp), %rdx
+       leaq -1*8(%rsp), %rdx
        movq %rdx, %rsp
-       CFI_ADJUST_CFA_OFFSET 6*8
+       CFI_ADJUST_CFA_OFFSET 1*8
+       leaq -10*8(%rsp), %rdx
        pushq_cfi $__KERNEL_DS
        pushq_cfi %rdx
        pushfq_cfi
@@ -1709,8 +1710,8 @@ nested_nmi:
        pushq_cfi $repeat_nmi
 
        /* Put stack back */
-       addq $(11*8), %rsp
-       CFI_ADJUST_CFA_OFFSET -11*8
+       addq $(6*8), %rsp
+       CFI_ADJUST_CFA_OFFSET -6*8
 
 nested_nmi_out:
        popq_cfi %rdx
@@ -1736,18 +1737,18 @@ first_nmi:
         * +-------------------------+
         * | NMI executing variable  |
         * +-------------------------+
-        * | Saved SS                |
-        * | Saved Return RSP        |
-        * | Saved RFLAGS            |
-        * | Saved CS                |
-        * | Saved RIP               |
-        * +-------------------------+
         * | copied SS               |
         * | copied Return RSP       |
         * | copied RFLAGS           |
         * | copied CS               |
         * | copied RIP              |
         * +-------------------------+
+        * | Saved SS                |
+        * | Saved Return RSP        |
+        * | Saved RFLAGS            |
+        * | Saved CS                |
+        * | Saved RIP               |
+        * +-------------------------+
         * | pt_regs                 |
         * +-------------------------+
         *
@@ -1763,9 +1764,14 @@ first_nmi:
        /* Set the NMI executing variable on the stack. */
        pushq_cfi $1
 
+       /*
+        * Leave room for the "copied" frame
+        */
+       subq $(5*8), %rsp
+
        /* Copy the stack frame to the Saved frame */
        .rept 5
-       pushq_cfi 6*8(%rsp)
+       pushq_cfi 11*8(%rsp)
        .endr
        CFI_DEF_CFA_OFFSET SS+8-RIP
 
@@ -1786,12 +1792,15 @@ repeat_nmi:
         * is benign for the non-repeat case, where 1 was pushed just above
         * to this very stack slot).
         */
-       movq $1, 5*8(%rsp)
+       movq $1, 10*8(%rsp)
 
        /* Make another copy, this one may be modified by nested NMIs */
+       addq $(10*8), %rsp
+       CFI_ADJUST_CFA_OFFSET -10*8
        .rept 5
-       pushq_cfi 4*8(%rsp)
+       pushq_cfi -6*8(%rsp)
        .endr
+       subq $(5*8), %rsp
        CFI_DEF_CFA_OFFSET SS+8-RIP
 end_repeat_nmi:
 
@@ -1842,8 +1851,12 @@ nmi_swapgs:
        SWAPGS_UNSAFE_STACK
 nmi_restore:
        RESTORE_ALL 8
+
+       /* Pop the extra iret frame */
+       addq $(5*8), %rsp
+
        /* Clear the NMI executing stack variable */
-       movq $0, 10*8(%rsp)
+       movq $0, 5*8(%rsp)
        jmp irq_return
        CFI_ENDPROC
 END(nmi)
This page took 0.066096 seconds and 5 git commands to generate.