From: Greg Kroah-Hartman Date: Wed, 16 Sep 2009 21:47:36 +0000 (-0700) Subject: another .30 patch X-Git-Tag: v2.6.30.8~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3139fc7c01026a91b50abfde5a0f9e45f871dcc4;p=thirdparty%2Fkernel%2Fstable-queue.git another .30 patch --- diff --git a/queue-2.6.30/powerpc-pseries-fix-to-handle-slb-resize-across-migration.patch b/queue-2.6.30/powerpc-pseries-fix-to-handle-slb-resize-across-migration.patch new file mode 100644 index 00000000000..4b28b2adbb5 --- /dev/null +++ b/queue-2.6.30/powerpc-pseries-fix-to-handle-slb-resize-across-migration.patch @@ -0,0 +1,164 @@ +From 46db2f86a3b2a94e0b33e0b4548fb7b7b6bdff66 Mon Sep 17 00:00:00 2001 +From: Brian King +Date: Fri, 28 Aug 2009 12:06:29 +0000 +Subject: powerpc/pseries: Fix to handle slb resize across migration + +From: Brian King + +commit 46db2f86a3b2a94e0b33e0b4548fb7b7b6bdff66 upstream. + +The SLB can change sizes across a live migration, which was not +being handled, resulting in possible machine crashes during +migration if migrating to a machine which has a smaller max SLB +size than the source machine. Fix this by first reducing the +SLB size to the minimum possible value, which is 32, prior to +migration. Then during the device tree update which occurs after +migration, we make the call to ensure the SLB gets updated. Also +add the slb_size to the lparcfg output so that the migration +tools can check to make sure the kernel has this capability +before allowing migration in scenarios where the SLB size will change. + +BenH: Fixed #include -> to avoid + breaking ppc32 build + +Signed-off-by: Brian King +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/mmu-hash64.h | 2 ++ + arch/powerpc/kernel/lparcfg.c | 3 +++ + arch/powerpc/kernel/rtas.c | 7 ++++++- + arch/powerpc/mm/slb.c | 16 ++++++++++++---- + arch/powerpc/platforms/pseries/reconfig.c | 9 ++++++++- + 5 files changed, 31 insertions(+), 6 deletions(-) + +--- a/arch/powerpc/include/asm/mmu-hash64.h ++++ b/arch/powerpc/include/asm/mmu-hash64.h +@@ -41,6 +41,7 @@ extern char initial_stab[]; + + #define SLB_NUM_BOLTED 3 + #define SLB_CACHE_ENTRIES 8 ++#define SLB_MIN_SIZE 32 + + /* Bits in the SLB ESID word */ + #define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */ +@@ -296,6 +297,7 @@ extern void slb_flush_and_rebolt(void); + extern void stab_initialize(unsigned long stab); + + extern void slb_vmalloc_update(void); ++extern void slb_set_size(u16 size); + #endif /* __ASSEMBLY__ */ + + /* +--- a/arch/powerpc/kernel/lparcfg.c ++++ b/arch/powerpc/kernel/lparcfg.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #define MODULE_VERS "1.8" + #define MODULE_NAME "lparcfg" +@@ -501,6 +502,8 @@ static int pseries_lparcfg_data(struct s + + seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc); + ++ seq_printf(m, "slb_size=%d\n", mmu_slb_size); ++ + return 0; + } + +--- a/arch/powerpc/kernel/rtas.c ++++ b/arch/powerpc/kernel/rtas.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + struct rtas_t rtas = { + .lock = SPIN_LOCK_UNLOCKED +@@ -692,6 +693,7 @@ static void rtas_percpu_suspend_me(void + { + long rc = H_SUCCESS; + unsigned long msr_save; ++ u16 slb_size = mmu_slb_size; + int cpu; + struct rtas_suspend_me_data *data = + (struct rtas_suspend_me_data *)info; +@@ -714,13 +716,16 @@ static void rtas_percpu_suspend_me(void + /* All other cpus are in H_JOIN, this cpu does + * the suspend. + */ ++ slb_set_size(SLB_MIN_SIZE); + printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", + smp_processor_id()); + data->error = rtas_call(data->token, 0, 1, NULL); + +- if (data->error) ++ if (data->error) { + printk(KERN_DEBUG "ibm,suspend-me returned %d\n", + data->error); ++ slb_set_size(slb_size); ++ } + } else { + printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", + smp_processor_id(), rc); +--- a/arch/powerpc/mm/slb.c ++++ b/arch/powerpc/mm/slb.c +@@ -247,14 +247,22 @@ void switch_slb(struct task_struct *tsk, + static inline void patch_slb_encoding(unsigned int *insn_addr, + unsigned int immed) + { +- /* Assume the instruction had a "0" immediate value, just +- * "or" in the new value +- */ +- *insn_addr |= immed; ++ *insn_addr = (*insn_addr & 0xffff0000) | immed; + flush_icache_range((unsigned long)insn_addr, 4+ + (unsigned long)insn_addr); + } + ++void slb_set_size(u16 size) ++{ ++ extern unsigned int *slb_compare_rr_to_size; ++ ++ if (mmu_slb_size == size) ++ return; ++ ++ mmu_slb_size = size; ++ patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size); ++} ++ + void slb_initialize(void) + { + unsigned long linear_llp, vmalloc_llp, io_llp; +--- a/arch/powerpc/platforms/pseries/reconfig.c ++++ b/arch/powerpc/platforms/pseries/reconfig.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + + +@@ -439,9 +440,15 @@ static int do_update_property(char *buf, + if (!newprop) + return -ENOMEM; + ++ if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) ++ slb_set_size(*(int *)value); ++ + oldprop = of_find_property(np, name,NULL); +- if (!oldprop) ++ if (!oldprop) { ++ if (strlen(name)) ++ return prom_add_property(np, newprop); + return -ENODEV; ++ } + + rc = prom_update_property(np, newprop, oldprop); + if (rc) diff --git a/queue-2.6.30/series b/queue-2.6.30/series index 09be7d6a7a3..1eb2805757c 100644 --- a/queue-2.6.30/series +++ b/queue-2.6.30/series @@ -21,3 +21,4 @@ v4l-em28xx-set-up-tda9887_conf-in-em28xx_card_setup.patch virtio_blk-don-t-bounce-highmem-requests.patch libata-fix-off-by-one-error-in-ata_tf_read_block.patch pci-unhide-the-smbus-on-the-compaq-evo-d510-usdt.patch +powerpc-pseries-fix-to-handle-slb-resize-across-migration.patch