powerpc/64s: Avoid r3 save/restore in SLB miss handler
authorNicholas Piggin <npiggin@gmail.com>
Sun, 21 May 2017 13:15:45 +0000 (23:15 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 20 Jun 2017 12:21:59 +0000 (22:21 +1000)
The SLB miss handler uses r3 for the faulting address but r12 is
mostly able to be freed up to save r3 in. It just requires SRR1
be reloaded again on error.

It would be more conventional to use r12 for SRR1 (and use r11 to
save r3), but slb_allocate_realmode clobbers r11 and not r12.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/exceptions-64s.S

index 059b3a3562505bac8506d48f1ded1d8c09444471..ed8628c6f0f4314a00039eebb1f25449ffd41050 100644 (file)
@@ -510,9 +510,9 @@ EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80)
        SET_SCRATCH0(r13)
        EXCEPTION_PROLOG_0(PACA_EXSLB)
        EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380)
-       std     r3,PACA_EXSLB+EX_R3(r13)
+       mr      r12,r3  /* save r3 */
        mfspr   r3,SPRN_DAR
-       mfspr   r12,SPRN_SRR1
+       mfspr   r11,SPRN_SRR1
        crset   4*cr6+eq
 #ifndef CONFIG_RELOCATABLE
        b       slb_miss_realmode
@@ -532,9 +532,9 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
        SET_SCRATCH0(r13)
        EXCEPTION_PROLOG_0(PACA_EXSLB)
        EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
-       std     r3,PACA_EXSLB+EX_R3(r13)
+       mr      r12,r3  /* save r3 */
        mfspr   r3,SPRN_DAR
-       mfspr   r12,SPRN_SRR1
+       mfspr   r11,SPRN_SRR1
        crset   4*cr6+eq
 #ifndef CONFIG_RELOCATABLE
        b       slb_miss_realmode
@@ -576,9 +576,9 @@ EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80)
        SET_SCRATCH0(r13)
        EXCEPTION_PROLOG_0(PACA_EXSLB)
        EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
-       std     r3,PACA_EXSLB+EX_R3(r13)
+       mr      r12,r3  /* save r3 */
        mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
-       mfspr   r12,SPRN_SRR1
+       mfspr   r11,SPRN_SRR1
        crclr   4*cr6+eq
 #ifndef CONFIG_RELOCATABLE
        b       slb_miss_realmode
@@ -593,9 +593,9 @@ EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80)
        SET_SCRATCH0(r13)
        EXCEPTION_PROLOG_0(PACA_EXSLB)
        EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
-       std     r3,PACA_EXSLB+EX_R3(r13)
+       mr      r12,r3  /* save r3 */
        mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
-       mfspr   r12,SPRN_SRR1
+       mfspr   r11,SPRN_SRR1
        crclr   4*cr6+eq
 #ifndef CONFIG_RELOCATABLE
        b       slb_miss_realmode
@@ -612,10 +612,10 @@ TRAMP_KVM(PACA_EXSLB, 0x480)
 EXC_COMMON_BEGIN(slb_miss_realmode)
        /*
         * r13 points to the PACA, r9 contains the saved CR,
-        * r12 contain the saved SRR1, SRR0 is still ready for return
+        * r12 contains the saved r3,
+        * r11 contain the saved SRR1, SRR0 is still ready for return
         * r3 has the faulting address
         * r9 - r13 are saved in paca->exslb.
-        * r3 is saved in paca->slb_r3
         * cr6.eq is set for a D-SLB miss, clear for a I-SLB miss
         * We assume we aren't going to take any exceptions during this
         * procedure.
@@ -624,6 +624,15 @@ EXC_COMMON_BEGIN(slb_miss_realmode)
        stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
        std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
 
+       /*
+        * Test MSR_RI before calling slb_allocate_realmode, because the
+        * MSR in r11 gets clobbered. However we still want to allocate
+        * SLB in case MSR_RI=0, to minimise the risk of getting stuck in
+        * recursive SLB faults. So use cr5 for this, which is preserved.
+        */
+       andi.   r11,r11,MSR_RI  /* check for unrecoverable exception */
+       cmpdi   cr5,r11,MSR_RI
+
        crset   4*cr0+eq
 #ifdef CONFIG_PPC_STD_MMU_64
 BEGIN_MMU_FTR_SECTION
@@ -637,21 +646,21 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
 
        beq-    8f              /* if bad address, make full stack frame */
 
-       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
-       beq-    2f
+       bne-    cr5,2f          /* if unrecoverable exception, oops */
 
        /* All done -- return from exception. */
 
 .machine       push
 .machine       "power4"
        mtcrf   0x80,r9
+       mtcrf   0x04,r9         /* MSR[RI] indication is in cr5 */
        mtcrf   0x02,r9         /* I/D indication is in cr6 */
        mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
 .machine       pop
 
        RESTORE_CTR(r9, PACA_EXSLB)
        RESTORE_PPR_PACA(PACA_EXSLB, r9)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
+       mr      r3,r12
        ld      r9,PACA_EXSLB+EX_R9(r13)
        ld      r10,PACA_EXSLB+EX_R10(r13)
        ld      r11,PACA_EXSLB+EX_R11(r13)
@@ -661,8 +670,9 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
        b       .       /* prevent speculative execution */
 
 2:     std     r3,PACA_EXSLB+EX_DAR(r13)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
+       mr      r3,r12
        mfspr   r11,SPRN_SRR0
+       mfspr   r12,SPRN_SRR1
        LOAD_HANDLER(r10,unrecov_slb)
        mtspr   SPRN_SRR0,r10
        ld      r10,PACAKMSR(r13)
@@ -671,8 +681,9 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)
        b       .
 
 8:     std     r3,PACA_EXSLB+EX_DAR(r13)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
+       mr      r3,r12
        mfspr   r11,SPRN_SRR0
+       mfspr   r12,SPRN_SRR1
        LOAD_HANDLER(r10,bad_addr_slb)
        mtspr   SPRN_SRR0,r10
        ld      r10,PACAKMSR(r13)