[pve-devel] [RFC pve-qemu 1/9] Add -list-flags command line option

Stefan Reiter s.reiter at proxmox.com
Thu Oct 28 13:41:42 CEST 2021


Useful for retrieving flags from default CPU models.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
 ...E-Add-list-flags-command-line-option.patch | 213 ++++++++++++++++++
 debian/patches/series                         |   1 +
 2 files changed, 214 insertions(+)
 create mode 100644 debian/patches/pve/0049-PVE-Add-list-flags-command-line-option.patch

diff --git a/debian/patches/pve/0049-PVE-Add-list-flags-command-line-option.patch b/debian/patches/pve/0049-PVE-Add-list-flags-command-line-option.patch
new file mode 100644
index 0000000..56ced90
--- /dev/null
+++ b/debian/patches/pve/0049-PVE-Add-list-flags-command-line-option.patch
@@ -0,0 +1,213 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Reiter <s.reiter at proxmox.com>
+Date: Wed, 27 May 2020 13:51:52 +0200
+Subject: [PATCH] PVE: Add -list-flags command line option
+
+Prints all flags for a given cpu model to stdout.
+
+Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
+---
+ include/sysemu/cpus.h    |  1 +
+ qemu-options.hx          |  8 ++++++
+ softmmu/cpus.c           | 10 +++++++
+ softmmu/vl.c             | 20 ++++++++++++++
+ target/i386/cpu-sysemu.c |  2 +-
+ target/i386/cpu.c        | 58 ++++++++++++++++++++++++++++++++++++++++
+ target/i386/cpu.h        |  4 +++
+ 7 files changed, 102 insertions(+), 1 deletion(-)
+
+diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
+index 868f1192de..433265b166 100644
+--- a/include/sysemu/cpus.h
++++ b/include/sysemu/cpus.h
+@@ -56,5 +56,6 @@ extern int smp_threads;
+ #endif
+ 
+ void list_cpus(const char *optarg);
++int list_cpu_flags(const char *model_name, Error **errp);
+ 
+ #endif
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 83aa59a920..33a8a31aa4 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -137,6 +137,14 @@ SRST
+     selection)
+ ERST
+ 
++DEF("list-flags", 0, QEMU_OPTION_list_flags,
++    "-list-flags     list all flags of specified -cpu on stdout, then exit. Respects -machine versions.\n", QEMU_ARCH_I386)
++SRST
++``-list-flags``
++    List all flags of specified -cpu on stdout, then exit. Respects
++    -machine versions.
++ERST
++
+ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
+     "-accel [accel=]accelerator[,prop[=value][,...]]\n"
+     "                select accelerator (kvm, xen, hax, hvf, nvmm, whpx or tcg; use 'help' for a list)\n"
+diff --git a/softmmu/cpus.c b/softmmu/cpus.c
+index 071085f840..f8351e2154 100644
+--- a/softmmu/cpus.c
++++ b/softmmu/cpus.c
+@@ -726,6 +726,16 @@ void list_cpus(const char *optarg)
+ #endif
+ }
+ 
++int list_cpu_flags(const char *model_name, Error **errp)
++{
++#if defined(cpu_list_flags)
++    return cpu_list_flags(model_name, errp);
++#endif
++
++    fprintf(stderr, "-list-flags not available for this architecture\n");
++    return 1;
++}
++
+ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
+                  bool has_cpu, int64_t cpu_index, Error **errp)
+ {
+diff --git a/softmmu/vl.c b/softmmu/vl.c
+index 5ca11e7469..f47f076a1f 100644
+--- a/softmmu/vl.c
++++ b/softmmu/vl.c
+@@ -145,6 +145,7 @@ typedef struct ObjectOption {
+ } ObjectOption;
+ 
+ static const char *cpu_option;
++bool list_cpu_flags_opt = false;
+ static const char *mem_path;
+ static const char *incoming;
+ static const char *loadvm;
+@@ -2817,6 +2818,9 @@ void qemu_init(int argc, char **argv, char **envp)
+                 /* hw initialization will check this */
+                 cpu_option = optarg;
+                 break;
++            case QEMU_OPTION_list_flags:
++                list_cpu_flags_opt = true;
++                break;
+             case QEMU_OPTION_hda:
+             case QEMU_OPTION_hdb:
+             case QEMU_OPTION_hdc:
+@@ -3635,6 +3639,22 @@ void qemu_init(int argc, char **argv, char **envp)
+     }
+     trace_init_file();
+ 
++    /* list flags if requested, then exit */
++    if (list_cpu_flags_opt) {
++        if (!cpu_option) {
++            printf("-cpu argument required for -list-flags\n");
++            exit(1);
++        }
++
++        /* Check for and remove cpu parameters other than model */
++        char *commaIdx = strchr(cpu_option, ',');
++        if (commaIdx != NULL) {
++            *commaIdx = 0;
++        }
++
++        exit(list_cpu_flags(cpu_option, &error_fatal));
++    }
++
+     qemu_init_main_loop(&error_fatal);
+     cpu_timers_init();
+ 
+diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c
+index 1078e3d157..1ebff3d847 100644
+--- a/target/i386/cpu-sysemu.c
++++ b/target/i386/cpu-sysemu.c
+@@ -142,7 +142,7 @@ static void object_apply_props(Object *obj, QDict *props, Error **errp)
+ }
+ 
+ /* Create X86CPU object according to model+props specification */
+-static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp)
++X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp)
+ {
+     X86CPU *xc = NULL;
+     X86CPUClass *xcc;
+diff --git a/target/i386/cpu.c b/target/i386/cpu.c
+index 34a7ce865b..a972dff4ed 100644
+--- a/target/i386/cpu.c
++++ b/target/i386/cpu.c
+@@ -6855,3 +6855,61 @@ static void x86_cpu_register_types(void)
+ }
+ 
+ type_init(x86_cpu_register_types)
++
++int x86_cpu_list_flags(const char *model_name, Error **errp) {
++    X86CPU *cpu;
++
++    cpu = x86_cpu_from_model(model_name, NULL, errp);
++    if (!cpu) {
++        fprintf(stderr, "Unknown CPU model '%s'\n", model_name);
++        return 1;
++    }
++
++    strList *result = NULL;
++    x86_cpu_list_feature_names(cpu->env.features, &result);
++    if (!result) {
++        fprintf(stderr, "No flags found for CPU model '%s'\n", model_name);
++        return 1;
++    }
++
++    strList *flag = result;
++    strList *seen = NULL;
++    strList **seenPtr;
++
++    while (flag) {
++        /* with 'host' and 'max' there are some flags without a value */
++        if (!flag->value) {
++            goto nextLoop;
++        }
++
++        /* don't print duplicates */
++        bool newFlag = true;
++        seenPtr = &seen;
++        while (*seenPtr) {
++            if (newFlag && strcmp((*seenPtr)->value, flag->value) == 0) {
++                newFlag = false;
++            }
++            seenPtr = &(*seenPtr)->next;
++        }
++
++        if (newFlag) {
++            printf("%s ", flag->value);
++
++            /* insert into 'seen' list; seenPtr points to first empty '->next'
++             * after loop above, so we can insert there directly */
++            strList *new = g_new0(strList, 1);
++            new->value = g_strdup(flag->value);
++            *seenPtr = new;
++        }
++
++nextLoop:
++        flag = flag->next;
++    }
++    printf("\n");
++
++    if (seen) {
++        g_free(seen);
++    }
++    g_free(result);
++    return 0;
++}
+diff --git a/target/i386/cpu.h b/target/i386/cpu.h
+index 6c50d3ab4f..bb88f53a2d 100644
+--- a/target/i386/cpu.h
++++ b/target/i386/cpu.h
+@@ -2013,6 +2013,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+ 
+ #define cpu_signal_handler cpu_x86_signal_handler
+ #define cpu_list x86_cpu_list
++#define cpu_list_flags x86_cpu_list_flags
+ 
+ /* MMU modes definitions */
+ #define MMU_KSMAP_IDX   0
+@@ -2246,4 +2247,7 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
+ # define TARGET_VSYSCALL_PAGE  (UINT64_C(-10) << 20)
+ #endif
+ 
++X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error **errp);
++int x86_cpu_list_flags(const char *model_name, Error **errp);
++
+ #endif /* I386_CPU_H */
diff --git a/debian/patches/series b/debian/patches/series
index fb5c213..70ce86e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -59,3 +59,4 @@ pve/0045-block-io-accept-NULL-qiov-in-bdrv_pad_request.patch
 pve/0046-block-add-alloc-track-driver.patch
 pve/0047-PVE-whitelist-invalid-QAPI-names-for-backwards-compa.patch
 pve/0048-PVE-savevm-async-register-yank-before-migration_inco.patch
+pve/0049-PVE-Add-list-flags-command-line-option.patch
-- 
2.30.2





More information about the pve-devel mailing list