diff options
| -rw-r--r-- | arch/powerpc/include/asm/machdep.h | 6 | ||||
| -rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 19 | ||||
| -rw-r--r-- | arch/powerpc/mm/pgtable_64.c | 24 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 20 |
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 | ||
| 415 | static void native_hugepage_invalidate(struct mm_struct *mm, | 415 | static 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 | ||
| 434 | static void pSeries_lpar_hugepage_invalidate(struct mm_struct *mm, | 434 | static 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) |
