public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: Dominik Csapak <d.csapak@proxmox.com>, pve-devel@lists.proxmox.com
Subject: Re: [PATCH qemu-server v2 1/2] tests: improve multiarch build support
Date: Wed, 4 Feb 2026 16:46:52 +0100	[thread overview]
Message-ID: <88e10fbe-3231-40da-8ea2-d95fc1576715@proxmox.com> (raw)
In-Reply-To: <20260204100425.1303295-1-d.csapak@proxmox.com>

Am 04.02.26 um 11:04 schrieb Dominik Csapak:
> instead of simply saving 'host_arch' in the global package namespace,
> use the PVE::Tools::get_host_arch helper, which caches the result
> anyway.
> 
> For easier testing:
> * introduce our own helper for getting the host arch, which uses
>   the PVE::Tools one. So we only have to mock the Tools one to get
>   correct behavior in the tests. Use this everywhere here where we need
>   it.
> * move the cpu_models_by_arch initialization into a sub that can be
>   called by the tests to re-initialize.
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> changes from v1:
> * add helpers to be more easily used and mocked by the tests instead
>   of modifying the module level variable
> 
>  src/PVE/QemuServer.pm                |   5 +-
>  src/PVE/QemuServer/CPUConfig.pm      | 258 ++++++++++++++-------------
>  src/PVE/QemuServer/Helpers.pm        |   8 +-
>  src/test/run_config2command_tests.pl |   8 +-
>  4 files changed, 146 insertions(+), 133 deletions(-)
> 
> 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..7d5559b0 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,8 +25,6 @@ our @EXPORT_OK = qw(
>      get_cvm_type
>  );
>  
> -my $host_arch = PVE::Tools::get_host_arch();
> -
>  my $arch_desc = {
>      description => "Virtual processor architecture. Defaults to the host architecture.",
>      type => 'string',
> @@ -100,130 +98,138 @@ 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
> +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};
> +        }
>      }
>  }
>  
> +initialize_cpu_models();

this now still always does this on module load, would be nicer to actually
only pay for that if needed by adding getter methods for each variable, like

sub get_all_cpu_models {
   initialize_cpu_models() if !defined($all_cpu_models);
   return $all_cpu_models;
}

Same with a get_cpu_models_by_arch getter.

And I'd split this and the host_arch change into separate patches, they are rather
unrelated to each other.




      parent reply	other threads:[~2026-02-04 15:46 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04 10:01 Dominik Csapak
2026-02-04 10:01 ` [PATCH qemu-server v2 2/2] tests: cfg2cmd: add some architecture tests Dominik Csapak
2026-02-04 15:46 ` Thomas Lamprecht [this message]

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=88e10fbe-3231-40da-8ea2-d95fc1576715@proxmox.com \
    --to=t.lamprecht@proxmox.com \
    --cc=d.csapak@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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal