powerpc: In HV mode, use HSPRG0 for PACA
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 20 Jan 2011 06:50:21 +0000 (17:50 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 20 Apr 2011 01:03:22 +0000 (11:03 +1000)
When running in Hypervisor mode (arch 2.06 or later), we store the PACA
in HSPRG0 instead of SPRG1. The architecture specifies that SPRGs may be
lost during a "nap" power management operation (though they aren't
currently on POWER7) and this enables use of SPRG1 by KVM guests.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/paca.c
arch/powerpc/kvm/book3s_rmhandlers.S

index 7778d6f..337b6fa 100644 (file)
@@ -56,8 +56,8 @@
 #define LOAD_HANDLER(reg, label)                                       \
        addi    reg,reg,(label)-_stext; /* virt addr of handler ... */
 
-#define EXCEPTION_PROLOG_1(area)                               \
-       mfspr   r13,SPRN_SPRG_PACA;     /* get paca address into r13 */ \
+#define EXCEPTION_PROLOG_1(area)                                       \
+       GET_PACA(r13);                                                  \
        std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
        std     r10,area+EX_R10(r13);                                   \
        std     r11,area+EX_R11(r13);                                   \
@@ -174,7 +174,7 @@ label##_pSeries:                                                    \
        HMT_MEDIUM;                                                     \
        DO_KVM  n;                                                      \
        mtspr   SPRN_SPRG_SCRATCH0,r13; /* save r13 */                  \
-       mfspr   r13,SPRN_SPRG_PACA;     /* get paca address into r13 */ \
+       GET_PACA(r13);                                                  \
        std     r9,PACA_EXGEN+EX_R9(r13);       /* save r9, r10 */      \
        std     r10,PACA_EXGEN+EX_R10(r13);                             \
        lbz     r10,PACASOFTIRQEN(r13);                                 \
index 6eb1d77..13429a0 100644 (file)
  * SPRG usage:
  *
  * All 64-bit:
- *     - SPRG1 stores PACA pointer
+ *     - SPRG1 stores PACA pointer except 64-bit server in
+ *        HV mode in which case it is HSPRG0
  *
  * 64-bit server:
  *     - SPRG0 unused (reserved for HV on Power4)
  *     - SPRG2 scratch for exception vectors
  *     - SPRG3 unused (user visible)
+ *      - HSPRG0 stores PACA in HV mode
+ *      - HSPRG1 scratch for "HV" exceptions
  *
  * 64-bit embedded
  *     - SPRG0 generic exception scratch
 
 #ifdef CONFIG_PPC_BOOK3S_64
 #define SPRN_SPRG_SCRATCH0     SPRN_SPRG2
+#define SPRN_SPRG_HPACA                SPRN_HSPRG0
+#define SPRN_SPRG_HSCRATCH0    SPRN_HSPRG1
+
+#define GET_PACA(rX)                                   \
+       BEGIN_FTR_SECTION_NESTED(66);                   \
+       mfspr   rX,SPRN_SPRG_PACA;                      \
+       FTR_SECTION_ELSE_NESTED(66);                    \
+       mfspr   rX,SPRN_SPRG_HPACA;                     \
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_PACA(rX)                                   \
+       BEGIN_FTR_SECTION_NESTED(66);                   \
+       mtspr   SPRN_SPRG_PACA,rX;                      \
+       FTR_SECTION_ELSE_NESTED(66);                    \
+       mtspr   SPRN_SPRG_HPACA,rX;                     \
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E_64
 #define SPRN_SPRG_TLB_EXFRAME  SPRN_SPRG2
 #define SPRN_SPRG_TLB_SCRATCH  SPRN_SPRG6
 #define SPRN_SPRG_GEN_SCRATCH  SPRN_SPRG0
+
+#define SET_PACA(rX)   mtspr   SPRN_SPRG_PACA,rX
+#define GET_PACA(rX)   mfspr   rX,SPRN_SPRG_PACA
+
 #endif
 
 #ifdef CONFIG_PPC_BOOK3S_32
 #define SPRN_SPRG_SCRATCH1     SPRN_SPRG1
 #endif
 
+
+
 /*
  * An mtfsf instruction with the L bit set. On CPUs that support this a
  * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
index d82878c..dbf5bfa 100644 (file)
@@ -838,7 +838,7 @@ _GLOBAL(enter_rtas)
 
 _STATIC(rtas_return_loc)
        /* relocation is off at this point */
-       mfspr   r4,SPRN_SPRG_PACA       /* Get PACA */
+       GET_PACA(r4)
        clrldi  r4,r4,2                 /* convert to realmode address */
 
        bcl     20,31,$+4
@@ -869,7 +869,7 @@ _STATIC(rtas_restore_regs)
        REST_8GPRS(14, r1)              /* Restore the non-volatiles */
        REST_10GPRS(22, r1)             /* ditto */
 
-       mfspr   r13,SPRN_SPRG_PACA
+       GET_PACA(r13)
 
        ld      r4,_CCR(r1)
        mtcr    r4
index aeb739e..6784bf7 100644 (file)
@@ -53,7 +53,7 @@ data_access_pSeries:
        DO_KVM  0x300
        mtspr   SPRN_SPRG_SCRATCH0,r13
 BEGIN_FTR_SECTION
-       mfspr   r13,SPRN_SPRG_PACA
+       GET_PACA(r13)
        std     r9,PACA_EXSLB+EX_R9(r13)
        std     r10,PACA_EXSLB+EX_R10(r13)
        mfspr   r10,SPRN_DAR
@@ -82,7 +82,7 @@ data_access_slb_pSeries:
        HMT_MEDIUM
        DO_KVM  0x380
        mtspr   SPRN_SPRG_SCRATCH0,r13
-       mfspr   r13,SPRN_SPRG_PACA              /* get paca address into r13 */
+       GET_PACA(r13)
        std     r3,PACA_EXSLB+EX_R3(r13)
        mfspr   r3,SPRN_DAR
        std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
@@ -121,7 +121,7 @@ instruction_access_slb_pSeries:
        HMT_MEDIUM
        DO_KVM  0x480
        mtspr   SPRN_SPRG_SCRATCH0,r13
-       mfspr   r13,SPRN_SPRG_PACA              /* get paca address into r13 */
+       GET_PACA(r13)
        std     r3,PACA_EXSLB+EX_R3(r13)
        mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
        std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
@@ -165,7 +165,7 @@ BEGIN_FTR_SECTION
        beq-    1f
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
        mr      r9,r13
-       mfspr   r13,SPRN_SPRG_PACA
+       GET_PACA(r13)
        mfspr   r11,SPRN_SRR0
        ld      r12,PACAKBASE(r13)
        ld      r10,PACAKMSR(r13)
index 3a319f9..39a4040 100644 (file)
@@ -228,7 +228,7 @@ generic_secondary_common_init:
        mr      r3,r24                  /* not found, copy phys to r3    */
        b       .kexec_wait             /* next kernel might do better   */
 
-2:     mtspr   SPRN_SPRG_PACA,r13      /* Save vaddr of paca in an SPRG */
+2:     SET_PACA(r13)
 #ifdef CONFIG_PPC_BOOK3E
        addi    r12,r13,PACA_EXTLB      /* and TLB exc frame in another  */
        mtspr   SPRN_SPRG_TLB_EXFRAME,r12
@@ -534,7 +534,7 @@ _GLOBAL(pmac_secondary_start)
        ld      r4,0(r4)                /* Get base vaddr of paca array */
        mulli   r13,r24,PACA_SIZE       /* Calculate vaddr of right paca */
        add     r13,r13,r4              /* for this processor.          */
-       mtspr   SPRN_SPRG_PACA,r13      /* Save vaddr of paca in an SPRG*/
+       SET_PACA(r13)                   /* Save vaddr of paca in an SPRG*/
 
        /* Mark interrupts soft and hard disabled (they might be enabled
         * in the PACA when doing hotplug)
index 10f0aad..102244e 100644 (file)
@@ -156,11 +156,22 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
 /* Put the paca pointer into r13 and SPRG_PACA */
 void setup_paca(struct paca_struct *new_paca)
 {
+       /* Setup r13 */
        local_paca = new_paca;
-       mtspr(SPRN_SPRG_PACA, local_paca);
+
 #ifdef CONFIG_PPC_BOOK3E
+       /* On Book3E, initialize the TLB miss exception frames */
        mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
+#else
+       /* In HV mode, we setup both HPACA and PACA to avoid problems
+        * if we do a GET_PACA() before the feature fixups have been
+        * applied
+        */
+       if (cpu_has_feature(CPU_FTR_HVMODE_206))
+               mtspr(SPRN_SPRG_HPACA, local_paca);
 #endif
+       mtspr(SPRN_SPRG_PACA, local_paca);
+
 }
 
 static int __initdata paca_size;
index 2b9c908..b0ff5ff 100644 (file)
@@ -35,9 +35,7 @@
 
 #if defined(CONFIG_PPC_BOOK3S_64)
 
-#define LOAD_SHADOW_VCPU(reg)                          \
-       mfspr   reg, SPRN_SPRG_PACA
-
+#define LOAD_SHADOW_VCPU(reg)  GET_PACA(reg)                                   
 #define SHADOW_VCPU_OFF                PACA_KVM_SVCPU
 #define MSR_NOIRQ              MSR_KERNEL & ~(MSR_IR | MSR_DR)
 #define FUNC(name)             GLUE(.,name)