diff options
| author | Scott Wood <scottwood@freescale.com> | 2014-03-10 18:29:38 -0400 |
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2014-03-19 20:57:14 -0400 |
| commit | 9d378dfac885f72b8b369d08fc61bef36e2f2dd1 (patch) | |
| tree | 8790aa68cd0944e031b35eb63f5be14ec678be2d /arch/powerpc/kernel | |
| parent | 82d86de25b9c99db546e17c6f7ebf9a691da557e (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.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 19 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso32/getcpu.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso64/getcpu.S | 2 |
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 | */ |
| 30 | V_FUNCTION_BEGIN(__kernel_getcpu) | 30 | V_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 | */ |
| 30 | V_FUNCTION_BEGIN(__kernel_getcpu) | 30 | V_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 |
