powerpc/6xx: Don't use SPRN_SPRG2 for storing stack pointer while in RTAS
authorChristophe Leroy <christophe.leroy@c-s.fr>
Thu, 21 Feb 2019 10:37:54 +0000 (10:37 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 21 Feb 2019 13:10:16 +0000 (00:10 +1100)
When calling RTAS, the stack pointer is stored in SPRN_SPRG2
in order to be able to restore it in case of machine check in RTAS.

As machine check is not a perfomance critical path, this patch
frees SPRN_SPRG2 by using a field in thread struct instead.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/head_32.S

index ee58526cb6c276d20c029ccab1fddf7d5575c4fb..e8682122ea3d2fad7a99db13323f0250e5b84653 100644 (file)
@@ -250,6 +250,9 @@ struct thread_struct {
 #ifdef CONFIG_PPC32
        void            *pgdir;         /* root of page-table tree */
        unsigned long   ksp_limit;      /* if ksp <= ksp_limit stack overflow */
+#ifdef CONFIG_PPC_RTAS
+       unsigned long   rtas_sp;        /* stack pointer for when in RTAS */
+#endif
 #endif
        /* Debug Registers */
        struct debug_reg debug;
index 1c98ef1f2d5b14c4347b5b27f648d611016dd15e..371ef6e8248eb6afb494e40f5d8796a6df485aa5 100644 (file)
 #ifdef CONFIG_PPC_BOOK3S_32
 #define SPRN_SPRG_SCRATCH0     SPRN_SPRG0
 #define SPRN_SPRG_SCRATCH1     SPRN_SPRG1
-#define SPRN_SPRG_RTAS         SPRN_SPRG2
 #define SPRN_SPRG_603_LRU      SPRN_SPRG4
 #endif
 
index 9ffc72ded73add59be3f267e0f8cfc922bdf827b..d6f9bdb1eb2eba17b1ea4d24b5611d353cf5b8fa 100644 (file)
@@ -93,6 +93,9 @@ int main(void)
        OFFSET(THREAD_INFO, task_struct, stack);
        DEFINE(THREAD_INFO_GAP, _ALIGN_UP(sizeof(struct thread_info), 16));
        OFFSET(KSP_LIMIT, thread_struct, ksp_limit);
+#ifdef CONFIG_PPC_RTAS
+       OFFSET(RTAS_SP, thread_struct, rtas_sp);
+#endif
 #endif /* CONFIG_PPC64 */
 
 #ifdef CONFIG_LIVEPATCH
index c2b66fbbf7f059a72c132d60dbc718103d39f8fd..6c671ceb5a0669596dd93b429998e3fbfe96dfc5 100644 (file)
@@ -1332,7 +1332,7 @@ _GLOBAL(enter_rtas)
        MTMSRD(r0)              /* don't get trashed */
        li      r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
        mtlr    r6
-       mtspr   SPRN_SPRG_RTAS,r7
+       stw     r7, THREAD + RTAS_SP(r2)
        mtspr   SPRN_SRR0,r8
        mtspr   SPRN_SRR1,r9
        RFI
@@ -1341,7 +1341,8 @@ _GLOBAL(enter_rtas)
        lwz     r9,8(r9)        /* original msr value */
        addi    r1,r1,INT_FRAME_SIZE
        li      r0,0
-       mtspr   SPRN_SPRG_RTAS,r0
+       tophys(r7, r2)
+       stw     r0, THREAD + RTAS_SP(r7)
        mtspr   SPRN_SRR0,r8
        mtspr   SPRN_SRR1,r9
        RFI                     /* return to caller */
index c2f564690778d6df618b9e44aa2cf25e73ca48e4..04128899a0a5cc1c404bad30a0160cc46e9685b1 100644 (file)
@@ -352,9 +352,8 @@ i##n:                                                               \
  * registers that might have bad values includes all the GPRs
  * and all the BATs.  We indicate that we are in RTAS by putting
  * a non-zero value, the address of the exception frame to use,
- * in SPRG2.  The machine check handler checks SPRG2 and uses its
- * value if it is non-zero.  If we ever needed to free up SPRG2,
- * we could use a field in the thread_info or thread_struct instead.
+ * in thread.rtas_sp.  The machine check handler checks thread.rtas_sp
+ * and uses its value if it is non-zero.
  * (Other exception handlers assume that r1 is a valid kernel stack
  * pointer when we take an exception from supervisor mode.)
  *     -- paulus.
@@ -365,16 +364,15 @@ i##n:                                                             \
        mtspr   SPRN_SPRG_SCRATCH1,r11
        mfcr    r10
 #ifdef CONFIG_PPC_CHRP
-       mfspr   r11,SPRN_SPRG_RTAS
-       cmpwi   0,r11,0
-       bne     7f
+       mfspr   r11, SPRN_SPRG_THREAD
+       lwz     r11, RTAS_SP(r11)
+       cmpwi   cr1, r11, 0
+       bne     cr1, 7f
 #endif /* CONFIG_PPC_CHRP */
        EXCEPTION_PROLOG_1
 7:     EXCEPTION_PROLOG_2
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_PPC_CHRP
-       mfspr   r4,SPRN_SPRG_RTAS
-       cmpwi   cr1,r4,0
        bne     cr1,1f
 #endif
        EXC_XFER_STD(0x200, machine_check_exception)
@@ -865,8 +863,10 @@ __secondary_start:
        tophys(r4,r2)
        addi    r4,r4,THREAD    /* phys address of our thread_struct */
        mtspr   SPRN_SPRG_THREAD,r4
+#ifdef CONFIG_PPC_RTAS
        li      r3,0
-       mtspr   SPRN_SPRG_RTAS,r3       /* 0 => not in RTAS */
+       stw     r3, RTAS_SP(r4)         /* 0 => not in RTAS */
+#endif
 
        /* enable MMU and jump to start_secondary */
        li      r4,MSR_KERNEL
@@ -950,8 +950,10 @@ start_here:
        tophys(r4,r2)
        addi    r4,r4,THREAD    /* init task's THREAD */
        mtspr   SPRN_SPRG_THREAD,r4
+#ifdef CONFIG_PPC_RTAS
        li      r3,0
-       mtspr   SPRN_SPRG_RTAS,r3       /* 0 => not in RTAS */
+       stw     r3, RTAS_SP(r4)         /* 0 => not in RTAS */
+#endif
 
        /* stack */
        lis     r1,init_thread_union@ha