From 45c12658a0f2ee1c7e629ea5906a509487113701 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin <markmc@redhat.com> Date: Wed, 1 Jul 2009 23:13:19 +0100 Subject: [PATCH 4/4] Fix eepro100 segfault during live migrate after NIC hot-unplug https://bugzilla.redhat.com/500980 eepro100 registers a savevm handler which is not removed when the NIC is hot-unplugged. This patch just cherry-picks eepro100 bits from: http://git.kernel.org/?p=virt/kvm/qemu-kvm.git;a=commitdiff;h=a34b6eb776 I've just now sent the eeprom savevm bit upstream. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Message-Id: <1246486399.598.96.camel@blaa> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 500980 RH-Upstream-status: applied Acked-by: Juan Quintela <quintela@redhat.com> Acked-by: Don Dutile <ddutile@redhat.com> Acked-by: Marcelo Tosatti <mtosatti@redhat.com> --- qemu/hw/eepro100.c | 22 ++++++++++++++++++++++ qemu/hw/eeprom93xx.c | 1 + 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/qemu/hw/eepro100.c b/qemu/hw/eepro100.c index 72fc54f..ae2b411 100644 --- a/qemu/hw/eepro100.c +++ b/qemu/hw/eepro100.c @@ -1736,6 +1736,25 @@ static void nic_save(QEMUFile * f, void *opaque) qemu_put_buffer(f, s->configuration, sizeof(s->configuration)); } +static void nic_cleanup(VLANClientState *vc) +{ + EEPRO100State *s = vc->opaque; + + unregister_savevm(vc->model, s); + + eeprom93xx_free(s->eeprom); +} + +static int pci_nic_uninit(PCIDevice *dev) +{ + PCIEEPRO100State *d = (PCIEEPRO100State *) dev; + EEPRO100State *s = &d->eepro100; + + cpu_unregister_io_memory(s->mmio_index); + + return 0; +} + static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, const char *name, uint32_t device) { @@ -1750,6 +1769,8 @@ static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, if (!d) return NULL; + d->dev.unregister = pci_nic_uninit; + s = &d->eepro100; s->device = device; s->pci_dev = &d->dev; @@ -1781,6 +1802,7 @@ static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, nic_receive, nic_can_receive, s); nd->vc = s->vc; + s->vc->cleanup = nic_cleanup; qemu_format_nic_info_str(s->vc, s->macaddr); diff --git a/qemu/hw/eeprom93xx.c b/qemu/hw/eeprom93xx.c index 896cffd..6de970a 100644 --- a/qemu/hw/eeprom93xx.c +++ b/qemu/hw/eeprom93xx.c @@ -301,6 +301,7 @@ void eeprom93xx_free(eeprom_t *eeprom) { /* Destroy EEPROM. */ logout("eeprom = 0x%p\n", eeprom); + unregister_savevm("eeprom", eeprom); qemu_free(eeprom); } -- 1.6.3.rc4.29.g8146