summaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2008-01-11 14:02:47 +1100
committerPaul Mackerras <paulus@samba.org>2008-01-11 16:33:55 +1100
commit473980a99316c0e788bca50996375a2815124ce1 (patch)
tree5fb9d5de6ee75299b32de0e0b66f5a868864c38f /arch/powerpc
parent6f4347c969674ed45de7d08d4b26d6326a95b959 (diff)
[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 <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/mm/slb.c8
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c1
3 files changed, 11 insertions, 0 deletions
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 27922dff8b94..a282bc212e80 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)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index fc48b96c81bf..412e6b42986f 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -29,6 +29,7 @@
#include <asm/vdso_datapage.h>
#include <asm/pSeries_reconfig.h>
#include "xics.h"
+#include "plpar_wrappers.h"
/* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = {
@@ -58,6 +59,7 @@ static void pseries_mach_cpu_die(void)
local_irq_disable();
idle_task_exit();
xics_teardown_cpu(0);
+ unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
rtas_stop_self();
/* Should never get here... */
BUG();
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 9a455d46379d..34317aa148a8 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -272,6 +272,7 @@ 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