Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 138

kvm-83-270.el5_11.src.rpm

From c5f051522192af7eae5f380882dd240a1aab9456 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Fri, 15 May 2009 13:00:45 +0100
Subject: [PATCH 15/16] Fix live migratation failure after pcnet NIC hot-unplug

https://bugzilla.redhat.com/500981

pcnet registers a savevm handler which is not removed when
the NIC is hot-unplugged.

This patch just cherry-picks pci_pcnet_cleanup() from:

  http://git.kernel.org/?p=virt/kvm/qemu-kvm.git;a=commitdiff;h=a34b6eb776

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Message-Id: <1242388845.25932.11.camel@blaa>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Bugzilla: 501729
RH-Upstream-status: applied(qemu-kvm/master)
Depends: <1242387172.25932.5.camel@blaa>
Depends: <1242387177.25932.6.camel@blaa>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Juan Quintela <quintela@redhat.com>
---
 qemu/hw/pcnet.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/qemu/hw/pcnet.c b/qemu/hw/pcnet.c
index f5bf15d..9dfc922 100644
--- a/qemu/hw/pcnet.c
+++ b/qemu/hw/pcnet.c
@@ -1929,7 +1929,15 @@ static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
+static void pcnet_common_cleanup(PCNetState *d)
+{
+    unregister_savevm("pcnet", d);
+
+    qemu_del_timer(d->poll_timer);
+    qemu_free_timer(d->poll_timer);
+}
+
+static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str, NetCleanup *cleanup)
 {
     d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
 
@@ -1938,6 +1946,7 @@ static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
     if (nd && nd->vlan) {
         d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
                                      pcnet_receive, pcnet_can_receive, d);
+        d->vc->cleanup = cleanup;
 
         qemu_format_nic_info_str(d->vc, d->nd->macaddr);
     } else {
@@ -1985,6 +1994,22 @@ static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
     cpu_physical_memory_read(addr, buf, len);
 }
 
+static void pci_pcnet_cleanup(VLANClientState *vc)
+{
+    PCNetState *d = vc->opaque;
+
+    pcnet_common_cleanup(d);
+}
+
+static int pci_pcnet_uninit(PCIDevice *dev)
+{
+    PCNetState *d = (PCNetState *)dev;
+
+    cpu_unregister_io_memory(d->mmio_index);
+
+    return 0;
+}
+
 PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
 {
     PCNetState *d;
@@ -2000,6 +2025,8 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
     if (!d)
 	return NULL;
 
+    d->dev.unregister = pci_pcnet_uninit;
+
     pci_conf = d->dev.config;
 
     *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
@@ -2034,7 +2061,7 @@ PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
     d->phys_mem_write = pci_physical_memory_write;
     d->pci_dev = &d->dev;
 
-    pcnet_common_init(d, nd, "pcnet");
+    pcnet_common_init(d, nd, "pcnet", pci_pcnet_cleanup);
     return (PCIDevice *)d;
 }
 
@@ -2109,6 +2136,6 @@ void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
     d->phys_mem_read = ledma_memory_read;
     d->phys_mem_write = ledma_memory_write;
 
-    pcnet_common_init(d, nd, "lance");
+    pcnet_common_init(d, nd, "lance", NULL);
 }
 #endif /* TARGET_SPARC */
-- 
1.6.3.rc4.29.g8146