Commit 9d378dfac885f72b8b369d08fc61bef36e2f2dd1

Authored by Scott Wood
1 parent 82d86de25b

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
... ... @@ -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
... ... @@ -29,7 +29,7 @@
29 29 */
30 30 V_FUNCTION_BEGIN(__kernel_getcpu)
31 31 .cfi_startproc
32   - mfspr r5,SPRN_USPRG3
  32 + mfspr r5,SPRN_SPRG_VDSO_READ
33 33 cmpdi cr0,r3,0
34 34 cmpdi cr1,r4,0
35 35 clrlwi r6,r5,16
arch/powerpc/kernel/vdso64/getcpu.S
... ... @@ -29,7 +29,7 @@
29 29 */
30 30 V_FUNCTION_BEGIN(__kernel_getcpu)
31 31 .cfi_startproc
32   - mfspr r5,SPRN_USPRG3
  32 + mfspr r5,SPRN_SPRG_VDSO_READ
33 33 cmpdi cr0,r3,0
34 34 cmpdi cr1,r4,0
35 35 clrlwi r6,r5,16
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)