[PATCH v3 01/11] KVM: pfncache: Return -EAGAIN for a lookup which hits an invalid memslot

From: David Woodhouse

Date: Fri Oct 16 2026 - 12:01:01 EST


From: David Woodhouse <dwmw@xxxxxxxxxxxx>

A memslot being deleted or moved is present in the active array but
flagged KVM_MEMSLOT_INVALID — a transient state which exists only
within a single KVM_SET_USER_MEMORY_REGION call and is announced by
a further generation bump when it resolves. gfn_to_hva_memslot()
collapses that case and a genuinely unbacked gfn into one error, and
the pfncache refresh reported both as -EFAULT.

Distinguish them: return -EAGAIN when the slot exists but is
invalid, mirroring what RET_PF_RETRY does for ordinary guest faults
on an invalid slot. Existing users don't *need* to change; most
will simply resolve again at the next refresh. But the distinct
error code *allows* a caller to retry.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Assisted-by: LLM
---
virt/kvm/pfncache.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
index 3659686b97c2..17aaebd76db8 100644
--- a/virt/kvm/pfncache.c
+++ b/virt/kvm/pfncache.c
@@ -304,7 +304,22 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l
gpc->uhva = gfn_to_hva_memslot(gpc->memslot, gfn);

if (kvm_is_error_hva(gpc->uhva)) {
- ret = -EFAULT;
+ /*
+ * A slot being deleted or moved is present
+ * but flagged invalid; the lookup failure is
+ * transient, resolved when the update
+ * completes (or reverts) and announced by a
+ * new memslot generation. Distinguish that
+ * from a genuinely unbacked gfn so that the
+ * caller may retry rather than report an
+ * error, as RET_PF_RETRY does for ordinary
+ * guest faults.
+ */
+ if (gpc->memslot &&
+ (gpc->memslot->flags & KVM_MEMSLOT_INVALID))
+ ret = -EAGAIN;
+ else
+ ret = -EFAULT;
goto out;
}

--
2.43.0