From: David Woodhouse <[email protected]> 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 <[email protected]> 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

