|
@@ -119,8 +119,12 @@ irqfd_shutdown(struct work_struct *work)
|
|
|
{
|
|
|
struct kvm_kernel_irqfd *irqfd =
|
|
|
container_of(work, struct kvm_kernel_irqfd, shutdown);
|
|
|
+ struct kvm *kvm = irqfd->kvm;
|
|
|
u64 cnt;
|
|
|
|
|
|
+ /* Make sure irqfd has been initalized in assign path. */
|
|
|
+ synchronize_srcu(&kvm->irq_srcu);
|
|
|
+
|
|
|
/*
|
|
|
* Synchronize with the wait-queue and unhook ourselves to prevent
|
|
|
* further events.
|
|
@@ -387,7 +391,6 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
|
|
|
|
|
idx = srcu_read_lock(&kvm->irq_srcu);
|
|
|
irqfd_update(kvm, irqfd);
|
|
|
- srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
|
|
|
|
list_add_tail(&irqfd->list, &kvm->irqfds.items);
|
|
|
|
|
@@ -421,6 +424,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ srcu_read_unlock(&kvm->irq_srcu, idx);
|
|
|
return 0;
|
|
|
|
|
|
fail:
|