aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qemu-options.hx4
-rw-r--r--vl.c122
2 files changed, 71 insertions, 55 deletions
diff --git a/qemu-options.hx b/qemu-options.hx
index ca6fdf6134..137a39b7ad 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -73,7 +73,7 @@ Select CPU model (@code{-cpu help} for list and additional feature selection)
ETEXI
DEF("smp", HAS_ARG, QEMU_OPTION_smp,
- "-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]\n"
+ "-smp [cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]\n"
" set the number of CPUs to 'n' [default=1]\n"
" maxcpus= maximum number of total cpus, including\n"
" offline CPUs for hotplug, etc\n"
@@ -82,7 +82,7 @@ DEF("smp", HAS_ARG, QEMU_OPTION_smp,
" sockets= number of discrete sockets in the system\n",
QEMU_ARCH_ALL)
STEXI
-@item -smp @var{n}[,cores=@var{cores}][,threads=@var{threads}][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
+@item -smp [cpus=]@var{n}[,cores=@var{cores}][,threads=@var{threads}][,sockets=@var{sockets}][,maxcpus=@var{maxcpus}]
@findex -smp
Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255
CPUs are supported. On Sparc32 target, Linux limits the number of usable CPUs
diff --git a/vl.c b/vl.c
index 0a8f056cc2..6d9fd7d807 100644
--- a/vl.c
+++ b/vl.c
@@ -1401,48 +1401,79 @@ static void numa_add(const char *optarg)
}
}
-static void smp_parse(const char *optarg)
+static QemuOptsList qemu_smp_opts = {
+ .name = "smp-opts",
+ .implied_opt_name = "cpus",
+ .merge_lists = true,
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_smp_opts.head),
+ .desc = {
+ {
+ .name = "cpus",
+ .type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "sockets",
+ .type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "cores",
+ .type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "threads",
+ .type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "maxcpus",
+ .type = QEMU_OPT_NUMBER,
+ },
+ { /*End of list */ }
+ },
+};
+
+static void smp_parse(QemuOpts *opts)
{
- int smp, sockets = 0, threads = 0, cores = 0;
- char *endptr;
- char option[128];
+ if (opts) {
- smp = strtoul(optarg, &endptr, 10);
- if (endptr != optarg) {
- if (*endptr == ',') {
- endptr++;
- }
- }
- if (get_param_value(option, 128, "sockets", endptr) != 0)
- sockets = strtoull(option, NULL, 10);
- if (get_param_value(option, 128, "cores", endptr) != 0)
- cores = strtoull(option, NULL, 10);
- if (get_param_value(option, 128, "threads", endptr) != 0)
- threads = strtoull(option, NULL, 10);
- if (get_param_value(option, 128, "maxcpus", endptr) != 0)
- max_cpus = strtoull(option, NULL, 10);
-
- /* compute missing values, prefer sockets over cores over threads */
- if (smp == 0 || sockets == 0) {
- sockets = sockets > 0 ? sockets : 1;
- cores = cores > 0 ? cores : 1;
- threads = threads > 0 ? threads : 1;
- if (smp == 0) {
- smp = cores * threads * sockets;
- }
- } else {
- if (cores == 0) {
+ unsigned cpus = qemu_opt_get_number(opts, "cpus", 0);
+ unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
+ unsigned cores = qemu_opt_get_number(opts, "cores", 0);
+ unsigned threads = qemu_opt_get_number(opts, "threads", 0);
+
+ /* compute missing values, prefer sockets over cores over threads */
+ if (cpus == 0 || sockets == 0) {
+ sockets = sockets > 0 ? sockets : 1;
+ cores = cores > 0 ? cores : 1;
threads = threads > 0 ? threads : 1;
- cores = smp / (sockets * threads);
+ if (cpus == 0) {
+ cpus = cores * threads * sockets;
+ }
} else {
- threads = smp / (cores * sockets);
+ if (cores == 0) {
+ threads = threads > 0 ? threads : 1;
+ cores = cpus / (sockets * threads);
+ } else {
+ threads = cpus / (cores * sockets);
+ }
}
+
+ max_cpus = qemu_opt_get_number(opts, "maxcpus", 0);
+
+ smp_cpus = cpus;
+ smp_cores = cores > 0 ? cores : 1;
+ smp_threads = threads > 0 ? threads : 1;
+
}
- smp_cpus = smp;
- smp_cores = cores > 0 ? cores : 1;
- smp_threads = threads > 0 ? threads : 1;
- if (max_cpus == 0)
+
+ if (max_cpus == 0) {
max_cpus = smp_cpus;
+ }
+
+ if (max_cpus > 255) {
+ fprintf(stderr, "Unsupported number of maxcpus\n");
+ exit(1);
+ }
+ if (max_cpus < smp_cpus) {
+ fprintf(stderr, "maxcpus must be equal to or greater than smp\n");
+ exit(1);
+ }
+
}
static void configure_realtime(QemuOpts *opts)
@@ -2895,6 +2926,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_smp_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_sandbox_opts);
qemu_add_opts(&qemu_add_fd_opts);
@@ -3561,18 +3593,7 @@ 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");
+ if (!qemu_opts_parse(qemu_find_opts("smp-opts"), optarg, 1)) {
exit(1);
}
break;
@@ -3896,12 +3917,7 @@ int main(int argc, char **argv, char **envp)
data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
}
- /*
- * Default to max_cpus = smp_cpus, in case the user doesn't
- * specify a max_cpus value.
- */
- if (!max_cpus)
- max_cpus = smp_cpus;
+ smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
if (smp_cpus > machine->max_cpus) {