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

