mirror of https://github.com/xqemu/xqemu.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 \
|
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
|
||||||
html info pdf txt \
|
html info pdf txt \
|
||||||
help check-help \
|
help check-help print-% \
|
||||||
docker docker-% vm-test vm-build-%
|
docker docker-% vm-test vm-build-%
|
||||||
|
|
||||||
|
print-%:
|
||||||
|
@echo '$*=$($*)'
|
||||||
|
|
||||||
# All following code might depend on configuration variables
|
# All following code might depend on configuration variables
|
||||||
ifneq ($(wildcard config-host.mak),)
|
ifneq ($(wildcard config-host.mak),)
|
||||||
# Put the all: rule here so that config-host.mak can contain dependencies.
|
# Put the all: rule here so that config-host.mak can contain dependencies.
|
||||||
|
@ -277,7 +280,7 @@ else
|
||||||
DOCS=
|
DOCS=
|
||||||
endif
|
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=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
|
||||||
SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %-config-devices.mak.d, $(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; \
|
goto label; \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
|
#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -107,7 +107,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
|
||||||
} \
|
} \
|
||||||
goto label; \
|
goto label; \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
|
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;
|
uint64_t lba;
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
|
|
||||||
|
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
||||||
|
|
||||||
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
|
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -675,7 +677,6 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
|
||||||
|
|
||||||
lba = sector_qemu2lun(sector_num, iscsilun);
|
lba = sector_qemu2lun(sector_num, iscsilun);
|
||||||
|
|
||||||
iscsi_co_init_iscsitask(iscsilun, &iTask);
|
|
||||||
qemu_mutex_lock(&iscsilun->mutex);
|
qemu_mutex_lock(&iscsilun->mutex);
|
||||||
retry:
|
retry:
|
||||||
if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
|
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);
|
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);
|
g_source_unref(src);
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
|
|
|
@ -42,8 +42,8 @@ typedef struct {
|
||||||
|
|
||||||
/* Protected by the Chardev chr_write_lock. */
|
/* Protected by the Chardev chr_write_lock. */
|
||||||
int connected;
|
int connected;
|
||||||
guint timer_tag;
|
GSource *timer_src;
|
||||||
guint open_tag;
|
GSource *open_source;
|
||||||
} PtyChardev;
|
} PtyChardev;
|
||||||
|
|
||||||
#define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY)
|
#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);
|
PtyChardev *s = PTY_CHARDEV(opaque);
|
||||||
|
|
||||||
qemu_mutex_lock(&chr->chr_write_lock);
|
qemu_mutex_lock(&chr->chr_write_lock);
|
||||||
s->timer_tag = 0;
|
s->timer_src = NULL;
|
||||||
s->open_tag = 0;
|
g_source_unref(s->open_source);
|
||||||
|
s->open_source = NULL;
|
||||||
if (!s->connected) {
|
if (!s->connected) {
|
||||||
/* Next poll ... */
|
/* Next poll ... */
|
||||||
pty_chr_update_read_handler_locked(chr);
|
pty_chr_update_read_handler_locked(chr);
|
||||||
|
@ -67,25 +68,25 @@ static gboolean pty_chr_timer(gpointer opaque)
|
||||||
return FALSE;
|
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. */
|
/* Called with chr_write_lock held. */
|
||||||
static void pty_chr_rearm_timer(Chardev *chr, int ms)
|
static void pty_chr_rearm_timer(Chardev *chr, int ms)
|
||||||
{
|
{
|
||||||
PtyChardev *s = PTY_CHARDEV(chr);
|
PtyChardev *s = PTY_CHARDEV(chr);
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
if (s->timer_tag) {
|
pty_chr_timer_cancel(s);
|
||||||
g_source_remove(s->timer_tag);
|
name = g_strdup_printf("pty-timer-%s", chr->label);
|
||||||
s->timer_tag = 0;
|
s->timer_src = qemu_chr_timeout_add_ms(chr, ms, pty_chr_timer, chr);
|
||||||
}
|
g_source_set_name(s->timer_src, name);
|
||||||
|
|
||||||
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);
|
|
||||||
g_free(name);
|
g_free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +184,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
|
||||||
Chardev *chr = CHARDEV(opaque);
|
Chardev *chr = CHARDEV(opaque);
|
||||||
PtyChardev *s = PTY_CHARDEV(opaque);
|
PtyChardev *s = PTY_CHARDEV(opaque);
|
||||||
|
|
||||||
s->open_tag = 0;
|
s->open_source = NULL;
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -194,9 +195,10 @@ static void pty_chr_state(Chardev *chr, int connected)
|
||||||
PtyChardev *s = PTY_CHARDEV(chr);
|
PtyChardev *s = PTY_CHARDEV(chr);
|
||||||
|
|
||||||
if (!connected) {
|
if (!connected) {
|
||||||
if (s->open_tag) {
|
if (s->open_source) {
|
||||||
g_source_remove(s->open_tag);
|
g_source_destroy(s->open_source);
|
||||||
s->open_tag = 0;
|
g_source_unref(s->open_source);
|
||||||
|
s->open_source = NULL;
|
||||||
}
|
}
|
||||||
remove_fd_in_watch(chr);
|
remove_fd_in_watch(chr);
|
||||||
s->connected = 0;
|
s->connected = 0;
|
||||||
|
@ -205,14 +207,15 @@ static void pty_chr_state(Chardev *chr, int connected)
|
||||||
* the virtual device linked to our pty. */
|
* the virtual device linked to our pty. */
|
||||||
pty_chr_rearm_timer(chr, 1000);
|
pty_chr_rearm_timer(chr, 1000);
|
||||||
} else {
|
} else {
|
||||||
if (s->timer_tag) {
|
pty_chr_timer_cancel(s);
|
||||||
g_source_remove(s->timer_tag);
|
|
||||||
s->timer_tag = 0;
|
|
||||||
}
|
|
||||||
if (!s->connected) {
|
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->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) {
|
if (!chr->gsource) {
|
||||||
chr->gsource = io_add_watch_poll(chr, s->ioc,
|
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);
|
qemu_mutex_lock(&chr->chr_write_lock);
|
||||||
pty_chr_state(chr, 0);
|
pty_chr_state(chr, 0);
|
||||||
object_unref(OBJECT(s->ioc));
|
object_unref(OBJECT(s->ioc));
|
||||||
if (s->timer_tag) {
|
pty_chr_timer_cancel(s);
|
||||||
g_source_remove(s->timer_tag);
|
|
||||||
s->timer_tag = 0;
|
|
||||||
}
|
|
||||||
qemu_mutex_unlock(&chr->chr_write_lock);
|
qemu_mutex_unlock(&chr->chr_write_lock);
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
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);
|
name = g_strdup_printf("chardev-pty-%s", chr->label);
|
||||||
qio_channel_set_name(QIO_CHANNEL(s->ioc), name);
|
qio_channel_set_name(QIO_CHANNEL(s->ioc), name);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
s->timer_tag = 0;
|
s->timer_src = NULL;
|
||||||
*be_opened = false;
|
*be_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,9 +64,13 @@ static void tty_serial_init(int fd, int speed,
|
||||||
#endif
|
#endif
|
||||||
tcgetattr(fd, &tty);
|
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;
|
speed = speed * 10 / 11;
|
||||||
do {
|
|
||||||
check_speed(50);
|
check_speed(50);
|
||||||
check_speed(75);
|
check_speed(75);
|
||||||
check_speed(110);
|
check_speed(110);
|
||||||
|
@ -125,8 +129,9 @@ static void tty_serial_init(int fd, int speed,
|
||||||
check_speed(4000000);
|
check_speed(4000000);
|
||||||
#endif
|
#endif
|
||||||
spd = B115200;
|
spd = B115200;
|
||||||
} while (0);
|
|
||||||
|
|
||||||
|
#undef check_speed
|
||||||
|
done:
|
||||||
cfsetispeed(&tty, spd);
|
cfsetispeed(&tty, spd);
|
||||||
cfsetospeed(&tty, spd);
|
cfsetospeed(&tty, spd);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ typedef struct {
|
||||||
bool is_telnet;
|
bool is_telnet;
|
||||||
bool is_tn3270;
|
bool is_tn3270;
|
||||||
|
|
||||||
guint reconnect_timer;
|
GSource *reconnect_timer;
|
||||||
int64_t reconnect_time;
|
int64_t reconnect_time;
|
||||||
bool connect_err_reported;
|
bool connect_err_reported;
|
||||||
} SocketChardev;
|
} SocketChardev;
|
||||||
|
@ -67,16 +67,27 @@ typedef struct {
|
||||||
|
|
||||||
static gboolean socket_reconnect_timeout(gpointer opaque);
|
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)
|
static void qemu_chr_socket_restart_timer(Chardev *chr)
|
||||||
{
|
{
|
||||||
SocketChardev *s = SOCKET_CHARDEV(chr);
|
SocketChardev *s = SOCKET_CHARDEV(chr);
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
assert(s->connected == 0);
|
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);
|
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);
|
g_free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,11 +792,7 @@ static void char_socket_finalize(Object *obj)
|
||||||
SocketChardev *s = SOCKET_CHARDEV(obj);
|
SocketChardev *s = SOCKET_CHARDEV(obj);
|
||||||
|
|
||||||
tcp_chr_free_connection(chr);
|
tcp_chr_free_connection(chr);
|
||||||
|
tcp_chr_reconn_timer_cancel(s);
|
||||||
if (s->reconnect_timer) {
|
|
||||||
g_source_remove(s->reconnect_timer);
|
|
||||||
s->reconnect_timer = 0;
|
|
||||||
}
|
|
||||||
qapi_free_SocketAddress(s->addr);
|
qapi_free_SocketAddress(s->addr);
|
||||||
if (s->listener) {
|
if (s->listener) {
|
||||||
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
|
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);
|
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
||||||
QIOChannelSocket *sioc;
|
QIOChannelSocket *sioc;
|
||||||
|
|
||||||
s->reconnect_timer = 0;
|
g_source_unref(s->reconnect_timer);
|
||||||
|
s->reconnect_timer = NULL;
|
||||||
|
|
||||||
if (chr->be_open) {
|
if (chr->be_open) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1084,6 +1084,24 @@ void qmp_chardev_send_break(const char *id, Error **errp)
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_BREAK);
|
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)
|
void qemu_chr_cleanup(void)
|
||||||
{
|
{
|
||||||
object_unparent(get_chardevs_root());
|
object_unparent(get_chardevs_root());
|
||||||
|
|
|
@ -3464,6 +3464,7 @@ else
|
||||||
done
|
done
|
||||||
if test "$found" = "no"; then
|
if test "$found" = "no"; then
|
||||||
LIBS="$pthread_lib $LIBS"
|
LIBS="$pthread_lib $LIBS"
|
||||||
|
libs_qga="$pthread_lib $libs_qga"
|
||||||
fi
|
fi
|
||||||
PTHREAD_LIB="$pthread_lib"
|
PTHREAD_LIB="$pthread_lib"
|
||||||
break
|
break
|
||||||
|
@ -5193,7 +5194,18 @@ if test "$gcov" = "yes" ; then
|
||||||
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
|
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
|
||||||
elif test "$fortify_source" = "yes" ; then
|
elif test "$fortify_source" = "yes" ; then
|
||||||
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
|
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
|
||||||
elif test "$debug" = "no"; then
|
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"
|
CFLAGS="-O2 $CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
134
cpus.c
134
cpus.c
|
@ -120,16 +120,11 @@ static bool all_cpu_threads_idle(void)
|
||||||
/* Protected by TimersState seqlock */
|
/* Protected by TimersState seqlock */
|
||||||
|
|
||||||
static bool icount_sleep = true;
|
static bool icount_sleep = true;
|
||||||
static int64_t vm_clock_warp_start = -1;
|
|
||||||
/* Conversion factor from emulated instructions to virtual clock ticks. */
|
/* Conversion factor from emulated instructions to virtual clock ticks. */
|
||||||
static int icount_time_shift;
|
static int icount_time_shift;
|
||||||
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
|
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
|
||||||
#define MAX_ICOUNT_SHIFT 10
|
#define MAX_ICOUNT_SHIFT 10
|
||||||
|
|
||||||
static QEMUTimer *icount_rt_timer;
|
|
||||||
static QEMUTimer *icount_vm_timer;
|
|
||||||
static QEMUTimer *icount_warp_timer;
|
|
||||||
|
|
||||||
typedef struct TimersState {
|
typedef struct TimersState {
|
||||||
/* Protected by BQL. */
|
/* Protected by BQL. */
|
||||||
int64_t cpu_ticks_prev;
|
int64_t cpu_ticks_prev;
|
||||||
|
@ -147,6 +142,11 @@ typedef struct TimersState {
|
||||||
int64_t qemu_icount_bias;
|
int64_t qemu_icount_bias;
|
||||||
/* Only written by TCG thread */
|
/* Only written by TCG thread */
|
||||||
int64_t qemu_icount;
|
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;
|
} TimersState;
|
||||||
|
|
||||||
static TimersState timers_state;
|
static TimersState timers_state;
|
||||||
|
@ -432,14 +432,14 @@ static void icount_adjust(void)
|
||||||
|
|
||||||
static void icount_adjust_rt(void *opaque)
|
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);
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
|
||||||
icount_adjust();
|
icount_adjust();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void icount_adjust_vm(void *opaque)
|
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) +
|
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||||
NANOSECONDS_PER_SECOND / 10);
|
NANOSECONDS_PER_SECOND / 10);
|
||||||
icount_adjust();
|
icount_adjust();
|
||||||
|
@ -460,7 +460,7 @@ static void icount_warp_rt(void)
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
|
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));
|
} while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
|
||||||
|
|
||||||
if (warp_start == -1) {
|
if (warp_start == -1) {
|
||||||
|
@ -473,7 +473,7 @@ static void icount_warp_rt(void)
|
||||||
cpu_get_clock_locked());
|
cpu_get_clock_locked());
|
||||||
int64_t warp_delta;
|
int64_t warp_delta;
|
||||||
|
|
||||||
warp_delta = clock - vm_clock_warp_start;
|
warp_delta = clock - timers_state.vm_clock_warp_start;
|
||||||
if (use_icount == 2) {
|
if (use_icount == 2) {
|
||||||
/*
|
/*
|
||||||
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
|
* 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;
|
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);
|
seqlock_write_end(&timers_state.vm_clock_seqlock);
|
||||||
|
|
||||||
if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
|
if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
|
||||||
|
@ -594,11 +594,13 @@ void qemu_start_warp_timer(void)
|
||||||
* every 100ms.
|
* every 100ms.
|
||||||
*/
|
*/
|
||||||
seqlock_write_begin(&timers_state.vm_clock_seqlock);
|
seqlock_write_begin(&timers_state.vm_clock_seqlock);
|
||||||
if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
|
if (timers_state.vm_clock_warp_start == -1
|
||||||
vm_clock_warp_start = clock;
|
|| timers_state.vm_clock_warp_start > clock) {
|
||||||
|
timers_state.vm_clock_warp_start = clock;
|
||||||
}
|
}
|
||||||
seqlock_write_end(&timers_state.vm_clock_seqlock);
|
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) {
|
} else if (deadline == 0) {
|
||||||
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
||||||
|
@ -623,7 +625,7 @@ static void qemu_account_warp_timer(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_del(icount_warp_timer);
|
timer_del(timers_state.icount_warp_timer);
|
||||||
icount_warp_rt();
|
icount_warp_rt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +634,45 @@ static bool icount_state_needed(void *opaque)
|
||||||
return use_icount;
|
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.
|
* 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_bias, TimersState),
|
||||||
VMSTATE_INT64(qemu_icount, TimersState),
|
VMSTATE_INT64(qemu_icount, TimersState),
|
||||||
VMSTATE_END_OF_LIST()
|
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);
|
icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
|
||||||
if (icount_sleep) {
|
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);
|
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.
|
the virtual time trigger catches emulated time passing too fast.
|
||||||
Realtime triggers occur even when idle, so use them less frequently
|
Realtime triggers occur even when idle, so use them less frequently
|
||||||
than VM triggers. */
|
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);
|
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);
|
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);
|
icount_adjust_vm, NULL);
|
||||||
timer_mod(icount_vm_timer,
|
timer_mod(timers_state.icount_vm_timer,
|
||||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||||
NANOSECONDS_PER_SECOND / 10);
|
NANOSECONDS_PER_SECOND / 10);
|
||||||
}
|
}
|
||||||
|
@ -862,7 +909,8 @@ static void kick_tcg_thread(void *opaque)
|
||||||
|
|
||||||
static void start_tcg_kick_timer(void)
|
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,
|
tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||||
kick_tcg_thread, NULL);
|
kick_tcg_thread, NULL);
|
||||||
timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
|
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)
|
static void stop_tcg_kick_timer(void)
|
||||||
{
|
{
|
||||||
|
assert(!mttcg_enabled);
|
||||||
if (tcg_kick_vcpu_timer) {
|
if (tcg_kick_vcpu_timer) {
|
||||||
timer_del(tcg_kick_vcpu_timer);
|
timer_del(tcg_kick_vcpu_timer);
|
||||||
tcg_kick_vcpu_timer = NULL;
|
tcg_kick_vcpu_timer = NULL;
|
||||||
|
@ -1090,18 +1139,9 @@ static void qemu_wait_io_event_common(CPUState *cpu)
|
||||||
process_queued_cpu_work(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) {
|
while (all_cpu_threads_idle()) {
|
||||||
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)) {
|
|
||||||
stop_tcg_kick_timer();
|
stop_tcg_kick_timer();
|
||||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
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);
|
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)) {
|
while (cpu_thread_is_idle(cpu)) {
|
||||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_wait_io_event_common(cpu);
|
#ifdef _WIN32
|
||||||
}
|
/* Eat dummy APC queued by qemu_cpu_kick_thread. */
|
||||||
|
if (!tcg_enabled()) {
|
||||||
static void qemu_hvf_wait_io_event(CPUState *cpu)
|
SleepEx(0, TRUE);
|
||||||
{
|
|
||||||
while (cpu_thread_is_idle(cpu)) {
|
|
||||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
qemu_wait_io_event_common(cpu);
|
qemu_wait_io_event_common(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1160,7 +1198,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
|
||||||
cpu_handle_guest_debug(cpu);
|
cpu_handle_guest_debug(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qemu_kvm_wait_io_event(cpu);
|
qemu_wait_io_event(cpu);
|
||||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||||
|
|
||||||
qemu_kvm_destroy_vcpu(cpu);
|
qemu_kvm_destroy_vcpu(cpu);
|
||||||
|
@ -1206,7 +1244,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
qemu_wait_io_event_common(cpu);
|
qemu_wait_io_event(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1423,7 +1461,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
|
||||||
atomic_mb_set(&cpu->exit_request, 0);
|
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();
|
deal_with_unplugged_cpus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1454,13 +1492,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cpu_thread_is_idle(cpu)) {
|
qemu_wait_io_event(cpu);
|
||||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
|
||||||
}
|
|
||||||
#ifdef _WIN32
|
|
||||||
SleepEx(0, TRUE);
|
|
||||||
#endif
|
|
||||||
qemu_wait_io_event_common(cpu);
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1497,7 +1529,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
|
||||||
cpu_handle_guest_debug(cpu);
|
cpu_handle_guest_debug(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qemu_hvf_wait_io_event(cpu);
|
qemu_wait_io_event(cpu);
|
||||||
} while (!cpu->unplug || cpu_can_run(cpu));
|
} while (!cpu->unplug || cpu_can_run(cpu));
|
||||||
|
|
||||||
hvf_vcpu_destroy(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);
|
atomic_mb_set(&cpu->exit_request, 0);
|
||||||
qemu_tcg_wait_io_event(cpu);
|
qemu_wait_io_event(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -79,7 +79,7 @@ static int qcrypto_ivgen_essiv_calculate(QCryptoIVGen *ivgen,
|
||||||
uint8_t *data = g_new(uint8_t, ndata);
|
uint8_t *data = g_new(uint8_t, ndata);
|
||||||
|
|
||||||
sector = cpu_to_le64(sector);
|
sector = cpu_to_le64(sector);
|
||||||
memcpy(data, (uint8_t *)§or, ndata);
|
memcpy(data, (uint8_t *)§or, MIN(sizeof(sector), ndata));
|
||||||
if (sizeof(sector) < ndata) {
|
if (sizeof(sector) < ndata) {
|
||||||
memset(data + sizeof(sector), 0, ndata - sizeof(sector));
|
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
|
static void
|
||||||
init_disasm (struct disassemble_info *info)
|
init_disasm (struct disassemble_info *info)
|
||||||
{
|
{
|
||||||
const struct s390_opcode *opcode;
|
int i;
|
||||||
const struct s390_opcode *opcode_end;
|
|
||||||
|
|
||||||
memset (opc_index, 0, sizeof (opc_index));
|
memset (opc_index, 0, sizeof (opc_index));
|
||||||
opcode_end = s390_opcodes + s390_num_opcodes;
|
|
||||||
for (opcode = s390_opcodes; opcode < opcode_end; opcode++)
|
/* Reverse order, such that each opc_index ends up pointing to the
|
||||||
{
|
first matching entry instead of the last. */
|
||||||
opc_index[(int) opcode->opcode[0]] = opcode - s390_opcodes;
|
for (i = s390_num_opcodes; i--; )
|
||||||
while ((opcode < opcode_end) &&
|
opc_index[s390_opcodes[i].opcode[0]] = i;
|
||||||
(opcode[1].opcode[0] == opcode->opcode[0]))
|
|
||||||
opcode++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef QEMU_DISABLE
|
#ifdef QEMU_DISABLE
|
||||||
switch (info->mach)
|
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
|
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
|
or userspace emulator target. It is merely a symlink back to the
|
||||||
Makefile.target in the top level.
|
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;
|
cpu->interrupt_request &= ~0x01;
|
||||||
tlb_flush(cpu);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,7 +1667,10 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static ram_addr_t find_ram_offset(ram_addr_t size)
|
||||||
{
|
{
|
||||||
RAMBlock *block, *next_block;
|
RAMBlock *block, *next_block;
|
||||||
|
@ -1673,19 +1683,33 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
RAMBLOCK_FOREACH(block) {
|
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) {
|
RAMBLOCK_FOREACH(next_block) {
|
||||||
if (next_block->offset >= end) {
|
if (next_block->offset >= candidate) {
|
||||||
next = MIN(next, next_block->offset);
|
next = MIN(next, next_block->offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (next - end >= size && next - end < mingap) {
|
|
||||||
offset = end;
|
/* If it fits remember our place and remember the size
|
||||||
mingap = next - end;
|
* 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) {
|
if (offset == RAM_ADDR_MAX) {
|
||||||
|
@ -1694,6 +1718,8 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace_find_ram_offset(size, offset);
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
if (STM_ADC_ERR_DEBUG >= lvl) { \
|
if (STM_ADC_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/* Fields for FlashPartInfo->flags */
|
/* Fields for FlashPartInfo->flags */
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define DB_PRINT(...) do { \
|
#define DB_PRINT(...) do { \
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} while (0);
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DB_PRINT(...)
|
#define DB_PRINT(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
if (STM_USART_ERR_DEBUG >= lvl) { \
|
if (STM_USART_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ typedef struct Terminal3270 {
|
||||||
uint8_t outv[OUTPUT_BUFFER_SIZE];
|
uint8_t outv[OUTPUT_BUFFER_SIZE];
|
||||||
int in_len;
|
int in_len;
|
||||||
bool handshake_done;
|
bool handshake_done;
|
||||||
guint timer_tag;
|
GSource *timer_src;
|
||||||
} Terminal3270;
|
} Terminal3270;
|
||||||
|
|
||||||
#define TYPE_TERMINAL_3270 "x-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;
|
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,
|
* Protocol handshake done,
|
||||||
* signal guest by an unsolicited DE irq.
|
* 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));
|
assert(size <= (INPUT_BUFFER_SIZE - t->in_len));
|
||||||
|
|
||||||
if (t->timer_tag) {
|
terminal_timer_cancel(t);
|
||||||
g_source_remove(t->timer_tag);
|
t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
|
||||||
t->timer_tag = 0;
|
send_timing_mark_cb, t);
|
||||||
}
|
|
||||||
t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
|
|
||||||
|
|
||||||
memcpy(&t->inv[t->in_len], buf, size);
|
memcpy(&t->inv[t->in_len], buf, size);
|
||||||
t->in_len += size;
|
t->in_len += size;
|
||||||
if (t->in_len < 2) {
|
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. */
|
/* Ensure the initial status correct, always reset them. */
|
||||||
t->in_len = 0;
|
t->in_len = 0;
|
||||||
t->handshake_done = false;
|
t->handshake_done = false;
|
||||||
if (t->timer_tag) {
|
terminal_timer_cancel(t);
|
||||||
g_source_remove(t->timer_tag);
|
|
||||||
t->timer_tag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case CHR_EVENT_OPENED:
|
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
|
* char-socket.c. Once qemu receives the terminal-type of the
|
||||||
* client, mark handshake done and trigger everything rolling again.
|
* 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;
|
break;
|
||||||
case CHR_EVENT_CLOSED:
|
case CHR_EVENT_CLOSED:
|
||||||
sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
|
sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
if (DEBUG_CG3) { \
|
if (DEBUG_CG3) { \
|
||||||
printf("CG3: " fmt , ## __VA_ARGS__); \
|
printf("CG3: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define TYPE_CG3 "cgthree"
|
#define TYPE_CG3 "cgthree"
|
||||||
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
|
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
if (DEBUG_DPCD) { \
|
if (DEBUG_DPCD) { \
|
||||||
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
|
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DPCD_READABLE_AREA 0x600
|
#define DPCD_READABLE_AREA 0x600
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
if (DEBUG_DP) { \
|
if (DEBUG_DP) { \
|
||||||
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
|
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register offset for DP.
|
* Register offset for DP.
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
if (PL330_ERR_DEBUG >= lvl) {\
|
if (PL330_ERR_DEBUG >= lvl) {\
|
||||||
fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
|
fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
|
if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
REG32(CTRL, 0x00)
|
REG32(CTRL, 0x00)
|
||||||
FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
|
FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
if (DEBUG_DPDMA) { \
|
if (DEBUG_DPDMA) { \
|
||||||
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
|
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Registers offset for DPDMA.
|
* Registers offset for DPDMA.
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
if (DEBUG_I2CDDC) { \
|
if (DEBUG_I2CDDC) { \
|
||||||
qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
|
qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/* Structure defining a monitor's characteristics in a
|
/* Structure defining a monitor's characteristics in a
|
||||||
* readable format: this should be passed to build_edid_blob()
|
* 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);
|
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,
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1729,9 +1734,14 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
|
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,
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
if (DEBUG_AUX) { \
|
if (DEBUG_AUX) { \
|
||||||
qemu_log("aux: " fmt , ## __VA_ARGS__); \
|
qemu_log("aux: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
|
#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
|
||||||
#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
|
#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
if (DEBUG_DBDMA) { \
|
if (DEBUG_DBDMA) { \
|
||||||
printf("DBDMA: " fmt , ## __VA_ARGS__); \
|
printf("DBDMA: " fmt , ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
|
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
|
||||||
if (DEBUG_DBDMA) { \
|
if (DEBUG_DBDMA) { \
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
|
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) { \
|
if (DEBUG_MMIO_INTERFACE) { \
|
||||||
qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
|
qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
static void mmio_interface_init(Object *obj)
|
static void mmio_interface_init(Object *obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
|
if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define XILINX_LOCK_KEY 0x767b
|
#define XILINX_LOCK_KEY 0x767b
|
||||||
#define XILINX_UNLOCK_KEY 0xdf0d
|
#define XILINX_UNLOCK_KEY 0xdf0d
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#define DB_PRINT(...) do { \
|
#define DB_PRINT(...) do { \
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} while (0);
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DB_PRINT(...)
|
#define DB_PRINT(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -456,32 +456,32 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
|
||||||
#define CHECK_RMD(ADDR,RES) do { \
|
#define CHECK_RMD(ADDR,RES) do { \
|
||||||
switch (BCR_SWSTYLE(s)) { \
|
switch (BCR_SWSTYLE(s)) { \
|
||||||
case 0x00: \
|
case 0x00: \
|
||||||
do { \
|
{ \
|
||||||
uint16_t rda[4]; \
|
uint16_t rda[4]; \
|
||||||
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
||||||
(void *)&rda[0], sizeof(rda), 0); \
|
(void *)&rda[0], sizeof(rda), 0); \
|
||||||
(RES) |= (rda[2] & 0xf000)!=0xf000; \
|
(RES) |= (rda[2] & 0xf000)!=0xf000; \
|
||||||
(RES) |= (rda[3] & 0xf000)!=0x0000; \
|
(RES) |= (rda[3] & 0xf000)!=0x0000; \
|
||||||
} while (0); \
|
} \
|
||||||
break; \
|
break; \
|
||||||
case 0x01: \
|
case 0x01: \
|
||||||
case 0x02: \
|
case 0x02: \
|
||||||
do { \
|
{ \
|
||||||
uint32_t rda[4]; \
|
uint32_t rda[4]; \
|
||||||
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
||||||
(void *)&rda[0], sizeof(rda), 0); \
|
(void *)&rda[0], sizeof(rda), 0); \
|
||||||
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||||
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
|
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
|
||||||
} while (0); \
|
} \
|
||||||
break; \
|
break; \
|
||||||
case 0x03: \
|
case 0x03: \
|
||||||
do { \
|
{ \
|
||||||
uint32_t rda[4]; \
|
uint32_t rda[4]; \
|
||||||
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
||||||
(void *)&rda[0], sizeof(rda), 0); \
|
(void *)&rda[0], sizeof(rda), 0); \
|
||||||
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
|
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
|
||||||
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||||
} while (0); \
|
} \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -489,22 +489,22 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
|
||||||
#define CHECK_TMD(ADDR,RES) do { \
|
#define CHECK_TMD(ADDR,RES) do { \
|
||||||
switch (BCR_SWSTYLE(s)) { \
|
switch (BCR_SWSTYLE(s)) { \
|
||||||
case 0x00: \
|
case 0x00: \
|
||||||
do { \
|
{ \
|
||||||
uint16_t xda[4]; \
|
uint16_t xda[4]; \
|
||||||
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
||||||
(void *)&xda[0], sizeof(xda), 0); \
|
(void *)&xda[0], sizeof(xda), 0); \
|
||||||
(RES) |= (xda[2] & 0xf000)!=0xf000; \
|
(RES) |= (xda[2] & 0xf000)!=0xf000; \
|
||||||
} while (0); \
|
} \
|
||||||
break; \
|
break; \
|
||||||
case 0x01: \
|
case 0x01: \
|
||||||
case 0x02: \
|
case 0x02: \
|
||||||
case 0x03: \
|
case 0x03: \
|
||||||
do { \
|
{ \
|
||||||
uint32_t xda[4]; \
|
uint32_t xda[4]; \
|
||||||
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
s->phys_mem_read(s->dma_opaque, (ADDR), \
|
||||||
(void *)&xda[0], sizeof(xda), 0); \
|
(void *)&xda[0], sizeof(xda), 0); \
|
||||||
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
|
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
|
||||||
} while (0); \
|
} \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
@ -80,7 +80,7 @@ static int nvram_post_load(void *opaque, int version_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write back nvram contents */
|
/* Write back nvram contents */
|
||||||
s->file = fopen(s->filename, "wb");
|
s->file = s->filename ? fopen(s->filename, "wb") : NULL;
|
||||||
if (s->file) {
|
if (s->file) {
|
||||||
/* Write back contents, as 'wb' mode cleaned the file */
|
/* Write back contents, as 'wb' mode cleaned the file */
|
||||||
if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
|
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);
|
sysbus_init_mmio(dev, &s->iomem);
|
||||||
|
|
||||||
/* Read current file */
|
/* Read current file */
|
||||||
file = fopen(s->filename, "rb");
|
file = s->filename ? fopen(s->filename, "rb") : NULL;
|
||||||
if (file) {
|
if (file) {
|
||||||
/* Read nvram contents */
|
/* Read nvram contents */
|
||||||
if (fread(s->contents, s->chip_size, 1, file) != 1) {
|
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->sector << BDRV_SECTOR_BITS,
|
||||||
&data->qiov, 0,
|
&data->qiov, 0,
|
||||||
scsi_write_same_complete, data);
|
scsi_write_same_complete, data);
|
||||||
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,6 +482,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
|
||||||
int rc;
|
int rc;
|
||||||
int sg_version;
|
int sg_version;
|
||||||
struct sg_scsi_id scsiid;
|
struct sg_scsi_id scsiid;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (!s->conf.blk) {
|
if (!s->conf.blk) {
|
||||||
error_setg(errp, "drive property not set");
|
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");
|
error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
|
||||||
return;
|
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 */
|
/* define device state */
|
||||||
s->type = scsiid.scsi_type;
|
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[] = {
|
static Property scsi_generic_properties[] = {
|
||||||
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
|
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
|
||||||
|
DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
if (MSS_SPI_ERR_DEBUG >= lvl) { \
|
if (MSS_SPI_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt "\n", __func__, ## args); \
|
qemu_log("%s: " fmt "\n", __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
if (STM_SPI_ERR_DEBUG >= lvl) { \
|
if (STM_SPI_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#define DB_PRINT(...) do { \
|
#define DB_PRINT(...) do { \
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} while (0);
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DB_PRINT(...)
|
#define DB_PRINT(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/* config register */
|
/* config register */
|
||||||
#define R_CONFIG (0x00 / 4)
|
#define R_CONFIG (0x00 / 4)
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
|
#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define DB_PRINT(...) do { \
|
#define DB_PRINT(...) do { \
|
||||||
fprintf(stderr, ": %s: ", __func__); \
|
fprintf(stderr, ": %s: ", __func__); \
|
||||||
fprintf(stderr, ## __VA_ARGS__); \
|
fprintf(stderr, ## __VA_ARGS__); \
|
||||||
} while (0);
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DB_PRINT(...)
|
#define DB_PRINT(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,6 +70,7 @@ typedef struct HPETState {
|
||||||
|
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
uint64_t hpet_offset;
|
uint64_t hpet_offset;
|
||||||
|
bool hpet_offset_saved;
|
||||||
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
|
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint8_t rtc_irq_level;
|
uint8_t rtc_irq_level;
|
||||||
|
@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque)
|
||||||
HPETState *s = opaque;
|
HPETState *s = opaque;
|
||||||
|
|
||||||
/* save current counter value */
|
/* save current counter value */
|
||||||
|
if (hpet_enabled(s)) {
|
||||||
s->hpet_counter = hpet_get_ticks(s);
|
s->hpet_counter = hpet_get_ticks(s);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +255,10 @@ static int hpet_post_load(void *opaque, int version_id)
|
||||||
HPETState *s = opaque;
|
HPETState *s = opaque;
|
||||||
|
|
||||||
/* Recalculate the offset between the main counter and guest time */
|
/* 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 */
|
/* Push number of timers into capability returned via HPET_ID */
|
||||||
s->capability &= ~HPET_ID_NUM_TIM_MASK;
|
s->capability &= ~HPET_ID_NUM_TIM_MASK;
|
||||||
|
@ -267,6 +273,13 @@ static int hpet_post_load(void *opaque, int version_id)
|
||||||
return 0;
|
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)
|
static bool hpet_rtc_irq_level_needed(void *opaque)
|
||||||
{
|
{
|
||||||
HPETState *s = 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 = {
|
static const VMStateDescription vmstate_hpet_timer = {
|
||||||
.name = "hpet_timer",
|
.name = "hpet_timer",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
|
@ -320,6 +344,7 @@ static const VMStateDescription vmstate_hpet = {
|
||||||
},
|
},
|
||||||
.subsections = (const VMStateDescription*[]) {
|
.subsections = (const VMStateDescription*[]) {
|
||||||
&vmstate_hpet_rtc_irq_level,
|
&vmstate_hpet_rtc_irq_level,
|
||||||
|
&vmstate_hpet_offset,
|
||||||
NULL
|
NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -762,6 +787,7 @@ static Property hpet_device_properties[] = {
|
||||||
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
|
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
|
||||||
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
|
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
|
||||||
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
|
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
|
||||||
|
DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
if (MSS_TIMER_ERR_DEBUG >= lvl) { \
|
if (MSS_TIMER_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt "\n", __func__, ## args); \
|
qemu_log("%s: " fmt "\n", __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
if (STM_TIMER_ERR_DEBUG >= lvl) { \
|
if (STM_TIMER_ERR_DEBUG >= lvl) { \
|
||||||
qemu_log("%s: " fmt, __func__, ## args); \
|
qemu_log("%s: " fmt, __func__, ## args); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
if (DEBUG_TPM) { \
|
if (DEBUG_TPM) { \
|
||||||
fprintf(stderr, fmt, ## __VA_ARGS__); \
|
fprintf(stderr, fmt, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
|
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
|
||||||
#define TPM_PASSTHROUGH(obj) \
|
#define TPM_PASSTHROUGH(obj) \
|
||||||
|
|
|
@ -90,7 +90,7 @@ typedef struct TPMState {
|
||||||
if (DEBUG_TIS) { \
|
if (DEBUG_TIS) { \
|
||||||
printf(fmt, ## __VA_ARGS__); \
|
printf(fmt, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/* tis registers */
|
/* tis registers */
|
||||||
#define TPM_TIS_REG_ACCESS 0x00
|
#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;
|
extern int term_escape_char;
|
||||||
|
|
||||||
|
GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
|
||||||
|
GSourceFunc func, void *private);
|
||||||
|
|
||||||
/* console.c */
|
/* console.c */
|
||||||
void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);
|
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;
|
uint64_t num_dirty = 0;
|
||||||
unsigned long *dest = rb->bmap;
|
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) ==
|
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 k;
|
||||||
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
|
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
|
||||||
unsigned long * const *src;
|
unsigned long * const *src;
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
#define HW_COMPAT_H
|
#define HW_COMPAT_H
|
||||||
|
|
||||||
#define HW_COMPAT_2_11 \
|
#define HW_COMPAT_2_11 \
|
||||||
/* empty */
|
{\
|
||||||
|
.driver = "hpet",\
|
||||||
|
.property = "hpet-offset-saved",\
|
||||||
|
.value = "false",\
|
||||||
|
},
|
||||||
|
|
||||||
#define HW_COMPAT_2_10 \
|
#define HW_COMPAT_2_10 \
|
||||||
{\
|
{\
|
||||||
|
|
|
@ -59,5 +59,6 @@ ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
|
||||||
ReadLineFlushFunc *flush_func,
|
ReadLineFlushFunc *flush_func,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
ReadLineCompletionFunc *completion_finder);
|
ReadLineCompletionFunc *completion_finder);
|
||||||
|
void readline_free(ReadLineState *rs);
|
||||||
|
|
||||||
#endif /* READLINE_H */
|
#endif /* READLINE_H */
|
||||||
|
|
|
@ -22,9 +22,31 @@ typedef struct QemuThread QemuThread;
|
||||||
|
|
||||||
void qemu_mutex_init(QemuMutex *mutex);
|
void qemu_mutex_init(QemuMutex *mutex);
|
||||||
void qemu_mutex_destroy(QemuMutex *mutex);
|
void qemu_mutex_destroy(QemuMutex *mutex);
|
||||||
void qemu_mutex_lock(QemuMutex *mutex);
|
int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
|
||||||
int qemu_mutex_trylock(QemuMutex *mutex);
|
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
|
||||||
void qemu_mutex_unlock(QemuMutex *mutex);
|
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. */
|
/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */
|
||||||
void qemu_rec_mutex_init(QemuRecMutex *mutex);
|
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_signal(QemuCond *cond);
|
||||||
void qemu_cond_broadcast(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_init(QemuSemaphore *sem, int init);
|
||||||
void qemu_sem_post(QemuSemaphore *sem);
|
void qemu_sem_post(QemuSemaphore *sem);
|
||||||
|
|
|
@ -88,7 +88,7 @@ static uint32_t known_capabilities = RDMA_CAPABILITY_PIN_ALL;
|
||||||
} \
|
} \
|
||||||
return rdma->error_state; \
|
return rdma->error_state; \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A work request ID is 64-bits and we split up these bits
|
* 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)) {
|
if (monitor_is_qmp(mon)) {
|
||||||
json_message_parser_destroy(&mon->qmp.parser);
|
json_message_parser_destroy(&mon->qmp.parser);
|
||||||
}
|
}
|
||||||
g_free(mon->rs);
|
readline_free(mon->rs);
|
||||||
QDECREF(mon->outbuf);
|
QDECREF(mon->outbuf);
|
||||||
qemu_mutex_destroy(&mon->out_lock);
|
qemu_mutex_destroy(&mon->out_lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,8 @@ modules:
|
||||||
# If called with only a single argument, will print nothing in quiet mode.
|
# 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))
|
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1))
|
||||||
|
|
||||||
|
MAKEFLAGS += $(if $(V),,--no-print-directory --quiet)
|
||||||
|
|
||||||
# cc-option
|
# cc-option
|
||||||
# Usage: CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
|
# 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.
|
# Check relative indent for conditionals and blocks.
|
||||||
if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
|
if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
|
||||||
my ($s, $c) = ($stat, $cond);
|
my ($s, $c) = ($stat, $cond);
|
||||||
|
|
|
@ -26,7 +26,7 @@ import os, sys
|
||||||
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
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):
|
class QemuCommand(gdb.Command):
|
||||||
'''Prefix for QEMU debug support commands'''
|
'''Prefix for QEMU debug support commands'''
|
||||||
|
@ -38,6 +38,8 @@ QemuCommand()
|
||||||
coroutine.CoroutineCommand()
|
coroutine.CoroutineCommand()
|
||||||
mtree.MtreeCommand()
|
mtree.MtreeCommand()
|
||||||
aio.HandlersCommand()
|
aio.HandlersCommand()
|
||||||
|
tcg.TCGLockStatusCommand()
|
||||||
|
timers.TimersCommand()
|
||||||
|
|
||||||
coroutine.CoroutineSPFunction()
|
coroutine.CoroutineSPFunction()
|
||||||
coroutine.CoroutinePCFunction()
|
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,19 +322,19 @@ int scsi_convert_sense(uint8_t *in_buf, int in_len,
|
||||||
SCSISense sense;
|
SCSISense sense;
|
||||||
bool fixed_in;
|
bool fixed_in;
|
||||||
|
|
||||||
fixed_in = (in_buf[0] & 2) == 0;
|
if (in_len == 0) {
|
||||||
if (in_len && fixed == fixed_in) {
|
return scsi_build_sense_buf(buf, len, SENSE_CODE(NO_SENSE), fixed);
|
||||||
memcpy(buf, in_buf, MIN(len, in_len));
|
|
||||||
return MIN(len, in_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_len == 0) {
|
fixed_in = (in_buf[0] & 2) == 0;
|
||||||
sense = SENSE_CODE(NO_SENSE);
|
if (fixed == fixed_in) {
|
||||||
|
memcpy(buf, in_buf, MIN(len, in_len));
|
||||||
|
return MIN(len, in_len);
|
||||||
} else {
|
} else {
|
||||||
sense = scsi_parse_sense_buf(in_buf, in_len);
|
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)
|
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", \
|
"at pc=%016" PRIx64 "\n", \
|
||||||
__FILE__, __LINE__, insn, s->pc - 4); \
|
__FILE__, __LINE__, insn, s->pc - 4); \
|
||||||
unallocated_encoding(s); \
|
unallocated_encoding(s); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
static void init_tmp_a64_array(DisasContext *s)
|
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;
|
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[] = {
|
static Property x86_cpu_properties[] = {
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
/* apic_id = 0 by default for *-user, see commit 9886e834 */
|
/* 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_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
|
||||||
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
|
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
|
||||||
|
void x86_update_hflags(CPUX86State* env);
|
||||||
|
|
||||||
#endif /* I386_CPU_H */
|
#endif /* I386_CPU_H */
|
||||||
|
|
|
@ -782,56 +782,6 @@ static int hax_set_segments(CPUArchState *env, struct vcpu_state_t *sregs)
|
||||||
return 0;
|
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)
|
static int hax_sync_vcpu_register(CPUArchState *env, int set)
|
||||||
{
|
{
|
||||||
struct vcpu_state_t regs;
|
struct vcpu_state_t regs;
|
||||||
|
@ -887,9 +837,6 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!set) {
|
|
||||||
hax_setup_qemu_emulator(env);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1070,6 +1017,7 @@ static int hax_arch_get_registers(CPUArchState *env)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x86_update_hflags(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,6 @@ int hvf_get_registers(CPUState *cpu_state)
|
||||||
X86CPU *x86cpu = X86_CPU(cpu_state);
|
X86CPU *x86cpu = X86_CPU(cpu_state);
|
||||||
CPUX86State *env = &x86cpu->env;
|
CPUX86State *env = &x86cpu->env;
|
||||||
|
|
||||||
|
|
||||||
env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
|
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_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
|
||||||
env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
|
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[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
|
||||||
env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
|
env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
|
||||||
|
|
||||||
|
x86_update_hflags(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,9 @@ static bool has_msr_hv_stimer;
|
||||||
static bool has_msr_hv_frequencies;
|
static bool has_msr_hv_frequencies;
|
||||||
static bool has_msr_xss;
|
static bool has_msr_xss;
|
||||||
|
|
||||||
static bool has_msr_architectural_pmu;
|
static uint32_t has_architectural_pmu_version;
|
||||||
static uint32_t num_architectural_pmu_counters;
|
static uint32_t num_architectural_pmu_gp_counters;
|
||||||
|
static uint32_t num_architectural_pmu_fixed_counters;
|
||||||
|
|
||||||
static int has_xsave;
|
static int has_xsave;
|
||||||
static int has_xcrs;
|
static int has_xcrs;
|
||||||
|
@ -872,19 +873,28 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit >= 0x0a) {
|
if (limit >= 0x0a) {
|
||||||
uint32_t ver;
|
uint32_t eax, edx;
|
||||||
|
|
||||||
cpu_x86_cpuid(env, 0x0a, 0, &ver, &unused, &unused, &unused);
|
cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx);
|
||||||
if ((ver & 0xff) > 0) {
|
|
||||||
has_msr_architectural_pmu = true;
|
has_architectural_pmu_version = eax & 0xff;
|
||||||
num_architectural_pmu_counters = (ver & 0xff00) >> 8;
|
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
|
/* Shouldn't be more than 32, since that's the number of bits
|
||||||
* available in EBX to tell us _which_ counters are available.
|
* available in EBX to tell us _which_ counters are available.
|
||||||
* Play it safe.
|
* Play it safe.
|
||||||
*/
|
*/
|
||||||
if (num_architectural_pmu_counters > MAX_GP_COUNTERS) {
|
if (num_architectural_pmu_gp_counters > MAX_GP_COUNTERS) {
|
||||||
num_architectural_pmu_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,22 +1660,25 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
||||||
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
|
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
|
||||||
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
|
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
|
||||||
}
|
}
|
||||||
if (has_msr_architectural_pmu) {
|
if (has_architectural_pmu_version > 0) {
|
||||||
|
if (has_architectural_pmu_version > 1) {
|
||||||
/* Stop the counter. */
|
/* Stop the counter. */
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
|
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_CTRL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the counter values. */
|
/* 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,
|
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i,
|
||||||
env->msr_fixed_counters[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,
|
kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i,
|
||||||
env->msr_gp_counters[i]);
|
env->msr_gp_counters[i]);
|
||||||
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i,
|
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i,
|
||||||
env->msr_gp_evtsel[i]);
|
env->msr_gp_evtsel[i]);
|
||||||
}
|
}
|
||||||
|
if (has_architectural_pmu_version > 1) {
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
|
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
|
||||||
env->msr_global_status);
|
env->msr_global_status);
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
|
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
|
||||||
|
@ -1677,6 +1690,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
|
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
|
||||||
env->msr_global_ctrl);
|
env->msr_global_ctrl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Hyper-V partition-wide MSRs: to avoid clearing them on cpu hot-add,
|
* Hyper-V partition-wide MSRs: to avoid clearing them on cpu hot-add,
|
||||||
* only sync them to KVM on the first cpu
|
* only sync them to KVM on the first cpu
|
||||||
|
@ -1877,7 +1891,6 @@ static int kvm_get_sregs(X86CPU *cpu)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
struct kvm_sregs sregs;
|
struct kvm_sregs sregs;
|
||||||
uint32_t hflags;
|
|
||||||
int bit, i, ret;
|
int bit, i, ret;
|
||||||
|
|
||||||
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_SREGS, &sregs);
|
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;
|
env->efer = sregs.efer;
|
||||||
|
|
||||||
/* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */
|
/* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */
|
||||||
|
x86_update_hflags(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)
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2030,15 +2006,17 @@ static int kvm_get_msrs(X86CPU *cpu)
|
||||||
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
|
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
|
||||||
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0);
|
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0);
|
||||||
}
|
}
|
||||||
if (has_msr_architectural_pmu) {
|
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_FIXED_CTR_CTRL, 0);
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_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_STATUS, 0);
|
||||||
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
|
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
|
||||||
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, 0);
|
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_PERFCTR0 + i, 0);
|
||||||
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + 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) {
|
if (entry->virq == virq) {
|
||||||
trace_kvm_x86_remove_msi_route(virq);
|
trace_kvm_x86_remove_msi_route(virq);
|
||||||
QLIST_REMOVE(entry, list);
|
QLIST_REMOVE(entry, list);
|
||||||
|
g_free(entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -682,13 +682,13 @@ static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
|
||||||
do { \
|
do { \
|
||||||
e = SIGNED_EVEN(a, df); \
|
e = SIGNED_EVEN(a, df); \
|
||||||
o = SIGNED_ODD(a, df); \
|
o = SIGNED_ODD(a, df); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define UNSIGNED_EXTRACT(e, o, a, df) \
|
#define UNSIGNED_EXTRACT(e, o, a, df) \
|
||||||
do { \
|
do { \
|
||||||
e = UNSIGNED_EVEN(a, df); \
|
e = UNSIGNED_EVEN(a, df); \
|
||||||
o = UNSIGNED_ODD(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)
|
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_COND_D MSA_LOOP_COND(DF_DOUBLE)
|
||||||
|
|
||||||
#define MSA_LOOP(DF) \
|
#define MSA_LOOP(DF) \
|
||||||
|
do { \
|
||||||
for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
|
for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
|
||||||
MSA_DO_ ## DF \
|
MSA_DO_ ## DF; \
|
||||||
}
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define MSA_FN_DF(FUNC) \
|
#define MSA_FN_DF(FUNC) \
|
||||||
void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
|
@ -1135,16 +1137,16 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
uint32_t i; \
|
uint32_t i; \
|
||||||
switch (df) { \
|
switch (df) { \
|
||||||
case DF_BYTE: \
|
case DF_BYTE: \
|
||||||
MSA_LOOP_B \
|
MSA_LOOP_B; \
|
||||||
break; \
|
break; \
|
||||||
case DF_HALF: \
|
case DF_HALF: \
|
||||||
MSA_LOOP_H \
|
MSA_LOOP_H; \
|
||||||
break; \
|
break; \
|
||||||
case DF_WORD: \
|
case DF_WORD: \
|
||||||
MSA_LOOP_W \
|
MSA_LOOP_W; \
|
||||||
break; \
|
break; \
|
||||||
case DF_DOUBLE: \
|
case DF_DOUBLE: \
|
||||||
MSA_LOOP_D \
|
MSA_LOOP_D; \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
assert(0); \
|
||||||
|
@ -1168,7 +1170,7 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
do { \
|
do { \
|
||||||
R##DF(pwx, i) = pwt->DF[2*i]; \
|
R##DF(pwx, i) = pwt->DF[2*i]; \
|
||||||
L##DF(pwx, i) = pws->DF[2*i]; \
|
L##DF(pwx, i) = pws->DF[2*i]; \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(pckev_df)
|
MSA_FN_DF(pckev_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
|
|
||||||
|
@ -1176,7 +1178,7 @@ MSA_FN_DF(pckev_df)
|
||||||
do { \
|
do { \
|
||||||
R##DF(pwx, i) = pwt->DF[2*i+1]; \
|
R##DF(pwx, i) = pwt->DF[2*i+1]; \
|
||||||
L##DF(pwx, i) = pws->DF[2*i+1]; \
|
L##DF(pwx, i) = pws->DF[2*i+1]; \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(pckod_df)
|
MSA_FN_DF(pckod_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
|
|
||||||
|
@ -1184,7 +1186,7 @@ MSA_FN_DF(pckod_df)
|
||||||
do { \
|
do { \
|
||||||
pwx->DF[2*i] = L##DF(pwt, i); \
|
pwx->DF[2*i] = L##DF(pwt, i); \
|
||||||
pwx->DF[2*i+1] = L##DF(pws, i); \
|
pwx->DF[2*i+1] = L##DF(pws, i); \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(ilvl_df)
|
MSA_FN_DF(ilvl_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
|
|
||||||
|
@ -1192,7 +1194,7 @@ MSA_FN_DF(ilvl_df)
|
||||||
do { \
|
do { \
|
||||||
pwx->DF[2*i] = R##DF(pwt, i); \
|
pwx->DF[2*i] = R##DF(pwt, i); \
|
||||||
pwx->DF[2*i+1] = R##DF(pws, i); \
|
pwx->DF[2*i+1] = R##DF(pws, i); \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(ilvr_df)
|
MSA_FN_DF(ilvr_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
|
|
||||||
|
@ -1200,7 +1202,7 @@ MSA_FN_DF(ilvr_df)
|
||||||
do { \
|
do { \
|
||||||
pwx->DF[2*i] = pwt->DF[2*i]; \
|
pwx->DF[2*i] = pwt->DF[2*i]; \
|
||||||
pwx->DF[2*i+1] = pws->DF[2*i]; \
|
pwx->DF[2*i+1] = pws->DF[2*i]; \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(ilvev_df)
|
MSA_FN_DF(ilvev_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
|
|
||||||
|
@ -1208,7 +1210,7 @@ MSA_FN_DF(ilvev_df)
|
||||||
do { \
|
do { \
|
||||||
pwx->DF[2*i] = pwt->DF[2*i+1]; \
|
pwx->DF[2*i] = pwt->DF[2*i+1]; \
|
||||||
pwx->DF[2*i+1] = pws->DF[2*i+1]; \
|
pwx->DF[2*i+1] = pws->DF[2*i+1]; \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(ilvod_df)
|
MSA_FN_DF(ilvod_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
#undef MSA_LOOP_COND
|
#undef MSA_LOOP_COND
|
||||||
|
@ -1222,7 +1224,7 @@ MSA_FN_DF(ilvod_df)
|
||||||
uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
|
uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
|
||||||
pwx->DF[i] = \
|
pwx->DF[i] = \
|
||||||
(pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
|
(pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
|
||||||
} while (0);
|
} while (0)
|
||||||
MSA_FN_DF(vshf_df)
|
MSA_FN_DF(vshf_df)
|
||||||
#undef MSA_DO
|
#undef MSA_DO
|
||||||
#undef MSA_LOOP_COND
|
#undef MSA_LOOP_COND
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
if (DEBUG_KVM) { \
|
if (DEBUG_KVM) { \
|
||||||
fprintf(stderr, fmt, ## __VA_ARGS__); \
|
fprintf(stderr, fmt, ## __VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define kvm_vm_check_mem_attr(s, attr) \
|
#define kvm_vm_check_mem_attr(s, attr) \
|
||||||
kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, 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-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-mips-y = tests/endianness-test$(EXESUF)
|
||||||
|
|
||||||
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
|
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
|
||||||
|
|
||||||
check-qtest-mips64el-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/endianness-test$(EXESUF)
|
||||||
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
|
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
|
||||||
check-qtest-ppc-y += tests/prom-env-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
|
gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
|
||||||
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
|
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
|
||||||
gcov-files-arm-y += hw/timer/arm_mptimer.c
|
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)
|
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ typedef struct {
|
||||||
do { \
|
do { \
|
||||||
memread(addr, &field, sizeof(field)); \
|
memread(addr, &field, sizeof(field)); \
|
||||||
addr += sizeof(field); \
|
addr += sizeof(field); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define ACPI_READ_ARRAY_PTR(arr, length, addr) \
|
#define ACPI_READ_ARRAY_PTR(arr, length, addr) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -40,7 +40,7 @@ typedef struct {
|
||||||
for (idx = 0; idx < length; ++idx) { \
|
for (idx = 0; idx < length; ++idx) { \
|
||||||
ACPI_READ_FIELD(arr[idx], addr); \
|
ACPI_READ_FIELD(arr[idx], addr); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define ACPI_READ_ARRAY(arr, addr) \
|
#define ACPI_READ_ARRAY(arr, addr) \
|
||||||
ACPI_READ_ARRAY_PTR(arr, sizeof(arr) / sizeof(arr[0]), 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_FIELD((table)->oem_revision, addr); \
|
||||||
ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \
|
ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \
|
||||||
ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \
|
ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define ACPI_ASSERT_CMP(actual, expected) do { \
|
#define ACPI_ASSERT_CMP(actual, expected) do { \
|
||||||
char ACPI_ASSERT_CMP_str[5] = {}; \
|
char ACPI_ASSERT_CMP_str[5] = {}; \
|
||||||
|
@ -77,7 +77,7 @@ typedef struct {
|
||||||
ACPI_READ_FIELD((field).bit_offset, addr); \
|
ACPI_READ_FIELD((field).bit_offset, addr); \
|
||||||
ACPI_READ_FIELD((field).access_width, addr); \
|
ACPI_READ_FIELD((field).access_width, addr); \
|
||||||
ACPI_READ_FIELD((field).address, addr); \
|
ACPI_READ_FIELD((field).address, addr); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
uint8_t acpi_calc_checksum(const uint8_t *data, int len);
|
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 */
|
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 {
|
typedef struct testdef {
|
||||||
const char *arch; /* Target architecture */
|
const char *arch; /* Target architecture */
|
||||||
const char *machine; /* Name of the machine */
|
const char *machine; /* Name of the machine */
|
||||||
|
@ -50,6 +81,12 @@ static testdef_t tests[] = {
|
||||||
{ "s390x", "s390-ccw-virtio",
|
{ "s390x", "s390-ccw-virtio",
|
||||||
"-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
|
"-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
|
||||||
{ "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
|
{ "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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,8 @@ static void do_test_equality(bool expected, int _, ...)
|
||||||
g_assert(qobject_is_equal(args[i], args[j]) == expected);
|
g_assert(qobject_is_equal(args[i], args[j]) == expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define check_equal(...) \
|
#define check_equal(...) \
|
||||||
|
|
|
@ -3,7 +3,7 @@ ENV PACKAGES \
|
||||||
ccache gettext git tar PyYAML sparse flex bison python2 bzip2 hostname \
|
ccache gettext git tar PyYAML sparse flex bison python2 bzip2 hostname \
|
||||||
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
|
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
|
||||||
gcc gcc-c++ clang make perl which bc findutils libaio-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-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
|
||||||
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
|
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
|
||||||
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
|
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
|
||||||
|
@ -15,4 +15,4 @@ ENV PACKAGES \
|
||||||
|
|
||||||
RUN dnf install -y $PACKAGES
|
RUN dnf install -y $PACKAGES
|
||||||
RUN rpm -q $PACKAGES | sort > /packages.txt
|
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"
|
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
|
# -fsanitize=undefined is broken on Fedora 23, skip it for now
|
||||||
# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
|
# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
|
||||||
#OPTS="$OPTS --extra-cflags=-fsanitize=undefined \
|
#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} \
|
TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
|
||||||
build_qemu --cross-prefix=$prefix \
|
build_qemu --cross-prefix=$prefix \
|
||||||
--enable-trace-backends=simple \
|
--enable-trace-backends=simple \
|
||||||
--enable-debug \
|
|
||||||
--enable-gnutls \
|
--enable-gnutls \
|
||||||
--enable-nettle \
|
--enable-nettle \
|
||||||
--enable-curl \
|
--enable-curl \
|
||||||
|
@ -35,4 +34,3 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ static void add_query_tests(QmpSchema *schema)
|
||||||
{
|
{
|
||||||
SchemaInfoList *tail;
|
SchemaInfoList *tail;
|
||||||
SchemaInfo *si, *arg_type, *ret_type;
|
SchemaInfo *si, *arg_type, *ret_type;
|
||||||
const char *test_name;
|
char *test_name;
|
||||||
|
|
||||||
/* Test the query-like commands */
|
/* Test the query-like commands */
|
||||||
for (tail = schema->list; tail; tail = tail->next) {
|
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);
|
test_name = g_strdup_printf("qmp/%s", si->name);
|
||||||
qtest_add_data_func(test_name, si->name, test_query);
|
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__); \
|
fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
|
||||||
exit (EXIT_FAILURE); \
|
exit (EXIT_FAILURE); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
unsigned char *dummybuf;
|
unsigned char *dummybuf;
|
||||||
static unsigned int pagesize;
|
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 */
|
/* Once more to check it still works after yielding */
|
||||||
g_assert(qemu_coroutine_entered(caller));
|
g_assert(qemu_coroutine_entered(caller));
|
||||||
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
|
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
|
||||||
qemu_coroutine_yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn verify_entered_step_1(void *opaque)
|
static void coroutine_fn verify_entered_step_1(void *opaque)
|
||||||
|
|
|
@ -283,7 +283,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
while (1) {
|
||||||
struct iovec *sg;
|
struct iovec *sg;
|
||||||
ssize_t ret, total = 0;
|
ssize_t ret, total = 0;
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
|
@ -343,7 +343,9 @@ vubr_backend_recv_cb(int sock, void *ctx)
|
||||||
|
|
||||||
free(elem);
|
free(elem);
|
||||||
elem = NULL;
|
elem = NULL;
|
||||||
} while (false); /* could loop if DONTWAIT worked? */
|
|
||||||
|
break; /* could loop if DONTWAIT worked? */
|
||||||
|
}
|
||||||
|
|
||||||
if (mhdr_cnt) {
|
if (mhdr_cnt) {
|
||||||
mhdr.num_buffers = i;
|
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_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
|
||||||
dma_map_wait(void *dbs) "dbs=%p"
|
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.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_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"
|
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 { \
|
#define setRed(r, pcolor) do { \
|
||||||
*pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
|
*pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
|
||||||
(((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
|
(((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define setGreen(g, pcolor) do { \
|
#define setGreen(g, pcolor) do { \
|
||||||
*pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
|
*pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
|
||||||
(((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
|
(((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define setBlue(b, pcolor) do { \
|
#define setBlue(b, pcolor) do { \
|
||||||
*pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
|
*pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
|
||||||
(((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
|
(((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
|
||||||
} while (0);
|
} while (0)
|
||||||
|
|
||||||
#define setAlpha(a, pcolor) do { \
|
#define setAlpha(a, pcolor) do { \
|
||||||
*pcolor = ((*pcolor) & (~(dpf->Amask))) + \
|
*pcolor = ((*pcolor) & (~(dpf->Amask))) + \
|
||||||
(((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
|
(((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,
|
static void glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
|
||||||
SDL_Rect *dst_rect)
|
SDL_Rect *dst_rect)
|
||||||
|
|
|
@ -105,7 +105,8 @@ static void cleanup_infolist(CommandLineParameterInfoList *head)
|
||||||
if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
|
if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
|
||||||
del_entry = cur->next;
|
del_entry = cur->next;
|
||||||
cur->next = cur->next->next;
|
cur->next = cur->next->next;
|
||||||
g_free(del_entry);
|
del_entry->next = NULL;
|
||||||
|
qapi_free_CommandLineParameterInfoList(del_entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pre_entry = pre_entry->next;
|
pre_entry = pre_entry->next;
|
||||||
|
|
|
@ -57,26 +57,28 @@ void qemu_mutex_destroy(QemuMutex *mutex)
|
||||||
error_exit(err, __func__);
|
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;
|
int err;
|
||||||
|
|
||||||
assert(mutex->initialized);
|
assert(mutex->initialized);
|
||||||
|
trace_qemu_mutex_lock(mutex, file, line);
|
||||||
|
|
||||||
err = pthread_mutex_lock(&mutex->lock);
|
err = pthread_mutex_lock(&mutex->lock);
|
||||||
if (err)
|
if (err)
|
||||||
error_exit(err, __func__);
|
error_exit(err, __func__);
|
||||||
|
|
||||||
trace_qemu_mutex_locked(mutex);
|
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;
|
int err;
|
||||||
|
|
||||||
assert(mutex->initialized);
|
assert(mutex->initialized);
|
||||||
err = pthread_mutex_trylock(&mutex->lock);
|
err = pthread_mutex_trylock(&mutex->lock);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
trace_qemu_mutex_locked(mutex);
|
trace_qemu_mutex_locked(mutex, file, line);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (err != EBUSY) {
|
if (err != EBUSY) {
|
||||||
|
@ -85,15 +87,16 @@ int qemu_mutex_trylock(QemuMutex *mutex)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_mutex_unlock(QemuMutex *mutex)
|
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
assert(mutex->initialized);
|
assert(mutex->initialized);
|
||||||
trace_qemu_mutex_unlocked(mutex);
|
|
||||||
err = pthread_mutex_unlock(&mutex->lock);
|
err = pthread_mutex_unlock(&mutex->lock);
|
||||||
if (err)
|
if (err)
|
||||||
error_exit(err, __func__);
|
error_exit(err, __func__);
|
||||||
|
|
||||||
|
trace_qemu_mutex_unlock(mutex, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_rec_mutex_init(QemuRecMutex *mutex)
|
void qemu_rec_mutex_init(QemuRecMutex *mutex)
|
||||||
|
@ -152,14 +155,14 @@ void qemu_cond_broadcast(QemuCond *cond)
|
||||||
error_exit(err, __func__);
|
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;
|
int err;
|
||||||
|
|
||||||
assert(cond->initialized);
|
assert(cond->initialized);
|
||||||
trace_qemu_mutex_unlocked(mutex);
|
trace_qemu_mutex_unlock(mutex, file, line);
|
||||||
err = pthread_cond_wait(&cond->cond, &mutex->lock);
|
err = pthread_cond_wait(&cond->cond, &mutex->lock);
|
||||||
trace_qemu_mutex_locked(mutex);
|
trace_qemu_mutex_locked(mutex, file, line);
|
||||||
if (err)
|
if (err)
|
||||||
error_exit(err, __func__);
|
error_exit(err, __func__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,30 +56,32 @@ void qemu_mutex_destroy(QemuMutex *mutex)
|
||||||
InitializeSRWLock(&mutex->lock);
|
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);
|
assert(mutex->initialized);
|
||||||
|
trace_qemu_mutex_lock(mutex, file, line);
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&mutex->lock);
|
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;
|
int owned;
|
||||||
|
|
||||||
assert(mutex->initialized);
|
assert(mutex->initialized);
|
||||||
owned = TryAcquireSRWLockExclusive(&mutex->lock);
|
owned = TryAcquireSRWLockExclusive(&mutex->lock);
|
||||||
if (owned) {
|
if (owned) {
|
||||||
trace_qemu_mutex_locked(mutex);
|
trace_qemu_mutex_locked(mutex, file, line);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_mutex_unlock(QemuMutex *mutex)
|
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
|
||||||
{
|
{
|
||||||
assert(mutex->initialized);
|
assert(mutex->initialized);
|
||||||
trace_qemu_mutex_unlocked(mutex);
|
trace_qemu_mutex_unlock(mutex, file, line);
|
||||||
ReleaseSRWLockExclusive(&mutex->lock);
|
ReleaseSRWLockExclusive(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,12 +142,12 @@ void qemu_cond_broadcast(QemuCond *cond)
|
||||||
WakeAllConditionVariable(&cond->var);
|
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);
|
assert(cond->initialized);
|
||||||
trace_qemu_mutex_unlocked(mutex);
|
trace_qemu_mutex_unlock(mutex, file, line);
|
||||||
SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
|
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)
|
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];
|
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,
|
ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
|
||||||
ReadLineFlushFunc *flush_func,
|
ReadLineFlushFunc *flush_func,
|
||||||
void *opaque,
|
void *opaque,
|
||||||
ReadLineCompletionFunc *completion_finder)
|
ReadLineCompletionFunc *completion_finder)
|
||||||
{
|
{
|
||||||
ReadLineState *rs = g_malloc0(sizeof(*rs));
|
ReadLineState *rs = g_new0(ReadLineState, 1);
|
||||||
|
|
||||||
rs->hist_entry = -1;
|
rs->hist_entry = -1;
|
||||||
rs->opaque = opaque;
|
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_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d"
|
||||||
lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
|
lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
|
||||||
|
|
||||||
# util/qemu-thread-posix.c
|
# util/qemu-thread.c
|
||||||
qemu_mutex_locked(void *lock) "locked mutex %p"
|
qemu_mutex_lock(void *mutex, const char *file, const int line) "waiting on mutex %p (%s:%d)"
|
||||||
qemu_mutex_unlocked(void *lock) "unlocked mutex %p"
|
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 */
|
return; /* duplicate */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data_dir[data_dir_idx++] = path;
|
data_dir[data_dir_idx++] = g_strdup(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool nonempty_str(const char *str)
|
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 *main_loop_err = NULL;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
bool list_data_dirs = false;
|
bool list_data_dirs = false;
|
||||||
char **dirs;
|
char *dir, **dirs;
|
||||||
typedef struct BlockdevOptions_queue {
|
typedef struct BlockdevOptions_queue {
|
||||||
BlockdevOptions *bdo;
|
BlockdevOptions *bdo;
|
||||||
Location loc;
|
Location loc;
|
||||||
|
@ -4181,9 +4181,12 @@ int main(int argc, char **argv, char **envp)
|
||||||
for (i = 0; dirs[i] != NULL; i++) {
|
for (i = 0; dirs[i] != NULL; i++) {
|
||||||
qemu_add_data_dir(dirs[i]);
|
qemu_add_data_dir(dirs[i]);
|
||||||
}
|
}
|
||||||
|
g_strfreev(dirs);
|
||||||
|
|
||||||
/* try to find datadir relative to the executable path */
|
/* 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 */
|
/* add the datadir specified when building */
|
||||||
qemu_add_data_dir(CONFIG_QEMU_DATADIR);
|
qemu_add_data_dir(CONFIG_QEMU_DATADIR);
|
||||||
|
|
Loading…
Reference in New Issue