From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 3E0D11FF139 for ; Tue, 10 Feb 2026 14:54:27 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 04A312D26; Tue, 10 Feb 2026 14:54:58 +0100 (CET) From: Fiona Ebner 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 Message-ID: <20260210135417.184127-2-f.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260210135417.184127-1-f.ebner@proxmox.com> References: <20260210135417.184127-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1770731576578 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.016 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: CB3R653LYLMXIIDQD2PXWIYNUEJP76BT X-Message-ID-Hash: CB3R653LYLMXIIDQD2PXWIYNUEJP76BT X-MailFrom: f.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: 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 Signed-off-by: Fiona Ebner --- 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","c= ortex-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":"Genuine= Intel","Broadwell-noTSX":"GenuineIntel","Broadwell-noTSX-IBRS":"GenuineInte= l","Cascadelake-Server":"GenuineIntel","Cascadelake-Server-noTSX":"GenuineI= ntel","Cascadelake-Server-v2":"GenuineIntel","Cascadelake-Server-v4":"Genui= neIntel","Cascadelake-Server-v5":"GenuineIntel","ClearwaterForest":"Genuine= Intel","Conroe":"GenuineIntel","Cooperlake":"GenuineIntel","Cooperlake-v2":= "GenuineIntel","EPYC":"AuthenticAMD","EPYC-Genoa":"AuthenticAMD","EPYC-Geno= a-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":"A= uthenticAMD","EPYC-v3":"AuthenticAMD","EPYC-v4":"AuthenticAMD","EPYC-v5":"A= uthenticAMD","GraniteRapids":"GenuineIntel","GraniteRapids-v2":"GenuineInte= l","GraniteRapids-v3":"GenuineIntel","Haswell":"GenuineIntel","Haswell-IBRS= ":"GenuineIntel","Haswell-noTSX":"GenuineIntel","Haswell-noTSX-IBRS":"Genui= neIntel","Icelake-Client":"GenuineIntel","Icelake-Client-noTSX":"GenuineInt= el","Icelake-Server":"GenuineIntel","Icelake-Server-noTSX":"GenuineIntel","= Icelake-Server-v3":"GenuineIntel","Icelake-Server-v4":"GenuineIntel","Icela= ke-Server-v5":"GenuineIntel","Icelake-Server-v6":"GenuineIntel","Icelake-Se= rver-v7":"GenuineIntel","IvyBridge":"GenuineIntel","IvyBridge-IBRS":"Genuin= eIntel","KnightsMill":"GenuineIntel","Nehalem":"GenuineIntel","Nehalem-IBRS= ":"GenuineIntel","Opteron_G1":"AuthenticAMD","Opteron_G2":"AuthenticAMD","O= pteron_G3":"AuthenticAMD","Opteron_G4":"AuthenticAMD","Opteron_G5":"Authent= icAMD","Penryn":"GenuineIntel","SandyBridge":"GenuineIntel","SandyBridge-IB= RS":"GenuineIntel","SapphireRapids":"GenuineIntel","SapphireRapids-v2":"Gen= uineIntel","SapphireRapids-v3":"GenuineIntel","SapphireRapids-v4":"GenuineI= ntel","SierraForest":"GenuineIntel","SierraForest-v2":"GenuineIntel","Sierr= aForest-v3":"GenuineIntel","Skylake-Client":"GenuineIntel","Skylake-Client-= IBRS":"GenuineIntel","Skylake-Client-noTSX-IBRS":"GenuineIntel","Skylake-Cl= ient-v4":"GenuineIntel","Skylake-Server":"GenuineIntel","Skylake-Server-IBR= S":"GenuineIntel","Skylake-Server-noTSX-IBRS":"GenuineIntel","Skylake-Serve= r-v4":"GenuineIntel","Skylake-Server-v5":"GenuineIntel","Westmere":"Genuine= Intel","Westmere-IBRS":"GenuineIntel","athlon":"AuthenticAMD","core2duo":"G= enuineIntel","coreduo":"GenuineIntel","kvm32":"default","kvm64":"default","= max":"default","pentium":"GenuineIntel","pentium2":"GenuineIntel","pentium3= ":"GenuineIntel","phenom":"AuthenticAMD","qemu32":"default","qemu64":"defau= lt"} \ 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 w= as created during build +# of pve-qemu. Continue to do so. + +my @skip_models =3D ( + '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 =3D qr/(@{[join('|', @skip_models)]})/; + +my $cpu_models =3D {}; +my $aliases =3D {}; + +while (my $line =3D ) { + last if $line =3D~ /^\s*Recognized CPUID flags:/; + next if $line =3D~ /^\s*Available CPUs:/; + next if $line =3D~ /^$/; + + $line =3D~ s/^\s+//; + $line =3D~ s/\s+$//; + + my ($model, $info) =3D ($line =3D~ m/^(\S+)\s*(.*)$/) or die "unexpect= ed line '$line'\n"; + + if ($model eq 'athlon-v1') { + # has unusual info: QEMU Virtual CPU version 2.5+ + $cpu_models->{$model} =3D 'AuthenticAMD'; + next; + } elsif ($model =3D~ m/^((kvm|qemu)(32|64)-v1|max)$/) { + $cpu_models->{$model} =3D 'default'; + next; + } elsif ($model =3D~ m/^$skip_models_re(-v\d)?$/) { + next; # skip + } + + if (!$info) { + if ($model =3D~ m/^(486|pentium(2|3)?)-v1$/) { + $cpu_models->{$model} =3D 'GenuineIntel'; + next; + } elsif ($model =3D~ m/^(a64fx|cortex-|neoverse-).*$/) { + $cpu_models->{$model} =3D 'ARM'; + next; + } + die "unable to deal with line '$line' - implement me" + } elsif ($info =3D~ m/^\(deprecated\)$/) { + next; + } elsif ($info =3D~ 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} =3D "${model}-v1"; + next; + } elsif ($info =3D~ m/^\(alias of (\S+)\)/) { + # alias will be resolved later + $aliases->{$model} =3D $1; + next; + } elsif ($info =3D~ m/^(Hygon|YongFeng|Zhaoxin)/) { + next; # skip + } elsif ($info =3D~ m/^AMD/) { + $cpu_models->{$model} =3D 'AuthenticAMD'; + next; + } elsif ($info =3D~ m/^(Intel|Genuine Intel|Westmere)/) { + $cpu_models->{$model} =3D '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 =3D $aliases->{$alias}; + # an alias might refer to a model that was skipped + next if !exists($cpu_models->{$target}); + $cpu_models->{$alias} =3D $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'} =3D 'GenuineIntel'; + $cpu_models->{'Icelake-Client-noTSX'} =3D 'GenuineIntel'; +} + +print to_json($cpu_models, { utf8 =3D> 1, canonical =3D> 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 :=3D $(destdir)/usr/share/kvm/recognized-CPUID-f= lags-x86_64 machine_file_x86_64 :=3D $(destdir)/usr/share/kvm/machine-versions-x86_64.= json machine_file_aarch64 :=3D $(destdir)/usr/share/kvm/machine-versions-aarch6= 4.json =20 +cpu_models_file_x86_64 :=3D $(destdir)/usr/share/kvm/cpu-models-x86_64.json +cpu_models_file_aarch64 :=3D $(destdir)/usr/share/kvm/cpu-models-aarch64.j= son + # default QEMU out-of-tree build directory is ./build BUILDDIR=3Dbuild =20 @@ -126,6 +129,15 @@ install: build $(destdir)/usr/bin/qemu-system-x86_64 -machine help | ./debian/parse-mach= ines.pl > $(machine_file_x86_64) $(destdir)/usr/bin/qemu-system-aarch64 -machine help | ./debian/parse-mac= hines.pl > $(machine_file_aarch64) =20 + # Supported CPU models are static for a given QEMU binary. + $(destdir)/usr/bin/qemu-system-x86_64 -cpu help | ./debian/parse-cpu-mode= ls.pl > $(cpu_models_file_x86_64) + $(destdir)/usr/bin/qemu-system-aarch64 -cpu help | ./debian/parse-cpu-mod= els.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 change= s 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. --=20 2.47.3