powerpc/booke64: Use SPRG0/3 scratch for bolted TLB miss & crit int
authorMihai Caraman <mihai.caraman@freescale.com>
Mon, 6 Aug 2012 03:27:07 +0000 (03:27 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 5 Sep 2012 05:35:52 +0000 (15:35 +1000)
Embedded.Hypervisor category defines GSPRG0..3 physical registers for guests.
Avoid SPRG4-7 usage as scratch in host exception handlers, otherwise guest
SPRG4-7 registers will be clobbered.
For bolted TLB miss exception handlers, which is the version currently
supported by KVM, use SPRN_SPRG_GEN_SCRATCH aka SPRG0 instead of
SPRN_SPRG_TLB_SCRATCH aka SPRG6. Keep using TLB PACA slots to fit in one
64-byte cache line.
For critical exception handlers use SPRG3 instead of SPRG7. Provide a routine
to store and restore user-visible SPRGs. This will be subsequently used
to restore VDSO information in SPRG3. Add EX_R13 to paca slots to free up
SPRG3 and change the critical exception epilog to use it.

Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/exception-64e.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/mm/tlb_low_64e.S

index e73452f090192f6eca59597d199a729126c9c0fc..51fa43e536b917c08c5870525c9a81063c1448e2 100644 (file)
@@ -46,8 +46,9 @@
 #define EX_CR          (1 * 8)
 #define EX_R10         (2 * 8)
 #define EX_R11         (3 * 8)
-#define EX_R14         (4 * 8)
-#define EX_R15         (5 * 8)
+#define EX_R13         (4 * 8)
+#define EX_R14         (5 * 8)
+#define EX_R15         (6 * 8)
 
 /*
  * The TLB miss exception uses different slots.
index c195bf0e624107e9ed952cae40506c838aee4ea4..a391244c18e1d545b73b005ee0dd71593185fa72 100644 (file)
  * 64-bit embedded
  *     - SPRG0 generic exception scratch
  *     - SPRG2 TLB exception stack
- *     - SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
+ *     - SPRG3 critical exception scratch and
+ *        CPU and NUMA node for VDSO getcpu (user visible)
  *     - SPRG4 unused (user visible)
  *     - SPRG6 TLB miss scratch (user visible, sorry !)
  *     - SPRG7 critical exception scratch
 
 #ifdef CONFIG_PPC_BOOK3E_64
 #define SPRN_SPRG_MC_SCRATCH   SPRN_SPRG8
-#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG7
+#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG3
 #define SPRN_SPRG_DBG_SCRATCH  SPRN_SPRG9
 #define SPRN_SPRG_TLB_EXFRAME  SPRN_SPRG2
 #define SPRN_SPRG_TLB_SCRATCH  SPRN_SPRG6
index 83c20e84a4fb851a359c690c699c6734324d6e38..7476b0ae09fbb9816afc42b09e2ed1cb17ea39a9 100644 (file)
@@ -42,6 +42,7 @@
        mfspr   r13,SPRN_SPRG_PACA;     /* get PACA */                      \
        std     r10,PACA_EX##type+EX_R10(r13);                              \
        std     r11,PACA_EX##type+EX_R11(r13);                              \
+       PROLOG_STORE_RESTORE_SCRATCH_##type;                                \
        mfcr    r10;                    /* save CR */                       \
        mfspr   r11,SPRN_##type##_SRR1;/* what are we coming from */        \
        DO_KVM  intnum,SPRN_##type##_SRR1;    /* KVM hook */                \
 #define GDBELL_EXCEPTION_PROLOG(n, intnum, addition)                       \
        EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
 
+/*
+ * Store user-visible scratch in PACA exception slots and restore proper value
+ */
+#define PROLOG_STORE_RESTORE_SCRATCH_GEN
+#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL
+#define PROLOG_STORE_RESTORE_SCRATCH_DBG
+#define PROLOG_STORE_RESTORE_SCRATCH_MC
+
+#define PROLOG_STORE_RESTORE_SCRATCH_CRIT                                  \
+       mfspr   r10,SPRN_SPRG_CRIT_SCRATCH;     /* get r13 */               \
+       std     r10,PACA_EXCRIT+EX_R13(r13)
+
 /* Variants of the "addition" argument for the prolog
  */
 #define PROLOG_ADDITION_NONE_GEN(n)
@@ -454,7 +467,7 @@ interrupt_end_book3e:
        mtcr    r10
        ld      r10,PACA_EXCRIT+EX_R10(r13)     /* restore registers */
        ld      r11,PACA_EXCRIT+EX_R11(r13)
-       mfspr   r13,SPRN_SPRG_CRIT_SCRATCH
+       ld      r13,PACA_EXCRIT+EX_R13(r13)
        rfci
 
        /* Normal debug exception */
@@ -467,7 +480,7 @@ interrupt_end_book3e:
        /* Now we mash up things to make it look like we are coming on a
         * normal exception
         */
-       mfspr   r15,SPRN_SPRG_CRIT_SCRATCH
+       ld      r15,PACA_EXCRIT+EX_R13(r13)
        mtspr   SPRN_SPRG_GEN_SCRATCH,r15
        mfspr   r14,SPRN_DBSR
        EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE)
index d884fa44d34f89342477a7a3e9e1e7e521de7ae9..b4113bf863538adbf6d0bffdaa3aabe090270064 100644 (file)
@@ -40,7 +40,7 @@
  **********************************************************************/
 
 .macro tlb_prolog_bolted intnum addr
-       mtspr   SPRN_SPRG_TLB_SCRATCH,r13
+       mtspr   SPRN_SPRG_GEN_SCRATCH,r13
        mfspr   r13,SPRN_SPRG_PACA
        std     r10,PACA_EXTLB+EX_TLB_R10(r13)
        mfcr    r10
@@ -69,7 +69,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
        ld      r15,PACA_EXTLB+EX_TLB_R15(r13)
        TLB_MISS_RESTORE_STATS_BOLTED
        ld      r16,PACA_EXTLB+EX_TLB_R16(r13)
-       mfspr   r13,SPRN_SPRG_TLB_SCRATCH
+       mfspr   r13,SPRN_SPRG_GEN_SCRATCH
 .endm
 
 /* Data TLB miss */