[PATCH RFC v2 32/50] KVM: guest_memfd: Refactor error handling in kvm_gmem_fault_user_mapping

From: Ackerley Tng via B4 Relay

Date: Thu Oct 22 2026 - 19:39:12 EST


From: Ackerley Tng <ackerleytng@xxxxxxxxxx>

Track the status of kvm_gmem_fault_user_mapping() using an explicit error
code rather than encoding errors into the folio pointer.

This moves away from relying on the folio pointer holding error states,
such as synthesizing ERR_PTR(-EACCES) when memory is not shared only to
extract PTR_ERR afterwards, and prepares kvm_gmem_fault_user_mapping() for
PFN mode in the next commit, where no folio is returned on success.

Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
virt/kvm/guest_memfd.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 3d89bc76f3867..8588912cb0b82 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -562,24 +562,28 @@ static bool kvm_gmem_supports_mmap(struct inode *inode)
static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf)
{
struct inode *inode = file_inode(vmf->vma->vm_file);
- struct folio *folio;
vm_fault_t ret = VM_FAULT_LOCKED;
+ struct folio *folio = NULL;
+ int r = 0;

if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode))
return VM_FAULT_SIGBUS;

filemap_invalidate_lock_shared(inode->i_mapping);
- if (kvm_gmem_is_shared_mem(inode, vmf->pgoff))
+ if (!kvm_gmem_is_shared_mem(inode, vmf->pgoff)) {
+ r = -EACCES;
+ } else {
folio = kvm_gmem_get_folio(inode, vmf->pgoff);
- else
- folio = ERR_PTR(-EACCES);
+ if (IS_ERR(folio))
+ r = PTR_ERR(folio);
+ }
filemap_invalidate_unlock_shared(inode->i_mapping);

- if (IS_ERR(folio)) {
- if (PTR_ERR(folio) == -EAGAIN)
+ if (r) {
+ if (r == -EAGAIN)
return VM_FAULT_RETRY;

- return vmf_error(PTR_ERR(folio));
+ return vmf_error(r);
}

if (WARN_ON_ONCE(folio_test_large(folio))) {

--
2.56.0.257.gf7497c7d27-goog