[POWERPC] Fix boot failure on POWER6
authorPaul Mackerras <paulus@samba.org>
Tue, 15 Jan 2008 06:29:33 +0000 (17:29 +1100)
committerPaul Mackerras <paulus@samba.org>
Tue, 15 Jan 2008 06:30:58 +0000 (17:30 +1100)
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 <paulus@samba.org>
arch/powerpc/mm/slb.c
arch/powerpc/platforms/pseries/lpar.c
include/asm-powerpc/mmu-hash64.h

index a282bc212e809d76ec1a6b0b134864dca05ea876..50d7372bc2ce4f01cb9e78abe41148f5dc2ecf23 100644 (file)
@@ -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
index 34317aa148a8368b8e0e154a461b101e5b2e2678..9a455d46379d525181a4278714e22304f72028db 100644 (file)
@@ -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
index 951e2487aa69019e80bd83b2d6ef8b12180afaf2..82328dec2b527d2ecdd05b0694ca2d8562c0558d 100644 (file)
@@ -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);