Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1480
Signed-off-by: Dinah Baum <dinahbaum123@gmail.com>
Signed-off-by: Dinah Baum <dinahbaum123@gmail.com>
---
cpu.c | 41 ++++++++++++++++++++++++++++++++++++++++
include/qapi/qmp/qdict.h | 1 +
qemu-options.hx | 7 ++++---
qobject/qdict.c | 5 +++++
softmmu/vl.c | 35 +++++++++++++++++++++++++++++++++-
5 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/cpu.c b/cpu.c
index a99d09cd47..9971ffeeba 100644
--- a/cpu.c
+++ b/cpu.c
@@ -43,6 +43,10 @@
#include "trace/trace-root.h"
#include "qemu/accel.h"
#include "qemu/plugin.h"
+#include "qemu/cutils.h"
+#include "qemu/qemu-print.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qobject.h"
uintptr_t qemu_host_page_size;
intptr_t qemu_host_page_mask;
@@ -312,6 +316,43 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
return get_cpu_model_expansion_info(type, model, errp);
}
+void list_cpu_model_expansion(CpuModelExpansionType type,
+ CpuModelInfo *model,
+ Error **errp)
+{
+ CpuModelExpansionInfo *expansion_info;
+ QDict *qdict;
+ QDictEntry *qdict_entry;
+ const char *key;
+ QObject *obj;
+ QType q_type;
+ GPtrArray *array;
+ int i;
+ const char *type_name;
+
+ expansion_info = get_cpu_model_expansion_info(type, model, errp);
+ if (expansion_info) {
+ qdict = qobject_to(QDict, expansion_info->model->props);
+ if (qdict) {
+ qemu_printf("%s features:\n", model->name);
+ array = g_ptr_array_new();
+ for (qdict_entry = (QDictEntry *)qdict_first(qdict); qdict_entry;
+ qdict_entry = (QDictEntry *)qdict_next(qdict, qdict_entry)) {
+ g_ptr_array_add(array, qdict_entry);
+ }
+ g_ptr_array_sort(array, (GCompareFunc)dict_key_compare);
+ for (i = 0; i < array->len; i++) {
+ qdict_entry = array->pdata[i];
+ key = qdict_entry_key(qdict_entry);
+ obj = qdict_get(qdict, key);
+ q_type = qobject_type(obj);
+ type_name = QType_str(q_type);
+ qemu_printf(" %s=<%s>\n", key, type_name);
+ }
+ }
+ }
+}
+
#if defined(CONFIG_USER_ONLY)
void tb_invalidate_phys_addr(hwaddr addr)
{
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 82e90fc072..d0b6c3d358 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -67,5 +67,6 @@ bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
const char *qdict_get_try_str(const QDict *qdict, const char *key);
QDict *qdict_clone_shallow(const QDict *src);
+int dict_key_compare(QDictEntry **entry1, QDictEntry **entry2);
#endif /* QDICT_H */
diff --git a/qemu-options.hx b/qemu-options.hx
index 29b98c3d4c..e0f0284927 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -169,11 +169,12 @@ SRST
ERST
DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
- "-cpu cpu select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
+ "-cpu cpu select CPU ('-cpu help' for list)\n"
+ " use '-cpu cpu,help' to print possible properties\n", QEMU_ARCH_ALL)
SRST
``-cpu model``
- Select CPU model (``-cpu help`` for list and additional feature
- selection)
+ Select CPU model (``-cpu help`` and ``-cpu cpu,help``) for list and additional feature
+ selection
ERST
DEF("accel", HAS_ARG, QEMU_OPTION_accel,
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 8faff230d3..31407e62f6 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -447,3 +447,8 @@ void qdict_unref(QDict *q)
{
qobject_unref(q);
}
+
+int dict_key_compare(QDictEntry **entry1, QDictEntry **entry2)
+{
+ return g_strcmp0(qdict_entry_key(*entry1), qdict_entry_key(*entry2));
+}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index b0b96f67fa..1fd87f2c06 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -501,6 +501,15 @@ static QemuOptsList qemu_action_opts = {
},
};
+static QemuOptsList qemu_cpu_opts = {
+ .name = "cpu",
+ .implied_opt_name = "cpu",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
+ .desc = {
+ { /* end of list */ }
+ },
+};
+
const char *qemu_get_vm_name(void)
{
return qemu_name;
@@ -1159,6 +1168,26 @@ static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
+static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+ CpuModelInfo *model;
+
+ if (cpu_option && is_help_option(cpu_option)) {
+ list_cpus();
+ return 1;
+ }
+
+ if (!cpu_option || !qemu_opt_has_help_opt(opts)) {
+ return 0;
+ }
+
+ model = g_new0(CpuModelInfo, 1);
+ model->name = (char *)qemu_opt_get(opts, "cpu");
+ /* TODO: handle other expansion cases */
+ list_cpu_model_expansion(CPU_MODEL_EXPANSION_TYPE_FULL, model, errp);
+ return 1;
+}
+
static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
@@ -2466,7 +2495,9 @@ static void qemu_process_help_options(void)
list_cpus();
exit(0);
}
-
+ if (qemu_opts_foreach(qemu_find_opts("cpu"), cpu_help_func, NULL, NULL)) {
+ exit(0);
+ }
if (qemu_opts_foreach(qemu_find_opts("device"),
device_help_func, NULL, NULL)) {
exit(0);
@@ -2704,6 +2735,7 @@ void qemu_init(int argc, char **argv)
qemu_add_opts(&qemu_semihosting_config_opts);
qemu_add_opts(&qemu_fw_cfg_opts);
qemu_add_opts(&qemu_action_opts);
+ qemu_add_opts(&qemu_cpu_opts);
module_call_init(MODULE_INIT_OPTS);
error_init(argv[0]);
@@ -2755,6 +2787,7 @@ void qemu_init(int argc, char **argv)
switch(popt->index) {
case QEMU_OPTION_cpu:
/* hw initialization will check this */
+ qemu_opts_parse_noisily(qemu_find_opts("cpu"), optarg, true);
cpu_option = optarg;
break;
case QEMU_OPTION_hda:
--
2.30.2
Dinah Baum <dinahbaum123@gmail.com> writes: > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1480 > Signed-off-by: Dinah Baum <dinahbaum123@gmail.com> > > Signed-off-by: Dinah Baum <dinahbaum123@gmail.com> Looks basically the same as v2, which means my review still applies. Message-ID: <878rdbfww1.fsf@pond.sub.org> https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg06699.html If you need further assistance, just ask.
Thanks, I will fix this. I somehow didn't catch that you had replied to the old one. -Dinah On Tue, Aug 1, 2023 at 10:10 AM Markus Armbruster <armbru@redhat.com> wrote: > Dinah Baum <dinahbaum123@gmail.com> writes: > > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1480 > > Signed-off-by: Dinah Baum <dinahbaum123@gmail.com> > > > > Signed-off-by: Dinah Baum <dinahbaum123@gmail.com> > > Looks basically the same as v2, which means my review still applies. > > Message-ID: <878rdbfww1.fsf@pond.sub.org> > https://lists.nongnu.org/archive/html/qemu-devel/2023-05/msg06699.html > > If you need further assistance, just ask. > >
Dinah B <dinahbaum123@gmail.com> writes: > Thanks, I will fix this. I somehow didn't catch that you had replied to the > old one. Happens :)
Hi, Is there a way to distinguish between qemu-system-* vs qemu-* builds? At first I thought #CONFIG_LINUX_USER might be it but not all non-mmu builds set this. Thanks, -Dinah On Wed, Aug 2, 2023 at 1:36 AM Markus Armbruster <armbru@redhat.com> wrote: > Dinah B <dinahbaum123@gmail.com> writes: > > > Thanks, I will fix this. I somehow didn't catch that you had replied to > the > > old one. > > Happens :) > >
Dinah B <dinahbaum123@gmail.com> writes: > Hi, > > Is there a way to distinguish between qemu-system-* vs qemu-* builds? > At first I thought #CONFIG_LINUX_USER might be it but not all non-mmu > builds set this. What are you trying to accomplish?
Hi, Due to extracting CPU features via a qmp command, it only works on qemu-system-* builds. Building qmp for non system builds strikes me as extreme overkill so I need a way to exclude this from non system builds. Or maybe there's a way to disentangle querying CPU features independent from the qom or qmp based data structures it's currently intertwined with. Thanks, -Dinah On Tue, Nov 14, 2023 at 12:44 PM Markus Armbruster <armbru@redhat.com> wrote: > Dinah B <dinahbaum123@gmail.com> writes: > > > Hi, > > > > Is there a way to distinguish between qemu-system-* vs qemu-* builds? > > At first I thought #CONFIG_LINUX_USER might be it but not all non-mmu > > builds set this. > > What are you trying to accomplish? > >
Just realized that the commit message on this one got a little mangled. I'm
happy to revise it but I'd prefer to get the code reviewed first before
doing a purely commit message change.
-Dinah
On Sun, Jul 30, 2023 at 2:41 AM Dinah Baum <dinahbaum123@gmail.com> wrote:
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1480
> Signed-off-by: Dinah Baum <dinahbaum123@gmail.com>
>
> Signed-off-by: Dinah Baum <dinahbaum123@gmail.com>
> ---
> cpu.c | 41 ++++++++++++++++++++++++++++++++++++++++
> include/qapi/qmp/qdict.h | 1 +
> qemu-options.hx | 7 ++++---
> qobject/qdict.c | 5 +++++
> softmmu/vl.c | 35 +++++++++++++++++++++++++++++++++-
> 5 files changed, 85 insertions(+), 4 deletions(-)
>
> diff --git a/cpu.c b/cpu.c
> index a99d09cd47..9971ffeeba 100644
> --- a/cpu.c
> +++ b/cpu.c
> @@ -43,6 +43,10 @@
> #include "trace/trace-root.h"
> #include "qemu/accel.h"
> #include "qemu/plugin.h"
> +#include "qemu/cutils.h"
> +#include "qemu/qemu-print.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qobject.h"
>
> uintptr_t qemu_host_page_size;
> intptr_t qemu_host_page_mask;
> @@ -312,6 +316,43 @@ CpuModelExpansionInfo
> *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
> return get_cpu_model_expansion_info(type, model, errp);
> }
>
> +void list_cpu_model_expansion(CpuModelExpansionType type,
> + CpuModelInfo *model,
> + Error **errp)
> +{
> + CpuModelExpansionInfo *expansion_info;
> + QDict *qdict;
> + QDictEntry *qdict_entry;
> + const char *key;
> + QObject *obj;
> + QType q_type;
> + GPtrArray *array;
> + int i;
> + const char *type_name;
> +
> + expansion_info = get_cpu_model_expansion_info(type, model, errp);
> + if (expansion_info) {
> + qdict = qobject_to(QDict, expansion_info->model->props);
> + if (qdict) {
> + qemu_printf("%s features:\n", model->name);
> + array = g_ptr_array_new();
> + for (qdict_entry = (QDictEntry *)qdict_first(qdict);
> qdict_entry;
> + qdict_entry = (QDictEntry *)qdict_next(qdict,
> qdict_entry)) {
> + g_ptr_array_add(array, qdict_entry);
> + }
> + g_ptr_array_sort(array, (GCompareFunc)dict_key_compare);
> + for (i = 0; i < array->len; i++) {
> + qdict_entry = array->pdata[i];
> + key = qdict_entry_key(qdict_entry);
> + obj = qdict_get(qdict, key);
> + q_type = qobject_type(obj);
> + type_name = QType_str(q_type);
> + qemu_printf(" %s=<%s>\n", key, type_name);
> + }
> + }
> + }
> +}
> +
> #if defined(CONFIG_USER_ONLY)
> void tb_invalidate_phys_addr(hwaddr addr)
> {
> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
> index 82e90fc072..d0b6c3d358 100644
> --- a/include/qapi/qmp/qdict.h
> +++ b/include/qapi/qmp/qdict.h
> @@ -67,5 +67,6 @@ bool qdict_get_try_bool(const QDict *qdict, const char
> *key, bool def_value);
> const char *qdict_get_try_str(const QDict *qdict, const char *key);
>
> QDict *qdict_clone_shallow(const QDict *src);
> +int dict_key_compare(QDictEntry **entry1, QDictEntry **entry2);
>
> #endif /* QDICT_H */
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 29b98c3d4c..e0f0284927 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -169,11 +169,12 @@ SRST
> ERST
>
> DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
> - "-cpu cpu select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
> + "-cpu cpu select CPU ('-cpu help' for list)\n"
> + " use '-cpu cpu,help' to print possible properties\n",
> QEMU_ARCH_ALL)
> SRST
> ``-cpu model``
> - Select CPU model (``-cpu help`` for list and additional feature
> - selection)
> + Select CPU model (``-cpu help`` and ``-cpu cpu,help``) for list and
> additional feature
> + selection
> ERST
>
> DEF("accel", HAS_ARG, QEMU_OPTION_accel,
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index 8faff230d3..31407e62f6 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -447,3 +447,8 @@ void qdict_unref(QDict *q)
> {
> qobject_unref(q);
> }
> +
> +int dict_key_compare(QDictEntry **entry1, QDictEntry **entry2)
> +{
> + return g_strcmp0(qdict_entry_key(*entry1), qdict_entry_key(*entry2));
> +}
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index b0b96f67fa..1fd87f2c06 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -501,6 +501,15 @@ static QemuOptsList qemu_action_opts = {
> },
> };
>
> +static QemuOptsList qemu_cpu_opts = {
> + .name = "cpu",
> + .implied_opt_name = "cpu",
> + .head = QTAILQ_HEAD_INITIALIZER(qemu_cpu_opts.head),
> + .desc = {
> + { /* end of list */ }
> + },
> +};
> +
> const char *qemu_get_vm_name(void)
> {
> return qemu_name;
> @@ -1159,6 +1168,26 @@ static int device_init_func(void *opaque, QemuOpts
> *opts, Error **errp)
> return 0;
> }
>
> +static int cpu_help_func(void *opaque, QemuOpts *opts, Error **errp)
> +{
> + CpuModelInfo *model;
> +
> + if (cpu_option && is_help_option(cpu_option)) {
> + list_cpus();
> + return 1;
> + }
> +
> + if (!cpu_option || !qemu_opt_has_help_opt(opts)) {
> + return 0;
> + }
> +
> + model = g_new0(CpuModelInfo, 1);
> + model->name = (char *)qemu_opt_get(opts, "cpu");
> + /* TODO: handle other expansion cases */
> + list_cpu_model_expansion(CPU_MODEL_EXPANSION_TYPE_FULL, model, errp);
> + return 1;
> +}
> +
> static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
> {
> Error *local_err = NULL;
> @@ -2466,7 +2495,9 @@ static void qemu_process_help_options(void)
> list_cpus();
> exit(0);
> }
> -
> + if (qemu_opts_foreach(qemu_find_opts("cpu"), cpu_help_func, NULL,
> NULL)) {
> + exit(0);
> + }
> if (qemu_opts_foreach(qemu_find_opts("device"),
> device_help_func, NULL, NULL)) {
> exit(0);
> @@ -2704,6 +2735,7 @@ void qemu_init(int argc, char **argv)
> qemu_add_opts(&qemu_semihosting_config_opts);
> qemu_add_opts(&qemu_fw_cfg_opts);
> qemu_add_opts(&qemu_action_opts);
> + qemu_add_opts(&qemu_cpu_opts);
> module_call_init(MODULE_INIT_OPTS);
>
> error_init(argv[0]);
> @@ -2755,6 +2787,7 @@ void qemu_init(int argc, char **argv)
> switch(popt->index) {
> case QEMU_OPTION_cpu:
> /* hw initialization will check this */
> + qemu_opts_parse_noisily(qemu_find_opts("cpu"), optarg,
> true);
> cpu_option = optarg;
> break;
> case QEMU_OPTION_hda:
> --
> 2.30.2
>
>
© 2016 - 2026 Red Hat, Inc.