diff options
Diffstat (limited to 'arch/ppc64/mm')
-rw-r--r-- | arch/ppc64/mm/hash_native.c | 13 | ||||
-rw-r--r-- | arch/ppc64/mm/hash_utils.c | 36 | ||||
-rw-r--r-- | arch/ppc64/mm/tlb.c | 23 |
3 files changed, 32 insertions, 40 deletions
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index bfd385b7713..174d14576c2 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c @@ -335,10 +335,9 @@ static void native_hpte_clear(void) local_irq_restore(flags); } -static void native_flush_hash_range(unsigned long context, - unsigned long number, int local) +static void native_flush_hash_range(unsigned long number, int local) { - unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn; + unsigned long va, vpn, hash, secondary, slot, flags, avpn; int i, j; hpte_t *hptep; unsigned long hpte_v; @@ -349,13 +348,7 @@ static void native_flush_hash_range(unsigned long context, j = 0; for (i = 0; i < number; i++) { - if (batch->addr[i] < KERNELBASE) - vsid = get_vsid(context, batch->addr[i]); - else - vsid = get_kernel_vsid(batch->addr[i]); - - va = (vsid << 28) | (batch->addr[i] & 0x0fffffff); - batch->vaddr[j] = va; + va = batch->vaddr[j]; if (large) vpn = va >> HPAGE_SHIFT; else diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 09475c8edf7..83507438d6a 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c @@ -90,7 +90,6 @@ static inline void loop_forever(void) ; } -#ifdef CONFIG_PPC_MULTIPLATFORM static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long mode, int large) { @@ -111,7 +110,7 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long vpn, hash, hpteg; unsigned long vsid = get_kernel_vsid(addr); unsigned long va = (vsid << 28) | (addr & 0xfffffff); - int ret; + int ret = -1; if (large) vpn = va >> HPAGE_SHIFT; @@ -129,16 +128,25 @@ static inline void create_pte_mapping(unsigned long start, unsigned long end, hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); +#ifdef CONFIG_PPC_ISERIES + if (systemcfg->platform & PLATFORM_ISERIES_LPAR) + ret = iSeries_hpte_bolt_or_insert(hpteg, va, + virt_to_abs(addr) >> PAGE_SHIFT, + vflags, tmp_mode); + else +#endif #ifdef CONFIG_PPC_PSERIES if (systemcfg->platform & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); else -#endif /* CONFIG_PPC_PSERIES */ +#endif +#ifdef CONFIG_PPC_MULTIPLATFORM ret = native_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); +#endif if (ret == -1) { ppc64_terminate_msg(0x20, "create_pte_mapping"); @@ -261,7 +269,6 @@ void __init htab_initialize(void) } #undef KB #undef MB -#endif /* CONFIG_PPC_MULTIPLATFORM */ /* * Called by asm hashtable.S for doing lazy icache flush @@ -355,18 +362,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) return ret; } -void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, - int local) +void flush_hash_page(unsigned long va, pte_t pte, int local) { - unsigned long vsid, vpn, va, hash, secondary, slot; + unsigned long vpn, hash, secondary, slot; unsigned long huge = pte_huge(pte); - if (ea < KERNELBASE) - vsid = get_vsid(context, ea); - else - vsid = get_kernel_vsid(ea); - - va = (vsid << 28) | (ea & 0x0fffffff); if (huge) vpn = va >> HPAGE_SHIFT; else @@ -381,17 +381,17 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, ppc_md.hpte_invalidate(slot, va, huge, local); } -void flush_hash_range(unsigned long context, unsigned long number, int local) +void flush_hash_range(unsigned long number, int local) { if (ppc_md.flush_hash_range) { - ppc_md.flush_hash_range(context, number, local); + ppc_md.flush_hash_range(number, local); } else { int i; - struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + struct ppc64_tlb_batch *batch = + &__get_cpu_var(ppc64_tlb_batch); for (i = 0; i < number; i++) - flush_hash_page(context, batch->addr[i], batch->pte[i], - local); + flush_hash_page(batch->vaddr[i], batch->pte[i], local); } } diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index 21fbffb23a4..09ab81a10f4 100644 --- a/arch/ppc64/mm/tlb.c +++ b/arch/ppc64/mm/tlb.c @@ -128,12 +128,10 @@ void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) void hpte_update(struct mm_struct *mm, unsigned long addr, unsigned long pte, int wrprot) { - int i; - unsigned long context = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); + unsigned long vsid; + int i; - if (REGION_ID(addr) == USER_REGION_ID) - context = mm->context.id; i = batch->index; /* @@ -143,19 +141,21 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, * up scanning and resetting referenced bits then our batch context * will change mid stream. */ - if (i != 0 && (context != batch->context || - batch->large != pte_huge(pte))) { + if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) { flush_tlb_pending(); i = 0; } - if (i == 0) { - batch->context = context; batch->mm = mm; batch->large = pte_huge(pte); } + if (addr < KERNELBASE) { + vsid = get_vsid(mm->context.id, addr); + WARN_ON(vsid == 0); + } else + vsid = get_kernel_vsid(addr); + batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff); batch->pte[i] = __pte(pte); - batch->addr[i] = addr; batch->index = ++i; if (i >= PPC64_TLB_BATCH_NR) flush_tlb_pending(); @@ -177,10 +177,9 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) local = 1; if (i == 1) - flush_hash_page(batch->context, batch->addr[0], batch->pte[0], - local); + flush_hash_page(batch->vaddr[0], batch->pte[0], local); else - flush_hash_range(batch->context, i, local); + flush_hash_range(i, local); batch->index = 0; put_cpu(); } |