From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 1719D1FF0B0 for ; Tue, 27 Oct 2026 11:14:34 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 942D821757; Tue, 27 Oct 2026 11:13:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=genua.de; s=202307; t=1793095942; bh=tDP+ArssMn7exWFeLaCCD6VJYulC1iVJg5R60y6OD9w=; h=Date:From:To:Subject:References:In-Reply-To:From; b=rIkQd4YjGNxXCAv/IN6UjA+atTYtQ9qrk8gY8pBf/Lu3ZXQk+OOGoAFz4YoSqbnOe MEj/WSFjUIgV8XxKFtg9RH1r4/bTa7GGUFlGVtbHk8kO8SgA6zST84GRg/mQ+SzU/L 9sz7g+Le6NIZVSNrrTn/eO6W0xS1I3jrAfeJx7VGkXBwdveGPFnIxEXlHcKbw4ZHM9 T5R+dHWjPJCQbmVbCOFvkno0s+MdMiAhPISV4CPMoJejY/fojXxgoj/0/xl6KCjD1u n01ImxG+Ulacka1Mu8+LZwktc/eu2OAmcxxlkwxQpwG1ko9nK2248j6Tjr9Ilyz0BN e4SSqcIoAqa4g== Date: Tue, 27 Oct 2026 11:12:21 +0100 From: Christian Ludwig To: Subject: [PATCH qemu-server v3 09/19] config: define bios schema as property-string Message-ID: <85e63753ada8c733e10dd43b7600a749592f3ccd.1793029144.git@genua.de> References: MIME-Version: 1.0 In-Reply-To: X-Originating-IP: [192.168.217.185] X-ClientProxiedBy: kch1-mta08.win.genua.de (10.208.16.108) To kch1-mta07.win.genua.de (10.208.16.107) Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline X-SPAM-LEVEL: Spam detection results: 0 AWL 0.062 Adjusted score from AWL reputation of From: address DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_PASS -0.001 SPF: sender matches SPF record UNPARSEABLE_RELAY 0.001 Informational: message has unparseable relay lines Message-ID-Hash: Q2MBR6QM3Q2VI5FEXJ473DHQH3PXRXAF X-Message-ID-Hash: Q2MBR6QM3Q2VI5FEXJ473DHQH3PXRXAF X-MailFrom: christian_ludwig@genua.de 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: Convert the bios parameter to a property-string and use the BIOS type as the default key for backward compatibility. This allows adding further BIOS related options, like a custom firmware image, as sub-properties. Add helpers to parse and print the property-string and to query the BIOS type, and use the latter everywhere the bios option was compared directly. No functional change intended. Signed-off-by: Christian Ludwig --- src/PVE/QemuConfig.pm | 3 ++- src/PVE/QemuServer.pm | 15 ++++++----- src/PVE/QemuServer/BIOS.pm | 48 +++++++++++++++++++++++++++++++++ src/PVE/QemuServer/CPUConfig.pm | 5 ++-- src/PVE/QemuServer/Makefile | 1 + src/PVE/QemuServer/PCI.pm | 3 ++- 6 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 src/PVE/QemuServer/BIOS.pm diff --git a/src/PVE/QemuConfig.pm b/src/PVE/QemuConfig.pm index 2ef6c075..d83a474c 100644 --- a/src/PVE/QemuConfig.pm +++ b/src/PVE/QemuConfig.pm @@ -10,6 +10,7 @@ use PVE::INotify; use PVE::JSONSchema; use PVE::QemuMigrate::Helpers; use PVE::QemuServer::Agent; +use PVE::QemuServer::BIOS; use PVE::QemuServer::Blockdev; use PVE::QemuServer::CPUConfig; use PVE::QemuServer::Drive; @@ -192,7 +193,7 @@ sub get_backup_volumes { my $reason = "backup="; $reason .= defined($drive->{backup}) ? 'no' : 'yes'; - if ($key =~ m/^efidisk/ && (!defined($conf->{bios}) || $conf->{bios} ne 'ovmf')) { + if ($key =~ m/^efidisk/ && PVE::QemuServer::BIOS::get_bios_type($conf) ne 'ovmf') { $included = 0; $reason = "efidisk but no OVMF BIOS"; } diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 74772fdd..c288ba22 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -53,6 +53,7 @@ use PVE::QemuConfig; use PVE::QemuConfig::NoWrite; use PVE::QemuMigrate::Helpers; use PVE::QemuServer::Agent qw(get_qga_key parse_guest_agent qga_check_running); +use PVE::QemuServer::BIOS qw(get_bios_type); use PVE::QemuServer::Blockdev; use PVE::QemuServer::BlockJob; use PVE::QemuServer::Cfg2Cmd; @@ -659,7 +660,7 @@ EODESCR bios => { optional => 1, type => 'string', - enum => [qw(seabios ovmf)], + format => 'pve-qm-bios', description => "Select BIOS implementation.", default => 'seabios', }, @@ -1535,7 +1536,7 @@ sub print_vga_device { my $edidoff = ""; if ($type eq 'VGA' && windows_version($conf->{ostype})) { - $edidoff = ",edid=off" if (!defined($conf->{bios}) || $conf->{bios} ne 'ovmf'); + $edidoff = ",edid=off" if get_bios_type($conf) ne 'ovmf'; } my $q35 = PVE::QemuServer::Machine::machine_type_is_q35($conf); @@ -3075,7 +3076,7 @@ my sub should_disable_smm { return if $machine =~ m/^virt/; # there is no smm flag that could be disabled return - (!defined($conf->{bios}) || $conf->{bios} eq 'seabios') + get_bios_type($conf) eq 'seabios' && $vga->{type} && $vga->{type} =~ m/^(serial\d+|none)$/; } @@ -3258,7 +3259,7 @@ sub config_to_command { push @$cmd, '-smbios', "type=1" . $smbios_string; } - if ($conf->{bios} && $conf->{bios} eq 'ovmf') { + if (get_bios_type($conf) eq 'ovmf') { die "OVMF (UEFI) BIOS is not supported on 32-bit CPU types\n" if !$forcecpu && get_cpu_bitness($conf->{cpu}, $arch) == 32; @@ -3771,10 +3772,10 @@ sub config_to_command { } if ($conf->{'amd-sev'}) { - push @$devices, '-object', get_amd_sev_object($conf->{'amd-sev'}, $conf->{bios}); + push @$devices, '-object', get_amd_sev_object($conf->{'amd-sev'}, get_bios_type($conf)); push @$machineFlags, 'confidential-guest-support=sev0'; } elsif ($conf->{'intel-tdx'}) { - my $tdx_object = get_intel_tdx_object($conf->{'intel-tdx'}, $conf->{bios}); + my $tdx_object = get_intel_tdx_object($conf->{'intel-tdx'}, get_bios_type($conf)); push @$devices, '-object', to_json($tdx_object, { canonical => 1 }); push @$machineFlags, 'confidential-guest-support=tdx0'; push @$machineFlags, 'kernel_irqchip=split'; @@ -5631,7 +5632,7 @@ sub vm_start_nolock { my $storage_hints = generate_storage_hints($conf, 1); PVE::Storage::activate_volumes($storecfg, $vollist, undef, $storage_hints); - check_efi_vars($storecfg, $vmid, $conf) if $conf->{bios} && $conf->{bios} eq 'ovmf'; + check_efi_vars($storecfg, $vmid, $conf) if get_bios_type($conf) eq 'ovmf'; PVE::QemuServer::Drive::warn_about_virtio_win_issues_in_config($conf); diff --git a/src/PVE/QemuServer/BIOS.pm b/src/PVE/QemuServer/BIOS.pm new file mode 100644 index 00000000..4e1a3936 --- /dev/null +++ b/src/PVE/QemuServer/BIOS.pm @@ -0,0 +1,48 @@ +package PVE::QemuServer::BIOS; + +use strict; +use warnings; + +use PVE::JSONSchema qw(parse_property_string print_property_string); + +use base 'Exporter'; + +our @EXPORT_OK = qw( + parse_bios + print_bios + get_bios_type +); + +my $bios_fmt = { + type => { + type => 'string', + enum => [qw(seabios ovmf)], + default_key => 1, + description => "Select BIOS implementation.", + }, +}; +PVE::JSONSchema::register_format('pve-qm-bios', $bios_fmt); + +sub parse_bios { + my ($value) = @_; + + return {} if !defined($value); + + return parse_property_string($bios_fmt, $value); +} + +sub print_bios { + my ($bios) = @_; + + return print_property_string($bios, $bios_fmt); +} + +# Returns the configured BIOS implementation, 'seabios' or 'ovmf'. +sub get_bios_type { + my ($conf) = @_; + + # SeaBIOS is the default if the bios option is not set + return parse_bios($conf->{bios})->{type} // 'seabios'; +} + +1; diff --git a/src/PVE/QemuServer/CPUConfig.pm b/src/PVE/QemuServer/CPUConfig.pm index 2bae55b2..c672302b 100644 --- a/src/PVE/QemuServer/CPUConfig.pm +++ b/src/PVE/QemuServer/CPUConfig.pm @@ -11,6 +11,7 @@ use PVE::ProcFSTools; use PVE::RESTEnvironment qw(log_warn); use PVE::Tools qw(run_command); +use PVE::QemuServer::BIOS qw(get_bios_type); use PVE::QemuServer::Helpers qw(min_version get_host_arch); use PVE::QemuServer::CPUFlags qw(cpu_flag_supported_re cpu_flag_any_re supported_cpu_flags_names); @@ -910,7 +911,7 @@ sub get_cpu_options( $hv_flags = get_hyperv_enlightenments( $winversion, $version_guard, - $conf->{bios}, + get_bios_type($conf), $gpu_passthrough, $hv_vendor_id, ); @@ -991,7 +992,7 @@ sub get_cpu_options( $cpu_str .= $phys_bits; } - check_phys_bits_above_40_compat($conf->{bios}, $cputype, $resolved_flags) + check_phys_bits_above_40_compat(get_bios_type($conf), $cputype, $resolved_flags) if $using_phys_bits_above_40; return ('-cpu', $cpu_str); diff --git a/src/PVE/QemuServer/Makefile b/src/PVE/QemuServer/Makefile index 060fac23..242f1155 100644 --- a/src/PVE/QemuServer/Makefile +++ b/src/PVE/QemuServer/Makefile @@ -3,6 +3,7 @@ PREFIX=/usr PERLDIR=$(PREFIX)/share/perl5 SOURCES=Agent.pm \ + BIOS.pm \ Blockdev.pm \ BlockJob.pm \ Cfg2Cmd.pm \ diff --git a/src/PVE/QemuServer/PCI.pm b/src/PVE/QemuServer/PCI.pm index d7dc6121..38640ff0 100644 --- a/src/PVE/QemuServer/PCI.pm +++ b/src/PVE/QemuServer/PCI.pm @@ -10,6 +10,7 @@ use PVE::Mapping::PCI; use PVE::SysFSTools; use PVE::Tools; +use PVE::QemuServer::BIOS qw(get_bios_type); use PVE::QemuServer::Helpers; use PVE::QemuServer::Machine; use PVE::QemuServer::PCI::Mdev; @@ -666,7 +667,7 @@ sub print_hostpci_devices { my $xvga = ''; if ($d->{'x-vga'}) { - $xvga = ',x-vga=on' if !($conf->{bios} && $conf->{bios} eq 'ovmf'); + $xvga = ',x-vga=on' if get_bios_type($conf) ne 'ovmf'; $kvm_off = 1; $vga->{type} = 'none' if !defined($conf->{vga}); $gpu_passthrough = 1; -- 2.34.1