Skip to content

Commit ae9d3e7

Browse files
sean-jcUlrich Hecht
authored andcommitted
KVM: x86: Take irqfds.lock when adding/deleting IRQ bypass producer
[ Upstream commit f1fb088d9cecde5c3066d8ff8846789667519b7d ] Take irqfds.lock when adding/deleting an IRQ bypass producer to ensure irqfd->producer isn't modified while kvm_irq_routing_update() is running. The only lock held when a producer is added/removed is irqbypass's mutex. Fixes: 8727688 ("KVM: x86: select IRQ_BYPASS_MANAGER") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20250404193923.1413163-5-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> [ Adjust context ] Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 5e5c6b3 commit ae9d3e7

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

arch/x86/kvm/x86.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9774,11 +9774,18 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
97749774
{
97759775
struct kvm_kernel_irqfd *irqfd =
97769776
container_of(cons, struct kvm_kernel_irqfd, consumer);
9777+
struct kvm *kvm = irqfd->kvm;
9778+
int ret;
97779779

9780+
spin_lock_irq(&kvm->irqfds.lock);
97789781
irqfd->producer = prod;
97799782

9780-
return kvm_x86_ops->update_pi_irte(irqfd->kvm,
9783+
ret = kvm_x86_ops->update_pi_irte(irqfd->kvm,
97819784
prod->irq, irqfd->gsi, 1);
9785+
9786+
spin_unlock_irq(&kvm->irqfds.lock);
9787+
9788+
return ret;
97829789
}
97839790

97849791
void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
@@ -9787,20 +9794,25 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
97879794
int ret;
97889795
struct kvm_kernel_irqfd *irqfd =
97899796
container_of(cons, struct kvm_kernel_irqfd, consumer);
9797+
struct kvm *kvm = irqfd->kvm;
97909798

97919799
WARN_ON(irqfd->producer != prod);
9792-
irqfd->producer = NULL;
97939800

97949801
/*
97959802
* When producer of consumer is unregistered, we change back to
97969803
* remapped mode, so we can re-use the current implementation
97979804
* when the irq is masked/disabled or the consumer side (KVM
97989805
* int this case doesn't want to receive the interrupts.
97999806
*/
9807+
spin_lock_irq(&kvm->irqfds.lock);
9808+
irqfd->producer = NULL;
9809+
98009810
ret = kvm_x86_ops->update_pi_irte(irqfd->kvm, prod->irq, irqfd->gsi, 0);
98019811
if (ret)
98029812
printk(KERN_INFO "irq bypass consumer (token %p) unregistration"
98039813
" fails: %d\n", irqfd->consumer.token, ret);
9814+
9815+
spin_unlock_irq(&kvm->irqfds.lock);
98049816
}
98059817

98069818
int kvm_arch_update_irqfd_routing(struct kvm *kvm, unsigned int host_irq,

0 commit comments

Comments
 (0)