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 <[email protected]>
Signed-off-by: Fiona Ebner <[email protected]>
---
 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




Reply via email to