diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/mmu-hash64.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparcfg.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 7 | ||||
-rw-r--r-- | arch/powerpc/mm/slb.c | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/reconfig.c | 9 |
5 files changed, 31 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index b537903b9fca..bebe31c2e907 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -41,6 +41,7 @@ extern char initial_stab[]; | |||
41 | 41 | ||
42 | #define SLB_NUM_BOLTED 3 | 42 | #define SLB_NUM_BOLTED 3 |
43 | #define SLB_CACHE_ENTRIES 8 | 43 | #define SLB_CACHE_ENTRIES 8 |
44 | #define SLB_MIN_SIZE 32 | ||
44 | 45 | ||
45 | /* Bits in the SLB ESID word */ | 46 | /* Bits in the SLB ESID word */ |
46 | #define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */ | 47 | #define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */ |
@@ -276,6 +277,7 @@ extern void slb_flush_and_rebolt(void); | |||
276 | extern void stab_initialize(unsigned long stab); | 277 | extern void stab_initialize(unsigned long stab); |
277 | 278 | ||
278 | extern void slb_vmalloc_update(void); | 279 | extern void slb_vmalloc_update(void); |
280 | extern void slb_set_size(u16 size); | ||
279 | #endif /* __ASSEMBLY__ */ | 281 | #endif /* __ASSEMBLY__ */ |
280 | 282 | ||
281 | /* | 283 | /* |
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index 2419cc706ff1..ed0ac4e4b8d8 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
36 | #include <asm/vdso_datapage.h> | 36 | #include <asm/vdso_datapage.h> |
37 | #include <asm/vio.h> | 37 | #include <asm/vio.h> |
38 | #include <asm/mmu.h> | ||
38 | 39 | ||
39 | #define MODULE_VERS "1.8" | 40 | #define MODULE_VERS "1.8" |
40 | #define MODULE_NAME "lparcfg" | 41 | #define MODULE_NAME "lparcfg" |
@@ -537,6 +538,8 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v) | |||
537 | 538 | ||
538 | seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc); | 539 | seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc); |
539 | 540 | ||
541 | seq_printf(m, "slb_size=%d\n", mmu_slb_size); | ||
542 | |||
540 | return 0; | 543 | return 0; |
541 | } | 544 | } |
542 | 545 | ||
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index c434823b8c83..bf90361bb70f 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
41 | #include <asm/time.h> | 41 | #include <asm/time.h> |
42 | #include <asm/mmu.h> | ||
42 | 43 | ||
43 | struct rtas_t rtas = { | 44 | struct rtas_t rtas = { |
44 | .lock = __RAW_SPIN_LOCK_UNLOCKED | 45 | .lock = __RAW_SPIN_LOCK_UNLOCKED |
@@ -713,6 +714,7 @@ static void rtas_percpu_suspend_me(void *info) | |||
713 | { | 714 | { |
714 | long rc = H_SUCCESS; | 715 | long rc = H_SUCCESS; |
715 | unsigned long msr_save; | 716 | unsigned long msr_save; |
717 | u16 slb_size = mmu_slb_size; | ||
716 | int cpu; | 718 | int cpu; |
717 | struct rtas_suspend_me_data *data = | 719 | struct rtas_suspend_me_data *data = |
718 | (struct rtas_suspend_me_data *)info; | 720 | (struct rtas_suspend_me_data *)info; |
@@ -735,13 +737,16 @@ static void rtas_percpu_suspend_me(void *info) | |||
735 | /* All other cpus are in H_JOIN, this cpu does | 737 | /* All other cpus are in H_JOIN, this cpu does |
736 | * the suspend. | 738 | * the suspend. |
737 | */ | 739 | */ |
740 | slb_set_size(SLB_MIN_SIZE); | ||
738 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", | 741 | printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", |
739 | smp_processor_id()); | 742 | smp_processor_id()); |
740 | data->error = rtas_call(data->token, 0, 1, NULL); | 743 | data->error = rtas_call(data->token, 0, 1, NULL); |
741 | 744 | ||
742 | if (data->error) | 745 | if (data->error) { |
743 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", | 746 | printk(KERN_DEBUG "ibm,suspend-me returned %d\n", |
744 | data->error); | 747 | data->error); |
748 | slb_set_size(slb_size); | ||
749 | } | ||
745 | } else { | 750 | } else { |
746 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", | 751 | printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", |
747 | smp_processor_id(), rc); | 752 | smp_processor_id(), rc); |
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 07961c5c169e..1d98ecc8eecd 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
@@ -249,14 +249,22 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) | |||
249 | static inline void patch_slb_encoding(unsigned int *insn_addr, | 249 | static inline void patch_slb_encoding(unsigned int *insn_addr, |
250 | unsigned int immed) | 250 | unsigned int immed) |
251 | { | 251 | { |
252 | /* Assume the instruction had a "0" immediate value, just | 252 | *insn_addr = (*insn_addr & 0xffff0000) | immed; |
253 | * "or" in the new value | ||
254 | */ | ||
255 | *insn_addr |= immed; | ||
256 | flush_icache_range((unsigned long)insn_addr, 4+ | 253 | flush_icache_range((unsigned long)insn_addr, 4+ |
257 | (unsigned long)insn_addr); | 254 | (unsigned long)insn_addr); |
258 | } | 255 | } |
259 | 256 | ||
257 | void slb_set_size(u16 size) | ||
258 | { | ||
259 | extern unsigned int *slb_compare_rr_to_size; | ||
260 | |||
261 | if (mmu_slb_size == size) | ||
262 | return; | ||
263 | |||
264 | mmu_slb_size = size; | ||
265 | patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size); | ||
266 | } | ||
267 | |||
260 | void slb_initialize(void) | 268 | void slb_initialize(void) |
261 | { | 269 | { |
262 | unsigned long linear_llp, vmalloc_llp, io_llp; | 270 | unsigned long linear_llp, vmalloc_llp, io_llp; |
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index b6f1b137d427..2e2bbe120b90 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/machdep.h> | 20 | #include <asm/machdep.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/pSeries_reconfig.h> | 22 | #include <asm/pSeries_reconfig.h> |
23 | #include <asm/mmu.h> | ||
23 | 24 | ||
24 | 25 | ||
25 | 26 | ||
@@ -439,9 +440,15 @@ static int do_update_property(char *buf, size_t bufsize) | |||
439 | if (!newprop) | 440 | if (!newprop) |
440 | return -ENOMEM; | 441 | return -ENOMEM; |
441 | 442 | ||
443 | if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) | ||
444 | slb_set_size(*(int *)value); | ||
445 | |||
442 | oldprop = of_find_property(np, name,NULL); | 446 | oldprop = of_find_property(np, name,NULL); |
443 | if (!oldprop) | 447 | if (!oldprop) { |
448 | if (strlen(name)) | ||
449 | return prom_add_property(np, newprop); | ||
444 | return -ENODEV; | 450 | return -ENODEV; |
451 | } | ||
445 | 452 | ||
446 | rc = prom_update_property(np, newprop, oldprop); | 453 | rc = prom_update_property(np, newprop, oldprop); |
447 | if (rc) | 454 | if (rc) |