From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Zhai, Edwin" Subject: [PATCH][QEMU] fix segmentation fault after hotplug pass-through device Date: Fri, 09 Apr 2010 17:01:01 +0800 Message-ID: <4BBEECCD.90203@intel.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060100010603050207020702" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: Ian Jackson Cc: Xen Developers , "Zhai, Edwin" List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --------------060100010603050207020702 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 Index: xen-dev/tools/ioemu-remote/hw/pt-msi.c =================================================================== --- xen-dev.orig/tools/ioemu-remote/hw/pt-msi.c +++ xen-dev/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-dev/tools/ioemu-remote/i386-dm/exec-dm.c =================================================================== --- xen-dev.orig/tools/ioemu-remote/i386-dm/exec-dm.c +++ xen-dev/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) - 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) -- best rgds, edwin --------------060100010603050207020702 Content-Type: text/plain; name="qemu-segfault.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu-segfault.patch" Index: xen-dev/tools/ioemu-remote/hw/pt-msi.c =================================================================== --- xen-dev.orig/tools/ioemu-remote/hw/pt-msi.c +++ xen-dev/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-dev/tools/ioemu-remote/i386-dm/exec-dm.c =================================================================== --- xen-dev.orig/tools/ioemu-remote/i386-dm/exec-dm.c +++ xen-dev/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) - 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) --------------060100010603050207020702 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --------------060100010603050207020702--