From 473980a99316c0e788bca50996375a2815124ce1 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 11 Jan 2008 14:02:47 +1100 Subject: [POWERPC] Fix CPU hotplug when using the SLB shadow buffer Before we register the SLB shadow buffer, we need to invalidate the entries in the buffer, otherwise we can end up stale entries from when we previously offlined the CPU. This does this invalidate as well as unregistering the buffer with PHYP before we offline the cpu. Tested and fixes crashes seen on 970MP (thanks to tonyb) and POWER5. Signed-off-by: Michael Neuling Signed-off-by: Paul Mackerras --- arch/powerpc/mm/slb.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/powerpc/mm') diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 27922dff8b9..a282bc212e8 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -82,6 +82,14 @@ static inline void slb_shadow_clear(unsigned long entry) get_slb_shadow()->save_area[entry].esid = 0; } +void slb_shadow_clear_all(void) +{ + int i; + + for (i = 0; i < SLB_NUM_BOLTED; i++) + slb_shadow_clear(i); +} + static inline void create_shadowed_slbe(unsigned long ea, int ssize, unsigned long flags, unsigned long entry) -- cgit v1.2.3-70-g09d2 From dfbe0d3b6be52596b5694b1bb75b19562e769021 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 15 Jan 2008 17:29:33 +1100 Subject: [POWERPC] Fix boot failure on POWER6 Commit 473980a99316c0e788bca50996375a2815124ce1 added a call to clear the SLB shadow buffer before registering it. Unfortunately this means that we clear out the entries that slb_initialize has previously set in there. On POWER6, the hypervisor uses the SLB shadow buffer when doing partition switches, and that means that after the next partition switch, each non-boot CPU has no SLB entries to map the kernel text and data, which causes it to crash. This fixes it by reverting most of 473980a9 and instead clearing the 3rd entry explicitly in slb_initialize. This fixes the problem that 473980a9 was trying to solve, but without breaking POWER6. Signed-off-by: Paul Mackerras --- arch/powerpc/mm/slb.c | 10 ++-------- arch/powerpc/platforms/pseries/lpar.c | 1 - include/asm-powerpc/mmu-hash64.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'arch/powerpc/mm') diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index a282bc212e8..50d7372bc2c 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -82,14 +82,6 @@ static inline void slb_shadow_clear(unsigned long entry) get_slb_shadow()->save_area[entry].esid = 0; } -void slb_shadow_clear_all(void) -{ - int i; - - for (i = 0; i < SLB_NUM_BOLTED; i++) - slb_shadow_clear(i); -} - static inline void create_shadowed_slbe(unsigned long ea, int ssize, unsigned long flags, unsigned long entry) @@ -300,6 +292,8 @@ void slb_initialize(void) create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1); + slb_shadow_clear(2); + /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes * elsewhere, we'll call _switch() which will bolt in the new diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 34317aa148a..9a455d46379 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -272,7 +272,6 @@ void vpa_init(int cpu) */ addr = __pa(&slb_shadow[cpu]); if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - slb_shadow_clear_all(); ret = register_slb_shadow(hwcpu, addr); if (ret) printk(KERN_ERR diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index 951e2487aa6..82328dec2b5 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h @@ -286,7 +286,6 @@ extern void hpte_init_iSeries(void); extern void hpte_init_beat(void); extern void hpte_init_beat_v3(void); -extern void slb_shadow_clear_all(void); extern void stabs_alloc(void); extern void slb_initialize(void); extern void slb_flush_and_rebolt(void); -- cgit v1.2.3-70-g09d2