coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
                        r = kvm_io_bus_unregister_dev(kvm,
                                zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
-
-                       kvm_iodevice_destructor(&dev->dev);
-
                        /*
                         * On failure, unregister destroys all devices on the
-                        * bus _except_ the target device, i.e. coalesced_zones
-                        * has been modified.  Bail after destroying the target
-                        * device, there's no need to restart the walk as there
-                        * aren't any zones left.
+                        * bus, including the target device. There's no need
+                        * to restart the walk as there aren't any zones left.
                         */
                        if (r)
                                break;
 
 }
 #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;
 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);
        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,