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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJZDE+gAAoJEL/70l94x66DIpYH/1IOz3u8ObD8D4Lor07LkCCZ
 vWFnTBMgGi9gTL5JQDnukRR3cmNp9EVOtAP5Yf+v+/Xqyq/FNGnoVWxCxEby7LtN
 zrIXbsKMCaEcGzRNJFcbKV+KZnzkJrz92J0NHy29ruCK1AsslOXAWf4Qb1MV+fQl
 6w2Upsh35usvWCNpFm2o8arzMEmNuE2xJDPKUB11GMrZT6TExq4Zqa8Zj1Ihc0sX
 XcDr+eeBmb65Vv3jQLntOhSWAy0Xxf/fDXYTQx+JLHFgvpSOIWMiS+fqIVXtT0bH
 0E4hQrBr0qjes8n8+9WGGQW2k8Ak0QlDvrZnQ97hTeV1k6SxW+2ATO2mLeJp9TM=
 =5hf2
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Stefan Hajnoczi 2017-05-08 13:29:40 -04:00
commit 1c5d506101
41 changed files with 703 additions and 295 deletions

View File

@ -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

View File

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

View File

@ -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) { if (chr->gsource) {
io_remove_watch_poll(chr->fd_in_tag, context); io_remove_watch_poll(chr->gsource);
chr->fd_in_tag = 0; chr->gsource = NULL;
} }
} }

View File

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

View File

@ -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) { if (!chr->gsource) {
chr->fd_in_tag = io_add_watch_poll(chr, s->ioc, 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);

View File

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

View File

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

View File

@ -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
configure vendored
View File

@ -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"

View File

@ -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
dump.c
View File

@ -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 {

View File

@ -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>

View File

@ -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>

View File

@ -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,

View File

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

View File

@ -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

View File

@ -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) { if (adp_reset_seq[s->adp_reset++] == val) {
s->adp_reset++; 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
hw/scsi/vhost-scsi-common.c Normal file
View File

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

View File

@ -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; int ret, abi_version;
VirtIODevice *vdev = VIRTIO_DEVICE(s); VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); const VhostOps *vhost_ops = vsc->dev.vhost_ops;
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
const VhostOps *vhost_ops = s->dev.vhost_ops;
if (!k->set_guest_notifiers) { ret = vhost_ops->vhost_scsi_get_abi_version(&vsc->dev, &abi_version);
error_report("binding does not support guest notifiers");
return -ENOSYS;
}
ret = vhost_ops->vhost_scsi_get_abi_version(&s->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" " %d is greater than vhost_scsi userspace supports: %d,"
" upgrade your version of QEMU", abi_version, " 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"); error_report("Error setting vhost-scsi endpoint");
goto err_vhost_stop; vhost_scsi_common_stop(vsc);
} }
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);
}
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; return ret;
} }
static void vhost_scsi_stop(VHostSCSI *s) static void vhost_scsi_stop(VHostSCSI *s)
{ {
VirtIODevice *vdev = VIRTIO_DEVICE(s); VHostSCSICommon *vsc = VHOST_SCSI_COMMON(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);
vhost_scsi_clear_endpoint(s); vhost_scsi_clear_endpoint(s);
vhost_dev_stop(&s->dev, vdev); vhost_scsi_common_stop(vsc);
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);
}
} }
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", error_report("unable to start vhost-scsi: %s", strerror(-ret));
strerror(-ret));
/* There is no userspace virtio-scsi fallback so exit */
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; vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
s->dev.vq_index = 0; vsc->dev.vq_index = 0;
s->dev.backend_features = 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; vsc->channel = 0;
s->lun = 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); migrate_del_blocker(vsc->migration_blocker);
g_free(s->dev.vqs); 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); migrate_del_blocker(vsc->migration_blocker);
error_free(s->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); vhost_dev_cleanup(&vsc->dev);
g_free(s->dev.vqs); 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("vhostfd", VirtIOSCSICommon, conf.vhostfd),
DEFINE_PROP_STRING("wwpn", VHostSCSI, parent_obj.conf.wwpn), DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn),
DEFINE_PROP_UINT32("boot_tpgt", VHostSCSI, parent_obj.conf.boot_tpgt, 0), DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
DEFINE_PROP_UINT32("num_queues", VHostSCSI, parent_obj.conf.num_queues, 1), DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues, 1),
DEFINE_PROP_UINT32("max_sectors", VHostSCSI, parent_obj.conf.max_sectors, DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors,
0xFFFF), 0xFFFF),
DEFINE_PROP_UINT32("cmd_per_lun", VHostSCSI, parent_obj.conf.cmd_per_lun, DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSICommon, conf.cmd_per_lun, 128),
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->get_features = vhost_scsi_common_get_features;
vdc->set_config = vhost_scsi_set_config; 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);
device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL, vsc->feature_bits = kernel_feature_bits;
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,

View File

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

View File

@ -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 */ uint8_t century; /* Index to century in RTC CMOS RAM */ \
/* IA-PC Boot Architecture Flags (see below for individual flags) */ \
struct AcpiFadtDescriptorRev1 uint16_t boot_flags; \
{ uint8_t reserved; /* Reserved, must be zero */ \
ACPI_FADT_COMMON_DEF /* Miscellaneous flag bits (see below for individual flags) */ \
uint8_t reserved4; /* Reserved */ uint32_t flags; \
uint8_t reserved4a; /* Reserved */ /* 64-bit address of the Reset register */ \
uint8_t reserved4b; /* Reserved */ struct AcpiGenericAddress reset_register; \
uint32_t flags; /* Value to write to the reset_register port to reset the system */ \
} QEMU_PACKED; uint8_t reset_value; \
typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1; /* 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) */

View File

@ -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,

View File

@ -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 */

View File

@ -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; VHostSCSICommon parent_obj;
Error *migration_blocker;
struct vhost_dev dev;
int32_t bootindex;
int channel;
int target;
int lun;
} VHostSCSI; } VHostSCSI;
#endif #endif

View File

@ -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;
}; };

View File

@ -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

View File

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

View File

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

Binary file not shown.

View File

@ -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 kvm, xen, hax or tcg can be available. By default, tcg is used. If there is
than one accelerator specified, the next one is used if the previous one fails more than one accelerator specified, the next one is used if the previous one
to initialize. 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" " select accelerator (kvm, xen, hax or tcg; use 'help' for a list)\n"
" thread=single|multi (enable multi-threaded TCG)", QEMU_ARCH_ALL) " 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 kvm, xen, hax or tcg can be available. By default, tcg is used. If there is
than one accelerator specified, the next one is used if the previous one fails more than one accelerator specified, the next one is used if the previous one
to initialize. 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 @@
Subproject commit 23d474943dcd55d0550a3d20b3d30e9040a4f15b Subproject commit cbaee52287e5f32373181cff50a00b6c4ac9015a

View File

@ -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

View File

@ -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,6 +896,20 @@ sub find_ending_index {
return $index; return $index;
} }
sub get_subsystem_name {
my ($index) = @_;
my $start = find_starting_index($index);
my $subsystem = $typevalue[$start];
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
return $subsystem;
}
sub get_maintainer_role { sub get_maintainer_role {
my ($index) = @_; my ($index) = @_;
@ -900,12 +918,7 @@ sub get_maintainer_role {
my $end = find_ending_index($index); my $end = find_ending_index($index);
my $role = "unknown"; my $role = "unknown";
my $subsystem = $typevalue[$start]; my $subsystem = get_subsystem_name($index);
if (length($subsystem) > 20) {
$subsystem = substr($subsystem, 0, 17);
$subsystem =~ s/\s*$//;
$subsystem = $subsystem . "...";
}
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 $subsystem = get_subsystem_name($index);
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 . "...";
}
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") {

View File

@ -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 cc->gdb_arch_name = x86_gdb_arch_name;
* 25 = eip, eflags, 6 seg regs, st[0-7], fctrl,...,fop, mxcsr. #ifdef TARGET_X86_64
*/ cc->gdb_core_xml_file = "i386-64bit-core.xml";
cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25; 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

View File

@ -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;
} }

View File

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

View File

@ -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->boot_flags, addr);
ACPI_READ_FIELD(fadt_table->reserved4a, addr); ACPI_READ_FIELD(fadt_table->reserved, addr);
ACPI_READ_FIELD(fadt_table->reserved4b, 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));

View File

@ -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__);
} }

View File

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

View File

@ -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"

23
vl.c
View File

@ -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");
if (!optarg || is_help_option(optarg)) {
olist = qemu_find_opts("machine"); error_printf("Possible accelerators: kvm, xen, hax, tcg\n");
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");
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);