cpus: Fix configure_icount() error API violation
The Error ** argument must be NULL, &error_abort, &error_fatal, or a pointer to a variable containing NULL. Passing an argument of the latter kind twice without clearing it in between is wrong: if the first call sets an error, it no longer points to NULL for the second call. configure_icount() is wrong that way. Harmless, because its @errp is always &error_abort or &error_fatal. Just as wrong (and just as harmless): when it fails, it can still update global state. Fix all that. Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20200422130719.28225-4-armbru@redhat.com>
This commit is contained in:
parent
77ed971b9d
commit
abc9bf69a6
49
cpus.c
49
cpus.c
@ -797,40 +797,49 @@ void cpu_ticks_init(void)
|
|||||||
|
|
||||||
void configure_icount(QemuOpts *opts, Error **errp)
|
void configure_icount(QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
const char *option;
|
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;
|
||||||
char *rem_str = NULL;
|
char *rem_str = NULL;
|
||||||
|
|
||||||
option = qemu_opt_get(opts, "shift");
|
if (!option && qemu_opt_get(opts, "align")) {
|
||||||
if (!option) {
|
|
||||||
if (qemu_opt_get(opts, "align") != NULL) {
|
|
||||||
error_setg(errp, "Please specify shift option when using align");
|
error_setg(errp, "Please specify shift option when using align");
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
|
if (align && !sleep) {
|
||||||
|
error_setg(errp, "align=on and sleep=off are incompatible");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(option, "auto") != 0) {
|
||||||
|
errno = 0;
|
||||||
|
time_shift = strtol(option, &rem_str, 0);
|
||||||
|
if (errno != 0 || *rem_str != '\0' || !strlen(option)) {
|
||||||
|
error_setg(errp, "icount: Invalid shift value");
|
||||||
|
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) {
|
if (icount_sleep) {
|
||||||
timers_state.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
icount_align_option = qemu_opt_get_bool(opts, "align", false);
|
icount_align_option = align;
|
||||||
|
|
||||||
if (icount_align_option && !icount_sleep) {
|
if (time_shift >= 0) {
|
||||||
error_setg(errp, "align=on and sleep=off are incompatible");
|
timers_state.icount_time_shift = time_shift;
|
||||||
}
|
|
||||||
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)) {
|
|
||||||
error_setg(errp, "icount: Invalid shift value");
|
|
||||||
}
|
|
||||||
use_icount = 1;
|
use_icount = 1;
|
||||||
return;
|
return;
|
||||||
} else if (icount_align_option) {
|
|
||||||
error_setg(errp, "shift=auto and align=on are incompatible");
|
|
||||||
} else if (!icount_sleep) {
|
|
||||||
error_setg(errp, "shift=auto and sleep=off are incompatible");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use_icount = 2;
|
use_icount = 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user