[PATCH RFC v2] KVM: pfncache: Check gpc->active before sanity checking GPA and HVA

"syzbot" <[email protected]> Wed, 29 Jul 2026 14:55:57 +0000 (UTC)
Newsgroups dev.linux.lists.syzbot
Message-ID <[email protected]>
When attempting to refresh a gfn_to_pfn_cache (gpc) that has never been
activated, KVM triggers a sanity-check warning in __kvm_gpc_refresh(). This
occurs because an inactive cache naturally has both its GPA and HVA
initialized to error values, which violates the condition that exactly one
of them must be valid.

This can be triggered via the KVM_XEN_HVM_EVTCHN_SEND ioctl. If the guest
has not yet set up the shared info page, the shinfo_cache is inactive.
Attempting to deliver the event returns -EWOULDBLOCK, prompting KVM to
attempt a refresh of the cache, leading to the warning:

------------[ cut here ]------------
kvm_is_error_gpa(gpa) == kvm_is_error_hva(uhva)
WARNING: arch/x86/kvm/../../../virt/kvm/pfncache.c:267 at
__kvm_gpc_refresh+0x1510/0x1710 virt/kvm/pfncache.c:267
...
Call Trace:
 <TASK>
 kvm_gpc_refresh+0xe1/0x110 virt/kvm/pfncache.c:382
 kvm_xen_set_evtchn+0x14f/0x220 arch/x86/kvm/xen.c:1945
 kvm_xen_hvm_evtchn_send+0x120/0x1e0 arch/x86/kvm/xen.c:2036
 kvm_arch_vm_ioctl+0xfad/0x1a10 arch/x86/kvm/x86.c:7523
 kvm_vm_ioctl+0x8f7/0xd30 virt/kvm/kvm_main.c:5381
...

The warning can also be triggered via vcpu_info_cache if an event is sent
while the cache is inactive, causing the vCPU to attempt a refresh when
injecting pending events.

Fix this by moving the check for an inactive cache to kvm_gpc_refresh(),
before calling __kvm_gpc_refresh(). It is completely safe to check
gpc->active under gpc->refresh_lock because all modifications to
gpc->active are fully serialized by gpc->refresh_lock. Bailing out early
also avoids the overhead of unnecessarily acquiring and releasing the lock
(which disables and re-enables interrupts) for a cache that cannot be
refreshed.

Fixes: 721f5b0dda78 ("KVM: pfncache: allow a cache to be activated with a fixed (userspace) HVA")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=cde12433b6c56f55d9ed
Link: https://syzkaller.appspot.com/ai_job?id=06c5ed03-3710-4a03-8db9-c370eb80da49
To: <[email protected]>
To: "Paolo Bonzini" <[email protected]>
To: "Paul Durrant" <[email protected]>
Cc: <[email protected]>

---
v2:
- Move the `gpc->active` check from `__kvm_gpc_refresh()` to `kvm_gpc_refresh()`.

v1:
https://lore.kernel.org/all/[email protected]/T/
---
diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
index 728d2c1b4..aac85a140 100644
--- a/virt/kvm/pfncache.c
+++ b/virt/kvm/pfncache.c
@@ -271,11 +271,6 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l
 
 	write_lock_irq(&gpc->lock);
 
-	if (!gpc->active) {
-		ret = -EINVAL;
-		goto out_unlock;
-	}
-
 	old_pfn = gpc->pfn;
 	old_khva = (void *)PAGE_ALIGN_DOWN((uintptr_t)gpc->khva);
 	old_uhva = PAGE_ALIGN_DOWN(gpc->uhva);
@@ -369,6 +364,9 @@ int kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, unsigned long len)
 
 	guard(mutex)(&gpc->refresh_lock);
 
+	if (!gpc->active)
+		return -EINVAL;
+
 	if (!kvm_gpc_is_valid_len(gpc->gpa, gpc->uhva, len))
 		return -EINVAL;
 


base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
-- 
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).

See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at [email protected].