e178e25130
OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=98a7b497156d81631d87c0adc03f8518
91 lines
2.9 KiB
Diff
91 lines
2.9 KiB
Diff
|
|
Subject: passthrough: fix segmentation fault after hotplug pass-through device
|
|
From: Ian Jackson ian.jackson@eu.citrix.com Tue Apr 13 12:07:33 2010 +0100
|
|
Date: Tue Apr 13 12:07:33 2010 +0100:
|
|
Git: b5160622517fb2d16d0836172a2e34633c9d94bf
|
|
|
|
This patch fixed the QEMU segmentation fault after hotplug
|
|
pass-through devices with MSI-X for many times.
|
|
|
|
There is a wrong boundary check in cpu_register_io_memory that uses
|
|
io_index rather than io_mem_nb. After many times of hotplug of MSI-X
|
|
pass-through device, io_mem_read[] got extended to overwrite mmio_cnt,
|
|
then cause QEMU segmentation fault.
|
|
|
|
This fix sync with upstream QEMU code in exec.c, and free unused
|
|
io_mem_XXX element after hot removal.
|
|
|
|
Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>
|
|
|
|
Index: xen-4.0.0-testing/tools/ioemu-remote/hw/pt-msi.c
|
|
===================================================================
|
|
--- xen-4.0.0-testing.orig/tools/ioemu-remote/hw/pt-msi.c
|
|
+++ xen-4.0.0-testing/tools/ioemu-remote/hw/pt-msi.c
|
|
@@ -623,5 +623,11 @@ void pt_msix_delete(struct pt_dev *dev)
|
|
dev->msix->table_offset_adjust);
|
|
}
|
|
|
|
+ if (dev->msix->mmio_index > 0)
|
|
+ {
|
|
+ cpu_unregister_io_memory(dev->msix->mmio_index);
|
|
+ }
|
|
+
|
|
+
|
|
free(dev->msix);
|
|
}
|
|
Index: xen-4.0.0-testing/tools/ioemu-remote/i386-dm/exec-dm.c
|
|
===================================================================
|
|
--- xen-4.0.0-testing.orig/tools/ioemu-remote/i386-dm/exec-dm.c
|
|
+++ xen-4.0.0-testing/tools/ioemu-remote/i386-dm/exec-dm.c
|
|
@@ -125,7 +125,7 @@ unsigned long qemu_host_page_mask;
|
|
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
|
|
CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
|
|
void *io_mem_opaque[IO_MEM_NB_ENTRIES];
|
|
-static int io_mem_nb = 1;
|
|
+char io_mem_used[IO_MEM_NB_ENTRIES];
|
|
|
|
/* log support */
|
|
FILE *logfile;
|
|
@@ -310,6 +310,20 @@ void cpu_register_physical_memory(target
|
|
mmio[mmio_cnt++].size = size;
|
|
}
|
|
|
|
+static int get_free_io_mem_idx(void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ /* Leave 1st element empty */
|
|
+ for (i = 1; i<IO_MEM_NB_ENTRIES; i++)
|
|
+ if (!io_mem_used[i]) {
|
|
+ io_mem_used[i] = 1;
|
|
+ return i;
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
/* mem_read and mem_write are arrays of functions containing the
|
|
function to access byte (index 0), word (index 1) and dword (index
|
|
2). All functions must be supplied. If io_index is non zero, the
|
|
@@ -324,9 +338,9 @@ int cpu_register_io_memory(int io_index,
|
|
int i;
|
|
|
|
if (io_index <= 0) {
|
|
- if (io_index >= IO_MEM_NB_ENTRIES)
|
|
- return -1;
|
|
- io_index = io_mem_nb++;
|
|
+ io_index = get_free_io_mem_idx();
|
|
+ if (io_index == -1)
|
|
+ return io_index;
|
|
} else {
|
|
if (io_index >= IO_MEM_NB_ENTRIES)
|
|
return -1;
|
|
@@ -357,6 +371,7 @@ void cpu_unregister_io_memory(int io_tab
|
|
io_mem_write[io_index][i] = NULL;
|
|
}
|
|
io_mem_opaque[io_index] = NULL;
|
|
+ io_mem_used[io_index] = 0;
|
|
}
|
|
|
|
void cpu_physical_memory_set_dirty(ram_addr_t addr)
|