Skip to content

Commit 5ea5ca3

Browse files
wei-w-wangsean-jc
authored andcommitted
KVM: destruct kvm_io_device while unregistering it from kvm_io_bus
Current usage of kvm_io_device requires users to destruct it with an extra call of kvm_iodevice_destructor after the device gets unregistered from kvm_io_bus. This is not necessary and can cause errors if a user forgot to make the extra call. Simplify the usage by combining kvm_iodevice_destructor into kvm_io_bus_unregister_dev. This reduces LOCs a bit for users and can avoid the leakage of destructing the device explicitly. Signed-off-by: Wei Wang <wei.w.wang@intel.com> Reviewed-by: Sean Christopherson <seanjc@google.com> Link: https://lore.kernel.org/r/20230207123713.3905-2-wei.w.wang@intel.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 5f643e4 commit 5ea5ca3

4 files changed

Lines changed: 17 additions & 22 deletions

File tree

include/kvm/iodev.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,4 @@ static inline int kvm_iodevice_write(struct kvm_vcpu *vcpu,
5555
: -EOPNOTSUPP;
5656
}
5757

58-
static inline void kvm_iodevice_destructor(struct kvm_io_device *dev)
59-
{
60-
if (dev->ops->destructor)
61-
dev->ops->destructor(dev);
62-
}
63-
6458
#endif /* __KVM_IODEV_H__ */

virt/kvm/coalesced_mmio.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,10 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
186186
coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
187187
r = kvm_io_bus_unregister_dev(kvm,
188188
zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev);
189-
190-
kvm_iodevice_destructor(&dev->dev);
191-
192189
/*
193190
* On failure, unregister destroys all devices on the
194-
* bus _except_ the target device, i.e. coalesced_zones
195-
* has been modified. Bail after destroying the target
196-
* device, there's no need to restart the walk as there
197-
* aren't any zones left.
191+
* bus, including the target device. There's no need
192+
* to restart the walk as there aren't any zones left.
198193
*/
199194
if (r)
200195
break;

virt/kvm/eventfd.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,6 @@ kvm_deassign_ioeventfd_idx(struct kvm *kvm, enum kvm_bus bus_idx,
931931
bus = kvm_get_bus(kvm, bus_idx);
932932
if (bus)
933933
bus->ioeventfd_count--;
934-
ioeventfd_release(p);
935934
ret = 0;
936935
break;
937936
}

virt/kvm/kvm_main.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5297,6 +5297,12 @@ static void hardware_disable_all(void)
52975297
}
52985298
#endif /* CONFIG_KVM_GENERIC_HARDWARE_ENABLING */
52995299

5300+
static void kvm_iodevice_destructor(struct kvm_io_device *dev)
5301+
{
5302+
if (dev->ops->destructor)
5303+
dev->ops->destructor(dev);
5304+
}
5305+
53005306
static void kvm_io_bus_destroy(struct kvm_io_bus *bus)
53015307
{
53025308
int i;
@@ -5520,7 +5526,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
55205526
int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
55215527
struct kvm_io_device *dev)
55225528
{
5523-
int i, j;
5529+
int i;
55245530
struct kvm_io_bus *new_bus, *bus;
55255531

55265532
lockdep_assert_held(&kvm->slots_lock);
@@ -5550,18 +5556,19 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
55505556
rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
55515557
synchronize_srcu_expedited(&kvm->srcu);
55525558

5553-
/* Destroy the old bus _after_ installing the (null) bus. */
5559+
/*
5560+
* If NULL bus is installed, destroy the old bus, including all the
5561+
* attached devices. Otherwise, destroy the caller's device only.
5562+
*/
55545563
if (!new_bus) {
55555564
pr_err("kvm: failed to shrink bus, removing it completely\n");
5556-
for (j = 0; j < bus->dev_count; j++) {
5557-
if (j == i)
5558-
continue;
5559-
kvm_iodevice_destructor(bus->range[j].dev);
5560-
}
5565+
kvm_io_bus_destroy(bus);
5566+
return -ENOMEM;
55615567
}
55625568

5569+
kvm_iodevice_destructor(dev);
55635570
kfree(bus);
5564-
return new_bus ? 0 : -ENOMEM;
5571+
return 0;
55655572
}
55665573

55675574
struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,

0 commit comments

Comments
 (0)