From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 120931FF13B for ; Wed, 03 Jun 2026 09:09:37 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8DA26376C7; Wed, 3 Jun 2026 09:09:33 +0200 (CEST) From: Arthur Bied-Charreton To: pve-devel@lists.proxmox.com Subject: [PATCH v3 1/2] build: include Hyper-V enlightenments in CPUID flags list Date: Wed, 3 Jun 2026 09:07:35 +0200 Message-ID: <20260603070857.184709-2-a.bied-charreton@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260603070857.184709-1-a.bied-charreton@proxmox.com> References: <20260603070857.184709-1-a.bied-charreton@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.132 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: 2QWWFFIOGUBGTZFRXMJVGYBNMKH2BVGF X-Message-ID-Hash: 2QWWFFIOGUBGTZFRXMJVGYBNMKH2BVGF X-MailFrom: abied-charreton@jett.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: ... by sourcing CPU flags from qom-list-properties. The recognized-CPUID-flags-x86_64 list was generated from QEMU's '-cpu help' output, which does not advertise Hyper-V enlightenments. Source the flags from the qom-list-properties QMP command instead to include them. The properties are queried from the max-x86_64-cpu CPU type, which is also available on aarch64 (as opposed to host-x86_64-cpu). The CPU typename is passed to the script as a CLI argument to allow easily extending it to query flags for other architectures. The following unwanted properties are filtered out: * Non-boolean properties, since the custom CPU models config only supports enable/disable. * Properties exposed by qom-list-properties that are neither CPUID flags nor Hyper-V enlightenments. * The 'hv-syndbg' Hyper-V enlightenment, which depends on whether KVM is available at build time and would therefore lead to inconsistent results. [0] [0] https://lore.proxmox.com/pve-devel/0fbeed5e-3d77-4126-828c-acdb04c109ff@proxmox.com/ Suggested-by: Fiona Ebner Signed-off-by: Arthur Bied-Charreton --- debian/parse-cpu-flags.pl | 144 ++++++++++++++++++++++++++++++++++---- debian/rules | 2 +- 2 files changed, 130 insertions(+), 16 deletions(-) diff --git a/debian/parse-cpu-flags.pl b/debian/parse-cpu-flags.pl index 1847b3e..e680f99 100755 --- a/debian/parse-cpu-flags.pl +++ b/debian/parse-cpu-flags.pl @@ -1,23 +1,137 @@ #!/usr/bin/perl -use warnings; -use strict; +use v5.36; -my @flags = (); -my $got_flags_section; +use IPC::Open2; +use JSON; -while () { - if (/^\s*Recognized CPUID flags:/) { - $got_flags_section = 1; - next; - } - next if !$got_flags_section; +# qemu/target/i386/cpu.c, x86_cpu_initfn() +my $qemu_cpu_flag_alias_map = { + cmp_legacy => 'cmp-legacy', + ds_cpl => 'ds-cpl', + ffxsr => 'fxsr-opt', + fxsr_opt => 'fxsr-opt', + 'hv-apicv' => 'hv-avic', + i64 => 'lm', + kvm_nopiodelay => 'kvm-nopiodelay', + kvm_mmu => 'kvm-mmu', + kvm_asyncpf => 'kvm-asyncpf', + kvm_asyncpf_int => 'kvm-asyncpf-int', + kvm_steal_time => 'kvm-steal-time', + kvm_pv_eoi => 'kvm-pv-eoi', + kvm_pv_unhalt => 'kvm-pv-unhalt', + kvm_poll_control => 'kvm-poll-control', + lahf_lm => 'lahf-lm', + lbr_fmt => 'lbr-fmt', + nodeid_msr => 'nodeid-msr', + nrip_save => 'nrip-save', + pause_filter => 'pause-filter', + pclmuldq => 'pclmulqdq', + perfctr_core => 'perfctr-core', + perfctr_nb => 'perfctr-nb', + sse3 => 'pni', + sse4_1 => 'sse4.1', + sse4_2 => 'sse4.2', + 'sse4-1' => 'sse4.1', + 'sse4-2' => 'sse4.2', + svm_lock => 'svm-lock', + tsc_adjust => 'tsc-adjust', + tsc_scale => 'tsc-scale', + vmcb_clean => 'vmcb-clean', + xd => 'nx', +}; - s/^\s+//; +# Static blacklist to be reviewed on QEMU bumps. +# +# Currently includes boolean properties from qom-list-properties that are neither CPUID +# flags ('-cpu help') nor Hyper-V enlightenments ('hv-*'). Entries excluded for other +# reasons are annotated inline. +my $filtered_props = { + 'max-x86_64-cpu' => { + check => 1, + 'cpuid-0xb' => 1, + enforce => 1, + 'fill-mtrr-mask' => 1, + 'host-cache-info' => 1, + 'host-phys-bits' => 1, + hotpluggable => 1, + hotplugged => 1, + # Presence varies at built-time based on whether KVM is present (CONFIG_SYNDBG) + # https://lore.proxmox.com/pve-devel/0fbeed5e-3d77-4126-828c-acdb04c109ff@proxmox.com/ + 'hv-syndbg' => 1, + kvm => 1, + 'kvm-pv-enforce-cpuid' => 1, + 'l3-cache' => 1, + 'legacy-cache' => 1, + 'legacy-multi-node' => 1, + lmce => 1, + migratable => 1, + pmu => 1, + realized => 1, + 'start-powered-off' => 1, + 'tcg-cpuid' => 1, + 'vmware-cpuid-freq' => 1, + 'x-amd-topoext-features-only' => 1, + 'x-arch-cap-always-on' => 1, + 'x-consistent-cache' => 1, + 'x-force-cpuid-0x1f' => 1, + 'x-force-features' => 1, + 'x-l1-cache-per-thread' => 1, + 'x-migrate-error-code' => 1, + 'x-migrate-smi-count' => 1, + 'x-pdcm-on-even-without-pmu' => 1, + 'x-vendor-cpuid-only' => 1, + 'x-vendor-cpuid-only-v2' => 1, + 'xen-vapic' => 1, + }, +}; - push @flags, split(/\s+/); -} +sub print_flags($qemu_bin, $typename) { + die "Unknown typename, must be one of '" . join("', '", keys $filtered_props->%*) . "'\n" + if !defined($filtered_props->{$typename}); + + my $pid = open2( + my $out, + my $in, + $qemu_bin, + '-machine', + 'none', + '-display', + 'none', + '-S', + '-qmp', + 'stdio', + '-nodefaults', + ); + + my $qmp = sub ($cmd, %args) { + print $in encode_json({ execute => $cmd, %args ? (arguments => \%args) : () }), "\n"; + while (my $line = <$out>) { + my $msg = decode_json($line); + next if $msg->{event}; + return $msg->{return} if exists($msg->{return}); + die "QMP error: " . encode_json($msg->{error}) if $msg->{error}; + } + }; -die "no QEMU/KVM CPU flags detected from STDIN input" if scalar (@flags) <= 0; + my $flags = {}; + my $greeting = <$out>; + my $decoded_greeting = decode_json($greeting); + die "Unexpected QMP greeting: $greeting\n" if !exists($decoded_greeting->{QMP}); + + $qmp->('qmp_capabilities'); + my $props = $qmp->('qom-list-properties', typename => $typename); + for my $qo ($props->@*) { + next if $qo->{type} ne 'bool' || defined($filtered_props->{$typename}->{$qo->{name}}); + my $resolved_name = $qemu_cpu_flag_alias_map->{$qo->{name}} // $qo->{name}; + $flags->{$resolved_name} = 1; + } + $qmp->('quit'); + waitpid($pid, 0); + + my @flags = sort keys $flags->%*; + print join("\n", @flags) . "\n"; +} -print join("\n", @flags) or die "$!\n"; +my ($qemu_bin, $typename) = @ARGV; +print_flags($qemu_bin, $typename); diff --git a/debian/rules b/debian/rules index c90db29..053f2f3 100755 --- a/debian/rules +++ b/debian/rules @@ -123,7 +123,7 @@ install: build rm -f $(destdir)/usr/lib/kvm/virtfs-proxy-helper # CPU flags are static for QEMU version, allows avoiding more costly checks - $(destdir)/usr/bin/qemu-system-x86_64 -cpu help | ./debian/parse-cpu-flags.pl > $(flagfile) + ./debian/parse-cpu-flags.pl $(destdir)/usr/bin/qemu-system-x86_64 max-x86_64-cpu > $(flagfile) # Supported machine versions are static for a given QEMU binary. $(destdir)/usr/bin/qemu-system-x86_64 -machine help | ./debian/parse-machines.pl > $(machine_file_x86_64) -- 2.47.3