Quellcode durchsuchen

Merge remote-tracking branch 'bonzini/tags/for-upstream' into staging

A large set of small patches.  I have not included yet vhost-user-scsi,
but it'll come in the next pull request.

* use GDB XML register description for x86
* use _Static_assert in QEMU_BUILD_BUG_ON
* add "R:" to MAINTAINERS and get_maintainers
* checkpatch improvements
* dump threading fixes
* first part of vhost-user-scsi support
* QemuMutex tracing
* vmw_pvscsi and megasas fixes
* sgabios module update
* use Rev3 (ACPI 2.0) FADT
* deprecate -hdachs
* improve -accel documentation
* hax fix
* qemu-char GSource bugfix

# gpg: Signature made Fri 05 May 2017 06:10:40 AM EDT
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* bonzini/tags/for-upstream: (21 commits)
  vhost-scsi: create a vhost-scsi-common abstraction
  libvhost-user: replace vasprintf() to fix build
  get_maintainer: add subsystem to reviewer output
  get_maintainer: --r (list reviewer) is on by default
  get_maintainer: it's '--pattern-depth', not '-pattern-depth'
  get_maintainer: Teach get_maintainer.pl about the new "R:" tag
  MAINTAINERS: Add "R:" tag for self-appointed reviewers
  Fix the -accel parameter and the documentation for 'hax'
  dump: Acquire BQL around vm_start() in dump thread
  hax: Fix memory mapping de-duplication logic
  checkpatch: Disallow glib asserts in main code
  trace: add qemu mutex lock and unlock trace events
  vmw_pvscsi: check message ring page count at initialisation
  sgabios: update for "fix wrong video attrs for int 10h,ah==13h"
  scsi: avoid an off-by-one error in megasas_mmio_write
  vl: deprecate the "-hdachs" option
  use _Static_assert in QEMU_BUILD_BUG_ON
  target/i386: Add GDB XML register description support
  char: Fix removing wrong GSource that be found by fd_in_tag
  hw/i386: Build-time assertion on pc/q35 reset register being identical.
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Stefan Hajnoczi vor 8 Jahren
Ursprung
Commit
1c5d506101

+ 2 - 0
MAINTAINERS

@@ -12,6 +12,8 @@ consult qemu-devel and not any specific individual privately.
 Descriptions of section entries:
 Descriptions of section entries:
 
 
 	M: Mail patches to: FullName <address@domain>
 	M: Mail patches to: FullName <address@domain>
+	R: Designated reviewer: FullName <address@domain>
+	   These reviewers should be CCed on patches.
 	L: Mailing list that is relevant to this area
 	L: Mailing list that is relevant to this area
 	W: Web-page with status/info
 	W: Web-page with status/info
 	Q: Patchwork web based patch tracking system site
 	Q: Patchwork web based patch tracking system site

+ 4 - 4
chardev/char-fd.c

@@ -58,7 +58,7 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
     ret = qio_channel_read(
     ret = qio_channel_read(
         chan, (gchar *)buf, len, NULL);
         chan, (gchar *)buf, len, NULL);
     if (ret == 0) {
     if (ret == 0) {
-        remove_fd_in_watch(chr, NULL);
+        remove_fd_in_watch(chr);
         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
         qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
         return FALSE;
         return FALSE;
     }
     }
@@ -89,9 +89,9 @@ static void fd_chr_update_read_handler(Chardev *chr,
 {
 {
     FDChardev *s = FD_CHARDEV(chr);
     FDChardev *s = FD_CHARDEV(chr);
 
 
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     if (s->ioc_in) {
     if (s->ioc_in) {
-        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc_in,
+        chr->gsource = io_add_watch_poll(chr, s->ioc_in,
                                            fd_chr_read_poll,
                                            fd_chr_read_poll,
                                            fd_chr_read, chr,
                                            fd_chr_read, chr,
                                            context);
                                            context);
@@ -103,7 +103,7 @@ static void char_fd_finalize(Object *obj)
     Chardev *chr = CHARDEV(obj);
     Chardev *chr = CHARDEV(obj);
     FDChardev *s = FD_CHARDEV(obj);
     FDChardev *s = FD_CHARDEV(obj);
 
 
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     if (s->ioc_in) {
     if (s->ioc_in) {
         object_unref(OBJECT(s->ioc_in));
         object_unref(OBJECT(s->ioc_in));
     }
     }

+ 8 - 15
chardev/char-io.c

@@ -98,7 +98,7 @@ static GSourceFuncs io_watch_poll_funcs = {
     .finalize = io_watch_poll_finalize,
     .finalize = io_watch_poll_finalize,
 };
 };
 
 
-guint io_add_watch_poll(Chardev *chr,
+GSource *io_add_watch_poll(Chardev *chr,
                         QIOChannel *ioc,
                         QIOChannel *ioc,
                         IOCanReadHandler *fd_can_read,
                         IOCanReadHandler *fd_can_read,
                         QIOChannelFunc fd_read,
                         QIOChannelFunc fd_read,
@@ -106,7 +106,6 @@ guint io_add_watch_poll(Chardev *chr,
                         GMainContext *context)
                         GMainContext *context)
 {
 {
     IOWatchPoll *iwp;
     IOWatchPoll *iwp;
-    int tag;
     char *name;
     char *name;
 
 
     iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
     iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
@@ -122,21 +121,15 @@ guint io_add_watch_poll(Chardev *chr,
     g_source_set_name((GSource *)iwp, name);
     g_source_set_name((GSource *)iwp, name);
     g_free(name);
     g_free(name);
 
 
-    tag = g_source_attach(&iwp->parent, context);
+    g_source_attach(&iwp->parent, context);
     g_source_unref(&iwp->parent);
     g_source_unref(&iwp->parent);
-    return tag;
+    return (GSource *)iwp;
 }
 }
 
 
-static void io_remove_watch_poll(guint tag, GMainContext *context)
+static void io_remove_watch_poll(GSource *source)
 {
 {
-    GSource *source;
     IOWatchPoll *iwp;
     IOWatchPoll *iwp;
 
 
-    g_return_if_fail(tag > 0);
-
-    source = g_main_context_find_source_by_id(context, tag);
-    g_return_if_fail(source != NULL);
-
     iwp = io_watch_poll_from_source(source);
     iwp = io_watch_poll_from_source(source);
     if (iwp->src) {
     if (iwp->src) {
         g_source_destroy(iwp->src);
         g_source_destroy(iwp->src);
@@ -146,11 +139,11 @@ static void io_remove_watch_poll(guint tag, GMainContext *context)
     g_source_destroy(&iwp->parent);
     g_source_destroy(&iwp->parent);
 }
 }
 
 
-void remove_fd_in_watch(Chardev *chr, GMainContext *context)
+void remove_fd_in_watch(Chardev *chr)
 {
 {
-    if (chr->fd_in_tag) {
-        io_remove_watch_poll(chr->fd_in_tag, context);
-        chr->fd_in_tag = 0;
+    if (chr->gsource) {
+        io_remove_watch_poll(chr->gsource);
+        chr->gsource = NULL;
     }
     }
 }
 }
 
 

+ 2 - 2
chardev/char-io.h

@@ -29,14 +29,14 @@
 #include "sysemu/char.h"
 #include "sysemu/char.h"
 
 
 /* Can only be used for read */
 /* Can only be used for read */
-guint io_add_watch_poll(Chardev *chr,
+GSource *io_add_watch_poll(Chardev *chr,
                         QIOChannel *ioc,
                         QIOChannel *ioc,
                         IOCanReadHandler *fd_can_read,
                         IOCanReadHandler *fd_can_read,
                         QIOChannelFunc fd_read,
                         QIOChannelFunc fd_read,
                         gpointer user_data,
                         gpointer user_data,
                         GMainContext *context);
                         GMainContext *context);
 
 
-void remove_fd_in_watch(Chardev *chr, GMainContext *context);
+void remove_fd_in_watch(Chardev *chr);
 
 
 int io_channel_send(QIOChannel *ioc, const void *buf, size_t len);
 int io_channel_send(QIOChannel *ioc, const void *buf, size_t len);
 
 

+ 3 - 3
chardev/char-pty.c

@@ -199,7 +199,7 @@ static void pty_chr_state(Chardev *chr, int connected)
             g_source_remove(s->open_tag);
             g_source_remove(s->open_tag);
             s->open_tag = 0;
             s->open_tag = 0;
         }
         }
-        remove_fd_in_watch(chr, NULL);
+        remove_fd_in_watch(chr);
         s->connected = 0;
         s->connected = 0;
         /* (re-)connect poll interval for idle guests: once per second.
         /* (re-)connect poll interval for idle guests: once per second.
          * We check more frequently in case the guests sends data to
          * We check more frequently in case the guests sends data to
@@ -215,8 +215,8 @@ static void pty_chr_state(Chardev *chr, int connected)
             s->connected = 1;
             s->connected = 1;
             s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
             s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
         }
         }
-        if (!chr->fd_in_tag) {
-            chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
+        if (!chr->gsource) {
+            chr->gsource = io_add_watch_poll(chr, s->ioc,
                                                pty_chr_read_poll,
                                                pty_chr_read_poll,
                                                pty_chr_read,
                                                pty_chr_read,
                                                chr, NULL);
                                                chr, NULL);

+ 4 - 4
chardev/char-socket.c

@@ -346,7 +346,7 @@ static void tcp_chr_free_connection(Chardev *chr)
     }
     }
 
 
     tcp_set_msgfds(chr, NULL, 0);
     tcp_set_msgfds(chr, NULL, 0);
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     object_unref(OBJECT(s->sioc));
     object_unref(OBJECT(s->sioc));
     s->sioc = NULL;
     s->sioc = NULL;
     object_unref(OBJECT(s->ioc));
     object_unref(OBJECT(s->ioc));
@@ -511,7 +511,7 @@ static void tcp_chr_connect(void *opaque)
 
 
     s->connected = 1;
     s->connected = 1;
     if (s->ioc) {
     if (s->ioc) {
-        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
+        chr->gsource = io_add_watch_poll(chr, s->ioc,
                                            tcp_chr_read_poll,
                                            tcp_chr_read_poll,
                                            tcp_chr_read,
                                            tcp_chr_read,
                                            chr, NULL);
                                            chr, NULL);
@@ -528,9 +528,9 @@ static void tcp_chr_update_read_handler(Chardev *chr,
         return;
         return;
     }
     }
 
 
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     if (s->ioc) {
     if (s->ioc) {
-        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
+        chr->gsource = io_add_watch_poll(chr, s->ioc,
                                            tcp_chr_read_poll,
                                            tcp_chr_read_poll,
                                            tcp_chr_read, chr,
                                            tcp_chr_read, chr,
                                            context);
                                            context);

+ 4 - 4
chardev/char-udp.c

@@ -90,7 +90,7 @@ static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
     ret = qio_channel_read(
     ret = qio_channel_read(
         s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
         s->ioc, (char *)s->buf, sizeof(s->buf), NULL);
     if (ret <= 0) {
     if (ret <= 0) {
-        remove_fd_in_watch(chr, NULL);
+        remove_fd_in_watch(chr);
         return FALSE;
         return FALSE;
     }
     }
     s->bufcnt = ret;
     s->bufcnt = ret;
@@ -105,9 +105,9 @@ static void udp_chr_update_read_handler(Chardev *chr,
 {
 {
     UdpChardev *s = UDP_CHARDEV(chr);
     UdpChardev *s = UDP_CHARDEV(chr);
 
 
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     if (s->ioc) {
     if (s->ioc) {
-        chr->fd_in_tag = io_add_watch_poll(chr, s->ioc,
+        chr->gsource = io_add_watch_poll(chr, s->ioc,
                                            udp_chr_read_poll,
                                            udp_chr_read_poll,
                                            udp_chr_read, chr,
                                            udp_chr_read, chr,
                                            context);
                                            context);
@@ -119,7 +119,7 @@ static void char_udp_finalize(Object *obj)
     Chardev *chr = CHARDEV(obj);
     Chardev *chr = CHARDEV(obj);
     UdpChardev *s = UDP_CHARDEV(obj);
     UdpChardev *s = UDP_CHARDEV(obj);
 
 
-    remove_fd_in_watch(chr, NULL);
+    remove_fd_in_watch(chr);
     if (s->ioc) {
     if (s->ioc) {
         object_unref(OBJECT(s->ioc));
         object_unref(OBJECT(s->ioc));
     }
     }

+ 1 - 1
chardev/char.c

@@ -554,7 +554,7 @@ void qemu_chr_fe_set_handlers(CharBackend *b,
     cc = CHARDEV_GET_CLASS(s);
     cc = CHARDEV_GET_CLASS(s);
     if (!opaque && !fd_can_read && !fd_read && !fd_event) {
     if (!opaque && !fd_can_read && !fd_read && !fd_event) {
         fe_open = 0;
         fe_open = 0;
-        remove_fd_in_watch(s, context);
+        remove_fd_in_watch(s);
     } else {
     } else {
         fe_open = 1;
         fe_open = 1;
     }
     }

+ 20 - 0
configure

@@ -4852,6 +4852,20 @@ EOF
   fi
   fi
 fi
 fi
 
 
+##########################################
+# check for _Static_assert()
+
+have_static_assert=no
+cat > $TMPC << EOF
+_Static_assert(1, "success");
+int main(void) {
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+    have_static_assert=yes
+fi
+
 ##########################################
 ##########################################
 # End of CC checks
 # End of CC checks
 # After here, no more $cc or $ld runs
 # After here, no more $cc or $ld runs
@@ -5848,6 +5862,10 @@ if test "$have_sysmacros" = "yes" ; then
   echo "CONFIG_SYSMACROS=y" >> $config_host_mak
   echo "CONFIG_SYSMACROS=y" >> $config_host_mak
 fi
 fi
 
 
+if test "$have_static_assert" = "yes" ; then
+  echo "CONFIG_STATIC_ASSERT=y" >> $config_host_mak
+fi
+
 # Hold two types of flag:
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 #                                     a thread we have a handle to
 #                                     a thread we have a handle to
@@ -6023,9 +6041,11 @@ TARGET_ABI_DIR=""
 
 
 case "$target_name" in
 case "$target_name" in
   i386)
   i386)
+    gdb_xml_files="i386-32bit-core.xml"
   ;;
   ;;
   x86_64)
   x86_64)
     TARGET_BASE_ARCH=i386
     TARGET_BASE_ARCH=i386
+    gdb_xml_files="i386-64bit-core.xml"
   ;;
   ;;
   alpha)
   alpha)
     mttcg="yes"
     mttcg="yes"

+ 1 - 1
contrib/libvhost-user/libvhost-user.c

@@ -81,7 +81,7 @@ vu_panic(VuDev *dev, const char *msg, ...)
     va_list ap;
     va_list ap;
 
 
     va_start(ap, msg);
     va_start(ap, msg);
-    (void)vasprintf(&buf, msg, ap);
+    buf = g_strdup_vprintf(msg, ap);
     va_end(ap);
     va_end(ap);
 
 
     dev->broken = true;
     dev->broken = true;

+ 7 - 0
dump.c

@@ -77,7 +77,13 @@ static int dump_cleanup(DumpState *s)
     memory_mapping_list_free(&s->list);
     memory_mapping_list_free(&s->list);
     close(s->fd);
     close(s->fd);
     if (s->resume) {
     if (s->resume) {
+        if (s->detached) {
+            qemu_mutex_lock_iothread();
+        }
         vm_start();
         vm_start();
+        if (s->detached) {
+            qemu_mutex_unlock_iothread();
+        }
     }
     }
 
 
     return 0;
     return 0;
@@ -1804,6 +1810,7 @@ void qmp_dump_guest_memory(bool paging, const char *file,
 
 
     if (detach_p) {
     if (detach_p) {
         /* detached dump */
         /* detached dump */
+        s->detached = true;
         qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
         qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
                            s, QEMU_THREAD_DETACHED);
                            s, QEMU_THREAD_DETACHED);
     } else {
     } else {

+ 65 - 0
gdb-xml/i386-32bit-core.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.i386.core">
+  <flags id="i386_eflags" size="4">
+    <field name="CF" start="0" end="0"/>
+    <field name="" start="1" end="1"/>
+    <field name="PF" start="2" end="2"/>
+    <field name="AF" start="4" end="4"/>
+    <field name="ZF" start="6" end="6"/>
+    <field name="SF" start="7" end="7"/>
+    <field name="TF" start="8" end="8"/>
+    <field name="IF" start="9" end="9"/>
+    <field name="DF" start="10" end="10"/>
+    <field name="OF" start="11" end="11"/>
+    <field name="NT" start="14" end="14"/>
+    <field name="RF" start="16" end="16"/>
+    <field name="VM" start="17" end="17"/>
+    <field name="AC" start="18" end="18"/>
+    <field name="VIF" start="19" end="19"/>
+    <field name="VIP" start="20" end="20"/>
+    <field name="ID" start="21" end="21"/>
+  </flags>
+
+  <reg name="eax" bitsize="32" type="int32"/>
+  <reg name="ecx" bitsize="32" type="int32"/>
+  <reg name="edx" bitsize="32" type="int32"/>
+  <reg name="ebx" bitsize="32" type="int32"/>
+  <reg name="esp" bitsize="32" type="data_ptr"/>
+  <reg name="ebp" bitsize="32" type="data_ptr"/>
+  <reg name="esi" bitsize="32" type="int32"/>
+  <reg name="edi" bitsize="32" type="int32"/>
+
+  <reg name="eip" bitsize="32" type="code_ptr"/>
+  <reg name="eflags" bitsize="32" type="i386_eflags"/>
+  <reg name="cs" bitsize="32" type="int32"/>
+  <reg name="ss" bitsize="32" type="int32"/>
+  <reg name="ds" bitsize="32" type="int32"/>
+  <reg name="es" bitsize="32" type="int32"/>
+  <reg name="fs" bitsize="32" type="int32"/>
+  <reg name="gs" bitsize="32" type="int32"/>
+
+  <reg name="st0" bitsize="80" type="i387_ext"/>
+  <reg name="st1" bitsize="80" type="i387_ext"/>
+  <reg name="st2" bitsize="80" type="i387_ext"/>
+  <reg name="st3" bitsize="80" type="i387_ext"/>
+  <reg name="st4" bitsize="80" type="i387_ext"/>
+  <reg name="st5" bitsize="80" type="i387_ext"/>
+  <reg name="st6" bitsize="80" type="i387_ext"/>
+  <reg name="st7" bitsize="80" type="i387_ext"/>
+
+  <reg name="fctrl" bitsize="32" type="int" group="float"/>
+  <reg name="fstat" bitsize="32" type="int" group="float"/>
+  <reg name="ftag" bitsize="32" type="int" group="float"/>
+  <reg name="fiseg" bitsize="32" type="int" group="float"/>
+  <reg name="fioff" bitsize="32" type="int" group="float"/>
+  <reg name="foseg" bitsize="32" type="int" group="float"/>
+  <reg name="fooff" bitsize="32" type="int" group="float"/>
+  <reg name="fop" bitsize="32" type="int" group="float"/>
+</feature>

+ 73 - 0
gdb-xml/i386-64bit-core.xml

@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.i386.core">
+  <flags id="i386_eflags" size="4">
+    <field name="CF" start="0" end="0"/>
+    <field name="" start="1" end="1"/>
+    <field name="PF" start="2" end="2"/>
+    <field name="AF" start="4" end="4"/>
+    <field name="ZF" start="6" end="6"/>
+    <field name="SF" start="7" end="7"/>
+    <field name="TF" start="8" end="8"/>
+    <field name="IF" start="9" end="9"/>
+    <field name="DF" start="10" end="10"/>
+    <field name="OF" start="11" end="11"/>
+    <field name="NT" start="14" end="14"/>
+    <field name="RF" start="16" end="16"/>
+    <field name="VM" start="17" end="17"/>
+    <field name="AC" start="18" end="18"/>
+    <field name="VIF" start="19" end="19"/>
+    <field name="VIP" start="20" end="20"/>
+    <field name="ID" start="21" end="21"/>
+  </flags>
+
+  <reg name="rax" bitsize="64" type="int64"/>
+  <reg name="rbx" bitsize="64" type="int64"/>
+  <reg name="rcx" bitsize="64" type="int64"/>
+  <reg name="rdx" bitsize="64" type="int64"/>
+  <reg name="rsi" bitsize="64" type="int64"/>
+  <reg name="rdi" bitsize="64" type="int64"/>
+  <reg name="rbp" bitsize="64" type="data_ptr"/>
+  <reg name="rsp" bitsize="64" type="data_ptr"/>
+  <reg name="r8" bitsize="64" type="int64"/>
+  <reg name="r9" bitsize="64" type="int64"/>
+  <reg name="r10" bitsize="64" type="int64"/>
+  <reg name="r11" bitsize="64" type="int64"/>
+  <reg name="r12" bitsize="64" type="int64"/>
+  <reg name="r13" bitsize="64" type="int64"/>
+  <reg name="r14" bitsize="64" type="int64"/>
+  <reg name="r15" bitsize="64" type="int64"/>
+
+  <reg name="rip" bitsize="64" type="code_ptr"/>
+  <reg name="eflags" bitsize="32" type="i386_eflags"/>
+  <reg name="cs" bitsize="32" type="int32"/>
+  <reg name="ss" bitsize="32" type="int32"/>
+  <reg name="ds" bitsize="32" type="int32"/>
+  <reg name="es" bitsize="32" type="int32"/>
+  <reg name="fs" bitsize="32" type="int32"/>
+  <reg name="gs" bitsize="32" type="int32"/>
+
+  <reg name="st0" bitsize="80" type="i387_ext"/>
+  <reg name="st1" bitsize="80" type="i387_ext"/>
+  <reg name="st2" bitsize="80" type="i387_ext"/>
+  <reg name="st3" bitsize="80" type="i387_ext"/>
+  <reg name="st4" bitsize="80" type="i387_ext"/>
+  <reg name="st5" bitsize="80" type="i387_ext"/>
+  <reg name="st6" bitsize="80" type="i387_ext"/>
+  <reg name="st7" bitsize="80" type="i387_ext"/>
+
+  <reg name="fctrl" bitsize="32" type="int" group="float"/>
+  <reg name="fstat" bitsize="32" type="int" group="float"/>
+  <reg name="ftag" bitsize="32" type="int" group="float"/>
+  <reg name="fiseg" bitsize="32" type="int" group="float"/>
+  <reg name="fioff" bitsize="32" type="int" group="float"/>
+  <reg name="foseg" bitsize="32" type="int" group="float"/>
+  <reg name="fooff" bitsize="32" type="int" group="float"/>
+  <reg name="fop" bitsize="32" type="int" group="float"/>
+</feature>

+ 32 - 3
hw/i386/acpi-build.c

@@ -272,7 +272,7 @@ build_facs(GArray *table_data, BIOSLinker *linker)
 }
 }
 
 
 /* Load chipset information in FADT */
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
 {
 {
     fadt->model = 1;
     fadt->model = 1;
     fadt->reserved1 = 0;
     fadt->reserved1 = 0;
@@ -304,6 +304,31 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
         fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
     }
     }
     fadt->century = RTC_CENTURY;
     fadt->century = RTC_CENTURY;
+
+    fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
+    fadt->reset_value = 0xf;
+    fadt->reset_register.space_id = AML_SYSTEM_IO;
+    fadt->reset_register.bit_width = 8;
+    fadt->reset_register.address = cpu_to_le64(ICH9_RST_CNT_IOPORT);
+    /* The above need not be conditional on machine type because the reset port
+     * happens to be the same on PIIX (pc) and ICH9 (q35). */
+    QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != RCR_IOPORT);
+
+    fadt->xpm1a_event_block.space_id = AML_SYSTEM_IO;
+    fadt->xpm1a_event_block.bit_width = fadt->pm1_evt_len * 8;
+    fadt->xpm1a_event_block.address = cpu_to_le64(pm->io_base);
+
+    fadt->xpm1a_control_block.space_id = AML_SYSTEM_IO;
+    fadt->xpm1a_control_block.bit_width = fadt->pm1_cnt_len * 8;
+    fadt->xpm1a_control_block.address = cpu_to_le64(pm->io_base + 0x4);
+
+    fadt->xpm_timer_block.space_id = AML_SYSTEM_IO;
+    fadt->xpm_timer_block.bit_width = fadt->pm_tmr_len * 8;
+    fadt->xpm_timer_block.address = cpu_to_le64(pm->io_base + 0x8);
+
+    fadt->xgpe0_block.space_id = AML_SYSTEM_IO;
+    fadt->xgpe0_block.bit_width = pm->gpe0_blk_len * 8;
+    fadt->xgpe0_block.address = cpu_to_le64(pm->gpe0_blk);
 }
 }
 
 
 
 
@@ -313,9 +338,10 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
            unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
            const char *oem_id, const char *oem_table_id)
            const char *oem_id, const char *oem_table_id)
 {
 {
-    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+    AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, sizeof(*fadt));
     unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
     unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
     unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
     unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+    unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
 
 
     /* FACS address to be filled by Guest linker */
     /* FACS address to be filled by Guest linker */
     bios_linker_loader_add_pointer(linker,
     bios_linker_loader_add_pointer(linker,
@@ -327,9 +353,12 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
     bios_linker_loader_add_pointer(linker,
     bios_linker_loader_add_pointer(linker,
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
         ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+    bios_linker_loader_add_pointer(linker,
+        ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt),
+        ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
 
     build_header(linker, table_data,
     build_header(linker, table_data,
-                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+                 (void *)fadt, "FACP", sizeof(*fadt), 3, oem_id, oem_table_id);
 }
 }
 
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,

+ 0 - 6
hw/pci-host/piix.c

@@ -58,12 +58,6 @@ typedef struct I440FXState {
 #define XEN_PIIX_NUM_PIRQS      128ULL
 #define XEN_PIIX_NUM_PIRQS      128ULL
 #define PIIX_PIRQC              0x60
 #define PIIX_PIRQC              0x60
 
 
-/*
- * Reset Control Register: PCI-accessible ISA-Compatible Register at address
- * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
- */
-#define RCR_IOPORT 0xcf9
-
 typedef struct PIIX3State {
 typedef struct PIIX3State {
     PCIDevice dev;
     PCIDevice dev;
 
 

+ 1 - 1
hw/scsi/Makefile.objs

@@ -10,5 +10,5 @@ obj-$(CONFIG_PSERIES) += spapr_vscsi.o
 
 
 ifeq ($(CONFIG_VIRTIO),y)
 ifeq ($(CONFIG_VIRTIO),y)
 obj-y += virtio-scsi.o virtio-scsi-dataplane.o
 obj-y += virtio-scsi.o virtio-scsi-dataplane.o
-obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
+obj-$(CONFIG_VHOST_SCSI) += vhost-scsi-common.o vhost-scsi.o
 endif
 endif

+ 5 - 5
hw/scsi/megasas.c

@@ -2138,15 +2138,15 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
     case MFI_SEQ:
     case MFI_SEQ:
         trace_megasas_mmio_writel("MFI_SEQ", val);
         trace_megasas_mmio_writel("MFI_SEQ", val);
         /* Magic sequence to start ADP reset */
         /* Magic sequence to start ADP reset */
-        if (adp_reset_seq[s->adp_reset] == val) {
-            s->adp_reset++;
+        if (adp_reset_seq[s->adp_reset++] == val) {
+            if (s->adp_reset == 6) {
+                s->adp_reset = 0;
+                s->diag = MFI_DIAG_WRITE_ENABLE;
+            }
         } else {
         } else {
             s->adp_reset = 0;
             s->adp_reset = 0;
             s->diag = 0;
             s->diag = 0;
         }
         }
-        if (s->adp_reset == 6) {
-            s->diag = MFI_DIAG_WRITE_ENABLE;
-        }
         break;
         break;
     case MFI_DIAG:
     case MFI_DIAG:
         trace_megasas_mmio_writel("MFI_DIAG", val);
         trace_megasas_mmio_writel("MFI_DIAG", val);

+ 143 - 0
hw/scsi/vhost-scsi-common.c

@@ -0,0 +1,143 @@
+/*
+ * vhost-scsi-common
+ *
+ * Copyright (c) 2016 Nutanix Inc. All rights reserved.
+ *
+ * Author:
+ *  Felipe Franciosi <felipe@nutanix.com>
+ *
+ * This work is largely based on the "vhost-scsi" implementation by:
+ *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
+ *  Nicholas Bellinger <nab@risingtidesystems.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include <linux/vhost.h>
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "migration/migration.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-scsi-common.h"
+#include "hw/virtio/virtio-scsi.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "hw/fw-path-provider.h"
+
+int vhost_scsi_common_start(VHostSCSICommon *vsc)
+{
+    int ret, i;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+
+    if (!k->set_guest_notifiers) {
+        error_report("binding does not support guest notifiers");
+        return -ENOSYS;
+    }
+
+    ret = vhost_dev_enable_notifiers(&vsc->dev, vdev);
+    if (ret < 0) {
+        return ret;
+    }
+
+    ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true);
+    if (ret < 0) {
+        error_report("Error binding guest notifier");
+        goto err_host_notifiers;
+    }
+
+    vsc->dev.acked_features = vdev->guest_features;
+    ret = vhost_dev_start(&vsc->dev, vdev);
+    if (ret < 0) {
+        error_report("Error start vhost dev");
+        goto err_guest_notifiers;
+    }
+
+    /* guest_notifier_mask/pending not used yet, so just unmask
+     * everything here.  virtio-pci will do the right thing by
+     * enabling/disabling irqfd.
+     */
+    for (i = 0; i < vsc->dev.nvqs; i++) {
+        vhost_virtqueue_mask(&vsc->dev, vdev, vsc->dev.vq_index + i, false);
+    }
+
+    return ret;
+
+err_guest_notifiers:
+    k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
+err_host_notifiers:
+    vhost_dev_disable_notifiers(&vsc->dev, vdev);
+    return ret;
+}
+
+void vhost_scsi_common_stop(VHostSCSICommon *vsc)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
+    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+    int ret = 0;
+
+    vhost_dev_stop(&vsc->dev, vdev);
+
+    if (k->set_guest_notifiers) {
+        ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
+        if (ret < 0) {
+                error_report("vhost guest notifier cleanup failed: %d", ret);
+        }
+    }
+    assert(ret >= 0);
+
+    vhost_dev_disable_notifiers(&vsc->dev, vdev);
+}
+
+uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features,
+                                        Error **errp)
+{
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);
+
+    return vhost_get_features(&vsc->dev, vsc->feature_bits, features);
+}
+
+void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config)
+{
+    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
+    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
+
+    if ((uint32_t)virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
+        (uint32_t)virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
+        error_report("vhost-scsi does not support changing the sense data and "
+                     "CDB sizes");
+        exit(1);
+    }
+}
+
+/*
+ * Implementation of an interface to adjust firmware path
+ * for the bootindex property handling.
+ */
+char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+                                        DeviceState *dev)
+{
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
+    /* format: /channel@channel/vhost-scsi@target,lun */
+    return g_strdup_printf("/channel@%x/%s@%x,%x", vsc->channel,
+                           qdev_fw_name(dev), vsc->target, vsc->lun);
+}
+
+static const TypeInfo vhost_scsi_common_info = {
+    .name = TYPE_VHOST_SCSI_COMMON,
+    .parent = TYPE_VIRTIO_SCSI_COMMON,
+    .instance_size = sizeof(VHostSCSICommon),
+    .abstract = true,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&vhost_scsi_common_info);
+}
+
+type_init(virtio_register_types)

+ 56 - 138
hw/scsi/vhost-scsi.c

@@ -42,13 +42,14 @@ static const int kernel_feature_bits[] = {
 static int vhost_scsi_set_endpoint(VHostSCSI *s)
 static int vhost_scsi_set_endpoint(VHostSCSI *s)
 {
 {
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
-    const VhostOps *vhost_ops = s->dev.vhost_ops;
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+    const VhostOps *vhost_ops = vsc->dev.vhost_ops;
     struct vhost_scsi_target backend;
     struct vhost_scsi_target backend;
     int ret;
     int ret;
 
 
     memset(&backend, 0, sizeof(backend));
     memset(&backend, 0, sizeof(backend));
     pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
     pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
-    ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend);
+    ret = vhost_ops->vhost_scsi_set_endpoint(&vsc->dev, &backend);
     if (ret < 0) {
     if (ret < 0) {
         return -errno;
         return -errno;
     }
     }
@@ -58,130 +59,62 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s)
 static void vhost_scsi_clear_endpoint(VHostSCSI *s)
 static void vhost_scsi_clear_endpoint(VHostSCSI *s)
 {
 {
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
     struct vhost_scsi_target backend;
     struct vhost_scsi_target backend;
-    const VhostOps *vhost_ops = s->dev.vhost_ops;
+    const VhostOps *vhost_ops = vsc->dev.vhost_ops;
 
 
     memset(&backend, 0, sizeof(backend));
     memset(&backend, 0, sizeof(backend));
     pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
     pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
-    vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend);
+    vhost_ops->vhost_scsi_clear_endpoint(&vsc->dev, &backend);
 }
 }
 
 
 static int vhost_scsi_start(VHostSCSI *s)
 static int vhost_scsi_start(VHostSCSI *s)
 {
 {
-    int ret, abi_version, i;
-    VirtIODevice *vdev = VIRTIO_DEVICE(s);
-    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-    const VhostOps *vhost_ops = s->dev.vhost_ops;
-
-    if (!k->set_guest_notifiers) {
-        error_report("binding does not support guest notifiers");
-        return -ENOSYS;
-    }
+    int ret, abi_version;
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+    const VhostOps *vhost_ops = vsc->dev.vhost_ops;
 
 
-    ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version);
+    ret = vhost_ops->vhost_scsi_get_abi_version(&vsc->dev, &abi_version);
     if (ret < 0) {
     if (ret < 0) {
         return -errno;
         return -errno;
     }
     }
     if (abi_version > VHOST_SCSI_ABI_VERSION) {
     if (abi_version > VHOST_SCSI_ABI_VERSION) {
         error_report("vhost-scsi: The running tcm_vhost kernel abi_version:"
         error_report("vhost-scsi: The running tcm_vhost kernel abi_version:"
-                     " %d is greater than vhost_scsi userspace supports: %d, please"
-                     " upgrade your version of QEMU", abi_version,
+                     " %d is greater than vhost_scsi userspace supports: %d,"
+                     " please upgrade your version of QEMU", abi_version,
                      VHOST_SCSI_ABI_VERSION);
                      VHOST_SCSI_ABI_VERSION);
         return -ENOSYS;
         return -ENOSYS;
     }
     }
 
 
-    ret = vhost_dev_enable_notifiers(&s->dev, vdev);
+    ret = vhost_scsi_common_start(vsc);
     if (ret < 0) {
     if (ret < 0) {
         return ret;
         return ret;
     }
     }
 
 
-    s->dev.acked_features = vdev->guest_features;
-    ret = vhost_dev_start(&s->dev, vdev);
-    if (ret < 0) {
-        error_report("Error start vhost dev");
-        goto err_notifiers;
-    }
-
     ret = vhost_scsi_set_endpoint(s);
     ret = vhost_scsi_set_endpoint(s);
     if (ret < 0) {
     if (ret < 0) {
-        error_report("Error set vhost-scsi endpoint");
-        goto err_vhost_stop;
-    }
-
-    ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true);
-    if (ret < 0) {
-        error_report("Error binding guest notifier");
-        goto err_endpoint;
-    }
-
-    /* guest_notifier_mask/pending not used yet, so just unmask
-     * everything here.  virtio-pci will do the right thing by
-     * enabling/disabling irqfd.
-     */
-    for (i = 0; i < s->dev.nvqs; i++) {
-        vhost_virtqueue_mask(&s->dev, vdev, s->dev.vq_index + i, false);
+        error_report("Error setting vhost-scsi endpoint");
+        vhost_scsi_common_stop(vsc);
     }
     }
 
 
     return ret;
     return ret;
-
-err_endpoint:
-    vhost_scsi_clear_endpoint(s);
-err_vhost_stop:
-    vhost_dev_stop(&s->dev, vdev);
-err_notifiers:
-    vhost_dev_disable_notifiers(&s->dev, vdev);
-    return ret;
 }
 }
 
 
 static void vhost_scsi_stop(VHostSCSI *s)
 static void vhost_scsi_stop(VHostSCSI *s)
 {
 {
-    VirtIODevice *vdev = VIRTIO_DEVICE(s);
-    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
-    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
-    int ret = 0;
-
-    if (k->set_guest_notifiers) {
-        ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
-        if (ret < 0) {
-                error_report("vhost guest notifier cleanup failed: %d", ret);
-        }
-    }
-    assert(ret >= 0);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
 
 
     vhost_scsi_clear_endpoint(s);
     vhost_scsi_clear_endpoint(s);
-    vhost_dev_stop(&s->dev, vdev);
-    vhost_dev_disable_notifiers(&s->dev, vdev);
-}
-
-static uint64_t vhost_scsi_get_features(VirtIODevice *vdev,
-                                        uint64_t features,
-                                        Error **errp)
-{
-    VHostSCSI *s = VHOST_SCSI(vdev);
-
-    return vhost_get_features(&s->dev, kernel_feature_bits, features);
-}
-
-static void vhost_scsi_set_config(VirtIODevice *vdev,
-                                  const uint8_t *config)
-{
-    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
-    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
-
-    if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
-        (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
-        error_report("vhost-scsi does not support changing the sense data and CDB sizes");
-        exit(1);
-    }
+    vhost_scsi_common_stop(vsc);
 }
 }
 
 
 static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
 static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
 {
 {
-    VHostSCSI *s = (VHostSCSI *)vdev;
+    VHostSCSI *s = VHOST_SCSI(vdev);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
     bool start = (val & VIRTIO_CONFIG_S_DRIVER_OK);
     bool start = (val & VIRTIO_CONFIG_S_DRIVER_OK);
 
 
-    if (s->dev.started == start) {
+    if (vsc->dev.started == start) {
         return;
         return;
     }
     }
 
 
@@ -190,10 +123,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
 
 
         ret = vhost_scsi_start(s);
         ret = vhost_scsi_start(s);
         if (ret < 0) {
         if (ret < 0) {
-            error_report("virtio-scsi: unable to start vhost: %s",
-                         strerror(-ret));
-
-            /* There is no userspace virtio-scsi fallback so exit */
+            error_report("unable to start vhost-scsi: %s", strerror(-ret));
             exit(1);
             exit(1);
         }
         }
     } else {
     } else {
@@ -208,7 +138,7 @@ static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 static void vhost_scsi_realize(DeviceState *dev, Error **errp)
 static void vhost_scsi_realize(DeviceState *dev, Error **errp)
 {
 {
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
-    VHostSCSI *s = VHOST_SCSI(dev);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
     Error *err = NULL;
     Error *err = NULL;
     int vhostfd = -1;
     int vhostfd = -1;
     int ret;
     int ret;
@@ -243,21 +173,21 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
         goto close_fd;
         goto close_fd;
     }
     }
 
 
-    error_setg(&s->migration_blocker,
+    error_setg(&vsc->migration_blocker,
                "vhost-scsi does not support migration");
                "vhost-scsi does not support migration");
-    migrate_add_blocker(s->migration_blocker, &err);
+    migrate_add_blocker(vsc->migration_blocker, &err);
     if (err) {
     if (err) {
         error_propagate(errp, err);
         error_propagate(errp, err);
-        error_free(s->migration_blocker);
+        error_free(vsc->migration_blocker);
         goto close_fd;
         goto close_fd;
     }
     }
 
 
-    s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
-    s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs);
-    s->dev.vq_index = 0;
-    s->dev.backend_features = 0;
+    vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
+    vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
+    vsc->dev.vq_index = 0;
+    vsc->dev.backend_features = 0;
 
 
-    ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd,
+    ret = vhost_dev_init(&vsc->dev, (void *)(uintptr_t)vhostfd,
                          VHOST_BACKEND_TYPE_KERNEL, 0);
                          VHOST_BACKEND_TYPE_KERNEL, 0);
     if (ret < 0) {
     if (ret < 0) {
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
         error_setg(errp, "vhost-scsi: vhost initialization failed: %s",
@@ -266,16 +196,16 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
     }
     }
 
 
     /* At present, channel and lun both are 0 for bootable vhost-scsi disk */
     /* At present, channel and lun both are 0 for bootable vhost-scsi disk */
-    s->channel = 0;
-    s->lun = 0;
+    vsc->channel = 0;
+    vsc->lun = 0;
     /* Note: we can also get the minimum tpgt from kernel */
     /* Note: we can also get the minimum tpgt from kernel */
-    s->target = vs->conf.boot_tpgt;
+    vsc->target = vs->conf.boot_tpgt;
 
 
     return;
     return;
 
 
  free_vqs:
  free_vqs:
-    migrate_del_blocker(s->migration_blocker);
-    g_free(s->dev.vqs);
+    migrate_del_blocker(vsc->migration_blocker);
+    g_free(vsc->dev.vqs);
  close_fd:
  close_fd:
     close(vhostfd);
     close(vhostfd);
     return;
     return;
@@ -284,42 +214,28 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp)
 static void vhost_scsi_unrealize(DeviceState *dev, Error **errp)
 static void vhost_scsi_unrealize(DeviceState *dev, Error **errp)
 {
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    VHostSCSI *s = VHOST_SCSI(dev);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
 
 
-    migrate_del_blocker(s->migration_blocker);
-    error_free(s->migration_blocker);
+    migrate_del_blocker(vsc->migration_blocker);
+    error_free(vsc->migration_blocker);
 
 
     /* This will stop vhost backend. */
     /* This will stop vhost backend. */
     vhost_scsi_set_status(vdev, 0);
     vhost_scsi_set_status(vdev, 0);
 
 
-    vhost_dev_cleanup(&s->dev);
-    g_free(s->dev.vqs);
+    vhost_dev_cleanup(&vsc->dev);
+    g_free(vsc->dev.vqs);
 
 
     virtio_scsi_common_unrealize(dev, errp);
     virtio_scsi_common_unrealize(dev, errp);
 }
 }
 
 
-/*
- * Implementation of an interface to adjust firmware path
- * for the bootindex property handling.
- */
-static char *vhost_scsi_get_fw_dev_path(FWPathProvider *p, BusState *bus,
-                                        DeviceState *dev)
-{
-    VHostSCSI *s = VHOST_SCSI(dev);
-    /* format: channel@channel/vhost-scsi@target,lun */
-    return g_strdup_printf("/channel@%x/%s@%x,%x", s->channel,
-                           qdev_fw_name(dev), s->target, s->lun);
-}
-
 static Property vhost_scsi_properties[] = {
 static Property vhost_scsi_properties[] = {
-    DEFINE_PROP_STRING("vhostfd", VHostSCSI, parent_obj.conf.vhostfd),
-    DEFINE_PROP_STRING("wwpn", VHostSCSI, parent_obj.conf.wwpn),
-    DEFINE_PROP_UINT32("boot_tpgt", VHostSCSI, parent_obj.conf.boot_tpgt, 0),
-    DEFINE_PROP_UINT32("num_queues", VHostSCSI, parent_obj.conf.num_queues, 1),
-    DEFINE_PROP_UINT32("max_sectors", VHostSCSI, parent_obj.conf.max_sectors,
-                                                 0xFFFF),
-    DEFINE_PROP_UINT32("cmd_per_lun", VHostSCSI, parent_obj.conf.cmd_per_lun,
-                                                 128),
+    DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd),
+    DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn),
+    DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
+    DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues, 1),
+    DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors,
+                       0xFFFF),
+    DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSICommon, conf.cmd_per_lun, 128),
     DEFINE_PROP_END_OF_LIST(),
     DEFINE_PROP_END_OF_LIST(),
 };
 };
 
 
@@ -333,23 +249,25 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     vdc->realize = vhost_scsi_realize;
     vdc->realize = vhost_scsi_realize;
     vdc->unrealize = vhost_scsi_unrealize;
     vdc->unrealize = vhost_scsi_unrealize;
-    vdc->get_features = vhost_scsi_get_features;
-    vdc->set_config = vhost_scsi_set_config;
+    vdc->get_features = vhost_scsi_common_get_features;
+    vdc->set_config = vhost_scsi_common_set_config;
     vdc->set_status = vhost_scsi_set_status;
     vdc->set_status = vhost_scsi_set_status;
-    fwc->get_dev_path = vhost_scsi_get_fw_dev_path;
+    fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path;
 }
 }
 
 
 static void vhost_scsi_instance_init(Object *obj)
 static void vhost_scsi_instance_init(Object *obj)
 {
 {
-    VHostSCSI *dev = VHOST_SCSI(obj);
+    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(obj);
+
+    vsc->feature_bits = kernel_feature_bits;
 
 
-    device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL,
-                                  DEVICE(dev), NULL);
+    device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL,
+                                  DEVICE(vsc), NULL);
 }
 }
 
 
 static const TypeInfo vhost_scsi_info = {
 static const TypeInfo vhost_scsi_info = {
     .name = TYPE_VHOST_SCSI,
     .name = TYPE_VHOST_SCSI,
-    .parent = TYPE_VIRTIO_SCSI_COMMON,
+    .parent = TYPE_VHOST_SCSI_COMMON,
     .instance_size = sizeof(VHostSCSI),
     .instance_size = sizeof(VHostSCSI),
     .class_init = vhost_scsi_class_init,
     .class_init = vhost_scsi_class_init,
     .instance_init = vhost_scsi_instance_init,
     .instance_init = vhost_scsi_instance_init,

+ 1 - 1
hw/scsi/vmw_pvscsi.c

@@ -202,7 +202,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
     uint32_t len_log2;
     uint32_t len_log2;
     uint32_t ring_size;
     uint32_t ring_size;
 
 
-    if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
+    if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
         return -1;
         return -1;
     }
     }
     ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
     ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;

+ 36 - 41
include/hw/acpi/acpi-defs.h

@@ -131,17 +131,37 @@ typedef struct AcpiTableHeader AcpiTableHeader;
     uint8_t  duty_width;   /* Bit width of duty cycle field in p_cnt reg */ \
     uint8_t  duty_width;   /* Bit width of duty cycle field in p_cnt reg */ \
     uint8_t  day_alrm;     /* Index to day-of-month alarm in RTC CMOS RAM */ \
     uint8_t  day_alrm;     /* Index to day-of-month alarm in RTC CMOS RAM */ \
     uint8_t  mon_alrm;     /* Index to month-of-year alarm in RTC CMOS RAM */ \
     uint8_t  mon_alrm;     /* Index to month-of-year alarm in RTC CMOS RAM */ \
-    uint8_t  century;      /* Index to century in RTC CMOS RAM */
-
-struct AcpiFadtDescriptorRev1
-{
-    ACPI_FADT_COMMON_DEF
-    uint8_t  reserved4;              /* Reserved */
-    uint8_t  reserved4a;             /* Reserved */
-    uint8_t  reserved4b;             /* Reserved */
-    uint32_t flags;
-} QEMU_PACKED;
-typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
+    uint8_t  century;      /* Index to century in RTC CMOS RAM */ \
+    /* IA-PC Boot Architecture Flags (see below for individual flags) */ \
+    uint16_t boot_flags; \
+    uint8_t reserved;    /* Reserved, must be zero */ \
+    /* Miscellaneous flag bits (see below for individual flags) */ \
+    uint32_t flags; \
+    /* 64-bit address of the Reset register */ \
+    struct AcpiGenericAddress reset_register; \
+    /* Value to write to the reset_register port to reset the system */ \
+    uint8_t reset_value; \
+    /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */ \
+    uint16_t arm_boot_flags; \
+    uint8_t minor_revision;  /* FADT Minor Revision (ACPI 5.1) */ \
+    uint64_t Xfacs;          /* 64-bit physical address of FACS */ \
+    uint64_t Xdsdt;          /* 64-bit physical address of DSDT */ \
+    /* 64-bit Extended Power Mgt 1a Event Reg Blk address */ \
+    struct AcpiGenericAddress xpm1a_event_block; \
+    /* 64-bit Extended Power Mgt 1b Event Reg Blk address */ \
+    struct AcpiGenericAddress xpm1b_event_block; \
+    /* 64-bit Extended Power Mgt 1a Control Reg Blk address */ \
+    struct AcpiGenericAddress xpm1a_control_block; \
+    /* 64-bit Extended Power Mgt 1b Control Reg Blk address */ \
+    struct AcpiGenericAddress xpm1b_control_block; \
+    /* 64-bit Extended Power Mgt 2 Control Reg Blk address */ \
+    struct AcpiGenericAddress xpm2_control_block; \
+    /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ \
+    struct AcpiGenericAddress xpm_timer_block; \
+    /* 64-bit Extended General Purpose Event 0 Reg Blk address */ \
+    struct AcpiGenericAddress xgpe0_block; \
+    /* 64-bit Extended General Purpose Event 1 Reg Blk address */ \
+    struct AcpiGenericAddress xgpe1_block; \
 
 
 struct AcpiGenericAddress {
 struct AcpiGenericAddress {
     uint8_t space_id;        /* Address space where struct or register exists */
     uint8_t space_id;        /* Address space where struct or register exists */
@@ -151,38 +171,13 @@ struct AcpiGenericAddress {
     uint64_t address;        /* 64-bit address of struct or register */
     uint64_t address;        /* 64-bit address of struct or register */
 } QEMU_PACKED;
 } QEMU_PACKED;
 
 
+struct AcpiFadtDescriptorRev3 {
+    ACPI_FADT_COMMON_DEF
+} QEMU_PACKED;
+typedef struct AcpiFadtDescriptorRev3 AcpiFadtDescriptorRev3;
+
 struct AcpiFadtDescriptorRev5_1 {
 struct AcpiFadtDescriptorRev5_1 {
     ACPI_FADT_COMMON_DEF
     ACPI_FADT_COMMON_DEF
-    /* IA-PC Boot Architecture Flags (see below for individual flags) */
-    uint16_t boot_flags;
-    uint8_t reserved;    /* Reserved, must be zero */
-    /* Miscellaneous flag bits (see below for individual flags) */
-    uint32_t flags;
-    /* 64-bit address of the Reset register */
-    struct AcpiGenericAddress reset_register;
-    /* Value to write to the reset_register port to reset the system */
-    uint8_t reset_value;
-    /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
-    uint16_t arm_boot_flags;
-    uint8_t minor_revision;  /* FADT Minor Revision (ACPI 5.1) */
-    uint64_t Xfacs;          /* 64-bit physical address of FACS */
-    uint64_t Xdsdt;          /* 64-bit physical address of DSDT */
-    /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
-    struct AcpiGenericAddress xpm1a_event_block;
-    /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
-    struct AcpiGenericAddress xpm1b_event_block;
-    /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
-    struct AcpiGenericAddress xpm1a_control_block;
-    /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
-    struct AcpiGenericAddress xpm1b_control_block;
-    /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
-    struct AcpiGenericAddress xpm2_control_block;
-    /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
-    struct AcpiGenericAddress xpm_timer_block;
-    /* 64-bit Extended General Purpose Event 0 Reg Blk address */
-    struct AcpiGenericAddress xgpe0_block;
-    /* 64-bit Extended General Purpose Event 1 Reg Blk address */
-    struct AcpiGenericAddress xgpe1_block;
     /* 64-bit Sleep Control register (ACPI 5.0) */
     /* 64-bit Sleep Control register (ACPI 5.0) */
     struct AcpiGenericAddress sleep_control;
     struct AcpiGenericAddress sleep_control;
     /* 64-bit Sleep Status register (ACPI 5.0) */
     /* 64-bit Sleep Status register (ACPI 5.0) */

+ 6 - 0
include/hw/i386/pc.h

@@ -303,6 +303,12 @@ typedef struct PCII440FXState PCII440FXState;
 
 
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 
 
+/*
+ * Reset Control Register: PCI-accessible ISA-Compatible Register at address
+ * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
+ */
+#define RCR_IOPORT 0xcf9
+
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
                     PCII440FXState **pi440fx_state, int *piix_devfn,
                     PCII440FXState **pi440fx_state, int *piix_devfn,
                     ISABus **isa_bus, qemu_irq *pic,
                     ISABus **isa_bus, qemu_irq *pic,

+ 48 - 0
include/hw/virtio/vhost-scsi-common.h

@@ -0,0 +1,48 @@
+/*
+ * vhost_scsi host device
+ *
+ * Copyright (c) 2016 Nutanix Inc. All rights reserved.
+ *
+ * Author:
+ *  Felipe Franciosi <felipe@nutanix.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef VHOST_SCSI_COMMON_H
+#define VHOST_SCSI_COMMON_H
+
+#include "qemu-common.h"
+#include "hw/qdev.h"
+#include "hw/virtio/virtio-scsi.h"
+#include "hw/virtio/vhost.h"
+#include "hw/fw-path-provider.h"
+
+#define TYPE_VHOST_SCSI_COMMON "vhost-scsi-common"
+#define VHOST_SCSI_COMMON(obj) \
+        OBJECT_CHECK(VHostSCSICommon, (obj), TYPE_VHOST_SCSI_COMMON)
+
+typedef struct VHostSCSICommon {
+    VirtIOSCSICommon parent_obj;
+
+    Error *migration_blocker;
+
+    struct vhost_dev dev;
+    const int *feature_bits;
+    int32_t bootindex;
+    int channel;
+    int target;
+    int lun;
+} VHostSCSICommon;
+
+int vhost_scsi_common_start(VHostSCSICommon *vsc);
+void vhost_scsi_common_stop(VHostSCSICommon *vsc);
+char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus,
+                                        DeviceState *dev);
+void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config);
+uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features,
+                                        Error **errp);
+
+#endif /* VHOST_SCSI_COMMON_H */

+ 2 - 9
include/hw/virtio/vhost-scsi.h

@@ -18,6 +18,7 @@
 #include "hw/qdev.h"
 #include "hw/qdev.h"
 #include "hw/virtio/virtio-scsi.h"
 #include "hw/virtio/virtio-scsi.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-scsi-common.h"
 
 
 enum vhost_scsi_vq_list {
 enum vhost_scsi_vq_list {
     VHOST_SCSI_VQ_CONTROL = 0,
     VHOST_SCSI_VQ_CONTROL = 0,
@@ -30,15 +31,7 @@ enum vhost_scsi_vq_list {
         OBJECT_CHECK(VHostSCSI, (obj), TYPE_VHOST_SCSI)
         OBJECT_CHECK(VHostSCSI, (obj), TYPE_VHOST_SCSI)
 
 
 typedef struct VHostSCSI {
 typedef struct VHostSCSI {
-    VirtIOSCSICommon parent_obj;
-
-    Error *migration_blocker;
-
-    struct vhost_dev dev;
-    int32_t bootindex;
-    int channel;
-    int target;
-    int lun;
+    VHostSCSICommon parent_obj;
 } VHostSCSI;
 } VHostSCSI;
 
 
 #endif
 #endif

+ 2 - 0
include/hw/virtio/virtio-scsi.h

@@ -49,8 +49,10 @@ struct VirtIOSCSIConf {
     uint32_t num_queues;
     uint32_t num_queues;
     uint32_t max_sectors;
     uint32_t max_sectors;
     uint32_t cmd_per_lun;
     uint32_t cmd_per_lun;
+#ifdef CONFIG_VHOST_SCSI
     char *vhostfd;
     char *vhostfd;
     char *wwpn;
     char *wwpn;
+#endif
     uint32_t boot_tpgt;
     uint32_t boot_tpgt;
     IOThread *iothread;
     IOThread *iothread;
 };
 };

+ 3 - 1
include/qemu/compiler.h

@@ -82,7 +82,9 @@
         int:(x) ? -1 : 1; \
         int:(x) ? -1 : 1; \
     }
     }
 
 
-#ifdef __COUNTER__
+#if defined(CONFIG_STATIC_ASSERT)
+#define QEMU_BUILD_BUG_ON(x) _Static_assert(!(x), "not expecting: " #x)
+#elif defined(__COUNTER__)
 #define QEMU_BUILD_BUG_ON(x) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \
 #define QEMU_BUILD_BUG_ON(x) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \
     glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused))
     glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused))
 #else
 #else

+ 1 - 1
include/sysemu/char.h

@@ -101,7 +101,7 @@ struct Chardev {
     char *filename;
     char *filename;
     int logfd;
     int logfd;
     int be_open;
     int be_open;
-    guint fd_in_tag;
+    GSource *gsource;
     DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
     DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST);
 };
 };
 
 

+ 1 - 0
include/sysemu/dump.h

@@ -157,6 +157,7 @@ typedef struct DumpState {
     uint32_t sh_info;
     uint32_t sh_info;
     bool have_section;
     bool have_section;
     bool resume;
     bool resume;
+    bool detached;
     ssize_t note_size;
     ssize_t note_size;
     hwaddr memory_offset;
     hwaddr memory_offset;
     int fd;
     int fd;

BIN
pc-bios/sgabios.bin


+ 9 - 9
qemu-options.hx

@@ -31,7 +31,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "-machine [type=]name[,prop[=value][,...]]\n"
     "-machine [type=]name[,prop[=value][,...]]\n"
     "                selects emulated machine ('-machine help' for list)\n"
     "                selects emulated machine ('-machine help' for list)\n"
     "                property accel=accel1[:accel2[:...]] selects accelerator\n"
     "                property accel=accel1[:accel2[:...]] selects accelerator\n"
-    "                supported accelerators are kvm, xen, tcg (default: tcg)\n"
+    "                supported accelerators are kvm, xen, hax or tcg (default: tcg)\n"
     "                kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n"
     "                kernel_irqchip=on|off|split controls accelerated irqchip support (default=off)\n"
     "                vmport=on|off|auto controls emulation of vmport (default: auto)\n"
     "                vmport=on|off|auto controls emulation of vmport (default: auto)\n"
     "                kvm_shadow_mem=size of KVM shadow MMU in bytes\n"
     "                kvm_shadow_mem=size of KVM shadow MMU in bytes\n"
@@ -52,9 +52,9 @@ available machines. Supported machine properties are:
 @table @option
 @table @option
 @item accel=@var{accels1}[:@var{accels2}[:...]]
 @item accel=@var{accels1}[:@var{accels2}[:...]]
 This is used to enable an accelerator. Depending on the target architecture,
 This is used to enable an accelerator. Depending on the target architecture,
-kvm, xen, or tcg can be available. By default, tcg is used. If there is more
-than one accelerator specified, the next one is used if the previous one fails
-to initialize.
+kvm, xen, hax or tcg can be available. By default, tcg is used. If there is
+more than one accelerator specified, the next one is used if the previous one
+fails to initialize.
 @item kernel_irqchip=on|off
 @item kernel_irqchip=on|off
 Controls in-kernel irqchip support for the chosen accelerator when available.
 Controls in-kernel irqchip support for the chosen accelerator when available.
 @item gfx_passthru=on|off
 @item gfx_passthru=on|off
@@ -97,15 +97,15 @@ ETEXI
 
 
 DEF("accel", HAS_ARG, QEMU_OPTION_accel,
 DEF("accel", HAS_ARG, QEMU_OPTION_accel,
     "-accel [accel=]accelerator[,thread=single|multi]\n"
     "-accel [accel=]accelerator[,thread=single|multi]\n"
-    "               select accelerator ('-accel help for list')\n"
-    "               thread=single|multi (enable multi-threaded TCG)", QEMU_ARCH_ALL)
+    "                select accelerator (kvm, xen, hax or tcg; use 'help' for a list)\n"
+    "                thread=single|multi (enable multi-threaded TCG)", QEMU_ARCH_ALL)
 STEXI
 STEXI
 @item -accel @var{name}[,prop=@var{value}[,...]]
 @item -accel @var{name}[,prop=@var{value}[,...]]
 @findex -accel
 @findex -accel
 This is used to enable an accelerator. Depending on the target architecture,
 This is used to enable an accelerator. Depending on the target architecture,
-kvm, xen, or tcg can be available. By default, tcg is used. If there is more
-than one accelerator specified, the next one is used if the previous one fails
-to initialize.
+kvm, xen, hax or tcg can be available. By default, tcg is used. If there is
+more than one accelerator specified, the next one is used if the previous one
+fails to initialize.
 @table @option
 @table @option
 @item thread=single|multi
 @item thread=single|multi
 Controls number of TCG threads. When the TCG is multi-threaded there will be one
 Controls number of TCG threads. When the TCG is multi-threaded there will be one

+ 1 - 1
roms/sgabios

@@ -1 +1 @@
-Subproject commit 23d474943dcd55d0550a3d20b3d30e9040a4f15b
+Subproject commit cbaee52287e5f32373181cff50a00b6c4ac9015a

+ 21 - 0
scripts/checkpatch.pl

@@ -2571,6 +2571,27 @@ sub process {
 		if ($line =~ /\bbzero\(/) {
 		if ($line =~ /\bbzero\(/) {
 			ERROR("use memset() instead of bzero()\n" . $herecurr);
 			ERROR("use memset() instead of bzero()\n" . $herecurr);
 		}
 		}
+		my $non_exit_glib_asserts = qr{g_assert_cmpstr|
+						g_assert_cmpint|
+						g_assert_cmpuint|
+						g_assert_cmphex|
+						g_assert_cmpfloat|
+						g_assert_true|
+						g_assert_false|
+						g_assert_nonnull|
+						g_assert_null|
+						g_assert_no_error|
+						g_assert_error|
+						g_test_assert_expected_messages|
+						g_test_trap_assert_passed|
+						g_test_trap_assert_stdout|
+						g_test_trap_assert_stdout_unmatched|
+						g_test_trap_assert_stderr|
+						g_test_trap_assert_stderr_unmatched}x;
+		if ($realfile !~ /^tests\// &&
+			$line =~ /\b(?:$non_exit_glib_asserts)\(/) {
+			ERROR("Use g_assert or g_assert_not_reached\n". $herecurr);
+		}
 	}
 	}
 
 
 	# If we have no input at all, then there is nothing to report on
 	# If we have no input at all, then there is nothing to report on

+ 37 - 16
scripts/get_maintainer.pl

@@ -21,6 +21,7 @@ my $lk_path = "./";
 my $email = 1;
 my $email = 1;
 my $email_usename = 1;
 my $email_usename = 1;
 my $email_maintainer = 1;
 my $email_maintainer = 1;
+my $email_reviewer = 1;
 my $email_list = 1;
 my $email_list = 1;
 my $email_subscriber_list = 0;
 my $email_subscriber_list = 0;
 my $email_git = 0;
 my $email_git = 0;
@@ -180,6 +181,7 @@ if (!GetOptions(
 		'remove-duplicates!' => \$email_remove_duplicates,
 		'remove-duplicates!' => \$email_remove_duplicates,
 		'mailmap!' => \$email_use_mailmap,
 		'mailmap!' => \$email_use_mailmap,
 		'm!' => \$email_maintainer,
 		'm!' => \$email_maintainer,
+		'r!' => \$email_reviewer,
 		'n!' => \$email_usename,
 		'n!' => \$email_usename,
 		'l!' => \$email_list,
 		'l!' => \$email_list,
 		's!' => \$email_subscriber_list,
 		's!' => \$email_subscriber_list,
@@ -238,7 +240,8 @@ if ($sections) {
 }
 }
 
 
 if ($email &&
 if ($email &&
-    ($email_maintainer + $email_list + $email_subscriber_list +
+    ($email_maintainer + $email_reviewer +
+     $email_list + $email_subscriber_list +
      $email_git + $email_git_blame) == 0) {
      $email_git + $email_git_blame) == 0) {
     die "$P: Please select at least 1 email option\n";
     die "$P: Please select at least 1 email option\n";
 }
 }
@@ -718,6 +721,7 @@ MAINTAINER field selection options:
     --hg-since => hg history to use (default: $email_hg_since)
     --hg-since => hg history to use (default: $email_hg_since)
     --interactive => display a menu (mostly useful if used with the --git option)
     --interactive => display a menu (mostly useful if used with the --git option)
     --m => include maintainer(s) if any
     --m => include maintainer(s) if any
+    --r => include reviewer(s) if any
     --n => include name 'Full Name <addr\@domain.tld>'
     --n => include name 'Full Name <addr\@domain.tld>'
     --l => include list(s) if any
     --l => include list(s) if any
     --s => include subscriber only list(s) if any
     --s => include subscriber only list(s) if any
@@ -744,7 +748,7 @@ Other options:
   --help => show this help information
   --help => show this help information
 
 
 Default options:
 Default options:
-  [--email --nogit --git-fallback --m --n --l --multiline -pattern-depth=0
+  [--email --nogit --git-fallback --m --r --n --l --multiline --pattern-depth=0
    --remove-duplicates --rolestats]
    --remove-duplicates --rolestats]
 
 
 Notes:
 Notes:
@@ -892,20 +896,29 @@ sub find_ending_index {
     return $index;
     return $index;
 }
 }
 
 
-sub get_maintainer_role {
+sub get_subsystem_name {
     my ($index) = @_;
     my ($index) = @_;
 
 
-    my $i;
     my $start = find_starting_index($index);
     my $start = find_starting_index($index);
-    my $end = find_ending_index($index);
 
 
-    my $role = "unknown";
     my $subsystem = $typevalue[$start];
     my $subsystem = $typevalue[$start];
     if (length($subsystem) > 20) {
     if (length($subsystem) > 20) {
 	$subsystem = substr($subsystem, 0, 17);
 	$subsystem = substr($subsystem, 0, 17);
 	$subsystem =~ s/\s*$//;
 	$subsystem =~ s/\s*$//;
 	$subsystem = $subsystem . "...";
 	$subsystem = $subsystem . "...";
     }
     }
+    return $subsystem;
+}
+
+sub get_maintainer_role {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    my $role = "unknown";
+    my $subsystem = get_subsystem_name($index);
 
 
     for ($i = $start + 1; $i < $end; $i++) {
     for ($i = $start + 1; $i < $end; $i++) {
 	my $tv = $typevalue[$i];
 	my $tv = $typevalue[$i];
@@ -939,16 +952,7 @@ sub get_maintainer_role {
 sub get_list_role {
 sub get_list_role {
     my ($index) = @_;
     my ($index) = @_;
 
 
-    my $i;
-    my $start = find_starting_index($index);
-    my $end = find_ending_index($index);
-
-    my $subsystem = $typevalue[$start];
-    if (length($subsystem) > 20) {
-	$subsystem = substr($subsystem, 0, 17);
-	$subsystem =~ s/\s*$//;
-	$subsystem = $subsystem . "...";
-    }
+    my $subsystem = get_subsystem_name($index);
 
 
     if ($subsystem eq "THE REST") {
     if ($subsystem eq "THE REST") {
 	$subsystem = "";
 	$subsystem = "";
@@ -1022,6 +1026,23 @@ sub add_categories {
 		    my $role = get_maintainer_role($i);
 		    my $role = get_maintainer_role($i);
 		    push_email_addresses($pvalue, $role);
 		    push_email_addresses($pvalue, $role);
 		}
 		}
+	    } elsif ($ptype eq "R") {
+		my ($name, $address) = parse_email($pvalue);
+		if ($name eq "") {
+		    if ($i > 0) {
+			my $tv = $typevalue[$i - 1];
+			if ($tv =~ m/^(.):\s*(.*)/) {
+			    if ($1 eq "P") {
+				$name = $2;
+				$pvalue = format_email($name, $address, $email_usename);
+			    }
+			}
+		    }
+		}
+		if ($email_reviewer) {
+		    my $subsystem = get_subsystem_name($i);
+		    push_email_addresses($pvalue, "reviewer:$subsystem");
+		}
 	    } elsif ($ptype eq "T") {
 	    } elsif ($ptype eq "T") {
 		push(@scm, $pvalue);
 		push(@scm, $pvalue);
 	    } elsif ($ptype eq "W") {
 	    } elsif ($ptype eq "W") {

+ 17 - 4
target/i386/cpu.c

@@ -2577,6 +2577,15 @@ out:
     return ret;
     return ret;
 }
 }
 
 
+static gchar *x86_gdb_arch_name(CPUState *cs)
+{
+#ifdef TARGET_X86_64
+    return g_strdup("i386:x86-64");
+#else
+    return g_strdup("i386");
+#endif
+}
+
 X86CPU *cpu_x86_init(const char *cpu_model)
 X86CPU *cpu_x86_init(const char *cpu_model)
 {
 {
     return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));
     return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));
@@ -4056,10 +4065,14 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
     cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
     cc->vmsd = &vmstate_x86_cpu;
     cc->vmsd = &vmstate_x86_cpu;
 #endif
 #endif
-    /* CPU_NB_REGS * 2 = general regs + xmm regs
-     * 25 = eip, eflags, 6 seg regs, st[0-7], fctrl,...,fop, mxcsr.
-     */
-    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
+    cc->gdb_arch_name = x86_gdb_arch_name;
+#ifdef TARGET_X86_64
+    cc->gdb_core_xml_file = "i386-64bit-core.xml";
+    cc->gdb_num_core_regs = 40;
+#else
+    cc->gdb_core_xml_file = "i386-32bit-core.xml";
+    cc->gdb_num_core_regs = 32;
+#endif
 #ifndef CONFIG_USER_ONLY
 #ifndef CONFIG_USER_ONLY
     cc->debug_excp_handler = breakpoint_handler;
     cc->debug_excp_handler = breakpoint_handler;
 #endif
 #endif

+ 17 - 2
target/i386/hax-mem.c

@@ -106,10 +106,10 @@ static void hax_update_mapping(uint64_t start_pa, uint32_t size,
                                uint64_t host_va, uint8_t flags)
                                uint64_t host_va, uint8_t flags)
 {
 {
     uint64_t end_pa = start_pa + size;
     uint64_t end_pa = start_pa + size;
-    uint32_t chunk_sz;
     HAXMapping *entry, *next;
     HAXMapping *entry, *next;
 
 
     QTAILQ_FOREACH_SAFE(entry, &mappings, entry, next) {
     QTAILQ_FOREACH_SAFE(entry, &mappings, entry, next) {
+        uint32_t chunk_sz;
         if (start_pa >= entry->start_pa + entry->size) {
         if (start_pa >= entry->start_pa + entry->size) {
             continue;
             continue;
         }
         }
@@ -121,7 +121,16 @@ static void hax_update_mapping(uint64_t start_pa, uint32_t size,
             start_pa += chunk_sz;
             start_pa += chunk_sz;
             host_va += chunk_sz;
             host_va += chunk_sz;
             size -= chunk_sz;
             size -= chunk_sz;
+        } else if (start_pa > entry->start_pa) {
+            /* split the existing chunk at start_pa */
+            chunk_sz = start_pa - entry->start_pa;
+            hax_insert_mapping_before(entry, entry->start_pa, chunk_sz,
+                                      entry->host_va, entry->flags);
+            entry->start_pa += chunk_sz;
+            entry->host_va += chunk_sz;
+            entry->size -= chunk_sz;
         }
         }
+        /* now start_pa == entry->start_pa */
         chunk_sz = MIN(size, entry->size);
         chunk_sz = MIN(size, entry->size);
         if (chunk_sz) {
         if (chunk_sz) {
             bool nop = hax_mapping_is_opposite(entry, host_va, flags);
             bool nop = hax_mapping_is_opposite(entry, host_va, flags);
@@ -165,8 +174,14 @@ static void hax_process_section(MemoryRegionSection *section, uint8_t flags)
     unsigned int delta;
     unsigned int delta;
     uint64_t host_va;
     uint64_t host_va;
 
 
-    /* We only care about RAM pages */
+    /* We only care about RAM and ROM regions */
     if (!memory_region_is_ram(mr)) {
     if (!memory_region_is_ram(mr)) {
+        if (memory_region_is_romd(mr)) {
+            /* HAXM kernel module does not support ROMD yet  */
+            fprintf(stderr, "%s: Warning: Ignoring ROMD region 0x%016" PRIx64
+                    "->0x%016" PRIx64 "\n", __func__, start_pa,
+                    start_pa + size);
+        }
         return;
         return;
     }
     }
 
 

+ 10 - 0
tests/acpi-utils.h

@@ -87,6 +87,16 @@ typedef struct {
     g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
     g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
 } while (0)
 } while (0)
 
 
+#define ACPI_READ_GENERIC_ADDRESS(field, addr)       \
+    do {                                             \
+        ACPI_READ_FIELD((field).space_id, addr);     \
+        ACPI_READ_FIELD((field).bit_width, addr);    \
+        ACPI_READ_FIELD((field).bit_offset, addr);   \
+        ACPI_READ_FIELD((field).access_width, addr); \
+        ACPI_READ_FIELD((field).address, addr);      \
+    } while (0);
+
+
 uint8_t acpi_calc_checksum(const uint8_t *data, int len);
 uint8_t acpi_calc_checksum(const uint8_t *data, int len);
 uint32_t acpi_find_rsdp_address(void);
 uint32_t acpi_find_rsdp_address(void);
 void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table);
 void acpi_parse_rsdp_table(uint32_t addr, AcpiRsdpDescriptor *rsdp_table);

+ 18 - 5
tests/bios-tables-test.c

@@ -29,7 +29,7 @@ typedef struct {
     uint32_t rsdp_addr;
     uint32_t rsdp_addr;
     AcpiRsdpDescriptor rsdp_table;
     AcpiRsdpDescriptor rsdp_table;
     AcpiRsdtDescriptorRev1 rsdt_table;
     AcpiRsdtDescriptorRev1 rsdt_table;
-    AcpiFadtDescriptorRev1 fadt_table;
+    AcpiFadtDescriptorRev3 fadt_table;
     AcpiFacsDescriptorRev1 facs_table;
     AcpiFacsDescriptorRev1 facs_table;
     uint32_t *rsdt_tables_addr;
     uint32_t *rsdt_tables_addr;
     int rsdt_tables_nr;
     int rsdt_tables_nr;
@@ -126,7 +126,7 @@ static void test_acpi_rsdt_table(test_data *data)
 
 
 static void test_acpi_fadt_table(test_data *data)
 static void test_acpi_fadt_table(test_data *data)
 {
 {
-    AcpiFadtDescriptorRev1 *fadt_table = &data->fadt_table;
+    AcpiFadtDescriptorRev3 *fadt_table = &data->fadt_table;
     uint32_t addr;
     uint32_t addr;
 
 
     /* FADT table comes first */
     /* FADT table comes first */
@@ -168,10 +168,23 @@ static void test_acpi_fadt_table(test_data *data)
     ACPI_READ_FIELD(fadt_table->day_alrm, addr);
     ACPI_READ_FIELD(fadt_table->day_alrm, addr);
     ACPI_READ_FIELD(fadt_table->mon_alrm, addr);
     ACPI_READ_FIELD(fadt_table->mon_alrm, addr);
     ACPI_READ_FIELD(fadt_table->century, addr);
     ACPI_READ_FIELD(fadt_table->century, addr);
-    ACPI_READ_FIELD(fadt_table->reserved4, addr);
-    ACPI_READ_FIELD(fadt_table->reserved4a, addr);
-    ACPI_READ_FIELD(fadt_table->reserved4b, addr);
+    ACPI_READ_FIELD(fadt_table->boot_flags, addr);
+    ACPI_READ_FIELD(fadt_table->reserved, addr);
     ACPI_READ_FIELD(fadt_table->flags, addr);
     ACPI_READ_FIELD(fadt_table->flags, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->reset_register, addr);
+    ACPI_READ_FIELD(fadt_table->reset_value, addr);
+    ACPI_READ_FIELD(fadt_table->arm_boot_flags, addr);
+    ACPI_READ_FIELD(fadt_table->minor_revision, addr);
+    ACPI_READ_FIELD(fadt_table->Xfacs, addr);
+    ACPI_READ_FIELD(fadt_table->Xdsdt, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_event_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1b_event_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1a_control_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm1b_control_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm2_control_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xpm_timer_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xgpe0_block, addr);
+    ACPI_READ_GENERIC_ADDRESS(fadt_table->xgpe1_block, addr);
 
 
     ACPI_ASSERT_CMP(fadt_table->signature, "FACP");
     ACPI_ASSERT_CMP(fadt_table->signature, "FACP");
     g_assert(!acpi_calc_checksum((uint8_t *)fadt_table, fadt_table->length));
     g_assert(!acpi_calc_checksum((uint8_t *)fadt_table, fadt_table->length));

+ 17 - 1
util/qemu-thread-posix.c

@@ -14,6 +14,7 @@
 #include "qemu/thread.h"
 #include "qemu/thread.h"
 #include "qemu/atomic.h"
 #include "qemu/atomic.h"
 #include "qemu/notify.h"
 #include "qemu/notify.h"
+#include "trace.h"
 
 
 static bool name_threads;
 static bool name_threads;
 
 
@@ -60,17 +61,30 @@ void qemu_mutex_lock(QemuMutex *mutex)
     err = pthread_mutex_lock(&mutex->lock);
     err = pthread_mutex_lock(&mutex->lock);
     if (err)
     if (err)
         error_exit(err, __func__);
         error_exit(err, __func__);
+
+    trace_qemu_mutex_locked(mutex);
 }
 }
 
 
 int qemu_mutex_trylock(QemuMutex *mutex)
 int qemu_mutex_trylock(QemuMutex *mutex)
 {
 {
-    return pthread_mutex_trylock(&mutex->lock);
+    int err;
+
+    err = pthread_mutex_trylock(&mutex->lock);
+    if (err == 0) {
+        trace_qemu_mutex_locked(mutex);
+        return 0;
+    }
+    if (err != EBUSY) {
+        error_exit(err, __func__);
+    }
+    return -EBUSY;
 }
 }
 
 
 void qemu_mutex_unlock(QemuMutex *mutex)
 void qemu_mutex_unlock(QemuMutex *mutex)
 {
 {
     int err;
     int err;
 
 
+    trace_qemu_mutex_unlocked(mutex);
     err = pthread_mutex_unlock(&mutex->lock);
     err = pthread_mutex_unlock(&mutex->lock);
     if (err)
     if (err)
         error_exit(err, __func__);
         error_exit(err, __func__);
@@ -130,7 +144,9 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
 {
 {
     int err;
     int err;
 
 
+    trace_qemu_mutex_unlocked(mutex);
     err = pthread_cond_wait(&cond->cond, &mutex->lock);
     err = pthread_cond_wait(&cond->cond, &mutex->lock);
+    trace_qemu_mutex_locked(mutex);
     if (err)
     if (err)
         error_exit(err, __func__);
         error_exit(err, __func__);
 }
 }

+ 10 - 1
util/qemu-thread-win32.c

@@ -19,6 +19,7 @@
 #include "qemu-common.h"
 #include "qemu-common.h"
 #include "qemu/thread.h"
 #include "qemu/thread.h"
 #include "qemu/notify.h"
 #include "qemu/notify.h"
+#include "trace.h"
 #include <process.h>
 #include <process.h>
 
 
 static bool name_threads;
 static bool name_threads;
@@ -55,6 +56,7 @@ void qemu_mutex_destroy(QemuMutex *mutex)
 void qemu_mutex_lock(QemuMutex *mutex)
 void qemu_mutex_lock(QemuMutex *mutex)
 {
 {
     AcquireSRWLockExclusive(&mutex->lock);
     AcquireSRWLockExclusive(&mutex->lock);
+    trace_qemu_mutex_locked(mutex);
 }
 }
 
 
 int qemu_mutex_trylock(QemuMutex *mutex)
 int qemu_mutex_trylock(QemuMutex *mutex)
@@ -62,11 +64,16 @@ int qemu_mutex_trylock(QemuMutex *mutex)
     int owned;
     int owned;
 
 
     owned = TryAcquireSRWLockExclusive(&mutex->lock);
     owned = TryAcquireSRWLockExclusive(&mutex->lock);
-    return !owned;
+    if (owned) {
+        trace_qemu_mutex_locked(mutex);
+        return 0;
+    }
+    return -EBUSY;
 }
 }
 
 
 void qemu_mutex_unlock(QemuMutex *mutex)
 void qemu_mutex_unlock(QemuMutex *mutex)
 {
 {
+    trace_qemu_mutex_unlocked(mutex);
     ReleaseSRWLockExclusive(&mutex->lock);
     ReleaseSRWLockExclusive(&mutex->lock);
 }
 }
 
 
@@ -118,7 +125,9 @@ void qemu_cond_broadcast(QemuCond *cond)
 
 
 void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
 void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
 {
 {
+    trace_qemu_mutex_unlocked(mutex);
     SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
     SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
+    trace_qemu_mutex_locked(mutex);
 }
 }
 
 
 void qemu_sem_init(QemuSemaphore *sem, int init)
 void qemu_sem_init(QemuSemaphore *sem, int init)

+ 4 - 0
util/trace-events

@@ -55,3 +55,7 @@ lockcnt_futex_wait_prepare(const void *lockcnt, int expected, int new) "lockcnt
 lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d"
 lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d"
 lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d"
 lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d"
 lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
 lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
+
+# util/qemu-thread-posix.c
+qemu_mutex_locked(void *lock) "locked mutex %p"
+qemu_mutex_unlocked(void *lock) "unlocked mutex %p"

+ 9 - 14
vl.c

@@ -3727,26 +3727,21 @@ int main(int argc, char **argv, char **envp)
                 qdev_prop_register_global(&kvm_pit_lost_tick_policy);
                 qdev_prop_register_global(&kvm_pit_lost_tick_policy);
                 break;
                 break;
             }
             }
-            case QEMU_OPTION_accel:
+            case QEMU_OPTION_accel: {
+                QemuOpts *accel_opts;
+
                 accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
                 accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
                                                      optarg, true);
                                                      optarg, true);
                 optarg = qemu_opt_get(accel_opts, "accel");
                 optarg = qemu_opt_get(accel_opts, "accel");
-
-                olist = qemu_find_opts("machine");
-                if (strcmp("kvm", optarg) == 0) {
-                    qemu_opts_parse_noisily(olist, "accel=kvm", false);
-                } else if (strcmp("xen", optarg) == 0) {
-                    qemu_opts_parse_noisily(olist, "accel=xen", false);
-                } else if (strcmp("tcg", optarg) == 0) {
-                    qemu_opts_parse_noisily(olist, "accel=tcg", false);
-                } else {
-                    if (!is_help_option(optarg)) {
-                        error_printf("Unknown accelerator: %s", optarg);
-                    }
-                    error_printf("Supported accelerators: kvm, xen, tcg\n");
+                if (!optarg || is_help_option(optarg)) {
+                    error_printf("Possible accelerators: kvm, xen, hax, tcg\n");
                     exit(1);
                     exit(1);
                 }
                 }
+                accel_opts = qemu_opts_create(qemu_find_opts("machine"), NULL,
+                                              false, &error_abort);
+                qemu_opt_set(accel_opts, "accel", optarg, &error_abort);
                 break;
                 break;
+            }
             case QEMU_OPTION_usb:
             case QEMU_OPTION_usb:
                 olist = qemu_find_opts("machine");
                 olist = qemu_find_opts("machine");
                 qemu_opts_parse_noisily(olist, "usb=on", false);
                 qemu_opts_parse_noisily(olist, "usb=on", false);