From 44a109c1b38ddc9f853c33861875d0a85262de4f Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Wed, 15 Mar 2017 20:50:14 -0400 Subject: [PATCH 1/3] ide: qdev: register ide bus unrealize function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we have an idebus unrealize function, but it was being registered as the unrealize function for the IDE Device, so it was not getting invoked on device teardown because nothing is "unrealizing" the IDE devices themselves. Suggested-by: John Snow Signed-off-by: Li Qiang Reviewed-by: Philippe Mathieu-Daudé Message-id: 1488449293-80280-2-git-send-email-liqiang6-s@360.cn Signed-off-by: John Snow --- hw/ide/qdev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index 4383cd111d..299e592fa2 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -31,7 +31,7 @@ /* --------------------------------- */ static char *idebus_get_fw_dev_path(DeviceState *dev); -static void idebus_unrealize(DeviceState *qdev, Error **errp); +static void idebus_unrealize(BusState *qdev, Error **errp); static Property ide_props[] = { DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1), @@ -43,14 +43,15 @@ static void ide_bus_class_init(ObjectClass *klass, void *data) BusClass *k = BUS_CLASS(klass); k->get_fw_dev_path = idebus_get_fw_dev_path; + k->unrealize = idebus_unrealize; } -static void idebus_unrealize(DeviceState *qdev, Error **errp) +static void idebus_unrealize(BusState *bus, Error **errp) { - IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus); + IDEBus *ibus = IDE_BUS(bus); - if (bus->vmstate) { - qemu_del_vm_change_state_handler(bus->vmstate); + if (ibus->vmstate) { + qemu_del_vm_change_state_handler(ibus->vmstate); } } @@ -370,7 +371,6 @@ static void ide_device_class_init(ObjectClass *klass, void *data) k->init = ide_qdev_init; set_bit(DEVICE_CATEGORY_STORAGE, k->categories); k->bus_type = TYPE_IDE_BUS; - k->unrealize = idebus_unrealize; k->props = ide_props; } From c9f086418a255f386e1c4d2c1418c032eb349537 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Wed, 15 Mar 2017 20:50:14 -0400 Subject: [PATCH 2/3] ide: core: add cleanup function As the pci ahci can be hotplug and unplug, in the ahci unrealize function it should free all the resource once allocated in the realized function. This patch add ide_exit to free the resource. Signed-off-by: Li Qiang Message-id: 1488449293-80280-3-git-send-email-liqiang6-s@360.cn Signed-off-by: John Snow --- hw/ide/core.c | 8 ++++++++ include/hw/ide/internal.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/ide/core.c b/hw/ide/core.c index db509b3e15..0b48b64d3a 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2603,6 +2603,14 @@ void ide_init2(IDEBus *bus, qemu_irq irq) bus->dma = &ide_dma_nop; } +void ide_exit(IDEState *s) +{ + timer_del(s->sector_write_timer); + timer_free(s->sector_write_timer); + qemu_vfree(s->smart_selftest_data); + qemu_vfree(s->io_buffer); +} + static const MemoryRegionPortio ide_portio_list[] = { { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew }, diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h index 88dc11808b..482a9512be 100644 --- a/include/hw/ide/internal.h +++ b/include/hw/ide/internal.h @@ -607,6 +607,7 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind, uint32_t cylinders, uint32_t heads, uint32_t secs, int chs_trans); void ide_init2(IDEBus *bus, qemu_irq irq); +void ide_exit(IDEState *s); void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2); void ide_register_restart_cb(IDEBus *bus); From d68f0f778e7f4fbd674627274267f269e40f0b04 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Wed, 15 Mar 2017 20:50:14 -0400 Subject: [PATCH 3/3] ide: ahci: call cleanup function in ahci unit This can avoid memory leak when hotunplug the ahci device. Signed-off-by: Li Qiang Message-id: 1488449293-80280-4-git-send-email-liqiang6-s@360.cn Signed-off-by: John Snow --- hw/ide/ahci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 6a17acf639..f60826d6e0 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -1485,6 +1485,18 @@ void ahci_realize(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports) void ahci_uninit(AHCIState *s) { + int i, j; + + for (i = 0; i < s->ports; i++) { + AHCIDevice *ad = &s->dev[i]; + + for (j = 0; j < 2; j++) { + IDEState *s = &ad->port.ifs[j]; + + ide_exit(s); + } + } + g_free(s->dev); }