From: David Woodhouse <dwmw@amazon.co.uk>
Sashiko analysis and torture testing of the upcoming conversion of the
gfn_to_pfn_cache from rwlock to atomic SRCU¹ highlighted a pre-existing
problem: refreshing a cache can fail while a memslot is briefly marked
KVM_MEMSLOT_INVALID during a memslot update. The Xen event channel and
timer delivery paths silently dropped events when they hit that window.
Return -EAGAIN from __kvm_gpc_refresh() to distinguish the transient
case from a genuinely unbacked GFN, and add a retry loop for the common
case callers which can just wait for the memslot update to complete, as
well as dealing with the corner cases which can't:
- The Xen attribute ioctls wait, so userspace never sees the
transient state.
- Timer delivery leaves ->arch.xen.timer_pending set and retries from
kvm_xen_inject_timer_irqs() on the next vCPU entry.
- The guest's own EVTCHNOP_send hypercall runs under vcpu_run's
kvm->srcu read section — the very reader the memslot update is
waiting for — so it cannot wait. Leave the hypercall uncompleted
without advancing RIP, so the guest re-executes it. This is how
Xen itself restarts preempted hypercalls.
Patches 6-9 are pulled forward from the SRCU series because they stand
alone:
- Three from Sean², extracting vcpu_info delivery into a separate
helper and taking the shared_info and vcpu_info pages out of dirty
tracking. Rebased: his series had first converted the GPC locks to
read_trylock(), which this one doesn't carry.
- Requesting the guest TLB flush from record_steal_time() itself, as
a standalone cleanup in preparation for converting that to GPC.
The final patch adds a selftest racing a guest EVTCHNOP_send loop
against a tight memslot delete/recreate loop. Tested with that and
xen_shinfo_test; an instrumented run showed 10 of its 4000 sends
hitting the update window and re-executing.
Based on kvm/next (d4b7fb647204).
https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/share/gpc-eagain
¹ https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/gpc-srcu-v2
² https://lore.kernel.org/kvm/20260529165114.748639-1-seanjc@google.com/
David Woodhouse (7):
KVM: pfncache: Return -EAGAIN for a lookup which hits an invalid memslot
KVM: pfncache: Add a 'wait' argument to the refresh and activate functions
KVM: x86/xen: Wait out memslot updates in the Xen attribute ioctls
KVM: x86/xen: Don't lose the timer event when delivery fails transiently
KVM: x86/xen: Retry event channel delivery which races a memslot update
KVM: x86: Request the guest TLB flush from record_steal_time()
KVM: selftests: Add Xen evtchn vs memslot-update race test
Sean Christopherson (3):
KVM: x86/xen: Extract delivery of event to vCPU into a separate helper
KVM: x86/xen: Explicitly tag "shared info" page as never being dirty tracked
KVM: x86/xen: Don't dirty track "vCPU info" page
arch/x86/kvm/irq.c | 2 +-
arch/x86/kvm/msrs.c | 2 +-
arch/x86/kvm/x86.c | 28 +-
arch/x86/kvm/xen.c | 312 +++++++++++-------
arch/x86/kvm/xen.h | 4 +-
include/linux/kvm_host.h | 30 +-
include/linux/kvm_types.h | 1 +
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/x86/xen_evtchn_memslot_race_test.c | 178 ++++++++++
.../selftests/kvm/x86/xen_shinfo_test.c | 11 +-
virt/kvm/pfncache.c | 136 ++++++--
11 files changed, 532 insertions(+), 173 deletions(-)
create mode 100644 tools/testing/selftests/kvm/x86/xen_evtchn_memslot_race_test.c
base-commit: d4b7fb647204f0c81dfeae2d1a708e4d858e0c94
--
2.43.0