This adds suboptions support for -cpu. Cc: Igor Mammedov <imamm...@redhat.com> Cc: Andreas Färber <afaer...@suse.de> Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- include/qom/cpu.h | 29 +++++++++++++++++++++++++++++ include/sysemu/sysemu.h | 1 + qom/cpu.c | 27 +++++++++++++++++++++++++++ vl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+)
diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 7739e00..7d3b043 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -124,6 +124,7 @@ typedef struct CPUClass { int cpuid, void *opaque); int (*write_elf32_qemunote)(WriteCoreDumpFunction f, CPUState *cpu, void *opaque); + void (*parse_options)(CPUState *cpu, Error **errp); const struct VMStateDescription *vmsd; int gdb_num_core_regs; @@ -327,6 +328,34 @@ static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) #endif /** + * cpu_parse_options: + * @cpu: The CPU to set options for. + */ +static inline int cpu_parse_options(CPUState *cpu) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + Error *err = NULL; + + if (cc->parse_options) { + cc->parse_options(cpu, &err); + if (err) { + return -1; + } + } + + /* No callback, let arch do it the old way */ + return 0; +} + +/** + * cpu_default_parse_options_func: + * The default handler for CPUClass::parse_options + * @cpu: the CPU to set option for. + * @errp: the handling error descriptor. + */ +void cpu_default_parse_options_func(CPUState *cpu, Error **errp); + +/** * cpu_reset: * @cpu: The CPU whose state is to be reset. */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index cd5791e..c6e3ea0 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -190,6 +190,7 @@ char *get_boot_devices_list(size_t *size); DeviceState *get_boot_device(uint32_t position); QemuOpts *qemu_get_machine_opts(void); +QemuOpts *qemu_get_cpu_opts(void); bool usb_enabled(bool default_usb); diff --git a/qom/cpu.c b/qom/cpu.c index 818fb26..231dec5 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -24,6 +24,8 @@ #include "qemu/notify.h" #include "qemu/log.h" #include "sysemu/sysemu.h" +#include "qapi/qmp/qerror.h" +#include "qemu/config-file.h" bool cpu_exists(int64_t id) { @@ -186,6 +188,31 @@ void cpu_reset(CPUState *cpu) } } +static int cpu_set_property(const char *name, const char *value, void *opaque) +{ + Error *err = NULL; + + if (strcmp(name, "type") == 0) { + return 0; + } + + object_property_parse(opaque, value, name, &err); + if (err != NULL) { + qerror_report_err(err); + error_free(err); + return -1; + } + + return 0; +} + +void cpu_default_parse_options_func(CPUState *cpu, Error **errp) +{ + if (qemu_opt_foreach(qemu_get_cpu_opts(), cpu_set_property, cpu, 1)) { + error_setg(errp, "Bad option"); + } +} + static void cpu_common_reset(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/vl.c b/vl.c index 4ad15b8..09f8e8b 100644 --- a/vl.c +++ b/vl.c @@ -433,6 +433,16 @@ static QemuOptsList qemu_machine_opts = { }, }; +static QemuOptsList qemu_cpu_opts = { + .name = "cpu", + .implied_opt_name = "type", + .merge_lists = true, + .head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head), + .desc = { + { /* End of list */ } + }, +}; + static QemuOptsList qemu_boot_opts = { .name = "boot-opts", .implied_opt_name = "order", @@ -548,6 +558,25 @@ QemuOpts *qemu_get_machine_opts(void) return opts; } +/** + * Get CPU options + * + * Returns: CPU options (never null). + */ +QemuOpts *qemu_get_cpu_opts(void) +{ + QemuOptsList *list; + QemuOpts *opts; + + list = qemu_find_opts("cpu"); + assert(list); + opts = qemu_opts_find(list, NULL); + if (!opts) { + opts = qemu_opts_create_nofail(list); + } + return opts; +} + const char *qemu_get_vm_name(void) { return qemu_name; @@ -2877,6 +2906,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_trace_opts); qemu_add_opts(&qemu_option_rom_opts); qemu_add_opts(&qemu_machine_opts); + qemu_add_opts(&qemu_cpu_opts); qemu_add_opts(&qemu_smp_opts); qemu_add_opts(&qemu_boot_opts); qemu_add_opts(&qemu_sandbox_opts); @@ -2972,7 +3002,19 @@ int main(int argc, char **argv, char **envp) } case QEMU_OPTION_cpu: /* hw initialization will check this */ + + /* Store cpu_model for old style parser */ cpu_model = optarg; + + /* + * Parse and save options in the cpu options list + * for a new parser + */ + olist = qemu_find_opts("cpu"); + opts = qemu_opts_parse(olist, optarg, 1); + if (!opts) { + exit(1); + } break; case QEMU_OPTION_hda: { -- 1.8.4.rc4