diff options
author | Max Krummenacher <max.krummenacher@toradex.com> | 2020-10-10 13:30:49 +0200 |
---|---|---|
committer | Max Krummenacher <max.krummenacher@toradex.com> | 2020-10-10 13:30:49 +0200 |
commit | 566575659eec6b0a72de46dd1c3ae8fc221a90a5 (patch) | |
tree | fed807b5725b3592752bb19005c9eea9dbcd387d /virt/kvm/kvm_main.c | |
parent | f1442a59da02a0b5ef648925f2f274a3e64999cc (diff) | |
parent | 18f617d6f398c264e3172532a5d3c656f17cecfa (diff) |
Merge tag 'v4.4.238' into toradex_vf_4.4-next
This is the 4.4.238 stable release
Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 82f3a9d78cab..ba8e8840b94b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3392,7 +3392,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, struct kvm_io_device *dev) { - int i; + int i, j; struct kvm_io_bus *new_bus, *bus; bus = kvm->buses[bus_idx]; @@ -3409,17 +3409,20 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, new_bus = kmalloc(sizeof(*bus) + ((bus->dev_count - 1) * sizeof(struct kvm_io_range)), GFP_KERNEL); - if (!new_bus) { + if (new_bus) { + memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range)); + new_bus->dev_count--; + memcpy(new_bus->range + i, bus->range + i + 1, + (new_bus->dev_count - i) * sizeof(struct kvm_io_range)); + } else { pr_err("kvm: failed to shrink bus, removing it completely\n"); - goto broken; + for (j = 0; j < bus->dev_count; j++) { + if (j == i) + continue; + kvm_iodevice_destructor(bus->range[j].dev); + } } - memcpy(new_bus, bus, sizeof(*bus) + i * sizeof(struct kvm_io_range)); - new_bus->dev_count--; - memcpy(new_bus->range + i, bus->range + i + 1, - (new_bus->dev_count - i) * sizeof(struct kvm_io_range)); - -broken: rcu_assign_pointer(kvm->buses[bus_idx], new_bus); synchronize_srcu_expedited(&kvm->srcu); kfree(bus); |