int fd_bootchk = 1;
static int no_reboot;
int no_shutdown = 0;
-int cursor_hide = 1;
int graphic_rotate = 0;
const char *watchdog;
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
.name = "accel",
.implied_opt_name = "accel",
.head = QTAILQ_HEAD_INITIALIZER(qemu_accel_opts.head),
- .merge_lists = true,
.desc = {
- {
- .name = "accel",
- .type = QEMU_OPT_STRING,
- .help = "Select the type of accelerator",
- },
- {
- .name = "thread",
- .type = QEMU_OPT_STRING,
- .help = "Enable/disable multi-threaded TCG",
- },
- { /* end of list */ }
+ /*
+ * no elements => accept any
+ * sanity checking will happen later
+ * when setting accelerator properties
+ */
+ { }
},
};
value = qemu_opt_get(opts, "driftfix");
if (value) {
if (!strcmp(value, "slew")) {
- static GlobalProperty slew_lost_ticks = {
- .driver = "mc146818rtc",
- .property = "lost_tick_policy",
- .value = "slew",
- };
-
- qdev_prop_register_global(&slew_lost_ticks);
+ object_register_sugar_prop("mc146818rtc",
+ "lost_tick_policy",
+ "slew");
} else if (!strcmp(value, "none")) {
/* discard is default */
} else {
static void configure_msg(QemuOpts *opts)
{
- enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true);
+ error_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
}
-/* Now we still need this for compatibility with XEN. */
-bool has_igd_gfx_passthru;
-static void igd_gfx_passthru(void)
-{
- has_igd_gfx_passthru = current_machine->igd_gfx_passthru;
-}
-
/***********************************************************/
/* USB devices */
}
}
+void qemu_system_guest_crashloaded(GuestPanicInformation *info)
+{
+ qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
+
+ qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
+ !!info, info);
+
+ if (info) {
+ qapi_free_GuestPanicInformation(info);
+ }
+}
+
void qemu_system_reset_request(ShutdownCause reason)
{
if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
RunState r;
ShutdownCause request;
- if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
- return false;
- }
if (preconfig_exit_requested) {
if (runstate_check(RUN_STATE_PRECONFIG)) {
runstate_set(RUN_STATE_PRELAUNCH);
pause_all_vcpus();
qemu_system_reset(request);
resume_all_vcpus();
+ /*
+ * runstate can change in pause_all_vcpus()
+ * as iothread mutex is unlocked
+ */
if (!runstate_check(RUN_STATE_RUNNING) &&
- !runstate_check(RUN_STATE_INMIGRATE)) {
+ !runstate_check(RUN_STATE_INMIGRATE) &&
+ !runstate_check(RUN_STATE_FINISH_MIGRATE)) {
runstate_set(RUN_STATE_PRELAUNCH);
}
}
{
const char *opts;
+ if (is_help_option(p)) {
+ qemu_display_help();
+ exit(0);
+ }
+
if (strstart(p, "sdl", &opts)) {
/*
* sdl DisplayType needs hand-crafted parser instead of
} else {
goto invalid_sdl_args;
}
+ } else if (strstart(opts, ",show-cursor=", &nextopt)) {
+ opts = nextopt;
+ dpy.has_show_cursor = true;
+ if (strstart(opts, "on", &nextopt)) {
+ dpy.show_cursor = true;
+ } else if (strstart(opts, "off", &nextopt)) {
+ dpy.show_cursor = false;
+ } else {
+ goto invalid_sdl_args;
+ }
} else if (strstart(opts, ",gl=", &nextopt)) {
opts = nextopt;
dpy.has_gl = true;
static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
- Chardev *chr;
- bool qmp;
- bool pretty = false;
- const char *chardev;
- const char *mode;
-
- mode = qemu_opt_get(opts, "mode");
- if (mode == NULL) {
- mode = "readline";
- }
- if (strcmp(mode, "readline") == 0) {
- qmp = false;
- } else if (strcmp(mode, "control") == 0) {
- qmp = true;
- } else {
- error_setg(errp, "unknown monitor mode \"%s\"", mode);
- return -1;
- }
-
- if (!qmp && qemu_opt_get(opts, "pretty")) {
- warn_report("'pretty' is deprecated for HMP monitors, it has no effect "
- "and will be removed in future versions");
- }
- if (qemu_opt_get_bool(opts, "pretty", 0)) {
- pretty = true;
- }
-
- chardev = qemu_opt_get(opts, "chardev");
- if (!chardev) {
- error_report("chardev is required");
- exit(1);
- }
- chr = qemu_chr_find(chardev);
- if (chr == NULL) {
- error_setg(errp, "chardev \"%s\" not found", chardev);
- return -1;
- }
-
- if (qmp) {
- monitor_init_qmp(chr, pretty);
- } else {
- monitor_init_hmp(chr, true);
- }
- return 0;
+ return monitor_init_opts(opts, errp);
}
static void monitor_parse(const char *optarg, const char *mode, bool pretty)
return machine_class;
}
-static int machine_set_property(void *opaque,
- const char *name, const char *value,
- Error **errp)
+static int object_parse_property_opt(Object *obj,
+ const char *name, const char *value,
+ const char *skip, Error **errp)
{
- Object *obj = OBJECT(opaque);
Error *local_err = NULL;
- char *p, *qom_name;
- if (strcmp(name, "type") == 0) {
+ if (g_str_equal(name, skip)) {
return 0;
}
- qom_name = g_strdup(name);
- for (p = qom_name; *p; p++) {
- if (*p == '_') {
- *p = '-';
- }
- }
-
- object_property_parse(obj, value, qom_name, &local_err);
- g_free(qom_name);
+ object_property_parse(obj, value, name, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return 0;
}
+static int machine_set_property(void *opaque,
+ const char *name, const char *value,
+ Error **errp)
+{
+ g_autofree char *qom_name = g_strdup(name);
+ char *p;
+
+ for (p = qom_name; *p; p++) {
+ if (*p == '_') {
+ *p = '-';
+ }
+ }
+
+ /* Legacy options do not correspond to MachineState properties. */
+ if (g_str_equal(qom_name, "accel")) {
+ return 0;
+ }
+ if (g_str_equal(qom_name, "igd-passthru")) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), qom_name, value);
+ return 0;
+ }
+ if (g_str_equal(qom_name, "kvm-shadow-mem") ||
+ g_str_equal(qom_name, "kernel-irqchip")) {
+ object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), qom_name, value);
+ return 0;
+ }
+
+ return object_parse_property_opt(opaque, name, value, "type", errp);
+}
/*
* Initial object creation happens before all other
return 0;
}
+static int accelerator_set_property(void *opaque,
+ const char *name, const char *value,
+ Error **errp)
+{
+ return object_parse_property_opt(opaque, name, value, "accel", errp);
+}
+
static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp)
{
- if (tcg_enabled()) {
- qemu_tcg_configure(opts, &error_fatal);
+ bool *p_init_failed = opaque;
+ const char *acc = qemu_opt_get(opts, "accel");
+ AccelClass *ac = accel_find(acc);
+ AccelState *accel;
+ int ret;
+
+ if (!ac) {
+ *p_init_failed = true;
+ error_report("invalid accelerator %s", acc);
+ return 0;
}
- return 0;
+ accel = ACCEL(object_new_with_class(OBJECT_CLASS(ac)));
+ object_apply_compat_props(OBJECT(accel));
+ qemu_opt_foreach(opts, accelerator_set_property,
+ accel,
+ &error_fatal);
+
+ ret = accel_init_machine(accel, current_machine);
+ if (ret < 0) {
+ *p_init_failed = true;
+ error_report("failed to initialize %s: %s",
+ acc, strerror(-ret));
+ return 0;
+ }
+
+ return 1;
}
-static void configure_accelerators(void)
+static void configure_accelerators(const char *progname)
{
- qemu_opts_foreach(qemu_find_opts("accel"),
- do_configure_accelerator, NULL, &error_fatal);
+ const char *accel;
+ bool init_failed = false;
+
+ qemu_opts_foreach(qemu_find_opts("icount"),
+ do_configure_icount, NULL, &error_fatal);
+
+ accel = qemu_opt_get(qemu_get_machine_opts(), "accel");
+ if (QTAILQ_EMPTY(&qemu_accel_opts.head)) {
+ char **accel_list, **tmp;
+
+ if (accel == NULL) {
+ /* Select the default accelerator */
+ bool have_tcg = accel_find("tcg");
+ bool have_kvm = accel_find("kvm");
+
+ if (have_tcg && have_kvm) {
+ if (g_str_has_suffix(progname, "kvm")) {
+ /* If the program name ends with "kvm", we prefer KVM */
+ accel = "kvm:tcg";
+ } else {
+ accel = "tcg:kvm";
+ }
+ } else if (have_kvm) {
+ accel = "kvm";
+ } else if (have_tcg) {
+ accel = "tcg";
+ } else {
+ error_report("No accelerator selected and"
+ " no default accelerator available");
+ exit(1);
+ }
+ }
+ accel_list = g_strsplit(accel, ":", 0);
+
+ for (tmp = accel_list; *tmp; tmp++) {
+ /*
+ * Filter invalid accelerators here, to prevent obscenities
+ * such as "-machine accel=tcg,,thread=single".
+ */
+ if (accel_find(*tmp)) {
+ qemu_opts_parse_noisily(qemu_find_opts("accel"), *tmp, true);
+ } else {
+ init_failed = true;
+ error_report("invalid accelerator %s", *tmp);
+ }
+ }
+ g_strfreev(accel_list);
+ } else {
+ if (accel != NULL) {
+ error_report("The -accel and \"-machine accel=\" options are incompatible");
+ exit(1);
+ }
+ }
+
+ if (!qemu_opts_foreach(qemu_find_opts("accel"),
+ do_configure_accelerator, &init_failed, &error_fatal)) {
+ if (!init_failed) {
+ error_report("no accelerator found");
+ }
+ exit(1);
+ }
+
+ if (init_failed) {
+ AccelClass *ac = ACCEL_GET_CLASS(current_accel());
+ error_report("falling back to %s", ac->name);
+ }
if (use_icount && !(tcg_enabled() || qtest_enabled())) {
error_report("-icount is not allowed with hardware virtualization");
gchar **optname = g_strsplit(typename,
ACCEL_CLASS_SUFFIX, 0);
printf("%s\n", optname[0]);
- g_free(optname);
+ g_strfreev(optname);
}
g_free(typename);
}
"use -M accel=... for now instead");
exit(1);
}
- opts = qemu_opts_create(qemu_find_opts("machine"), NULL,
- false, &error_abort);
- qemu_opt_set(opts, "accel", optarg, &error_abort);
break;
case QEMU_OPTION_usb:
olist = qemu_find_opts("machine");
no_shutdown = 1;
break;
case QEMU_OPTION_show_cursor:
- cursor_hide = 0;
+ warn_report("The -show-cursor option is deprecated, "
+ "use -display {sdl,gtk},show-cursor=on instead");
+ dpy.has_show_cursor = true;
+ dpy.show_cursor = true;
break;
case QEMU_OPTION_uuid:
if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) {
error_report("TCG is disabled");
exit(1);
#endif
- if (qemu_strtoul(optarg, NULL, 0, &tcg_tb_size) < 0) {
- error_report("Invalid argument to -tb-size");
- exit(1);
- }
+ warn_report("The -tb-size option is deprecated, use -accel tcg,tb-size instead");
+ object_register_sugar_prop(ACCEL_CLASS_NAME("tcg"), "tb-size", optarg);
break;
case QEMU_OPTION_icount:
icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"),
cleanup_add_fd, NULL, &error_fatal);
#endif
- current_machine = MACHINE(object_new(object_class_get_name(
- OBJECT_CLASS(machine_class))));
+ current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
if (machine_help_func(qemu_get_machine_opts(), current_machine)) {
exit(0);
}
/* Open the logfile at this point and set the log mask if necessary.
*/
- if (log_file) {
- qemu_set_log_filename(log_file, &error_fatal);
- }
-
+ qemu_set_log_filename(log_file, &error_fatal);
if (log_mask) {
int mask;
mask = qemu_str_to_log_mask(log_mask);
* Note: uses machine properties such as kernel-irqchip, must run
* after machine_set_property().
*/
- qemu_opts_foreach(qemu_find_opts("icount"),
- do_configure_icount, NULL, &error_fatal);
- configure_accelerator(current_machine, argv[0]);
+ configure_accelerators(argv[0]);
/*
* Beware, QOM objects created before this point miss global and
qemu_spice_init();
cpu_ticks_init();
- configure_accelerators();
if (default_net) {
QemuOptsList *net = qemu_find_opts("net");
qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, &error_fatal);
+ /* connect semihosting console input if requested */
+ qemu_semihosting_console_init();
+
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
exit(1);
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
exit(1);
}
- /* Check if IGD GFX passthrough. */
- igd_gfx_passthru();
-
/* init generic devices */
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
qemu_opts_foreach(qemu_find_opts("device"),
/* TODO: once all bus devices are qdevified, this should be done
* when bus is created by qdev.c */
- qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
+ /*
+ * TODO: If we had a main 'reset container' that the whole system
+ * lived in, we could reset that using the multi-phase reset
+ * APIs. For the moment, we just reset the sysbus, which will cause
+ * all devices hanging off it (and all their child buses, recursively)
+ * to be reset. Note that this will *not* reset any Device objects
+ * which are not attached to some part of the qbus tree!
+ */
+ qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
qemu_run_machine_init_done_notifiers();
if (rom_check_and_register_reset() != 0) {