]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/powerpc/kernel/exceptions-64s.S
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[linux.git] / arch / powerpc / kernel / exceptions-64s.S
index e6d8354d79ef25a34ece7766683813a65ffde57c..f14f3c04ec7e0c7d366f60d161ff0ced6f1497ad 100644 (file)
@@ -824,7 +824,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
  * r3 volatile parameter and return value for status
  * r4-r10 volatile input and output value
  * r11 volatile hypercall number and output value
- * r12 volatile
+ * r12 volatile input and output value
  * r13-r31 nonvolatile
  * LR nonvolatile
  * CTR volatile
@@ -834,25 +834,26 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
  * Other registers nonvolatile
  *
  * The intersection of volatile registers that don't contain possible
- * inputs is: r12, cr0, xer, ctr. We may use these as scratch regs
- * upon entry without saving.
+ * inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
+ * without saving, though xer is not a good idea to use, as hardware may
+ * interpret some bits so it may be costly to change them.
  */
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
        /*
         * There is a little bit of juggling to get syscall and hcall
-        * working well. Save r10 in ctr to be restored in case it is a
-        * hcall.
+        * working well. Save r13 in ctr to avoid using SPRG scratch
+        * register.
         *
         * Userspace syscalls have already saved the PPR, hcalls must save
         * it before setting HMT_MEDIUM.
         */
 #define SYSCALL_KVMTEST                                                        \
-       mr      r12,r13;                                                \
+       mtctr   r13;                                                    \
        GET_PACA(r13);                                                  \
-       mtctr   r10;                                                    \
+       std     r10,PACA_EXGEN+EX_R10(r13);                             \
        KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
        HMT_MEDIUM;                                                     \
-       mr      r9,r12;                                                 \
+       mfctr   r9;
 
 #else
 #define SYSCALL_KVMTEST                                                        \
@@ -935,8 +936,8 @@ EXC_VIRT_END(system_call, 0x4c00, 0x100)
         * This is a hcall, so register convention is as above, with these
         * differences:
         * r13 = PACA
-        * r12 = orig r13
-        * ctr = orig r10
+        * ctr = orig r13
+        * orig r10 saved in PACA
         */
 TRAMP_KVM_BEGIN(do_kvm_0xc00)
         /*
@@ -944,14 +945,13 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00)
          * HMT_MEDIUM. That allows the KVM code to save that value into the
          * guest state (it is the guest's PPR value).
          */
-       OPT_GET_SPR(r0, SPRN_PPR, CPU_FTR_HAS_PPR)
+       OPT_GET_SPR(r10, SPRN_PPR, CPU_FTR_HAS_PPR)
        HMT_MEDIUM
-       OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r0, CPU_FTR_HAS_PPR)
+       OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r10, CPU_FTR_HAS_PPR)
        mfctr   r10
-       SET_SCRATCH0(r12)
+       SET_SCRATCH0(r10)
        std     r9,PACA_EXGEN+EX_R9(r13)
        mfcr    r9
-       std     r10,PACA_EXGEN+EX_R10(r13)
        KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
 #endif
 
@@ -1325,10 +1325,18 @@ EXC_VIRT_NONE(0x5800, 0x100)
        std     r10,PACA_EXGEN+EX_R13(r13);             \
        EXCEPTION_PROLOG_PSERIES_1(soft_nmi_common, _H)
 
+/*
+ * Branch to soft_nmi_interrupt using the emergency stack. The emergency
+ * stack is one that is usable by maskable interrupts so long as MSR_EE
+ * remains off. It is used for recovery when something has corrupted the
+ * normal kernel stack, for example. The "soft NMI" must not use the process
+ * stack because we want irq disabled sections to avoid touching the stack
+ * at all (other than PMU interrupts), so use the emergency stack for this,
+ * and run it entirely with interrupts hard disabled.
+ */
 EXC_COMMON_BEGIN(soft_nmi_common)
        mr      r10,r1
        ld      r1,PACAEMERGSP(r13)
-       ld      r1,PACA_NMI_EMERG_SP(r13)
        subi    r1,r1,INT_FRAME_SIZE
        EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900,
                        system_reset, soft_nmi_interrupt,