Patchwork [05/15] wdt_i6300esb: fix io type leakage

login
register
mail settings
Submitter Anthony Liguori
Date Feb. 9, 2010, 10:01 p.m.
Message ID <1265752899-26980-6-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/44966/
State New
Headers show

Comments

Anthony Liguori - Feb. 9, 2010, 10:01 p.m.
The watchdog device registers an io type in the pci map_func callback.  This
callback is invoked whenever the OS needs to reposition the IO region in memory.
While we automatically unmap previous mappings, we don't unregister the io type
(since the PCI layer does not know about this).

The current code will leak io types and eventually exhaust them.  You can
reproduce it by repeatedly rebooting a guest for about 30 times.

The fix is to register the io type once at init.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/wdt_i6300esb.c |   30 +++++++++++++++++-------------
 1 files changed, 17 insertions(+), 13 deletions(-)

Patch

diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index be0e89e..6c08c32 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -98,6 +98,8 @@  struct I6300State {
     int previous_reboot_flag;   /* If the watchdog caused the previous
                                  * reboot, this flag will be set.
                                  */
+
+    int io_mem;
 };
 
 typedef struct I6300State I6300State;
@@ -342,27 +344,27 @@  static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
     }
 }
 
+static CPUReadMemoryFunc * const mem_read[3] = {
+    i6300esb_mem_readb,
+    i6300esb_mem_readw,
+    i6300esb_mem_readl,
+};
+
+static CPUWriteMemoryFunc * const mem_write[3] = {
+    i6300esb_mem_writeb,
+    i6300esb_mem_writew,
+    i6300esb_mem_writel,
+};
+
 static void i6300esb_map(PCIDevice *dev, int region_num,
                          pcibus_t addr, pcibus_t size, int type)
 {
-    static CPUReadMemoryFunc * const mem_read[3] = {
-        i6300esb_mem_readb,
-        i6300esb_mem_readw,
-        i6300esb_mem_readl,
-    };
-    static CPUWriteMemoryFunc * const mem_write[3] = {
-        i6300esb_mem_writeb,
-        i6300esb_mem_writew,
-        i6300esb_mem_writel,
-    };
     I6300State *d = DO_UPCAST(I6300State, dev, dev);
-    int io_mem;
 
     i6300esb_debug("addr = %"FMT_PCIBUS", size = %"FMT_PCIBUS", type = %d\n",
                    addr, size, type);
 
-    io_mem = cpu_register_io_memory(mem_read, mem_write, d);
-    cpu_register_physical_memory (addr, 0x10, io_mem);
+    cpu_register_physical_memory (addr, 0x10, d->io_mem);
     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
 }
 
@@ -406,6 +408,8 @@  static int i6300esb_init(PCIDevice *dev)
     d->stage = 1;
     d->unlock_state = 0;
     d->previous_reboot_flag = 0;
+    d->io_mem = cpu_register_io_memory(mem_read, mem_write, d);
+
 
     pci_conf = d->dev.config;
     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);