]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - virt/kvm/kvm_main.c
Merge tag 'kvm-x86-generic-6.5' of https://github.com/kvm-x86/linux into HEAD
[thirdparty/linux.git] / virt / kvm / kvm_main.c
index c5e4f0a0db4aaeb9f17372f709ad4cf8fed1ffb8..ab8c8eb9fd624275fdb485bf1c06c9d1fbe7b260 100644 (file)
@@ -3888,7 +3888,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)
 static int vcpu_get_pid(void *data, u64 *val)
 {
        struct kvm_vcpu *vcpu = data;
-       *val = pid_nr(rcu_access_pointer(vcpu->pid));
+
+       rcu_read_lock();
+       *val = pid_nr(rcu_dereference(vcpu->pid));
+       rcu_read_unlock();
        return 0;
 }
 
@@ -3990,7 +3993,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
        if (r < 0)
                goto kvm_put_xa_release;
 
-       if (KVM_BUG_ON(!!xa_store(&kvm->vcpu_array, vcpu->vcpu_idx, vcpu, 0), kvm)) {
+       if (KVM_BUG_ON(xa_store(&kvm->vcpu_array, vcpu->vcpu_idx, vcpu, 0), kvm)) {
                r = -EINVAL;
                goto kvm_put_xa_release;
        }
@@ -5313,6 +5316,12 @@ static void hardware_disable_all(void)
 }
 #endif /* CONFIG_KVM_GENERIC_HARDWARE_ENABLING */
 
+static void kvm_iodevice_destructor(struct kvm_io_device *dev)
+{
+       if (dev->ops->destructor)
+               dev->ops->destructor(dev);
+}
+
 static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
 {
        int i;
@@ -5536,7 +5545,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
 int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
                              struct kvm_io_device *dev)
 {
-       int i, j;
+       int i;
        struct kvm_io_bus *new_bus, *bus;
 
        lockdep_assert_held(&kvm->slots_lock);
@@ -5566,18 +5575,19 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
        rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
        synchronize_srcu_expedited(&kvm->srcu);
 
-       /* Destroy the old bus _after_ installing the (null) bus. */
+       /*
+        * If NULL bus is installed, destroy the old bus, including all the
+        * attached devices. Otherwise, destroy the caller's device only.
+        */
        if (!new_bus) {
                pr_err("kvm: failed to shrink bus, removing it completely\n");
-               for (j = 0; j < bus->dev_count; j++) {
-                       if (j == i)
-                               continue;
-                       kvm_iodevice_destructor(bus->range[j].dev);
-               }
+               kvm_io_bus_destroy(bus);
+               return -ENOMEM;
        }
 
+       kvm_iodevice_destructor(dev);
        kfree(bus);
-       return new_bus ? 0 : -ENOMEM;
+       return 0;
 }
 
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,