all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH qemu-server] cpu config: Move CPU flags utils to CPUConfig module
Date: Tue, 17 Feb 2026 11:50:49 +0100	[thread overview]
Message-ID: <20260217105050.194368-1-a.bied-charreton@proxmox.com> (raw)

...where they fit better alongside other CPU-related utilities.

Signed-off-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
---
 src/PVE/QemuServer.pm           | 131 +-------------------------------
 src/PVE/QemuServer/CPUConfig.pm | 131 +++++++++++++++++++++++++++++++-
 2 files changed, 131 insertions(+), 131 deletions(-)

diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 5d2dbe03..2121f7c8 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;
@@ -2911,134 +2910,6 @@ sub vga_conf_has_spice {
     return $1 || 1;
 }
 
-# To use query_supported_cpu_flags and query_understood_cpu_flags to get flags
-# to use in a QEMU command line (-cpu element), first array_intersect the result
-# of query_supported_ with query_understood_. This is necessary because:
-#
-# a) query_understood_ returns flags the host cannot use and
-# b) query_supported_ (rather the QMP call) doesn't actually return CPU
-#    flags, but CPU settings - with most of them being flags. Those settings
-#    (and some flags, curiously) cannot be specified as a "-cpu" argument.
-#
-# query_supported_ needs to start up to 2 temporary VMs and is therefore rather
-# expensive. If you need the value returned from this, you can get it much
-# cheaper from pmxcfs using PVE::Cluster::get_node_kv('cpuflags-$accel') with
-# $accel being 'kvm' or 'tcg'.
-#
-# pvestatd calls this function on startup and whenever the QEMU/KVM version
-# changes, automatically populating pmxcfs.
-#
-# Returns: { kvm => [ flagX, flagY, ... ], tcg => [ flag1, flag2, ... ] }
-# since kvm and tcg machines support different flags
-#
-sub query_supported_cpu_flags {
-    my ($arch) = @_;
-
-    $arch //= get_host_arch();
-    my $default_machine = PVE::QemuServer::Machine::default_machine_for_arch($arch);
-
-    my $flags = {};
-
-    # FIXME: Once this is merged, the code below should work for ARM as well:
-    # https://lists.nongnu.org/archive/html/qemu-devel/2019-06/msg04947.html
-    die "QEMU/KVM cannot detect CPU flags on ARM (aarch64)\n"
-        if $arch eq "aarch64";
-
-    my $kvm_supported = defined(kvm_version());
-    my $qemu_cmd = PVE::QemuServer::Helpers::get_command_for_arch($arch);
-    my $fakevmid = -1;
-    my $pidfile = PVE::QemuServer::Helpers::vm_pidfile_name($fakevmid);
-
-    # Start a temporary (frozen) VM with vmid -1 to allow sending a QMP command
-    my $query_supported_run_qemu = sub {
-        my ($kvm) = @_;
-
-        my $flags = {};
-        my $cmd = [
-            $qemu_cmd,
-            '-machine',
-            $default_machine,
-            '-display',
-            'none',
-            '-chardev',
-            "socket,id=qmp,path=/var/run/qemu-server/$fakevmid.qmp,server=on,wait=off",
-            '-mon',
-            'chardev=qmp,mode=control',
-            '-pidfile',
-            $pidfile,
-            '-S',
-            '-daemonize',
-        ];
-
-        if (!$kvm) {
-            push @$cmd, '-accel', 'tcg';
-        }
-
-        my $rc = run_command($cmd, noerr => 1, quiet => 0);
-        die "QEMU flag querying VM exited with code " . $rc if $rc;
-
-        eval {
-            my $cmd_result = mon_cmd(
-                $fakevmid,
-                'query-cpu-model-expansion',
-                type => 'full',
-                model => { name => 'host' },
-            );
-
-            my $props = $cmd_result->{model}->{props};
-            foreach my $prop (keys %$props) {
-                next if $props->{$prop} ne '1';
-                # QEMU returns some flags multiple times, with '_', '.' or '-'
-                # (e.g. lahf_lm and lahf-lm; sse4.2, sse4-2 and sse4_2; ...).
-                # We only keep those with underscores, to match /proc/cpuinfo
-                $prop =~ s/\.|-/_/g;
-                $flags->{$prop} = 1;
-            }
-        };
-        my $err = $@;
-
-        # force stop with 10 sec timeout and 'nocheck', always stop, even if QMP failed
-        vm_stop(undef, $fakevmid, 1, 1, 10, 0, 1);
-
-        die $err if $err;
-
-        return [sort keys %$flags];
-    };
-
-    # We need to query QEMU twice, since KVM and TCG have different supported flags
-    PVE::QemuConfig->lock_config(
-        $fakevmid,
-        sub {
-            $flags->{tcg} = eval { $query_supported_run_qemu->(0) };
-            warn "warning: failed querying supported tcg flags: $@\n" if $@;
-
-            if ($kvm_supported) {
-                $flags->{kvm} = eval { $query_supported_run_qemu->(1) };
-                warn "warning: failed querying supported kvm flags: $@\n" if $@;
-            }
-        },
-    );
-
-    return $flags;
-}
-
-# Understood CPU flags are written to a file at 'pve-qemu' compile time
-my $understood_cpu_flag_dir = "/usr/share/kvm";
-
-sub query_understood_cpu_flags {
-    my $arch = get_host_arch();
-    my $filepath = "$understood_cpu_flag_dir/recognized-CPUID-flags-$arch";
-
-    die "Cannot query understood QEMU CPU flags for architecture: $arch (file not found)\n"
-        if !-e $filepath;
-
-    my $raw = file_get_contents($filepath);
-    $raw =~ s/^\s+|\s+$//g;
-    my @flags = split(/\s+/, $raw);
-
-    return \@flags;
-}
-
 # Since commit 277d33454f77ec1d1e0bc04e37621e4dd2424b67 in pve-qemu, smm is not off by default
 # anymore. But smm=off seems to be required when using SeaBIOS and serial display.
 my sub should_disable_smm {
diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm
index 32ec4954..e53f0978 100644
--- a/src/PVE/QemuServer/CPUConfig.pm
+++ b/src/PVE/QemuServer/CPUConfig.pm
@@ -9,7 +9,8 @@ use PVE::JSONSchema qw(json_bool);
 use PVE::Cluster qw(cfs_register_file cfs_read_file);
 use PVE::ProcFSTools;
 use PVE::RESTEnvironment qw(log_warn);
-use PVE::Tools qw(run_command);
+use PVE::Tools qw(run_command get_host_arch);
+use PVE::QemuServer::Monitor qw(mon_cmd);
 
 use PVE::QemuServer::Helpers qw(min_version);
 
@@ -579,6 +580,134 @@ sub add_cpu_json_properties {
     return $prop;
 }
 
+# To use query_supported_cpu_flags and query_understood_cpu_flags to get flags
+# to use in a QEMU command line (-cpu element), first array_intersect the result
+# of query_supported_ with query_understood_. This is necessary because:
+#
+# a) query_understood_ returns flags the host cannot use and
+# b) query_supported_ (rather the QMP call) doesn't actually return CPU
+#    flags, but CPU settings - with most of them being flags. Those settings
+#    (and some flags, curiously) cannot be specified as a "-cpu" argument.
+#
+# query_supported_ needs to start up to 2 temporary VMs and is therefore rather
+# expensive. If you need the value returned from this, you can get it much
+# cheaper from pmxcfs using PVE::Cluster::get_node_kv('cpuflags-$accel') with
+# $accel being 'kvm' or 'tcg'.
+#
+# pvestatd calls this function on startup and whenever the QEMU/KVM version
+# changes, automatically populating pmxcfs.
+#
+# Returns: { kvm => [ flagX, flagY, ... ], tcg => [ flag1, flag2, ... ] }
+# since kvm and tcg machines support different flags
+#
+sub query_supported_cpu_flags {
+    my ($arch) = @_;
+
+    $arch //= get_host_arch();
+    my $default_machine = PVE::QemuServer::Machine::default_machine_for_arch($arch);
+
+    my $flags = {};
+
+    # FIXME: Once this is merged, the code below should work for ARM as well:
+    # https://lists.nongnu.org/archive/html/qemu-devel/2019-06/msg04947.html
+    die "QEMU/KVM cannot detect CPU flags on ARM (aarch64)\n"
+        if $arch eq "aarch64";
+
+    my $kvm_supported = defined(PVE::QemuServer::kvm_version());
+    my $qemu_cmd = PVE::QemuServer::Helpers::get_command_for_arch($arch);
+    my $fakevmid = -1;
+    my $pidfile = PVE::QemuServer::Helpers::vm_pidfile_name($fakevmid);
+
+    # Start a temporary (frozen) VM with vmid -1 to allow sending a QMP command
+    my $query_supported_run_qemu = sub {
+        my ($kvm) = @_;
+
+        my $flags = {};
+        my $cmd = [
+            $qemu_cmd,
+            '-machine',
+            $default_machine,
+            '-display',
+            'none',
+            '-chardev',
+            "socket,id=qmp,path=/var/run/qemu-server/$fakevmid.qmp,server=on,wait=off",
+            '-mon',
+            'chardev=qmp,mode=control',
+            '-pidfile',
+            $pidfile,
+            '-S',
+            '-daemonize',
+        ];
+
+        if (!$kvm) {
+            push @$cmd, '-accel', 'tcg';
+        }
+
+        my $rc = run_command($cmd, noerr => 1, quiet => 0);
+        die "QEMU flag querying VM exited with code " . $rc if $rc;
+
+        eval {
+            my $cmd_result = mon_cmd(
+                $fakevmid,
+                'query-cpu-model-expansion',
+                type => 'full',
+                model => { name => 'host' },
+            );
+
+            my $props = $cmd_result->{model}->{props};
+            foreach my $prop (keys %$props) {
+                next if $props->{$prop} ne '1';
+                # QEMU returns some flags multiple times, with '_', '.' or '-'
+                # (e.g. lahf_lm and lahf-lm; sse4.2, sse4-2 and sse4_2; ...).
+                # We only keep those with underscores, to match /proc/cpuinfo
+                $prop =~ s/\.|-/_/g;
+                $flags->{$prop} = 1;
+            }
+        };
+        my $err = $@;
+
+        # force stop with 10 sec timeout and 'nocheck', always stop, even if QMP failed
+        PVE::QemuServer::vm_stop(undef, $fakevmid, 1, 1, 10, 0, 1);
+
+        die $err if $err;
+
+        return [sort keys %$flags];
+    };
+
+    # We need to query QEMU twice, since KVM and TCG have different supported flags
+    PVE::QemuConfig->lock_config(
+        $fakevmid,
+        sub {
+            $flags->{tcg} = eval { $query_supported_run_qemu->(0) };
+            warn "warning: failed querying supported tcg flags: $@\n" if $@;
+
+            if ($kvm_supported) {
+                $flags->{kvm} = eval { $query_supported_run_qemu->(1) };
+                warn "warning: failed querying supported kvm flags: $@\n" if $@;
+            }
+        },
+    );
+
+    return $flags;
+}
+
+# Understood CPU flags are written to a file at 'pve-qemu' compile time
+my $understood_cpu_flag_dir = "/usr/share/kvm";
+
+sub query_understood_cpu_flags {
+    my $arch = get_host_arch();
+    my $filepath = "$understood_cpu_flag_dir/recognized-CPUID-flags-$arch";
+
+    die "Cannot query understood QEMU CPU flags for architecture: $arch (file not found)\n"
+        if !-e $filepath;
+
+    my $raw = PVE::Tools::file_get_contents($filepath);
+    $raw =~ s/^\s+|\s+$//g;
+    my @flags = split(/\s+/, $raw);
+
+    return \@flags;
+}
+
 sub get_cpu_models {
     my ($include_custom, $arch) = @_;
 
-- 
2.47.3




             reply	other threads:[~2026-02-17 10:50 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-17 10:50 Arthur Bied-Charreton [this message]
2026-02-17 10:50 ` [PATCH pve-manager] cpu config: Update path to query_supported_cpu_flags Arthur Bied-Charreton
2026-02-18 10:42 ` [PATCH qemu-server] cpu config: Move CPU flags utils to CPUConfig module 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=20260217105050.194368-1-a.bied-charreton@proxmox.com \
    --to=a.bied-charreton@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 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.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal