aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
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) \