diff options
-rw-r--r-- | arch/ppc64/kernel/pSeries_lpar.c | 5 | ||||
-rw-r--r-- | arch/ppc64/mm/hash_native.c | 13 | ||||
-rw-r--r-- | arch/ppc64/mm/hash_utils.c | 21 | ||||
-rw-r--r-- | arch/ppc64/mm/tlb.c | 25 | ||||
-rw-r--r-- | include/asm-ppc64/machdep.h | 5 | ||||
-rw-r--r-- | include/asm-ppc64/tlbflush.h | 7 |
6 files changed, 28 insertions, 48 deletions
diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index a6de83f2078f..268d8362dde7 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c | |||
@@ -486,8 +486,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, | |||
486 | * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie | 486 | * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie |
487 | * lock. | 487 | * lock. |
488 | */ | 488 | */ |
489 | void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number, | 489 | void pSeries_lpar_flush_hash_range(unsigned long number, int local) |
490 | int local) | ||
491 | { | 490 | { |
492 | int i; | 491 | int i; |
493 | unsigned long flags = 0; | 492 | unsigned long flags = 0; |
@@ -498,7 +497,7 @@ void pSeries_lpar_flush_hash_range(unsigned long context, unsigned long number, | |||
498 | spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); | 497 | spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); |
499 | 498 | ||
500 | for (i = 0; i < number; i++) | 499 | for (i = 0; i < number; i++) |
501 | flush_hash_page(context, batch->addr[i], batch->pte[i], local); | 500 | flush_hash_page(batch->vaddr[i], batch->pte[i], local); |
502 | 501 | ||
503 | if (lock_tlbie) | 502 | if (lock_tlbie) |
504 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); | 503 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 7626bb59954d..29b074505d3e 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) | |||
335 | local_irq_restore(flags); | 335 | local_irq_restore(flags); |
336 | } | 336 | } |
337 | 337 | ||
338 | static void native_flush_hash_range(unsigned long context, | 338 | static void native_flush_hash_range(unsigned long number, int local) |
339 | unsigned long number, int local) | ||
340 | { | 339 | { |
341 | unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn; | 340 | unsigned long va, vpn, hash, secondary, slot, flags, avpn; |
342 | int i, j; | 341 | int i, j; |
343 | hpte_t *hptep; | 342 | hpte_t *hptep; |
344 | unsigned long hpte_v; | 343 | unsigned long hpte_v; |
@@ -351,13 +350,7 @@ static void native_flush_hash_range(unsigned long context, | |||
351 | 350 | ||
352 | j = 0; | 351 | j = 0; |
353 | for (i = 0; i < number; i++) { | 352 | for (i = 0; i < number; i++) { |
354 | if (batch->addr[i] < KERNELBASE) | 353 | va = batch->vaddr[j]; |
355 | vsid = get_vsid(context, batch->addr[i]); | ||
356 | else | ||
357 | vsid = get_kernel_vsid(batch->addr[i]); | ||
358 | |||
359 | va = (vsid << 28) | (batch->addr[i] & 0x0fffffff); | ||
360 | batch->vaddr[j] = va; | ||
361 | if (large) | 354 | if (large) |
362 | vpn = va >> HPAGE_SHIFT; | 355 | vpn = va >> HPAGE_SHIFT; |
363 | else | 356 | else |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 09475c8edf7c..36cf474b3d36 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
@@ -355,18 +355,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
355 | return ret; | 355 | return ret; |
356 | } | 356 | } |
357 | 357 | ||
358 | void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | 358 | void flush_hash_page(unsigned long va, pte_t pte, int local) |
359 | int local) | ||
360 | { | 359 | { |
361 | unsigned long vsid, vpn, va, hash, secondary, slot; | 360 | unsigned long vpn, hash, secondary, slot; |
362 | unsigned long huge = pte_huge(pte); | 361 | unsigned long huge = pte_huge(pte); |
363 | 362 | ||
364 | if (ea < KERNELBASE) | ||
365 | vsid = get_vsid(context, ea); | ||
366 | else | ||
367 | vsid = get_kernel_vsid(ea); | ||
368 | |||
369 | va = (vsid << 28) | (ea & 0x0fffffff); | ||
370 | if (huge) | 363 | if (huge) |
371 | vpn = va >> HPAGE_SHIFT; | 364 | vpn = va >> HPAGE_SHIFT; |
372 | else | 365 | else |
@@ -381,17 +374,17 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | |||
381 | ppc_md.hpte_invalidate(slot, va, huge, local); | 374 | ppc_md.hpte_invalidate(slot, va, huge, local); |
382 | } | 375 | } |
383 | 376 | ||
384 | void flush_hash_range(unsigned long context, unsigned long number, int local) | 377 | void flush_hash_range(unsigned long number, int local) |
385 | { | 378 | { |
386 | if (ppc_md.flush_hash_range) { | 379 | if (ppc_md.flush_hash_range) { |
387 | ppc_md.flush_hash_range(context, number, local); | 380 | ppc_md.flush_hash_range(number, local); |
388 | } else { | 381 | } else { |
389 | int i; | 382 | int i; |
390 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 383 | struct ppc64_tlb_batch *batch = |
384 | &__get_cpu_var(ppc64_tlb_batch); | ||
391 | 385 | ||
392 | for (i = 0; i < number; i++) | 386 | for (i = 0; i < number; i++) |
393 | flush_hash_page(context, batch->addr[i], batch->pte[i], | 387 | flush_hash_page(batch->vaddr[i], batch->pte[i], local); |
394 | local); | ||
395 | } | 388 | } |
396 | } | 389 | } |
397 | 390 | ||
diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index d8a6593a13f0..31afd95bf870 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) | |||
128 | void hpte_update(struct mm_struct *mm, unsigned long addr, | 128 | void hpte_update(struct mm_struct *mm, unsigned long addr, |
129 | unsigned long pte, int wrprot) | 129 | unsigned long pte, int wrprot) |
130 | { | 130 | { |
131 | int i; | ||
132 | unsigned long context = 0; | ||
133 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 131 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); |
132 | unsigned long vsid; | ||
133 | int i; | ||
134 | 134 | ||
135 | if (REGION_ID(addr) == USER_REGION_ID) | ||
136 | context = mm->context.id; | ||
137 | i = batch->index; | 135 | i = batch->index; |
138 | 136 | ||
139 | /* | 137 | /* |
@@ -143,17 +141,19 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, | |||
143 | * up scanning and resetting referenced bits then our batch context | 141 | * up scanning and resetting referenced bits then our batch context |
144 | * will change mid stream. | 142 | * will change mid stream. |
145 | */ | 143 | */ |
146 | if (unlikely(i != 0 && context != batch->context)) { | 144 | if (unlikely(i != 0 && mm != batch->mm)) { |
147 | flush_tlb_pending(); | 145 | flush_tlb_pending(); |
148 | i = 0; | 146 | i = 0; |
149 | } | 147 | } |
150 | 148 | if (i == 0) | |
151 | if (i == 0) { | ||
152 | batch->context = context; | ||
153 | batch->mm = mm; | 149 | batch->mm = mm; |
154 | } | 150 | if (addr < KERNELBASE) { |
151 | vsid = get_vsid(mm->context.id, addr); | ||
152 | WARN_ON(vsid == 0); | ||
153 | } else | ||
154 | vsid = get_kernel_vsid(addr); | ||
155 | batch->vaddr[i] = (vsid << 28 ) | (addr & 0x0fffffff); | ||
155 | batch->pte[i] = __pte(pte); | 156 | batch->pte[i] = __pte(pte); |
156 | batch->addr[i] = addr; | ||
157 | batch->index = ++i; | 157 | batch->index = ++i; |
158 | if (i >= PPC64_TLB_BATCH_NR) | 158 | if (i >= PPC64_TLB_BATCH_NR) |
159 | flush_tlb_pending(); | 159 | flush_tlb_pending(); |
@@ -175,10 +175,9 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) | |||
175 | local = 1; | 175 | local = 1; |
176 | 176 | ||
177 | if (i == 1) | 177 | if (i == 1) |
178 | flush_hash_page(batch->context, batch->addr[0], batch->pte[0], | 178 | flush_hash_page(batch->vaddr[0], batch->pte[0], local); |
179 | local); | ||
180 | else | 179 | else |
181 | flush_hash_range(batch->context, i, local); | 180 | flush_hash_range(i, local); |
182 | batch->index = 0; | 181 | batch->index = 0; |
183 | put_cpu(); | 182 | put_cpu(); |
184 | } | 183 | } |
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index 8027160ec96d..d35d9d3e44cf 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h | |||
@@ -56,9 +56,8 @@ struct machdep_calls { | |||
56 | unsigned long vflags, | 56 | unsigned long vflags, |
57 | unsigned long rflags); | 57 | unsigned long rflags); |
58 | long (*hpte_remove)(unsigned long hpte_group); | 58 | long (*hpte_remove)(unsigned long hpte_group); |
59 | void (*flush_hash_range)(unsigned long context, | 59 | void (*flush_hash_range)(unsigned long number, int local); |
60 | unsigned long number, | 60 | |
61 | int local); | ||
62 | /* special for kexec, to be called in real mode, linar mapping is | 61 | /* special for kexec, to be called in real mode, linar mapping is |
63 | * destroyed as well */ | 62 | * destroyed as well */ |
64 | void (*hpte_clear_all)(void); | 63 | void (*hpte_clear_all)(void); |
diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h index 45411a67e082..800bc0010cfb 100644 --- a/include/asm-ppc64/tlbflush.h +++ b/include/asm-ppc64/tlbflush.h | |||
@@ -20,10 +20,8 @@ | |||
20 | struct mm_struct; | 20 | struct mm_struct; |
21 | struct ppc64_tlb_batch { | 21 | struct ppc64_tlb_batch { |
22 | unsigned long index; | 22 | unsigned long index; |
23 | unsigned long context; | ||
24 | struct mm_struct *mm; | 23 | struct mm_struct *mm; |
25 | pte_t pte[PPC64_TLB_BATCH_NR]; | 24 | pte_t pte[PPC64_TLB_BATCH_NR]; |
26 | unsigned long addr[PPC64_TLB_BATCH_NR]; | ||
27 | unsigned long vaddr[PPC64_TLB_BATCH_NR]; | 25 | unsigned long vaddr[PPC64_TLB_BATCH_NR]; |
28 | }; | 26 | }; |
29 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | 27 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); |
@@ -47,8 +45,7 @@ static inline void flush_tlb_pending(void) | |||
47 | #define flush_tlb_kernel_range(start, end) flush_tlb_pending() | 45 | #define flush_tlb_kernel_range(start, end) flush_tlb_pending() |
48 | #define flush_tlb_pgtables(mm, start, end) do { } while (0) | 46 | #define flush_tlb_pgtables(mm, start, end) do { } while (0) |
49 | 47 | ||
50 | extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | 48 | extern void flush_hash_page(unsigned long va, pte_t pte, int local); |
51 | int local); | 49 | void flush_hash_range(unsigned long number, int local); |
52 | void flush_hash_range(unsigned long context, unsigned long number, int local); | ||
53 | 50 | ||
54 | #endif /* _PPC64_TLBFLUSH_H */ | 51 | #endif /* _PPC64_TLBFLUSH_H */ |