powerpc: In HV mode, use HSPRG0 for PACA

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 24cc67de
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
addi reg,reg,(label)-_stext; /* virt addr of handler ... */ addi reg,reg,(label)-_stext; /* virt addr of handler ... */
#define EXCEPTION_PROLOG_1(area) \ #define EXCEPTION_PROLOG_1(area) \
mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ GET_PACA(r13); \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \ std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \ std r11,area+EX_R11(r13); \
...@@ -174,7 +174,7 @@ label##_pSeries: \ ...@@ -174,7 +174,7 @@ label##_pSeries: \
HMT_MEDIUM; \ HMT_MEDIUM; \
DO_KVM n; \ DO_KVM n; \
mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ 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 r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
std r10,PACA_EXGEN+EX_R10(r13); \ std r10,PACA_EXGEN+EX_R10(r13); \
lbz r10,PACASOFTIRQEN(r13); \ lbz r10,PACASOFTIRQEN(r13); \
......
...@@ -715,12 +715,15 @@ ...@@ -715,12 +715,15 @@
* SPRG usage: * SPRG usage:
* *
* All 64-bit: * 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: * 64-bit server:
* - SPRG0 unused (reserved for HV on Power4) * - SPRG0 unused (reserved for HV on Power4)
* - SPRG2 scratch for exception vectors * - SPRG2 scratch for exception vectors
* - SPRG3 unused (user visible) * - SPRG3 unused (user visible)
* - HSPRG0 stores PACA in HV mode
* - HSPRG1 scratch for "HV" exceptions
* *
* 64-bit embedded * 64-bit embedded
* - SPRG0 generic exception scratch * - SPRG0 generic exception scratch
...@@ -783,6 +786,22 @@ ...@@ -783,6 +786,22 @@
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
#define SPRN_SPRG_SCRATCH0 SPRN_SPRG2 #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 #endif
#ifdef CONFIG_PPC_BOOK3E_64 #ifdef CONFIG_PPC_BOOK3E_64
...@@ -792,6 +811,10 @@ ...@@ -792,6 +811,10 @@
#define SPRN_SPRG_TLB_EXFRAME SPRN_SPRG2 #define SPRN_SPRG_TLB_EXFRAME SPRN_SPRG2
#define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6 #define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6
#define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0 #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 #endif
#ifdef CONFIG_PPC_BOOK3S_32 #ifdef CONFIG_PPC_BOOK3S_32
...@@ -842,6 +865,8 @@ ...@@ -842,6 +865,8 @@
#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
#endif #endif
/* /*
* An mtfsf instruction with the L bit set. On CPUs that support this a * 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. * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
......
...@@ -838,7 +838,7 @@ _GLOBAL(enter_rtas) ...@@ -838,7 +838,7 @@ _GLOBAL(enter_rtas)
_STATIC(rtas_return_loc) _STATIC(rtas_return_loc)
/* relocation is off at this point */ /* relocation is off at this point */
mfspr r4,SPRN_SPRG_PACA /* Get PACA */ GET_PACA(r4)
clrldi r4,r4,2 /* convert to realmode address */ clrldi r4,r4,2 /* convert to realmode address */
bcl 20,31,$+4 bcl 20,31,$+4
...@@ -869,7 +869,7 @@ _STATIC(rtas_restore_regs) ...@@ -869,7 +869,7 @@ _STATIC(rtas_restore_regs)
REST_8GPRS(14, r1) /* Restore the non-volatiles */ REST_8GPRS(14, r1) /* Restore the non-volatiles */
REST_10GPRS(22, r1) /* ditto */ REST_10GPRS(22, r1) /* ditto */
mfspr r13,SPRN_SPRG_PACA GET_PACA(r13)
ld r4,_CCR(r1) ld r4,_CCR(r1)
mtcr r4 mtcr r4
......
...@@ -53,7 +53,7 @@ data_access_pSeries: ...@@ -53,7 +53,7 @@ data_access_pSeries:
DO_KVM 0x300 DO_KVM 0x300
mtspr SPRN_SPRG_SCRATCH0,r13 mtspr SPRN_SPRG_SCRATCH0,r13
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mfspr r13,SPRN_SPRG_PACA GET_PACA(r13)
std r9,PACA_EXSLB+EX_R9(r13) std r9,PACA_EXSLB+EX_R9(r13)
std r10,PACA_EXSLB+EX_R10(r13) std r10,PACA_EXSLB+EX_R10(r13)
mfspr r10,SPRN_DAR mfspr r10,SPRN_DAR
...@@ -82,7 +82,7 @@ data_access_slb_pSeries: ...@@ -82,7 +82,7 @@ data_access_slb_pSeries:
HMT_MEDIUM HMT_MEDIUM
DO_KVM 0x380 DO_KVM 0x380
mtspr SPRN_SPRG_SCRATCH0,r13 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) std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_DAR mfspr r3,SPRN_DAR
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
...@@ -121,7 +121,7 @@ instruction_access_slb_pSeries: ...@@ -121,7 +121,7 @@ instruction_access_slb_pSeries:
HMT_MEDIUM HMT_MEDIUM
DO_KVM 0x480 DO_KVM 0x480
mtspr SPRN_SPRG_SCRATCH0,r13 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) std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
...@@ -165,7 +165,7 @@ BEGIN_FTR_SECTION ...@@ -165,7 +165,7 @@ BEGIN_FTR_SECTION
beq- 1f beq- 1f
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
mr r9,r13 mr r9,r13
mfspr r13,SPRN_SPRG_PACA GET_PACA(r13)
mfspr r11,SPRN_SRR0 mfspr r11,SPRN_SRR0
ld r12,PACAKBASE(r13) ld r12,PACAKBASE(r13)
ld r10,PACAKMSR(r13) ld r10,PACAKMSR(r13)
......
...@@ -228,7 +228,7 @@ generic_secondary_common_init: ...@@ -228,7 +228,7 @@ generic_secondary_common_init:
mr r3,r24 /* not found, copy phys to r3 */ mr r3,r24 /* not found, copy phys to r3 */
b .kexec_wait /* next kernel might do better */ 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 #ifdef CONFIG_PPC_BOOK3E
addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */ addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */
mtspr SPRN_SPRG_TLB_EXFRAME,r12 mtspr SPRN_SPRG_TLB_EXFRAME,r12
...@@ -534,7 +534,7 @@ _GLOBAL(pmac_secondary_start) ...@@ -534,7 +534,7 @@ _GLOBAL(pmac_secondary_start)
ld r4,0(r4) /* Get base vaddr of paca array */ ld r4,0(r4) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r4 /* for this processor. */ 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 /* Mark interrupts soft and hard disabled (they might be enabled
* in the PACA when doing hotplug) * in the PACA when doing hotplug)
......
...@@ -156,11 +156,22 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) ...@@ -156,11 +156,22 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
/* Put the paca pointer into r13 and SPRG_PACA */ /* Put the paca pointer into r13 and SPRG_PACA */
void setup_paca(struct paca_struct *new_paca) void setup_paca(struct paca_struct *new_paca)
{ {
/* Setup r13 */
local_paca = new_paca; local_paca = new_paca;
mtspr(SPRN_SPRG_PACA, local_paca);
#ifdef CONFIG_PPC_BOOK3E #ifdef CONFIG_PPC_BOOK3E
/* On Book3E, initialize the TLB miss exception frames */
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); 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 #endif
mtspr(SPRN_SPRG_PACA, local_paca);
} }
static int __initdata paca_size; static int __initdata paca_size;
......
...@@ -35,9 +35,7 @@ ...@@ -35,9 +35,7 @@
#if defined(CONFIG_PPC_BOOK3S_64) #if defined(CONFIG_PPC_BOOK3S_64)
#define LOAD_SHADOW_VCPU(reg) \ #define LOAD_SHADOW_VCPU(reg) GET_PACA(reg)
mfspr reg, SPRN_SPRG_PACA
#define SHADOW_VCPU_OFF PACA_KVM_SVCPU #define SHADOW_VCPU_OFF PACA_KVM_SVCPU
#define MSR_NOIRQ MSR_KERNEL & ~(MSR_IR | MSR_DR) #define MSR_NOIRQ MSR_KERNEL & ~(MSR_IR | MSR_DR)
#define FUNC(name) GLUE(.,name) #define FUNC(name) GLUE(.,name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment