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
48 changed files with 665 additions and 488 deletions
+2
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/*
+3 -9
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;
+36 -15
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;
}
+16 -34
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;
+7 -1
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)) {
+10
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 = {
+30 -43
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;
+12 -6
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)
Vendored
+36 -1
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
+11
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]
+15
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]
+9
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
+20 -17
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);
}
}
+42 -2
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);
+1
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);
}
+4
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"
+5 -9
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;
}
+12 -74
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)
+49
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)
+7
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

Some files were not shown because too many files have changed in this diff Show More