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
next 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox