mirror of https://gitee.com/openkylin/qemu.git
* 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) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJaXgkRAAoJEL/70l94x66DA3EIAI8z8Y+1NAmbLqiHhrrN9Ji/ b8EHQ8wf0pwwrHuRVKYZvKUU8yvp/CRIoVWZwfeGjRbZC+l7l+BAwdOx42Bj/dUW VopNzcJMu3s5SNwoYLvs01OjhciBYNXWTXBkIiErwurF0Ow7oYR7trkLwOw0veSO L4qFAGoIBI/7b6BZ3YRQXshhzdSQ6dvHrDness2V1c0crLG+yhvjKJ8PJ2tJyNZO DbsrCd7hS6e6liSUqdLj9XgRySFj9R5kgjaLjckjg1SC6kmhLN9hyke8iXgH7uvz WGnRPmKjKexFHVYgR0rRFlazcQclAczHuIi/OZe0HLi6trg2YKBkolMaQLQdgfk= =HTyS -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
c1d5b9add7
7
Makefile
7
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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
||||
##########################################
|
||||
|
|
134
cpus.c
134
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;
|
||||
|
|
|
@ -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 *)§or, ndata);
|
||||
memcpy(data, (uint8_t *)§or, MIN(sizeof(sector), ndata));
|
||||
if (sizeof(sector) < ndata) {
|
||||
memset(data + sizeof(sector), 0, ndata - sizeof(sector));
|
||||
}
|
||||
|
|
16
disas/s390.c
16
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)
|
||||
|
|
|
@ -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.
|
||||
|
|
40
exec.c
40
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
fprintf(stderr, ": %s: ", __func__); \
|
||||
fprintf(stderr, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* Fields for FlashPartInfo->flags */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
if (DEBUG_DPCD) { \
|
||||
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
#define DPCD_READABLE_AREA 0x600
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
if (DEBUG_DP) { \
|
||||
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Register offset for DP.
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
if (DEBUG_DPDMA) { \
|
||||
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Registers offset for DPDMA.
|
||||
|
|
|
@ -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()
|
||||
|
|
18
hw/i386/pc.c
18
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
/*
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
fprintf(stderr, ": %s: ", __func__); \
|
||||
fprintf(stderr, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
/* config register */
|
||||
#define R_CONFIG (0x00 / 4)
|
||||
|
|
|
@ -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__)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 \
|
||||
{\
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"]))
|
|
@ -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);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
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 @@ def __init__(self):
|
|||
coroutine.CoroutineCommand()
|
||||
mtree.MtreeCommand()
|
||||
aio.HandlersCommand()
|
||||
tcg.TCGLockStatusCommand()
|
||||
timers.TimersCommand()
|
||||
|
||||
coroutine.CoroutineSPFunction()
|
||||
coroutine.CoroutinePCFunction()
|
||||
|
|
|
@ -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))
|
|
@ -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")
|
14
scsi/utils.c
14
scsi/utils.c
|
@ -322,18 +322,18 @@ int scsi_convert_sense(uint8_t *in_buf, int in_len,
|
|||
SCSISense sense;
|
||||
bool fixed_in;
|
||||
|
||||
fixed_in = (in_buf[0] & 2) == 0;
|
||||
if (in_len && fixed == fixed_in) {
|
||||
memcpy(buf, in_buf, MIN(len, in_len));
|
||||
return MIN(len, in_len);
|
||||
if (in_len == 0) {
|
||||
return scsi_build_sense_buf(buf, len, SENSE_CODE(NO_SENSE), fixed);
|
||||
}
|
||||
|
||||
if (in_len == 0) {
|
||||
sense = SENSE_CODE(NO_SENSE);
|
||||
fixed_in = (in_buf[0] & 2) == 0;
|
||||
if (fixed == fixed_in) {
|
||||
memcpy(buf, in_buf, MIN(len, in_len));
|
||||
return MIN(len, in_len);
|
||||
} 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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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(...) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)"
|
||||
|
|
9
vl.c
9
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);
|
||||
|
|
Loading…
Reference in New Issue