aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/machdep.h6
-rw-r--r--arch/powerpc/mm/hash_native_64.c19
-rw-r--r--arch/powerpc/mm/pgtable_64.c24
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c20
4 files changed, 26 insertions, 43 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 44e90516519b..b125ceab149c 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -57,10 +57,10 @@ struct machdep_calls {
57 void (*hpte_removebolted)(unsigned long ea, 57 void (*hpte_removebolted)(unsigned long ea,
58 int psize, int ssize); 58 int psize, int ssize);
59 void (*flush_hash_range)(unsigned long number, int local); 59 void (*flush_hash_range)(unsigned long number, int local);
60 void (*hugepage_invalidate)(struct mm_struct *mm, 60 void (*hugepage_invalidate)(unsigned long vsid,
61 unsigned long addr,
61 unsigned char *hpte_slot_array, 62 unsigned char *hpte_slot_array,
62 unsigned long addr, int psize); 63 int psize, int ssize);
63
64 /* special for kexec, to be called in real mode, linear mapping is 64 /* special for kexec, to be called in real mode, linear mapping is
65 * destroyed as well */ 65 * destroyed as well */
66 void (*hpte_clear_all)(void); 66 void (*hpte_clear_all)(void);
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index cf1d325eae8b..fb89d7695a9a 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -412,18 +412,18 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
412 local_irq_restore(flags); 412 local_irq_restore(flags);
413} 413}
414 414
415static void native_hugepage_invalidate(struct mm_struct *mm, 415static void native_hugepage_invalidate(unsigned long vsid,
416 unsigned long addr,
416 unsigned char *hpte_slot_array, 417 unsigned char *hpte_slot_array,
417 unsigned long addr, int psize) 418 int psize, int ssize)
418{ 419{
419 int ssize = 0, i; 420 int i, lock_tlbie;
420 int lock_tlbie;
421 struct hash_pte *hptep; 421 struct hash_pte *hptep;
422 int actual_psize = MMU_PAGE_16M; 422 int actual_psize = MMU_PAGE_16M;
423 unsigned int max_hpte_count, valid; 423 unsigned int max_hpte_count, valid;
424 unsigned long flags, s_addr = addr; 424 unsigned long flags, s_addr = addr;
425 unsigned long hpte_v, want_v, shift; 425 unsigned long hpte_v, want_v, shift;
426 unsigned long hidx, vpn = 0, vsid, hash, slot; 426 unsigned long hidx, vpn = 0, hash, slot;
427 427
428 shift = mmu_psize_defs[psize].shift; 428 shift = mmu_psize_defs[psize].shift;
429 max_hpte_count = 1U << (PMD_SHIFT - shift); 429 max_hpte_count = 1U << (PMD_SHIFT - shift);
@@ -437,15 +437,6 @@ static void native_hugepage_invalidate(struct mm_struct *mm,
437 437
438 /* get the vpn */ 438 /* get the vpn */
439 addr = s_addr + (i * (1ul << shift)); 439 addr = s_addr + (i * (1ul << shift));
440 if (!is_kernel_addr(addr)) {
441 ssize = user_segment_size(addr);
442 vsid = get_vsid(mm->context.id, addr, ssize);
443 WARN_ON(vsid == 0);
444 } else {
445 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
446 ssize = mmu_kernel_ssize;
447 }
448
449 vpn = hpt_vpn(addr, vsid, ssize); 440 vpn = hpt_vpn(addr, vsid, ssize);
450 hash = hpt_hash(vpn, shift, ssize); 441 hash = hpt_hash(vpn, shift, ssize);
451 if (hidx & _PTEIDX_SECONDARY) 442 if (hidx & _PTEIDX_SECONDARY)
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 3b3c4d34c7a0..5039f3b04d6e 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -745,12 +745,21 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
745 if (!hpte_slot_array) 745 if (!hpte_slot_array)
746 return; 746 return;
747 747
748 /* get the base page size */ 748 /* get the base page size,vsid and segment size */
749 psize = get_slice_psize(mm, s_addr); 749 psize = get_slice_psize(mm, s_addr);
750 if (!is_kernel_addr(s_addr)) {
751 ssize = user_segment_size(s_addr);
752 vsid = get_vsid(mm->context.id, s_addr, ssize);
753 WARN_ON(vsid == 0);
754 } else {
755 vsid = get_kernel_vsid(s_addr, mmu_kernel_ssize);
756 ssize = mmu_kernel_ssize;
757 }
750 758
751 if (ppc_md.hugepage_invalidate) 759 if (ppc_md.hugepage_invalidate)
752 return ppc_md.hugepage_invalidate(mm, hpte_slot_array, 760 return ppc_md.hugepage_invalidate(vsid, s_addr,
753 s_addr, psize); 761 hpte_slot_array,
762 psize, ssize);
754 /* 763 /*
755 * No bluk hpte removal support, invalidate each entry 764 * No bluk hpte removal support, invalidate each entry
756 */ 765 */
@@ -768,15 +777,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
768 777
769 /* get the vpn */ 778 /* get the vpn */
770 addr = s_addr + (i * (1ul << shift)); 779 addr = s_addr + (i * (1ul << shift));
771 if (!is_kernel_addr(addr)) {
772 ssize = user_segment_size(addr);
773 vsid = get_vsid(mm->context.id, addr, ssize);
774 WARN_ON(vsid == 0);
775 } else {
776 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
777 ssize = mmu_kernel_ssize;
778 }
779
780 vpn = hpt_vpn(addr, vsid, ssize); 780 vpn = hpt_vpn(addr, vsid, ssize);
781 hash = hpt_hash(vpn, shift, ssize); 781 hash = hpt_hash(vpn, shift, ssize);
782 if (hidx & _PTEIDX_SECONDARY) 782 if (hidx & _PTEIDX_SECONDARY)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index fbfcef514aa7..34e64237fff9 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -431,16 +431,17 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
431 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); 431 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
432} 432}
433 433
434static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm, 434static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
435 unsigned char *hpte_slot_array, 435 unsigned long addr,
436 unsigned long addr, int psize) 436 unsigned char *hpte_slot_array,
437 int psize, int ssize)
437{ 438{
438 int ssize = 0, i, index = 0; 439 int i, index = 0;
439 unsigned long s_addr = addr; 440 unsigned long s_addr = addr;
440 unsigned int max_hpte_count, valid; 441 unsigned int max_hpte_count, valid;
441 unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH]; 442 unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH];
442 unsigned long slot_array[PPC64_HUGE_HPTE_BATCH]; 443 unsigned long slot_array[PPC64_HUGE_HPTE_BATCH];
443 unsigned long shift, hidx, vpn = 0, vsid, hash, slot; 444 unsigned long shift, hidx, vpn = 0, hash, slot;
444 445
445 shift = mmu_psize_defs[psize].shift; 446 shift = mmu_psize_defs[psize].shift;
446 max_hpte_count = 1U << (PMD_SHIFT - shift); 447 max_hpte_count = 1U << (PMD_SHIFT - shift);
@@ -453,15 +454,6 @@ static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm,
453 454
454 /* get the vpn */ 455 /* get the vpn */
455 addr = s_addr + (i * (1ul << shift)); 456 addr = s_addr + (i * (1ul << shift));
456 if (!is_kernel_addr(addr)) {
457 ssize = user_segment_size(addr);
458 vsid = get_vsid(mm->context.id, addr, ssize);
459 WARN_ON(vsid == 0);
460 } else {
461 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
462 ssize = mmu_kernel_ssize;
463 }
464
465 vpn = hpt_vpn(addr, vsid, ssize); 457 vpn = hpt_vpn(addr, vsid, ssize);
466 hash = hpt_hash(vpn, shift, ssize); 458 hash = hpt_hash(vpn, shift, ssize);
467 if (hidx & _PTEIDX_SECONDARY) 459 if (hidx & _PTEIDX_SECONDARY)