X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/7ed57b66221b5a3e23b3519824637b297dc92090..d85f4222b4681da7ebf8a90b26e085a68fa2c55a:/vl.c diff --git a/vl.c b/vl.c index 58023fca02..f7560de622 100644 --- a/vl.c +++ b/vl.c @@ -81,16 +81,18 @@ int main(int argc, char **argv) #include "sysemu/numa.h" #include "exec/gdbstub.h" #include "qemu/timer.h" -#include "sysemu/char.h" +#include "chardev/char.h" #include "qemu/bitmap.h" #include "qemu/log.h" #include "sysemu/blockdev.h" #include "hw/block/block.h" -#include "migration/block.h" +#include "migration/misc.h" +#include "migration/snapshot.h" +#include "migration/global_state.h" #include "sysemu/tpm.h" #include "sysemu/dma.h" +#include "hw/audio/soundhw.h" #include "audio/audio.h" -#include "migration/migration.h" #include "sysemu/cpus.h" #include "migration/colo.h" #include "sysemu/kvm.h" @@ -186,7 +188,6 @@ bool boot_strict; uint8_t *boot_splash_filedata; size_t boot_splash_filedata_size; uint8_t qemu_extra_params_fw[2]; -int only_migratable; /* turn it off unless user states otherwise */ int icount_align_option; @@ -1435,6 +1436,9 @@ static int usb_parse(const char *cmdline) void hmp_usb_add(Monitor *mon, const QDict *qdict) { const char *devname = qdict_get_str(qdict, "devname"); + + error_report("usb_add is deprecated, please use device_add instead"); + if (usb_device_add(devname) < 0) { error_report("could not add USB device '%s'", devname); } @@ -1443,6 +1447,9 @@ void hmp_usb_add(Monitor *mon, const QDict *qdict) void hmp_usb_del(Monitor *mon, const QDict *qdict) { const char *devname = qdict_get_str(qdict, "devname"); + + error_report("usb_del is deprecated, please use device_del instead"); + if (usb_device_del(devname) < 0) { error_report("could not delete USB device '%s'", devname); } @@ -1597,8 +1604,9 @@ void vm_state_notify(int running, RunState state) } } -static int reset_requested; -static int shutdown_requested, shutdown_signal = -1; +static ShutdownCause reset_requested; +static ShutdownCause shutdown_requested; +static int shutdown_signal; static pid_t shutdown_pid; static int powerdown_requested; static int debug_requested; @@ -1612,24 +1620,24 @@ static NotifierList wakeup_notifiers = NOTIFIER_LIST_INITIALIZER(wakeup_notifiers); static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); -int qemu_shutdown_requested_get(void) +ShutdownCause qemu_shutdown_requested_get(void) { return shutdown_requested; } -int qemu_reset_requested_get(void) +ShutdownCause qemu_reset_requested_get(void) { return reset_requested; } static int qemu_shutdown_requested(void) { - return atomic_xchg(&shutdown_requested, 0); + return atomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE); } static void qemu_kill_report(void) { - if (!qtest_driver() && shutdown_signal != -1) { + if (!qtest_driver() && shutdown_signal) { if (shutdown_pid == 0) { /* This happens for eg ^C at the terminal, so it's worth * avoiding printing an odd message in that case. @@ -1643,18 +1651,19 @@ static void qemu_kill_report(void) shutdown_cmd ? shutdown_cmd : ""); g_free(shutdown_cmd); } - shutdown_signal = -1; + shutdown_signal = 0; } } -static int qemu_reset_requested(void) +static ShutdownCause qemu_reset_requested(void) { - int r = reset_requested; + ShutdownCause r = reset_requested; + if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) { - reset_requested = 0; + reset_requested = SHUTDOWN_CAUSE_NONE; return r; } - return false; + return SHUTDOWN_CAUSE_NONE; } static int qemu_suspend_requested(void) @@ -1686,7 +1695,10 @@ static int qemu_debug_requested(void) return r; } -void qemu_system_reset(bool report) +/* + * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE. + */ +void qemu_system_reset(ShutdownCause reason) { MachineClass *mc; @@ -1699,8 +1711,9 @@ void qemu_system_reset(bool report) } else { qemu_devices_reset(); } - if (report) { - qapi_event_send_reset(&error_abort); + if (reason) { + qapi_event_send_reset(shutdown_caused_by_guest(reason), + &error_abort); } cpu_synchronize_all_post_reset(); } @@ -1718,7 +1731,7 @@ void qemu_system_guest_panicked(GuestPanicInformation *info) if (!no_shutdown) { qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF, !!info, info, &error_abort); - qemu_system_shutdown_request(); + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC); } if (info) { @@ -1735,12 +1748,12 @@ void qemu_system_guest_panicked(GuestPanicInformation *info) } } -void qemu_system_reset_request(void) +void qemu_system_reset_request(ShutdownCause reason) { if (no_reboot) { - shutdown_requested = 1; + shutdown_requested = reason; } else { - reset_requested = 1; + reset_requested = reason; } cpu_stop_current(); qemu_notify_event(); @@ -1807,15 +1820,15 @@ void qemu_system_killed(int signal, pid_t pid) /* Cannot call qemu_system_shutdown_request directly because * we are in a signal handler. */ - shutdown_requested = 1; + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; qemu_notify_event(); } -void qemu_system_shutdown_request(void) +void qemu_system_shutdown_request(ShutdownCause reason) { - trace_qemu_system_shutdown_request(); - replay_shutdown_request(); - shutdown_requested = 1; + trace_qemu_system_shutdown_request(reason); + replay_shutdown_request(reason); + shutdown_requested = reason; qemu_notify_event(); } @@ -1846,24 +1859,29 @@ void qemu_system_debug_request(void) static bool main_loop_should_exit(void) { RunState r; + ShutdownCause request; + if (qemu_debug_requested()) { vm_stop(RUN_STATE_DEBUG); } if (qemu_suspend_requested()) { qemu_system_suspend(); } - if (qemu_shutdown_requested()) { + request = qemu_shutdown_requested(); + if (request) { qemu_kill_report(); - qapi_event_send_shutdown(&error_abort); + qapi_event_send_shutdown(shutdown_caused_by_guest(request), + &error_abort); if (no_shutdown) { vm_stop(RUN_STATE_SHUTDOWN); } else { return true; } } - if (qemu_reset_requested()) { + request = qemu_reset_requested(); + if (request) { pause_all_vcpus(); - qemu_system_reset(VMRESET_REPORT); + qemu_system_reset(request); resume_all_vcpus(); if (!runstate_check(RUN_STATE_RUNNING) && !runstate_check(RUN_STATE_INMIGRATE)) { @@ -1872,7 +1890,7 @@ static bool main_loop_should_exit(void) } if (qemu_wakeup_requested()) { pause_all_vcpus(); - qemu_system_reset(VMRESET_SILENT); + qemu_system_reset(SHUTDOWN_CAUSE_NONE); notifier_list_notify(&wakeup_notifiers, &wakeup_reason); wakeup_reason = QEMU_WAKEUP_REASON_NONE; resume_all_vcpus(); @@ -2050,6 +2068,7 @@ typedef enum DisplayType { DT_SDL, DT_COCOA, DT_GTK, + DT_EGL, DT_NONE, } DisplayType; @@ -2127,6 +2146,15 @@ static DisplayType select_display(const char *p) error_report("VNC requires a display argument vnc="); exit(1); } + } else if (strstart(p, "egl-headless", &opts)) { +#ifdef CONFIG_OPENGL_DMABUF + request_opengl = 1; + display_opengl = 1; + display = DT_EGL; +#else + fprintf(stderr, "egl support is disabled\n"); + exit(1); +#endif } else if (strstart(p, "curses", &opts)) { #ifdef CONFIG_CURSES display = DT_CURSES; @@ -2940,6 +2968,25 @@ static int qemu_read_default_config_file(void) return 0; } +static void user_register_global_props(void) +{ + qemu_opts_foreach(qemu_find_opts("global"), + global_init_func, NULL, NULL); +} + +/* + * Note: we should see that these properties are actually having a + * priority: accel < machine < user. This means e.g. when user + * specifies something in "-global", it'll always be used with highest + * priority than either machine/accelerator compat properties. + */ +static void register_global_properties(MachineState *ms) +{ + accel_register_compat_props(ms->accelerator); + machine_register_compat_props(ms); + user_register_global_props(); +} + int main(int argc, char **argv, char **envp) { int i; @@ -3524,10 +3571,11 @@ int main(int argc, char **argv, char **envp) exit(1); } fsdev = qemu_opts_create(qemu_find_opts("fsdev"), + qemu_opts_id(opts) ?: qemu_opt_get(opts, "mount_tag"), 1, NULL); if (!fsdev) { - error_report("duplicate fsdev id: %s", + error_report("duplicate or invalid fsdev id: %s", qemu_opt_get(opts, "mount_tag")); exit(1); } @@ -3565,7 +3613,7 @@ int main(int argc, char **argv, char **envp) &error_abort); qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort); qemu_opt_set(device, "fsdev", - qemu_opt_get(opts, "mount_tag"), &error_abort); + qemu_opts_id(fsdev), &error_abort); qemu_opt_set(device, "mount_tag", qemu_opt_get(opts, "mount_tag"), &error_abort); break; @@ -3727,26 +3775,25 @@ int main(int argc, char **argv, char **envp) qdev_prop_register_global(&kvm_pit_lost_tick_policy); break; } - case QEMU_OPTION_accel: { - QemuOpts *accel_opts; - + case QEMU_OPTION_accel: accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"), optarg, true); optarg = qemu_opt_get(accel_opts, "accel"); if (!optarg || is_help_option(optarg)) { error_printf("Possible accelerators: kvm, xen, hax, tcg\n"); - exit(1); + exit(0); } - accel_opts = qemu_opts_create(qemu_find_opts("machine"), NULL, - false, &error_abort); - qemu_opt_set(accel_opts, "accel", optarg, &error_abort); + 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"); qemu_opts_parse_noisily(olist, "usb=on", false); break; case QEMU_OPTION_usbdevice: + error_report("'-usbdevice' is deprecated, please use " + "'-device usb-...' instead"); olist = qemu_find_opts("machine"); qemu_opts_parse_noisily(olist, "usb=on", false); add_device_config(DEV_USB, optarg); @@ -3886,9 +3933,13 @@ int main(int argc, char **argv, char **envp) configure_rtc(opts); break; case QEMU_OPTION_tb_size: - tcg_tb_size = strtol(optarg, NULL, 0); - if (tcg_tb_size < 0) { - tcg_tb_size = 0; + if (!tcg_enabled()) { + error_report("TCG is disabled"); + exit(1); + } + if (qemu_strtoul(optarg, NULL, 0, &tcg_tb_size) < 0) { + error_report("Invalid argument to -tb-size"); + exit(1); } break; case QEMU_OPTION_icount: @@ -3905,7 +3956,13 @@ int main(int argc, char **argv, char **envp) incoming = optarg; break; case QEMU_OPTION_only_migratable: - only_migratable = 1; + /* + * TODO: we can remove this option one day, and we + * should all use: + * + * "-global migration.only-migratable=true" + */ + qemu_global_option("migration.only-migratable=true"); break; case QEMU_OPTION_nodefaults: has_defaults = 0; @@ -4361,6 +4418,18 @@ int main(int argc, char **argv, char **envp) configure_accelerator(current_machine); + /* + * Register all the global properties, including accel properties, + * machine properties, and user-specified ones. + */ + register_global_properties(current_machine); + + /* + * Migration object can only be created after global properties + * are applied correctly. + */ + migration_object_init(); + if (qtest_chrdev) { qtest_init(qtest_chrdev, qtest_log, &error_fatal); } @@ -4428,7 +4497,9 @@ int main(int argc, char **argv, char **envp) qemu_opts_del(icount_opts); } - qemu_tcg_configure(accel_opts, &error_fatal); + if (tcg_enabled()) { + qemu_tcg_configure(accel_opts, &error_fatal); + } if (default_net) { QemuOptsList *net = qemu_find_opts("net"); @@ -4503,7 +4574,7 @@ int main(int argc, char **argv, char **envp) default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); - parse_numa_opts(machine_class); + parse_numa_opts(current_machine); if (qemu_opts_foreach(qemu_find_opts("mon"), mon_init_func, NULL, NULL)) { @@ -4542,11 +4613,6 @@ int main(int argc, char **argv, char **envp) exit (i == 1 ? 1 : 0); } - machine_register_compat_props(current_machine); - - qemu_opts_foreach(qemu_find_opts("global"), - global_init_func, NULL, NULL); - /* This checkpoint is required by replay to separate prior clock reading from the other reads, because timer polling functions query clock values from the log. */ @@ -4559,11 +4625,11 @@ int main(int argc, char **argv, char **envp) current_machine->boot_order = boot_order; current_machine->cpu_model = cpu_model; - machine_class->init(current_machine); + machine_run_board_init(current_machine); realtime_init(); - audio_init(); + soundhw_init(); if (hax_enabled()) { hax_sync_vcpus(); @@ -4592,8 +4658,6 @@ int main(int argc, char **argv, char **envp) cpu_synchronize_all_post_init(); - numa_post_machine_init(); - rom_reset_order_override(); /* @@ -4659,6 +4723,12 @@ int main(int argc, char **argv, char **envp) qemu_spice_display_init(); } +#ifdef CONFIG_OPENGL_DMABUF + if (display_type == DT_EGL) { + egl_headless_init(); + } +#endif + if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) { exit(1); } @@ -4681,12 +4751,14 @@ int main(int argc, char **argv, char **envp) reading from the other reads, because timer polling functions query clock values from the log. */ replay_checkpoint(CHECKPOINT_RESET); - qemu_system_reset(VMRESET_SILENT); + qemu_system_reset(SHUTDOWN_CAUSE_NONE); register_global_state(); if (replay_mode != REPLAY_MODE_NONE) { replay_vmstate_init(); } else if (loadvm) { - if (load_vmstate(loadvm) < 0) { + Error *local_err = NULL; + if (load_snapshot(loadvm, &local_err) < 0) { + error_report_err(local_err); autostart = 0; } }