summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorR Sharada <sharada@in.ibm.com>2005-06-25 14:58:08 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 16:24:51 -0700
commitf4c82d5132b0592f5d6befc5b652cbd4b08f12ff (patch)
tree3889ea8eeb4dfa6c995b6dc93574d24c238a6deb /arch
parent70765aa4bdb8862a49fcf5b28f3deaf561cf5ae7 (diff)
downloadlinux-f4c82d5132b0592f5d6befc5b652cbd4b08f12ff.tar.gz
linux-f4c82d5132b0592f5d6befc5b652cbd4b08f12ff.tar.bz2
linux-f4c82d5132b0592f5d6befc5b652cbd4b08f12ff.zip
[PATCH] ppc64 kexec: native hash clear
Add code to clear the hash table and invalidate the tlb for native (SMP, non-LPAR) mode. Supports 16M and 4k pages. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: R Sharada <sharada@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/ppc64/mm/hash_native.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
index 52b6b9305341..4fec05817d66 100644
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -304,6 +304,50 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
local_irq_restore(flags);
}
+/*
+ * clear all mappings on kexec. All cpus are in real mode (or they will
+ * be when they isi), and we are the only one left. We rely on our kernel
+ * mapping being 0xC0's and the hardware ignoring those two real bits.
+ *
+ * TODO: add batching support when enabled. remember, no dynamic memory here,
+ * athough there is the control page available...
+ */
+static void native_hpte_clear(void)
+{
+ unsigned long slot, slots, flags;
+ HPTE *hptep = htab_address;
+ Hpte_dword0 dw0;
+ unsigned long pteg_count;
+
+ pteg_count = htab_hash_mask + 1;
+
+ local_irq_save(flags);
+
+ /* we take the tlbie lock and hold it. Some hardware will
+ * deadlock if we try to tlbie from two processors at once.
+ */
+ spin_lock(&native_tlbie_lock);
+
+ slots = pteg_count * HPTES_PER_GROUP;
+
+ for (slot = 0; slot < slots; slot++, hptep++) {
+ /*
+ * we could lock the pte here, but we are the only cpu
+ * running, right? and for crash dump, we probably
+ * don't want to wait for a maybe bad cpu.
+ */
+ dw0 = hptep->dw0.dw0;
+
+ if (dw0.v) {
+ hptep->dw0.dword0 = 0;
+ tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l);
+ }
+ }
+
+ spin_unlock(&native_tlbie_lock);
+ local_irq_restore(flags);
+}
+
static void native_flush_hash_range(unsigned long context,
unsigned long number, int local)
{
@@ -415,7 +459,8 @@ void hpte_init_native(void)
ppc_md.hpte_updatepp = native_hpte_updatepp;
ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
ppc_md.hpte_insert = native_hpte_insert;
- ppc_md.hpte_remove = native_hpte_remove;
+ ppc_md.hpte_remove = native_hpte_remove;
+ ppc_md.hpte_clear_all = native_hpte_clear;
if (tlb_batching_enabled())
ppc_md.flush_hash_range = native_flush_hash_range;
htab_finish_init();