Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Dec 2012 03:55:20 +0000 (19:55 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Dec 2012 03:55:20 +0000 (19:55 -0800)
Pull x86 asm changes from Ingo Molnar:
 "Two fixlets and a cleanup."

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86_32: Return actual stack when requesting sp from regs
  x86: Don't clobber top of pt_regs in nested NMI
  x86/asm: Clean up copy_page_*() comments and code

1  2 
arch/x86/include/asm/ptrace.h
arch/x86/kernel/entry_64.S

@@@ -205,14 -205,21 +205,14 @@@ static inline bool user_64bit_mode(stru
  }
  #endif
  
 -/*
 - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
 - * when it traps.  The previous stack will be directly underneath the saved
 - * registers, and 'sp/ss' won't even have been saved. Thus the '&regs->sp'.
 - *
 - * This is valid only for kernel mode traps.
 - */
 -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 -{
  #ifdef CONFIG_X86_32
 -      return (unsigned long)(&regs->sp);
 +extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
  #else
 +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 +{
        return regs->sp;
 -#endif
  }
 +#endif
  
  #define GET_IP(regs) ((regs)->ip)
  #define GET_FP(regs) ((regs)->bp)
@@@ -239,6 -246,15 +239,15 @@@ static inline unsigned long regs_get_re
  {
        if (unlikely(offset > MAX_REG_OFFSET))
                return 0;
+ #ifdef CONFIG_X86_32
+       /*
+        * Traps from the kernel do not save sp and ss.
+        * Use the helper function to retrieve sp.
+        */
+       if (offset == offsetof(struct pt_regs, sp) &&
+           regs->cs == __KERNEL_CS)
+               return kernel_stack_pointer(regs);
+ #endif
        return *(unsigned long *)((unsigned long)regs + offset);
  }
  
@@@ -56,7 -56,7 +56,7 @@@
  #include <asm/ftrace.h>
  #include <asm/percpu.h>
  #include <asm/asm.h>
 -#include <asm/rcu.h>
 +#include <asm/context_tracking.h>
  #include <asm/smap.h>
  #include <linux/err.h>
  
@@@ -995,8 -995,8 +995,8 @@@ END(interrupt
         */
        .p2align CONFIG_X86_L1_CACHE_SHIFT
  common_interrupt:
 -      ASM_CLAC
        XCPT_FRAME
 +      ASM_CLAC
        addq $-0x80,(%rsp)              /* Adjust vector to [-256,-1] range */
        interrupt do_IRQ
        /* 0(%rsp): old_rsp-ARGOFFSET */
@@@ -1135,8 -1135,8 +1135,8 @@@ END(common_interrupt
   */
  .macro apicinterrupt num sym do_sym
  ENTRY(\sym)
 -      ASM_CLAC
        INTR_FRAME
 +      ASM_CLAC
        pushq_cfi $~(\num)
  .Lcommon_\sym:
        interrupt \do_sym
@@@ -1190,8 -1190,8 +1190,8 @@@ apicinterrupt IRQ_WORK_VECTOR 
   */
  .macro zeroentry sym do_sym
  ENTRY(\sym)
 -      ASM_CLAC
        INTR_FRAME
 +      ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@@ -1208,8 -1208,8 +1208,8 @@@ END(\sym
  
  .macro paranoidzeroentry sym do_sym
  ENTRY(\sym)
 -      ASM_CLAC
        INTR_FRAME
 +      ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@@ -1227,8 -1227,8 +1227,8 @@@ END(\sym
  #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
  .macro paranoidzeroentry_ist sym do_sym ist
  ENTRY(\sym)
 -      ASM_CLAC
        INTR_FRAME
 +      ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $ORIG_RAX-R15, %rsp
@@@ -1247,8 -1247,8 +1247,8 @@@ END(\sym
  
  .macro errorentry sym do_sym
  ENTRY(\sym)
 -      ASM_CLAC
        XCPT_FRAME
 +      ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
        CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@@ -1266,8 -1266,8 +1266,8 @@@ END(\sym
        /* error code is on the stack already */
  .macro paranoiderrorentry sym do_sym
  ENTRY(\sym)
 -      ASM_CLAC
        XCPT_FRAME
 +      ASM_CLAC
        PARAVIRT_ADJUST_EXCEPTION_FRAME
        subq $ORIG_RAX-R15, %rsp
        CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
@@@ -1699,9 -1699,10 +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
        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 +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                 |
         * +-------------------------+
         *
        /* 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 +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 +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)