Context |
Check |
Description |
bjorn/pre-ci_am |
success
|
Success
|
bjorn/build-rv32-defconfig |
success
|
build-rv32-defconfig
|
bjorn/build-rv64-clang-allmodconfig |
success
|
build-rv64-clang-allmodconfig
|
bjorn/build-rv64-gcc-allmodconfig |
success
|
build-rv64-gcc-allmodconfig
|
bjorn/build-rv64-nommu-k210-defconfig |
success
|
build-rv64-nommu-k210-defconfig
|
bjorn/build-rv64-nommu-k210-virt |
success
|
build-rv64-nommu-k210-virt
|
bjorn/checkpatch |
success
|
checkpatch
|
bjorn/dtb-warn-rv64 |
success
|
dtb-warn-rv64
|
bjorn/header-inline |
success
|
header-inline
|
bjorn/kdoc |
success
|
kdoc
|
bjorn/module-param |
success
|
module-param
|
bjorn/verify-fixes |
success
|
verify-fixes
|
bjorn/verify-signedoff |
success
|
verify-signedoff
|
@@ -401,6 +401,18 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
*/
init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
+ /*
+ * Set the irqfd routing and add it to KVM's list before registering
+ * the irqfd with the eventfd, so that the routing information is valid
+ * and stays valid, e.g. if there are GSI routing changes, prior to
+ * making the irqfd visible, i.e. before it might be signaled.
+ *
+ * Note, holding SRCU ensures a stable read of routing information, and
+ * also prevents irqfd_shutdown() from freeing the irqfd before it's
+ * fully initialized.
+ */
+ idx = srcu_read_lock(&kvm->irq_srcu);
+
spin_lock_irq(&kvm->irqfds.lock);
ret = 0;
@@ -409,11 +421,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
continue;
/* This fd is used for another irq already. */
ret = -EBUSY;
- spin_unlock_irq(&kvm->irqfds.lock);
- goto fail;
+ goto fail_duplicate;
}
- idx = srcu_read_lock(&kvm->irq_srcu);
irqfd_update(kvm, irqfd);
list_add_tail(&irqfd->list, &kvm->irqfds.items);
@@ -449,6 +459,9 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
srcu_read_unlock(&kvm->irq_srcu, idx);
return 0;
+fail_duplicate:
+ spin_unlock_irq(&kvm->irqfds.lock);
+ srcu_read_unlock(&kvm->irq_srcu, idx);
fail:
if (irqfd->resampler)
irqfd_resampler_shutdown(irqfd);
Acquire SRCU outside of irqfds.lock so that the locking is symmetrical, and add a comment explaining why on earth KVM holds SRCU for so long. Signed-off-by: Sean Christopherson <seanjc@google.com> --- virt/kvm/eventfd.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)