summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/slb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-11 16:09:49 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-11 16:09:49 -0700
commit75ecb1a4d148b274aa9acd1d6ccaca0a4654784e (patch)
tree7fa39362bfb1a4dbd3f4227f98b85c2e5d36d398 /arch/powerpc/mm/slb.c
parent73819b2d26aeb7719bb501c0136687b89d5ac3ef (diff)
parentd1f5a77f2c9db5b8a565eabdf8b534b02e32cc44 (diff)
downloadtalos-op-linux-75ecb1a4d148b274aa9acd1d6ccaca0a4654784e.tar.gz
talos-op-linux-75ecb1a4d148b274aa9acd1d6ccaca0a4654784e.zip
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: [POWERPC] Fix size check for hugetlbfs [POWERPC] Fix initialization and usage of dma_mask [POWERPC] Fix more section mismatches in head_64.S [POWERPC] Revert "[POWERPC] Add 'mdio' to bus scan id list for platforms with QE UEC" [POWERPC] PS3: Update ps3_defconfig [POWERPC] PS3: Remove text saying PS3 support is incomplete [POWERPC] PS3: Fix storage probe logic [POWERPC] cell: Move SPU affinity init to spu_management_of_ops [POWERPC] Fix potential duplicate entry in SLB shadow buffer
Diffstat (limited to 'arch/powerpc/mm/slb.c')
-rw-r--r--arch/powerpc/mm/slb.c45
1 files changed, 16 insertions, 29 deletions
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index b0697017d0e8..a73d2d700973 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -69,20 +69,9 @@ static inline void slb_shadow_update(unsigned long ea,
smp_wmb();
}
-static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
- unsigned long entry)
+static inline void slb_shadow_clear(unsigned long entry)
{
- /*
- * Updating the shadow buffer before writing the SLB ensures
- * we don't get a stale entry here if we get preempted by PHYP
- * between these two statements.
- */
- slb_shadow_update(ea, flags, entry);
-
- asm volatile("slbmte %0,%1" :
- : "r" (mk_vsid_data(ea, flags)),
- "r" (mk_esid_data(ea, entry))
- : "memory" );
+ get_slb_shadow()->save_area[entry].esid = 0;
}
void slb_flush_and_rebolt(void)
@@ -100,11 +89,13 @@ void slb_flush_and_rebolt(void)
vflags = SLB_VSID_KERNEL | vmalloc_llp;
ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
- if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
+ if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) {
ksp_esid_data &= ~SLB_ESID_V;
-
- /* Only third entry (stack) may change here so only resave that */
- slb_shadow_update(get_paca()->kstack, lflags, 2);
+ slb_shadow_clear(2);
+ } else {
+ /* Update stack entry; others don't change */
+ slb_shadow_update(get_paca()->kstack, lflags, 2);
+ }
/* We need to do this all in asm, so we're sure we don't touch
* the stack between the slbia and rebolting it. */
@@ -235,16 +226,12 @@ void slb_initialize(void)
vflags = SLB_VSID_KERNEL | vmalloc_llp;
/* Invalidate the entire SLB (even slot 0) & all the ERATS */
- asm volatile("isync":::"memory");
- asm volatile("slbmte %0,%0"::"r" (0) : "memory");
- asm volatile("isync; slbia; isync":::"memory");
- create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
-
- create_shadowed_slbe(VMALLOC_START, vflags, 1);
-
- /* 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
- * one. */
- asm volatile("isync":::"memory");
+ slb_shadow_update(PAGE_OFFSET, lflags, 0);
+ asm volatile("isync; slbia; sync; slbmte %0,%1; isync" ::
+ "r" (get_slb_shadow()->save_area[0].vsid),
+ "r" (get_slb_shadow()->save_area[0].esid) : "memory");
+
+ slb_shadow_update(VMALLOC_START, vflags, 1);
+
+ slb_flush_and_rebolt();
}
OpenPOWER on IntegriCloud