diff options
Diffstat (limited to 'cpus.c')
-rw-r--r-- | cpus.c | 50 |
1 files changed, 29 insertions, 21 deletions
@@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/config-file.h" +#include "qemu/cutils.h" #include "migration/vmstate.h" #include "monitor/monitor.h" #include "qapi/error.h" @@ -797,40 +798,47 @@ void cpu_ticks_init(void) void configure_icount(QemuOpts *opts, Error **errp) { - const char *option; - char *rem_str = NULL; + const char *option = qemu_opt_get(opts, "shift"); + bool sleep = qemu_opt_get_bool(opts, "sleep", true); + bool align = qemu_opt_get_bool(opts, "align", false); + long time_shift = -1; - option = qemu_opt_get(opts, "shift"); - if (!option) { - if (qemu_opt_get(opts, "align") != NULL) { - error_setg(errp, "Please specify shift option when using align"); - } + if (!option && qemu_opt_get(opts, "align")) { + error_setg(errp, "Please specify shift option when using align"); return; } - icount_sleep = qemu_opt_get_bool(opts, "sleep", true); - if (icount_sleep) { - timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, - icount_timer_cb, NULL); - } - - icount_align_option = qemu_opt_get_bool(opts, "align", false); - - if (icount_align_option && !icount_sleep) { + if (align && !sleep) { error_setg(errp, "align=on and sleep=off are incompatible"); + return; } + if (strcmp(option, "auto") != 0) { - errno = 0; - timers_state.icount_time_shift = strtol(option, &rem_str, 0); - if (errno != 0 || *rem_str != '\0' || !strlen(option)) { + if (qemu_strtol(option, NULL, 0, &time_shift) < 0 + || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) { error_setg(errp, "icount: Invalid shift value"); + return; } - use_icount = 1; - return; } else if (icount_align_option) { error_setg(errp, "shift=auto and align=on are incompatible"); + return; } else if (!icount_sleep) { error_setg(errp, "shift=auto and sleep=off are incompatible"); + return; + } + + icount_sleep = sleep; + if (icount_sleep) { + timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT, + icount_timer_cb, NULL); + } + + icount_align_option = align; + + if (time_shift >= 0) { + timers_state.icount_time_shift = time_shift; + use_icount = 1; + return; } use_icount = 2; |