implement kvm_remove_ioperm_data to free ioperm data, and call it in free_assigned_device to avoid leak. Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> --- qemu/hw/device-assignment.c | 2 ++ qemu/qemu-kvm.c | 17 +++++++++++++++++ qemu/qemu-kvm.h | 1 + 3 files changed, 20 insertions(+), 0 deletions(-) diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c index 5003611..82ff00a 100644 --- a/qemu/hw/device-assignment.c +++ b/qemu/hw/device-assignment.c @@ -457,6 +457,8 @@ void free_assigned_device(AssignedDevInfo *adev) if (!pci_region->valid || !(pci_region->type & IORESOURCE_MEM)) continue; + kvm_remove_ioperm_data(region->u.r_baseport, region->r_size); + if (region->u.r_virtbase) { int ret = munmap(region->u.r_virtbase, (pci_region->size + 0xFFF) & 0xFFFFF000); diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 5ff63ad..f14237e 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -1329,6 +1329,23 @@ void kvm_add_ioperm_data(struct ioperm_data *data) LIST_INSERT_HEAD(&ioperm_head, data, entries); } +void kvm_remove_ioperm_data(unsigned long start_port, unsigned long num) +{ + struct ioperm_data *data; + + data = LIST_FIRST(&ioperm_head); + while (data) { + struct ioperm_data *next = LIST_NEXT(data, entries); + + if (data->start_port == start_port && data->num == num) { + LIST_REMOVE(data, entries); + qemu_free(data); + } + + data = next; + } +} + void kvm_ioperm(CPUState *env, void *data) { if (kvm_enabled() && qemu_system_ready) diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h index 042dd93..e7acd2e 100644 --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -127,6 +127,7 @@ struct ioperm_data; void kvm_ioperm(CPUState *env, void *data); void kvm_add_ioperm_data(struct ioperm_data *data); +void kvm_remove_ioperm_data(unsigned long start_port, unsigned long num); void kvm_arch_do_ioperm(void *_data); #endif -- 1.6.0.4
Attachment:
0002-kvm-qemu-fix-leak-of-ioperm-data.patch
Description: 0002-kvm-qemu-fix-leak-of-ioperm-data.patch