]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: SVM: Add a comment to explain why avic_vcpu_blocking() ignores IRQ blocking
authorSean Christopherson <seanjc@google.com>
Wed, 11 Jun 2025 22:45:23 +0000 (15:45 -0700)
committerSean Christopherson <seanjc@google.com>
Mon, 23 Jun 2025 16:50:17 +0000 (09:50 -0700)
Add a comment to explain why KVM clears IsRunning when putting a vCPU,
even though leaving IsRunning=1 would be ok from a functional perspective.
Per Maxim's experiments, a misbehaving VM could spam the AVIC doorbell so
fast as to induce a 50%+ loss in performance.

Link: https://lore.kernel.org/all/8d7e0d0391df4efc7cb28557297eb2ec9904f1e5.camel@redhat.com
Cc: Maxim Levitsky <mlevitsk@redhat.com>
Acked-by: Naveen N Rao (AMD) <naveen@kernel.org>
Link: https://lore.kernel.org/r/20250611224604.313496-22-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/avic.c

index 72b8cab2fbce92631ddc098e47dbe4ab82207471..375a29022000ec1d8a5351e26886a23c43279db0 100644 (file)
@@ -1122,19 +1122,24 @@ void avic_vcpu_blocking(struct kvm_vcpu *vcpu)
        if (!kvm_vcpu_apicv_active(vcpu))
                return;
 
-       /*
-        * Unload the AVIC when the vCPU is about to block, _before_
-        * the vCPU actually blocks.
-        *
-        * Any IRQs that arrive before IsRunning=0 will not cause an
-        * incomplete IPI vmexit on the source, therefore vIRR will also
-        * be checked by kvm_vcpu_check_block() before blocking.  The
-        * memory barrier implicit in set_current_state orders writing
-        * IsRunning=0 before reading the vIRR.  The processor needs a
-        * matching memory barrier on interrupt delivery between writing
-        * IRR and reading IsRunning; the lack of this barrier might be
-        * the cause of errata #1235).
-        */
+       /*
+        * Unload the AVIC when the vCPU is about to block, _before_ the vCPU
+        * actually blocks.
+        *
+        * Note, any IRQs that arrive before IsRunning=0 will not cause an
+        * incomplete IPI vmexit on the source; kvm_vcpu_check_block() handles
+        * this by checking vIRR one last time before blocking.  The memory
+        * barrier implicit in set_current_state orders writing IsRunning=0
+        * before reading the vIRR.  The processor needs a matching memory
+        * barrier on interrupt delivery between writing IRR and reading
+        * IsRunning; the lack of this barrier might be the cause of errata #1235).
+        *
+        * Clear IsRunning=0 even if guest IRQs are disabled, i.e. even if KVM
+        * doesn't need to detect events for scheduling purposes.  The doorbell
+        * used to signal running vCPUs cannot be blocked, i.e. will perturb the
+        * CPU and cause noisy neighbor problems if the VM is sending interrupts
+        * to the vCPU while it's scheduled out.
+        */
        avic_vcpu_put(vcpu);
 }