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


Reply via email to