Re: [PATCH RFC] KVM: pfncache: Check gpc->active before sanity checking GPA and HVA
Aleksandr Nogikh <[email protected]> Wed, 29 Jul 2026 15:21:35 +0200
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <CANp29Y5FVs_k4fjVWxFNUcAkX-xvg3ZJR1eysYttfe1A-qReBQ@mail.gmail.com> |
Based off the discussion in https://lore.kernel.org/all/[email protected]/T/ Moving the `!gpc->active` check into `__kvm_gpc_refresh()` is too late because `kvm_gpc_refresh()` calls `kvm_gpc_is_valid_len(gpc->gpa, gpc->uhva, len)` *before* calling `__kvm_gpc_refresh()`. On an inactive cache (`gpc->gpa =3D=3D INVALID_GPA` and `gpc->uhva =3D=3D KVM_HVA_ERR_BAD`), `kvm_gpc_is_valid_len()` will still end up running `offset_in_page(uhva)` on an invalid HVA. `if (!gpc->active)` needs to be checked at the start of `kvm_gpc_refresh()` right after acquiring `gpc->refresh_lock`, before `kvm_gpc_is_valid_len()` is called. On Wed, Jul 29, 2026 at 3:18=E2=80=AFPM 'syzbot' via syzkaller-upstream-moderation <[email protected]> wrote: > > 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(). Th= is > occurs because an inactive cache naturally has both its GPA and HVA > initialized to error values, which violates the condition that exactly on= e > 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) =3D=3D 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 the very beginning = of > __kvm_gpc_refresh(), before the WARN_ON_ONCE and before acquiring the > gpc->lock. It is completely safe to check gpc->active before acquiring > gpc->lock because all modifications to gpc->active are fully serialized b= y > gpc->refresh_lock, which is already held and asserted at the start of the > function. Bailing out early also avoids the overhead of unnecessarily > acquiring and releasing the lock (which disables and re-enables interrupt= s) > 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=3Dcde12433b6c56f55d9ed > Link: https://syzkaller.appspot.com/ai_job?id=3D4e819403-979c-4f19-96ab-2= 8961c06eab0 > To: <[email protected]> > To: "Paolo Bonzini" <[email protected]> > To: "Paul Durrant" <[email protected]> > Cc: <[email protected]> > > --- > diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c > index 728d2c1b4..fcfd5555b 100644 > --- a/virt/kvm/pfncache.c > +++ b/virt/kvm/pfncache.c > @@ -263,19 +263,17 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cach= e *gpc, gpa_t gpa, unsigned l > void *old_khva; > int ret; > > + lockdep_assert_held(&gpc->refresh_lock); > + > + if (!gpc->active) > + return -EINVAL; > + > /* Either gpa or uhva must be valid, but not both */ > if (WARN_ON_ONCE(kvm_is_error_gpa(gpa) =3D=3D kvm_is_error_hva(uh= va))) > return -EINVAL; > > - lockdep_assert_held(&gpc->refresh_lock); > - > write_lock_irq(&gpc->lock); > > - if (!gpc->active) { > - ret =3D -EINVAL; > - goto out_unlock; > - } > - > old_pfn =3D gpc->pfn; > old_khva =3D (void *)PAGE_ALIGN_DOWN((uintptr_t)gpc->khva); > old_uhva =3D PAGE_ALIGN_DOWN(gpc->uhva); > > > 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]. > > -- > You received this message because you are subscribed to the Google Groups= "syzkaller-upstream-moderation" group. > To unsubscribe from this group and stop receiving emails from it, send an= email to [email protected]. > To view this discussion visit https://groups.google.com/d/msgid/syzkaller= -upstream-moderation/a144cc7e-406a-4896-9299-9f425c722100%40mail.kernel.org= .