aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-16 15:45:15 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-16 15:45:15 +0000
commitc1d5b9add7b04661bedef9a3379a8b82547b53db (patch)
tree7c064b14e4a3645aedbd7d7f0009b9ee71ad9952
parentaae39d24a387a273deab3eb930dbf730aa379e22 (diff)
parentb5976c2e46e86b36b01d8ac380a182e22209a7cd (diff)
downloadqemu-c1d5b9add7b04661bedef9a3379a8b82547b53db.zip
qemu-c1d5b9add7b04661bedef9a3379a8b82547b53db.tar.gz
qemu-c1d5b9add7b04661bedef9a3379a8b82547b53db.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* QemuMutex tracing improvements (Alex) * ram_addr_t optimization (David) * SCSI fixes (Fam, Stefan, me) * do {} while (0) fixes (Eric) * KVM fix for PMU (Jan) * memory leak fixes from ASAN (Marc-André) * migration fix for HPET, icount, loadvm (Maria, Pavel) * hflags fixes (me, Tao) * block/iscsi uninitialized variable (Peter L.) * full support for GMainContexts in character devices (Peter Xu) * more boot-serial-test (Thomas) * Memory leak fix (Zhecheng) # gpg: Signature made Tue 16 Jan 2018 14:15:45 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: (51 commits) scripts/analyse-locks-simpletrace.py: script to analyse lock times util/qemu-thread-*: add qemu_lock, locked and unlock trace events cpu: flush TB cache when loading VMState block/iscsi: fix initialization of iTask in iscsi_co_get_block_status find_ram_offset: Align ram_addr_t allocation on long boundaries find_ram_offset: Add comments and tracing cpu_physical_memory_sync_dirty_bitmap: Another alignment fix checkpatch: Enforce proper do/while (0) style maint: Fix macros with broken 'do/while(0); ' usage tests: Avoid 'do/while(false); ' in vhost-user-bridge chardev: Clean up previous patch indentation chardev: Use goto/label instead of do/break/while(0) mips: Tweak location of ';' in macros net: Drop unusual use of do { } while (0); irq: fix memory leak cpus: unify qemu_*_wait_io_event icount: fixed saving/restoring of icount warp timers scripts/qemu-gdb/timers.py: new helper to dump timer state scripts/qemu-gdb: add simple tcg lock status helper target-i386: update hflags on Hypervisor.framework ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--Makefile7
-rw-r--r--audio/paaudio.c4
-rw-r--r--block/iscsi.c3
-rw-r--r--chardev/char-fe.c2
-rw-r--r--chardev/char-pty.c64
-rw-r--r--chardev/char-serial.c75
-rw-r--r--chardev/char-socket.c28
-rw-r--r--chardev/char.c18
-rwxr-xr-xconfigure16
-rw-r--r--cpus.c134
-rw-r--r--crypto/ivgen-essiv.c2
-rw-r--r--disas/s390.c16
-rw-r--r--docs/devel/build-system.txt13
-rw-r--r--exec.c40
-rw-r--r--hw/adc/stm32f2xx_adc.c2
-rw-r--r--hw/block/m25p80.c2
-rw-r--r--hw/char/cadence_uart.c2
-rw-r--r--hw/char/stm32f2xx_usart.c2
-rw-r--r--hw/char/terminal3270.c28
-rw-r--r--hw/display/cg3.c2
-rw-r--r--hw/display/dpcd.c2
-rw-r--r--hw/display/xlnx_dp.c2
-rw-r--r--hw/dma/pl330.c2
-rw-r--r--hw/dma/xlnx-zynq-devcfg.c2
-rw-r--r--hw/dma/xlnx_dpdma.c2
-rw-r--r--hw/i2c/i2c-ddc.c2
-rw-r--r--hw/i386/pc.c18
-rw-r--r--hw/misc/auxbus.c2
-rw-r--r--hw/misc/macio/mac_dbdma.c4
-rw-r--r--hw/misc/mmio_interface.c2
-rw-r--r--hw/misc/stm32f2xx_syscfg.c2
-rw-r--r--hw/misc/zynq_slcr.c2
-rw-r--r--hw/net/cadence_gem.c2
-rw-r--r--hw/net/pcnet.c20
-rw-r--r--hw/nvram/ds1225y.c4
-rw-r--r--hw/scsi/scsi-disk.c1
-rw-r--r--hw/scsi/scsi-generic.c9
-rw-r--r--hw/ssi/mss-spi.c2
-rw-r--r--hw/ssi/stm32f2xx_spi.c2
-rw-r--r--hw/ssi/xilinx_spi.c2
-rw-r--r--hw/ssi/xilinx_spips.c2
-rw-r--r--hw/timer/a9gtimer.c2
-rw-r--r--hw/timer/cadence_ttc.c2
-rw-r--r--hw/timer/hpet.c30
-rw-r--r--hw/timer/mss-timer.c2
-rw-r--r--hw/timer/stm32f2xx_timer.c2
-rw-r--r--hw/tpm/tpm_passthrough.c2
-rw-r--r--hw/tpm/tpm_tis.c2
-rw-r--r--include/chardev/char.h3
-rw-r--r--include/exec/ram_addr.h5
-rw-r--r--include/hw/compat.h6
-rw-r--r--include/qemu/readline.h1
-rw-r--r--include/qemu/thread.h39
-rw-r--r--migration/rdma.c2
-rw-r--r--monitor.c2
-rw-r--r--rules.mak2
-rwxr-xr-xscripts/analyse-locks-simpletrace.py99
-rwxr-xr-xscripts/checkpatch.pl5
-rw-r--r--scripts/qemu-gdb.py4
-rw-r--r--scripts/qemugdb/tcg.py46
-rw-r--r--scripts/qemugdb/timers.py54
-rw-r--r--scsi/utils.c12
-rw-r--r--target/arm/translate-a64.c2
-rw-r--r--target/i386/cpu.c42
-rw-r--r--target/i386/cpu.h2
-rw-r--r--target/i386/hax-all.c54
-rw-r--r--target/i386/hvf/x86hvf.c2
-rw-r--r--target/i386/kvm.c121
-rw-r--r--target/mips/msa_helper.c34
-rw-r--r--target/s390x/kvm.c2
-rw-r--r--tests/Makefile.include5
-rw-r--r--tests/acpi-utils.h8
-rw-r--r--tests/boot-serial-test.c37
-rw-r--r--tests/check-qobject.c2
-rw-r--r--tests/docker/dockerfiles/fedora.docker4
-rwxr-xr-xtests/docker/test-clang2
-rwxr-xr-xtests/docker/test-debug26
-rwxr-xr-xtests/docker/test-mingw2
-rw-r--r--tests/qmp-test.c3
-rw-r--r--tests/tcg/test-mmap.c2
-rw-r--r--tests/test-coroutine.c1
-rw-r--r--tests/vhost-user-bridge.c6
-rw-r--r--trace-events4
-rw-r--r--ui/sdl_zoom_template.h8
-rw-r--r--util/qemu-config.c3
-rw-r--r--util/qemu-thread-posix.c21
-rw-r--r--util/qemu-thread-win32.c20
-rw-r--r--util/readline.c18
-rw-r--r--util/trace-events7
-rw-r--r--vl.c9
90 files changed, 900 insertions, 415 deletions
diff --git a/Makefile b/Makefile
index d86ecd2..f26ef1b 100644
--- a/Makefile
+++ b/Makefile
@@ -8,9 +8,12 @@ SRC_PATH=.
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
html info pdf txt \
- help check-help \
+ help check-help print-% \
docker docker-% vm-test vm-build-%
+print-%:
+ @echo '$*=$($*)'
+
# All following code might depend on configuration variables
ifneq ($(wildcard config-host.mak),)
# Put the all: rule here so that config-host.mak can contain dependencies.
@@ -277,7 +280,7 @@ else
DOCS=
endif
-SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) BUILD_DIR=$(BUILD_DIR)
+SUBDIR_MAKEFLAGS=BUILD_DIR=$(BUILD_DIR)
SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %-config-devices.mak.d, $(TARGET_DIRS))
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 65beb6f..2a35e6f 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -89,7 +89,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
} \
goto label; \
} \
- } while (0);
+ } while (0)
#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
do { \
@@ -107,7 +107,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
} \
goto label; \
} \
- } while (0);
+ } while (0)
static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
{
diff --git a/block/iscsi.c b/block/iscsi.c
index 5c0a9e5..6a1c537 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -658,6 +658,8 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
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;
@@ -675,7 +677,6 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
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,
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index ee6d596..c611b3f 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -356,7 +356,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
}
g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
- tag = g_source_attach(src, NULL);
+ tag = g_source_attach(src, s->gcontext);
g_source_unref(src);
return tag;
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 761ae6d..89315e6 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -42,8 +42,8 @@ typedef struct {
/* Protected by the Chardev chr_write_lock. */
int connected;
- guint timer_tag;
- guint open_tag;
+ GSource *timer_src;
+ GSource *open_source;
} PtyChardev;
#define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY)
@@ -57,8 +57,9 @@ static gboolean pty_chr_timer(gpointer opaque)
PtyChardev *s = PTY_CHARDEV(opaque);
qemu_mutex_lock(&chr->chr_write_lock);
- s->timer_tag = 0;
- s->open_tag = 0;
+ s->timer_src = NULL;
+ g_source_unref(s->open_source);
+ s->open_source = NULL;
if (!s->connected) {
/* Next poll ... */
pty_chr_update_read_handler_locked(chr);
@@ -67,25 +68,25 @@ static gboolean pty_chr_timer(gpointer opaque)
return FALSE;
}
+static void pty_chr_timer_cancel(PtyChardev *s)
+{
+ if (s->timer_src) {
+ g_source_destroy(s->timer_src);
+ g_source_unref(s->timer_src);
+ s->timer_src = NULL;
+ }
+}
+
/* Called with chr_write_lock held. */
static void pty_chr_rearm_timer(Chardev *chr, int ms)
{
PtyChardev *s = PTY_CHARDEV(chr);
char *name;
- if (s->timer_tag) {
- g_source_remove(s->timer_tag);
- s->timer_tag = 0;
- }
-
- if (ms == 1000) {
- name = g_strdup_printf("pty-timer-secs-%s", chr->label);
- s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
- } else {
- name = g_strdup_printf("pty-timer-ms-%s", chr->label);
- s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
- }
- g_source_set_name_by_id(s->timer_tag, name);
+ pty_chr_timer_cancel(s);
+ name = g_strdup_printf("pty-timer-%s", chr->label);
+ s->timer_src = qemu_chr_timeout_add_ms(chr, ms, pty_chr_timer, chr);
+ g_source_set_name(s->timer_src, name);
g_free(name);
}
@@ -183,7 +184,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
- s->open_tag = 0;
+ s->open_source = NULL;
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
return FALSE;
}
@@ -194,9 +195,10 @@ static void pty_chr_state(Chardev *chr, int connected)
PtyChardev *s = PTY_CHARDEV(chr);
if (!connected) {
- if (s->open_tag) {
- g_source_remove(s->open_tag);
- s->open_tag = 0;
+ if (s->open_source) {
+ g_source_destroy(s->open_source);
+ g_source_unref(s->open_source);
+ s->open_source = NULL;
}
remove_fd_in_watch(chr);
s->connected = 0;
@@ -205,14 +207,15 @@ static void pty_chr_state(Chardev *chr, int connected)
* the virtual device linked to our pty. */
pty_chr_rearm_timer(chr, 1000);
} else {
- if (s->timer_tag) {
- g_source_remove(s->timer_tag);
- s->timer_tag = 0;
- }
+ pty_chr_timer_cancel(s);
if (!s->connected) {
- g_assert(s->open_tag == 0);
+ g_assert(s->open_source == NULL);
+ s->open_source = g_idle_source_new();
s->connected = 1;
- s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
+ g_source_set_callback(s->open_source,
+ qemu_chr_be_generic_open_func,
+ chr, NULL);
+ g_source_attach(s->open_source, chr->gcontext);
}
if (!chr->gsource) {
chr->gsource = io_add_watch_poll(chr, s->ioc,
@@ -231,10 +234,7 @@ static void char_pty_finalize(Object *obj)
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_state(chr, 0);
object_unref(OBJECT(s->ioc));
- if (s->timer_tag) {
- g_source_remove(s->timer_tag);
- s->timer_tag = 0;
- }
+ pty_chr_timer_cancel(s);
qemu_mutex_unlock(&chr->chr_write_lock);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
@@ -267,7 +267,7 @@ static void char_pty_open(Chardev *chr,
name = g_strdup_printf("chardev-pty-%s", chr->label);
qio_channel_set_name(QIO_CHANNEL(s->ioc), name);
g_free(name);
- s->timer_tag = 0;
+ s->timer_src = NULL;
*be_opened = false;
}
diff --git a/chardev/char-serial.c b/chardev/char-serial.c
index 2f8f838..93392c5 100644
--- a/chardev/char-serial.c
+++ b/chardev/char-serial.c
@@ -64,69 +64,74 @@ static void tty_serial_init(int fd, int speed,
#endif
tcgetattr(fd, &tty);
-#define check_speed(val) if (speed <= val) { spd = B##val; break; }
+#define check_speed(val) \
+ if (speed <= val) { \
+ spd = B##val; \
+ goto done; \
+ }
+
speed = speed * 10 / 11;
- do {
- check_speed(50);
- check_speed(75);
- check_speed(110);
- check_speed(134);
- check_speed(150);
- check_speed(200);
- check_speed(300);
- check_speed(600);
- check_speed(1200);
- check_speed(1800);
- check_speed(2400);
- check_speed(4800);
- check_speed(9600);
- check_speed(19200);
- check_speed(38400);
- /* Non-Posix values follow. They may be unsupported on some systems. */
- check_speed(57600);
- check_speed(115200);
+ check_speed(50);
+ check_speed(75);
+ check_speed(110);
+ check_speed(134);
+ check_speed(150);
+ check_speed(200);
+ check_speed(300);
+ check_speed(600);
+ check_speed(1200);
+ check_speed(1800);
+ check_speed(2400);
+ check_speed(4800);
+ check_speed(9600);
+ check_speed(19200);
+ check_speed(38400);
+ /* Non-Posix values follow. They may be unsupported on some systems. */
+ check_speed(57600);
+ check_speed(115200);
#ifdef B230400
- check_speed(230400);
+ check_speed(230400);
#endif
#ifdef B460800
- check_speed(460800);
+ check_speed(460800);
#endif
#ifdef B500000
- check_speed(500000);
+ check_speed(500000);
#endif
#ifdef B576000
- check_speed(576000);
+ check_speed(576000);
#endif
#ifdef B921600
- check_speed(921600);
+ check_speed(921600);
#endif
#ifdef B1000000
- check_speed(1000000);
+ check_speed(1000000);
#endif
#ifdef B1152000
- check_speed(1152000);
+ check_speed(1152000);
#endif
#ifdef B1500000
- check_speed(1500000);
+ check_speed(1500000);
#endif
#ifdef B2000000
- check_speed(2000000);
+ check_speed(2000000);
#endif
#ifdef B2500000
- check_speed(2500000);
+ check_speed(2500000);
#endif
#ifdef B3000000
- check_speed(3000000);
+ check_speed(3000000);
#endif
#ifdef B3500000
- check_speed(3500000);
+ check_speed(3500000);
#endif
#ifdef B4000000
- check_speed(4000000);
+ check_speed(4000000);
#endif
- spd = B115200;
- } while (0);
+ spd = B115200;
+#undef check_speed
+ done:
cfsetispeed(&tty, spd);
cfsetospeed(&tty, spd);
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 630a7f2..77cdf48 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -57,7 +57,7 @@ typedef struct {
bool is_telnet;
bool is_tn3270;
- guint reconnect_timer;
+ GSource *reconnect_timer;
int64_t reconnect_time;
bool connect_err_reported;
} SocketChardev;
@@ -67,16 +67,27 @@ typedef struct {
static gboolean socket_reconnect_timeout(gpointer opaque);
+static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
+{
+ if (s->reconnect_timer) {
+ g_source_destroy(s->reconnect_timer);
+ g_source_unref(s->reconnect_timer);
+ s->reconnect_timer = NULL;
+ }
+}
+
static void qemu_chr_socket_restart_timer(Chardev *chr)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
char *name;
assert(s->connected == 0);
- s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
- socket_reconnect_timeout, chr);
name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
- g_source_set_name_by_id(s->reconnect_timer, name);
+ s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
+ s->reconnect_time * 1000,
+ socket_reconnect_timeout,
+ chr);
+ g_source_set_name(s->reconnect_timer, name);
g_free(name);
}
@@ -781,11 +792,7 @@ static void char_socket_finalize(Object *obj)
SocketChardev *s = SOCKET_CHARDEV(obj);
tcp_chr_free_connection(chr);
-
- if (s->reconnect_timer) {
- g_source_remove(s->reconnect_timer);
- s->reconnect_timer = 0;
- }
+ tcp_chr_reconn_timer_cancel(s);
qapi_free_SocketAddress(s->addr);
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
@@ -824,7 +831,8 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
SocketChardev *s = SOCKET_CHARDEV(opaque);
QIOChannelSocket *sioc;
- s->reconnect_timer = 0;
+ g_source_unref(s->reconnect_timer);
+ s->reconnect_timer = NULL;
if (chr->be_open) {
return false;
diff --git a/chardev/char.c b/chardev/char.c
index 8c3765e..3e14de1 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -1084,6 +1084,24 @@ void qmp_chardev_send_break(const char *id, Error **errp)
qemu_chr_be_event(chr, CHR_EVENT_BREAK);
}
+/*
+ * Add a timeout callback for the chardev (in milliseconds), return
+ * the GSource object created. Please use this to add timeout hook for
+ * chardev instead of g_timeout_add() and g_timeout_add_seconds(), to
+ * make sure the gcontext that the task bound to is correct.
+ */
+GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
+ GSourceFunc func, void *private)
+{
+ GSource *source = g_timeout_source_new(ms);
+
+ assert(func);
+ g_source_set_callback(source, func, private, NULL);
+ g_source_attach(source, chr->gcontext);
+
+ return source;
+}
+
void qemu_chr_cleanup(void)
{
object_unparent(get_chardevs_root());
diff --git a/configure b/configure
index b272a03..6d8c996 100755
--- a/configure
+++ b/configure
@@ -3464,6 +3464,7 @@ else
done
if test "$found" = "no"; then
LIBS="$pthread_lib $LIBS"
+ libs_qga="$pthread_lib $libs_qga"
fi
PTHREAD_LIB="$pthread_lib"
break
@@ -5193,8 +5194,19 @@ if test "$gcov" = "yes" ; then
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
elif test "$fortify_source" = "yes" ; then
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
-elif test "$debug" = "no"; then
- CFLAGS="-O2 $CFLAGS"
+elif test "$debug" = "yes"; then
+ if compile_prog "-Og" ""; then
+ CFLAGS="-Og $CFLAGS"
+ elif compile_prog "-O1" ""; then
+ CFLAGS="-O1 $CFLAGS"
+ fi
+ # Workaround GCC false-positive Wuninitialized bugs with Og or O1:
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
+ if cc_has_warning_flag "-Wno-maybe-uninitialized"; then
+ CFLAGS="-Wno-maybe-uninitialized $CFLAGS"
+ fi
+else
+ CFLAGS="-O2 $CFLAGS"
fi
##########################################
diff --git a/cpus.c b/cpus.c
index e8139de..2cb0af9 100644
--- a/cpus.c
+++ b/cpus.c
@@ -120,16 +120,11 @@ static bool all_cpu_threads_idle(void)
/* Protected by TimersState seqlock */
static bool icount_sleep = true;
-static int64_t vm_clock_warp_start = -1;
/* Conversion factor from emulated instructions to virtual clock ticks. */
static int icount_time_shift;
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
#define MAX_ICOUNT_SHIFT 10
-static QEMUTimer *icount_rt_timer;
-static QEMUTimer *icount_vm_timer;
-static QEMUTimer *icount_warp_timer;
-
typedef struct TimersState {
/* Protected by BQL. */
int64_t cpu_ticks_prev;
@@ -147,6 +142,11 @@ typedef struct TimersState {
int64_t qemu_icount_bias;
/* Only written by TCG thread */
int64_t qemu_icount;
+ /* for adjusting icount */
+ int64_t vm_clock_warp_start;
+ QEMUTimer *icount_rt_timer;
+ QEMUTimer *icount_vm_timer;
+ QEMUTimer *icount_warp_timer;
} TimersState;
static TimersState timers_state;
@@ -432,14 +432,14 @@ static void icount_adjust(void)
static void icount_adjust_rt(void *opaque)
{
- timer_mod(icount_rt_timer,
+ timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
icount_adjust();
}
static void icount_adjust_vm(void *opaque)
{
- timer_mod(icount_vm_timer,
+ timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
icount_adjust();
@@ -460,7 +460,7 @@ static void icount_warp_rt(void)
*/
do {
seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
- warp_start = vm_clock_warp_start;
+ warp_start = timers_state.vm_clock_warp_start;
} while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
if (warp_start == -1) {
@@ -473,7 +473,7 @@ static void icount_warp_rt(void)
cpu_get_clock_locked());
int64_t warp_delta;
- warp_delta = clock - vm_clock_warp_start;
+ warp_delta = clock - timers_state.vm_clock_warp_start;
if (use_icount == 2) {
/*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
@@ -485,7 +485,7 @@ static void icount_warp_rt(void)
}
timers_state.qemu_icount_bias += warp_delta;
}
- vm_clock_warp_start = -1;
+ timers_state.vm_clock_warp_start = -1;
seqlock_write_end(&timers_state.vm_clock_seqlock);
if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
@@ -594,11 +594,13 @@ void qemu_start_warp_timer(void)
* every 100ms.
*/
seqlock_write_begin(&timers_state.vm_clock_seqlock);
- if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
- vm_clock_warp_start = clock;
+ if (timers_state.vm_clock_warp_start == -1
+ || timers_state.vm_clock_warp_start > clock) {
+ timers_state.vm_clock_warp_start = clock;
}
seqlock_write_end(&timers_state.vm_clock_seqlock);
- timer_mod_anticipate(icount_warp_timer, clock + deadline);
+ timer_mod_anticipate(timers_state.icount_warp_timer,
+ clock + deadline);
}
} else if (deadline == 0) {
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
@@ -623,7 +625,7 @@ static void qemu_account_warp_timer(void)
return;
}
- timer_del(icount_warp_timer);
+ timer_del(timers_state.icount_warp_timer);
icount_warp_rt();
}
@@ -632,6 +634,45 @@ static bool icount_state_needed(void *opaque)
return use_icount;
}
+static bool warp_timer_state_needed(void *opaque)
+{
+ TimersState *s = opaque;
+ return s->icount_warp_timer != NULL;
+}
+
+static bool adjust_timers_state_needed(void *opaque)
+{
+ TimersState *s = opaque;
+ return s->icount_rt_timer != NULL;
+}
+
+/*
+ * Subsection for warp timer migration is optional, because may not be created
+ */
+static const VMStateDescription icount_vmstate_warp_timer = {
+ .name = "timer/icount/warp_timer",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = warp_timer_state_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT64(vm_clock_warp_start, TimersState),
+ VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription icount_vmstate_adjust_timers = {
+ .name = "timer/icount/timers",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = adjust_timers_state_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
+ VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
/*
* This is a subsection for icount migration.
*/
@@ -644,6 +685,11 @@ static const VMStateDescription icount_vmstate_timers = {
VMSTATE_INT64(qemu_icount_bias, TimersState),
VMSTATE_INT64(qemu_icount, TimersState),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &icount_vmstate_warp_timer,
+ &icount_vmstate_adjust_timers,
+ NULL
}
};
@@ -754,7 +800,7 @@ void configure_icount(QemuOpts *opts, Error **errp)
icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
if (icount_sleep) {
- icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
+ timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
icount_timer_cb, NULL);
}
@@ -788,13 +834,14 @@ void configure_icount(QemuOpts *opts, Error **errp)
the virtual time trigger catches emulated time passing too fast.
Realtime triggers occur even when idle, so use them less frequently
than VM triggers. */
- icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
+ timers_state.vm_clock_warp_start = -1;
+ timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
icount_adjust_rt, NULL);
- timer_mod(icount_rt_timer,
+ timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
- icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
icount_adjust_vm, NULL);
- timer_mod(icount_vm_timer,
+ timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
}
@@ -862,7 +909,8 @@ static void kick_tcg_thread(void *opaque)
static void start_tcg_kick_timer(void)
{
- if (!mttcg_enabled && !tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
+ assert(!mttcg_enabled);
+ if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
kick_tcg_thread, NULL);
timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
@@ -871,6 +919,7 @@ static void start_tcg_kick_timer(void)
static void stop_tcg_kick_timer(void)
{
+ assert(!mttcg_enabled);
if (tcg_kick_vcpu_timer) {
timer_del(tcg_kick_vcpu_timer);
tcg_kick_vcpu_timer = NULL;
@@ -1090,18 +1139,9 @@ static void qemu_wait_io_event_common(CPUState *cpu)
process_queued_cpu_work(cpu);
}
-static bool qemu_tcg_should_sleep(CPUState *cpu)
+static void qemu_tcg_rr_wait_io_event(CPUState *cpu)
{
- if (mttcg_enabled) {
- return cpu_thread_is_idle(cpu);
- } else {
- return all_cpu_threads_idle();
- }
-}
-
-static void qemu_tcg_wait_io_event(CPUState *cpu)
-{
- while (qemu_tcg_should_sleep(cpu)) {
+ while (all_cpu_threads_idle()) {
stop_tcg_kick_timer();
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
@@ -1111,20 +1151,18 @@ static void qemu_tcg_wait_io_event(CPUState *cpu)
qemu_wait_io_event_common(cpu);
}
-static void qemu_kvm_wait_io_event(CPUState *cpu)
+static void qemu_wait_io_event(CPUState *cpu)
{
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
- qemu_wait_io_event_common(cpu);
-}
-
-static void qemu_hvf_wait_io_event(CPUState *cpu)
-{
- while (cpu_thread_is_idle(cpu)) {
- qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
+#ifdef _WIN32
+ /* Eat dummy APC queued by qemu_cpu_kick_thread. */
+ if (!tcg_enabled()) {
+ SleepEx(0, TRUE);
}
+#endif
qemu_wait_io_event_common(cpu);
}
@@ -1160,7 +1198,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
cpu_handle_guest_debug(cpu);
}
}
- qemu_kvm_wait_io_event(cpu);
+ qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
qemu_kvm_destroy_vcpu(cpu);
@@ -1206,7 +1244,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
exit(1);
}
qemu_mutex_lock_iothread();
- qemu_wait_io_event_common(cpu);
+ qemu_wait_io_event(cpu);
}
return NULL;
@@ -1423,7 +1461,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
atomic_mb_set(&cpu->exit_request, 0);
}
- qemu_tcg_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus));
+ qemu_tcg_rr_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus));
deal_with_unplugged_cpus();
}
@@ -1454,13 +1492,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
}
}
- while (cpu_thread_is_idle(cpu)) {
- qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
- }
-#ifdef _WIN32
- SleepEx(0, TRUE);
-#endif
- qemu_wait_io_event_common(cpu);
+ qemu_wait_io_event(cpu);
}
return NULL;
}
@@ -1497,7 +1529,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
cpu_handle_guest_debug(cpu);
}
}
- qemu_hvf_wait_io_event(cpu);
+ qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
hvf_vcpu_destroy(cpu);
@@ -1576,7 +1608,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
atomic_mb_set(&cpu->exit_request, 0);
- qemu_tcg_wait_io_event(cpu);
+ qemu_wait_io_event(cpu);
}
return NULL;
diff --git a/crypto/ivgen-essiv.c b/crypto/ivgen-essiv.c
index cba20bd..ad4d926 100644
--- a/crypto/ivgen-essiv.c
+++ b/crypto/ivgen-essiv.c
@@ -79,7 +79,7 @@ static int qcrypto_ivgen_essiv_calculate(QCryptoIVGen *ivgen,
uint8_t *data = g_new(uint8_t, ndata);
sector = cpu_to_le64(sector);
- memcpy(data, (uint8_t *)&sector, ndata);
+ memcpy(data, (uint8_t *)&sector, MIN(sizeof(sector), ndata));
if (sizeof(sector) < ndata) {
memset(data + sizeof(sector), 0, ndata - sizeof(sector));
}
diff --git a/disas/s390.c b/disas/s390.c
index 1f167d2..6393860 100644
--- a/disas/s390.c
+++ b/disas/s390.c
@@ -207,18 +207,14 @@ static int opc_index[256];
static void
init_disasm (struct disassemble_info *info)
{
- const struct s390_opcode *opcode;
- const struct s390_opcode *opcode_end;
+ int i;
memset (opc_index, 0, sizeof (opc_index));
- opcode_end = s390_opcodes + s390_num_opcodes;
- for (opcode = s390_opcodes; opcode < opcode_end; opcode++)
- {
- opc_index[(int) opcode->opcode[0]] = opcode - s390_opcodes;
- while ((opcode < opcode_end) &&
- (opcode[1].opcode[0] == opcode->opcode[0]))
- opcode++;
- }
+
+ /* Reverse order, such that each opc_index ends up pointing to the
+ first matching entry instead of the last. */
+ for (i = s390_num_opcodes; i--; )
+ opc_index[s390_opcodes[i].opcode[0]] = i;
#ifdef QEMU_DISABLE
switch (info->mach)
diff --git a/docs/devel/build-system.txt b/docs/devel/build-system.txt
index 386ef36..52501f2 100644
--- a/docs/devel/build-system.txt
+++ b/docs/devel/build-system.txt
@@ -510,3 +510,16 @@ default-configs/$TARGET-NAME file as input.
This is the entrypoint used when make recurses to build a single system
or userspace emulator target. It is merely a symlink back to the
Makefile.target in the top level.
+
+
+Useful make targets
+===================
+
+- help
+
+ Print a help message for the most common build targets.
+
+- print-VAR
+
+ Print the value of the variable VAR. Useful for debugging the build
+ system.
diff --git a/exec.c b/exec.c
index 4722e52..d28fc0c 100644
--- a/exec.c
+++ b/exec.c
@@ -623,6 +623,13 @@ static int cpu_common_post_load(void *opaque, int version_id)
cpu->interrupt_request &= ~0x01;
tlb_flush(cpu);
+ /* loadvm has just updated the content of RAM, bypassing the
+ * usual mechanisms that ensure we flush TBs for writes to
+ * memory we've translated code from. So we must flush all TBs,
+ * which will now be stale.
+ */
+ tb_flush(cpu);
+
return 0;
}
@@ -1660,7 +1667,10 @@ static void *file_ram_alloc(RAMBlock *block,
}
#endif
-/* Called with the ramlist lock held. */
+/* Allocate space within the ram_addr_t space that governs the
+ * dirty bitmaps.
+ * Called with the ramlist lock held.
+ */
static ram_addr_t find_ram_offset(ram_addr_t size)
{
RAMBlock *block, *next_block;
@@ -1673,19 +1683,33 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
}
RAMBLOCK_FOREACH(block) {
- ram_addr_t end, next = RAM_ADDR_MAX;
+ ram_addr_t candidate, next = RAM_ADDR_MAX;
- end = block->offset + block->max_length;
+ /* Align blocks to start on a 'long' in the bitmap
+ * which makes the bitmap sync'ing take the fast path.
+ */
+ candidate = block->offset + block->max_length;
+ candidate = ROUND_UP(candidate, BITS_PER_LONG << TARGET_PAGE_BITS);
+ /* Search for the closest following block
+ * and find the gap.
+ */
RAMBLOCK_FOREACH(next_block) {
- if (next_block->offset >= end) {
+ if (next_block->offset >= candidate) {
next = MIN(next, next_block->offset);
}
}
- if (next - end >= size && next - end < mingap) {
- offset = end;
- mingap = next - end;
+
+ /* If it fits remember our place and remember the size
+ * of gap, but keep going so that we might find a smaller
+ * gap to fill so avoiding fragmentation.
+ */
+ if (next - candidate >= size && next - candidate < mingap) {
+ offset = candidate;
+ mingap = next - candidate;
}
+
+ trace_find_ram_offset_loop(size, candidate, offset, next, mingap);
}
if (offset == RAM_ADDR_MAX) {
@@ -1694,6 +1718,8 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
abort();
}
+ trace_find_ram_offset(size, offset);
+
return offset;
}
diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c
index 90fe9de..13f31ad 100644
--- a/hw/adc/stm32f2xx_adc.c
+++ b/hw/adc/stm32f2xx_adc.c
@@ -37,7 +37,7 @@
if (STM_ADC_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index ea14216..b49c8e9 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -40,7 +40,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* Fields for FlashPartInfo->flags */
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 6143494..fbdbd46 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -33,7 +33,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 268e435..07b462d 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -34,7 +34,7 @@
if (STM_USART_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index a109ce5..e9c45e5 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -31,7 +31,7 @@ typedef struct Terminal3270 {
uint8_t outv[OUTPUT_BUFFER_SIZE];
int in_len;
bool handshake_done;
- guint timer_tag;
+ GSource *timer_src;
} Terminal3270;
#define TYPE_TERMINAL_3270 "x-terminal3270"
@@ -45,6 +45,15 @@ static int terminal_can_read(void *opaque)
return INPUT_BUFFER_SIZE - t->in_len;
}
+static void terminal_timer_cancel(Terminal3270 *t)
+{
+ if (t->timer_src) {
+ g_source_destroy(t->timer_src);
+ g_source_unref(t->timer_src);
+ t->timer_src = NULL;
+ }
+}
+
/*
* Protocol handshake done,
* signal guest by an unsolicited DE irq.
@@ -90,12 +99,9 @@ static void terminal_read(void *opaque, const uint8_t *buf, int size)
assert(size <= (INPUT_BUFFER_SIZE - t->in_len));
- if (t->timer_tag) {
- g_source_remove(t->timer_tag);
- t->timer_tag = 0;
- }
- t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
-
+ terminal_timer_cancel(t);
+ t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
+ send_timing_mark_cb, t);
memcpy(&t->inv[t->in_len], buf, size);
t->in_len += size;
if (t->in_len < 2) {
@@ -145,10 +151,7 @@ static void chr_event(void *opaque, int event)
/* Ensure the initial status correct, always reset them. */
t->in_len = 0;
t->handshake_done = false;
- if (t->timer_tag) {
- g_source_remove(t->timer_tag);
- t->timer_tag = 0;
- }
+ terminal_timer_cancel(t);
switch (event) {
case CHR_EVENT_OPENED:
@@ -157,7 +160,8 @@ static void chr_event(void *opaque, int event)
* char-socket.c. Once qemu receives the terminal-type of the
* client, mark handshake done and trigger everything rolling again.
*/
- t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
+ t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
+ send_timing_mark_cb, t);
break;
case CHR_EVENT_CLOSED:
sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index e069c44..cafd9f4 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -63,7 +63,7 @@
if (DEBUG_CG3) { \
printf("CG3: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c
index ce92ff6..943002b 100644
--- a/hw/display/dpcd.c
+++ b/hw/display/dpcd.c
@@ -39,7 +39,7 @@
if (DEBUG_DPCD) { \
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DPCD_READABLE_AREA 0x600
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 561f828..ead4e1a 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -34,7 +34,7 @@
if (DEBUG_DP) { \
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/*
* Register offset for DP.
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 32cf839..d071049 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -29,7 +29,7 @@
if (PL330_ERR_DEBUG >= lvl) {\
fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/dma/xlnx-zynq-devcfg.c b/hw/dma/xlnx-zynq-devcfg.c
index 3b10523..12bb2e3 100644
--- a/hw/dma/xlnx-zynq-devcfg.c
+++ b/hw/dma/xlnx-zynq-devcfg.c
@@ -43,7 +43,7 @@
if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
REG32(CTRL, 0x00)
FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
index 8ceb21d..077c7da 100644
--- a/hw/dma/xlnx_dpdma.c
+++ b/hw/dma/xlnx_dpdma.c
@@ -34,7 +34,7 @@
if (DEBUG_DPDMA) { \
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/*
* Registers offset for DPDMA.
diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c
index 6b92e95..199dac9 100644
--- a/hw/i2c/i2c-ddc.c
+++ b/hw/i2c/i2c-ddc.c
@@ -30,7 +30,7 @@
if (DEBUG_I2CDDC) { \
qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* Structure defining a monitor's characteristics in a
* readable format: this should be passed to build_edid_blob()
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3fcf318..55686bf 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1695,9 +1695,14 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
align = memory_region_get_alignment(mr);
}
- if (!pcms->acpi_dev) {
+ /*
+ * When -no-acpi is used with Q35 machine type, no ACPI is built,
+ * but pcms->acpi_dev is still created. Check !acpi_enabled in
+ * addition to cover this case.
+ */
+ if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
- "memory hotplug is not enabled: missing acpi device");
+ "memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}
@@ -1729,9 +1734,14 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
- if (!pcms->acpi_dev) {
+ /*
+ * When -no-acpi is used with Q35 machine type, no ACPI is built,
+ * but pcms->acpi_dev is still created. Check !acpi_enabled in
+ * addition to cover this case.
+ */
+ if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
- "memory hotplug is not enabled: missing acpi device");
+ "memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index 1182745..b4cacd6 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -40,7 +40,7 @@
if (DEBUG_AUX) { \
qemu_log("aux: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index 0eddf2e..1b2a69b 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -52,7 +52,7 @@
if (DEBUG_DBDMA) { \
printf("DBDMA: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
if (DEBUG_DBDMA) { \
@@ -60,7 +60,7 @@
printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
} \
} \
-} while (0);
+} while (0)
/*
*/
diff --git a/hw/misc/mmio_interface.c b/hw/misc/mmio_interface.c
index 894e980..3b0e203 100644
--- a/hw/misc/mmio_interface.c
+++ b/hw/misc/mmio_interface.c
@@ -39,7 +39,7 @@ static uint64_t mmio_interface_counter;
if (DEBUG_MMIO_INTERFACE) { \
qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
} \
-} while (0);
+} while (0)
static void mmio_interface_init(Object *obj)
{
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
index 7c45833..7f10195 100644
--- a/hw/misc/stm32f2xx_syscfg.c
+++ b/hw/misc/stm32f2xx_syscfg.c
@@ -34,7 +34,7 @@
if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 44304d4..d6bdd02 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -30,7 +30,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
- } while (0);
+ } while (0)
#define XILINX_LOCK_KEY 0x767b
#define XILINX_UNLOCK_KEY 0xdf0d
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 3943187..0fa4b0d 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -34,7 +34,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 39d5d93..606b05c 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -456,32 +456,32 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_RMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
- do { \
+ { \
uint16_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[2] & 0xf000)!=0xf000; \
(RES) |= (rda[3] & 0xf000)!=0x0000; \
- } while (0); \
+ } \
break; \
case 0x01: \
case 0x02: \
- do { \
+ { \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
- } while (0); \
+ } \
break; \
case 0x03: \
- do { \
+ { \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
+ } \
break; \
} \
} while (0)
@@ -489,22 +489,22 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_TMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
- do { \
+ { \
uint16_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[2] & 0xf000)!=0xf000; \
- } while (0); \
+ } \
break; \
case 0x01: \
case 0x02: \
case 0x03: \
- do { \
+ { \
uint32_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
+ } \
break; \
} \
} while (0)
diff --git a/hw/nvram/ds1225y.c b/hw/nvram/ds1225y.c
index 57d5ab2..ad7345f 100644
--- a/hw/nvram/ds1225y.c
+++ b/hw/nvram/ds1225y.c
@@ -80,7 +80,7 @@ static int nvram_post_load(void *opaque, int version_id)
}
/* Write back nvram contents */
- s->file = fopen(s->filename, "wb");
+ s->file = s->filename ? fopen(s->filename, "wb") : NULL;
if (s->file) {
/* Write back contents, as 'wb' mode cleaned the file */
if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
@@ -126,7 +126,7 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
/* Read current file */
- file = fopen(s->filename, "rb");
+ file = s->filename ? fopen(s->filename, "rb") : NULL;
if (file) {
/* Read nvram contents */
if (fread(s->contents, s->chip_size, 1, file) != 1) {
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e58833a..49d2559 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1755,6 +1755,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
data->sector << BDRV_SECTOR_BITS,
&data->qiov, 0,
scsi_write_same_complete, data);
+ aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
return;
}
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index bd0d9ff..ba70c0d 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -482,6 +482,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
int rc;
int sg_version;
struct sg_scsi_id scsiid;
+ Error *local_err = NULL;
if (!s->conf.blk) {
error_setg(errp, "drive property not set");
@@ -515,6 +516,13 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
return;
}
+ blkconf_apply_backend_options(&s->conf,
+ blk_is_read_only(s->conf.blk),
+ true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
/* define device state */
s->type = scsiid.scsi_type;
@@ -565,6 +573,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
+ DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index d60daba..185e1a3 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -35,7 +35,7 @@
if (MSS_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
index 26a1b4d..69514da 100644
--- a/hw/ssi/stm32f2xx_spi.c
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -35,7 +35,7 @@
if (STM_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index 33482f0..83585bc 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -36,7 +36,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index d8187fa..85c5d0c 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -43,7 +43,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* config register */
#define R_CONFIG (0x00 / 4)
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index ce1dc63..96d534d 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -37,7 +37,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 5e65fdb..1005640 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -24,7 +24,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 577371b..d97436b 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -70,6 +70,7 @@ typedef struct HPETState {
MemoryRegion iomem;
uint64_t hpet_offset;
+ bool hpet_offset_saved;
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
uint32_t flags;
uint8_t rtc_irq_level;
@@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque)
HPETState *s = opaque;
/* save current counter value */
- s->hpet_counter = hpet_get_ticks(s);
+ if (hpet_enabled(s)) {
+ s->hpet_counter = hpet_get_ticks(s);
+ }
return 0;
}
@@ -252,7 +255,10 @@ static int hpet_post_load(void *opaque, int version_id)
HPETState *s = opaque;
/* Recalculate the offset between the main counter and guest time */
- s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (!s->hpet_offset_saved) {
+ s->hpet_offset = ticks_to_ns(s->hpet_counter)
+ - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ }
/* Push number of timers into capability returned via HPET_ID */
s->capability &= ~HPET_ID_NUM_TIM_MASK;
@@ -267,6 +273,13 @@ static int hpet_post_load(void *opaque, int version_id)
return 0;
}
+static bool hpet_offset_needed(void *opaque)
+{
+ HPETState *s = opaque;
+
+ return hpet_enabled(s) && s->hpet_offset_saved;
+}
+
static bool hpet_rtc_irq_level_needed(void *opaque)
{
HPETState *s = opaque;
@@ -285,6 +298,17 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = {
}
};
+static const VMStateDescription vmstate_hpet_offset = {
+ .name = "hpet/offset",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hpet_offset_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(hpet_offset, HPETState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_hpet_timer = {
.name = "hpet_timer",
.version_id = 1,
@@ -320,6 +344,7 @@ static const VMStateDescription vmstate_hpet = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_hpet_rtc_irq_level,
+ &vmstate_hpet_offset,
NULL
}
};
@@ -762,6 +787,7 @@ static Property hpet_device_properties[] = {
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
+ DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
index 60f1213..4f81457 100644
--- a/hw/timer/mss-timer.c
+++ b/hw/timer/mss-timer.c
@@ -36,7 +36,7 @@
if (MSS_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
index e5f5e14..58fc7b1 100644
--- a/hw/timer/stm32f2xx_timer.c
+++ b/hw/timer/stm32f2xx_timer.c
@@ -34,7 +34,7 @@
if (STM_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 149fae6..29142f3 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -38,7 +38,7 @@
if (DEBUG_TPM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
#define TPM_PASSTHROUGH(obj) \
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 561384c..8b5eb01 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -90,7 +90,7 @@ typedef struct TPMState {
if (DEBUG_TIS) { \
printf(fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* tis registers */
#define TPM_TIS_REG_ACCESS 0x00
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 778d610..d8941fc 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -256,6 +256,9 @@ Chardev *qemu_chardev_new(const char *id, const char *typename,
extern int term_escape_char;
+GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
+ GSourceFunc func, void *private);
+
/* console.c */
void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 6cbc02a..7633ef6 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -391,9 +391,10 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
uint64_t num_dirty = 0;
unsigned long *dest = rb->bmap;
- /* start address is aligned at the start of a word? */
+ /* start address and length is aligned at the start of a word? */
if (((word * BITS_PER_LONG) << TARGET_PAGE_BITS) ==
- (start + rb->offset)) {
+ (start + rb->offset) &&
+ !(length & ((BITS_PER_LONG << TARGET_PAGE_BITS) - 1))) {
int k;
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
unsigned long * const *src;
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 263de97..7f31850 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -2,7 +2,11 @@
#define HW_COMPAT_H
#define HW_COMPAT_2_11 \
- /* empty */
+ {\
+ .driver = "hpet",\
+ .property = "hpet-offset-saved",\
+ .value = "false",\
+ },
#define HW_COMPAT_2_10 \
{\
diff --git a/include/qemu/readline.h b/include/qemu/readline.h
index c08cf74..e812583 100644
--- a/include/qemu/readline.h
+++ b/include/qemu/readline.h
@@ -59,5 +59,6 @@ ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
ReadLineFlushFunc *flush_func,
void *opaque,
ReadLineCompletionFunc *completion_finder);
+void readline_free(ReadLineState *rs);
#endif /* READLINE_H */
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 9910f49..9af4e94 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -22,9 +22,31 @@ typedef struct QemuThread QemuThread;
void qemu_mutex_init(QemuMutex *mutex);
void qemu_mutex_destroy(QemuMutex *mutex);
-void qemu_mutex_lock(QemuMutex *mutex);
-int qemu_mutex_trylock(QemuMutex *mutex);
-void qemu_mutex_unlock(QemuMutex *mutex);
+int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
+void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
+void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line);
+
+#define qemu_mutex_lock(mutex) \
+ qemu_mutex_lock_impl(mutex, __FILE__, __LINE__)
+#define qemu_mutex_trylock(mutex) \
+ qemu_mutex_trylock_impl(mutex, __FILE__, __LINE__)
+#define qemu_mutex_unlock(mutex) \
+ qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__)
+
+static inline void (qemu_mutex_lock)(QemuMutex *mutex)
+{
+ qemu_mutex_lock(mutex);
+}
+
+static inline int (qemu_mutex_trylock)(QemuMutex *mutex)
+{
+ return qemu_mutex_trylock(mutex);
+}
+
+static inline void (qemu_mutex_unlock)(QemuMutex *mutex)
+{
+ qemu_mutex_unlock(mutex);
+}
/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */
void qemu_rec_mutex_init(QemuRecMutex *mutex);
@@ -39,7 +61,16 @@ void qemu_cond_destroy(QemuCond *cond);
*/
void qemu_cond_signal(QemuCond *cond);
void qemu_cond_broadcast(QemuCond *cond);
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
+void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex,
+ const char *file, const int line);
+
+#define qemu_cond_wait(cond, mutex) \
+ qemu_cond_wait_impl(cond, mutex, __FILE__, __LINE__)
+
+static inline void (qemu_cond_wait)(QemuCond *cond, QemuMutex *mutex)
+{
+ qemu_cond_wait(cond, mutex);
+}
void qemu_sem_init(QemuSemaphore *sem, int init);
void qemu_sem_post(QemuSemaphore *sem);
diff --git a/migration/rdma.c b/migration/rdma.c
index ca56594..9d5a424 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -88,7 +88,7 @@ static uint32_t known_capabilities = RDMA_CAPABILITY_PIN_ALL;
} \
return rdma->error_state; \
} \
- } while (0);
+ } while (0)
/*
* A work request ID is 64-bits and we split up these bits
diff --git a/monitor.c b/monitor.c
index d682eee..b9da5e2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -583,7 +583,7 @@ static void monitor_data_destroy(Monitor *mon)
if (monitor_is_qmp(mon)) {
json_message_parser_destroy(&mon->qmp.parser);
}
- g_free(mon->rs);
+ readline_free(mon->rs);
QDECREF(mon->outbuf);
qemu_mutex_destroy(&mon->out_lock);
}
diff --git a/rules.mak b/rules.mak
index 6e94333..5fb4951 100644
--- a/rules.mak
+++ b/rules.mak
@@ -131,6 +131,8 @@ modules:
# If called with only a single argument, will print nothing in quiet mode.
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1))
+MAKEFLAGS += $(if $(V),,--no-print-directory --quiet)
+
# cc-option
# Usage: CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
diff --git a/scripts/analyse-locks-simpletrace.py b/scripts/analyse-locks-simpletrace.py
new file mode 100755
index 0000000..101e84d
--- /dev/null
+++ b/scripts/analyse-locks-simpletrace.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Analyse lock events and compute statistics
+#
+# Author: Alex Bennée <alex.bennee@linaro.org>
+#
+
+import os
+import simpletrace
+import argparse
+import numpy as np
+
+class MutexAnalyser(simpletrace.Analyzer):
+ "A simpletrace Analyser for checking locks."
+
+ def __init__(self):
+ self.locks = 0
+ self.locked = 0
+ self.unlocks = 0
+ self.mutex_records = {}
+
+ def _get_mutex(self, mutex):
+ if not mutex in self.mutex_records:
+ self.mutex_records[mutex] = {"locks": 0,
+ "lock_time": 0,
+ "acquire_times": [],
+ "locked": 0,
+ "locked_time": 0,
+ "held_times": [],
+ "unlocked": 0}
+
+ return self.mutex_records[mutex]
+
+ def qemu_mutex_lock(self, timestamp, mutex, filename, line):
+ self.locks += 1
+ rec = self._get_mutex(mutex)
+ rec["locks"] += 1
+ rec["lock_time"] = timestamp[0]
+ rec["lock_loc"] = (filename, line)
+
+ def qemu_mutex_locked(self, timestamp, mutex, filename, line):
+ self.locked += 1
+ rec = self._get_mutex(mutex)
+ rec["locked"] += 1
+ rec["locked_time"] = timestamp[0]
+ acquire_time = rec["locked_time"] - rec["lock_time"]
+ rec["locked_loc"] = (filename, line)
+ rec["acquire_times"].append(acquire_time)
+
+ def qemu_mutex_unlock(self, timestamp, mutex, filename, line):
+ self.unlocks += 1
+ rec = self._get_mutex(mutex)
+ rec["unlocked"] += 1
+ held_time = timestamp[0] - rec["locked_time"]
+ rec["held_times"].append(held_time)
+ rec["unlock_loc"] = (filename, line)
+
+
+def get_args():
+ "Grab options"
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--output", "-o", type=str, help="Render plot to file")
+ parser.add_argument("events", type=str, help='trace file read from')
+ parser.add_argument("tracefile", type=str, help='trace file read from')
+ return parser.parse_args()
+
+if __name__ == '__main__':
+ args = get_args()
+
+ # Gather data from the trace
+ analyser = MutexAnalyser()
+ simpletrace.process(args.events, args.tracefile, analyser)
+
+ print ("Total locks: %d, locked: %d, unlocked: %d" %
+ (analyser.locks, analyser.locked, analyser.unlocks))
+
+ # Now dump the individual lock stats
+ for key, val in sorted(analyser.mutex_records.iteritems(),
+ key=lambda (k,v): v["locks"]):
+ print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" %
+ (key, val["locks"], val["locked"], val["unlocked"]))
+
+ acquire_times = np.array(val["acquire_times"])
+ if len(acquire_times) > 0:
+ print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" %
+ (acquire_times.min(), np.median(acquire_times),
+ acquire_times.mean(), acquire_times.max()))
+
+ held_times = np.array(val["held_times"])
+ if len(held_times) > 0:
+ print (" Held Time: min:%d median:%d avg:%.2f max:%d" %
+ (held_times.min(), np.median(held_times),
+ held_times.mean(), held_times.max()))
+
+ # Check if any locks still held
+ if val["locks"] > val["locked"]:
+ print (" LOCK HELD (%s:%s)" % (val["locked_loc"]))
+ print (" BLOCKED (%s:%s)" % (val["lock_loc"]))
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3dc27d9..accba24 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1622,6 +1622,11 @@ sub process {
}
}
+# 'do ... while (0/false)' only makes sense in macros, without trailing ';'
+ if ($line =~ /while\s*\((0|false)\);/) {
+ ERROR("suspicious ; after while (0)\n" . $herecurr);
+ }
+
# Check relative indent for conditionals and blocks.
if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
my ($s, $c) = ($stat, $cond);
diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py
index b3f8e04..690827e 100644
--- a/scripts/qemu-gdb.py
+++ b/scripts/qemu-gdb.py
@@ -26,7 +26,7 @@ import os, sys
sys.path.append(os.path.dirname(__file__))
-from qemugdb import aio, mtree, coroutine
+from qemugdb import aio, mtree, coroutine, tcg, timers
class QemuCommand(gdb.Command):
'''Prefix for QEMU debug support commands'''
@@ -38,6 +38,8 @@ QemuCommand()
coroutine.CoroutineCommand()
mtree.MtreeCommand()
aio.HandlersCommand()
+tcg.TCGLockStatusCommand()
+timers.TimersCommand()
coroutine.CoroutineSPFunction()
coroutine.CoroutinePCFunction()
diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py
new file mode 100644
index 0000000..8c7f1d7
--- /dev/null
+++ b/scripts/qemugdb/tcg.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# GDB debugging support, TCG status
+#
+# Copyright 2016 Linaro Ltd
+#
+# Authors:
+# Alex Bennée <alex.bennee@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+# Contributions after 2012-01-13 are licensed under the terms of the
+# GNU GPL, version 2 or (at your option) any later version.
+
+# 'qemu tcg-lock-status' -- display the TCG lock status across threads
+
+import gdb
+
+class TCGLockStatusCommand(gdb.Command):
+ '''Display TCG Execution Status'''
+ def __init__(self):
+ gdb.Command.__init__(self, 'qemu tcg-lock-status', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+
+ def invoke(self, arg, from_tty):
+ gdb.write("Thread, BQL (iothread_mutex), Replay, Blocked?\n")
+ for thread in gdb.inferiors()[0].threads():
+ thread.switch()
+
+ iothread = gdb.parse_and_eval("iothread_locked")
+ replay = gdb.parse_and_eval("replay_locked")
+
+ frame = gdb.selected_frame()
+ if frame.name() == "__lll_lock_wait":
+ frame.older().select()
+ mutex = gdb.parse_and_eval("mutex")
+ owner = gdb.parse_and_eval("mutex->__data.__owner")
+ blocked = ("__lll_lock_wait waiting on %s from %d" %
+ (mutex, owner))
+ else:
+ blocked = "not blocked"
+
+ gdb.write("%d/%d, %s, %s, %s\n" % (thread.num, thread.ptid[1],
+ iothread, replay, blocked))
diff --git a/scripts/qemugdb/timers.py b/scripts/qemugdb/timers.py
new file mode 100644
index 0000000..be71a00
--- /dev/null
+++ b/scripts/qemugdb/timers.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+# GDB debugging support
+#
+# Copyright 2017 Linaro Ltd
+#
+# Author: Alex Bennée <alex.bennee@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+# 'qemu timers' -- display the current timerlists
+
+import gdb
+
+class TimersCommand(gdb.Command):
+ '''Display the current QEMU timers'''
+
+ def __init__(self):
+ 'Register the class as a gdb command'
+ gdb.Command.__init__(self, 'qemu timers', gdb.COMMAND_DATA,
+ gdb.COMPLETE_NONE)
+
+ def dump_timers(self, timer):
+ "Follow a timer and recursively dump each one in the list."
+ # timer should be of type QemuTimer
+ gdb.write(" timer %s/%s (cb:%s,opq:%s)\n" % (
+ timer['expire_time'],
+ timer['scale'],
+ timer['cb'],
+ timer['opaque']))
+
+ if int(timer['next']) > 0:
+ self.dump_timers(timer['next'])
+
+
+ def process_timerlist(self, tlist, ttype):
+ gdb.write("Processing %s timers\n" % (ttype))
+ gdb.write(" clock %s is enabled:%s, last:%s\n" % (
+ tlist['clock']['type'],
+ tlist['clock']['enabled'],
+ tlist['clock']['last']))
+ if int(tlist['active_timers']) > 0:
+ self.dump_timers(tlist['active_timers'])
+
+
+ def invoke(self, arg, from_tty):
+ 'Run the command'
+ main_timers = gdb.parse_and_eval("main_loop_tlg")
+
+ # This will break if QEMUClockType in timer.h is redfined
+ self.process_timerlist(main_timers['tl'][0], "Realtime")
+ self.process_timerlist(main_timers['tl'][1], "Virtual")
+ self.process_timerlist(main_timers['tl'][2], "Host")
+ self.process_timerlist(main_timers['tl'][3], "Virtual RT")
diff --git a/scsi/utils.c b/scsi/utils.c
index ddae650..8738522 100644
--- a/scsi/utils.c
+++ b/scsi/utils.c
@@ -322,18 +322,18 @@ int scsi_convert_sense(uint8_t *in_buf, int in_len,
SCSISense sense;
bool fixed_in;
+ if (in_len == 0) {
+ return scsi_build_sense_buf(buf, len, SENSE_CODE(NO_SENSE), fixed);
+ }
+
fixed_in = (in_buf[0] & 2) == 0;
- if (in_len && fixed == fixed_in) {
+ if (fixed == fixed_in) {
memcpy(buf, in_buf, MIN(len, in_len));
return MIN(len, in_len);
- }
-
- if (in_len == 0) {
- sense = SENSE_CODE(NO_SENSE);
} else {
sense = scsi_parse_sense_buf(in_buf, in_len);
+ return scsi_build_sense_buf(buf, len, sense, fixed);
}
- return scsi_build_sense_buf(buf, len, sense, fixed);
}
int scsi_sense_to_errno(int key, int asc, int ascq)
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index cf537e9..70c1e08 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -400,7 +400,7 @@ static void unallocated_encoding(DisasContext *s)
"at pc=%016" PRIx64 "\n", \
__FILE__, __LINE__, insn, s->pc - 4); \
unallocated_encoding(s); \
- } while (0);
+ } while (0)
static void init_tmp_a64_array(DisasContext *s)
{
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3818d72..ad8196b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4147,6 +4147,48 @@ static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
info->cap_insn_split = 8;
}
+void x86_update_hflags(CPUX86State *env)
+{
+ uint32_t hflags;
+#define HFLAG_COPY_MASK \
+ ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
+ HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
+ HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
+ HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
+
+ hflags = env->hflags & HFLAG_COPY_MASK;
+ hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
+ hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
+ hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
+ (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
+ hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
+
+ if (env->cr[4] & CR4_OSFXSR_MASK) {
+ hflags |= HF_OSFXSR_MASK;
+ }
+
+ if (env->efer & MSR_EFER_LMA) {
+ hflags |= HF_LMA_MASK;
+ }
+
+ if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
+ hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
+ } else {
+ hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
+ (DESC_B_SHIFT - HF_CS32_SHIFT);
+ hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
+ (DESC_B_SHIFT - HF_SS32_SHIFT);
+ if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
+ !(hflags & HF_CS32_MASK)) {
+ hflags |= HF_ADDSEG_MASK;
+ } else {
+ hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
+ env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
+ }
+ }
+ env->hflags = hflags;
+}
+
static Property x86_cpu_properties[] = {
#ifdef CONFIG_USER_ONLY
/* apic_id = 0 by default for *-user, see commit 9886e834 */
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 62c4742..f64e5ed 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1778,4 +1778,6 @@ bool cpu_is_bsp(X86CPU *cpu);
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
+void x86_update_hflags(CPUX86State* env);
+
#endif /* I386_CPU_H */
diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c
index 3ce6950..934ec4a 100644
--- a/target/i386/hax-all.c
+++ b/target/i386/hax-all.c
@@ -782,56 +782,6 @@ static int hax_set_segments(CPUArchState *env, struct vcpu_state_t *sregs)
return 0;
}
-/*
- * After get the state from the kernel module, some
- * qemu emulator state need be updated also
- */
-static int hax_setup_qemu_emulator(CPUArchState *env)
-{
-
-#define HFLAG_COPY_MASK (~( \
- HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
- HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
- HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
- HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK))
-
- uint32_t hflags;
-
- hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
- hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
- hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
- (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
- hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
- hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<
- (HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);
-
- if (env->efer & MSR_EFER_LMA) {
- hflags |= HF_LMA_MASK;
- }
-
- if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
- hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
- } else {
- hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
- (DESC_B_SHIFT - HF_CS32_SHIFT);
- hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
- (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (!(env->cr[0] & CR0_PE_MASK) ||
- (env->eflags & VM_MASK) || !(hflags & HF_CS32_MASK)) {
- hflags |= HF_ADDSEG_MASK;
- } else {
- hflags |= ((env->segs[R_DS].base |
- env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
- }
- }
-
- hflags &= ~HF_SMM_MASK;
-
- env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;
- return 0;
-}
-
static int hax_sync_vcpu_register(CPUArchState *env, int set)
{
struct vcpu_state_t regs;
@@ -887,9 +837,6 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
return -1;
}
}
- if (!set) {
- hax_setup_qemu_emulator(env);
- }
return 0;
}
@@ -1070,6 +1017,7 @@ static int hax_arch_get_registers(CPUArchState *env)
return ret;
}
+ x86_update_hflags(env);
return 0;
}
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
index 71c0515..7803e09 100644
--- a/target/i386/hvf/x86hvf.c
+++ b/target/i386/hvf/x86hvf.c
@@ -297,7 +297,6 @@ int hvf_get_registers(CPUState *cpu_state)
X86CPU *x86cpu = X86_CPU(cpu_state);
CPUX86State *env = &x86cpu->env;
-
env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
env->regs[R_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
@@ -333,6 +332,7 @@ int hvf_get_registers(CPUState *cpu_state)
env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
+ x86_update_hflags(env);
return 0;
}
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 6f69e2f..4912f4d 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -92,8 +92,9 @@ static bool has_msr_hv_stimer;
static bool has_msr_hv_frequencies;
static bool has_msr_xss;
-static bool has_msr_architectural_pmu;
-static uint32_t num_architectural_pmu_counters;
+static uint32_t has_architectural_pmu_version;
+static uint32_t num_architectural_pmu_gp_counters;
+static uint32_t num_architectural_pmu_fixed_counters;
static int has_xsave;
static int has_xcrs;
@@ -872,19 +873,28 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
if (limit >= 0x0a) {
- uint32_t ver;
+ uint32_t eax, edx;
- cpu_x86_cpuid(env, 0x0a, 0, &ver, &unused, &unused, &unused);
- if ((ver & 0xff) > 0) {
- has_msr_architectural_pmu = true;
- num_architectural_pmu_counters = (ver & 0xff00) >> 8;
+ cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx);
+
+ has_architectural_pmu_version = eax & 0xff;
+ if (has_architectural_pmu_version > 0) {
+ num_architectural_pmu_gp_counters = (eax & 0xff00) >> 8;
/* Shouldn't be more than 32, since that's the number of bits
* available in EBX to tell us _which_ counters are available.
* Play it safe.
*/
- if (num_architectural_pmu_counters > MAX_GP_COUNTERS) {
- num_architectural_pmu_counters = MAX_GP_COUNTERS;
+ if (num_architectural_pmu_gp_counters > MAX_GP_COUNTERS) {
+ num_architectural_pmu_gp_counters = MAX_GP_COUNTERS;
+ }
+
+ if (has_architectural_pmu_version > 1) {
+ num_architectural_pmu_fixed_counters = edx & 0x1f;
+
+ if (num_architectural_pmu_fixed_counters > MAX_FIXED_COUNTERS) {
+ num_architectural_pmu_fixed_counters = MAX_FIXED_COUNTERS;
+ }
}
}
}
@@ -1650,32 +1660,36 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
}
- if (has_msr_architectural_pmu) {
- /* Stop the counter. */
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ if (has_architectural_pmu_version > 0) {
+ if (has_architectural_pmu_version > 1) {
+ /* Stop the counter. */
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ }
/* Set the counter values. */
- for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+ for (i = 0; i < num_architectural_pmu_fixed_counters; i++) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i,
env->msr_fixed_counters[i]);
}
- for (i = 0; i < num_architectural_pmu_counters; i++) {
+ for (i = 0; i < num_architectural_pmu_gp_counters; i++) {
kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i,
env->msr_gp_counters[i]);
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i,
env->msr_gp_evtsel[i]);
}
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
- env->msr_global_status);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
- env->msr_global_ovf_ctrl);
-
- /* Now start the PMU. */
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
- env->msr_fixed_ctr_ctrl);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
- env->msr_global_ctrl);
+ if (has_architectural_pmu_version > 1) {
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
+ env->msr_global_status);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+ env->msr_global_ovf_ctrl);
+
+ /* Now start the PMU. */
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
+ env->msr_fixed_ctr_ctrl);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
+ env->msr_global_ctrl);
+ }
}
/*
* Hyper-V partition-wide MSRs: to avoid clearing them on cpu hot-add,
@@ -1877,7 +1891,6 @@ static int kvm_get_sregs(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
struct kvm_sregs sregs;
- uint32_t hflags;
int bit, i, ret;
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_SREGS, &sregs);
@@ -1919,44 +1932,7 @@ static int kvm_get_sregs(X86CPU *cpu)
env->efer = sregs.efer;
/* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */
-
-#define HFLAG_COPY_MASK \
- ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
- HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
- HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
- HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
-
- hflags = env->hflags & HFLAG_COPY_MASK;
- hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
- hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
- hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
- (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
- hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
-
- if (env->cr[4] & CR4_OSFXSR_MASK) {
- hflags |= HF_OSFXSR_MASK;
- }
-
- if (env->efer & MSR_EFER_LMA) {
- hflags |= HF_LMA_MASK;
- }
-
- if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
- hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
- } else {
- hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
- (DESC_B_SHIFT - HF_CS32_SHIFT);
- hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
- (DESC_B_SHIFT - HF_SS32_SHIFT);
- if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
- !(hflags & HF_CS32_MASK)) {
- hflags |= HF_ADDSEG_MASK;
- } else {
- hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
- env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
- }
- }
- env->hflags = hflags;
+ x86_update_hflags(env);
return 0;
}
@@ -2030,15 +2006,17 @@ static int kvm_get_msrs(X86CPU *cpu)
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0);
}
- if (has_msr_architectural_pmu) {
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
- kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
- for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+ if (has_architectural_pmu_version > 0) {
+ if (has_architectural_pmu_version > 1) {
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
+ kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
+ }
+ for (i = 0; i < num_architectural_pmu_fixed_counters; i++) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, 0);
}
- for (i = 0; i < num_architectural_pmu_counters; i++) {
+ for (i = 0; i < num_architectural_pmu_gp_counters; i++) {
kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, 0);
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, 0);
}
@@ -3492,6 +3470,7 @@ int kvm_arch_release_virq_post(int virq)
if (entry->virq == virq) {
trace_kvm_x86_remove_msi_route(virq);
QLIST_REMOVE(entry, list);
+ g_free(entry);
break;
}
}
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index f167a42..8fb7a36 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -682,13 +682,13 @@ static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
do { \
e = SIGNED_EVEN(a, df); \
o = SIGNED_ODD(a, df); \
- } while (0);
+ } while (0)
#define UNSIGNED_EXTRACT(e, o, a, df) \
do { \
e = UNSIGNED_EVEN(a, df); \
o = UNSIGNED_ODD(a, df); \
- } while (0);
+ } while (0)
static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
@@ -1120,9 +1120,11 @@ void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
#define MSA_LOOP(DF) \
+ do { \
for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
- MSA_DO_ ## DF \
- }
+ MSA_DO_ ## DF; \
+ } \
+ } while (0)
#define MSA_FN_DF(FUNC) \
void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
@@ -1135,17 +1137,17 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
uint32_t i; \
switch (df) { \
case DF_BYTE: \
- MSA_LOOP_B \
+ MSA_LOOP_B; \
break; \
case DF_HALF: \
- MSA_LOOP_H \
+ MSA_LOOP_H; \
break; \
case DF_WORD: \
- MSA_LOOP_W \
+ MSA_LOOP_W; \
break; \
case DF_DOUBLE: \
- MSA_LOOP_D \
- break; \
+ MSA_LOOP_D; \
+ break; \
default: \
assert(0); \
} \
@@ -1168,7 +1170,7 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
do { \
R##DF(pwx, i) = pwt->DF[2*i]; \
L##DF(pwx, i) = pws->DF[2*i]; \
- } while (0);
+ } while (0)
MSA_FN_DF(pckev_df)
#undef MSA_DO
@@ -1176,7 +1178,7 @@ MSA_FN_DF(pckev_df)
do { \
R##DF(pwx, i) = pwt->DF[2*i+1]; \
L##DF(pwx, i) = pws->DF[2*i+1]; \
- } while (0);
+ } while (0)
MSA_FN_DF(pckod_df)
#undef MSA_DO
@@ -1184,7 +1186,7 @@ MSA_FN_DF(pckod_df)
do { \
pwx->DF[2*i] = L##DF(pwt, i); \
pwx->DF[2*i+1] = L##DF(pws, i); \
- } while (0);
+ } while (0)
MSA_FN_DF(ilvl_df)
#undef MSA_DO
@@ -1192,7 +1194,7 @@ MSA_FN_DF(ilvl_df)
do { \
pwx->DF[2*i] = R##DF(pwt, i); \
pwx->DF[2*i+1] = R##DF(pws, i); \
- } while (0);
+ } while (0)
MSA_FN_DF(ilvr_df)
#undef MSA_DO
@@ -1200,7 +1202,7 @@ MSA_FN_DF(ilvr_df)
do { \
pwx->DF[2*i] = pwt->DF[2*i]; \
pwx->DF[2*i+1] = pws->DF[2*i]; \
- } while (0);
+ } while (0)
MSA_FN_DF(ilvev_df)
#undef MSA_DO
@@ -1208,7 +1210,7 @@ MSA_FN_DF(ilvev_df)
do { \
pwx->DF[2*i] = pwt->DF[2*i+1]; \
pwx->DF[2*i+1] = pws->DF[2*i+1]; \
- } while (0);
+ } while (0)
MSA_FN_DF(ilvod_df)
#undef MSA_DO
#undef MSA_LOOP_COND
@@ -1222,7 +1224,7 @@ MSA_FN_DF(ilvod_df)
uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
pwx->DF[i] = \
(pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
- } while (0);
+ } while (0)
MSA_FN_DF(vshf_df)
#undef MSA_DO
#undef MSA_LOOP_COND
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index 9b8b59f..6a18a41 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -58,7 +58,7 @@
if (DEBUG_KVM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define kvm_vm_check_mem_attr(s, attr) \
kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr)
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 39a4b53..8883274 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -300,12 +300,16 @@ check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
check-qtest-m68k-y = tests/boot-serial-test$(EXESUF)
+check-qtest-microblaze-y = tests/boot-serial-test$(EXESUF)
+
check-qtest-mips-y = tests/endianness-test$(EXESUF)
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
+check-qtest-moxie-y = tests/boot-serial-test$(EXESUF)
+
check-qtest-ppc-y = tests/endianness-test$(EXESUF)
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
@@ -358,6 +362,7 @@ check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
gcov-files-arm-y += hw/timer/arm_mptimer.c
+check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
diff --git a/tests/acpi-utils.h b/tests/acpi-utils.h
index d5ca5b6..ac52abd 100644
--- a/tests/acpi-utils.h
+++ b/tests/acpi-utils.h
@@ -32,7 +32,7 @@ typedef struct {
do { \
memread(addr, &field, sizeof(field)); \
addr += sizeof(field); \
- } while (0);
+ } while (0)
#define ACPI_READ_ARRAY_PTR(arr, length, addr) \
do { \
@@ -40,7 +40,7 @@ typedef struct {
for (idx = 0; idx < length; ++idx) { \
ACPI_READ_FIELD(arr[idx], addr); \
} \
- } while (0);
+ } while (0)
#define ACPI_READ_ARRAY(arr, addr) \
ACPI_READ_ARRAY_PTR(arr, sizeof(arr) / sizeof(arr[0]), addr)
@@ -56,7 +56,7 @@ typedef struct {
ACPI_READ_FIELD((table)->oem_revision, addr); \
ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \
ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \
- } while (0);
+ } while (0)
#define ACPI_ASSERT_CMP(actual, expected) do { \
char ACPI_ASSERT_CMP_str[5] = {}; \
@@ -77,7 +77,7 @@ typedef struct {
ACPI_READ_FIELD((field).bit_offset, addr); \
ACPI_READ_FIELD((field).access_width, addr); \
ACPI_READ_FIELD((field).address, addr); \
- } while (0);
+ } while (0)
uint8_t acpi_calc_checksum(const uint8_t *data, int len);
diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index dd3828c..663b78b 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -24,6 +24,37 @@ static const uint8_t kernel_mcf5208[] = {
0x60, 0xfa /* bra.s loop */
};
+static const uint8_t kernel_pls3adsp1800[] = {
+ 0xb0, 0x00, 0x84, 0x00, /* imm 0x8400 */
+ 0x30, 0x60, 0x00, 0x04, /* addik r3,r0,4 */
+ 0x30, 0x80, 0x00, 0x54, /* addik r4,r0,'T' */
+ 0xf0, 0x83, 0x00, 0x00, /* sbi r4,r3,0 */
+ 0xb8, 0x00, 0xff, 0xfc /* bri -4 loop */
+};
+
+static const uint8_t kernel_plml605[] = {
+ 0xe0, 0x83, 0x00, 0xb0, /* imm 0x83e0 */
+ 0x00, 0x10, 0x60, 0x30, /* addik r3,r0,0x1000 */
+ 0x54, 0x00, 0x80, 0x30, /* addik r4,r0,'T' */
+ 0x00, 0x00, 0x83, 0xf0, /* sbi r4,r3,0 */
+ 0xfc, 0xff, 0x00, 0xb8 /* bri -4 loop */
+};
+
+static const uint8_t bios_moxiesim[] = {
+ 0x20, 0x10, 0x00, 0x00, 0x03, 0xf8, /* ldi.s r1,0x3f8 */
+ 0x1b, 0x20, 0x00, 0x00, 0x00, 0x54, /* ldi.b r2,'T' */
+ 0x1e, 0x12, /* st.b r1,r2 */
+ 0x1a, 0x00, 0x00, 0x00, 0x10, 0x00 /* jmpa 0x1000 */
+};
+
+static const uint8_t bios_raspi2[] = {
+ 0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */
+ 0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */
+ 0x00, 0x20, 0xc3, 0xe5, /* strb r2,[r3] */
+ 0xfb, 0xff, 0xff, 0xea, /* b loop */
+ 0x00, 0x10, 0x20, 0x3f, /* 0x3f201000 = UART0 base addr */
+};
+
typedef struct testdef {
const char *arch; /* Target architecture */
const char *machine; /* Name of the machine */
@@ -50,6 +81,12 @@ static testdef_t tests[] = {
{ "s390x", "s390-ccw-virtio",
"-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
{ "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
+ { "microblaze", "petalogix-s3adsp1800", "", "TT",
+ sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
+ { "microblazeel", "petalogix-ml605", "", "TT",
+ sizeof(kernel_plml605), kernel_plml605 },
+ { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, bios_moxiesim },
+ { "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
{ NULL }
};
diff --git a/tests/check-qobject.c b/tests/check-qobject.c
index 03e9175..710f9e6 100644
--- a/tests/check-qobject.c
+++ b/tests/check-qobject.c
@@ -59,6 +59,8 @@ static void do_test_equality(bool expected, int _, ...)
g_assert(qobject_is_equal(args[i], args[j]) == expected);
}
}
+
+ g_free(args);
}
#define check_equal(...) \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 4b26c3a..32de731 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -3,7 +3,7 @@ ENV PACKAGES \
ccache gettext git tar PyYAML sparse flex bison python2 bzip2 hostname \
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
gcc gcc-c++ clang make perl which bc findutils libaio-devel \
- nettle-devel \
+ nettle-devel libasan libubsan \
mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
@@ -15,4 +15,4 @@ ENV PACKAGES \
RUN dnf install -y $PACKAGES
RUN rpm -q $PACKAGES | sort > /packages.txt
-ENV FEATURES mingw clang pyyaml
+ENV FEATURES mingw clang pyyaml asan
diff --git a/tests/docker/test-clang b/tests/docker/test-clang
index 1eb61a3..e90a793 100755
--- a/tests/docker/test-clang
+++ b/tests/docker/test-clang
@@ -17,7 +17,7 @@ requires clang
cd "$BUILD_DIR"
-OPTS="--enable-debug --cxx=clang++ --cc=clang --host-cc=clang"
+OPTS="--cxx=clang++ --cc=clang --host-cc=clang"
# -fsanitize=undefined is broken on Fedora 23, skip it for now
# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
#OPTS="$OPTS --extra-cflags=-fsanitize=undefined \
diff --git a/tests/docker/test-debug b/tests/docker/test-debug
new file mode 100755
index 0000000..d020b06
--- /dev/null
+++ b/tests/docker/test-debug
@@ -0,0 +1,26 @@
+#!/bin/bash -e
+#
+# Compile and check with clang & --enable-debug.
+#
+# Copyright (c) 2016-2018 Red Hat Inc.
+#
+# Authors:
+# Fam Zheng <famz@redhat.com>
+# Marc-André Lureau <marcandre.lureau@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2
+# or (at your option) any later version. See the COPYING file in
+# the top-level directory.
+
+. common.rc
+
+requires clang asan
+
+cd "$BUILD_DIR"
+
+OPTS="--cxx=clang++ --cc=clang --host-cc=clang"
+OPTS="--enable-debug $OPTS"
+
+build_qemu $OPTS
+make $MAKEFLAGS check
+install_qemu
diff --git a/tests/docker/test-mingw b/tests/docker/test-mingw
index 39a1da4..503a6bc 100755
--- a/tests/docker/test-mingw
+++ b/tests/docker/test-mingw
@@ -22,7 +22,6 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
build_qemu --cross-prefix=$prefix \
--enable-trace-backends=simple \
- --enable-debug \
--enable-gnutls \
--enable-nettle \
--enable-curl \
@@ -35,4 +34,3 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
make clean
done
-
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index c5a5c10..36feb22 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -271,7 +271,7 @@ static void add_query_tests(QmpSchema *schema)
{
SchemaInfoList *tail;
SchemaInfo *si, *arg_type, *ret_type;
- const char *test_name;
+ char *test_name;
/* Test the query-like commands */
for (tail = schema->list; tail; tail = tail->next) {
@@ -297,6 +297,7 @@ static void add_query_tests(QmpSchema *schema)
test_name = g_strdup_printf("qmp/%s", si->name);
qtest_add_data_func(test_name, si->name, test_query);
+ g_free(test_name);
}
}
diff --git a/tests/tcg/test-mmap.c b/tests/tcg/test-mmap.c
index 3982fa2..cdefadf 100644
--- a/tests/tcg/test-mmap.c
+++ b/tests/tcg/test-mmap.c
@@ -39,7 +39,7 @@ do \
fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
exit (EXIT_FAILURE); \
} \
-} while (0);
+} while (0)
unsigned char *dummybuf;
static unsigned int pagesize;
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index abd97c2..76c6461 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -67,7 +67,6 @@ static void coroutine_fn verify_entered_step_2(void *opaque)
/* Once more to check it still works after yielding */
g_assert(qemu_coroutine_entered(caller));
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
- qemu_coroutine_yield();
}
static void coroutine_fn verify_entered_step_1(void *opaque)
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index d820033..e0605a5 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -283,7 +283,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
return;
}
- do {
+ while (1) {
struct iovec *sg;
ssize_t ret, total = 0;
unsigned int num;
@@ -343,7 +343,9 @@ vubr_backend_recv_cb(int sock, void *ctx)
free(elem);
elem = NULL;
- } while (false); /* could loop if DONTWAIT worked? */
+
+ break; /* could loop if DONTWAIT worked? */
+ }
if (mhdr_cnt) {
mhdr.num_buffers = i;
diff --git a/trace-events b/trace-events
index 3695959..ec95e67 100644
--- a/trace-events
+++ b/trace-events
@@ -55,6 +55,10 @@ dma_complete(void *dbs, int ret, void *cb) "dbs=%p ret=%d cb=%p"
dma_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
dma_map_wait(void *dbs) "dbs=%p"
+# # exec.c
+find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" PRIx64 " @ 0x%" PRIx64
+find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
+
# memory.c
memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
memory_region_ops_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
diff --git a/ui/sdl_zoom_template.h b/ui/sdl_zoom_template.h
index 3bb508b..6a424ad 100644
--- a/ui/sdl_zoom_template.h
+++ b/ui/sdl_zoom_template.h
@@ -34,22 +34,22 @@
#define setRed(r, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
(((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
-} while (0);
+} while (0)
#define setGreen(g, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
(((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
-} while (0);
+} while (0)
#define setBlue(b, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
(((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
-} while (0);
+} while (0)
#define setAlpha(a, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Amask))) + \
(((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
-} while (0);
+} while (0)
static void glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
SDL_Rect *dst_rect)
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 99b0e46..029fec5 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -105,7 +105,8 @@ static void cleanup_infolist(CommandLineParameterInfoList *head)
if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
del_entry = cur->next;
cur->next = cur->next->next;
- g_free(del_entry);
+ del_entry->next = NULL;
+ qapi_free_CommandLineParameterInfoList(del_entry);
break;
}
pre_entry = pre_entry->next;
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 959a570..b789cf3 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -57,26 +57,28 @@ void qemu_mutex_destroy(QemuMutex *mutex)
error_exit(err, __func__);
}
-void qemu_mutex_lock(QemuMutex *mutex)
+void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
+ trace_qemu_mutex_lock(mutex, file, line);
+
err = pthread_mutex_lock(&mutex->lock);
if (err)
error_exit(err, __func__);
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
}
-int qemu_mutex_trylock(QemuMutex *mutex)
+int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
err = pthread_mutex_trylock(&mutex->lock);
if (err == 0) {
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
return 0;
}
if (err != EBUSY) {
@@ -85,15 +87,16 @@ int qemu_mutex_trylock(QemuMutex *mutex)
return -EBUSY;
}
-void qemu_mutex_unlock(QemuMutex *mutex)
+void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
- trace_qemu_mutex_unlocked(mutex);
err = pthread_mutex_unlock(&mutex->lock);
if (err)
error_exit(err, __func__);
+
+ trace_qemu_mutex_unlock(mutex, file, line);
}
void qemu_rec_mutex_init(QemuRecMutex *mutex)
@@ -152,14 +155,14 @@ void qemu_cond_broadcast(QemuCond *cond)
error_exit(err, __func__);
}
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(cond->initialized);
- trace_qemu_mutex_unlocked(mutex);
+ trace_qemu_mutex_unlock(mutex, file, line);
err = pthread_cond_wait(&cond->cond, &mutex->lock);
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
if (err)
error_exit(err, __func__);
}
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 94f3491..ab60c0d 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -56,30 +56,32 @@ void qemu_mutex_destroy(QemuMutex *mutex)
InitializeSRWLock(&mutex->lock);
}
-void qemu_mutex_lock(QemuMutex *mutex)
+void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
{
assert(mutex->initialized);
+ trace_qemu_mutex_lock(mutex, file, line);
+
AcquireSRWLockExclusive(&mutex->lock);
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
}
-int qemu_mutex_trylock(QemuMutex *mutex)
+int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
{
int owned;
assert(mutex->initialized);
owned = TryAcquireSRWLockExclusive(&mutex->lock);
if (owned) {
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
return 0;
}
return -EBUSY;
}
-void qemu_mutex_unlock(QemuMutex *mutex)
+void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
{
assert(mutex->initialized);
- trace_qemu_mutex_unlocked(mutex);
+ trace_qemu_mutex_unlock(mutex, file, line);
ReleaseSRWLockExclusive(&mutex->lock);
}
@@ -140,12 +142,12 @@ void qemu_cond_broadcast(QemuCond *cond)
WakeAllConditionVariable(&cond->var);
}
-void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
+void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
{
assert(cond->initialized);
- trace_qemu_mutex_unlocked(mutex);
+ trace_qemu_mutex_unlock(mutex, file, line);
SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
- trace_qemu_mutex_locked(mutex);
+ trace_qemu_mutex_locked(mutex, file, line);
}
void qemu_sem_init(QemuSemaphore *sem, int init)
diff --git a/util/readline.c b/util/readline.c
index bbdee79..24ec839 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -500,12 +500,28 @@ const char *readline_get_history(ReadLineState *rs, unsigned int index)
return rs->history[index];
}
+void readline_free(ReadLineState *rs)
+{
+ int i;
+
+ if (!rs) {
+ return;
+ }
+ for (i = 0; i < READLINE_MAX_CMDS; i++) {
+ g_free(rs->history[i]);
+ }
+ for (i = 0; i < READLINE_MAX_COMPLETIONS; i++) {
+ g_free(rs->completions[i]);
+ }
+ g_free(rs);
+}
+
ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
ReadLineFlushFunc *flush_func,
void *opaque,
ReadLineCompletionFunc *completion_finder)
{
- ReadLineState *rs = g_malloc0(sizeof(*rs));
+ ReadLineState *rs = g_new0(ReadLineState, 1);
rs->hist_entry = -1;
rs->opaque = opaque;
diff --git a/util/trace-events b/util/trace-events
index 025499f..515e625 100644
--- a/util/trace-events
+++ b/util/trace-events
@@ -56,6 +56,7 @@ lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d"
lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d"
lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
-# util/qemu-thread-posix.c
-qemu_mutex_locked(void *lock) "locked mutex %p"
-qemu_mutex_unlocked(void *lock) "unlocked mutex %p"
+# util/qemu-thread.c
+qemu_mutex_lock(void *mutex, const char *file, const int line) "waiting on mutex %p (%s:%d)"
+qemu_mutex_locked(void *mutex, const char *file, const int line) "taken mutex %p (%s:%d)"
+qemu_mutex_unlock(void *mutex, const char *file, const int line) "released mutex %p (%s:%d)"
diff --git a/vl.c b/vl.c
index f1c52fe..2586f25 100644
--- a/vl.c
+++ b/vl.c
@@ -2318,7 +2318,7 @@ static void qemu_add_data_dir(const char *path)
return; /* duplicate */
}
}
- data_dir[data_dir_idx++] = path;
+ data_dir[data_dir_idx++] = g_strdup(path);
}
static inline bool nonempty_str(const char *str)
@@ -3078,7 +3078,7 @@ int main(int argc, char **argv, char **envp)
Error *main_loop_err = NULL;
Error *err = NULL;
bool list_data_dirs = false;
- char **dirs;
+ char *dir, **dirs;
typedef struct BlockdevOptions_queue {
BlockdevOptions *bdo;
Location loc;
@@ -4181,9 +4181,12 @@ int main(int argc, char **argv, char **envp)
for (i = 0; dirs[i] != NULL; i++) {
qemu_add_data_dir(dirs[i]);
}
+ g_strfreev(dirs);
/* try to find datadir relative to the executable path */
- qemu_add_data_dir(os_find_datadir());
+ dir = os_find_datadir();
+ qemu_add_data_dir(dir);
+ g_free(dir);
/* add the datadir specified when building */
qemu_add_data_dir(CONFIG_QEMU_DATADIR);