xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: "Zhai, Edwin" <edwin.zhai@intel.com>
To: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Xen Developers <xen-devel@lists.xensource.com>,
	"Zhai, Edwin" <edwin.zhai@intel.com>
Subject: [PATCH][QEMU] fix segmentation fault after hotplug pass-through device
Date: Fri, 09 Apr 2010 17:01:01 +0800	[thread overview]
Message-ID: <4BBEECCD.90203@intel.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2708 bytes --]

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-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; 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)


-- 
best rgds,
edwin


[-- Attachment #2: qemu-segfault.patch --]
[-- Type: text/plain, Size: 2177 bytes --]

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; 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)

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

                 reply	other threads:[~2010-04-09  9:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BBEECCD.90203@intel.com \
    --to=edwin.zhai@intel.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).