* [PATCH] KVM: x86/xen: Fix data race on poll event channel
@ 2026-08-24 11:43 Chengfeng Ye
2026-08-25 18:21 ` David Woodhouse
0 siblings, 1 reply; 2+ messages in thread
From: Chengfeng Ye @ 2026-08-24 11:43 UTC (permalink / raw)
To: dwmw2, paul, seanjc, pbonzini
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, boris.ostrovsky, kvm,
linux-kernel, stable, Chengfeng Ye
Use READ_ONCE() and WRITE_ONCE() for runtime accesses to poll_evtchn.
This marks the intentionally concurrent scalar accesses and prevents the
compiler from splitting, merging, or inventing accesses.
kvm_xen_schedop_poll() publishes the single port, or -1 for multiple
ports, before setting poll_mask and halting the vCPU. Event delivery can
call kvm_xen_check_poller() on another CPU while the vCPU thread publishes
that value or resets the field to zero after returning from
kvm_vcpu_halt():
vCPU thread event delivery thread
----------- ---------------------
poll_evtchn = port
set_bit(poll_mask)
kvm_vcpu_halt()
poll_evtchn = READ
poll_evtchn = 0
clear_bit(poll_mask)
The plain read and writes therefore race. KCSAN reported:
BUG: KCSAN: data-race in kvm_xen_hypercall / kvm_xen_set_evtchn_fast
read to 0xffff888112f55af0 of 4 bytes by task 98:
kvm_xen_set_evtchn_fast+0x204/0x7c0
kvm_xen_hvm_evtchn_send+0xab/0x100
kvm_arch_vm_ioctl+0xb31/0xd90
kvm_vm_ioctl+0xf42/0x16c0
write to 0xffff888112f55af0 of 4 bytes by task 96:
kvm_xen_hypercall+0xd8d/0xf50
kvm_emulate_hypercall+0x157/0x1d0
vmx_handle_exit+0x40f/0xae0
vcpu_run+0x137f/0x27d0
kvm_arch_vcpu_ioctl_run+0x5a5/0x970
The field is an aligned int on x86. Access annotations preserve the
existing matching, callback, and poll-mask control flow while making the
single-copy access requirement explicit.
Fixes: 1a65105a5aba ("KVM: x86/xen: handle PV spinlocks slowpath")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
arch/x86/kvm/xen.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index eae17141773a..cd15d2379616 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -1536,9 +1536,9 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
}
if (sched_poll.nr_ports == 1)
- vcpu->arch.xen.poll_evtchn = port;
+ WRITE_ONCE(vcpu->arch.xen.poll_evtchn, port);
else
- vcpu->arch.xen.poll_evtchn = -1;
+ WRITE_ONCE(vcpu->arch.xen.poll_evtchn, -1);
set_bit(vcpu->vcpu_idx, vcpu->kvm->arch.xen.poll_mask);
@@ -1557,7 +1557,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
}
- vcpu->arch.xen.poll_evtchn = 0;
+ WRITE_ONCE(vcpu->arch.xen.poll_evtchn, 0);
*r = 0;
out:
/* Really, this is only needed in case of timeout */
@@ -1773,7 +1773,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
{
- int poll_evtchn = vcpu->arch.xen.poll_evtchn;
+ int poll_evtchn = READ_ONCE(vcpu->arch.xen.poll_evtchn);
if ((poll_evtchn == port || poll_evtchn == -1) &&
test_and_clear_bit(vcpu->vcpu_idx, vcpu->kvm->arch.xen.poll_mask)) {
base-commit: 388b607d107c07aaade04c7f22f344cab6bdccd3
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] KVM: x86/xen: Fix data race on poll event channel
2026-08-24 11:43 [PATCH] KVM: x86/xen: Fix data race on poll event channel Chengfeng Ye
@ 2026-08-25 18:21 ` David Woodhouse
0 siblings, 0 replies; 2+ messages in thread
From: David Woodhouse @ 2026-08-25 18:21 UTC (permalink / raw)
To: Chengfeng Ye, paul, seanjc, pbonzini
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, boris.ostrovsky, kvm,
linux-kernel, stable
[-- Attachment #1: Type: text/plain, Size: 2261 bytes --]
On Mon, 2026-08-24 at 19:43 +0800, Chengfeng Ye wrote:
> Use READ_ONCE() and WRITE_ONCE() for runtime accesses to poll_evtchn.
> This marks the intentionally concurrent scalar accesses and prevents the
> compiler from splitting, merging, or inventing accesses.
>
> kvm_xen_schedop_poll() publishes the single port, or -1 for multiple
> ports, before setting poll_mask and halting the vCPU. Event delivery can
> call kvm_xen_check_poller() on another CPU while the vCPU thread publishes
> that value or resets the field to zero after returning from
> kvm_vcpu_halt():
>
> vCPU thread event delivery thread
> ----------- ---------------------
> poll_evtchn = port
> set_bit(poll_mask)
> kvm_vcpu_halt()
> poll_evtchn = READ
> poll_evtchn = 0
> clear_bit(poll_mask)
>
> The plain read and writes therefore race. KCSAN reported:
>
> BUG: KCSAN: data-race in kvm_xen_hypercall / kvm_xen_set_evtchn_fast
>
> read to 0xffff888112f55af0 of 4 bytes by task 98:
> kvm_xen_set_evtchn_fast+0x204/0x7c0
> kvm_xen_hvm_evtchn_send+0xab/0x100
> kvm_arch_vm_ioctl+0xb31/0xd90
> kvm_vm_ioctl+0xf42/0x16c0
>
> write to 0xffff888112f55af0 of 4 bytes by task 96:
> kvm_xen_hypercall+0xd8d/0xf50
> kvm_emulate_hypercall+0x157/0x1d0
> vmx_handle_exit+0x40f/0xae0
> vcpu_run+0x137f/0x27d0
> kvm_arch_vcpu_ioctl_run+0x5a5/0x970
>
> The field is an aligned int on x86. Access annotations preserve the
> existing matching, callback, and poll-mask control flow while making the
> single-copy access requirement explicit.
>
> Fixes: 1a65105a5aba ("KVM: x86/xen: handle PV spinlocks slowpath")
> Cc: stable@vger.kernel.org
> Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
LGTM, thanks. I don't think we need Cc:stable for a KCSAN splat, and
possibly not even the Fixes: tag. I'll roll it into my series at
https://lore.kernel.org/all/20260811094829.98794-1-dwmw2@infradead.org/
now sitting at
https://git.infradead.org/?p=users/dwmw2/linux.git;a=shortlog;h=refs/heads/xen-v3
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 6179 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-25 18:22 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24 11:43 [PATCH] KVM: x86/xen: Fix data race on poll event channel Chengfeng Ye
2026-08-25 18:21 ` David Woodhouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox