Revision 9a291a7c9428155e8e623e4a3989f8be47134df5 authored by James Morse on 02 June 2017, 21:46:46 UTC, committed by Linus Torvalds on 02 June 2017, 22:07:38 UTC
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 x86
too, so I think this should be a fix.  This doesn't apply earlier than
stable's v4.11.1 due to all sorts of cleanup.

[james.morse@arm.com: add vm_fault_to_errno() call to faultin_page()]
suggested.
  Link: http://lkml.kernel.org/r/20170525171035.16359-1-james.morse@arm.com
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/20170524160900.28786-1-james.morse@arm.com
Signed-off-by: James Morse <james.morse@arm.com>
Acked-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Cc: <stable@vger.kernel.org>	[4.11.1+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 70feee0
History
File Mode Size
blocklayout
filelayout
flexfilelayout
Kconfig -rw-r--r-- 5.8 KB
Makefile -rw-r--r-- 1.2 KB
cache_lib.c -rw-r--r-- 3.8 KB
cache_lib.h -rw-r--r-- 1016 bytes
callback.c -rw-r--r-- 10.9 KB
callback.h -rw-r--r-- 5.1 KB
callback_proc.c -rw-r--r-- 16.7 KB
callback_xdr.c -rw-r--r-- 25.7 KB
client.c -rw-r--r-- 33.3 KB
delegation.c -rw-r--r-- 29.0 KB
delegation.h -rw-r--r-- 2.9 KB
dir.c -rw-r--r-- 63.5 KB
direct.c -rw-r--r-- 28.6 KB
dns_resolve.c -rw-r--r-- 10.0 KB
dns_resolve.h -rw-r--r-- 812 bytes
file.c -rw-r--r-- 22.0 KB
fscache-index.c -rw-r--r-- 9.3 KB
fscache.c -rw-r--r-- 11.9 KB
fscache.h -rw-r--r-- 6.5 KB
getroot.c -rw-r--r-- 3.5 KB
inode.c -rw-r--r-- 58.5 KB
internal.h -rw-r--r-- 24.0 KB
io.c -rw-r--r-- 4.0 KB
iostat.h -rw-r--r-- 1.8 KB
mount_clnt.c -rw-r--r-- 12.2 KB
namespace.c -rw-r--r-- 6.9 KB
netns.h -rw-r--r-- 903 bytes
nfs.h -rw-r--r-- 993 bytes
nfs2super.c -rw-r--r-- 569 bytes
nfs2xdr.c -rw-r--r-- 25.9 KB
nfs3_fs.h -rw-r--r-- 1.1 KB
nfs3acl.c -rw-r--r-- 8.0 KB
nfs3client.c -rw-r--r-- 3.1 KB
nfs3proc.c -rw-r--r-- 25.2 KB
nfs3super.c -rw-r--r-- 649 bytes
nfs3xdr.c -rw-r--r-- 54.9 KB
nfs42.h -rw-r--r-- 804 bytes
nfs42proc.c -rw-r--r-- 14.4 KB
nfs42xdr.c -rw-r--r-- 15.7 KB
nfs4_fs.h -rw-r--r-- 18.6 KB
nfs4client.c -rw-r--r-- 31.1 KB
nfs4file.c -rw-r--r-- 6.2 KB
nfs4getroot.c -rw-r--r-- 975 bytes
nfs4idmap.c -rw-r--r-- 19.2 KB
nfs4idmap.h -rw-r--r-- 2.7 KB
nfs4namespace.c -rw-r--r-- 12.7 KB
nfs4proc.c -rw-r--r-- 251.5 KB
nfs4renewd.c -rw-r--r-- 4.8 KB
nfs4session.c -rw-r--r-- 16.6 KB
nfs4session.h -rw-r--r-- 5.1 KB
nfs4state.c -rw-r--r-- 65.9 KB
nfs4super.c -rw-r--r-- 8.7 KB
nfs4sysctl.c -rw-r--r-- 1.4 KB
nfs4trace.c -rw-r--r-- 435 bytes
nfs4trace.h -rw-r--r-- 42.9 KB
nfs4xdr.c -rw-r--r-- 197.0 KB
nfsroot.c -rw-r--r-- 9.5 KB
nfstrace.c -rw-r--r-- 292 bytes
nfstrace.h -rw-r--r-- 18.0 KB
pagelist.c -rw-r--r-- 33.9 KB
pnfs.c -rw-r--r-- 73.0 KB
pnfs.h -rw-r--r-- 23.0 KB
pnfs_dev.c -rw-r--r-- 9.6 KB
pnfs_nfs.c -rw-r--r-- 24.1 KB
proc.c -rw-r--r-- 18.8 KB
read.c -rw-r--r-- 11.5 KB
super.c -rw-r--r-- 74.9 KB
symlink.c -rw-r--r-- 1.8 KB
sysctl.c -rw-r--r-- 1.3 KB
unlink.c -rw-r--r-- 13.5 KB
write.c -rw-r--r-- 54.9 KB

back to top