[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240710234222.2333120-16-jthoughton@google.com>
Date: Wed, 10 Jul 2024 23:42:19 +0000
From: James Houghton <jthoughton@...gle.com>
To: Paolo Bonzini <pbonzini@...hat.com>
Cc: Marc Zyngier <maz@...nel.org>, Oliver Upton <oliver.upton@...ux.dev>,
James Morse <james.morse@....com>, Suzuki K Poulose <suzuki.poulose@....com>,
Zenghui Yu <yuzenghui@...wei.com>, Sean Christopherson <seanjc@...gle.com>, Shuah Khan <shuah@...nel.org>,
Peter Xu <peterx@...hat.org>, Axel Rasmussen <axelrasmussen@...gle.com>,
David Matlack <dmatlack@...gle.com>, James Houghton <jthoughton@...gle.com>, kvm@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org, kvmarm@...ts.linux.dev
Subject: [RFC PATCH 15/18] KVM: guest_memfd: Add KVM Userfault support
We now have to pass our struct kvm into __kvm_gmem_get_pfn to know if a
gfn is userfault-enabled or not.
For faults on userfault-enabled gfns, indicate this to the caller by
setting *pfn to KVM_PFN_ERR_USERFAULT. Architectures may use this to
know to return a userfault to userspace, though they should be careful
to set a value for *pfn before calling (e.g. KVM_PFN_ERR_FAULT).
While we're at it, set *pfn to KVM_PFN_ERR_HWPOISON for accesses to
poisoned gfns.
Signed-off-by: James Houghton <jthoughton@...gle.com>
---
virt/kvm/guest_memfd.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 9148b9679bb1..ba7a981e3396 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -542,8 +542,9 @@ void kvm_gmem_unbind(struct kvm_memory_slot *slot)
fput(file);
}
-static int __kvm_gmem_get_pfn(struct file *file, struct kvm_memory_slot *slot,
- gfn_t gfn, kvm_pfn_t *pfn, int *max_order, bool prepare)
+static int __kvm_gmem_get_pfn(struct kvm *kvm, struct file *file,
+ struct kvm_memory_slot *slot, gfn_t gfn, kvm_pfn_t *pfn,
+ int *max_order, bool prepare)
{
pgoff_t index = gfn - slot->base_gfn + slot->gmem.pgoff;
struct kvm_gmem *gmem = file->private_data;
@@ -551,6 +552,11 @@ static int __kvm_gmem_get_pfn(struct file *file, struct kvm_memory_slot *slot,
struct page *page;
int r;
+ if (gfn_has_userfault(kvm, gfn)) {
+ *pfn = KVM_PFN_ERR_USERFAULT;
+ return -EFAULT;
+ }
+
if (file != slot->gmem.file) {
WARN_ON_ONCE(slot->gmem.file);
return -EFAULT;
@@ -567,6 +573,7 @@ static int __kvm_gmem_get_pfn(struct file *file, struct kvm_memory_slot *slot,
return PTR_ERR(folio);
if (folio_test_hwpoison(folio)) {
+ *pfn = KVM_PFN_ERR_HWPOISON;
folio_unlock(folio);
folio_put(folio);
return -EHWPOISON;
@@ -594,7 +601,7 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
if (!file)
return -EFAULT;
- r = __kvm_gmem_get_pfn(file, slot, gfn, pfn, max_order, true);
+ r = __kvm_gmem_get_pfn(kvm, file, slot, gfn, pfn, max_order, true);
fput(file);
return r;
}
@@ -634,7 +641,8 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long
break;
}
- ret = __kvm_gmem_get_pfn(file, slot, gfn, &pfn, &max_order, false);
+ ret = __kvm_gmem_get_pfn(kvm, file, slot, gfn, &pfn,
+ &max_order, false);
if (ret)
break;
--
2.45.2.993.g49e7a77208-goog
Powered by blists - more mailing lists