KVM: VMX: Read Posted Interrupt "control" exactly once per loop iteration
authorSean Christopherson <seanjc@google.com>
Sat, 9 Oct 2021 02:12:19 +0000 (19:12 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Dec 2021 09:24:56 +0000 (04:24 -0500)
Use READ_ONCE() when loading the posted interrupt descriptor control
field to ensure "old" and "new" have the same base value.  If the
compiler emits separate loads, and loads into "new" before "old", KVM
could theoretically drop the ON bit if it were set between the loads.

Fixes: 28b835d60fcc ("KVM: Update Posted-Interrupts Descriptor when vCPU is preempted")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20211009021236.4122790-27-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx/posted_intr.c

index b72dbe80f87a0941864cd8478eca3188f3492bd9..a1ce598e95444907d7f483a6737703df33a6c7a5 100644 (file)
@@ -54,7 +54,7 @@ void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
 
        /* The full case.  */
        do {
-               old.control = new.control = pi_desc->control;
+               old.control = new.control = READ_ONCE(pi_desc->control);
 
                dest = cpu_physical_id(cpu);
 
@@ -107,7 +107,7 @@ static void __pi_post_block(struct kvm_vcpu *vcpu)
        unsigned int dest;
 
        do {
-               old.control = new.control = pi_desc->control;
+               old.control = new.control = READ_ONCE(pi_desc->control);
                WARN(old.nv != POSTED_INTR_WAKEUP_VECTOR,
                     "Wakeup handler not enabled while the VCPU is blocked\n");
 
@@ -160,7 +160,7 @@ int pi_pre_block(struct kvm_vcpu *vcpu)
        spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->cpu));
 
        do {
-               old.control = new.control = pi_desc->control;
+               old.control = new.control = READ_ONCE(pi_desc->control);
 
                WARN((pi_desc->sn == 1),
                     "Warning: SN field of posted-interrupts "