* [PATCH qemu-server v3 0/3] improve multiarch build support
@ 2026-02-05 14:17 Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 1/3] tests: improve multiarch build support by introducing local get_host_arch helper Dominik Csapak
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Dominik Csapak @ 2026-02-05 14:17 UTC (permalink / raw)
To: pve-devel
For now I took the first approach i mentioned in the previous patches
discussion, hope that's ok. If not, just holler and I'll do it
differently.
changes from v2:
* split the first patch up in two
* use the get_host_arch helper everywhere in the package
* use a getter that auto-intiializes the global cpu model list
Dominik Csapak (3):
tests: improve multiarch build support by introducing local
get_host_arch helper
tests: improve multiarch build support by allowing re-init of cpu
models
tests: cfg2cmd: add some architecture tests
src/PVE/API2/Qemu/Machine.pm | 3 +-
src/PVE/QemuServer.pm | 5 +-
src/PVE/QemuServer/CPUConfig.pm | 282 ++++++++++--------
src/PVE/QemuServer/Helpers.pm | 8 +-
src/test/Makefile | 5 +-
src/test/cfg2cmd/aarch64/simple-arm-host.conf | 17 ++
.../cfg2cmd/aarch64/simple-arm-host.conf.cmd | 41 +++
src/test/cfg2cmd/aarch64/simple-arm.conf | 17 ++
src/test/cfg2cmd/aarch64/simple-arm.conf.cmd | 41 +++
src/test/run_config2command_tests.pl | 8 +-
10 files changed, 287 insertions(+), 140 deletions(-)
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm-host.conf
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm-host.conf.cmd
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm.conf
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm.conf.cmd
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH qemu-server v3 1/3] tests: improve multiarch build support by introducing local get_host_arch helper
2026-02-05 14:17 [PATCH qemu-server v3 0/3] improve multiarch build support Dominik Csapak
@ 2026-02-05 14:17 ` Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 2/3] tests: improve multiarch build support by allowing re-init of cpu models Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 3/3] tests: cfg2cmd: add some architecture tests Dominik Csapak
2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2026-02-05 14:17 UTC (permalink / raw)
To: pve-devel
Since mocking imported functions have to be done for each package that
imports them, we would have to mock get_host_arch for each package that
imports it from PVE::Tools. Instead, introduce one local helper here
that uses the function from PVE::Tools. This allows us to only need to
override it one time.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v2:
* split out from first patch
* use the helper everywhere in the package
src/PVE/API2/Qemu/Machine.pm | 3 ++-
src/PVE/QemuServer.pm | 5 ++---
src/PVE/QemuServer/CPUConfig.pm | 12 ++++++------
src/PVE/QemuServer/Helpers.pm | 8 +++++++-
src/test/run_config2command_tests.pl | 6 +++---
5 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/src/PVE/API2/Qemu/Machine.pm b/src/PVE/API2/Qemu/Machine.pm
index 26195eae..adc36d49 100644
--- a/src/PVE/API2/Qemu/Machine.pm
+++ b/src/PVE/API2/Qemu/Machine.pm
@@ -7,9 +7,10 @@ use JSON;
use PVE::JSONSchema qw(get_standard_option);
use PVE::RESTHandler;
-use PVE::Tools qw(extract_param file_get_contents get_host_arch);
+use PVE::Tools qw(extract_param file_get_contents);
use PVE::QemuServer::Machine;
+use PVE::QemuServer::Helpers qw(get_host_arch);
use base qw(PVE::RESTHandler);
diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 5d2dbe03..8bf23945 100644
--- a/src/PVE/QemuServer.pm
+++ b/src/PVE/QemuServer.pm
@@ -46,8 +46,7 @@ use PVE::SafeSyslog;
use PVE::Storage;
use PVE::SysFSTools;
use PVE::Systemd;
-use PVE::Tools
- qw(run_command file_read_firstline file_get_contents dir_glob_foreach get_host_arch $IPV6RE);
+use PVE::Tools qw(run_command file_read_firstline file_get_contents dir_glob_foreach $IPV6RE);
use PVE::QMPClient;
use PVE::QemuConfig;
@@ -58,7 +57,7 @@ use PVE::QemuServer::Blockdev;
use PVE::QemuServer::BlockJob;
use PVE::QemuServer::Cfg2Cmd;
use PVE::QemuServer::Helpers
- qw(config_aware_timeout get_iscsi_initiator_name min_version kvm_user_version windows_version);
+ qw(config_aware_timeout get_iscsi_initiator_name get_host_arch min_version kvm_user_version windows_version);
use PVE::QemuServer::Cloudinit;
use PVE::QemuServer::CGroup;
use PVE::QemuServer::CPUConfig qw(
diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm
index 32ec4954..0218908e 100644
--- a/src/PVE/QemuServer/CPUConfig.pm
+++ b/src/PVE/QemuServer/CPUConfig.pm
@@ -11,7 +11,7 @@ use PVE::ProcFSTools;
use PVE::RESTEnvironment qw(log_warn);
use PVE::Tools qw(run_command);
-use PVE::QemuServer::Helpers qw(min_version);
+use PVE::QemuServer::Helpers qw(min_version get_host_arch);
use base qw(PVE::SectionConfig Exporter);
@@ -25,7 +25,7 @@ our @EXPORT_OK = qw(
get_cvm_type
);
-my $host_arch = PVE::Tools::get_host_arch();
+my $host_arch = get_host_arch();
my $arch_desc = {
description => "Virtual processor architecture. Defaults to the host architecture.",
@@ -294,7 +294,7 @@ my $supported_cpu_flags_by_arch = {
sub get_supported_cpu_flags {
my ($arch) = @_;
- $arch = $host_arch if !defined($arch);
+ $arch = get_host_arch() if !defined($arch);
return $supported_cpu_flags_by_arch->{$arch};
}
@@ -582,7 +582,7 @@ sub add_cpu_json_properties {
sub get_cpu_models {
my ($include_custom, $arch) = @_;
- $arch = $host_arch if !defined($arch);
+ $arch = get_host_arch() if !defined($arch);
my $cpu_vendor_list = $cpu_models_by_arch->{$arch};
my $models = [];
@@ -1077,13 +1077,13 @@ sub get_default_cpu_type {
sub is_native_arch($) {
my ($arch) = @_;
- return $host_arch eq $arch;
+ return get_host_arch() eq $arch;
}
sub get_cpu_bitness {
my ($cpu_prop_str, $arch) = @_;
- $arch //= $host_arch;
+ $arch //= get_host_arch();
my $cputype = get_default_cpu_type($arch, 0);
diff --git a/src/PVE/QemuServer/Helpers.pm b/src/PVE/QemuServer/Helpers.pm
index 35c00754..e898440c 100644
--- a/src/PVE/QemuServer/Helpers.pm
+++ b/src/PVE/QemuServer/Helpers.pm
@@ -10,7 +10,7 @@ use JSON;
use PVE::Cluster;
use PVE::INotify;
use PVE::ProcFSTools;
-use PVE::Tools qw(get_host_arch);
+use PVE::Tools;
use base 'Exporter';
our @EXPORT_OK = qw(
@@ -20,6 +20,7 @@ our @EXPORT_OK = qw(
kvm_user_version
parse_number_sets
windows_version
+ get_host_arch
);
my $nodename = PVE::INotify::nodename();
@@ -29,6 +30,11 @@ my $arch_to_qemu_binary = {
x86_64 => '/usr/bin/qemu-system-x86_64',
};
+# wrapper around the Tools helper, having it here makes it easier for testing
+sub get_host_arch {
+ return PVE::Tools::get_host_arch();
+}
+
sub get_command_for_arch($) {
my ($arch) = @_;
return '/usr/bin/kvm' if get_host_arch() eq $arch; # i.e. native arch
diff --git a/src/test/run_config2command_tests.pl b/src/test/run_config2command_tests.pl
index 4c872d1c..c20f2377 100755
--- a/src/test/run_config2command_tests.pl
+++ b/src/test/run_config2command_tests.pl
@@ -253,9 +253,6 @@ $qemu_server_module->mock(
kernel_has_vhost_net => sub {
return 1; # TODO: make this per-test configurable?
},
- get_host_arch => sub() {
- return $current_test->{host_arch} // 'x86_64';
- },
get_iscsi_initiator_name => sub {
return 'iqn.1993-08.org.debian:01:aabbccddeeff';
},
@@ -388,6 +385,9 @@ $pve_common_tools->mock(
},
);
},
+ get_host_arch => sub() {
+ return $current_test->{host_arch} // 'x86_64';
+ },
);
my $pve_cpuconfig;
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH qemu-server v3 2/3] tests: improve multiarch build support by allowing re-init of cpu models
2026-02-05 14:17 [PATCH qemu-server v3 0/3] improve multiarch build support Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 1/3] tests: improve multiarch build support by introducing local get_host_arch helper Dominik Csapak
@ 2026-02-05 14:17 ` Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 3/3] tests: cfg2cmd: add some architecture tests Dominik Csapak
2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2026-02-05 14:17 UTC (permalink / raw)
To: pve-devel
instead of simply saving 'host_arch','all_cpu_models' and
'cpu_models_by_arch' in the global package namespace, after initializing
directly in the module, use an initialization function and a getter to
generate this.
This has two advantages:
* Only the first use actually fills the package wide variable
(currently the $cpu_fmt uses this on module load)
* We can call the initialization manually in the tests where we need it
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
changes from v2:
* split out from first patch
* use getters that auto-initialize the global cpu model list
src/PVE/QemuServer/CPUConfig.pm | 272 ++++++++++++++-------------
src/test/run_config2command_tests.pl | 2 +
2 files changed, 148 insertions(+), 126 deletions(-)
diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm
index 0218908e..165c48a7 100644
--- a/src/PVE/QemuServer/CPUConfig.pm
+++ b/src/PVE/QemuServer/CPUConfig.pm
@@ -25,8 +25,6 @@ our @EXPORT_OK = qw(
get_cvm_type
);
-my $host_arch = get_host_arch();
-
my $arch_desc = {
description => "Virtual processor architecture. Defaults to the host architecture.",
type => 'string',
@@ -100,130 +98,152 @@ my $cputypes_32bit = {
'qemu32' => 1,
};
-my $cpu_models_by_arch = {
- x86_64 => {
- # Intel CPUs
- 486 => 'GenuineIntel',
- pentium => 'GenuineIntel',
- pentium2 => 'GenuineIntel',
- pentium3 => 'GenuineIntel',
- coreduo => 'GenuineIntel',
- core2duo => 'GenuineIntel',
- Conroe => 'GenuineIntel',
- Penryn => 'GenuineIntel',
- Nehalem => 'GenuineIntel',
- 'Nehalem-IBRS' => 'GenuineIntel',
- Westmere => 'GenuineIntel',
- 'Westmere-IBRS' => 'GenuineIntel',
- SandyBridge => 'GenuineIntel',
- 'SandyBridge-IBRS' => 'GenuineIntel',
- IvyBridge => 'GenuineIntel',
- 'IvyBridge-IBRS' => 'GenuineIntel',
- Haswell => 'GenuineIntel',
- 'Haswell-IBRS' => 'GenuineIntel',
- 'Haswell-noTSX' => 'GenuineIntel',
- 'Haswell-noTSX-IBRS' => 'GenuineIntel',
- Broadwell => 'GenuineIntel',
- 'Broadwell-IBRS' => 'GenuineIntel',
- 'Broadwell-noTSX' => 'GenuineIntel',
- 'Broadwell-noTSX-IBRS' => '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',
- 'Cascadelake-Server' => 'GenuineIntel',
- 'Cascadelake-Server-v2' => 'GenuineIntel',
- 'Cascadelake-Server-noTSX' => 'GenuineIntel',
- 'Cascadelake-Server-v4' => 'GenuineIntel',
- 'Cascadelake-Server-v5' => 'GenuineIntel',
- 'Cooperlake' => 'GenuineIntel',
- 'Cooperlake-v2' => 'GenuineIntel',
- KnightsMill => 'GenuineIntel',
- 'Icelake-Client' => 'GenuineIntel', # depreacated, removed with QEMU 7.1
- 'Icelake-Client-noTSX' => 'GenuineIntel', # depreacated, removed with QEMU 7.1
- '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',
- 'SapphireRapids' => 'GenuineIntel',
- 'SapphireRapids-v2' => 'GenuineIntel',
- 'SapphireRapids-v3' => 'GenuineIntel',
- 'SapphireRapids-v4' => 'GenuineIntel',
- 'GraniteRapids' => 'GenuineIntel',
- 'GraniteRapids-v2' => 'GenuineIntel',
- 'GraniteRapids-v3' => 'GenuineIntel',
- 'SierraForest' => 'GenuineIntel',
- 'SierraForest-v2' => 'GenuineIntel',
- 'SierraForest-v3' => 'GenuineIntel',
- 'ClearwaterForest' => 'GenuineIntel',
-
- # AMD CPUs
- athlon => 'AuthenticAMD',
- phenom => 'AuthenticAMD',
- Opteron_G1 => 'AuthenticAMD',
- Opteron_G2 => 'AuthenticAMD',
- Opteron_G3 => 'AuthenticAMD',
- Opteron_G4 => 'AuthenticAMD',
- Opteron_G5 => 'AuthenticAMD',
- EPYC => 'AuthenticAMD',
- 'EPYC-IBPB' => 'AuthenticAMD',
- 'EPYC-v3' => 'AuthenticAMD',
- 'EPYC-v4' => 'AuthenticAMD',
- 'EPYC-v5' => 'AuthenticAMD',
- 'EPYC-Rome' => 'AuthenticAMD',
- 'EPYC-Rome-v2' => 'AuthenticAMD',
- 'EPYC-Rome-v3' => 'AuthenticAMD',
- 'EPYC-Rome-v4' => 'AuthenticAMD',
- 'EPYC-Rome-v5' => 'AuthenticAMD',
- 'EPYC-Milan' => 'AuthenticAMD',
- 'EPYC-Milan-v2' => 'AuthenticAMD',
- 'EPYC-Milan-v3' => 'AuthenticAMD',
- 'EPYC-Genoa' => 'AuthenticAMD',
- 'EPYC-Genoa-v2' => 'AuthenticAMD',
- 'EPYC-Turin' => 'AuthenticAMD',
-
- # generic types, use vendor from host node
- kvm32 => 'default',
- kvm64 => 'default',
- qemu32 => 'default',
- qemu64 => 'default',
- max => 'default',
- },
- aarch64 => {
- 'a64fx' => 'ARM',
- 'cortex-a35' => 'ARM',
- 'cortex-a53' => 'ARM',
- 'cortex-a55' => 'ARM',
- 'cortex-a57' => 'ARM',
- 'cortex-a710' => 'ARM',
- 'cortex-a72' => 'ARM',
- 'cortex-a76' => 'ARM',
- 'neoverse-n1' => 'ARM',
- 'neoverse-n2' => 'ARM',
- 'neoverse-v1' => 'ARM',
- # 32 bit and deprecated models were not added
- max => 'default',
- },
-};
+my $cpu_models_by_arch;
+my $all_cpu_models;
-# The host CPU model only exists if the arch matches
-$cpu_models_by_arch->{$host_arch}->{host} = 'default';
+# helper to make it easier for testing
+# initializes both '$cpu_models_by_arch' and '$all_cpu_models'
+sub initialize_cpu_models {
+ $cpu_models_by_arch = {
+ x86_64 => {
+ # Intel CPUs
+ 486 => 'GenuineIntel',
+ pentium => 'GenuineIntel',
+ pentium2 => 'GenuineIntel',
+ pentium3 => 'GenuineIntel',
+ coreduo => 'GenuineIntel',
+ core2duo => 'GenuineIntel',
+ Conroe => 'GenuineIntel',
+ Penryn => 'GenuineIntel',
+ Nehalem => 'GenuineIntel',
+ 'Nehalem-IBRS' => 'GenuineIntel',
+ Westmere => 'GenuineIntel',
+ 'Westmere-IBRS' => 'GenuineIntel',
+ SandyBridge => 'GenuineIntel',
+ 'SandyBridge-IBRS' => 'GenuineIntel',
+ IvyBridge => 'GenuineIntel',
+ 'IvyBridge-IBRS' => 'GenuineIntel',
+ Haswell => 'GenuineIntel',
+ 'Haswell-IBRS' => 'GenuineIntel',
+ 'Haswell-noTSX' => 'GenuineIntel',
+ 'Haswell-noTSX-IBRS' => 'GenuineIntel',
+ Broadwell => 'GenuineIntel',
+ 'Broadwell-IBRS' => 'GenuineIntel',
+ 'Broadwell-noTSX' => 'GenuineIntel',
+ 'Broadwell-noTSX-IBRS' => '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',
+ 'Cascadelake-Server' => 'GenuineIntel',
+ 'Cascadelake-Server-v2' => 'GenuineIntel',
+ 'Cascadelake-Server-noTSX' => 'GenuineIntel',
+ 'Cascadelake-Server-v4' => 'GenuineIntel',
+ 'Cascadelake-Server-v5' => 'GenuineIntel',
+ 'Cooperlake' => 'GenuineIntel',
+ 'Cooperlake-v2' => 'GenuineIntel',
+ KnightsMill => 'GenuineIntel',
+ 'Icelake-Client' => 'GenuineIntel', # depreacated, removed with QEMU 7.1
+ 'Icelake-Client-noTSX' => 'GenuineIntel', # depreacated, removed with QEMU 7.1
+ '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',
+ 'SapphireRapids' => 'GenuineIntel',
+ 'SapphireRapids-v2' => 'GenuineIntel',
+ 'SapphireRapids-v3' => 'GenuineIntel',
+ 'SapphireRapids-v4' => 'GenuineIntel',
+ 'GraniteRapids' => 'GenuineIntel',
+ 'GraniteRapids-v2' => 'GenuineIntel',
+ 'GraniteRapids-v3' => 'GenuineIntel',
+ 'SierraForest' => 'GenuineIntel',
+ 'SierraForest-v2' => 'GenuineIntel',
+ 'SierraForest-v3' => 'GenuineIntel',
+ 'ClearwaterForest' => 'GenuineIntel',
+
+ # AMD CPUs
+ athlon => 'AuthenticAMD',
+ phenom => 'AuthenticAMD',
+ Opteron_G1 => 'AuthenticAMD',
+ Opteron_G2 => 'AuthenticAMD',
+ Opteron_G3 => 'AuthenticAMD',
+ Opteron_G4 => 'AuthenticAMD',
+ Opteron_G5 => 'AuthenticAMD',
+ EPYC => 'AuthenticAMD',
+ 'EPYC-IBPB' => 'AuthenticAMD',
+ 'EPYC-v3' => 'AuthenticAMD',
+ 'EPYC-v4' => 'AuthenticAMD',
+ 'EPYC-v5' => 'AuthenticAMD',
+ 'EPYC-Rome' => 'AuthenticAMD',
+ 'EPYC-Rome-v2' => 'AuthenticAMD',
+ 'EPYC-Rome-v3' => 'AuthenticAMD',
+ 'EPYC-Rome-v4' => 'AuthenticAMD',
+ 'EPYC-Rome-v5' => 'AuthenticAMD',
+ 'EPYC-Milan' => 'AuthenticAMD',
+ 'EPYC-Milan-v2' => 'AuthenticAMD',
+ 'EPYC-Milan-v3' => 'AuthenticAMD',
+ 'EPYC-Genoa' => 'AuthenticAMD',
+ 'EPYC-Genoa-v2' => 'AuthenticAMD',
+ 'EPYC-Turin' => 'AuthenticAMD',
+
+ # generic types, use vendor from host node
+ kvm32 => 'default',
+ kvm64 => 'default',
+ qemu32 => 'default',
+ qemu64 => 'default',
+ max => 'default',
+ },
+ aarch64 => {
+ 'a64fx' => 'ARM',
+ 'cortex-a35' => 'ARM',
+ 'cortex-a53' => 'ARM',
+ 'cortex-a55' => 'ARM',
+ 'cortex-a57' => 'ARM',
+ 'cortex-a710' => 'ARM',
+ 'cortex-a72' => 'ARM',
+ 'cortex-a76' => 'ARM',
+ 'neoverse-n1' => 'ARM',
+ 'neoverse-n2' => 'ARM',
+ 'neoverse-v1' => 'ARM',
+ # 32 bit and deprecated models were not added
+ max => 'default',
+ },
+ };
-my $all_cpu_models;
-for my $arch (keys $cpu_models_by_arch->%*) {
- for my $model (keys $cpu_models_by_arch->{$arch}->%*) {
- $all_cpu_models->{$model} = $cpu_models_by_arch->{$arch}->{$model};
+ my $host_arch = get_host_arch();
+ # The host CPU model only exists if the arch matches
+ $cpu_models_by_arch->{$host_arch}->{host} = 'default';
+
+ for my $arch (keys $cpu_models_by_arch->%*) {
+ for my $model (keys $cpu_models_by_arch->{$arch}->%*) {
+ $all_cpu_models->{$model} = $cpu_models_by_arch->{$arch}->{$model};
+ }
}
}
+# returns the cpu models for the given architecture, or if $arch is not given, a
+# map from available architectures to models
+sub get_cpu_models_by_arch {
+ my ($arch) = @_;
+ initialize_cpu_models() if !defined($cpu_models_by_arch);
+ return $cpu_models_by_arch->{$arch} if defined($arch);
+ return $cpu_models_by_arch;
+}
+
+# returns a map of all availble cpu models regardless of architecture
+sub get_all_cpu_models {
+ initialize_cpu_models() if !defined($all_cpu_models);
+ return $all_cpu_models;
+}
+
my $supported_cpu_flags_by_arch = {
x86_64 => [
{
@@ -325,7 +345,7 @@ my $cpu_fmt = {
"CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model."
. " Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.",
type => 'string',
- enum => [sort { lc("$a") cmp lc("$b") } keys $all_cpu_models->%*],
+ enum => [sort { lc("$a") cmp lc("$b") } keys get_all_cpu_models()->%*],
default => 'kvm64',
optional => 1,
},
@@ -583,7 +603,7 @@ sub get_cpu_models {
my ($include_custom, $arch) = @_;
$arch = get_host_arch() if !defined($arch);
- my $cpu_vendor_list = $cpu_models_by_arch->{$arch};
+ my $cpu_vendor_list = get_cpu_models_by_arch($arch);
my $models = [];
@@ -614,7 +634,7 @@ sub get_cpu_models {
for my $custom_model (keys %{ $conf->{ids} }) {
my $reported_model = $conf->{ids}->{$custom_model}->{'reported-model'};
$reported_model //= $cpu_fmt->{'reported-model'}->{default};
- my $vendor = $all_cpu_models->{$reported_model};
+ my $vendor = get_all_cpu_models()->{$reported_model};
push @$models,
{
name => "custom-$custom_model",
@@ -870,7 +890,7 @@ sub get_cpu_options {
}
die "CPU model '$cputype' does not exist for configured vCPU architecture '$arch'\n"
- if !defined($cpu_models_by_arch->{$arch}->{$cputype});
+ if !defined(get_cpu_models_by_arch($arch)->{$cputype});
my $pve_flags = get_pve_cpu_flags($conf, $kvm, $cputype, $arch, $machine_version);
@@ -910,7 +930,7 @@ sub get_cpu_options {
if ($arch eq 'x86_64') {
# $cputype is the "reported-model" for custom types, so we can just look up
# the vendor in the default list
- my $cpu_vendor = $cpu_models_by_arch->{$arch}->{$cputype} or die "internal error";
+ my $cpu_vendor = get_cpu_models_by_arch($arch)->{$cputype} or die "internal error";
$pve_forced_flags->{'vendor'} = { value => $cpu_vendor } if $cpu_vendor ne 'default';
}
diff --git a/src/test/run_config2command_tests.pl b/src/test/run_config2command_tests.pl
index c20f2377..7ca2014e 100755
--- a/src/test/run_config2command_tests.pl
+++ b/src/test/run_config2command_tests.pl
@@ -235,6 +235,8 @@ sub parse_test($config_fn) {
$testname = "'$testname' - $desc";
}
$current_test->{testname} = $testname;
+
+ PVE::QemuServer::CPUConfig::initialize_cpu_models();
}
sub get_test_qemu_version {
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH qemu-server v3 3/3] tests: cfg2cmd: add some architecture tests
2026-02-05 14:17 [PATCH qemu-server v3 0/3] improve multiarch build support Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 1/3] tests: improve multiarch build support by introducing local get_host_arch helper Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 2/3] tests: improve multiarch build support by allowing re-init of cpu models Dominik Csapak
@ 2026-02-05 14:17 ` Dominik Csapak
2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2026-02-05 14:17 UTC (permalink / raw)
To: pve-devel
one for manually setting
arch: aarch64
in the config for an 'x86_64' host architecture, and one where
we don't have 'arch' set in the config on an aarch64 host.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
no changes from v2
src/test/Makefile | 5 ++-
src/test/cfg2cmd/aarch64/simple-arm-host.conf | 17 ++++++++
.../cfg2cmd/aarch64/simple-arm-host.conf.cmd | 41 +++++++++++++++++++
src/test/cfg2cmd/aarch64/simple-arm.conf | 17 ++++++++
src/test/cfg2cmd/aarch64/simple-arm.conf.cmd | 41 +++++++++++++++++++
5 files changed, 120 insertions(+), 1 deletion(-)
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm-host.conf
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm-host.conf.cmd
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm.conf
create mode 100644 src/test/cfg2cmd/aarch64/simple-arm.conf.cmd
diff --git a/src/test/Makefile b/src/test/Makefile
index 2ef9073a..cf589f41 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,6 +1,6 @@
all: test
-test: test_snapshot test_cfg_to_cmd test_pci_addr_conflicts test_pci_reservation test_qemu_img_convert test_migration test_restore_config test_parse_config
+test: test_snapshot test_cfg_to_cmd test_cfg_to_cmd_aarch64 test_pci_addr_conflicts test_pci_reservation test_qemu_img_convert test_migration test_restore_config test_parse_config
test_snapshot: run_snapshot_tests.pl
./run_snapshot_tests.pl
@@ -9,6 +9,9 @@ test_snapshot: run_snapshot_tests.pl
test_cfg_to_cmd: run_config2command_tests.pl cfg2cmd/*.conf
perl -I../ ./run_config2command_tests.pl
+test_cfg_to_cmd_aarch64: run_config2command_tests.pl cfg2cmd/aarch64/*.conf
+ perl -I../ ./run_config2command_tests.pl cfg2cmd/aarch64
+
test_qemu_img_convert: run_qemu_img_convert_tests.pl
perl -I../ ./run_qemu_img_convert_tests.pl
diff --git a/src/test/cfg2cmd/aarch64/simple-arm-host.conf b/src/test/cfg2cmd/aarch64/simple-arm-host.conf
new file mode 100644
index 00000000..1488dbf5
--- /dev/null
+++ b/src/test/cfg2cmd/aarch64/simple-arm-host.conf
@@ -0,0 +1,17 @@
+# TEST: Simple test for a basic configuration with aarch64 set as the host architecture
+# HOST_ARCH: aarch64
+bootdisk: scsi0
+bios: ovmf
+cores: 3
+ide2: none,media=cdrom
+memory: 768
+name: simple
+net0: virtio=A2:C0:43:77:08:A0,bridge=vmbr0
+numa: 0
+ostype: l26
+scsi0: local:8006/vm-8006-disk-0.qcow2,discard=on,size=104858K
+scsihw: virtio-scsi-pci
+smbios1: uuid=7b10d7af-b932-4c66-b2c3-3996152ec465
+sockets: 1
+vmgenid: c773c261-d800-4348-9f5d-167fadd53cf8
+efidisk0: local:8006/vm-8006-disk-1.qcow2,efitype=4m
diff --git a/src/test/cfg2cmd/aarch64/simple-arm-host.conf.cmd b/src/test/cfg2cmd/aarch64/simple-arm-host.conf.cmd
new file mode 100644
index 00000000..bf7443ab
--- /dev/null
+++ b/src/test/cfg2cmd/aarch64/simple-arm-host.conf.cmd
@@ -0,0 +1,41 @@
+/usr/bin/kvm \
+ -id 8006 \
+ -name 'simple,debug-threads=on' \
+ -no-shutdown \
+ -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+ -mon 'chardev=qmp,mode=control' \
+ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
+ -mon 'chardev=qmp-event,mode=control' \
+ -pidfile /var/run/qemu-server/8006.pid \
+ -daemonize \
+ -smbios 'type=1,uuid=7b10d7af-b932-4c66-b2c3-3996152ec465' \
+ -object '{"id":"throttle-drive-efidisk0","limits":{},"qom-type":"throttle-group"}' \
+ -blockdev '{"driver":"raw","file":{"driver":"file","filename":"/usr/share/pve-edk2-firmware//AAVMF_CODE.fd"},"node-name":"pflash0","read-only":true}' \
+ -blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":false,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-1.qcow2","node-name":"e4abf08bba72d3a54b87a58d2f50906","read-only":false},"node-name":"f4abf08bba72d3a54b87a58d2f50906","read-only":false},"node-name":"drive-efidisk0","read-only":false,"throttle-group":"throttle-drive-efidisk0"}' \
+ -smp '3,sockets=1,cores=3,maxcpus=3' \
+ -nodefaults \
+ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+ -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+ -cpu cortex-a57 \
+ -m 768 \
+ -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pcie.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pcie.0,addr=0x1f' \
+ -device 'vmgenid,guid=c773c261-d800-4348-9f5d-167fadd53cf8' \
+ -device 'usb-ehci,id=ehci,bus=pcie.0,addr=0x1' \
+ -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \
+ -device 'usb-kbd,id=keyboard,bus=ehci.0,port=2' \
+ -device 'virtio-gpu,id=vga,bus=pcie.0,addr=0x2' \
+ -device 'virtio-serial,id=spice,bus=pcie.0,addr=0x9' \
+ -chardev 'spicevmc,id=vdagent,name=vdagent' \
+ -device 'virtserialport,chardev=vdagent,name=com.redhat.spice.0' \
+ -spice 'tls-port=61000,addr=127.0.0.1,tls-ciphers=HIGH,seamless-migration=on' \
+ -device 'virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x3,free-page-reporting=on' \
+ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+ -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
+ -device 'virtio-scsi-pci,id=scsihw0,bus=pcie.0,addr=0x5' \
+ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"ecd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"fcd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \
+ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \
+ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \
+ -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pcie.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \
+ -machine 'pflash0=pflash0,pflash1=drive-efidisk0,type=virt+pve0'
diff --git a/src/test/cfg2cmd/aarch64/simple-arm.conf b/src/test/cfg2cmd/aarch64/simple-arm.conf
new file mode 100644
index 00000000..6b5f3dd0
--- /dev/null
+++ b/src/test/cfg2cmd/aarch64/simple-arm.conf
@@ -0,0 +1,17 @@
+# TEST: Simple test for a basic configuration with aarch64 set as architecture
+arch: aarch64
+bootdisk: scsi0
+bios: ovmf
+cores: 3
+ide2: none,media=cdrom
+memory: 768
+name: simple
+net0: virtio=A2:C0:43:77:08:A0,bridge=vmbr0
+numa: 0
+ostype: l26
+scsi0: local:8006/vm-8006-disk-0.qcow2,discard=on,size=104858K
+scsihw: virtio-scsi-pci
+smbios1: uuid=7b10d7af-b932-4c66-b2c3-3996152ec465
+sockets: 1
+vmgenid: c773c261-d800-4348-9f5d-167fadd53cf8
+efidisk0: local:8006/vm-8006-disk-0.qcow2,efitype=4m
diff --git a/src/test/cfg2cmd/aarch64/simple-arm.conf.cmd b/src/test/cfg2cmd/aarch64/simple-arm.conf.cmd
new file mode 100644
index 00000000..5b32e91c
--- /dev/null
+++ b/src/test/cfg2cmd/aarch64/simple-arm.conf.cmd
@@ -0,0 +1,41 @@
+/usr/bin/qemu-system-aarch64 \
+ -id 8006 \
+ -name 'simple,debug-threads=on' \
+ -no-shutdown \
+ -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \
+ -mon 'chardev=qmp,mode=control' \
+ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
+ -mon 'chardev=qmp-event,mode=control' \
+ -pidfile /var/run/qemu-server/8006.pid \
+ -daemonize \
+ -smbios 'type=1,uuid=7b10d7af-b932-4c66-b2c3-3996152ec465' \
+ -object '{"id":"throttle-drive-efidisk0","limits":{},"qom-type":"throttle-group"}' \
+ -blockdev '{"driver":"raw","file":{"driver":"file","filename":"/usr/share/pve-edk2-firmware//AAVMF_CODE.fd"},"node-name":"pflash0","read-only":true}' \
+ -blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":false,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":false,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"ea05d68a0ec0fe4a8d93dde338f7405","read-only":false},"node-name":"fa05d68a0ec0fe4a8d93dde338f7405","read-only":false},"node-name":"drive-efidisk0","read-only":false,"throttle-group":"throttle-drive-efidisk0"}' \
+ -smp '3,sockets=1,cores=3,maxcpus=3' \
+ -nodefaults \
+ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
+ -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \
+ -cpu cortex-a57 \
+ -m 768 \
+ -object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
+ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pcie.0,addr=0x1e' \
+ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pcie.0,addr=0x1f' \
+ -device 'vmgenid,guid=c773c261-d800-4348-9f5d-167fadd53cf8' \
+ -device 'usb-ehci,id=ehci,bus=pcie.0,addr=0x1' \
+ -device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \
+ -device 'usb-kbd,id=keyboard,bus=ehci.0,port=2' \
+ -device 'virtio-gpu,id=vga,bus=pcie.0,addr=0x2' \
+ -device 'virtio-serial,id=spice,bus=pcie.0,addr=0x9' \
+ -chardev 'spicevmc,id=vdagent,name=vdagent' \
+ -device 'virtserialport,chardev=vdagent,name=com.redhat.spice.0' \
+ -spice 'tls-port=61000,addr=127.0.0.1,tls-ciphers=HIGH,seamless-migration=on' \
+ -device 'virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x3,free-page-reporting=on' \
+ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \
+ -device 'ide-cd,bus=ide.1,unit=0,id=ide2,bootindex=200' \
+ -device 'virtio-scsi-pci,id=scsihw0,bus=pcie.0,addr=0x5' \
+ -blockdev '{"detect-zeroes":"unmap","discard":"unmap","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"unmap","discard":"unmap","driver":"file","filename":"/var/lib/vz/images/8006/vm-8006-disk-0.qcow2","node-name":"ecd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"fcd04be4259153b8293415fefa2a84c","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \
+ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \
+ -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown' \
+ -device 'virtio-net-pci,mac=A2:C0:43:77:08:A0,netdev=net0,bus=pcie.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500' \
+ -machine 'pflash0=pflash0,pflash1=drive-efidisk0,accel=tcg,type=virt+pve0'
--
2.47.3
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-05 14:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-05 14:17 [PATCH qemu-server v3 0/3] improve multiarch build support Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 1/3] tests: improve multiarch build support by introducing local get_host_arch helper Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 2/3] tests: improve multiarch build support by allowing re-init of cpu models Dominik Csapak
2026-02-05 14:17 ` [PATCH qemu-server v3 3/3] tests: cfg2cmd: add some architecture tests Dominik Csapak
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.