From: Fiona Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH qemu 1/2] generate and ship static list of CPU models
Date: Tue, 10 Feb 2026 14:52:28 +0100 [thread overview]
Message-ID: <20260210135417.184127-2-f.ebner@proxmox.com> (raw)
In-Reply-To: <20260210135417.184127-1-f.ebner@proxmox.com>
Fail the build when the list changes, so that new models can be
picked up selectively and other changes that might require adaptations
are not missed.
Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
debian/cpu-models-aarch64.json | 1 +
debian/cpu-models-x86_64.json | 1 +
debian/parse-cpu-models.pl | 121 +++++++++++++++++++++++++++++++++
debian/rules | 12 ++++
4 files changed, 135 insertions(+)
create mode 100644 debian/cpu-models-aarch64.json
create mode 100644 debian/cpu-models-x86_64.json
create mode 100755 debian/parse-cpu-models.pl
diff --git a/debian/cpu-models-aarch64.json b/debian/cpu-models-aarch64.json
new file mode 100644
index 0000000..a69c05f
--- /dev/null
+++ b/debian/cpu-models-aarch64.json
@@ -0,0 +1 @@
+{"a64fx":"ARM","cortex-a35":"ARM","cortex-a53":"ARM","cortex-a55":"ARM","cortex-a57":"ARM","cortex-a710":"ARM","cortex-a72":"ARM","cortex-a76":"ARM","max":"default","neoverse-n1":"ARM","neoverse-n2":"ARM","neoverse-v1":"ARM"}
\ No newline at end of file
diff --git a/debian/cpu-models-x86_64.json b/debian/cpu-models-x86_64.json
new file mode 100644
index 0000000..178dbf0
--- /dev/null
+++ b/debian/cpu-models-x86_64.json
@@ -0,0 +1 @@
+{"486":"GenuineIntel","Broadwell":"GenuineIntel","Broadwell-IBRS":"GenuineIntel","Broadwell-noTSX":"GenuineIntel","Broadwell-noTSX-IBRS":"GenuineIntel","Cascadelake-Server":"GenuineIntel","Cascadelake-Server-noTSX":"GenuineIntel","Cascadelake-Server-v2":"GenuineIntel","Cascadelake-Server-v4":"GenuineIntel","Cascadelake-Server-v5":"GenuineIntel","ClearwaterForest":"GenuineIntel","Conroe":"GenuineIntel","Cooperlake":"GenuineIntel","Cooperlake-v2":"GenuineIntel","EPYC":"AuthenticAMD","EPYC-Genoa":"AuthenticAMD","EPYC-Genoa-v2":"AuthenticAMD","EPYC-IBPB":"AuthenticAMD","EPYC-Milan":"AuthenticAMD","EPYC-Milan-v2":"AuthenticAMD","EPYC-Milan-v3":"AuthenticAMD","EPYC-Rome":"AuthenticAMD","EPYC-Rome-v2":"AuthenticAMD","EPYC-Rome-v3":"AuthenticAMD","EPYC-Rome-v4":"AuthenticAMD","EPYC-Rome-v5":"AuthenticAMD","EPYC-Turin":"AuthenticAMD","EPYC-v3":"AuthenticAMD","EPYC-v4":"AuthenticAMD","EPYC-v5":"AuthenticAMD","GraniteRapids":"GenuineIntel","GraniteRapids-v2":"GenuineIntel","GraniteRapids-v3":"GenuineIntel","Haswell":"GenuineIntel","Haswell-IBRS":"GenuineIntel","Haswell-noTSX":"GenuineIntel","Haswell-noTSX-IBRS":"GenuineIntel","Icelake-Client":"GenuineIntel","Icelake-Client-noTSX":"GenuineIntel","Icelake-Server":"GenuineIntel","Icelake-Server-noTSX":"GenuineIntel","Icelake-Server-v3":"GenuineIntel","Icelake-Server-v4":"GenuineIntel","Icelake-Server-v5":"GenuineIntel","Icelake-Server-v6":"GenuineIntel","Icelake-Server-v7":"GenuineIntel","IvyBridge":"GenuineIntel","IvyBridge-IBRS":"GenuineIntel","KnightsMill":"GenuineIntel","Nehalem":"GenuineIntel","Nehalem-IBRS":"GenuineIntel","Opteron_G1":"AuthenticAMD","Opteron_G2":"AuthenticAMD","Opteron_G3":"AuthenticAMD","Opteron_G4":"AuthenticAMD","Opteron_G5":"AuthenticAMD","Penryn":"GenuineIntel","SandyBridge":"GenuineIntel","SandyBridge-IBRS":"GenuineIntel","SapphireRapids":"GenuineIntel","SapphireRapids-v2":"GenuineIntel","SapphireRapids-v3":"GenuineIntel","SapphireRapids-v4":"GenuineIntel","SierraForest":"GenuineIntel","SierraForest-v2":"GenuineIntel","SierraForest-v3":"GenuineIntel","Skylake-Client":"GenuineIntel","Skylake-Client-IBRS":"GenuineIntel","Skylake-Client-noTSX-IBRS":"GenuineIntel","Skylake-Client-v4":"GenuineIntel","Skylake-Server":"GenuineIntel","Skylake-Server-IBRS":"GenuineIntel","Skylake-Server-noTSX-IBRS":"GenuineIntel","Skylake-Server-v4":"GenuineIntel","Skylake-Server-v5":"GenuineIntel","Westmere":"GenuineIntel","Westmere-IBRS":"GenuineIntel","athlon":"AuthenticAMD","core2duo":"GenuineIntel","coreduo":"GenuineIntel","kvm32":"default","kvm64":"default","max":"default","pentium":"GenuineIntel","pentium2":"GenuineIntel","pentium3":"GenuineIntel","phenom":"AuthenticAMD","qemu32":"default","qemu64":"default"}
\ No newline at end of file
diff --git a/debian/parse-cpu-models.pl b/debian/parse-cpu-models.pl
new file mode 100755
index 0000000..02086db
--- /dev/null
+++ b/debian/parse-cpu-models.pl
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+
+use v5.36;
+
+use JSON qw(to_json);
+
+# NOTE: Only the alias names were exposed in qemu-server before the info was created during build
+# of pve-qemu. Continue to do so.
+
+my @skip_models = (
+ 'base',
+ 'host', # added in qemu-server depending on arch
+
+ # x86_64
+ 'n270',
+ 'Denverton',
+ 'Snowridge',
+ # some more are skipped based on vendor
+
+ # aarch64
+ 'arm1026',
+ 'arm1136',
+ 'arm1136-r2',
+ 'arm1176',
+ 'arm11mpcore',
+ 'arm926',
+ 'arm946',
+ 'cortex-a7',
+ 'cortex-a8',
+ 'cortex-a9',
+ 'cortex-a15',
+ 'cortex-m0',
+ 'cortex-m3',
+ 'cortex-m33',
+ 'cortex-m4',
+ 'cortex-m55',
+ 'cortex-m7',
+ 'cortex-r5',
+ 'cortex-r52',
+ 'cortex-r5f',
+ 'sa1100',
+ 'sa1110',
+ 'ti925t',
+ # some more are skipped based on being deprecated
+);
+my $skip_models_re = qr/(@{[join('|', @skip_models)]})/;
+
+my $cpu_models = {};
+my $aliases = {};
+
+while (my $line = <STDIN>) {
+ last if $line =~ /^\s*Recognized CPUID flags:/;
+ next if $line =~ /^\s*Available CPUs:/;
+ next if $line =~ /^$/;
+
+ $line =~ s/^\s+//;
+ $line =~ s/\s+$//;
+
+ my ($model, $info) = ($line =~ m/^(\S+)\s*(.*)$/) or die "unexpected line '$line'\n";
+
+ if ($model eq 'athlon-v1') {
+ # has unusual info: QEMU Virtual CPU version 2.5+
+ $cpu_models->{$model} = 'AuthenticAMD';
+ next;
+ } elsif ($model =~ m/^((kvm|qemu)(32|64)-v1|max)$/) {
+ $cpu_models->{$model} = 'default';
+ next;
+ } elsif ($model =~ m/^$skip_models_re(-v\d)?$/) {
+ next; # skip
+ }
+
+ if (!$info) {
+ if ($model =~ m/^(486|pentium(2|3)?)-v1$/) {
+ $cpu_models->{$model} = 'GenuineIntel';
+ next;
+ } elsif ($model =~ m/^(a64fx|cortex-|neoverse-).*$/) {
+ $cpu_models->{$model} = 'ARM';
+ next;
+ }
+ die "unable to deal with line '$line' - implement me"
+ } elsif ($info =~ m/^\(deprecated\)$/) {
+ next;
+ } elsif ($info =~ m/^\(alias configured by machine type\)/) {
+ # For now, such an alias always corresponds to the -v1 for q35 and i440fx (not for microvm)
+ $aliases->{$model} = "${model}-v1";
+ next;
+ } elsif ($info =~ m/^\(alias of (\S+)\)/) {
+ # alias will be resolved later
+ $aliases->{$model} = $1;
+ next;
+ } elsif ($info =~ m/^(Hygon|YongFeng|Zhaoxin)/) {
+ next; # skip
+ } elsif ($info =~ m/^AMD/) {
+ $cpu_models->{$model} = 'AuthenticAMD';
+ next;
+ } elsif ($info =~ m/^(Intel|Genuine Intel|Westmere)/) {
+ $cpu_models->{$model} = 'GenuineIntel';
+ next;
+ }
+
+ die "unable to deal with line '$line' - implement me";
+}
+
+# Backwards compat - resolve the alias and only expose the alias.
+for my $alias (keys $aliases->%*) {
+ my $target = $aliases->{$alias};
+ # an alias might refer to a model that was skipped
+ next if !exists($cpu_models->{$target});
+ $cpu_models->{$alias} = $cpu_models->{$target};
+ delete $cpu_models->{$target};
+}
+
+# Backwards compat - there never was such a client CPU, but it was exposed in the past - mapped to
+# the corresponding server CPU model in qemu-server.
+if ($cpu_models->{'Icelake-Server'}) {
+ $cpu_models->{'Icelake-Client'} = 'GenuineIntel';
+ $cpu_models->{'Icelake-Client-noTSX'} = 'GenuineIntel';
+}
+
+print to_json($cpu_models, { utf8 => 1, canonical => 1 })
+ or die "failed to encode detected CPU models as JSON - $!\n";
diff --git a/debian/rules b/debian/rules
index c407172..04e8f53 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,6 +14,9 @@ flagfile := $(destdir)/usr/share/kvm/recognized-CPUID-flags-x86_64
machine_file_x86_64 := $(destdir)/usr/share/kvm/machine-versions-x86_64.json
machine_file_aarch64 := $(destdir)/usr/share/kvm/machine-versions-aarch64.json
+cpu_models_file_x86_64 := $(destdir)/usr/share/kvm/cpu-models-x86_64.json
+cpu_models_file_aarch64 := $(destdir)/usr/share/kvm/cpu-models-aarch64.json
+
# default QEMU out-of-tree build directory is ./build
BUILDDIR=build
@@ -126,6 +129,15 @@ install: build
$(destdir)/usr/bin/qemu-system-x86_64 -machine help | ./debian/parse-machines.pl > $(machine_file_x86_64)
$(destdir)/usr/bin/qemu-system-aarch64 -machine help | ./debian/parse-machines.pl > $(machine_file_aarch64)
+ # Supported CPU models are static for a given QEMU binary.
+ $(destdir)/usr/bin/qemu-system-x86_64 -cpu help | ./debian/parse-cpu-models.pl > $(cpu_models_file_x86_64)
+ $(destdir)/usr/bin/qemu-system-aarch64 -cpu help | ./debian/parse-cpu-models.pl > $(cpu_models_file_aarch64)
+ # NOTE: If the diff fails here after upgrading the QEMU submodule, check which new models
+ # are to be picked up and which are to be excluded, adapt to other changes and commit the
+ # new expected files (and parse-cpu-models.pl script).
+ diff $(cpu_models_file_x86_64) ./debian/cpu-models-x86_64.json
+ diff $(cpu_models_file_aarch64) ./debian/cpu-models-aarch64.json
+
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
--
2.47.3
next prev parent reply other threads:[~2026-02-10 13:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-10 13:52 [PATCH-SERIES qemu/qemu-server 0/2] generate and ship static list of CPU models with pve-qemu-kvm Fiona Ebner
2026-02-10 13:52 ` Fiona Ebner [this message]
2026-02-11 10:33 ` [PATCH qemu 1/2] generate and ship static list of CPU models Thomas Lamprecht
2026-02-11 11:41 ` Fiona Ebner
2026-02-17 18:28 ` applied: " Thomas Lamprecht
2026-02-10 13:52 ` [PATCH qemu-server 2/2] cpu config: use static CPU model list shipped by QEMU package if available Fiona Ebner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260210135417.184127-2-f.ebner@proxmox.com \
--to=f.ebner@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox