aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2006-08-07 02:19:19 -0400
committerPaul Mackerras <paulus@samba.org>2006-08-08 03:08:56 -0400
commit2f6093c84730b4bad65bcd0f2f904a5769b1dfc5 (patch)
treeab4e64a0520e944062f418e91706ff968e23a6ea /arch/powerpc/kernel
parent452b5e21216011f2f068e80443568f5f3f3f4d63 (diff)
[POWERPC] Implement SLB shadow buffer
This adds a shadow buffer for the SLBs and regsiters it with PHYP. Only the bolted SLB entries (top 3) are shadowed. The SLB shadow buffer tells the hypervisor what the kernel needs to have in the SLB for the kernel to be able to function. The hypervisor can use this information to speed up partition context switches. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/entry_64.S13
-rw-r--r--arch/powerpc/kernel/paca.c15
3 files changed, 29 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index ac0631958b20..2ef7ea860379 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -135,11 +135,13 @@ int main(void)
135 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); 135 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
136 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); 136 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
137 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 137 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
138 DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
138 139
139 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 140 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
140 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); 141 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
141 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); 142 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
142 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); 143 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
144 DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
143#endif /* CONFIG_PPC64 */ 145#endif /* CONFIG_PPC64 */
144 146
145 /* RTAS */ 147 /* RTAS */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 54d9f5cdaab4..5baea498ea64 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -323,6 +323,11 @@ _GLOBAL(ret_from_fork)
323 * The code which creates the new task context is in 'copy_thread' 323 * The code which creates the new task context is in 'copy_thread'
324 * in arch/powerpc/kernel/process.c 324 * in arch/powerpc/kernel/process.c
325 */ 325 */
326#define SHADOW_SLB_BOLTED_STACK_ESID \
327 (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1))
328#define SHADOW_SLB_BOLTED_STACK_VSID \
329 (SLBSHADOW_SAVEAREA + 0x10*(SLB_NUM_BOLTED-1) + 8)
330
326 .align 7 331 .align 7
327_GLOBAL(_switch) 332_GLOBAL(_switch)
328 mflr r0 333 mflr r0
@@ -375,6 +380,14 @@ BEGIN_FTR_SECTION
375 ld r7,KSP_VSID(r4) /* Get new stack's VSID */ 380 ld r7,KSP_VSID(r4) /* Get new stack's VSID */
376 oris r0,r6,(SLB_ESID_V)@h 381 oris r0,r6,(SLB_ESID_V)@h
377 ori r0,r0,(SLB_NUM_BOLTED-1)@l 382 ori r0,r0,(SLB_NUM_BOLTED-1)@l
383
384 /* Update the last bolted SLB */
385 ld r9,PACA_SLBSHADOWPTR(r13)
386 li r12,0
387 std r12,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Clear ESID */
388 std r7,SHADOW_SLB_BOLTED_STACK_VSID(r9) /* Save VSID */
389 std r0,SHADOW_SLB_BOLTED_STACK_ESID(r9) /* Save ESID */
390
378 slbie r6 391 slbie r6
379 slbie r6 /* Workaround POWER5 < DD2.1 issue */ 392 slbie r6 /* Workaround POWER5 < DD2.1 issue */
380 slbmte r7,r0 393 slbmte r7,r0
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index c68741fed14b..55f1a25085cd 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
17#include <asm/lppaca.h> 17#include <asm/lppaca.h>
18#include <asm/iseries/it_lp_reg_save.h> 18#include <asm/iseries/it_lp_reg_save.h>
19#include <asm/paca.h> 19#include <asm/paca.h>
20#include <asm/mmu.h>
20 21
21 22
22/* This symbol is provided by the linker - let it fill in the paca 23/* This symbol is provided by the linker - let it fill in the paca
@@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
45 }, 46 },
46}; 47};
47 48
49/*
50 * 3 persistent SLBs are registered here. The buffer will be zero
51 * initially, hence will all be invaild until we actually write them.
52 */
53struct slb_shadow slb_shadow[] __cacheline_aligned = {
54 [0 ... (NR_CPUS-1)] = {
55 .persistent = SLB_NUM_BOLTED,
56 .buffer_length = sizeof(struct slb_shadow),
57 },
58};
59
48/* The Paca is an array with one entry per processor. Each contains an 60/* The Paca is an array with one entry per processor. Each contains an
49 * lppaca, which contains the information shared between the 61 * lppaca, which contains the information shared between the
50 * hypervisor and Linux. 62 * hypervisor and Linux.
@@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
59 .lock_token = 0x8000, \ 71 .lock_token = 0x8000, \
60 .paca_index = (number), /* Paca Index */ \ 72 .paca_index = (number), /* Paca Index */ \
61 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 73 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
62 .hw_cpu_id = 0xffff, 74 .hw_cpu_id = 0xffff, \
75 .slb_shadow_ptr = &slb_shadow[number],
63 76
64#ifdef CONFIG_PPC_ISERIES 77#ifdef CONFIG_PPC_ISERIES
65#define PACA_INIT_ISERIES(number) \ 78#define PACA_INIT_ISERIES(number) \