Assert that IRQs are already disabled when putting a vCPU on a CPU's PI
wakeup list, as opposed to saving/disabling+restoring IRQs. KVM relies on
IRQs being disabled until the vCPU task is fully scheduled out, i.e. until
the scheduler has dropped all of its per-CPU locks (e.g. for the runqueue),
as attempting to wake the task while it's being scheduled out could lead
to deadlock.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/vmx/posted_intr.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c
index ec08fa3caf43..840d435229a8 100644
--- a/arch/x86/kvm/vmx/posted_intr.c
+++ b/arch/x86/kvm/vmx/posted_intr.c
@@ -148,9 +148,8 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu)
struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct pi_desc old, new;
- unsigned long flags;
- local_irq_save(flags);
+ lockdep_assert_irqs_disabled();
raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
list_add_tail(&vmx->pi_wakeup_list,
@@ -176,8 +175,6 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu)
*/
if (pi_test_on(&new))
__apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR);
-
- local_irq_restore(flags);
}
static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu)
--
2.49.0.472.ge94155a9ec-goog
Reviewed-by: Yan Zhao <yan.y.zhao@intel.com> On Tue, Apr 01, 2025 at 08:47:26AM -0700, Sean Christopherson wrote: > Assert that IRQs are already disabled when putting a vCPU on a CPU's PI > wakeup list, as opposed to saving/disabling+restoring IRQs. KVM relies on > IRQs being disabled until the vCPU task is fully scheduled out, i.e. until > the scheduler has dropped all of its per-CPU locks (e.g. for the runqueue), > as attempting to wake the task while it's being scheduled out could lead > to deadlock. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/vmx/posted_intr.c | 5 +---- > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c > index ec08fa3caf43..840d435229a8 100644 > --- a/arch/x86/kvm/vmx/posted_intr.c > +++ b/arch/x86/kvm/vmx/posted_intr.c > @@ -148,9 +148,8 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) > struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); > struct vcpu_vmx *vmx = to_vmx(vcpu); > struct pi_desc old, new; > - unsigned long flags; > > - local_irq_save(flags); > + lockdep_assert_irqs_disabled(); > > raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); > list_add_tail(&vmx->pi_wakeup_list, > @@ -176,8 +175,6 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) > */ > if (pi_test_on(&new)) > __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR); > - > - local_irq_restore(flags); > } > > static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu) > -- > 2.49.0.472.ge94155a9ec-goog >
On Tue, 2025-04-01 at 08:47 -0700, Sean Christopherson wrote: > Assert that IRQs are already disabled when putting a vCPU on a CPU's PI > wakeup list, as opposed to saving/disabling+restoring IRQs. KVM relies on > IRQs being disabled until the vCPU task is fully scheduled out, i.e. until > the scheduler has dropped all of its per-CPU locks (e.g. for the runqueue), > as attempting to wake the task while it's being scheduled out could lead > to deadlock. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/vmx/posted_intr.c | 5 +---- > 1 file changed, 1 insertion(+), 4 deletions(-) > > diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c > index ec08fa3caf43..840d435229a8 100644 > --- a/arch/x86/kvm/vmx/posted_intr.c > +++ b/arch/x86/kvm/vmx/posted_intr.c > @@ -148,9 +148,8 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) > struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); > struct vcpu_vmx *vmx = to_vmx(vcpu); > struct pi_desc old, new; > - unsigned long flags; > > - local_irq_save(flags); > + lockdep_assert_irqs_disabled(); > > raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu)); > list_add_tail(&vmx->pi_wakeup_list, > @@ -176,8 +175,6 @@ static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu) > */ > if (pi_test_on(&new)) > __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR); > - > - local_irq_restore(flags); > } > > static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu) Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Best regards, Maxim Levitsky
© 2016 - 2025 Red Hat, Inc.