Re: [PATCH 2/3] KVM: x86: Fix a semi theoretical bug in kvm_arch_async_page_present_queued

From: Paolo Bonzini

Date: Tue Sep 23 2025 - 15:29:03 EST


On 9/23/25 20:55, Sean Christopherson wrote:
On Tue, Sep 23, 2025, Paolo Bonzini wrote:
On 8/13/25 21:23, Maxim Levitsky wrote:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9018d56b4b0a..3d45a4cd08a4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13459,9 +13459,14 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu,
void kvm_arch_async_page_present_queued(struct kvm_vcpu *vcpu)
{
- kvm_make_request(KVM_REQ_APF_READY, vcpu);
- if (!vcpu->arch.apf.pageready_pending)
+ /* Pairs with smp_store_release in vcpu_enter_guest. */
+ bool in_guest_mode = (smp_load_acquire(&vcpu->mode) == IN_GUEST_MODE);
+ bool page_ready_pending = READ_ONCE(vcpu->arch.apf.pageready_pending);
+
+ if (!in_guest_mode || !page_ready_pending) {
+ kvm_make_request(KVM_REQ_APF_READY, vcpu);
kvm_vcpu_kick(vcpu);
+ }

Unlike Sean, I think the race exists in abstract and is not benign

How is it not benign? I never said the race doesn't exist, I said that consuming
a stale vcpu->arch.apf.pageready_pending in kvm_arch_async_page_present_queued()
is benign.

In principle there is a possibility that a KVM_REQ_APF_READY is missed. Just by the reading of the specs, without a smp__mb_after_atomic() this is broken:

kvm_make_request(KVM_REQ_APF_READY, vcpu);
if (!vcpu->arch.apf.pageready_pending)
kvm_vcpu_kick(vcpu);

It won't happen because set_bit() is written with asm("memory"), because x86 set_bit() does prevent reordering at the processor level, etc.

In other words the race is only avoided by the fact that compiler reorderings are prevented even in cases that memory-barriers.txt does not promise.

Paolo