arm64: hugetlb: Handle swap entries in huge_pte_offset() for contiguous hugepages
authorPunit Agrawal <punit.agrawal@arm.com>
Tue, 22 Aug 2017 10:42:45 +0000 (11:42 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 22 Aug 2017 14:57:02 +0000 (15:57 +0100)
huge_pte_offset() was updated to correctly handle swap entries for
hugepages. With the addition of the size parameter, it is now possible
to disambiguate whether the request is for a regular hugepage or a
contiguous hugepage.

Fix huge_pte_offset() for contiguous hugepages by using the size to find
the correct page table entry.

Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Cc: David Woods <dwoods@mellanox.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/mm/hugetlbpage.c

index b82df85fe920e36e252d5abecd79d1d1d1387458..b91ec151e62c98286766f4b991ef18e21eab1f71 100644 (file)
@@ -221,19 +221,28 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
                return NULL;
 
        pud = pud_offset(pgd, addr);
-       if (pud_none(*pud))
+       if (sz != PUD_SIZE && pud_none(*pud))
                return NULL;
-       /* swap or huge page */
-       if (!pud_present(*pud) || pud_huge(*pud))
+       /* hugepage or swap? */
+       if (pud_huge(*pud) || !pud_present(*pud))
                return (pte_t *)pud;
        /* table; check the next level */
 
+       if (sz == CONT_PMD_SIZE)
+               addr &= CONT_PMD_MASK;
+
        pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd))
+       if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) &&
+           pmd_none(*pmd))
                return NULL;
-       if (!pmd_present(*pmd) || pmd_huge(*pmd))
+       if (pmd_huge(*pmd) || !pmd_present(*pmd))
                return (pte_t *)pmd;
 
+       if (sz == CONT_PTE_SIZE) {
+               pte_t *pte = pte_offset_kernel(pmd, (addr & CONT_PTE_MASK));
+               return pte;
+       }
+
        return NULL;
 }