From: David Woodhouse kvm_xen_schedop_poll() validates port numbers against kvm_max_evtchn_port() and then calls wait_pending_event() which reads the shinfo mode again to select the bitmap layout. Latch kvm_xen_has_64bit_shinfo() once and pass it to both max_evtchn_port() and wait_pending_event(). As with the previous fix to kvm_xen_set_evtchn_fast(), this is harmless in practice for the same reasons: the inconsistency can only corrupt fields in the guest's own shared_info page, and the same corruption can occur anyway if the mode changes immediately after the latch. Fixes: d518b9d0fc80 ("KVM: x86/xen: handle PV spinlocks slowpath") Assisted-by: Kiro:claude-opus-4.6-1m Signed-off-by: David Woodhouse --- arch/x86/kvm/xen.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 9edfdc585337..e249a1b1d446 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1436,8 +1436,8 @@ static inline int kvm_max_evtchn_port(struct kvm *kvm) return max_evtchn_port(kvm_xen_has_64bit_shinfo(kvm)); } -static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, - evtchn_port_t *ports) +static bool wait_pending_event(struct kvm_vcpu *vcpu, bool has_64bit_shinfo, + int nr_ports, evtchn_port_t *ports) { struct kvm *kvm = vcpu->kvm; struct gfn_to_pfn_cache *gpc = &kvm->arch.xen.shinfo_cache; @@ -1452,7 +1452,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, goto out_rcu; ret = false; - if (kvm_xen_has_64bit_shinfo(kvm)) { + if (has_64bit_shinfo) { struct shared_info *shinfo = gpc->khva; pending_bits = (unsigned long *)&shinfo->evtchn_pending; } else { @@ -1477,6 +1477,7 @@ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool is_64bit, u64 param, u64 *r) { + bool has_64bit_shinfo = kvm_xen_has_64bit_shinfo(vcpu->kvm); struct sched_poll sched_poll; evtchn_port_t port, *ports; struct x86_exception e; @@ -1535,7 +1536,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool is_64bit, } for (i = 0; i < sched_poll.nr_ports; i++) { - if (ports[i] >= kvm_max_evtchn_port(vcpu->kvm)) { + if (ports[i] >= max_evtchn_port(has_64bit_shinfo)) { *r = -EINVAL; goto out; } @@ -1548,7 +1549,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool is_64bit, set_bit(vcpu->vcpu_idx, vcpu->kvm->arch.xen.poll_mask); - if (!wait_pending_event(vcpu, sched_poll.nr_ports, ports)) { + if (!wait_pending_event(vcpu, has_64bit_shinfo, sched_poll.nr_ports, ports)) { kvm_set_mp_state(vcpu, KVM_MP_STATE_HALTED); if (sched_poll.timeout) -- 2.55.0