diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 13 | ||||
-rw-r--r-- | arch/powerpc/kernel/paca.c | 15 |
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 | */ | ||
53 | struct 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) \ |