powerpc/mm/hash64: Zero PGD pages on allocation

"Linux Kernel Mailing List" <[email protected]> Wed, 14 Feb 2018 18:19:53 +0000 (UTC)
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/fc5c2f4a55a2c258e12013cdf287cf266dbcd2a7
Commit:     fc5c2f4a55a2c258e12013cdf287cf266dbcd2a7
Parent:     ff31e105464d8c8c973019646827020aed9c2d9f
Refname:    refs/heads/master
Author:     Aneesh Kumar K.V <[email protected]>
AuthorDate: Tue Feb 13 16:39:33 2018 +0530
Committer:  Michael Ellerman <[email protected]>
CommitDate: Tue Feb 13 22:37:48 2018 +1100

    powerpc/mm/hash64: Zero PGD pages on allocation
    
    On powerpc we allocate page table pages from slab caches of different
    sizes. Currently we have a constructor that zeroes out the objects when
    we allocate them for the first time.
    
    We expect the objects to be zeroed out when we free the the object
    back to slab cache. This happens in the unmap path. For hugetlb pages
    we call huge_pte_get_and_clear() to do that.
    
    With the current configuration of page table size, both PUD and PGD
    level tables are allocated from the same slab cache. At the PUD level,
    we use the second half of the table to store the slot information. But
    we never clear that when unmapping.
    
    When such a freed object is then allocated for a PGD page, the second
    half of the page table page will not be zeroed as expected. This
    results in a kernel crash.
    
    Fix it by always clearing PGD pages when they're allocated.
    
    Signed-off-by: Aneesh Kumar K.V <[email protected]>
    [mpe: Change log wording and formatting, add whitespace]
    Signed-off-by: Michael Ellerman <[email protected]>
---
 arch/powerpc/include/asm/book3s/64/pgalloc.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h
index 827ebce4df90..4746bc68d446 100644
--- a/arch/powerpc/include/asm/book3s/64/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h
@@ -73,10 +73,16 @@ static inline void radix__pgd_free(struct mm_struct *mm, pgd_t *pgd)
 
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
+	pgd_t *pgd;
+
 	if (radix_enabled())
 		return radix__pgd_alloc(mm);
-	return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
-		pgtable_gfp_flags(mm, GFP_KERNEL));
+
+	pgd = kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
+			       pgtable_gfp_flags(mm, GFP_KERNEL));
+	memset(pgd, 0, PGD_TABLE_SIZE);
+
+	return pgd;
 }
 
 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html