aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/hash_native_64.c3
-rw-r--r--arch/powerpc/mm/hash_utils_64.c106
-rw-r--r--arch/powerpc/mm/mmu_context_64.c2
3 files changed, 46 insertions, 65 deletions
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index a0f3cbd00d3..c90f124f3c7 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void)
}
#endif
-void hpte_init_native(void)
+void __init hpte_init_native(void)
{
ppc_md.hpte_invalidate = native_hpte_invalidate;
ppc_md.hpte_updatepp = native_hpte_updatepp;
@@ -530,5 +530,4 @@ void hpte_init_native(void)
ppc_md.hpte_clear_all = native_hpte_clear;
if (tlb_batching_enabled())
ppc_md.flush_hash_range = native_flush_hash_range;
- htab_finish_init();
}
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index d03fd2b4445..3cc6d68f711 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -167,34 +167,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
hash = hpt_hash(va, shift);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
- /* The crap below can be cleaned once ppd_md.probe() can
- * set up the hash callbacks, thus we can just used the
- * normal insert callback here.
- */
-#ifdef CONFIG_PPC_ISERIES
- if (machine_is(iseries))
- ret = iSeries_hpte_insert(hpteg, va,
- paddr,
- tmp_mode,
- HPTE_V_BOLTED,
- psize);
- else
-#endif
-#ifdef CONFIG_PPC_PSERIES
- if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR))
- ret = pSeries_lpar_hpte_insert(hpteg, va,
- paddr,
- tmp_mode,
- HPTE_V_BOLTED,
- psize);
- else
-#endif
-#ifdef CONFIG_PPC_MULTIPLATFORM
- ret = native_hpte_insert(hpteg, va,
- paddr,
- tmp_mode, HPTE_V_BOLTED,
- psize);
-#endif
+ DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert);
+
+ BUG_ON(!ppc_md.hpte_insert);
+ ret = ppc_md.hpte_insert(hpteg, va, paddr,
+ tmp_mode, HPTE_V_BOLTED, psize);
+
if (ret < 0)
break;
}
@@ -413,6 +391,41 @@ void create_section_mapping(unsigned long start, unsigned long end)
}
#endif /* CONFIG_MEMORY_HOTPLUG */
+static inline void make_bl(unsigned int *insn_addr, void *func)
+{
+ unsigned long funcp = *((unsigned long *)func);
+ int offset = funcp - (unsigned long)insn_addr;
+
+ *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
+ flush_icache_range((unsigned long)insn_addr, 4+
+ (unsigned long)insn_addr);
+}
+
+static void __init htab_finish_init(void)
+{
+ extern unsigned int *htab_call_hpte_insert1;
+ extern unsigned int *htab_call_hpte_insert2;
+ extern unsigned int *htab_call_hpte_remove;
+ extern unsigned int *htab_call_hpte_updatepp;
+
+#ifdef CONFIG_PPC_64K_PAGES
+ extern unsigned int *ht64_call_hpte_insert1;
+ extern unsigned int *ht64_call_hpte_insert2;
+ extern unsigned int *ht64_call_hpte_remove;
+ extern unsigned int *ht64_call_hpte_updatepp;
+
+ make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
+ make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
+ make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
+ make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
+#endif /* CONFIG_PPC_64K_PAGES */
+
+ make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
+ make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
+ make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
+ make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+}
+
void __init htab_initialize(void)
{
unsigned long table;
@@ -525,6 +538,8 @@ void __init htab_initialize(void)
mmu_linear_psize));
}
+ htab_finish_init();
+
DBG(" <- htab_initialize()\n");
}
#undef KB
@@ -787,16 +802,6 @@ void flush_hash_range(unsigned long number, int local)
}
}
-static inline void make_bl(unsigned int *insn_addr, void *func)
-{
- unsigned long funcp = *((unsigned long *)func);
- int offset = funcp - (unsigned long)insn_addr;
-
- *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
- flush_icache_range((unsigned long)insn_addr, 4+
- (unsigned long)insn_addr);
-}
-
/*
* low_hash_fault is called when we the low level hash code failed
* to instert a PTE due to an hypervisor error
@@ -815,28 +820,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address)
}
bad_page_fault(regs, address, SIGBUS);
}
-
-void __init htab_finish_init(void)
-{
- extern unsigned int *htab_call_hpte_insert1;
- extern unsigned int *htab_call_hpte_insert2;
- extern unsigned int *htab_call_hpte_remove;
- extern unsigned int *htab_call_hpte_updatepp;
-
-#ifdef CONFIG_PPC_64K_PAGES
- extern unsigned int *ht64_call_hpte_insert1;
- extern unsigned int *ht64_call_hpte_insert2;
- extern unsigned int *ht64_call_hpte_remove;
- extern unsigned int *ht64_call_hpte_updatepp;
-
- make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
- make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
- make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
- make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
-#endif /* CONFIG_PPC_64K_PAGES */
-
- make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
- make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
- make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
- make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
-}
diff --git a/arch/powerpc/mm/mmu_context_64.c b/arch/powerpc/mm/mmu_context_64.c
index 65d18dca266..e2051efa09c 100644
--- a/arch/powerpc/mm/mmu_context_64.c
+++ b/arch/powerpc/mm/mmu_context_64.c
@@ -44,7 +44,9 @@ again:
return err;
if (index > MAX_CONTEXT) {
+ spin_lock(&mmu_context_lock);
idr_remove(&mmu_context_idr, index);
+ spin_unlock(&mmu_context_lock);
return -ENOMEM;
}