Commit 9d378dfac885f72b8b369d08fc61bef36e2f2dd1
1 parent
82d86de25b
Exists in
master
and in
13 other branches
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
Showing 12 changed files with 33 additions and 47 deletions Side-by-side Diff
- arch/powerpc/include/asm/exception-64e.h
- arch/powerpc/include/asm/kvm_booke_hv_asm.h
- arch/powerpc/include/asm/paca.h
- arch/powerpc/include/asm/reg.h
- arch/powerpc/kernel/asm-offsets.c
- arch/powerpc/kernel/exceptions-64e.S
- arch/powerpc/kernel/vdso.c
- arch/powerpc/kernel/vdso32/getcpu.S
- arch/powerpc/kernel/vdso64/getcpu.S
- arch/powerpc/kvm/book3s_hv_rmhandlers.S
- arch/powerpc/kvm/book3s_interrupts.S
- arch/powerpc/kvm/bookehv_interrupts.S
arch/powerpc/include/asm/exception-64e.h
... | ... | @@ -46,9 +46,8 @@ |
46 | 46 | #define EX_CR (1 * 8) |
47 | 47 | #define EX_R10 (2 * 8) |
48 | 48 | #define EX_R11 (3 * 8) |
49 | -#define EX_R13 (4 * 8) | |
50 | -#define EX_R14 (5 * 8) | |
51 | -#define EX_R15 (6 * 8) | |
49 | +#define EX_R14 (4 * 8) | |
50 | +#define EX_R15 (5 * 8) | |
52 | 51 | |
53 | 52 | /* |
54 | 53 | * The TLB miss exception uses different slots. |
arch/powerpc/include/asm/kvm_booke_hv_asm.h
... | ... | @@ -36,19 +36,12 @@ |
36 | 36 | * *(r8 + GPR11) = saved r11 |
37 | 37 | * |
38 | 38 | * 64-bit host |
39 | - * Expected inputs (GEN/GDBELL/DBG/MC exception types): | |
39 | + * Expected inputs (GEN/GDBELL/DBG/CRIT/MC exception types): | |
40 | 40 | * r10 = saved CR |
41 | 41 | * r13 = PACA_POINTER |
42 | 42 | * *(r13 + PACA_EX##type + EX_R10) = saved r10 |
43 | 43 | * *(r13 + PACA_EX##type + EX_R11) = saved r11 |
44 | 44 | * SPRN_SPRG_##type##_SCRATCH = saved r13 |
45 | - * | |
46 | - * Expected inputs (CRIT exception type): | |
47 | - * r10 = saved CR | |
48 | - * r13 = PACA_POINTER | |
49 | - * *(r13 + PACA_EX##type + EX_R10) = saved r10 | |
50 | - * *(r13 + PACA_EX##type + EX_R11) = saved r11 | |
51 | - * *(r13 + PACA_EX##type + EX_R13) = saved r13 | |
52 | 45 | * |
53 | 46 | * Expected inputs (TLB exception type): |
54 | 47 | * r10 = saved CR |
arch/powerpc/include/asm/paca.h
... | ... | @@ -146,7 +146,7 @@ |
146 | 146 | u8 io_sync; /* writel() needs spin_unlock sync */ |
147 | 147 | u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ |
148 | 148 | u8 nap_state_lost; /* NV GPR values lost in power7_idle */ |
149 | - u64 sprg3; /* Saved user-visible sprg */ | |
149 | + u64 sprg_vdso; /* Saved user-visible sprg */ | |
150 | 150 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
151 | 151 | u64 tm_scratch; /* TM scratch area for reclaim */ |
152 | 152 | #endif |
arch/powerpc/include/asm/reg.h
... | ... | @@ -577,9 +577,13 @@ |
577 | 577 | #define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ |
578 | 578 | #define SPRN_USPRG3 0x103 /* SPRG3 userspace read */ |
579 | 579 | #define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ |
580 | +#define SPRN_USPRG4 0x104 /* SPRG4 userspace read */ | |
580 | 581 | #define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ |
582 | +#define SPRN_USPRG5 0x105 /* SPRG5 userspace read */ | |
581 | 583 | #define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ |
584 | +#define SPRN_USPRG6 0x106 /* SPRG6 userspace read */ | |
582 | 585 | #define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ |
586 | +#define SPRN_USPRG7 0x107 /* SPRG7 userspace read */ | |
583 | 587 | #define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ |
584 | 588 | #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ |
585 | 589 | #define SRR1_ISI_NOPT 0x40000000 /* ISI: Not found in hash */ |
586 | 590 | |
... | ... | @@ -879,11 +883,10 @@ |
879 | 883 | * 64-bit embedded |
880 | 884 | * - SPRG0 generic exception scratch |
881 | 885 | * - SPRG2 TLB exception stack |
882 | - * - SPRG3 critical exception scratch and | |
883 | - * CPU and NUMA node for VDSO getcpu (user visible) | |
886 | + * - SPRG3 critical exception scratch (user visible, sorry!) | |
884 | 887 | * - SPRG4 unused (user visible) |
885 | 888 | * - SPRG6 TLB miss scratch (user visible, sorry !) |
886 | - * - SPRG7 critical exception scratch | |
889 | + * - SPRG7 CPU and NUMA node for VDSO getcpu (user visible) | |
887 | 890 | * - SPRG8 machine check exception scratch |
888 | 891 | * - SPRG9 debug exception scratch |
889 | 892 | * |
... | ... | @@ -940,6 +943,8 @@ |
940 | 943 | #define SPRN_SPRG_SCRATCH0 SPRN_SPRG2 |
941 | 944 | #define SPRN_SPRG_HPACA SPRN_HSPRG0 |
942 | 945 | #define SPRN_SPRG_HSCRATCH0 SPRN_HSPRG1 |
946 | +#define SPRN_SPRG_VDSO_READ SPRN_USPRG3 | |
947 | +#define SPRN_SPRG_VDSO_WRITE SPRN_SPRG3 | |
943 | 948 | |
944 | 949 | #define GET_PACA(rX) \ |
945 | 950 | BEGIN_FTR_SECTION_NESTED(66); \ |
... | ... | @@ -983,6 +988,8 @@ |
983 | 988 | #define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6 |
984 | 989 | #define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0 |
985 | 990 | #define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH |
991 | +#define SPRN_SPRG_VDSO_READ SPRN_USPRG7 | |
992 | +#define SPRN_SPRG_VDSO_WRITE SPRN_SPRG7 | |
986 | 993 | |
987 | 994 | #define SET_PACA(rX) mtspr SPRN_SPRG_PACA,rX |
988 | 995 | #define GET_PACA(rX) mfspr rX,SPRN_SPRG_PACA |
arch/powerpc/kernel/asm-offsets.c
... | ... | @@ -253,7 +253,7 @@ |
253 | 253 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); |
254 | 254 | DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); |
255 | 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 | 257 | #endif /* CONFIG_PPC64 */ |
258 | 258 | |
259 | 259 | /* RTAS */ |
arch/powerpc/kernel/exceptions-64e.S
... | ... | @@ -55,7 +55,6 @@ |
55 | 55 | mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \ |
56 | 56 | std r10,PACA_EX##type+EX_R10(r13); \ |
57 | 57 | std r11,PACA_EX##type+EX_R11(r13); \ |
58 | - PROLOG_STORE_RESTORE_SCRATCH_##type; \ | |
59 | 58 | mfcr r10; /* save CR */ \ |
60 | 59 | mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ |
61 | 60 | DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \ |
... | ... | @@ -116,20 +115,6 @@ |
116 | 115 | #define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \ |
117 | 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 | 118 | /* Variants of the "addition" argument for the prolog |
134 | 119 | */ |
135 | 120 | #define PROLOG_ADDITION_NONE_GEN(n) |
... | ... | @@ -529,7 +514,7 @@ |
529 | 514 | mtcr r10 |
530 | 515 | ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */ |
531 | 516 | ld r11,PACA_EXCRIT+EX_R11(r13) |
532 | - ld r13,PACA_EXCRIT+EX_R13(r13) | |
517 | + mfspr r13,SPRN_SPRG_CRIT_SCRATCH | |
533 | 518 | rfci |
534 | 519 | |
535 | 520 | /* Normal debug exception */ |
... | ... | @@ -542,7 +527,7 @@ |
542 | 527 | /* Now we mash up things to make it look like we are coming on a |
543 | 528 | * normal exception |
544 | 529 | */ |
545 | - ld r15,PACA_EXCRIT+EX_R13(r13) | |
530 | + mfspr r15,SPRN_SPRG_CRIT_SCRATCH | |
546 | 531 | mtspr SPRN_SPRG_GEN_SCRATCH,r15 |
547 | 532 | mfspr r14,SPRN_DBSR |
548 | 533 | EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE) |
arch/powerpc/kernel/vdso.c
... | ... | @@ -715,8 +715,8 @@ |
715 | 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 | |
719 | - * the next 16 bits. The VDSO uses this to implement getcpu(). | |
718 | + * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node | |
719 | + * in the next 16 bits. The VDSO uses this to implement getcpu(). | |
720 | 720 | */ |
721 | 721 | cpu = get_cpu(); |
722 | 722 | WARN_ON_ONCE(cpu > 0xffff); |
... | ... | @@ -725,8 +725,8 @@ |
725 | 725 | WARN_ON_ONCE(node > 0xffff); |
726 | 726 | |
727 | 727 | val = (cpu & 0xfff) | ((node & 0xffff) << 16); |
728 | - mtspr(SPRN_SPRG3, val); | |
729 | - get_paca()->sprg3 = val; | |
728 | + mtspr(SPRN_SPRG_VDSO_WRITE, val); | |
729 | + get_paca()->sprg_vdso = val; | |
730 | 730 | |
731 | 731 | put_cpu(); |
732 | 732 |
arch/powerpc/kernel/vdso32/getcpu.S
arch/powerpc/kernel/vdso64/getcpu.S
arch/powerpc/kvm/book3s_hv_rmhandlers.S
... | ... | @@ -75,8 +75,8 @@ |
75 | 75 | END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) |
76 | 76 | |
77 | 77 | /* Restore SPRG3 */ |
78 | - ld r3,PACA_SPRG3(r13) | |
79 | - mtspr SPRN_SPRG3,r3 | |
78 | + ld r3,PACA_SPRG_VDSO(r13) | |
79 | + mtspr SPRN_SPRG_VDSO_WRITE,r3 | |
80 | 80 | |
81 | 81 | /* Reload the host's PMU registers */ |
82 | 82 | ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ |
arch/powerpc/kvm/book3s_interrupts.S
... | ... | @@ -153,8 +153,8 @@ |
153 | 153 | * Reload kernel SPRG3 value. |
154 | 154 | * No need to save guest value as usermode can't modify SPRG3. |
155 | 155 | */ |
156 | - ld r3, PACA_SPRG3(r13) | |
157 | - mtspr SPRN_SPRG3, r3 | |
156 | + ld r3, PACA_SPRG_VDSO(r13) | |
157 | + mtspr SPRN_SPRG_VDSO_WRITE, r3 | |
158 | 158 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
159 | 159 | |
160 | 160 | /* R7 = vcpu */ |
arch/powerpc/kvm/bookehv_interrupts.S
... | ... | @@ -229,11 +229,7 @@ |
229 | 229 | stw r10, VCPU_CR(r4) |
230 | 230 | PPC_STL r11, VCPU_GPR(R4)(r4) |
231 | 231 | PPC_STL r5, VCPU_GPR(R5)(r4) |
232 | - .if \type == EX_CRIT | |
233 | - PPC_LL r5, (\paca_ex + EX_R13)(r13) | |
234 | - .else | |
235 | 232 | mfspr r5, \scratch |
236 | - .endif | |
237 | 233 | PPC_STL r6, VCPU_GPR(R6)(r4) |
238 | 234 | PPC_STL r8, VCPU_GPR(R8)(r4) |
239 | 235 | PPC_STL r9, VCPU_GPR(R9)(r4) |
240 | 236 | |
... | ... | @@ -435,10 +431,16 @@ |
435 | 431 | PPC_STL r5, VCPU_LR(r4) |
436 | 432 | mfspr r7, SPRN_SPRG5 |
437 | 433 | stw r3, VCPU_VRSAVE(r4) |
434 | +#ifdef CONFIG_64BIT | |
435 | + PPC_LL r3, PACA_SPRG_VDSO(r13) | |
436 | +#endif | |
438 | 437 | PPC_STD(r6, VCPU_SHARED_SPRG4, r11) |
439 | 438 | mfspr r8, SPRN_SPRG6 |
440 | 439 | PPC_STD(r7, VCPU_SHARED_SPRG5, r11) |
441 | 440 | mfspr r9, SPRN_SPRG7 |
441 | +#ifdef CONFIG_64BIT | |
442 | + mtspr SPRN_SPRG_VDSO_WRITE, r3 | |
443 | +#endif | |
442 | 444 | PPC_STD(r8, VCPU_SHARED_SPRG6, r11) |
443 | 445 | mfxer r3 |
444 | 446 | PPC_STD(r9, VCPU_SHARED_SPRG7, r11) |