* 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:
Peter Maydell 2018-01-16 15:45:15 +00:00
commit c1d5b9add7
90 changed files with 900 additions and 415 deletions

View File

@ -8,9 +8,12 @@ SRC_PATH=.
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
html info pdf txt \
help check-help \
help check-help print-% \
docker docker-% vm-test vm-build-%
print-%:
@echo '$*=$($*)'
# All following code might depend on configuration variables
ifneq ($(wildcard config-host.mak),)
# Put the all: rule here so that config-host.mak can contain dependencies.
@ -277,7 +280,7 @@ else
DOCS=
endif
SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) BUILD_DIR=$(BUILD_DIR)
SUBDIR_MAKEFLAGS=BUILD_DIR=$(BUILD_DIR)
SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %-config-devices.mak.d, $(TARGET_DIRS))

View File

@ -89,7 +89,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
} \
goto label; \
} \
} while (0);
} while (0)
#define CHECK_DEAD_GOTO(c, stream, rerror, label) \
do { \
@ -107,7 +107,7 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
} \
goto label; \
} \
} while (0);
} while (0)
static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int *rerror)
{

View File

@ -658,6 +658,8 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
uint64_t lba;
int64_t ret;
iscsi_co_init_iscsitask(iscsilun, &iTask);
if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
ret = -EINVAL;
goto out;
@ -675,7 +677,6 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
lba = sector_qemu2lun(sector_num, iscsilun);
iscsi_co_init_iscsitask(iscsilun, &iTask);
qemu_mutex_lock(&iscsilun->mutex);
retry:
if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,

View File

@ -356,7 +356,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
}
g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
tag = g_source_attach(src, NULL);
tag = g_source_attach(src, s->gcontext);
g_source_unref(src);
return tag;

View File

@ -42,8 +42,8 @@ typedef struct {
/* Protected by the Chardev chr_write_lock. */
int connected;
guint timer_tag;
guint open_tag;
GSource *timer_src;
GSource *open_source;
} PtyChardev;
#define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY)
@ -57,8 +57,9 @@ static gboolean pty_chr_timer(gpointer opaque)
PtyChardev *s = PTY_CHARDEV(opaque);
qemu_mutex_lock(&chr->chr_write_lock);
s->timer_tag = 0;
s->open_tag = 0;
s->timer_src = NULL;
g_source_unref(s->open_source);
s->open_source = NULL;
if (!s->connected) {
/* Next poll ... */
pty_chr_update_read_handler_locked(chr);
@ -67,25 +68,25 @@ static gboolean pty_chr_timer(gpointer opaque)
return FALSE;
}
static void pty_chr_timer_cancel(PtyChardev *s)
{
if (s->timer_src) {
g_source_destroy(s->timer_src);
g_source_unref(s->timer_src);
s->timer_src = NULL;
}
}
/* Called with chr_write_lock held. */
static void pty_chr_rearm_timer(Chardev *chr, int ms)
{
PtyChardev *s = PTY_CHARDEV(chr);
char *name;
if (s->timer_tag) {
g_source_remove(s->timer_tag);
s->timer_tag = 0;
}
if (ms == 1000) {
name = g_strdup_printf("pty-timer-secs-%s", chr->label);
s->timer_tag = g_timeout_add_seconds(1, pty_chr_timer, chr);
} else {
name = g_strdup_printf("pty-timer-ms-%s", chr->label);
s->timer_tag = g_timeout_add(ms, pty_chr_timer, chr);
}
g_source_set_name_by_id(s->timer_tag, name);
pty_chr_timer_cancel(s);
name = g_strdup_printf("pty-timer-%s", chr->label);
s->timer_src = qemu_chr_timeout_add_ms(chr, ms, pty_chr_timer, chr);
g_source_set_name(s->timer_src, name);
g_free(name);
}
@ -183,7 +184,7 @@ static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
s->open_tag = 0;
s->open_source = NULL;
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
return FALSE;
}
@ -194,9 +195,10 @@ static void pty_chr_state(Chardev *chr, int connected)
PtyChardev *s = PTY_CHARDEV(chr);
if (!connected) {
if (s->open_tag) {
g_source_remove(s->open_tag);
s->open_tag = 0;
if (s->open_source) {
g_source_destroy(s->open_source);
g_source_unref(s->open_source);
s->open_source = NULL;
}
remove_fd_in_watch(chr);
s->connected = 0;
@ -205,14 +207,15 @@ static void pty_chr_state(Chardev *chr, int connected)
* the virtual device linked to our pty. */
pty_chr_rearm_timer(chr, 1000);
} else {
if (s->timer_tag) {
g_source_remove(s->timer_tag);
s->timer_tag = 0;
}
pty_chr_timer_cancel(s);
if (!s->connected) {
g_assert(s->open_tag == 0);
g_assert(s->open_source == NULL);
s->open_source = g_idle_source_new();
s->connected = 1;
s->open_tag = g_idle_add(qemu_chr_be_generic_open_func, chr);
g_source_set_callback(s->open_source,
qemu_chr_be_generic_open_func,
chr, NULL);
g_source_attach(s->open_source, chr->gcontext);
}
if (!chr->gsource) {
chr->gsource = io_add_watch_poll(chr, s->ioc,
@ -231,10 +234,7 @@ static void char_pty_finalize(Object *obj)
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_state(chr, 0);
object_unref(OBJECT(s->ioc));
if (s->timer_tag) {
g_source_remove(s->timer_tag);
s->timer_tag = 0;
}
pty_chr_timer_cancel(s);
qemu_mutex_unlock(&chr->chr_write_lock);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
@ -267,7 +267,7 @@ static void char_pty_open(Chardev *chr,
name = g_strdup_printf("chardev-pty-%s", chr->label);
qio_channel_set_name(QIO_CHANNEL(s->ioc), name);
g_free(name);
s->timer_tag = 0;
s->timer_src = NULL;
*be_opened = false;
}

View File

@ -64,69 +64,74 @@ static void tty_serial_init(int fd, int speed,
#endif
tcgetattr(fd, &tty);
#define check_speed(val) if (speed <= val) { spd = B##val; break; }
#define check_speed(val) \
if (speed <= val) { \
spd = B##val; \
goto done; \
}
speed = speed * 10 / 11;
do {
check_speed(50);
check_speed(75);
check_speed(110);
check_speed(134);
check_speed(150);
check_speed(200);
check_speed(300);
check_speed(600);
check_speed(1200);
check_speed(1800);
check_speed(2400);
check_speed(4800);
check_speed(9600);
check_speed(19200);
check_speed(38400);
/* Non-Posix values follow. They may be unsupported on some systems. */
check_speed(57600);
check_speed(115200);
check_speed(50);
check_speed(75);
check_speed(110);
check_speed(134);
check_speed(150);
check_speed(200);
check_speed(300);
check_speed(600);
check_speed(1200);
check_speed(1800);
check_speed(2400);
check_speed(4800);
check_speed(9600);
check_speed(19200);
check_speed(38400);
/* Non-Posix values follow. They may be unsupported on some systems. */
check_speed(57600);
check_speed(115200);
#ifdef B230400
check_speed(230400);
check_speed(230400);
#endif
#ifdef B460800
check_speed(460800);
check_speed(460800);
#endif
#ifdef B500000
check_speed(500000);
check_speed(500000);
#endif
#ifdef B576000
check_speed(576000);
check_speed(576000);
#endif
#ifdef B921600
check_speed(921600);
check_speed(921600);
#endif
#ifdef B1000000
check_speed(1000000);
check_speed(1000000);
#endif
#ifdef B1152000
check_speed(1152000);
check_speed(1152000);
#endif
#ifdef B1500000
check_speed(1500000);
check_speed(1500000);
#endif
#ifdef B2000000
check_speed(2000000);
check_speed(2000000);
#endif
#ifdef B2500000
check_speed(2500000);
check_speed(2500000);
#endif
#ifdef B3000000
check_speed(3000000);
check_speed(3000000);
#endif
#ifdef B3500000
check_speed(3500000);
check_speed(3500000);
#endif
#ifdef B4000000
check_speed(4000000);
check_speed(4000000);
#endif
spd = B115200;
} while (0);
spd = B115200;
#undef check_speed
done:
cfsetispeed(&tty, spd);
cfsetospeed(&tty, spd);

View File

@ -57,7 +57,7 @@ typedef struct {
bool is_telnet;
bool is_tn3270;
guint reconnect_timer;
GSource *reconnect_timer;
int64_t reconnect_time;
bool connect_err_reported;
} SocketChardev;
@ -67,16 +67,27 @@ typedef struct {
static gboolean socket_reconnect_timeout(gpointer opaque);
static void tcp_chr_reconn_timer_cancel(SocketChardev *s)
{
if (s->reconnect_timer) {
g_source_destroy(s->reconnect_timer);
g_source_unref(s->reconnect_timer);
s->reconnect_timer = NULL;
}
}
static void qemu_chr_socket_restart_timer(Chardev *chr)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
char *name;
assert(s->connected == 0);
s->reconnect_timer = g_timeout_add_seconds(s->reconnect_time,
socket_reconnect_timeout, chr);
name = g_strdup_printf("chardev-socket-reconnect-%s", chr->label);
g_source_set_name_by_id(s->reconnect_timer, name);
s->reconnect_timer = qemu_chr_timeout_add_ms(chr,
s->reconnect_time * 1000,
socket_reconnect_timeout,
chr);
g_source_set_name(s->reconnect_timer, name);
g_free(name);
}
@ -781,11 +792,7 @@ static void char_socket_finalize(Object *obj)
SocketChardev *s = SOCKET_CHARDEV(obj);
tcp_chr_free_connection(chr);
if (s->reconnect_timer) {
g_source_remove(s->reconnect_timer);
s->reconnect_timer = 0;
}
tcp_chr_reconn_timer_cancel(s);
qapi_free_SocketAddress(s->addr);
if (s->listener) {
qio_net_listener_set_client_func(s->listener, NULL, NULL, NULL);
@ -824,7 +831,8 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
SocketChardev *s = SOCKET_CHARDEV(opaque);
QIOChannelSocket *sioc;
s->reconnect_timer = 0;
g_source_unref(s->reconnect_timer);
s->reconnect_timer = NULL;
if (chr->be_open) {
return false;

View File

@ -1084,6 +1084,24 @@ void qmp_chardev_send_break(const char *id, Error **errp)
qemu_chr_be_event(chr, CHR_EVENT_BREAK);
}
/*
* Add a timeout callback for the chardev (in milliseconds), return
* the GSource object created. Please use this to add timeout hook for
* chardev instead of g_timeout_add() and g_timeout_add_seconds(), to
* make sure the gcontext that the task bound to is correct.
*/
GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
GSourceFunc func, void *private)
{
GSource *source = g_timeout_source_new(ms);
assert(func);
g_source_set_callback(source, func, private, NULL);
g_source_attach(source, chr->gcontext);
return source;
}
void qemu_chr_cleanup(void)
{
object_unparent(get_chardevs_root());

16
configure vendored
View File

@ -3464,6 +3464,7 @@ else
done
if test "$found" = "no"; then
LIBS="$pthread_lib $LIBS"
libs_qga="$pthread_lib $libs_qga"
fi
PTHREAD_LIB="$pthread_lib"
break
@ -5193,8 +5194,19 @@ if test "$gcov" = "yes" ; then
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
elif test "$fortify_source" = "yes" ; then
CFLAGS="-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $CFLAGS"
elif test "$debug" = "no"; then
CFLAGS="-O2 $CFLAGS"
elif test "$debug" = "yes"; then
if compile_prog "-Og" ""; then
CFLAGS="-Og $CFLAGS"
elif compile_prog "-O1" ""; then
CFLAGS="-O1 $CFLAGS"
fi
# Workaround GCC false-positive Wuninitialized bugs with Og or O1:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
if cc_has_warning_flag "-Wno-maybe-uninitialized"; then
CFLAGS="-Wno-maybe-uninitialized $CFLAGS"
fi
else
CFLAGS="-O2 $CFLAGS"
fi
##########################################

134
cpus.c
View File

@ -120,16 +120,11 @@ static bool all_cpu_threads_idle(void)
/* Protected by TimersState seqlock */
static bool icount_sleep = true;
static int64_t vm_clock_warp_start = -1;
/* Conversion factor from emulated instructions to virtual clock ticks. */
static int icount_time_shift;
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
#define MAX_ICOUNT_SHIFT 10
static QEMUTimer *icount_rt_timer;
static QEMUTimer *icount_vm_timer;
static QEMUTimer *icount_warp_timer;
typedef struct TimersState {
/* Protected by BQL. */
int64_t cpu_ticks_prev;
@ -147,6 +142,11 @@ typedef struct TimersState {
int64_t qemu_icount_bias;
/* Only written by TCG thread */
int64_t qemu_icount;
/* for adjusting icount */
int64_t vm_clock_warp_start;
QEMUTimer *icount_rt_timer;
QEMUTimer *icount_vm_timer;
QEMUTimer *icount_warp_timer;
} TimersState;
static TimersState timers_state;
@ -432,14 +432,14 @@ static void icount_adjust(void)
static void icount_adjust_rt(void *opaque)
{
timer_mod(icount_rt_timer,
timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
icount_adjust();
}
static void icount_adjust_vm(void *opaque)
{
timer_mod(icount_vm_timer,
timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
icount_adjust();
@ -460,7 +460,7 @@ static void icount_warp_rt(void)
*/
do {
seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
warp_start = vm_clock_warp_start;
warp_start = timers_state.vm_clock_warp_start;
} while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
if (warp_start == -1) {
@ -473,7 +473,7 @@ static void icount_warp_rt(void)
cpu_get_clock_locked());
int64_t warp_delta;
warp_delta = clock - vm_clock_warp_start;
warp_delta = clock - timers_state.vm_clock_warp_start;
if (use_icount == 2) {
/*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
@ -485,7 +485,7 @@ static void icount_warp_rt(void)
}
timers_state.qemu_icount_bias += warp_delta;
}
vm_clock_warp_start = -1;
timers_state.vm_clock_warp_start = -1;
seqlock_write_end(&timers_state.vm_clock_seqlock);
if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
@ -594,11 +594,13 @@ void qemu_start_warp_timer(void)
* every 100ms.
*/
seqlock_write_begin(&timers_state.vm_clock_seqlock);
if (vm_clock_warp_start == -1 || vm_clock_warp_start > clock) {
vm_clock_warp_start = clock;
if (timers_state.vm_clock_warp_start == -1
|| timers_state.vm_clock_warp_start > clock) {
timers_state.vm_clock_warp_start = clock;
}
seqlock_write_end(&timers_state.vm_clock_seqlock);
timer_mod_anticipate(icount_warp_timer, clock + deadline);
timer_mod_anticipate(timers_state.icount_warp_timer,
clock + deadline);
}
} else if (deadline == 0) {
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
@ -623,7 +625,7 @@ static void qemu_account_warp_timer(void)
return;
}
timer_del(icount_warp_timer);
timer_del(timers_state.icount_warp_timer);
icount_warp_rt();
}
@ -632,6 +634,45 @@ static bool icount_state_needed(void *opaque)
return use_icount;
}
static bool warp_timer_state_needed(void *opaque)
{
TimersState *s = opaque;
return s->icount_warp_timer != NULL;
}
static bool adjust_timers_state_needed(void *opaque)
{
TimersState *s = opaque;
return s->icount_rt_timer != NULL;
}
/*
* Subsection for warp timer migration is optional, because may not be created
*/
static const VMStateDescription icount_vmstate_warp_timer = {
.name = "timer/icount/warp_timer",
.version_id = 1,
.minimum_version_id = 1,
.needed = warp_timer_state_needed,
.fields = (VMStateField[]) {
VMSTATE_INT64(vm_clock_warp_start, TimersState),
VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription icount_vmstate_adjust_timers = {
.name = "timer/icount/timers",
.version_id = 1,
.minimum_version_id = 1,
.needed = adjust_timers_state_needed,
.fields = (VMStateField[]) {
VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
VMSTATE_END_OF_LIST()
}
};
/*
* This is a subsection for icount migration.
*/
@ -644,6 +685,11 @@ static const VMStateDescription icount_vmstate_timers = {
VMSTATE_INT64(qemu_icount_bias, TimersState),
VMSTATE_INT64(qemu_icount, TimersState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&icount_vmstate_warp_timer,
&icount_vmstate_adjust_timers,
NULL
}
};
@ -754,7 +800,7 @@ void configure_icount(QemuOpts *opts, Error **errp)
icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
if (icount_sleep) {
icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
icount_timer_cb, NULL);
}
@ -788,13 +834,14 @@ void configure_icount(QemuOpts *opts, Error **errp)
the virtual time trigger catches emulated time passing too fast.
Realtime triggers occur even when idle, so use them less frequently
than VM triggers. */
icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
timers_state.vm_clock_warp_start = -1;
timers_state.icount_rt_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL_RT,
icount_adjust_rt, NULL);
timer_mod(icount_rt_timer,
timer_mod(timers_state.icount_rt_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL_RT) + 1000);
icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
timers_state.icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
icount_adjust_vm, NULL);
timer_mod(icount_vm_timer,
timer_mod(timers_state.icount_vm_timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
}
@ -862,7 +909,8 @@ static void kick_tcg_thread(void *opaque)
static void start_tcg_kick_timer(void)
{
if (!mttcg_enabled && !tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
assert(!mttcg_enabled);
if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
kick_tcg_thread, NULL);
timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
@ -871,6 +919,7 @@ static void start_tcg_kick_timer(void)
static void stop_tcg_kick_timer(void)
{
assert(!mttcg_enabled);
if (tcg_kick_vcpu_timer) {
timer_del(tcg_kick_vcpu_timer);
tcg_kick_vcpu_timer = NULL;
@ -1090,18 +1139,9 @@ static void qemu_wait_io_event_common(CPUState *cpu)
process_queued_cpu_work(cpu);
}
static bool qemu_tcg_should_sleep(CPUState *cpu)
static void qemu_tcg_rr_wait_io_event(CPUState *cpu)
{
if (mttcg_enabled) {
return cpu_thread_is_idle(cpu);
} else {
return all_cpu_threads_idle();
}
}
static void qemu_tcg_wait_io_event(CPUState *cpu)
{
while (qemu_tcg_should_sleep(cpu)) {
while (all_cpu_threads_idle()) {
stop_tcg_kick_timer();
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
@ -1111,20 +1151,18 @@ static void qemu_tcg_wait_io_event(CPUState *cpu)
qemu_wait_io_event_common(cpu);
}
static void qemu_kvm_wait_io_event(CPUState *cpu)
static void qemu_wait_io_event(CPUState *cpu)
{
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
qemu_wait_io_event_common(cpu);
}
static void qemu_hvf_wait_io_event(CPUState *cpu)
{
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
#ifdef _WIN32
/* Eat dummy APC queued by qemu_cpu_kick_thread. */
if (!tcg_enabled()) {
SleepEx(0, TRUE);
}
#endif
qemu_wait_io_event_common(cpu);
}
@ -1160,7 +1198,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
cpu_handle_guest_debug(cpu);
}
}
qemu_kvm_wait_io_event(cpu);
qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
qemu_kvm_destroy_vcpu(cpu);
@ -1206,7 +1244,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
exit(1);
}
qemu_mutex_lock_iothread();
qemu_wait_io_event_common(cpu);
qemu_wait_io_event(cpu);
}
return NULL;
@ -1423,7 +1461,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
atomic_mb_set(&cpu->exit_request, 0);
}
qemu_tcg_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus));
qemu_tcg_rr_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus));
deal_with_unplugged_cpus();
}
@ -1454,13 +1492,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
}
}
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
#ifdef _WIN32
SleepEx(0, TRUE);
#endif
qemu_wait_io_event_common(cpu);
qemu_wait_io_event(cpu);
}
return NULL;
}
@ -1497,7 +1529,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
cpu_handle_guest_debug(cpu);
}
}
qemu_hvf_wait_io_event(cpu);
qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
hvf_vcpu_destroy(cpu);
@ -1576,7 +1608,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
atomic_mb_set(&cpu->exit_request, 0);
qemu_tcg_wait_io_event(cpu);
qemu_wait_io_event(cpu);
}
return NULL;

View File

@ -79,7 +79,7 @@ static int qcrypto_ivgen_essiv_calculate(QCryptoIVGen *ivgen,
uint8_t *data = g_new(uint8_t, ndata);
sector = cpu_to_le64(sector);
memcpy(data, (uint8_t *)&sector, ndata);
memcpy(data, (uint8_t *)&sector, MIN(sizeof(sector), ndata));
if (sizeof(sector) < ndata) {
memset(data + sizeof(sector), 0, ndata - sizeof(sector));
}

View File

@ -207,18 +207,14 @@ static int opc_index[256];
static void
init_disasm (struct disassemble_info *info)
{
const struct s390_opcode *opcode;
const struct s390_opcode *opcode_end;
int i;
memset (opc_index, 0, sizeof (opc_index));
opcode_end = s390_opcodes + s390_num_opcodes;
for (opcode = s390_opcodes; opcode < opcode_end; opcode++)
{
opc_index[(int) opcode->opcode[0]] = opcode - s390_opcodes;
while ((opcode < opcode_end) &&
(opcode[1].opcode[0] == opcode->opcode[0]))
opcode++;
}
/* Reverse order, such that each opc_index ends up pointing to the
first matching entry instead of the last. */
for (i = s390_num_opcodes; i--; )
opc_index[s390_opcodes[i].opcode[0]] = i;
#ifdef QEMU_DISABLE
switch (info->mach)

View File

@ -510,3 +510,16 @@ default-configs/$TARGET-NAME file as input.
This is the entrypoint used when make recurses to build a single system
or userspace emulator target. It is merely a symlink back to the
Makefile.target in the top level.
Useful make targets
===================
- help
Print a help message for the most common build targets.
- print-VAR
Print the value of the variable VAR. Useful for debugging the build
system.

40
exec.c
View File

@ -623,6 +623,13 @@ static int cpu_common_post_load(void *opaque, int version_id)
cpu->interrupt_request &= ~0x01;
tlb_flush(cpu);
/* loadvm has just updated the content of RAM, bypassing the
* usual mechanisms that ensure we flush TBs for writes to
* memory we've translated code from. So we must flush all TBs,
* which will now be stale.
*/
tb_flush(cpu);
return 0;
}
@ -1660,7 +1667,10 @@ static void *file_ram_alloc(RAMBlock *block,
}
#endif
/* Called with the ramlist lock held. */
/* Allocate space within the ram_addr_t space that governs the
* dirty bitmaps.
* Called with the ramlist lock held.
*/
static ram_addr_t find_ram_offset(ram_addr_t size)
{
RAMBlock *block, *next_block;
@ -1673,19 +1683,33 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
}
RAMBLOCK_FOREACH(block) {
ram_addr_t end, next = RAM_ADDR_MAX;
ram_addr_t candidate, next = RAM_ADDR_MAX;
end = block->offset + block->max_length;
/* Align blocks to start on a 'long' in the bitmap
* which makes the bitmap sync'ing take the fast path.
*/
candidate = block->offset + block->max_length;
candidate = ROUND_UP(candidate, BITS_PER_LONG << TARGET_PAGE_BITS);
/* Search for the closest following block
* and find the gap.
*/
RAMBLOCK_FOREACH(next_block) {
if (next_block->offset >= end) {
if (next_block->offset >= candidate) {
next = MIN(next, next_block->offset);
}
}
if (next - end >= size && next - end < mingap) {
offset = end;
mingap = next - end;
/* If it fits remember our place and remember the size
* of gap, but keep going so that we might find a smaller
* gap to fill so avoiding fragmentation.
*/
if (next - candidate >= size && next - candidate < mingap) {
offset = candidate;
mingap = next - candidate;
}
trace_find_ram_offset_loop(size, candidate, offset, next, mingap);
}
if (offset == RAM_ADDR_MAX) {
@ -1694,6 +1718,8 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
abort();
}
trace_find_ram_offset(size, offset);
return offset;
}

View File

@ -37,7 +37,7 @@
if (STM_ADC_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -40,7 +40,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/* Fields for FlashPartInfo->flags */

View File

@ -33,7 +33,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} while (0);
} while (0)
#else
#define DB_PRINT(...)
#endif

View File

@ -34,7 +34,7 @@
if (STM_USART_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -31,7 +31,7 @@ typedef struct Terminal3270 {
uint8_t outv[OUTPUT_BUFFER_SIZE];
int in_len;
bool handshake_done;
guint timer_tag;
GSource *timer_src;
} Terminal3270;
#define TYPE_TERMINAL_3270 "x-terminal3270"
@ -45,6 +45,15 @@ static int terminal_can_read(void *opaque)
return INPUT_BUFFER_SIZE - t->in_len;
}
static void terminal_timer_cancel(Terminal3270 *t)
{
if (t->timer_src) {
g_source_destroy(t->timer_src);
g_source_unref(t->timer_src);
t->timer_src = NULL;
}
}
/*
* Protocol handshake done,
* signal guest by an unsolicited DE irq.
@ -90,12 +99,9 @@ static void terminal_read(void *opaque, const uint8_t *buf, int size)
assert(size <= (INPUT_BUFFER_SIZE - t->in_len));
if (t->timer_tag) {
g_source_remove(t->timer_tag);
t->timer_tag = 0;
}
t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
terminal_timer_cancel(t);
t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
send_timing_mark_cb, t);
memcpy(&t->inv[t->in_len], buf, size);
t->in_len += size;
if (t->in_len < 2) {
@ -145,10 +151,7 @@ static void chr_event(void *opaque, int event)
/* Ensure the initial status correct, always reset them. */
t->in_len = 0;
t->handshake_done = false;
if (t->timer_tag) {
g_source_remove(t->timer_tag);
t->timer_tag = 0;
}
terminal_timer_cancel(t);
switch (event) {
case CHR_EVENT_OPENED:
@ -157,7 +160,8 @@ static void chr_event(void *opaque, int event)
* char-socket.c. Once qemu receives the terminal-type of the
* client, mark handshake done and trigger everything rolling again.
*/
t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
send_timing_mark_cb, t);
break;
case CHR_EVENT_CLOSED:
sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;

View File

@ -63,7 +63,7 @@
if (DEBUG_CG3) { \
printf("CG3: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)

View File

@ -39,7 +39,7 @@
if (DEBUG_DPCD) { \
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define DPCD_READABLE_AREA 0x600

View File

@ -34,7 +34,7 @@
if (DEBUG_DP) { \
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/*
* Register offset for DP.

View File

@ -29,7 +29,7 @@
if (PL330_ERR_DEBUG >= lvl) {\
fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -43,7 +43,7 @@
if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
REG32(CTRL, 0x00)
FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */

View File

@ -34,7 +34,7 @@
if (DEBUG_DPDMA) { \
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/*
* Registers offset for DPDMA.

View File

@ -30,7 +30,7 @@
if (DEBUG_I2CDDC) { \
qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/* Structure defining a monitor's characteristics in a
* readable format: this should be passed to build_edid_blob()

View File

@ -1695,9 +1695,14 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
align = memory_region_get_alignment(mr);
}
if (!pcms->acpi_dev) {
/*
* When -no-acpi is used with Q35 machine type, no ACPI is built,
* but pcms->acpi_dev is still created. Check !acpi_enabled in
* addition to cover this case.
*/
if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
"memory hotplug is not enabled: missing acpi device");
"memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}
@ -1729,9 +1734,14 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
if (!pcms->acpi_dev) {
/*
* When -no-acpi is used with Q35 machine type, no ACPI is built,
* but pcms->acpi_dev is still created. Check !acpi_enabled in
* addition to cover this case.
*/
if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
"memory hotplug is not enabled: missing acpi device");
"memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}

View File

@ -40,7 +40,7 @@
if (DEBUG_AUX) { \
qemu_log("aux: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)

View File

@ -52,7 +52,7 @@
if (DEBUG_DBDMA) { \
printf("DBDMA: " fmt , ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
if (DEBUG_DBDMA) { \
@ -60,7 +60,7 @@
printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
} \
} \
} while (0);
} while (0)
/*
*/

View File

@ -39,7 +39,7 @@ static uint64_t mmio_interface_counter;
if (DEBUG_MMIO_INTERFACE) { \
qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
} \
} while (0);
} while (0)
static void mmio_interface_init(Object *obj)
{

View File

@ -34,7 +34,7 @@
if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -30,7 +30,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define XILINX_LOCK_KEY 0x767b
#define XILINX_UNLOCK_KEY 0xdf0d

View File

@ -34,7 +34,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} while (0);
} while (0)
#else
#define DB_PRINT(...)
#endif

View File

@ -456,32 +456,32 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_RMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
do { \
{ \
uint16_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[2] & 0xf000)!=0xf000; \
(RES) |= (rda[3] & 0xf000)!=0x0000; \
} while (0); \
} \
break; \
case 0x01: \
case 0x02: \
do { \
{ \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
} while (0); \
} \
break; \
case 0x03: \
do { \
{ \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
} while (0); \
} \
break; \
} \
} while (0)
@ -489,22 +489,22 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_TMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
do { \
{ \
uint16_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[2] & 0xf000)!=0xf000; \
} while (0); \
} \
break; \
case 0x01: \
case 0x02: \
case 0x03: \
do { \
{ \
uint32_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
} while (0); \
} \
break; \
} \
} while (0)

View File

@ -80,7 +80,7 @@ static int nvram_post_load(void *opaque, int version_id)
}
/* Write back nvram contents */
s->file = fopen(s->filename, "wb");
s->file = s->filename ? fopen(s->filename, "wb") : NULL;
if (s->file) {
/* Write back contents, as 'wb' mode cleaned the file */
if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
@ -126,7 +126,7 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
/* Read current file */
file = fopen(s->filename, "rb");
file = s->filename ? fopen(s->filename, "rb") : NULL;
if (file) {
/* Read nvram contents */
if (fread(s->contents, s->chip_size, 1, file) != 1) {

View File

@ -1755,6 +1755,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
data->sector << BDRV_SECTOR_BITS,
&data->qiov, 0,
scsi_write_same_complete, data);
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
return;
}

View File

@ -482,6 +482,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
int rc;
int sg_version;
struct sg_scsi_id scsiid;
Error *local_err = NULL;
if (!s->conf.blk) {
error_setg(errp, "drive property not set");
@ -515,6 +516,13 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
return;
}
blkconf_apply_backend_options(&s->conf,
blk_is_read_only(s->conf.blk),
true, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
/* define device state */
s->type = scsiid.scsi_type;
@ -565,6 +573,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -35,7 +35,7 @@
if (MSS_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -35,7 +35,7 @@
if (STM_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -36,7 +36,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} while (0);
} while (0)
#else
#define DB_PRINT(...)
#endif

View File

@ -43,7 +43,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/* config register */
#define R_CONFIG (0x00 / 4)

View File

@ -37,7 +37,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)

View File

@ -24,7 +24,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} while (0);
} while (0)
#else
#define DB_PRINT(...)
#endif

View File

@ -70,6 +70,7 @@ typedef struct HPETState {
MemoryRegion iomem;
uint64_t hpet_offset;
bool hpet_offset_saved;
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
uint32_t flags;
uint8_t rtc_irq_level;
@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque)
HPETState *s = opaque;
/* save current counter value */
s->hpet_counter = hpet_get_ticks(s);
if (hpet_enabled(s)) {
s->hpet_counter = hpet_get_ticks(s);
}
return 0;
}
@ -252,7 +255,10 @@ static int hpet_post_load(void *opaque, int version_id)
HPETState *s = opaque;
/* Recalculate the offset between the main counter and guest time */
s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (!s->hpet_offset_saved) {
s->hpet_offset = ticks_to_ns(s->hpet_counter)
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
/* Push number of timers into capability returned via HPET_ID */
s->capability &= ~HPET_ID_NUM_TIM_MASK;
@ -267,6 +273,13 @@ static int hpet_post_load(void *opaque, int version_id)
return 0;
}
static bool hpet_offset_needed(void *opaque)
{
HPETState *s = opaque;
return hpet_enabled(s) && s->hpet_offset_saved;
}
static bool hpet_rtc_irq_level_needed(void *opaque)
{
HPETState *s = opaque;
@ -285,6 +298,17 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = {
}
};
static const VMStateDescription vmstate_hpet_offset = {
.name = "hpet/offset",
.version_id = 1,
.minimum_version_id = 1,
.needed = hpet_offset_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT64(hpet_offset, HPETState),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_hpet_timer = {
.name = "hpet_timer",
.version_id = 1,
@ -320,6 +344,7 @@ static const VMStateDescription vmstate_hpet = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_hpet_rtc_irq_level,
&vmstate_hpet_offset,
NULL
}
};
@ -762,6 +787,7 @@ static Property hpet_device_properties[] = {
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -36,7 +36,7 @@
if (MSS_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -34,7 +34,7 @@
if (STM_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
} while (0);
} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)

View File

@ -38,7 +38,7 @@
if (DEBUG_TPM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
#define TPM_PASSTHROUGH(obj) \

View File

@ -90,7 +90,7 @@ typedef struct TPMState {
if (DEBUG_TIS) { \
printf(fmt, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
/* tis registers */
#define TPM_TIS_REG_ACCESS 0x00

View File

@ -256,6 +256,9 @@ Chardev *qemu_chardev_new(const char *id, const char *typename,
extern int term_escape_char;
GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
GSourceFunc func, void *private);
/* console.c */
void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);

View File

@ -391,9 +391,10 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
uint64_t num_dirty = 0;
unsigned long *dest = rb->bmap;
/* start address is aligned at the start of a word? */
/* start address and length is aligned at the start of a word? */
if (((word * BITS_PER_LONG) << TARGET_PAGE_BITS) ==
(start + rb->offset)) {
(start + rb->offset) &&
!(length & ((BITS_PER_LONG << TARGET_PAGE_BITS) - 1))) {
int k;
int nr = BITS_TO_LONGS(length >> TARGET_PAGE_BITS);
unsigned long * const *src;

View File

@ -2,7 +2,11 @@
#define HW_COMPAT_H
#define HW_COMPAT_2_11 \
/* empty */
{\
.driver = "hpet",\
.property = "hpet-offset-saved",\
.value = "false",\
},
#define HW_COMPAT_2_10 \
{\

View File

@ -59,5 +59,6 @@ ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
ReadLineFlushFunc *flush_func,
void *opaque,
ReadLineCompletionFunc *completion_finder);
void readline_free(ReadLineState *rs);
#endif /* READLINE_H */

View File

@ -22,9 +22,31 @@ typedef struct QemuThread QemuThread;
void qemu_mutex_init(QemuMutex *mutex);
void qemu_mutex_destroy(QemuMutex *mutex);
void qemu_mutex_lock(QemuMutex *mutex);
int qemu_mutex_trylock(QemuMutex *mutex);
void qemu_mutex_unlock(QemuMutex *mutex);
int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line);
#define qemu_mutex_lock(mutex) \
qemu_mutex_lock_impl(mutex, __FILE__, __LINE__)
#define qemu_mutex_trylock(mutex) \
qemu_mutex_trylock_impl(mutex, __FILE__, __LINE__)
#define qemu_mutex_unlock(mutex) \
qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__)
static inline void (qemu_mutex_lock)(QemuMutex *mutex)
{
qemu_mutex_lock(mutex);
}
static inline int (qemu_mutex_trylock)(QemuMutex *mutex)
{
return qemu_mutex_trylock(mutex);
}
static inline void (qemu_mutex_unlock)(QemuMutex *mutex)
{
qemu_mutex_unlock(mutex);
}
/* Prototypes for other functions are in thread-posix.h/thread-win32.h. */
void qemu_rec_mutex_init(QemuRecMutex *mutex);
@ -39,7 +61,16 @@ void qemu_cond_destroy(QemuCond *cond);
*/
void qemu_cond_signal(QemuCond *cond);
void qemu_cond_broadcast(QemuCond *cond);
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex);
void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex,
const char *file, const int line);
#define qemu_cond_wait(cond, mutex) \
qemu_cond_wait_impl(cond, mutex, __FILE__, __LINE__)
static inline void (qemu_cond_wait)(QemuCond *cond, QemuMutex *mutex)
{
qemu_cond_wait(cond, mutex);
}
void qemu_sem_init(QemuSemaphore *sem, int init);
void qemu_sem_post(QemuSemaphore *sem);

View File

@ -88,7 +88,7 @@ static uint32_t known_capabilities = RDMA_CAPABILITY_PIN_ALL;
} \
return rdma->error_state; \
} \
} while (0);
} while (0)
/*
* A work request ID is 64-bits and we split up these bits

View File

@ -583,7 +583,7 @@ static void monitor_data_destroy(Monitor *mon)
if (monitor_is_qmp(mon)) {
json_message_parser_destroy(&mon->qmp.parser);
}
g_free(mon->rs);
readline_free(mon->rs);
QDECREF(mon->outbuf);
qemu_mutex_destroy(&mon->out_lock);
}

View File

@ -131,6 +131,8 @@ modules:
# If called with only a single argument, will print nothing in quiet mode.
quiet-command = $(if $(V),$1,$(if $(2),@printf " %-7s %s\n" $2 $3 && $1, @$1))
MAKEFLAGS += $(if $(V),,--no-print-directory --quiet)
# cc-option
# Usage: CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)

View File

@ -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"]))

View File

@ -1622,6 +1622,11 @@ sub process {
}
}
# 'do ... while (0/false)' only makes sense in macros, without trailing ';'
if ($line =~ /while\s*\((0|false)\);/) {
ERROR("suspicious ; after while (0)\n" . $herecurr);
}
# Check relative indent for conditionals and blocks.
if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
my ($s, $c) = ($stat, $cond);

View File

@ -26,7 +26,7 @@ import os, sys
sys.path.append(os.path.dirname(__file__))
from qemugdb import aio, mtree, coroutine
from qemugdb import aio, mtree, coroutine, tcg, timers
class QemuCommand(gdb.Command):
'''Prefix for QEMU debug support commands'''
@ -38,6 +38,8 @@ QemuCommand()
coroutine.CoroutineCommand()
mtree.MtreeCommand()
aio.HandlersCommand()
tcg.TCGLockStatusCommand()
timers.TimersCommand()
coroutine.CoroutineSPFunction()
coroutine.CoroutinePCFunction()

46
scripts/qemugdb/tcg.py Normal file
View File

@ -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))

54
scripts/qemugdb/timers.py Normal file
View File

@ -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")

View File

@ -322,18 +322,18 @@ int scsi_convert_sense(uint8_t *in_buf, int in_len,
SCSISense sense;
bool fixed_in;
fixed_in = (in_buf[0] & 2) == 0;
if (in_len && fixed == fixed_in) {
memcpy(buf, in_buf, MIN(len, in_len));
return MIN(len, in_len);
if (in_len == 0) {
return scsi_build_sense_buf(buf, len, SENSE_CODE(NO_SENSE), fixed);
}
if (in_len == 0) {
sense = SENSE_CODE(NO_SENSE);
fixed_in = (in_buf[0] & 2) == 0;
if (fixed == fixed_in) {
memcpy(buf, in_buf, MIN(len, in_len));
return MIN(len, in_len);
} else {
sense = scsi_parse_sense_buf(in_buf, in_len);
return scsi_build_sense_buf(buf, len, sense, fixed);
}
return scsi_build_sense_buf(buf, len, sense, fixed);
}
int scsi_sense_to_errno(int key, int asc, int ascq)

View File

@ -400,7 +400,7 @@ static void unallocated_encoding(DisasContext *s)
"at pc=%016" PRIx64 "\n", \
__FILE__, __LINE__, insn, s->pc - 4); \
unallocated_encoding(s); \
} while (0);
} while (0)
static void init_tmp_a64_array(DisasContext *s)
{

View File

@ -4147,6 +4147,48 @@ static void x86_disas_set_info(CPUState *cs, disassemble_info *info)
info->cap_insn_split = 8;
}
void x86_update_hflags(CPUX86State *env)
{
uint32_t hflags;
#define HFLAG_COPY_MASK \
~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
hflags = env->hflags & HFLAG_COPY_MASK;
hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
if (env->cr[4] & CR4_OSFXSR_MASK) {
hflags |= HF_OSFXSR_MASK;
}
if (env->efer & MSR_EFER_LMA) {
hflags |= HF_LMA_MASK;
}
if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
} else {
hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_CS32_SHIFT);
hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_SS32_SHIFT);
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
!(hflags & HF_CS32_MASK)) {
hflags |= HF_ADDSEG_MASK;
} else {
hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
}
}
env->hflags = hflags;
}
static Property x86_cpu_properties[] = {
#ifdef CONFIG_USER_ONLY
/* apic_id = 0 by default for *-user, see commit 9886e834 */

View File

@ -1778,4 +1778,6 @@ bool cpu_is_bsp(X86CPU *cpu);
void x86_cpu_xrstor_all_areas(X86CPU *cpu, const X86XSaveArea *buf);
void x86_cpu_xsave_all_areas(X86CPU *cpu, X86XSaveArea *buf);
void x86_update_hflags(CPUX86State* env);
#endif /* I386_CPU_H */

View File

@ -782,56 +782,6 @@ static int hax_set_segments(CPUArchState *env, struct vcpu_state_t *sregs)
return 0;
}
/*
* After get the state from the kernel module, some
* qemu emulator state need be updated also
*/
static int hax_setup_qemu_emulator(CPUArchState *env)
{
#define HFLAG_COPY_MASK (~( \
HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK))
uint32_t hflags;
hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<
(HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);
if (env->efer & MSR_EFER_LMA) {
hflags |= HF_LMA_MASK;
}
if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
} else {
hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_CS32_SHIFT);
hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_SS32_SHIFT);
if (!(env->cr[0] & CR0_PE_MASK) ||
(env->eflags & VM_MASK) || !(hflags & HF_CS32_MASK)) {
hflags |= HF_ADDSEG_MASK;
} else {
hflags |= ((env->segs[R_DS].base |
env->segs[R_ES].base |
env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
}
}
hflags &= ~HF_SMM_MASK;
env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;
return 0;
}
static int hax_sync_vcpu_register(CPUArchState *env, int set)
{
struct vcpu_state_t regs;
@ -887,9 +837,6 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
return -1;
}
}
if (!set) {
hax_setup_qemu_emulator(env);
}
return 0;
}
@ -1070,6 +1017,7 @@ static int hax_arch_get_registers(CPUArchState *env)
return ret;
}
x86_update_hflags(env);
return 0;
}

View File

@ -297,7 +297,6 @@ int hvf_get_registers(CPUState *cpu_state)
X86CPU *x86cpu = X86_CPU(cpu_state);
CPUX86State *env = &x86cpu->env;
env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
env->regs[R_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
@ -333,6 +332,7 @@ int hvf_get_registers(CPUState *cpu_state)
env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
x86_update_hflags(env);
return 0;
}

View File

@ -92,8 +92,9 @@ static bool has_msr_hv_stimer;
static bool has_msr_hv_frequencies;
static bool has_msr_xss;
static bool has_msr_architectural_pmu;
static uint32_t num_architectural_pmu_counters;
static uint32_t has_architectural_pmu_version;
static uint32_t num_architectural_pmu_gp_counters;
static uint32_t num_architectural_pmu_fixed_counters;
static int has_xsave;
static int has_xcrs;
@ -872,19 +873,28 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
if (limit >= 0x0a) {
uint32_t ver;
uint32_t eax, edx;
cpu_x86_cpuid(env, 0x0a, 0, &ver, &unused, &unused, &unused);
if ((ver & 0xff) > 0) {
has_msr_architectural_pmu = true;
num_architectural_pmu_counters = (ver & 0xff00) >> 8;
cpu_x86_cpuid(env, 0x0a, 0, &eax, &unused, &unused, &edx);
has_architectural_pmu_version = eax & 0xff;
if (has_architectural_pmu_version > 0) {
num_architectural_pmu_gp_counters = (eax & 0xff00) >> 8;
/* Shouldn't be more than 32, since that's the number of bits
* available in EBX to tell us _which_ counters are available.
* Play it safe.
*/
if (num_architectural_pmu_counters > MAX_GP_COUNTERS) {
num_architectural_pmu_counters = MAX_GP_COUNTERS;
if (num_architectural_pmu_gp_counters > MAX_GP_COUNTERS) {
num_architectural_pmu_gp_counters = MAX_GP_COUNTERS;
}
if (has_architectural_pmu_version > 1) {
num_architectural_pmu_fixed_counters = edx & 0x1f;
if (num_architectural_pmu_fixed_counters > MAX_FIXED_COUNTERS) {
num_architectural_pmu_fixed_counters = MAX_FIXED_COUNTERS;
}
}
}
}
@ -1650,32 +1660,36 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
}
if (has_msr_architectural_pmu) {
/* Stop the counter. */
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
if (has_architectural_pmu_version > 0) {
if (has_architectural_pmu_version > 1) {
/* Stop the counter. */
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
}
/* Set the counter values. */
for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
for (i = 0; i < num_architectural_pmu_fixed_counters; i++) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i,
env->msr_fixed_counters[i]);
}
for (i = 0; i < num_architectural_pmu_counters; i++) {
for (i = 0; i < num_architectural_pmu_gp_counters; i++) {
kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i,
env->msr_gp_counters[i]);
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i,
env->msr_gp_evtsel[i]);
}
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
env->msr_global_status);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
env->msr_global_ovf_ctrl);
if (has_architectural_pmu_version > 1) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS,
env->msr_global_status);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL,
env->msr_global_ovf_ctrl);
/* Now start the PMU. */
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
env->msr_fixed_ctr_ctrl);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
env->msr_global_ctrl);
/* Now start the PMU. */
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL,
env->msr_fixed_ctr_ctrl);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL,
env->msr_global_ctrl);
}
}
/*
* Hyper-V partition-wide MSRs: to avoid clearing them on cpu hot-add,
@ -1877,7 +1891,6 @@ static int kvm_get_sregs(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
struct kvm_sregs sregs;
uint32_t hflags;
int bit, i, ret;
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_SREGS, &sregs);
@ -1919,44 +1932,7 @@ static int kvm_get_sregs(X86CPU *cpu)
env->efer = sregs.efer;
/* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */
#define HFLAG_COPY_MASK \
~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
hflags = env->hflags & HFLAG_COPY_MASK;
hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
if (env->cr[4] & CR4_OSFXSR_MASK) {
hflags |= HF_OSFXSR_MASK;
}
if (env->efer & MSR_EFER_LMA) {
hflags |= HF_LMA_MASK;
}
if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
} else {
hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_CS32_SHIFT);
hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
(DESC_B_SHIFT - HF_SS32_SHIFT);
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK) ||
!(hflags & HF_CS32_MASK)) {
hflags |= HF_ADDSEG_MASK;
} else {
hflags |= ((env->segs[R_DS].base | env->segs[R_ES].base |
env->segs[R_SS].base) != 0) << HF_ADDSEG_SHIFT;
}
}
env->hflags = hflags;
x86_update_hflags(env);
return 0;
}
@ -2030,15 +2006,17 @@ static int kvm_get_msrs(X86CPU *cpu)
if (env->features[FEAT_KVM] & (1 << KVM_FEATURE_STEAL_TIME)) {
kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0);
}
if (has_msr_architectural_pmu) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
if (has_architectural_pmu_version > 0) {
if (has_architectural_pmu_version > 1) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
}
for (i = 0; i < num_architectural_pmu_fixed_counters; i++) {
kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, 0);
}
for (i = 0; i < num_architectural_pmu_counters; i++) {
for (i = 0; i < num_architectural_pmu_gp_counters; i++) {
kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, 0);
kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, 0);
}
@ -3492,6 +3470,7 @@ int kvm_arch_release_virq_post(int virq)
if (entry->virq == virq) {
trace_kvm_x86_remove_msi_route(virq);
QLIST_REMOVE(entry, list);
g_free(entry);
break;
}
}

View File

@ -682,13 +682,13 @@ static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
do { \
e = SIGNED_EVEN(a, df); \
o = SIGNED_ODD(a, df); \
} while (0);
} while (0)
#define UNSIGNED_EXTRACT(e, o, a, df) \
do { \
e = UNSIGNED_EVEN(a, df); \
o = UNSIGNED_ODD(a, df); \
} while (0);
} while (0)
static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
@ -1120,9 +1120,11 @@ void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
#define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
#define MSA_LOOP(DF) \
do { \
for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
MSA_DO_ ## DF \
}
MSA_DO_ ## DF; \
} \
} while (0)
#define MSA_FN_DF(FUNC) \
void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
@ -1135,17 +1137,17 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
uint32_t i; \
switch (df) { \
case DF_BYTE: \
MSA_LOOP_B \
MSA_LOOP_B; \
break; \
case DF_HALF: \
MSA_LOOP_H \
MSA_LOOP_H; \
break; \
case DF_WORD: \
MSA_LOOP_W \
MSA_LOOP_W; \
break; \
case DF_DOUBLE: \
MSA_LOOP_D \
break; \
MSA_LOOP_D; \
break; \
default: \
assert(0); \
} \
@ -1168,7 +1170,7 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
do { \
R##DF(pwx, i) = pwt->DF[2*i]; \
L##DF(pwx, i) = pws->DF[2*i]; \
} while (0);
} while (0)
MSA_FN_DF(pckev_df)
#undef MSA_DO
@ -1176,7 +1178,7 @@ MSA_FN_DF(pckev_df)
do { \
R##DF(pwx, i) = pwt->DF[2*i+1]; \
L##DF(pwx, i) = pws->DF[2*i+1]; \
} while (0);
} while (0)
MSA_FN_DF(pckod_df)
#undef MSA_DO
@ -1184,7 +1186,7 @@ MSA_FN_DF(pckod_df)
do { \
pwx->DF[2*i] = L##DF(pwt, i); \
pwx->DF[2*i+1] = L##DF(pws, i); \
} while (0);
} while (0)
MSA_FN_DF(ilvl_df)
#undef MSA_DO
@ -1192,7 +1194,7 @@ MSA_FN_DF(ilvl_df)
do { \
pwx->DF[2*i] = R##DF(pwt, i); \
pwx->DF[2*i+1] = R##DF(pws, i); \
} while (0);
} while (0)
MSA_FN_DF(ilvr_df)
#undef MSA_DO
@ -1200,7 +1202,7 @@ MSA_FN_DF(ilvr_df)
do { \
pwx->DF[2*i] = pwt->DF[2*i]; \
pwx->DF[2*i+1] = pws->DF[2*i]; \
} while (0);
} while (0)
MSA_FN_DF(ilvev_df)
#undef MSA_DO
@ -1208,7 +1210,7 @@ MSA_FN_DF(ilvev_df)
do { \
pwx->DF[2*i] = pwt->DF[2*i+1]; \
pwx->DF[2*i+1] = pws->DF[2*i+1]; \
} while (0);
} while (0)
MSA_FN_DF(ilvod_df)
#undef MSA_DO
#undef MSA_LOOP_COND
@ -1222,7 +1224,7 @@ MSA_FN_DF(ilvod_df)
uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
pwx->DF[i] = \
(pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
} while (0);
} while (0)
MSA_FN_DF(vshf_df)
#undef MSA_DO
#undef MSA_LOOP_COND

View File

@ -58,7 +58,7 @@
if (DEBUG_KVM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
} while (0);
} while (0)
#define kvm_vm_check_mem_attr(s, attr) \
kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr)

View File

@ -300,12 +300,16 @@ check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
check-qtest-m68k-y = tests/boot-serial-test$(EXESUF)
check-qtest-microblaze-y = tests/boot-serial-test$(EXESUF)
check-qtest-mips-y = tests/endianness-test$(EXESUF)
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
check-qtest-moxie-y = tests/boot-serial-test$(EXESUF)
check-qtest-ppc-y = tests/endianness-test$(EXESUF)
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
@ -358,6 +362,7 @@ check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
gcov-files-arm-y += hw/timer/arm_mptimer.c
check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
check-qtest-aarch64-y = tests/numa-test$(EXESUF)

View File

@ -32,7 +32,7 @@ typedef struct {
do { \
memread(addr, &field, sizeof(field)); \
addr += sizeof(field); \
} while (0);
} while (0)
#define ACPI_READ_ARRAY_PTR(arr, length, addr) \
do { \
@ -40,7 +40,7 @@ typedef struct {
for (idx = 0; idx < length; ++idx) { \
ACPI_READ_FIELD(arr[idx], addr); \
} \
} while (0);
} while (0)
#define ACPI_READ_ARRAY(arr, addr) \
ACPI_READ_ARRAY_PTR(arr, sizeof(arr) / sizeof(arr[0]), addr)
@ -56,7 +56,7 @@ typedef struct {
ACPI_READ_FIELD((table)->oem_revision, addr); \
ACPI_READ_ARRAY((table)->asl_compiler_id, addr); \
ACPI_READ_FIELD((table)->asl_compiler_revision, addr); \
} while (0);
} while (0)
#define ACPI_ASSERT_CMP(actual, expected) do { \
char ACPI_ASSERT_CMP_str[5] = {}; \
@ -77,7 +77,7 @@ typedef struct {
ACPI_READ_FIELD((field).bit_offset, addr); \
ACPI_READ_FIELD((field).access_width, addr); \
ACPI_READ_FIELD((field).address, addr); \
} while (0);
} while (0)
uint8_t acpi_calc_checksum(const uint8_t *data, int len);

View File

@ -24,6 +24,37 @@ static const uint8_t kernel_mcf5208[] = {
0x60, 0xfa /* bra.s loop */
};
static const uint8_t kernel_pls3adsp1800[] = {
0xb0, 0x00, 0x84, 0x00, /* imm 0x8400 */
0x30, 0x60, 0x00, 0x04, /* addik r3,r0,4 */
0x30, 0x80, 0x00, 0x54, /* addik r4,r0,'T' */
0xf0, 0x83, 0x00, 0x00, /* sbi r4,r3,0 */
0xb8, 0x00, 0xff, 0xfc /* bri -4 loop */
};
static const uint8_t kernel_plml605[] = {
0xe0, 0x83, 0x00, 0xb0, /* imm 0x83e0 */
0x00, 0x10, 0x60, 0x30, /* addik r3,r0,0x1000 */
0x54, 0x00, 0x80, 0x30, /* addik r4,r0,'T' */
0x00, 0x00, 0x83, 0xf0, /* sbi r4,r3,0 */
0xfc, 0xff, 0x00, 0xb8 /* bri -4 loop */
};
static const uint8_t bios_moxiesim[] = {
0x20, 0x10, 0x00, 0x00, 0x03, 0xf8, /* ldi.s r1,0x3f8 */
0x1b, 0x20, 0x00, 0x00, 0x00, 0x54, /* ldi.b r2,'T' */
0x1e, 0x12, /* st.b r1,r2 */
0x1a, 0x00, 0x00, 0x00, 0x10, 0x00 /* jmpa 0x1000 */
};
static const uint8_t bios_raspi2[] = {
0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */
0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */
0x00, 0x20, 0xc3, 0xe5, /* strb r2,[r3] */
0xfb, 0xff, 0xff, 0xea, /* b loop */
0x00, 0x10, 0x20, 0x3f, /* 0x3f201000 = UART0 base addr */
};
typedef struct testdef {
const char *arch; /* Target architecture */
const char *machine; /* Name of the machine */
@ -50,6 +81,12 @@ static testdef_t tests[] = {
{ "s390x", "s390-ccw-virtio",
"-nodefaults -device sclpconsole,chardev=serial0", "virtio device" },
{ "m68k", "mcf5208evb", "", "TT", sizeof(kernel_mcf5208), kernel_mcf5208 },
{ "microblaze", "petalogix-s3adsp1800", "", "TT",
sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
{ "microblazeel", "petalogix-ml605", "", "TT",
sizeof(kernel_plml605), kernel_plml605 },
{ "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, bios_moxiesim },
{ "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
{ NULL }
};

View File

@ -59,6 +59,8 @@ static void do_test_equality(bool expected, int _, ...)
g_assert(qobject_is_equal(args[i], args[j]) == expected);
}
}
g_free(args);
}
#define check_equal(...) \

View File

@ -3,7 +3,7 @@ ENV PACKAGES \
ccache gettext git tar PyYAML sparse flex bison python2 bzip2 hostname \
glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \
gcc gcc-c++ clang make perl which bc findutils libaio-devel \
nettle-devel \
nettle-devel libasan libubsan \
mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \
mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \
mingw32-libjpeg-turbo mingw32-libpng mingw32-curl mingw32-libssh2 \
@ -15,4 +15,4 @@ ENV PACKAGES \
RUN dnf install -y $PACKAGES
RUN rpm -q $PACKAGES | sort > /packages.txt
ENV FEATURES mingw clang pyyaml
ENV FEATURES mingw clang pyyaml asan

View File

@ -17,7 +17,7 @@ requires clang
cd "$BUILD_DIR"
OPTS="--enable-debug --cxx=clang++ --cc=clang --host-cc=clang"
OPTS="--cxx=clang++ --cc=clang --host-cc=clang"
# -fsanitize=undefined is broken on Fedora 23, skip it for now
# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
#OPTS="$OPTS --extra-cflags=-fsanitize=undefined \

26
tests/docker/test-debug Executable file
View File

@ -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

View File

@ -22,7 +22,6 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \
build_qemu --cross-prefix=$prefix \
--enable-trace-backends=simple \
--enable-debug \
--enable-gnutls \
--enable-nettle \
--enable-curl \
@ -35,4 +34,3 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
make clean
done

View File

@ -271,7 +271,7 @@ static void add_query_tests(QmpSchema *schema)
{
SchemaInfoList *tail;
SchemaInfo *si, *arg_type, *ret_type;
const char *test_name;
char *test_name;
/* Test the query-like commands */
for (tail = schema->list; tail; tail = tail->next) {
@ -297,6 +297,7 @@ static void add_query_tests(QmpSchema *schema)
test_name = g_strdup_printf("qmp/%s", si->name);
qtest_add_data_func(test_name, si->name, test_query);
g_free(test_name);
}
}

View File

@ -39,7 +39,7 @@ do \
fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
exit (EXIT_FAILURE); \
} \
} while (0);
} while (0)
unsigned char *dummybuf;
static unsigned int pagesize;

View File

@ -67,7 +67,6 @@ static void coroutine_fn verify_entered_step_2(void *opaque)
/* Once more to check it still works after yielding */
g_assert(qemu_coroutine_entered(caller));
g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
qemu_coroutine_yield();
}
static void coroutine_fn verify_entered_step_1(void *opaque)

View File

@ -283,7 +283,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
return;
}
do {
while (1) {
struct iovec *sg;
ssize_t ret, total = 0;
unsigned int num;
@ -343,7 +343,9 @@ vubr_backend_recv_cb(int sock, void *ctx)
free(elem);
elem = NULL;
} while (false); /* could loop if DONTWAIT worked? */
break; /* could loop if DONTWAIT worked? */
}
if (mhdr_cnt) {
mhdr.num_buffers = i;

View File

@ -55,6 +55,10 @@ dma_complete(void *dbs, int ret, void *cb) "dbs=%p ret=%d cb=%p"
dma_blk_cb(void *dbs, int ret) "dbs=%p ret=%d"
dma_map_wait(void *dbs) "dbs=%p"
# # exec.c
find_ram_offset(uint64_t size, uint64_t offset) "size: 0x%" PRIx64 " @ 0x%" PRIx64
find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, uint64_t next, uint64_t mingap) "trying size: 0x%" PRIx64 " @ 0x%" PRIx64 ", offset: 0x%" PRIx64" next: 0x%" PRIx64 " mingap: 0x%" PRIx64
# memory.c
memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
memory_region_ops_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"

View File

@ -34,22 +34,22 @@
#define setRed(r, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
(((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
} while (0);
} while (0)
#define setGreen(g, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
(((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
} while (0);
} while (0)
#define setBlue(b, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
(((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
} while (0);
} while (0)
#define setAlpha(a, pcolor) do { \
*pcolor = ((*pcolor) & (~(dpf->Amask))) + \
(((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
} while (0);
} while (0)
static void glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
SDL_Rect *dst_rect)

View File

@ -105,7 +105,8 @@ static void cleanup_infolist(CommandLineParameterInfoList *head)
if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
del_entry = cur->next;
cur->next = cur->next->next;
g_free(del_entry);
del_entry->next = NULL;
qapi_free_CommandLineParameterInfoList(del_entry);
break;
}
pre_entry = pre_entry->next;

View File

@ -57,26 +57,28 @@ void qemu_mutex_destroy(QemuMutex *mutex)
error_exit(err, __func__);
}
void qemu_mutex_lock(QemuMutex *mutex)
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
trace_qemu_mutex_lock(mutex, file, line);
err = pthread_mutex_lock(&mutex->lock);
if (err)
error_exit(err, __func__);
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
}
int qemu_mutex_trylock(QemuMutex *mutex)
int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
err = pthread_mutex_trylock(&mutex->lock);
if (err == 0) {
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
return 0;
}
if (err != EBUSY) {
@ -85,15 +87,16 @@ int qemu_mutex_trylock(QemuMutex *mutex)
return -EBUSY;
}
void qemu_mutex_unlock(QemuMutex *mutex)
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(mutex->initialized);
trace_qemu_mutex_unlocked(mutex);
err = pthread_mutex_unlock(&mutex->lock);
if (err)
error_exit(err, __func__);
trace_qemu_mutex_unlock(mutex, file, line);
}
void qemu_rec_mutex_init(QemuRecMutex *mutex)
@ -152,14 +155,14 @@ void qemu_cond_broadcast(QemuCond *cond)
error_exit(err, __func__);
}
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
{
int err;
assert(cond->initialized);
trace_qemu_mutex_unlocked(mutex);
trace_qemu_mutex_unlock(mutex, file, line);
err = pthread_cond_wait(&cond->cond, &mutex->lock);
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
if (err)
error_exit(err, __func__);
}

View File

@ -56,30 +56,32 @@ void qemu_mutex_destroy(QemuMutex *mutex)
InitializeSRWLock(&mutex->lock);
}
void qemu_mutex_lock(QemuMutex *mutex)
void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line)
{
assert(mutex->initialized);
trace_qemu_mutex_lock(mutex, file, line);
AcquireSRWLockExclusive(&mutex->lock);
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
}
int qemu_mutex_trylock(QemuMutex *mutex)
int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line)
{
int owned;
assert(mutex->initialized);
owned = TryAcquireSRWLockExclusive(&mutex->lock);
if (owned) {
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
return 0;
}
return -EBUSY;
}
void qemu_mutex_unlock(QemuMutex *mutex)
void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line)
{
assert(mutex->initialized);
trace_qemu_mutex_unlocked(mutex);
trace_qemu_mutex_unlock(mutex, file, line);
ReleaseSRWLockExclusive(&mutex->lock);
}
@ -140,12 +142,12 @@ void qemu_cond_broadcast(QemuCond *cond)
WakeAllConditionVariable(&cond->var);
}
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, const int line)
{
assert(cond->initialized);
trace_qemu_mutex_unlocked(mutex);
trace_qemu_mutex_unlock(mutex, file, line);
SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
trace_qemu_mutex_locked(mutex);
trace_qemu_mutex_locked(mutex, file, line);
}
void qemu_sem_init(QemuSemaphore *sem, int init)

View File

@ -500,12 +500,28 @@ const char *readline_get_history(ReadLineState *rs, unsigned int index)
return rs->history[index];
}
void readline_free(ReadLineState *rs)
{
int i;
if (!rs) {
return;
}
for (i = 0; i < READLINE_MAX_CMDS; i++) {
g_free(rs->history[i]);
}
for (i = 0; i < READLINE_MAX_COMPLETIONS; i++) {
g_free(rs->completions[i]);
}
g_free(rs);
}
ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
ReadLineFlushFunc *flush_func,
void *opaque,
ReadLineCompletionFunc *completion_finder)
{
ReadLineState *rs = g_malloc0(sizeof(*rs));
ReadLineState *rs = g_new0(ReadLineState, 1);
rs->hist_entry = -1;
rs->opaque = opaque;

View File

@ -56,6 +56,7 @@ lockcnt_futex_wait(const void *lockcnt, int val) "lockcnt %p waiting on %d"
lockcnt_futex_wait_resume(const void *lockcnt, int new) "lockcnt %p after wait: %d"
lockcnt_futex_wake(const void *lockcnt) "lockcnt %p waking up one waiter"
# util/qemu-thread-posix.c
qemu_mutex_locked(void *lock) "locked mutex %p"
qemu_mutex_unlocked(void *lock) "unlocked mutex %p"
# util/qemu-thread.c
qemu_mutex_lock(void *mutex, const char *file, const int line) "waiting on mutex %p (%s:%d)"
qemu_mutex_locked(void *mutex, const char *file, const int line) "taken mutex %p (%s:%d)"
qemu_mutex_unlock(void *mutex, const char *file, const int line) "released mutex %p (%s:%d)"

9
vl.c
View File

@ -2318,7 +2318,7 @@ static void qemu_add_data_dir(const char *path)
return; /* duplicate */
}
}
data_dir[data_dir_idx++] = path;
data_dir[data_dir_idx++] = g_strdup(path);
}
static inline bool nonempty_str(const char *str)
@ -3078,7 +3078,7 @@ int main(int argc, char **argv, char **envp)
Error *main_loop_err = NULL;
Error *err = NULL;
bool list_data_dirs = false;
char **dirs;
char *dir, **dirs;
typedef struct BlockdevOptions_queue {
BlockdevOptions *bdo;
Location loc;
@ -4181,9 +4181,12 @@ int main(int argc, char **argv, char **envp)
for (i = 0; dirs[i] != NULL; i++) {
qemu_add_data_dir(dirs[i]);
}
g_strfreev(dirs);
/* try to find datadir relative to the executable path */
qemu_add_data_dir(os_find_datadir());
dir = os_find_datadir();
qemu_add_data_dir(dir);
g_free(dir);
/* add the datadir specified when building */
qemu_add_data_dir(CONFIG_QEMU_DATADIR);