• James Morse's avatar
    mm/hugetlb: report -EHWPOISON not -EFAULT when FOLL_HWPOISON is specified · 9a291a7c
    James Morse authored
    KVM uses get_user_pages() to resolve its stage2 faults.  KVM sets the
    FOLL_HWPOISON flag causing faultin_page() to return -EHWPOISON when it
    finds a VM_FAULT_HWPOISON.  KVM handles these hwpoison pages as a
    special case.  (check_user_page_hwpoison())
    
    When huge pages are involved, this doesn't work so well.
    get_user_pages() calls follow_hugetlb_page(), which stops early if it
    receives VM_FAULT_HWPOISON from hugetlb_fault(), eventually returning
    -EFAULT to the caller.  The step to map this to -EHWPOISON based on the
    FOLL_ flags is missing.  The hwpoison special case is skipped, and
    -EFAULT is returned to user-space, causing Qemu or kvmtool to exit.
    
    Instead, move this VM_FAULT_ to errno mapping code into a header file
    and use it from faultin_page() and follow_hugetlb_page().
    
    With this, KVM works as expected.
    
    This isn't a problem for arm64 today as we haven't enabled
    MEMORY_FAILURE, but I can't see any reason this doesn't happen on ...
    9a291a7c
mm.h 79.7 KB