From: "Jason J. Herne" <jjhe...@us.ibm.com> Add infrastructure for treating cpus as devices. This patch allows cpus to be specified using a combination of '-smp' and '-device cpu'. This approach forces a change in the way cpus are counted via smp_cpus.
Signed-off-by: Jason J. Herne <jjhe...@us.ibm.com> --- include/hw/boards.h | 3 ++ vl.c | 95 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 14 deletions(-) diff --git a/include/hw/boards.h b/include/hw/boards.h index ed427a1..b0c86bf 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -47,8 +47,11 @@ typedef struct QEMUMachine { GlobalProperty *compat_props; struct QEMUMachine *next; const char *hw_version; + const char *cpu_device_str; } QEMUMachine; +#define CPUS_ARE_DEVICES(qemu_mach) (qemu_mach->cpu_device_str != NULL) + int qemu_register_machine(QEMUMachine *m); QEMUMachine *find_default_machine(void); diff --git a/vl.c b/vl.c index 71e1e6d..873834f 100644 --- a/vl.c +++ b/vl.c @@ -546,6 +546,46 @@ static int default_driver_check(QemuOpts *opts, void *opaque) return 0; } +static void convert_smp_to_cpu_devices(QEMUMachine *machine) +{ + int i; + QemuOpts *opts; + + for (i = 0; i < smp_cpus; i++) { + opts = qemu_opts_create_nofail(qemu_find_opts("device")); + qemu_opt_set(opts, "driver", machine->cpu_device_str); + } + smp_cpus = 0; +} + +static int count_cpu_devices(QemuOpts *opts, void *opaque) +{ + const char *driver = qemu_opt_get(opts, "driver"); + QEMUMachine *machine = (QEMUMachine *)opaque; + + /* Skip non-cpu devices*/ + if (!driver || strcmp(driver, machine->cpu_device_str) != 0) { + return 0; + } + + smp_cpus += 1; + return 0; +} + +static int handle_cpu_device(QemuOpts *opts, void *opaque) +{ + const char *driver = qemu_opt_get(opts, "driver"); + QEMUMachine *machine = (QEMUMachine *)opaque; + + /* Skip non-cpu devices*/ + if (!driver || strcmp(driver, machine->cpu_device_str) != 0) { + return 0; + } + + qdev_device_add(opts); + return 0; +} + /***********************************************************/ /* QEMU state */ @@ -2318,6 +2358,13 @@ static int device_help_func(QemuOpts *opts, void *opaque) static int device_init_func(QemuOpts *opts, void *opaque) { DeviceState *dev; + const char *driver = qemu_opt_get(opts, "driver"); + QEMUMachine *machine = (QEMUMachine *)opaque; + + /* Skip cpu devices*/ + if (!driver || strcmp(driver, machine->cpu_device_str) == 0) { + return 0; + } dev = qdev_device_add(opts); if (!dev) @@ -3630,19 +3677,6 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_smp: smp_parse(optarg); - if (smp_cpus < 1) { - fprintf(stderr, "Invalid number of CPUs\n"); - exit(1); - } - if (max_cpus < smp_cpus) { - fprintf(stderr, "maxcpus must be equal to or greater than " - "smp\n"); - exit(1); - } - if (max_cpus > 255) { - fprintf(stderr, "Unsupported number of maxcpus\n"); - exit(1); - } break; case QEMU_OPTION_vnc: #ifdef CONFIG_VNC @@ -3965,6 +3999,16 @@ int main(int argc, char **argv, char **envp) } /* + * Count cpu devices. Cpu count is determied by adding -device cpu + * statements to the number of cpus specified on the -smp statement. + */ + if (CPUS_ARE_DEVICES(machine)) { + convert_smp_to_cpu_devices(machine); + qemu_opts_foreach(qemu_find_opts("device"), count_cpu_devices, + machine, 0); + } + + /* * Default to max_cpus = smp_cpus, in case the user doesn't * specify a max_cpus value. */ @@ -3979,6 +4023,20 @@ int main(int argc, char **argv, char **envp) exit(1); } + if (smp_cpus < 1) { + fprintf(stderr, "Invalid number of CPUs\n"); + exit(1); + } + if (max_cpus < smp_cpus) { + fprintf(stderr, "maxcpus must be equal to or greater than the number of" + " cpus defined\n"); + exit(1); + } + if (max_cpus > 255) { + fprintf(stderr, "Unsupported number of maxcpus\n"); + exit(1); + } + /* * Get the default machine options from the machine if it is not already * specified either by the configuration file or by the command line. @@ -4305,6 +4363,13 @@ int main(int argc, char **argv, char **envp) .cpu_model = cpu_model }; machine->init(&args); + /* Create cpu devices */ + if (CPUS_ARE_DEVICES(machine)) { + smp_cpus = 0; /* Reset this because each cpu will count itself */ + qemu_opts_foreach(qemu_find_opts("device"), handle_cpu_device, + machine, 0); + } + if (machine->post_cpu_init) { machine->post_cpu_init(); } @@ -4324,8 +4389,10 @@ int main(int argc, char **argv, char **envp) } /* init generic devices */ - if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0) + if (qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, machine, 1) != 0) { exit(1); + } net_check_clients(); -- 1.7.10.4