* Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
* lock.
*/
-void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number,
- int local)
+void pSeries_lpar_flush_hash_range(unsigned long number, int local)
{
int i;
unsigned long flags = 0;
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
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);
if (lock_tlbie)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
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;
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
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
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);
}
}
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;
/*
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
*/
- if (unlikely(i != 0 && context != batch->context)) {
+ if (unlikely(i != 0 && mm != batch->mm)) {
flush_tlb_pending();
i = 0;
}
-
- if (i == 0) {
- batch->context = context;
+ if (i == 0)
batch->mm = mm;
- }
+ 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();
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();
}
unsigned long vflags,
unsigned long rflags);
long (*hpte_remove)(unsigned long hpte_group);
- void (*flush_hash_range)(unsigned long context,
- unsigned long number,
- int local);
+ void (*flush_hash_range)(unsigned long number, int local);
+
/* special for kexec, to be called in real mode, linar mapping is
* destroyed as well */
void (*hpte_clear_all)(void);
struct mm_struct;
struct ppc64_tlb_batch {
unsigned long index;
- unsigned long context;
struct mm_struct *mm;
pte_t pte[PPC64_TLB_BATCH_NR];
- unsigned long addr[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR];
};
DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
#define flush_tlb_kernel_range(start, end) flush_tlb_pending()
#define flush_tlb_pgtables(mm, start, end) do { } while (0)
-extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte,
- int local);
-void flush_hash_range(unsigned long context, unsigned long number, int local);
+extern void flush_hash_page(unsigned long va, pte_t pte, int local);
+void flush_hash_range(unsigned long number, int local);
#endif /* _PPC64_TLBFLUSH_H */