X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=vl.c;h=56aa221385c476df5f461d992a30bd558a4408aa;hb=d65af288a84d8bf8c27e55d45545f52f016c08a7;hp=c696ad2a13d4ed59c594976d3b073e741e81a949;hpb=0427b6257e2a901d60c58cad6f1b750a76fad4a8;p=mirror_qemu.git diff --git a/vl.c b/vl.c index c696ad2a13..56aa221385 100644 --- a/vl.c +++ b/vl.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "qemu/units.h" #include "qapi/error.h" #include "qemu-version.h" @@ -30,6 +31,7 @@ #include "qemu/help_option.h" #include "qemu/uuid.h" #include "sysemu/seccomp.h" +#include "sysemu/tcg.h" #ifdef CONFIG_SDL #if defined(__APPLE__) || defined(main) @@ -53,7 +55,6 @@ int main(int argc, char **argv) #include "qemu/error-report.h" #include "qemu/sockets.h" #include "hw/hw.h" -#include "hw/boards.h" #include "sysemu/accel.h" #include "hw/usb.h" #include "hw/isa/isa.h" @@ -116,18 +117,18 @@ int main(int argc, char **argv) #include "qapi/opts-visitor.h" #include "qapi/clone-visitor.h" #include "qom/object_interfaces.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "crypto/init.h" #include "sysemu/replay.h" #include "qapi/qapi-events-run-state.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qapi-visit-ui.h" #include "qapi/qapi-commands-block-core.h" -#include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qerror.h" #include "sysemu/iothread.h" +#include "qemu/guest-random.h" #define MAX_VIRTIO_CONSOLES 1 @@ -162,10 +163,6 @@ static Chardev **serial_hds; Chardev *parallel_hds[MAX_PARALLEL_PORTS]; int win2k_install_hack = 0; int singlestep = 0; -int smp_cpus; -unsigned int max_cpus; -int smp_cores = 1; -int smp_threads = 1; int acpi_enabled = 1; int no_hpet = 0; int fd_bootchk = 1; @@ -238,6 +235,7 @@ static struct { { .driver = "qxl-vga", .flag = &default_vga }, { .driver = "virtio-vga", .flag = &default_vga }, { .driver = "ati-vga", .flag = &default_vga }, + { .driver = "vhost-user-vga", .flag = &default_vga }, }; static QemuOptsList qemu_rtc_opts = { @@ -500,25 +498,6 @@ static QemuOptsList qemu_icount_opts = { }, }; -static QemuOptsList qemu_semihosting_config_opts = { - .name = "semihosting-config", - .implied_opt_name = "enable", - .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head), - .desc = { - { - .name = "enable", - .type = QEMU_OPT_BOOL, - }, { - .name = "target", - .type = QEMU_OPT_STRING, - }, { - .name = "arg", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - static QemuOptsList qemu_fw_cfg_opts = { .name = "fw_cfg", .implied_opt_name = "name", @@ -725,7 +704,7 @@ void runstate_set(RunState new_state) assert(new_state < RUN_STATE__MAX); trace_runstate_set(current_run_state, RunState_str(current_run_state), - new_state, RunState_str(current_run_state)); + new_state, RunState_str(new_state)); if (current_run_state == new_state) { return; @@ -1282,8 +1261,9 @@ static void smp_parse(QemuOpts *opts) sockets = sockets > 0 ? sockets : 1; cpus = cores * threads * sockets; } else { - max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); - sockets = max_cpus / (cores * threads); + current_machine->smp.max_cpus = + qemu_opt_get_number(opts, "maxcpus", cpus); + sockets = current_machine->smp.max_cpus / (cores * threads); } } else if (cores == 0) { threads = threads > 0 ? threads : 1; @@ -1300,34 +1280,37 @@ static void smp_parse(QemuOpts *opts) exit(1); } - max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); + current_machine->smp.max_cpus = + qemu_opt_get_number(opts, "maxcpus", cpus); - if (max_cpus < cpus) { + if (current_machine->smp.max_cpus < cpus) { error_report("maxcpus must be equal to or greater than smp"); exit(1); } - if (sockets * cores * threads > max_cpus) { + if (sockets * cores * threads > current_machine->smp.max_cpus) { error_report("cpu topology: " "sockets (%u) * cores (%u) * threads (%u) > " "maxcpus (%u)", - sockets, cores, threads, max_cpus); + sockets, cores, threads, + current_machine->smp.max_cpus); exit(1); } - if (sockets * cores * threads != max_cpus) { + if (sockets * cores * threads != current_machine->smp.max_cpus) { warn_report("Invalid CPU topology deprecated: " "sockets (%u) * cores (%u) * threads (%u) " "!= maxcpus (%u)", - sockets, cores, threads, max_cpus); + sockets, cores, threads, + current_machine->smp.max_cpus); } - smp_cpus = cpus; - smp_cores = cores; - smp_threads = threads; + current_machine->smp.cpus = cpus; + current_machine->smp.cores = cores; + current_machine->smp.threads = threads; } - if (smp_cpus > 1) { + if (current_machine->smp.cpus > 1) { Error *blocker = NULL; error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); replay_add_blocker(blocker); @@ -1350,80 +1333,6 @@ static void configure_msg(QemuOpts *opts) enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); } -/***********************************************************/ -/* Semihosting */ - -typedef struct SemihostingConfig { - bool enabled; - SemihostingTarget target; - const char **argv; - int argc; - const char *cmdline; /* concatenated argv */ -} SemihostingConfig; - -static SemihostingConfig semihosting; - -bool semihosting_enabled(void) -{ - return semihosting.enabled; -} - -SemihostingTarget semihosting_get_target(void) -{ - return semihosting.target; -} - -const char *semihosting_get_arg(int i) -{ - if (i >= semihosting.argc) { - return NULL; - } - return semihosting.argv[i]; -} - -int semihosting_get_argc(void) -{ - return semihosting.argc; -} - -const char *semihosting_get_cmdline(void) -{ - if (semihosting.cmdline == NULL && semihosting.argc > 0) { - semihosting.cmdline = g_strjoinv(" ", (gchar **)semihosting.argv); - } - return semihosting.cmdline; -} - -static int add_semihosting_arg(void *opaque, - const char *name, const char *val, - Error **errp) -{ - SemihostingConfig *s = opaque; - if (strcmp(name, "arg") == 0) { - s->argc++; - /* one extra element as g_strjoinv() expects NULL-terminated array */ - s->argv = g_realloc(s->argv, (s->argc + 1) * sizeof(void *)); - s->argv[s->argc - 1] = val; - s->argv[s->argc] = NULL; - } - return 0; -} - -/* Use strings passed via -kernel/-append to initialize semihosting.argv[] */ -static inline void semihosting_arg_fallback(const char *file, const char *cmd) -{ - char *cmd_token; - - /* argv[0] */ - add_semihosting_arg(&semihosting, "arg", file, NULL); - - /* split -append and initialize argv[1..n] */ - cmd_token = strtok(g_strdup(cmd), " "); - while (cmd_token) { - add_semihosting_arg(&semihosting, "arg", cmd_token, NULL); - cmd_token = strtok(NULL, " "); - } -} /* Now we still need this for compatibility with XEN. */ bool has_igd_gfx_passthru; @@ -1465,80 +1374,34 @@ static int usb_parse(const char *cmdline) MachineState *current_machine; -static MachineClass *find_machine(const char *name) +static MachineClass *find_machine(const char *name, GSList *machines) { - GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); - MachineClass *mc = NULL; + GSList *el; for (el = machines; el; el = el->next) { - MachineClass *temp = el->data; - - if (!strcmp(temp->name, name)) { - mc = temp; - break; - } - if (temp->alias && - !strcmp(temp->alias, name)) { - mc = temp; - break; - } - } - - g_slist_free(machines); - return mc; -} - -MachineClass *find_default_machine(void) -{ - GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); - MachineClass *mc = NULL; - - for (el = machines; el; el = el->next) { - MachineClass *temp = el->data; + MachineClass *mc = el->data; - if (temp->is_default) { - mc = temp; - break; + if (!strcmp(mc->name, name) || !g_strcmp0(mc->alias, name)) { + return mc; } } - g_slist_free(machines); - return mc; + return NULL; } -MachineInfoList *qmp_query_machines(Error **errp) +static MachineClass *find_default_machine(GSList *machines) { - GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); - MachineInfoList *mach_list = NULL; + GSList *el; for (el = machines; el; el = el->next) { MachineClass *mc = el->data; - MachineInfoList *entry; - MachineInfo *info; - info = g_malloc0(sizeof(*info)); if (mc->is_default) { - info->has_is_default = true; - info->is_default = true; + return mc; } - - if (mc->alias) { - info->has_alias = true; - info->alias = g_strdup(mc->alias); - } - - info->name = g_strdup(mc->name); - info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus; - info->hotpluggable_cpus = mc->has_hotpluggable_cpus; - - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = mach_list; - mach_list = entry; } - g_slist_free(machines); - return mach_list; + return NULL; } static int machine_help_func(QemuOpts *opts, MachineState *machine) @@ -1556,12 +1419,12 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine) continue; } - error_printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name, - prop->name, prop->type); + printf("%s.%s=%s", MACHINE_GET_CLASS(machine)->name, + prop->name, prop->type); if (prop->description) { - error_printf(" (%s)\n", prop->description); + printf(" (%s)\n", prop->description); } else { - error_printf("\n"); + printf("\n"); } } @@ -1717,7 +1580,7 @@ void qemu_system_reset(ShutdownCause reason) cpu_synchronize_all_states(); if (mc && mc->reset) { - mc->reset(); + mc->reset(current_machine); } else { qemu_devices_reset(); } @@ -1839,14 +1702,6 @@ bool qemu_wakeup_suspend_enabled(void) return wakeup_suspend_enabled; } -CurrentMachineParams *qmp_query_current_machine(Error **errp) -{ - CurrentMachineParams *params = g_malloc0(sizeof(*params)); - params->wakeup_suspend_support = qemu_wakeup_suspend_enabled(); - - return params; -} - void qemu_system_killed(int signal, pid_t pid) { shutdown_signal = signal; @@ -2026,9 +1881,10 @@ typedef struct VGAInterfaceInfo { const char *class_names[2]; } VGAInterfaceInfo; -static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = { +static const VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = { [VGA_NONE] = { .opt_name = "none", + .name = "no graphic card", }, [VGA_STD] = { .opt_name = "std", @@ -2067,12 +1923,13 @@ static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = { }, [VGA_XENFB] = { .opt_name = "xenfb", + .name = "Xen paravirtualized framebuffer", }, }; static bool vga_interface_available(VGAInterfaceType t) { - VGAInterfaceInfo *ti = &vga_interfaces[t]; + const VGAInterfaceInfo *ti = &vga_interfaces[t]; assert(t < VGA_TYPE_MAX); return !ti->class_names[0] || @@ -2080,14 +1937,42 @@ static bool vga_interface_available(VGAInterfaceType t) object_class_by_name(ti->class_names[1]); } -static void select_vgahw(const char *p) +static const char * +get_default_vga_model(const MachineClass *machine_class) +{ + if (machine_class->default_display) { + return machine_class->default_display; + } else if (vga_interface_available(VGA_CIRRUS)) { + return "cirrus"; + } else if (vga_interface_available(VGA_STD)) { + return "std"; + } + + return NULL; +} + +static void select_vgahw(const MachineClass *machine_class, const char *p) { const char *opts; int t; + if (g_str_equal(p, "help")) { + const char *def = get_default_vga_model(machine_class); + + for (t = 0; t < VGA_TYPE_MAX; t++) { + const VGAInterfaceInfo *ti = &vga_interfaces[t]; + + if (vga_interface_available(t) && ti->opt_name) { + printf("%-20s %s%s\n", ti->opt_name, ti->name ?: "", + g_str_equal(ti->opt_name, def) ? " (default)" : ""); + } + } + exit(0); + } + assert(vga_interface_type == VGA_NONE); for (t = 0; t < VGA_TYPE_MAX; t++) { - VGAInterfaceInfo *ti = &vga_interfaces[t]; + const VGAInterfaceInfo *ti = &vga_interfaces[t]; if (ti->opt_name && strstart(p, ti->opt_name, &opts)) { if (!vga_interface_available(t)) { error_report("%s not available", ti->name); @@ -2369,25 +2254,31 @@ static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp) static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) { Chardev *chr; + bool qmp; + bool pretty = false; const char *chardev; const char *mode; - int flags; mode = qemu_opt_get(opts, "mode"); if (mode == NULL) { mode = "readline"; } if (strcmp(mode, "readline") == 0) { - flags = MONITOR_USE_READLINE; + qmp = false; } else if (strcmp(mode, "control") == 0) { - flags = MONITOR_USE_CONTROL; + qmp = true; } else { error_setg(errp, "unknown monitor mode \"%s\"", mode); return -1; } - if (qemu_opt_get_bool(opts, "pretty", 0)) - flags |= MONITOR_USE_PRETTY; + 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) { @@ -2400,7 +2291,11 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) return -1; } - monitor_init(chr, flags); + if (qmp) { + monitor_init_qmp(chr, pretty); + } else { + monitor_init_hmp(chr, true); + } return 0; } @@ -2426,7 +2321,11 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty) opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal); qemu_opt_set(opts, "mode", mode, &error_abort); qemu_opt_set(opts, "chardev", label, &error_abort); - qemu_opt_set_bool(opts, "pretty", pretty, &error_abort); + if (!strcmp(mode, "control")) { + qemu_opt_set_bool(opts, "pretty", pretty, &error_abort); + } else { + assert(pretty == false); + } monitor_device_index++; } @@ -2585,22 +2484,12 @@ static gint machine_class_cmp(gconstpointer a, gconstpointer b) object_class_get_name(OBJECT_CLASS(mc1))); } - static MachineClass *machine_parse(const char *name) +static MachineClass *machine_parse(const char *name, GSList *machines) { - MachineClass *mc = NULL; - GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); + MachineClass *mc; + GSList *el; - if (name) { - mc = find_machine(name); - } - if (mc) { - g_slist_free(machines); - return mc; - } - if (name && !is_help_option(name)) { - error_report("unsupported machine type"); - error_printf("Use -machine help to list supported machines\n"); - } else { + if (is_help_option(name)) { printf("Supported machines are:\n"); machines = g_slist_sort(machines, machine_class_cmp); for (el = machines; el; el = el->next) { @@ -2612,10 +2501,16 @@ static gint machine_class_cmp(gconstpointer a, gconstpointer b) mc->is_default ? " (default)" : "", mc->deprecation_reason ? " (deprecated)" : ""); } + exit(0); } - g_slist_free(machines); - exit(!name || !is_help_option(name)); + mc = find_machine(name, machines); + if (!mc) { + error_report("unsupported machine type"); + error_printf("Use -machine help to list supported machines\n"); + exit(1); + } + return mc; } void qemu_add_exit_notifier(Notifier *notify) @@ -2706,7 +2601,8 @@ static const QEMUOption *lookup_opt(int argc, char **argv, static MachineClass *select_machine(void) { - MachineClass *machine_class = find_default_machine(); + GSList *machines = object_class_get_list(TYPE_MACHINE, false); + MachineClass *machine_class = find_default_machine(machines); const char *optarg; QemuOpts *opts; Location loc; @@ -2718,7 +2614,7 @@ static MachineClass *select_machine(void) optarg = qemu_opt_get(opts, "type"); if (optarg) { - machine_class = machine_parse(optarg); + machine_class = machine_parse(optarg, machines); } if (!machine_class) { @@ -2728,6 +2624,7 @@ static MachineClass *select_machine(void) } loc_pop(&loc); + g_slist_free(machines); return machine_class; } @@ -2825,20 +2722,25 @@ static bool object_create_initial(const char *type, QemuOpts *opts) exit(0); } - if (g_str_equal(type, "rng-egd") || - g_str_has_prefix(type, "pr-manager-")) { + /* + * Objects should not be made "delayed" without a reason. If you + * add one, state the reason in a comment! + */ + + /* Reason: rng-egd property "chardev" */ + if (g_str_equal(type, "rng-egd")) { return false; } #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) + /* Reason: cryptodev-vhost-user property "chardev" */ if (g_str_equal(type, "cryptodev-vhost-user")) { return false; } #endif /* - * return false for concrete netfilters since - * they depend on netdevs already existing + * Reason: filter-* property "netdev" etc. */ if (g_str_equal(type, "filter-buffer") || g_str_equal(type, "filter-dump") || @@ -3002,7 +2904,7 @@ int main(int argc, char **argv, char **envp) const char *optarg; const char *loadvm = NULL; MachineClass *machine_class; - const char *cpu_model; + const char *cpu_option; const char *vga_model = NULL; const char *qtest_chrdev = NULL; const char *qtest_log = NULL; @@ -3022,6 +2924,7 @@ int main(int argc, char **argv, char **envp) char *dir, **dirs; BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); + error_init(argv[0]); module_call_init(MODULE_INIT_TRACE); qemu_init_cpu_list(); @@ -3030,7 +2933,6 @@ int main(int argc, char **argv, char **envp) qemu_mutex_lock_iothread(); atexit(qemu_run_exit_notifiers); - error_set_progname(argv[0]); qemu_init_exec_dir(argv[0]); module_call_init(MODULE_INIT_QOM); @@ -3081,7 +2983,7 @@ int main(int argc, char **argv, char **envp) QLIST_INIT (&vm_change_state_head); os_setup_early_signal_handling(); - cpu_model = NULL; + cpu_option = NULL; snapshot = 0; nb_nics = 0; @@ -3133,7 +3035,7 @@ int main(int argc, char **argv, char **envp) switch(popt->index) { case QEMU_OPTION_cpu: /* hw initialization will check this */ - cpu_model = optarg; + cpu_option = optarg; break; case QEMU_OPTION_hda: case QEMU_OPTION_hdb: @@ -3332,6 +3234,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_DFILTER: qemu_set_dfilter_ranges(optarg, &error_fatal); break; + case QEMU_OPTION_seed: + qemu_guest_random_seed_main(optarg, &error_fatal); + break; case QEMU_OPTION_s: add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT); break; @@ -3520,6 +3425,10 @@ int main(int argc, char **argv, char **envp) QemuOpts *fsdev; QemuOpts *device; + warn_report("'-virtfs_synth' is deprecated, please use " + "'-fsdev synth' and '-device virtio-9p-...' " + "instead"); + fsdev = qemu_opts_create(qemu_find_opts("fsdev"), "v_synth", 1, NULL); if (!fsdev) { @@ -3643,7 +3552,23 @@ int main(int argc, char **argv, char **envp) optarg, true); optarg = qemu_opt_get(accel_opts, "accel"); if (!optarg || is_help_option(optarg)) { - error_printf("Possible accelerators: kvm, xen, hax, tcg\n"); + printf("Accelerators supported in QEMU binary:\n"); + GSList *el, *accel_list = object_class_get_list(TYPE_ACCEL, + false); + for (el = accel_list; el; el = el->next) { + gchar *typename = g_strdup(object_class_get_name( + OBJECT_CLASS(el->data))); + /* omit qtest which is used for tests only */ + if (g_strcmp0(typename, ACCEL_CLASS_NAME("qtest")) && + g_str_has_suffix(typename, ACCEL_CLASS_SUFFIX)) { + gchar **optname = g_strsplit(typename, + ACCEL_CLASS_SUFFIX, 0); + printf("%s\n", optname[0]); + g_free(optname); + } + g_free(typename); + } + g_slist_free(accel_list); exit(0); } opts = qemu_opts_create(qemu_find_opts("machine"), NULL, @@ -3718,37 +3643,10 @@ int main(int argc, char **argv, char **envp) nb_option_roms++; break; case QEMU_OPTION_semihosting: - semihosting.enabled = true; - semihosting.target = SEMIHOSTING_TARGET_AUTO; + qemu_semihosting_enable(); break; case QEMU_OPTION_semihosting_config: - semihosting.enabled = true; - opts = qemu_opts_parse_noisily(qemu_find_opts("semihosting-config"), - optarg, false); - if (opts != NULL) { - semihosting.enabled = qemu_opt_get_bool(opts, "enable", - true); - const char *target = qemu_opt_get(opts, "target"); - if (target != NULL) { - if (strcmp("native", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_NATIVE; - } else if (strcmp("gdb", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_GDB; - } else if (strcmp("auto", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_AUTO; - } else { - error_report("unsupported semihosting-config %s", - optarg); - exit(1); - } - } else { - semihosting.target = SEMIHOSTING_TARGET_AUTO; - } - /* Set semihosting argument count and vector */ - qemu_opt_foreach(opts, add_semihosting_arg, - &semihosting, NULL); - } else { - error_report("unsupported semihosting-config %s", optarg); + if (qemu_semihosting_config_options(optarg) != 0) { exit(1); } break; @@ -3879,17 +3777,19 @@ int main(int argc, char **argv, char **envp) qtest_log = optarg; break; case QEMU_OPTION_sandbox: -#ifdef CONFIG_SECCOMP - opts = qemu_opts_parse_noisily(qemu_find_opts("sandbox"), - optarg, true); + olist = qemu_find_opts("sandbox"); + if (!olist) { +#ifndef CONFIG_SECCOMP + error_report("-sandbox support is not enabled " + "in this QEMU binary"); +#endif + exit(1); + } + + opts = qemu_opts_parse_noisily(olist, optarg, true); if (!opts) { exit(1); } -#else - error_report("-sandbox support is not enabled " - "in this QEMU binary"); - exit(1); -#endif break; case QEMU_OPTION_add_fd: #ifndef _WIN32 @@ -3912,6 +3812,8 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_realtime: + warn_report("'-realtime mlock=...' is deprecated, please use " + "'-overcommit mem-lock=...' instead"); opts = qemu_opts_parse_noisily(qemu_find_opts("realtime"), optarg, false); if (!opts) { @@ -4050,8 +3952,8 @@ int main(int argc, char **argv, char **envp) qemu_set_hw_version(machine_class->hw_version); } - if (cpu_model && is_help_option(cpu_model)) { - list_cpus(stdout, &fprintf, cpu_model); + if (cpu_option && is_help_option(cpu_option)) { + list_cpus(cpu_option); exit(0); } @@ -4107,21 +4009,25 @@ int main(int argc, char **argv, char **envp) machine_class->default_cpus = machine_class->default_cpus ?: 1; /* default to machine_class->default_cpus */ - smp_cpus = machine_class->default_cpus; - max_cpus = machine_class->default_cpus; + current_machine->smp.cpus = machine_class->default_cpus; + current_machine->smp.max_cpus = machine_class->default_cpus; + current_machine->smp.cores = 1; + current_machine->smp.threads = 1; smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL)); /* sanity-check smp_cpus and max_cpus against machine_class */ - if (smp_cpus < machine_class->min_cpus) { + if (current_machine->smp.cpus < machine_class->min_cpus) { error_report("Invalid SMP CPUs %d. The min CPUs " - "supported by machine '%s' is %d", smp_cpus, + "supported by machine '%s' is %d", + current_machine->smp.cpus, machine_class->name, machine_class->min_cpus); exit(1); } - if (max_cpus > machine_class->max_cpus) { + if (current_machine->smp.max_cpus > machine_class->max_cpus) { error_report("Invalid SMP CPUs %d. The max CPUs " - "supported by machine '%s' is %d", max_cpus, + "supported by machine '%s' is %d", + current_machine->smp.max_cpus, machine_class->name, machine_class->max_cpus); exit(1); } @@ -4261,6 +4167,8 @@ int main(int argc, char **argv, char **envp) qemu_opts_foreach(qemu_find_opts("chardev"), chardev_init_func, NULL, &error_fatal); + /* now chardevs have been created we may have semihosting to connect */ + qemu_semihosting_connect_chardevs(); #ifdef CONFIG_VIRTFS qemu_opts_foreach(qemu_find_opts("fsdev"), @@ -4299,9 +4207,9 @@ int main(int argc, char **argv, char **envp) * Global properties get set up by qdev_prop_register_global(), * called from user_register_global_props(), and certain option * desugaring. Also in CPU feature desugaring (buried in - * parse_cpu_model()), which happens below this point, but may + * parse_cpu_option()), which happens below this point, but may * only target the CPU type, which can only be created after - * parse_cpu_model() returned the type. + * parse_cpu_option() returned the type. * * Machine compat properties: object_set_machine_compat_props(). * Accelerator compat props: object_set_accelerator_compat_props(), @@ -4437,16 +4345,10 @@ int main(int argc, char **argv, char **envp) /* If no default VGA is requested, the default is "none". */ if (default_vga) { - if (machine_class->default_display) { - vga_model = machine_class->default_display; - } else if (vga_interface_available(VGA_CIRRUS)) { - vga_model = "cirrus"; - } else if (vga_interface_available(VGA_STD)) { - vga_model = "std"; - } + vga_model = get_default_vga_model(machine_class); } if (vga_model) { - select_vgahw(vga_model); + select_vgahw(machine_class, vga_model); } if (watchdog) { @@ -4465,8 +4367,8 @@ int main(int argc, char **argv, char **envp) /* parse features once if machine provides default cpu_type */ current_machine->cpu_type = machine_class->default_cpu_type; - if (cpu_model) { - current_machine->cpu_type = parse_cpu_model(cpu_model); + if (cpu_option) { + current_machine->cpu_type = parse_cpu_option(cpu_option); } parse_numa_opts(current_machine);