• Gerald Schaefer's avatar
    s390/mm: fix dynamic pagetable upgrade for hugetlbfs · 4b7d98f1
    Gerald Schaefer authored
    commit 5f490a52 upstream.
    
    Commit ee71d16d ("s390/mm: make TASK_SIZE independent from the number
    of page table levels") changed the logic of TASK_SIZE and also removed the
    arch_mmap_check() implementation for s390. This combination has a subtle
    effect on how get_unmapped_area() for hugetlbfs pages works. It is now
    possible that a user process establishes a hugetlbfs mapping at an address
    above 4 TB, without triggering a dynamic pagetable upgrade from 3 to 4
    levels.
    
    This is because hugetlbfs mappings will not use mm->get_unmapped_area, but
    rather file->f_op->get_unmapped_area, which currently is the generic
    implementation of hugetlb_get_unmapped_area() that does not know about s390
    dynamic pagetable upgrades, but with the new definition of TASK_SIZE, it
    will now allow mappings above 4 TB.
    
    Subsequent access to such a mapped address above 4 TB will result in a page
    fault loop, because the CPU cannot translate such a large address with 3
    pagetable levels. The fault handler will try to map in a hugepage at the
    address, but due to the folded pagetable logic it will end up with creating
    entries in the 3 level pagetable, possibly overwriting existing mappings,
    and then it all repeats when the access is retried.
    
    Apart from the page fault loop, this can have various nasty effects, e.g.
    kernel panic from one of the BUG_ON() checks in memory management code,
    or even data loss if an existing mapping gets overwritten.
    
    Fix this by implementing HAVE_ARCH_HUGETLB_UNMAPPED_AREA support for s390,
    providing an s390 version for hugetlb_get_unmapped_area() with pagetable
    upgrade support similar to arch_get_unmapped_area(), which will then be
    used instead of the generic version.
    
    Fixes: ee71d16d ("s390/mm: make TASK_SIZE independent from the number of page table levels")
    Cc: <stable@vger.kernel.org> # 4.12+
    Signed-off-by: default avatarGerald Schaefer <gerald.schaefer@de.ibm.com>
    Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    4b7d98f1
hugetlbpage.c 10.1 KB