aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/hugetlbpage.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-06-08 13:19:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-06-08 13:19:40 -0400
commit987aec39a74373c55c3bedd5c3c83896d78fd0a2 (patch)
tree66aba6d4f166f269be95fe4d267d57efe533aefd /arch/powerpc/mm/hugetlbpage.c
parent303cda0ea7c1c33701812ccb80d37083a4093c7c (diff)
parentd4a4f75cd8f29cd9464a5a32e9224a91571d6649 (diff)
Merge 4.1-rc7 into driver-core-next
We want the fixes in this branch as well for testing and merge resolution. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/mm/hugetlbpage.c')
-rw-r--r--arch/powerpc/mm/hugetlbpage.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index d230158c9770..6fd3fdeb1953 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -689,27 +689,34 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
689struct page * 689struct page *
690follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) 690follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
691{ 691{
692 pte_t *ptep; 692 pte_t *ptep, pte;
693 struct page *page;
694 unsigned shift; 693 unsigned shift;
695 unsigned long mask, flags; 694 unsigned long mask, flags;
695 struct page *page = ERR_PTR(-EINVAL);
696
697 local_irq_save(flags);
698 ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift);
699 if (!ptep)
700 goto no_page;
701 pte = READ_ONCE(*ptep);
696 /* 702 /*
703 * Verify it is a huge page else bail.
697 * Transparent hugepages are handled by generic code. We can skip them 704 * Transparent hugepages are handled by generic code. We can skip them
698 * here. 705 * here.
699 */ 706 */
700 local_irq_save(flags); 707 if (!shift || pmd_trans_huge(__pmd(pte_val(pte))))
701 ptep = find_linux_pte_or_hugepte(mm->pgd, address, &shift); 708 goto no_page;
702 709
703 /* Verify it is a huge page else bail. */ 710 if (!pte_present(pte)) {
704 if (!ptep || !shift || pmd_trans_huge(*(pmd_t *)ptep)) { 711 page = NULL;
705 local_irq_restore(flags); 712 goto no_page;
706 return ERR_PTR(-EINVAL);
707 } 713 }
708 mask = (1UL << shift) - 1; 714 mask = (1UL << shift) - 1;
709 page = pte_page(*ptep); 715 page = pte_page(pte);
710 if (page) 716 if (page)
711 page += (address & mask) / PAGE_SIZE; 717 page += (address & mask) / PAGE_SIZE;
712 718
719no_page:
713 local_irq_restore(flags); 720 local_irq_restore(flags);
714 return page; 721 return page;
715} 722}