* NBD and chardev conversion to QIONetListener (Daniel)

* MTTCG fixes (David)
 * Hyper-V fixes (Roman, Evgeny)
 * share-rw option (Fam)
 * Mux chardev event bugfix (Marc-André)
 * Add systemd unit files in contrib/ (me)
 * SCSI and block/iscsi.c bugfixes (me, Peter L.)
 * unassigned_mem_ops fixes (Peter M.)
 * VEX decoding fix (Peter M.)
 * "info pic" and "info irq" improvements (Peter Xu)
 * vmport trace events (Philippe)
 * Braille chardev bugfix (Samuel)
 * Compiler warnings fix (Stefan)
 * initial support for TCG smoke test of more boards (Thomas)
 * New CPU features (Yang)
 * Reduce startup memory usage (Yang)
 * QemuThread race fix (linhecheng)
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAlo7cTkUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroPTsQf+IlIjTWnwBKaoECDo3t5Nulj84+O5
 KLLwW7Yhy6vtu1U8N2kxzGickGf+wF1OEw0916Ku6b/P2jpKNogjDxXBQuO+uerG
 fPdc17gpSLcIXFzcfhiEH7pKJsdtcW+TTWPoF/RNK0KLP/tmJ+SBNNn0Ly0KRxQ9
 t4YoMkFiybMZ+bpuixy/2TN2ZRwyuGdjXSiFLjium6ioPF262f4DqXV8PA7kfV8b
 FCANCql/p0HvAtURgzsJt0lfqAatKLOUELE4ClHBjUfGCLXAwMw8LQ0F/9jBAcaz
 fJov/RKjh5y2Av9mjCaTPEu+E550+4qdDcfpk2kuV8xH+CUspUpqGGm3jw==
 =y+Yl
 -----END PGP SIGNATURE-----

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

* NBD and chardev conversion to QIONetListener (Daniel)
* MTTCG fixes (David)
* Hyper-V fixes (Roman, Evgeny)
* share-rw option (Fam)
* Mux chardev event bugfix (Marc-André)
* Add systemd unit files in contrib/ (me)
* SCSI and block/iscsi.c bugfixes (me, Peter L.)
* unassigned_mem_ops fixes (Peter M.)
* VEX decoding fix (Peter M.)
* "info pic" and "info irq" improvements (Peter Xu)
* vmport trace events (Philippe)
* Braille chardev bugfix (Samuel)
* Compiler warnings fix (Stefan)
* initial support for TCG smoke test of more boards (Thomas)
* New CPU features (Yang)
* Reduce startup memory usage (Yang)
* QemuThread race fix (linhecheng)

# gpg: Signature made Thu 21 Dec 2017 08:30:49 GMT
# 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

* remotes/bonzini/tags/for-upstream: (41 commits)
  chardev: convert the socket server to QIONetListener
  blockdev: convert qemu-nbd server to QIONetListener
  blockdev: convert internal NBD server to QIONetListener
  test: add some chardev mux event tests
  chardev: fix backend events regression with mux chardev
  rcu: reduce more than 7MB heap memory by malloc_trim()
  checkpatch: volatile with a comment or sig_atomic_t is okay
  i8259: move TYPE_INTERRUPT_STATS_PROVIDER upper
  kvm-i8259: support "info pic" and "info irq"
  i8259: generalize statistics into common code
  i8259: use DEBUG_IRQ_COUNT always
  i8259: convert DPRINTFs into trace
  Remove legacy -no-kvm-pit option
  scsi: replace hex constants with #defines
  scsi: provide general-purpose functions to manage sense data
  hw/i386/vmport: replace fprintf() by trace events or LOG_UNIMP
  hw/mips/boston: Remove workaround for writes to ROM aborting
  exec: Don't reuse unassigned_mem_ops for io_mem_rom
  block/iscsi: only report an iSCSI Failure if we don't handle it gracefully
  block/iscsi: dont leave allocmap in an invalid state on UNMAP failure
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-12-21 16:34:23 +00:00
commit 23bafd75cd
48 changed files with 665 additions and 488 deletions

View file

@ -1011,6 +1011,7 @@ T: git git://github.com/jasowang/qemu.git net
SCSI
M: Paolo Bonzini <pbonzini@redhat.com>
R: Fam Zheng <famz@redhat.com>
S: Supported
F: include/hw/scsi/*
F: hw/scsi/*
@ -1271,6 +1272,7 @@ T: git git://github.com/stefanha/qemu.git block
Block SCSI subsystem
M: Paolo Bonzini <pbonzini@redhat.com>
R: Fam Zheng <famz@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: include/scsi/*

View file

@ -525,19 +525,13 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
TranslationBlock **last_tb)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
int32_t insns_left;
/* Clear the interrupt flag now since we're processing
* cpu->interrupt_request and cpu->exit_request.
* Ensure zeroing happens before reading cpu->exit_request or
* cpu->interrupt_request (see also smp_wmb in cpu_exit())
*/
insns_left = atomic_read(&cpu->icount_decr.u32);
atomic_set(&cpu->icount_decr.u16.high, 0);
if (unlikely(insns_left < 0)) {
/* Ensure the zeroing of icount_decr comes before the next read
* of cpu->exit_request or cpu->interrupt_request.
*/
smp_mb();
}
atomic_mb_set(&cpu->icount_decr.u16.high, 0);
if (unlikely(atomic_read(&cpu->interrupt_request))) {
int interrupt_request;

View file

@ -2,7 +2,7 @@
* QEMU Block driver for iSCSI images
*
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
* Copyright (c) 2012-2016 Peter Lieven <pl@kamp.de>
* Copyright (c) 2012-2017 Peter Lieven <pl@kamp.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -104,6 +104,7 @@ typedef struct IscsiTask {
IscsiLun *iscsilun;
QEMUTimer retry_timer;
int err_code;
char *err_str;
} IscsiTask;
typedef struct IscsiAIOCB {
@ -265,7 +266,7 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
}
}
iTask->err_code = iscsi_translate_sense(&task->sense);
error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
iTask->err_str = g_strdup(iscsi_get_error(iscsi));
}
out:
@ -629,6 +630,8 @@ retry:
if (iTask.status != SCSI_STATUS_GOOD) {
iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
error_report("iSCSI WRITE10/16 failed at lba %" PRIu64 ": %s", lba,
iTask.err_str);
r = iTask.err_code;
goto out_unlock;
}
@ -637,6 +640,7 @@ retry:
out_unlock:
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
return r;
}
@ -651,10 +655,9 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL;
struct IscsiTask iTask;
uint64_t lba;
int64_t ret;
iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
ret = -EINVAL;
goto out;
@ -670,11 +673,13 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
goto out;
}
lba = sector_qemu2lun(sector_num, iscsilun);
iscsi_co_init_iscsitask(iscsilun, &iTask);
qemu_mutex_lock(&iscsilun->mutex);
retry:
if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
sector_qemu2lun(sector_num, iscsilun),
8 + 16, iscsi_co_generic_cb,
lba, 8 + 16, iscsi_co_generic_cb,
&iTask) == NULL) {
ret = -ENOMEM;
goto out_unlock;
@ -701,6 +706,8 @@ retry:
* because the device is busy or the cmd is not
* supported) we pretend all blocks are allocated
* for backwards compatibility */
error_report("iSCSI GET_LBA_STATUS failed at lba %" PRIu64 ": %s",
lba, iTask.err_str);
goto out_unlock;
}
@ -738,6 +745,7 @@ retry:
}
out_unlock:
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
out:
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
@ -756,6 +764,7 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
struct IscsiTask iTask;
uint64_t lba;
uint32_t num_sectors;
int r = 0;
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
return -EINVAL;
@ -853,19 +862,23 @@ retry:
iTask.complete = 0;
goto retry;
}
qemu_mutex_unlock(&iscsilun->mutex);
if (iTask.status != SCSI_STATUS_GOOD) {
return iTask.err_code;
error_report("iSCSI READ10/16 failed at lba %" PRIu64 ": %s",
lba, iTask.err_str);
r = iTask.err_code;
}
return 0;
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
return r;
}
static int coroutine_fn iscsi_co_flush(BlockDriverState *bs)
{
IscsiLun *iscsilun = bs->opaque;
struct IscsiTask iTask;
int r = 0;
iscsi_co_init_iscsitask(iscsilun, &iTask);
qemu_mutex_lock(&iscsilun->mutex);
@ -892,13 +905,15 @@ retry:
iTask.complete = 0;
goto retry;
}
qemu_mutex_unlock(&iscsilun->mutex);
if (iTask.status != SCSI_STATUS_GOOD) {
return iTask.err_code;
error_report("iSCSI SYNCHRONIZECACHE10 failed: %s", iTask.err_str);
r = iTask.err_code;
}
return 0;
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
return r;
}
#ifdef __linux__
@ -1128,6 +1143,9 @@ retry:
goto retry;
}
iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS);
if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {
/* the target might fail with a check condition if it
is not happy with the alignment of the UNMAP request
@ -1136,15 +1154,15 @@ retry:
}
if (iTask.status != SCSI_STATUS_GOOD) {
error_report("iSCSI UNMAP failed at lba %" PRIu64 ": %s",
list.lba, iTask.err_str);
r = iTask.err_code;
goto out_unlock;
}
iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS);
out_unlock:
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
return r;
}
@ -1241,6 +1259,8 @@ retry:
if (iTask.status != SCSI_STATUS_GOOD) {
iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS);
error_report("iSCSI WRITESAME10/16 failed at lba %" PRIu64 ": %s",
lba, iTask.err_str);
r = iTask.err_code;
goto out_unlock;
}
@ -1255,6 +1275,7 @@ retry:
out_unlock:
qemu_mutex_unlock(&iscsilun->mutex);
g_free(iTask.err_str);
return r;
}

View file

@ -18,10 +18,10 @@
#include "qmp-commands.h"
#include "block/nbd.h"
#include "io/channel-socket.h"
#include "io/net-listener.h"
typedef struct NBDServerData {
QIOChannelSocket *listen_ioc;
int watch;
QIONetListener *listener;
QCryptoTLSCreds *tlscreds;
} NBDServerData;
@ -32,27 +32,13 @@ static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
nbd_client_put(client);
}
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
gpointer opaque)
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
QIOChannelSocket *cioc;
if (!nbd_server) {
return FALSE;
}
cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
NULL);
if (!cioc) {
return TRUE;
}
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
nbd_client_new(NULL, cioc,
nbd_server->tlscreds, NULL,
nbd_blockdev_client_closed);
object_unref(OBJECT(cioc));
return TRUE;
}
@ -62,10 +48,8 @@ static void nbd_server_free(NBDServerData *server)
return;
}
if (server->watch != -1) {
g_source_remove(server->watch);
}
object_unref(OBJECT(server->listen_ioc));
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
if (server->tlscreds) {
object_unref(OBJECT(server->tlscreds));
}
@ -112,12 +96,12 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
}
nbd_server = g_new0(NBDServerData, 1);
nbd_server->watch = -1;
nbd_server->listen_ioc = qio_channel_socket_new();
qio_channel_set_name(QIO_CHANNEL(nbd_server->listen_ioc),
"nbd-listener");
if (qio_channel_socket_listen_sync(
nbd_server->listen_ioc, addr, errp) < 0) {
nbd_server->listener = qio_net_listener_new();
qio_net_listener_set_name(nbd_server->listener,
"nbd-listener");
if (qio_net_listener_open_sync(nbd_server->listener, addr, errp) < 0) {
goto error;
}
@ -134,12 +118,10 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
}
}
nbd_server->watch = qio_channel_add_watch(
QIO_CHANNEL(nbd_server->listen_ioc),
G_IO_IN,
nbd_accept,
NULL,
NULL);
qio_net_listener_set_client_func(nbd_server->listener,
nbd_accept,
NULL,
NULL);
return;

View file

@ -1,7 +1,7 @@
/*
* QEMU Baum Braille Device
*
* Copyright (c) 2008, 2010-2011, 2016 Samuel Thibault
* Copyright (c) 2008, 2010-2011, 2016-2017 Samuel Thibault
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -239,6 +239,12 @@ static int baum_deferred_init(BaumChardev *baum)
brlapi_perror("baum: brlapi__getDisplaySize");
return 0;
}
if (baum->y > 1) {
baum->y = 1;
}
if (baum->x > 84) {
baum->x = 84;
}
con = qemu_console_lookup_by_index(0);
if (con && qemu_console_is_graphic(con)) {

View file

@ -123,6 +123,15 @@ static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event)
}
}
static void mux_chr_be_event(Chardev *chr, int event)
{
MuxChardev *d = MUX_CHARDEV(chr);
if (d->focus != -1) {
mux_chr_send_event(d, d->focus, event);
}
}
static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch)
{
if (d->term_got_escape) {
@ -346,6 +355,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data)
cc->chr_write = mux_chr_write;
cc->chr_accept_input = mux_chr_accept_input;
cc->chr_add_watch = mux_chr_add_watch;
cc->chr_be_event = mux_chr_be_event;
}
static const TypeInfo char_mux_type_info = {

View file

@ -25,6 +25,7 @@
#include "chardev/char.h"
#include "io/channel-socket.h"
#include "io/channel-tls.h"
#include "io/net-listener.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/clone-visitor.h"
@ -40,8 +41,7 @@ typedef struct {
Chardev parent;
QIOChannel *ioc; /* Client I/O channel */
QIOChannelSocket *sioc; /* Client master channel */
QIOChannelSocket *listen_ioc;
guint listen_tag;
QIONetListener *listener;
QCryptoTLSCreds *tls_creds;
int connected;
int max_size;
@ -93,9 +93,9 @@ static void check_report_connect_error(Chardev *chr,
qemu_chr_socket_restart_timer(chr);
}
static gboolean tcp_chr_accept(QIOChannel *chan,
GIOCondition cond,
void *opaque);
static void tcp_chr_accept(QIONetListener *listener,
QIOChannelSocket *cioc,
void *opaque);
static int tcp_chr_read_poll(void *opaque);
static void tcp_chr_disconnect(Chardev *chr);
@ -401,9 +401,9 @@ static void tcp_chr_disconnect(Chardev *chr)
tcp_chr_free_connection(chr);
if (s->listen_ioc && s->listen_tag == 0) {
s->listen_tag = qio_channel_add_watch(
QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);
if (s->listener) {
qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
chr, NULL);
}
update_disconnected_filename(s);
if (emit_close) {
@ -702,9 +702,8 @@ static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
if (s->do_nodelay) {
qio_channel_set_delay(s->ioc, false);
}
if (s->listen_tag) {
g_source_remove(s->listen_tag);
s->listen_tag = 0;
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
}
if (s->tls_creds) {
@ -736,24 +735,14 @@ static int tcp_chr_add_client(Chardev *chr, int fd)
return ret;
}
static gboolean tcp_chr_accept(QIOChannel *channel,
GIOCondition cond,
void *opaque)
static void tcp_chr_accept(QIONetListener *listener,
QIOChannelSocket *cioc,
void *opaque)
{
Chardev *chr = CHARDEV(opaque);
QIOChannelSocket *sioc;
sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(channel),
NULL);
if (!sioc) {
return TRUE;
}
tcp_chr_new_client(chr, sioc);
object_unref(OBJECT(sioc));
return TRUE;
tcp_chr_set_client_ioc_name(chr, cioc);
tcp_chr_new_client(chr, cioc);
}
static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
@ -767,9 +756,10 @@ static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
if (s->is_listen) {
info_report("QEMU waiting for connection on: %s",
chr->filename);
qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL);
tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr);
qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL);
sioc = qio_net_listener_wait_client(s->listener);
tcp_chr_set_client_ioc_name(chr, sioc);
tcp_chr_new_client(chr, sioc);
object_unref(OBJECT(sioc));
} else {
sioc = qio_channel_socket_new();
tcp_chr_set_client_ioc_name(chr, sioc);
@ -797,12 +787,9 @@ static void char_socket_finalize(Object *obj)
s->reconnect_timer = 0;
}
qapi_free_SocketAddress(s->addr);
if (s->listen_tag) {
g_source_remove(s->listen_tag);
s->listen_tag = 0;
}
if (s->listen_ioc) {
object_unref(OBJECT(s->listen_ioc));
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
object_unref(OBJECT(s->listener));
}
if (s->tls_creds) {
object_unref(OBJECT(s->tls_creds));
@ -935,29 +922,29 @@ static void qmp_chardev_open_socket(Chardev *chr,
} else {
if (s->is_listen) {
char *name;
sioc = qio_channel_socket_new();
s->listener = qio_net_listener_new();
name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
qio_channel_set_name(QIO_CHANNEL(sioc), name);
qio_net_listener_set_name(s->listener, name);
g_free(name);
if (qio_channel_socket_listen_sync(sioc, s->addr, errp) < 0) {
if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
object_unref(OBJECT(s->listener));
s->listener = NULL;
goto error;
}
qapi_free_SocketAddress(s->addr);
s->addr = socket_local_address(sioc->fd, errp);
s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
update_disconnected_filename(s);
s->listen_ioc = sioc;
if (is_waitconnect &&
qemu_chr_wait_connected(chr, errp) < 0) {
return;
}
if (!s->ioc) {
s->listen_tag = qio_channel_add_watch(
QIO_CHANNEL(s->listen_ioc), G_IO_IN,
tcp_chr_accept, chr, NULL);
qio_net_listener_set_client_func(s->listener, tcp_chr_accept,
chr, NULL);
}
} else if (qemu_chr_wait_connected(chr, errp) < 0) {
goto error;

View file

@ -43,10 +43,19 @@ static Object *get_chardevs_root(void)
return container_get(object_get_root(), "/chardevs");
}
void qemu_chr_be_event(Chardev *s, int event)
static void chr_be_event(Chardev *s, int event)
{
CharBackend *be = s->be;
if (!be || !be->chr_event) {
return;
}
be->chr_event(be->opaque, event);
}
void qemu_chr_be_event(Chardev *s, int event)
{
/* Keep track if the char device is open */
switch (event) {
case CHR_EVENT_OPENED:
@ -57,11 +66,7 @@ void qemu_chr_be_event(Chardev *s, int event)
break;
}
if (!be || !be->chr_event) {
return;
}
be->chr_event(be->opaque, event);
CHARDEV_GET_CLASS(s)->chr_be_event(s, event);
}
/* Not reporting errors from writing to logfile, as logs are
@ -244,6 +249,7 @@ static void char_class_init(ObjectClass *oc, void *data)
ChardevClass *cc = CHARDEV_CLASS(oc);
cc->chr_write = null_chr_write;
cc->chr_be_event = chr_be_event;
}
static void char_finalize(Object *obj)

37
configure vendored
View file

@ -426,6 +426,7 @@ vxhs=""
supported_cpu="no"
supported_os="no"
bogus_os="no"
malloc_trim=""
# parse CC options first
for opt do
@ -1047,6 +1048,10 @@ for opt do
;;
--enable-tcg) tcg="yes"
;;
--disable-malloc-trim) malloc_trim="no"
;;
--enable-malloc-trim) malloc_trim="yes"
;;
--disable-spice) spice="no"
;;
--enable-spice) spice="yes"
@ -1466,6 +1471,7 @@ Advanced options (experts only):
Default:trace-<pid>
--disable-slirp disable SLIRP userspace network connectivity
--enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
--enable-malloc-trim enable libc malloc_trim() for memory optimization
--oss-lib path to OSS library
--cpu=CPU Build for host CPU [$cpu]
--with-coroutine=BACKEND coroutine backend. Supported options:
@ -3860,6 +3866,30 @@ if test "$tcmalloc" = "yes" && test "$jemalloc" = "yes" ; then
exit 1
fi
# Even if malloc_trim() is available, these non-libc memory allocators
# do not support it.
if test "$tcmalloc" = "yes" || test "$jemalloc" = "yes" ; then
if test "$malloc_trim" = "yes" ; then
echo "Disabling malloc_trim with non-libc memory allocator"
fi
malloc_trim="no"
fi
#######################################
# malloc_trim
if test "$malloc_trim" != "no" ; then
cat > $TMPC << EOF
#include <malloc.h>
int main(void) { malloc_trim(0); return 0; }
EOF
if compile_prog "" "" ; then
malloc_trim="yes"
else
malloc_trim="no"
fi
fi
##########################################
# tcmalloc probe
@ -3923,7 +3953,7 @@ fi
# check if memfd is supported
memfd=no
cat > $TMPC << EOF
#include <sys/memfd.h>
#include <sys/mman.h>
int main(void)
{
@ -5505,6 +5535,7 @@ if test "$tcg" = "yes" ; then
echo "TCG debug enabled $debug_tcg"
echo "TCG interpreter $tcg_interpreter"
fi
echo "malloc trim support $malloc_trim"
echo "RDMA support $rdma"
echo "fdt support $fdt"
echo "preadv support $preadv"
@ -6015,6 +6046,10 @@ if test "$opengl" = "yes" ; then
fi
fi
if test "$malloc_trim" = "yes" ; then
echo "CONFIG_MALLOC_TRIM=y" >> $config_host_mak
fi
if test "$avx2_opt" = "yes" ; then
echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
fi

View file

@ -0,0 +1,11 @@
[Unit]
Description=QEMU Guest Agent
BindTo=dev-virtio\x2dports-org.qemu.guest_agent.0.device
After=dev-virtio\x2dports-org.qemu.guest_agent.0.device
[Service]
ExecStart=-/usr/bin/qemu-ga
Restart=always
RestartSec=0
[Install]

View file

@ -0,0 +1,15 @@
[Unit]
Description=Persistent Reservation Daemon for QEMU
[Service]
WorkingDirectory=/tmp
Type=simple
ExecStart=/usr/bin/qemu-pr-helper
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=/var/run
RestrictAddressFamilies=AF_UNIX
Restart=always
RestartSec=0
[Install]

View file

@ -0,0 +1,9 @@
[Unit]
Description=Persistent Reservation Daemon for QEMU
[Socket]
ListenStream=/run/qemu-pr-helper.sock
SocketMode=0600
[Install]
WantedBy=multi-user.target

37
cpus.c
View file

@ -1057,13 +1057,22 @@ static void qemu_tcg_destroy_vcpu(CPUState *cpu)
{
}
static void qemu_cpu_stop(CPUState *cpu, bool exit)
{
g_assert(qemu_cpu_is_self(cpu));
cpu->stop = false;
cpu->stopped = true;
if (exit) {
cpu_exit(cpu);
}
qemu_cond_broadcast(&qemu_pause_cond);
}
static void qemu_wait_io_event_common(CPUState *cpu)
{
atomic_mb_set(&cpu->thread_kicked, false);
if (cpu->stop) {
cpu->stop = false;
cpu->stopped = true;
qemu_cond_broadcast(&qemu_pause_cond);
qemu_cpu_stop(cpu, false);
}
process_queued_cpu_work(cpu);
}
@ -1610,12 +1619,12 @@ void pause_all_vcpus(void)
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
CPU_FOREACH(cpu) {
cpu->stop = true;
qemu_cpu_kick(cpu);
}
if (qemu_in_vcpu_thread()) {
cpu_stop_current();
if (qemu_cpu_is_self(cpu)) {
qemu_cpu_stop(cpu, true);
} else {
cpu->stop = true;
qemu_cpu_kick(cpu);
}
}
while (!all_vcpus_paused()) {
@ -1778,11 +1787,8 @@ void qemu_init_vcpu(CPUState *cpu)
/* If the target cpu hasn't set up any address spaces itself,
* give it the default one.
*/
AddressSpace *as = g_new0(AddressSpace, 1);
address_space_init(as, cpu->memory, "cpu-memory");
cpu->num_ases = 1;
cpu_address_space_init(cpu, as, 0);
cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory);
}
if (kvm_enabled()) {
@ -1799,10 +1805,7 @@ void qemu_init_vcpu(CPUState *cpu)
void cpu_stop_current(void)
{
if (current_cpu) {
current_cpu->stop = false;
current_cpu->stopped = true;
cpu_exit(current_cpu);
qemu_cond_broadcast(&qemu_pause_cond);
qemu_cpu_stop(current_cpu, true);
}
}

44
exec.c
View file

@ -705,9 +705,17 @@ CPUState *qemu_get_cpu(int index)
}
#if !defined(CONFIG_USER_ONLY)
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx)
void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr)
{
CPUAddressSpace *newas;
AddressSpace *as = g_new0(AddressSpace, 1);
char *as_name;
assert(mr);
as_name = g_strdup_printf("%s-%d", prefix, cpu->cpu_index);
address_space_init(as, mr, as_name);
g_free(as_name);
/* Target code should have set num_ases before calling us */
assert(asidx < cpu->num_ases);
@ -2717,6 +2725,37 @@ static uint16_t dummy_section(PhysPageMap *map, FlatView *fv, MemoryRegion *mr)
return phys_section_add(map, &section);
}
static void readonly_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
/* Ignore any write to ROM. */
}
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
unsigned size, bool is_write)
{
return is_write;
}
/* This will only be used for writes, because reads are special cased
* to directly access the underlying host ram.
*/
static const MemoryRegionOps readonly_mem_ops = {
.write = readonly_mem_write,
.valid.accepts = readonly_mem_accepts,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 8,
.unaligned = false,
},
.impl = {
.min_access_size = 1,
.max_access_size = 8,
.unaligned = false,
},
};
MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs)
{
int asidx = cpu_asidx_from_attrs(cpu, attrs);
@ -2729,7 +2768,8 @@ MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs)
static void io_mem_init(void)
{
memory_region_init_io(&io_mem_rom, NULL, &unassigned_mem_ops, NULL, NULL, UINT64_MAX);
memory_region_init_io(&io_mem_rom, NULL, &readonly_mem_ops,
NULL, NULL, UINT64_MAX);
memory_region_init_io(&io_mem_unassigned, NULL, &unassigned_mem_ops, NULL,
NULL, UINT64_MAX);

View file

@ -111,6 +111,7 @@ static void kvm_pic_set_irq(void *opaque, int irq, int level)
{
int delivered;
pic_stat_update_irq(irq, level);
delivered = kvm_set_irq(kvm_state, irq, level);
apic_report_irq_delivered(delivered);
}

View file

@ -113,3 +113,7 @@ amdvi_mode_invalid(uint8_t level, uint64_t addr)"error: translation level 0x%"PR
amdvi_page_fault(uint64_t addr) "error: page fault accessing guest physical address 0x%"PRIx64
amdvi_iotlb_hit(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "hit iotlb devid %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64
amdvi_translation_result(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "devid: %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64
# hw/i386/vmport.c
vmport_register(unsigned char command, void *func, void *opaque) "command: 0x%02x func: %p opaque: %p"
vmport_command(unsigned char command) "command: 0x%02x"

View file

@ -27,8 +27,7 @@
#include "hw/i386/pc.h"
#include "sysemu/hw_accel.h"
#include "hw/qdev.h"
/* #define VMPORT_DEBUG */
#include "trace.h"
#define VMPORT_CMD_GETVERSION 0x0a
#define VMPORT_CMD_GETRAMSIZE 0x14
@ -54,6 +53,7 @@ void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque)
return;
}
trace_vmport_register(command, func, opaque);
port_state->func[command] = func;
port_state->opaque[command] = opaque;
}
@ -76,13 +76,9 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
}
command = env->regs[R_ECX];
if (command >= VMPORT_ENTRIES) {
return eax;
}
if (!s->func[command]) {
#ifdef VMPORT_DEBUG
fprintf(stderr, "vmport: unknown command %x\n", command);
#endif
trace_vmport_command(command);
if (command >= VMPORT_ENTRIES || !s->func[command]) {
qemu_log_mask(LOG_UNIMP, "vmport: unknown command %x\n", command);
return eax;
}

View file

@ -25,24 +25,15 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
#include "monitor/monitor.h"
#include "qemu/timer.h"
#include "qemu/log.h"
#include "hw/isa/i8259_internal.h"
#include "hw/intc/intc.h"
#include "trace.h"
/* debug PIC */
//#define DEBUG_PIC
#ifdef DEBUG_PIC
#define DPRINTF(fmt, ...) \
do { printf("pic: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...)
#endif
//#define DEBUG_IRQ_LATENCY
//#define DEBUG_IRQ_COUNT
#define TYPE_I8259 "isa-i8259"
#define PIC_CLASS(class) OBJECT_CLASS_CHECK(PICClass, (class), TYPE_I8259)
@ -58,12 +49,6 @@ typedef struct PICClass {
DeviceRealize parent_realize;
} PICClass;
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
static int irq_level[16];
#endif
#ifdef DEBUG_IRQ_COUNT
static uint64_t irq_count[16];
#endif
#ifdef DEBUG_IRQ_LATENCY
static int64_t irq_time[16];
#endif
@ -122,8 +107,7 @@ static void pic_update_irq(PICCommonState *s)
irq = pic_get_irq(s);
if (irq >= 0) {
DPRINTF("pic%d: imr=%x irr=%x padd=%d\n",
s->master ? 0 : 1, s->imr, s->irr, s->priority_add);
trace_pic_update_irq(s->master, s->imr, s->irr, s->priority_add);
qemu_irq_raise(s->int_out[0]);
} else {
qemu_irq_lower(s->int_out[0]);
@ -135,22 +119,11 @@ static void pic_set_irq(void *opaque, int irq, int level)
{
PICCommonState *s = opaque;
int mask = 1 << irq;
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) || \
defined(DEBUG_IRQ_LATENCY)
int irq_index = s->master ? irq : irq + 8;
#endif
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
if (level != irq_level[irq_index]) {
DPRINTF("pic_set_irq: irq=%d level=%d\n", irq_index, level);
irq_level[irq_index] = level;
#ifdef DEBUG_IRQ_COUNT
if (level == 1) {
irq_count[irq_index]++;
}
#endif
}
#endif
trace_pic_set_irq(s->master, irq, level);
pic_stat_update_irq(irq_index, level);
#ifdef DEBUG_IRQ_LATENCY
if (level) {
irq_time[irq_index] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@ -223,18 +196,18 @@ int pic_read_irq(DeviceState *d)
intno = s->irq_base + irq;
}
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY)
if (irq == 2) {
irq = irq2 + 8;
}
#endif
#ifdef DEBUG_IRQ_LATENCY
printf("IRQ%d latency=%0.3fus\n",
irq,
(double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
irq_time[irq]) * 1000000.0 / NANOSECONDS_PER_SECOND);
#endif
DPRINTF("pic_interrupt: irq=%d\n", irq);
trace_pic_interrupt(irq, intno);
return intno;
}
@ -252,35 +225,6 @@ static void pic_reset(DeviceState *dev)
pic_init_reset(s);
}
static bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs)
{
PICCommonState *s = PIC_COMMON(obj);
if (s->master) {
#ifdef DEBUG_IRQ_COUNT
*irq_counts = irq_count;
*nb_irqs = ARRAY_SIZE(irq_count);
#else
return false;
#endif
} else {
*irq_counts = NULL;
*nb_irqs = 0;
}
return true;
}
static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
{
PICCommonState *s = PIC_COMMON(obj);
monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d "
"irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
s->master ? 0 : 1, s->irr, s->imr, s->isr, s->priority_add,
s->irq_base, s->read_reg_select, s->elcr,
s->special_fully_nested_mode);
}
static void pic_ioport_write(void *opaque, hwaddr addr64,
uint64_t val64, unsigned size)
{
@ -289,7 +233,8 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
uint32_t val = val64;
int priority, cmd, irq;
DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);
trace_pic_ioport_write(s->master, addr, val);
if (addr == 0) {
if (val & 0x10) {
pic_init_reset(s);
@ -402,7 +347,7 @@ static uint64_t pic_ioport_read(void *opaque, hwaddr addr,
ret = s->imr;
}
}
DPRINTF("read: addr=0x%02" HWADDR_PRIx " val=0x%02x\n", addr, ret);
trace_pic_ioport_read(s->master, addr, ret);
return ret;
}
@ -497,13 +442,10 @@ static void i8259_class_init(ObjectClass *klass, void *data)
{
PICClass *k = PIC_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
k->parent_realize = dc->realize;
dc->realize = pic_realize;
dc->reset = pic_reset;
ic->get_statistics = pic_get_statistics;
ic->print_info = pic_print_info;
}
static const TypeInfo i8259_info = {
@ -512,10 +454,6 @@ static const TypeInfo i8259_info = {
.parent = TYPE_PIC_COMMON,
.class_init = i8259_class_init,
.class_size = sizeof(PICClass),
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};
static void pic_register_types(void)

View file

@ -25,6 +25,10 @@
#include "qemu/osdep.h"
#include "hw/i386/pc.h"
#include "hw/isa/i8259_internal.h"
#include "monitor/monitor.h"
static int irq_level[16];
static uint64_t irq_count[16];
void pic_reset_common(PICCommonState *s)
{
@ -98,6 +102,44 @@ ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master)
return isadev;
}
void pic_stat_update_irq(int irq, int level)
{
if (level != irq_level[irq]) {
irq_level[irq] = level;
if (level == 1) {
irq_count[irq]++;
}
}
}
bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs)
{
PICCommonState *s = PIC_COMMON(obj);
if (s->master) {
*irq_counts = irq_count;
*nb_irqs = ARRAY_SIZE(irq_count);
} else {
*irq_counts = NULL;
*nb_irqs = 0;
}
return true;
}
void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
{
PICCommonState *s = PIC_COMMON(obj);
pic_dispatch_pre_save(s);
monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d "
"irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
s->master ? 0 : 1, s->irr, s->imr, s->isr, s->priority_add,
s->irq_base, s->read_reg_select, s->elcr,
s->special_fully_nested_mode);
}
static const VMStateDescription vmstate_pic_common = {
.name = "i8259",
.version_id = 1,
@ -136,6 +178,7 @@ static Property pic_properties_common[] = {
static void pic_common_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
dc->vmsd = &vmstate_pic_common;
dc->props = pic_properties_common;
@ -147,6 +190,8 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
* code.
*/
dc->user_creatable = false;
ic->get_statistics = pic_get_statistics;
ic->print_info = pic_print_info;
}
static const TypeInfo pic_common_type = {
@ -156,6 +201,10 @@ static const TypeInfo pic_common_type = {
.class_size = sizeof(PICCommonClass),
.class_init = pic_common_class_init,
.abstract = true,
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};
static void pic_common_register_types(void)

View file

@ -1,5 +1,12 @@
# See docs/devel/tracing.txt for syntax documentation.
# hw/intc/i8259.c
pic_update_irq(bool master, uint8_t imr, uint8_t irr, uint8_t padd) "master %d imr %"PRIu8" irr %"PRIu8" padd %"PRIu8
pic_set_irq(bool master, int irq, int level) "master %d irq %d level %d"
pic_interrupt(int irq, int intno) "irq %d intno %d"
pic_ioport_write(bool master, uint64_t addr, uint64_t val) "master %d addr 0x%"PRIx64" val 0x%"PRIx64
pic_ioport_read(bool master, uint64_t addr, int val) "master %d addr 0x%"PRIx64" val 0x%x"
# hw/intc/apic_common.c
cpu_set_apic_base(uint64_t val) "0x%016"PRIx64
cpu_get_apic_base(uint64_t val) "0x%016"PRIx64

View file

@ -248,16 +248,6 @@ static const MemoryRegionOps boston_platreg_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void boston_flash_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
}
static const MemoryRegionOps boston_flash_ops = {
.write = boston_flash_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static const TypeInfo boston_device = {
.name = TYPE_MIPS_BOSTON,
.parent = TYPE_SYS_BUS_DEVICE,
@ -481,8 +471,8 @@ static void boston_mach_init(MachineState *machine)
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
flash = g_new(MemoryRegion, 1);
memory_region_init_rom_device_nomigrate(flash, NULL, &boston_flash_ops, s,
"boston.flash", 128 * M_BYTE, &err);
memory_region_init_rom_nomigrate(flash, NULL,
"boston.flash", 128 * M_BYTE, &err);
memory_region_add_subregion_overlap(sys_mem, 0x18000000, flash, 0);
ddr = g_new(MemoryRegion, 1);

View file

@ -25,6 +25,7 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
@ -40,6 +41,8 @@
#include "elf.h"
#define PHYS_MEM_BASE 0x80000000
#define FIRMWARE_BASE 0x1000
#define FIRMWARE_SIZE (128 * 0x1000)
typedef struct {
uint64_t ram_size;
@ -122,8 +125,8 @@ static void moxiesim_init(MachineState *machine)
memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size, &error_fatal);
memory_region_add_subregion(address_space_mem, ram_base, ram);
memory_region_init_ram(rom, NULL, "moxie.rom", 128 * 0x1000, &error_fatal);
memory_region_add_subregion(get_system_memory(), 0x1000, rom);
memory_region_init_ram(rom, NULL, "moxie.rom", FIRMWARE_SIZE, &error_fatal);
memory_region_add_subregion(get_system_memory(), FIRMWARE_BASE, rom);
if (kernel_filename) {
loader_params.ram_size = ram_size;
@ -132,6 +135,11 @@ static void moxiesim_init(MachineState *machine)
loader_params.initrd_filename = initrd_filename;
load_kernel(cpu, &loader_params);
}
if (bios_name) {
if (load_image_targphys(bios_name, FIRMWARE_BASE, FIRMWARE_SIZE) < 0) {
error_report("Failed to load firmware '%s'", bios_name);
}
}
/* A single 16450 sits at offset 0x3f8. */
if (serial_hds[0]) {

View file

@ -540,20 +540,8 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
if (req->lun != 0) {
const struct SCSISense sense = SENSE_CODE(LUN_NOT_SUPPORTED);
if (fixed_sense) {
r->buf[0] = 0x70;
r->buf[2] = sense.key;
r->buf[10] = 10;
r->buf[12] = sense.asc;
r->buf[13] = sense.ascq;
r->len = MIN(req->cmd.xfer, SCSI_SENSE_LEN);
} else {
r->buf[0] = 0x72;
r->buf[1] = sense.key;
r->buf[2] = sense.asc;
r->buf[3] = sense.ascq;
r->len = 8;
}
r->len = scsi_build_sense_buf(r->buf, req->cmd.xfer,
sense, fixed_sense);
} else {
r->len = scsi_device_get_sense(r->req.dev, r->buf,
MIN(req->cmd.xfer, r->buf_len),

View file

@ -3004,6 +3004,7 @@ static const TypeInfo scsi_cd_info = {
static Property scsi_block_properties[] = {
DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
DEFINE_PROP_END_OF_LIST(),
};

View file

@ -248,6 +248,7 @@ typedef struct ChardevClass {
void (*chr_accept_input)(Chardev *chr);
void (*chr_set_echo)(Chardev *chr, bool echo);
void (*chr_set_fe_open)(Chardev *chr, int fe_open);
void (*chr_be_event)(Chardev *s, int event);
} ChardevClass;
Chardev *qemu_chardev_new(const char *id, const char *typename,

View file

@ -74,8 +74,9 @@ void cpu_reloading_memory_map(void);
/**
* cpu_address_space_init:
* @cpu: CPU to add this address space to
* @as: address space to add
* @asidx: integer index of this address space
* @prefix: prefix to be used as name of address space
* @mr: the root memory region of address space
*
* Add the specified address space to the CPU's cpu_ases list.
* The address space added with @asidx 0 is the one used for the
@ -89,7 +90,8 @@ void cpu_reloading_memory_map(void);
*
* Note that with KVM only one address space is supported.
*/
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx);
void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr);
#endif
#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)

View file

@ -28,6 +28,7 @@
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
#include "hw/intc/intc.h"
typedef struct PICCommonState PICCommonState;
@ -76,8 +77,10 @@ struct PICCommonState {
};
void pic_reset_common(PICCommonState *s);
ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
void pic_stat_update_irq(int irq, int level);
bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs);
void pic_print_info(InterruptStatsProvider *obj, Monitor *mon);
#endif /* QEMU_I8259_INTERNAL_H */

View file

@ -35,7 +35,7 @@ int inet_connect_saddr(InetSocketAddress *saddr, Error **errp);
NetworkAddressFamily inet_netfamily(int family);
int unix_listen(const char *path, char *ostr, int olen, Error **errp);
int unix_listen(const char *path, Error **errp);
int unix_connect(const char *path, Error **errp);
SocketAddress *socket_parse(const char *str, Error **errp);

View file

@ -31,6 +31,9 @@ typedef struct SCSISense {
} SCSISense;
int scsi_build_sense(uint8_t *buf, SCSISense sense);
SCSISense scsi_parse_sense_buf(const uint8_t *in_buf, int in_len);
int scsi_build_sense_buf(uint8_t *buf, size_t max_size, SCSISense sense,
bool fixed_sense);
/*
* Predefined sense codes
@ -76,7 +79,11 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
extern const struct SCSISense sense_code_LUN_COMM_FAILURE;
/* Command aborted, Overlapped Commands Attempted */
extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS;
/* LUN not ready, Capacity data has changed */
/* Medium error, Unrecovered read error */
extern const struct SCSISense sense_code_READ_ERROR;
/* LUN not ready, Cause not reportable */
extern const struct SCSISense sense_code_NOT_READY;
/* Unit attention, Capacity data has changed */
extern const struct SCSISense sense_code_CAPACITY_CHANGED;
/* Unit attention, SCSI bus reset */
extern const struct SCSISense sense_code_SCSI_BUS_RESET;

View file

@ -2612,11 +2612,6 @@ synonym for setting ``-global kvm-pit.lost_tick_policy=discard''.
The ``-no-kvm-irqchip'' argument is now a synonym for
setting ``-machine kernel_irqchip=off''.
@subsection -no-kvm-pit (since 1.3.0)
The ``-no-kvm-pit'' argument is ignored. It is no longer
possible to disable the KVM PIT directly.
@subsection -no-kvm (since 1.3.0)
The ``-no-kvm'' argument is now a synonym for setting

View file

@ -37,6 +37,7 @@
#include "qapi/qmp/qstring.h"
#include "qom/object_interfaces.h"
#include "io/channel-socket.h"
#include "io/net-listener.h"
#include "crypto/init.h"
#include "trace/control.h"
#include "qemu-version.h"
@ -62,8 +63,7 @@ static int persistent = 0;
static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state;
static int shared = 1;
static int nb_fds;
static QIOChannelSocket *server_ioc;
static int server_watch = -1;
static QIONetListener *server;
static QCryptoTLSCreds *tlscreds;
static void usage(const char *name)
@ -344,44 +344,25 @@ static void nbd_client_closed(NBDClient *client, bool negotiated)
nbd_client_put(client);
}
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
QIOChannelSocket *cioc;
cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
NULL);
if (!cioc) {
return TRUE;
}
if (state >= TERMINATE) {
object_unref(OBJECT(cioc));
return TRUE;
return;
}
nb_fds++;
nbd_update_server_watch();
nbd_client_new(newproto ? NULL : exp, cioc,
tlscreds, NULL, nbd_client_closed);
object_unref(OBJECT(cioc));
return TRUE;
}
static void nbd_update_server_watch(void)
{
if (nbd_can_accept()) {
if (server_watch == -1) {
server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
G_IO_IN,
nbd_accept,
NULL, NULL);
}
qio_net_listener_set_client_func(server, nbd_accept, NULL, NULL);
} else {
if (server_watch != -1) {
g_source_remove(server_watch);
server_watch = -1;
}
qio_net_listener_set_client_func(server, NULL, NULL, NULL);
}
}
@ -915,23 +896,29 @@ int main(int argc, char **argv)
snprintf(sockpath, 128, SOCKET_PATH, basename(device));
}
server = qio_net_listener_new();
if (socket_activation == 0) {
server_ioc = qio_channel_socket_new();
saddr = nbd_build_socket_address(sockpath, bindto, port);
if (qio_channel_socket_listen_sync(server_ioc, saddr, &local_err) < 0) {
object_unref(OBJECT(server_ioc));
if (qio_net_listener_open_sync(server, saddr, &local_err) < 0) {
object_unref(OBJECT(server));
error_report_err(local_err);
return 1;
exit(EXIT_FAILURE);
}
} else {
size_t i;
/* See comment in check_socket_activation above. */
assert(socket_activation == 1);
server_ioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD,
&local_err);
if (server_ioc == NULL) {
error_report("Failed to use socket activation: %s",
error_get_pretty(local_err));
exit(EXIT_FAILURE);
for (i = 0; i < socket_activation; i++) {
QIOChannelSocket *sioc;
sioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD + i,
&local_err);
if (sioc == NULL) {
object_unref(OBJECT(server));
error_report("Failed to use socket activation: %s",
error_get_pretty(local_err));
exit(EXIT_FAILURE);
}
qio_net_listener_add(server, sioc);
object_unref(OBJECT(sioc));
}
}

View file

@ -3927,9 +3927,6 @@ HXCOMM Deprecated by kvm-pit driver properties
DEF("no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection,
"", QEMU_ARCH_I386)
HXCOMM Deprecated (ignored)
DEF("no-kvm-pit", 0, QEMU_OPTION_no_kvm_pit, "", QEMU_ARCH_I386)
HXCOMM Deprecated by -machine kernel_irqchip=on|off property
DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386)

View file

@ -190,7 +190,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path,
if (fd < 0) {
Error *local_err = NULL;
fd = unix_listen(path, NULL, strlen(path), &local_err);
fd = unix_listen(path, &local_err);
if (local_err != NULL) {
g_critical("%s", error_get_pretty(local_err));
error_free(local_err);

View file

@ -2475,8 +2475,11 @@ sub process {
# no volatiles please
my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
ERROR("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/ &&
$line !~ /sig_atomic_t/ &&
!ctx_has_comment($first_line, $linenr)) {
my $msg = "Use of volatile is usually wrong, please add a comment\n" . $herecurr;
ERROR($msg);
}
# warn about #if 0

View file

@ -314,6 +314,22 @@ static int is_mpath(int fd)
return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
}
static SCSISense mpath_generic_sense(int r)
{
switch (r) {
case MPATH_PR_SENSE_NOT_READY:
return SENSE_CODE(NOT_READY);
case MPATH_PR_SENSE_MEDIUM_ERROR:
return SENSE_CODE(READ_ERROR);
case MPATH_PR_SENSE_HARDWARE_ERROR:
return SENSE_CODE(TARGET_FAILURE);
case MPATH_PR_SENSE_ABORTED_COMMAND:
return SENSE_CODE(IO_ERROR);
default:
abort();
}
}
static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
{
switch (r) {
@ -329,7 +345,13 @@ static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
*/
uint8_t cdb[6] = { TEST_UNIT_READY };
int sz = 0;
return do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
int r = do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
if (r != GOOD) {
return r;
}
scsi_build_sense(sense, mpath_generic_sense(r));
return CHECK_CONDITION;
}
case MPATH_PR_SENSE_UNIT_ATTENTION:
@ -449,7 +471,7 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
memset(&paramp, 0, sizeof(paramp));
memcpy(&paramp.key, &param[0], 8);
memcpy(&paramp.sa_key, &param[8], 8);
paramp.sa_flags = param[10];
paramp.sa_flags = param[20];
if (sz > PR_OUT_FIXED_PARAM_SIZE) {
size_t transportid_len;
int i, j;
@ -478,8 +500,8 @@ static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
j += offsetof(struct transportid, n_port_name[8]);
i += 24;
break;
case 3:
case 0x43:
case 5:
case 0x45:
/* iSCSI transport. */
len = lduw_be_p(&param[i + 2]);
if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {

View file

@ -96,15 +96,60 @@ int scsi_cdb_length(uint8_t *buf)
return cdb_len;
}
SCSISense scsi_parse_sense_buf(const uint8_t *in_buf, int in_len)
{
bool fixed_in;
SCSISense sense;
assert(in_len > 0);
fixed_in = (in_buf[0] & 2) == 0;
if (fixed_in) {
if (in_len < 14) {
return SENSE_CODE(IO_ERROR);
}
sense.key = in_buf[2];
sense.asc = in_buf[12];
sense.ascq = in_buf[13];
} else {
if (in_len < 4) {
return SENSE_CODE(IO_ERROR);
}
sense.key = in_buf[1];
sense.asc = in_buf[2];
sense.ascq = in_buf[3];
}
return sense;
}
int scsi_build_sense_buf(uint8_t *out_buf, size_t size, SCSISense sense,
bool fixed_sense)
{
int len;
uint8_t buf[SCSI_SENSE_LEN] = { 0 };
if (fixed_sense) {
buf[0] = 0x70;
buf[2] = sense.key;
buf[7] = 10;
buf[12] = sense.asc;
buf[13] = sense.ascq;
len = 18;
} else {
buf[0] = 0x72;
buf[1] = sense.key;
buf[2] = sense.asc;
buf[3] = sense.ascq;
len = 8;
}
len = MIN(len, size);
memcpy(out_buf, buf, len);
return len;
}
int scsi_build_sense(uint8_t *buf, SCSISense sense)
{
memset(buf, 0, 18);
buf[0] = 0x70;
buf[2] = sense.key;
buf[7] = 10;
buf[12] = sense.asc;
buf[13] = sense.ascq;
return 18;
return scsi_build_sense_buf(buf, SCSI_SENSE_LEN, sense, true);
}
/*
@ -211,6 +256,16 @@ const struct SCSISense sense_code_LUN_COMM_FAILURE = {
.key = ABORTED_COMMAND, .asc = 0x08, .ascq = 0x00
};
/* Medium Error, Unrecovered read error */
const struct SCSISense sense_code_READ_ERROR = {
.key = MEDIUM_ERROR, .asc = 0x11, .ascq = 0x00
};
/* Not ready, Cause not reportable */
const struct SCSISense sense_code_NOT_READY = {
.key = NOT_READY, .asc = 0x04, .ascq = 0x00
};
/* Unit attention, Capacity data has changed */
const struct SCSISense sense_code_CAPACITY_CHANGED = {
.key = UNIT_ATTENTION, .asc = 0x2a, .ascq = 0x09
@ -264,67 +319,36 @@ const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
int scsi_convert_sense(uint8_t *in_buf, int in_len,
uint8_t *buf, int len, bool fixed)
{
bool fixed_in;
SCSISense sense;
if (!fixed && len < 8) {
return 0;
bool fixed_in;
fixed_in = (in_buf[0] & 2) == 0;
if (in_len && fixed == fixed_in) {
memcpy(buf, in_buf, MIN(len, in_len));
return MIN(len, in_len);
}
if (in_len == 0) {
sense.key = NO_SENSE;
sense.asc = 0;
sense.ascq = 0;
sense = SENSE_CODE(NO_SENSE);
} else {
fixed_in = (in_buf[0] & 2) == 0;
if (fixed == fixed_in) {
memcpy(buf, in_buf, MIN(len, in_len));
return MIN(len, in_len);
}
if (fixed_in) {
sense.key = in_buf[2];
sense.asc = in_buf[12];
sense.ascq = in_buf[13];
} else {
sense.key = in_buf[1];
sense.asc = in_buf[2];
sense.ascq = in_buf[3];
}
}
memset(buf, 0, len);
if (fixed) {
/* Return fixed format sense buffer */
buf[0] = 0x70;
buf[2] = sense.key;
buf[7] = 10;
buf[12] = sense.asc;
buf[13] = sense.ascq;
return MIN(len, SCSI_SENSE_LEN);
} else {
/* Return descriptor format sense buffer */
buf[0] = 0x72;
buf[1] = sense.key;
buf[2] = sense.asc;
buf[3] = sense.ascq;
return 8;
sense = scsi_parse_sense_buf(in_buf, in_len);
}
return scsi_build_sense_buf(buf, len, sense, fixed);
}
int scsi_sense_to_errno(int key, int asc, int ascq)
{
switch (key) {
case 0x00: /* NO SENSE */
case 0x01: /* RECOVERED ERROR */
case 0x06: /* UNIT ATTENTION */
case NO_SENSE:
case RECOVERED_ERROR:
case UNIT_ATTENTION:
/* These sense keys are not errors */
return 0;
case 0x0b: /* COMMAND ABORTED */
case ABORTED_COMMAND: /* COMMAND ABORTED */
return ECANCELED;
case 0x02: /* NOT READY */
case 0x05: /* ILLEGAL REQUEST */
case 0x07: /* DATA PROTECTION */
case NOT_READY:
case ILLEGAL_REQUEST:
case DATA_PROTECT:
/* Parse ASCQ */
break;
default:
@ -356,34 +380,15 @@ int scsi_sense_to_errno(int key, int asc, int ascq)
}
}
int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size)
int scsi_sense_buf_to_errno(const uint8_t *in_buf, size_t in_len)
{
int key, asc, ascq;
if (sense_size < 1) {
SCSISense sense;
if (in_len < 1) {
return EIO;
}
switch (sense[0]) {
case 0x70: /* Fixed format sense data. */
if (sense_size < 14) {
return EIO;
}
key = sense[2] & 0xF;
asc = sense[12];
ascq = sense[13];
break;
case 0x72: /* Descriptor format sense data. */
if (sense_size < 4) {
return EIO;
}
key = sense[1] & 0xF;
asc = sense[2];
ascq = sense[3];
break;
default:
return EIO;
break;
}
return scsi_sense_to_errno(key, asc, ascq);
sense = scsi_parse_sense_buf(in_buf, in_len);
return scsi_sense_to_errno(sense.key, sense.asc, sense.ascq);
}
const char *scsi_command_name(uint8_t cmd)

View file

@ -705,9 +705,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
CPUARMState *env = &cpu->env;
int pagebits;
Error *local_err = NULL;
#ifndef CONFIG_USER_ONLY
AddressSpace *as;
#endif
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
@ -912,21 +909,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
#ifndef CONFIG_USER_ONLY
if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
as = g_new0(AddressSpace, 1);
cs->num_ases = 2;
if (!cpu->secure_memory) {
cpu->secure_memory = cs->memory;
}
address_space_init(as, cpu->secure_memory, "cpu-secure-memory");
cpu_address_space_init(cs, as, ARMASIdx_S);
cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory",
cpu->secure_memory);
} else {
cs->num_ases = 1;
}
as = g_new0(AddressSpace, 1);
address_space_init(as, cs->memory, "cpu-memory");
cpu_address_space_init(cs, as, ARMASIdx_NS);
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
#endif
qemu_init_vcpu(cs);

View file

@ -437,9 +437,9 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_7_0_ECX] = {
.feat_names = {
NULL, "avx512vbmi", "umip", "pku",
"ospke", NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "avx512-vpopcntdq", NULL,
"ospke", NULL, "avx512vbmi2", NULL,
"gfni", "vaes", "vpclmulqdq", "avx512vnni",
"avx512bitalg", NULL, "avx512-vpopcntdq", NULL,
"la57", NULL, NULL, NULL,
NULL, NULL, "rdpid", NULL,
NULL, NULL, NULL, NULL,
@ -3736,11 +3736,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
#ifndef CONFIG_USER_ONLY
if (tcg_enabled()) {
AddressSpace *as_normal = g_new0(AddressSpace, 1);
AddressSpace *as_smm = g_new(AddressSpace, 1);
address_space_init(as_normal, cs->memory, "cpu-memory");
cpu->cpu_as_mem = g_new(MemoryRegion, 1);
cpu->cpu_as_root = g_new(MemoryRegion, 1);
@ -3755,11 +3750,10 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
get_system_memory(), 0, ~0ull);
memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
memory_region_set_enabled(cpu->cpu_as_mem, true);
address_space_init(as_smm, cpu->cpu_as_root, "CPU");
cs->num_ases = 2;
cpu_address_space_init(cs, as_normal, 0);
cpu_address_space_init(cs, as_smm, 1);
cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
/* ... SMRAM with higher priority, linked from /machine/smram. */
cpu->machine_done.notify = x86_cpu_machine_done;

View file

@ -635,6 +635,12 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_7_0_ECX_UMIP (1U << 2)
#define CPUID_7_0_ECX_PKU (1U << 3)
#define CPUID_7_0_ECX_OSPKE (1U << 4)
#define CPUID_7_0_ECX_VBMI2 (1U << 6) /* Additional VBMI Instrs */
#define CPUID_7_0_ECX_GFNI (1U << 8)
#define CPUID_7_0_ECX_VAES (1U << 9)
#define CPUID_7_0_ECX_VPCLMULQDQ (1U << 10)
#define CPUID_7_0_ECX_AVX512VNNI (1U << 11)
#define CPUID_7_0_ECX_AVX512BITALG (1U << 12)
#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) /* POPCNT for vectors of DW/QW */
#define CPUID_7_0_ECX_LA57 (1U << 16)
#define CPUID_7_0_ECX_RDPID (1U << 22)
@ -1091,14 +1097,16 @@ typedef struct CPUX86State {
uint64_t async_pf_en_msr;
uint64_t pv_eoi_en_msr;
/* Partition-wide HV MSRs, will be updated only on the first vcpu */
uint64_t msr_hv_hypercall;
uint64_t msr_hv_guest_os_id;
uint64_t msr_hv_vapic;
uint64_t msr_hv_tsc;
/* Per-VCPU HV MSRs */
uint64_t msr_hv_vapic;
uint64_t msr_hv_crash_params[HV_CRASH_PARAMS];
uint64_t msr_hv_runtime;
uint64_t msr_hv_synic_control;
uint64_t msr_hv_synic_version;
uint64_t msr_hv_synic_evt_page;
uint64_t msr_hv_synic_msg_page;
uint64_t msr_hv_synic_sint[HV_SINT_COUNT];

View file

@ -662,8 +662,6 @@ static int hyperv_handle_properties(CPUState *cs)
env->features[FEAT_HYPERV_EAX] |= HV_VP_RUNTIME_AVAILABLE;
}
if (cpu->hyperv_synic) {
int sint;
if (!has_msr_hv_synic ||
kvm_vcpu_enable_cap(cs, KVM_CAP_HYPERV_SYNIC, 0)) {
fprintf(stderr, "Hyper-V SynIC is not supported by kernel\n");
@ -671,10 +669,6 @@ static int hyperv_handle_properties(CPUState *cs)
}
env->features[FEAT_HYPERV_EAX] |= HV_SYNIC_AVAILABLE;
env->msr_hv_synic_version = HV_SYNIC_VERSION;
for (sint = 0; sint < ARRAY_SIZE(env->msr_hv_synic_sint); sint++) {
env->msr_hv_synic_sint[sint] = HV_SINT_MASKED;
}
}
if (cpu->hyperv_stimer) {
if (!has_msr_hv_stimer) {
@ -1053,6 +1047,13 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
} else {
env->mp_state = KVM_MP_STATE_RUNNABLE;
}
if (cpu->hyperv_synic) {
int i;
for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) {
env->msr_hv_synic_sint[i] = HV_SINT_MASKED;
}
}
}
void kvm_arch_do_init_vcpu(X86CPU *cpu)
@ -1678,19 +1679,26 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
env->msr_global_ctrl);
}
if (has_msr_hv_hypercall) {
kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID,
env->msr_hv_guest_os_id);
kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL,
env->msr_hv_hypercall);
/*
* Hyper-V partition-wide MSRs: to avoid clearing them on cpu hot-add,
* only sync them to KVM on the first cpu
*/
if (current_cpu == first_cpu) {
if (has_msr_hv_hypercall) {
kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID,
env->msr_hv_guest_os_id);
kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL,
env->msr_hv_hypercall);
}
if (cpu->hyperv_time) {
kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC,
env->msr_hv_tsc);
}
}
if (cpu->hyperv_vapic) {
kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE,
env->msr_hv_vapic);
}
if (cpu->hyperv_time) {
kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc);
}
if (has_msr_hv_crash) {
int j;
@ -1706,10 +1714,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (cpu->hyperv_synic) {
int j;
kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, HV_SYNIC_VERSION);
kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL,
env->msr_hv_synic_control);
kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION,
env->msr_hv_synic_version);
kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP,
env->msr_hv_synic_evt_page);
kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP,
@ -2073,7 +2081,6 @@ static int kvm_get_msrs(X86CPU *cpu)
uint32_t msr;
kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, 0);
kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, 0);
kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, 0);
kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, 0);
for (msr = HV_X64_MSR_SINT0; msr <= HV_X64_MSR_SINT15; msr++) {
@ -2277,9 +2284,6 @@ static int kvm_get_msrs(X86CPU *cpu)
case HV_X64_MSR_SCONTROL:
env->msr_hv_synic_control = msrs[i].data;
break;
case HV_X64_MSR_SVERSION:
env->msr_hv_synic_version = msrs[i].data;
break;
case HV_X64_MSR_SIEFP:
env->msr_hv_synic_evt_page = msrs[i].data;
break;

View file

@ -4467,10 +4467,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
target_ulong pc_start = s->base.pc_next;
s->pc_start = s->pc = pc_start;
prefixes = 0;
s->override = -1;
rex_w = -1;
rex_r = 0;
#ifdef TARGET_X86_64
s->rex_x = 0;
s->rex_b = 0;
@ -4484,6 +4481,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
return s->pc;
}
prefixes = 0;
rex_w = -1;
rex_r = 0;
next_byte:
b = x86_ldub_code(env, s);
/* Collect prefixes. */
@ -4547,9 +4548,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
/* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
otherwise the instruction is LES or LDS. */
s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
break;
}
s->pc++;
/* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ

View file

@ -7,9 +7,10 @@
* or later. See the COPYING file in the top-level directory.
*
* This test is used to check that the serial output of the firmware
* (that we provide for some machines) contains an expected string.
* Thus we check that the firmware still boots at least to a certain
* point and so we know that the machine is not completely broken.
* (that we provide for some machines) or some small mini-kernels that
* we provide here contains an expected string. Thus we check that the
* firmware/kernel still boots at least to a certain point and so we
* know that the machine is not completely broken.
*/
#include "qemu/osdep.h"
@ -20,6 +21,9 @@ typedef struct testdef {
const char *machine; /* Name of the machine */
const char *extra; /* Additional parameters */
const char *expect; /* Expected string in the serial output */
size_t codesize; /* Size of the kernel or bios data */
const uint8_t *kernel; /* Set in case we use our own mini kernel */
const uint8_t *bios; /* Set in case we use our own mini bios */
} testdef_t;
static testdef_t tests[] = {
@ -43,12 +47,13 @@ static testdef_t tests[] = {
static void check_guest_output(const testdef_t *test, int fd)
{
bool output_ok = false;
int i, nbr, pos = 0;
int i, nbr, pos = 0, ccnt;
char ch;
/* Poll serial output... Wait at most 60 seconds */
for (i = 0; i < 6000; ++i) {
while ((nbr = read(fd, &ch, 1)) == 1) {
ccnt = 0;
while ((nbr = read(fd, &ch, 1)) == 1 && ccnt++ < 512) {
if (ch == test->expect[pos]) {
pos += 1;
if (test->expect[pos] == '\0') {
@ -71,26 +76,52 @@ done:
static void test_machine(const void *data)
{
const testdef_t *test = data;
char tmpname[] = "/tmp/qtest-boot-serial-XXXXXX";
int fd;
char serialtmp[] = "/tmp/qtest-boot-serial-sXXXXXX";
char codetmp[] = "/tmp/qtest-boot-serial-cXXXXXX";
const char *codeparam = "";
const uint8_t *code = NULL;
int ser_fd;
fd = mkstemp(tmpname);
g_assert(fd != -1);
ser_fd = mkstemp(serialtmp);
g_assert(ser_fd != -1);
if (test->kernel) {
code = test->kernel;
codeparam = "-kernel";
} else if (test->bios) {
code = test->bios;
codeparam = "-bios";
}
if (code) {
ssize_t wlen;
int code_fd;
code_fd = mkstemp(codetmp);
g_assert(code_fd != -1);
wlen = write(code_fd, code, test->codesize);
g_assert(wlen == test->codesize);
close(code_fd);
}
/*
* Make sure that this test uses tcg if available: It is used as a
* fast-enough smoketest for that.
*/
global_qtest = qtest_startf("-M %s,accel=tcg:kvm "
global_qtest = qtest_startf("%s %s -M %s,accel=tcg:kvm "
"-chardev file,id=serial0,path=%s "
"-no-shutdown -serial chardev:serial0 %s",
test->machine, tmpname, test->extra);
unlink(tmpname);
codeparam, code ? codetmp : "",
test->machine, serialtmp, test->extra);
unlink(serialtmp);
if (code) {
unlink(codetmp);
}
check_guest_output(test, fd);
check_guest_output(test, ser_fd);
qtest_quit(global_qtest);
close(fd);
close(ser_fd);
}
int main(int argc, char *argv[])

View file

@ -5,6 +5,7 @@
#include "qemu/config-file.h"
#include "qemu/sockets.h"
#include "chardev/char-fe.h"
#include "chardev/char-mux.h"
#include "sysemu/sysemu.h"
#include "qapi/error.h"
#include "qom/qom-qobject.h"
@ -164,6 +165,7 @@ static void char_mux_test(void)
FeHandler h1 = { 0, }, h2 = { 0, };
CharBackend chr_be1, chr_be2;
muxes_realized = true; /* done after machine init */
opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
1, &error_abort);
qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
@ -201,8 +203,23 @@ static void char_mux_test(void)
g_assert_cmpstr(h2.read_buf, ==, "hello");
h2.read_count = 0;
g_assert_cmpint(h1.last_event, !=, 42); /* should be MUX_OUT or OPENED */
g_assert_cmpint(h2.last_event, !=, 42); /* should be MUX_IN or OPENED */
/* sending event on the base broadcast to all fe, historical reasons? */
qemu_chr_be_event(base, 42);
g_assert_cmpint(h1.last_event, ==, 42);
g_assert_cmpint(h2.last_event, ==, 42);
qemu_chr_be_event(chr, -1);
g_assert_cmpint(h1.last_event, ==, 42);
g_assert_cmpint(h2.last_event, ==, -1);
/* switch focus */
qemu_chr_be_write(base, (void *)"\1c", 2);
g_assert_cmpint(h1.last_event, ==, CHR_EVENT_MUX_IN);
g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
qemu_chr_be_event(chr, -1);
g_assert_cmpint(h1.last_event, ==, -1);
g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
qemu_chr_be_write(base, (void *)"hello", 6);
g_assert_cmpint(h2.read_count, ==, 0);

View file

@ -31,9 +31,7 @@
#include "qemu/memfd.h"
#ifdef CONFIG_MEMFD
#include <sys/memfd.h>
#elif defined CONFIG_LINUX
#if defined CONFIG_LINUX && !defined CONFIG_MEMFD
#include <sys/syscall.h>
#include <asm/unistd.h>

View file

@ -198,7 +198,6 @@ static int try_bind(int socket, InetSocketAddress *saddr, struct addrinfo *e)
static int inet_listen_saddr(InetSocketAddress *saddr,
int port_offset,
bool update_addr,
Error **errp)
{
struct addrinfo ai,*res,*e;
@ -326,15 +325,6 @@ listen_failed:
return -1;
listen_ok:
if (update_addr) {
g_free(saddr->host);
saddr->host = g_strdup(uaddr);
g_free(saddr->port);
saddr->port = g_strdup_printf("%d",
inet_getport(e) - port_offset);
saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6;
saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6;
}
freeaddrinfo(res);
return slisten;
}
@ -790,7 +780,6 @@ static int vsock_parse(VsockSocketAddress *addr, const char *str,
#ifndef _WIN32
static int unix_listen_saddr(UnixSocketAddress *saddr,
bool update_addr,
Error **errp)
{
struct sockaddr_un un;
@ -855,12 +844,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
goto err;
}
if (update_addr && pathbuf) {
g_free(saddr->path);
saddr->path = pathbuf;
} else {
g_free(pathbuf);
}
g_free(pathbuf);
return sock;
err:
@ -920,7 +904,6 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
#else
static int unix_listen_saddr(UnixSocketAddress *saddr,
bool update_addr,
Error **errp)
{
error_setg(errp, "unix sockets are not available on windows");
@ -937,7 +920,7 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
#endif
/* compatibility wrapper */
int unix_listen(const char *str, char *ostr, int olen, Error **errp)
int unix_listen(const char *str, Error **errp)
{
char *path, *optstr;
int sock, len;
@ -957,11 +940,7 @@ int unix_listen(const char *str, char *ostr, int olen, Error **errp)
saddr->path = g_strdup(str);
}
sock = unix_listen_saddr(saddr, true, errp);
if (sock != -1 && ostr) {
snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : "");
}
sock = unix_listen_saddr(saddr, errp);
qapi_free_UnixSocketAddress(saddr);
return sock;
@ -1052,11 +1031,11 @@ int socket_listen(SocketAddress *addr, Error **errp)
switch (addr->type) {
case SOCKET_ADDRESS_TYPE_INET:
fd = inet_listen_saddr(&addr->u.inet, 0, false, errp);
fd = inet_listen_saddr(&addr->u.inet, 0, errp);
break;
case SOCKET_ADDRESS_TYPE_UNIX:
fd = unix_listen_saddr(&addr->u.q_unix, false, errp);
fd = unix_listen_saddr(&addr->u.q_unix, errp);
break;
case SOCKET_ADDRESS_TYPE_FD:

View file

@ -479,15 +479,29 @@ static void __attribute__((constructor)) qemu_thread_atexit_init(void)
}
/* Attempt to set the threads name; note that this is for debug, so
* we're not going to fail if we can't set it.
*/
static void qemu_thread_set_name(QemuThread *thread, const char *name)
{
#ifdef CONFIG_PTHREAD_SETNAME_NP
pthread_setname_np(thread->thread, name);
#endif
typedef struct {
void *(*start_routine)(void *);
void *arg;
char *name;
} QemuThreadArgs;
static void *qemu_thread_start(void *args)
{
QemuThreadArgs *qemu_thread_args = args;
void *(*start_routine)(void *) = qemu_thread_args->start_routine;
void *arg = qemu_thread_args->arg;
/* Attempt to set the threads name; note that this is for debug, so
* we're not going to fail if we can't set it.
*/
pthread_setname_np(pthread_self(), qemu_thread_args->name);
g_free(qemu_thread_args->name);
g_free(qemu_thread_args);
return start_routine(arg);
}
#endif
void qemu_thread_create(QemuThread *thread, const char *name,
void *(*start_routine)(void*),
@ -502,23 +516,34 @@ void qemu_thread_create(QemuThread *thread, const char *name,
error_exit(err, __func__);
}
if (mode == QEMU_THREAD_DETACHED) {
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
}
/* Leave signal handling to the iothread. */
sigfillset(&set);
pthread_sigmask(SIG_SETMASK, &set, &oldset);
err = pthread_create(&thread->thread, &attr, start_routine, arg);
#ifdef CONFIG_PTHREAD_SETNAME_NP
if (name_threads) {
QemuThreadArgs *qemu_thread_args;
qemu_thread_args = g_new0(QemuThreadArgs, 1);
qemu_thread_args->name = g_strdup(name);
qemu_thread_args->start_routine = start_routine;
qemu_thread_args->arg = arg;
err = pthread_create(&thread->thread, &attr,
qemu_thread_start, qemu_thread_args);
} else
#endif
{
err = pthread_create(&thread->thread, &attr,
start_routine, arg);
}
if (err)
error_exit(err, __func__);
if (name_threads) {
qemu_thread_set_name(thread, name);
}
if (mode == QEMU_THREAD_DETACHED) {
err = pthread_detach(thread->thread);
if (err) {
error_exit(err, __func__);
}
}
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
pthread_attr_destroy(&attr);

View file

@ -32,6 +32,9 @@
#include "qemu/atomic.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#if defined(CONFIG_MALLOC_TRIM)
#include <malloc.h>
#endif
/*
* Global grace period counter. Bit 0 is always one in rcu_gp_ctr.
@ -246,6 +249,9 @@ static void *call_rcu_thread(void *opaque)
qemu_event_reset(&rcu_call_ready_event);
n = atomic_read(&rcu_call_count);
if (n == 0) {
#if defined(CONFIG_MALLOC_TRIM)
malloc_trim(4 * 1024 * 1024);
#endif
qemu_event_wait(&rcu_call_ready_event);
}
}

4
vl.c
View file

@ -3817,10 +3817,6 @@ int main(int argc, char **argv, char **envp)
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=tcg", false);
break;
case QEMU_OPTION_no_kvm_pit: {
warn_report("ignoring deprecated option");
break;
}
case QEMU_OPTION_no_kvm_pit_reinjection: {
static GlobalProperty kvm_pit_lost_tick_policy = {
.driver = "kvm-pit",