aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-03-10 18:29:38 -0400
committerScott Wood <scottwood@freescale.com>2014-03-19 20:57:14 -0400
commit9d378dfac885f72b8b369d08fc61bef36e2f2dd1 (patch)
tree8790aa68cd0944e031b35eb63f5be14ec678be2d /arch/powerpc/kernel
parent82d86de25b9c99db546e17c6f7ebf9a691da557e (diff)
powerpc/booke64: Use SPRG7 for VDSO
Previously SPRG3 was marked for use by both VDSO and critical interrupts (though critical interrupts were not fully implemented). In commit 8b64a9dfb091f1eca8b7e58da82f1e7d1d5fe0ad ("powerpc/booke64: Use SPRG0/3 scratch for bolted TLB miss & crit int"), Mihai Caraman made an attempt to resolve this conflict by restoring the VDSO value early in the critical interrupt, but this has some issues: - It's incompatible with EXCEPTION_COMMON which restores r13 from the by-then-overwritten scratch (this cost me some debugging time). - It forces critical exceptions to be a special case handled differently from even machine check and debug level exceptions. - It didn't occur to me that it was possible to make this work at all (by doing a final "ld r13, PACA_EXCRIT+EX_R13(r13)") until after I made (most of) this patch. :-) It might be worth investigating using a load rather than SPRG on return from all exceptions (except TLB misses where the scratch never leaves the SPRG) -- it could save a few cycles. Until then, let's stick with SPRG for all exceptions. Since we cannot use SPRG4-7 for scratch without corrupting the state of a KVM guest, move VDSO to SPRG7 on book3e. Since neither SPRG4-7 nor critical interrupts exist on book3s, SPRG3 is still used for VDSO there. Signed-off-by: Scott Wood <scottwood@freescale.com> Cc: Mihai Caraman <mihai.caraman@freescale.com> Cc: Anton Blanchard <anton@samba.org> Cc: Paul Mackerras <paulus@samba.org> Cc: kvm-ppc@vger.kernel.org
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S19
-rw-r--r--arch/powerpc/kernel/vdso.c8
-rw-r--r--arch/powerpc/kernel/vdso32/getcpu.S2
-rw-r--r--arch/powerpc/kernel/vdso64/getcpu.S2
5 files changed, 9 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index b5aacf72ae6f..dba8140ebc20 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -253,7 +253,7 @@ int main(void)
253 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 253 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
254 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); 254 DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
255 DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost)); 255 DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
256 DEFINE(PACA_SPRG3, offsetof(struct paca_struct, sprg3)); 256 DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
257#endif /* CONFIG_PPC64 */ 257#endif /* CONFIG_PPC64 */
258 258
259 /* RTAS */ 259 /* RTAS */
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 41380a424108..89e1133b0185 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -55,7 +55,6 @@
55 mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \ 55 mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \
56 std r10,PACA_EX##type+EX_R10(r13); \ 56 std r10,PACA_EX##type+EX_R10(r13); \
57 std r11,PACA_EX##type+EX_R11(r13); \ 57 std r11,PACA_EX##type+EX_R11(r13); \
58 PROLOG_STORE_RESTORE_SCRATCH_##type; \
59 mfcr r10; /* save CR */ \ 58 mfcr r10; /* save CR */ \
60 mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ 59 mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \
61 DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \ 60 DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \
@@ -116,20 +115,6 @@
116#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \ 115#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \
117 EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n)) 116 EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
118 117
119/*
120 * Store user-visible scratch in PACA exception slots and restore proper value
121 */
122#define PROLOG_STORE_RESTORE_SCRATCH_GEN
123#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL
124#define PROLOG_STORE_RESTORE_SCRATCH_DBG
125#define PROLOG_STORE_RESTORE_SCRATCH_MC
126
127#define PROLOG_STORE_RESTORE_SCRATCH_CRIT \
128 mfspr r10,SPRN_SPRG_CRIT_SCRATCH; /* get r13 */ \
129 std r10,PACA_EXCRIT+EX_R13(r13); \
130 ld r11,PACA_SPRG3(r13); \
131 mtspr SPRN_SPRG_CRIT_SCRATCH,r11;
132
133/* Variants of the "addition" argument for the prolog 118/* Variants of the "addition" argument for the prolog
134 */ 119 */
135#define PROLOG_ADDITION_NONE_GEN(n) 120#define PROLOG_ADDITION_NONE_GEN(n)
@@ -529,7 +514,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
529 mtcr r10 514 mtcr r10
530 ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */ 515 ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */
531 ld r11,PACA_EXCRIT+EX_R11(r13) 516 ld r11,PACA_EXCRIT+EX_R11(r13)
532 ld r13,PACA_EXCRIT+EX_R13(r13) 517 mfspr r13,SPRN_SPRG_CRIT_SCRATCH
533 rfci 518 rfci
534 519
535 /* Normal debug exception */ 520 /* Normal debug exception */
@@ -542,7 +527,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
542 /* Now we mash up things to make it look like we are coming on a 527 /* Now we mash up things to make it look like we are coming on a
543 * normal exception 528 * normal exception
544 */ 529 */
545 ld r15,PACA_EXCRIT+EX_R13(r13) 530 mfspr r15,SPRN_SPRG_CRIT_SCRATCH
546 mtspr SPRN_SPRG_GEN_SCRATCH,r15 531 mtspr SPRN_SPRG_GEN_SCRATCH,r15
547 mfspr r14,SPRN_DBSR 532 mfspr r14,SPRN_DBSR
548 EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE) 533 EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE)
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 094e45c16a17..ce74c335a6a4 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -715,8 +715,8 @@ int vdso_getcpu_init(void)
715 unsigned long cpu, node, val; 715 unsigned long cpu, node, val;
716 716
717 /* 717 /*
718 * SPRG3 contains the CPU in the bottom 16 bits and the NUMA node in 718 * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node
719 * the next 16 bits. The VDSO uses this to implement getcpu(). 719 * in the next 16 bits. The VDSO uses this to implement getcpu().
720 */ 720 */
721 cpu = get_cpu(); 721 cpu = get_cpu();
722 WARN_ON_ONCE(cpu > 0xffff); 722 WARN_ON_ONCE(cpu > 0xffff);
@@ -725,8 +725,8 @@ int vdso_getcpu_init(void)
725 WARN_ON_ONCE(node > 0xffff); 725 WARN_ON_ONCE(node > 0xffff);
726 726
727 val = (cpu & 0xfff) | ((node & 0xffff) << 16); 727 val = (cpu & 0xfff) | ((node & 0xffff) << 16);
728 mtspr(SPRN_SPRG3, val); 728 mtspr(SPRN_SPRG_VDSO_WRITE, val);
729 get_paca()->sprg3 = val; 729 get_paca()->sprg_vdso = val;
730 730
731 put_cpu(); 731 put_cpu();
732 732
diff --git a/arch/powerpc/kernel/vdso32/getcpu.S b/arch/powerpc/kernel/vdso32/getcpu.S
index 47afd08c90f7..23eb9a9441bd 100644
--- a/arch/powerpc/kernel/vdso32/getcpu.S
+++ b/arch/powerpc/kernel/vdso32/getcpu.S
@@ -29,7 +29,7 @@
29 */ 29 */
30V_FUNCTION_BEGIN(__kernel_getcpu) 30V_FUNCTION_BEGIN(__kernel_getcpu)
31 .cfi_startproc 31 .cfi_startproc
32 mfspr r5,SPRN_USPRG3 32 mfspr r5,SPRN_SPRG_VDSO_READ
33 cmpdi cr0,r3,0 33 cmpdi cr0,r3,0
34 cmpdi cr1,r4,0 34 cmpdi cr1,r4,0
35 clrlwi r6,r5,16 35 clrlwi r6,r5,16
diff --git a/arch/powerpc/kernel/vdso64/getcpu.S b/arch/powerpc/kernel/vdso64/getcpu.S
index 47afd08c90f7..23eb9a9441bd 100644
--- a/arch/powerpc/kernel/vdso64/getcpu.S
+++ b/arch/powerpc/kernel/vdso64/getcpu.S
@@ -29,7 +29,7 @@
29 */ 29 */
30V_FUNCTION_BEGIN(__kernel_getcpu) 30V_FUNCTION_BEGIN(__kernel_getcpu)
31 .cfi_startproc 31 .cfi_startproc
32 mfspr r5,SPRN_USPRG3 32 mfspr r5,SPRN_SPRG_VDSO_READ
33 cmpdi cr0,r3,0 33 cmpdi cr0,r3,0
34 cmpdi cr1,r4,0 34 cmpdi cr1,r4,0
35 clrlwi r6,r5,16 35 clrlwi r6,r5,16