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 574F01FF0A7 for ; Mon, 17 Aug 2026 13:59:45 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 1CC2D23D3C; Mon, 17 Aug 2026 13:59:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=genua.de; s=202307; t=1786967970; bh=YMMTaDT+3MmyAt1UmwUHxqa7nrXYWoXWP4Gt5A4JbpM=; h=Date:From:To:Subject:References:In-Reply-To:From; b=bEBoER34Rc2kGLl9gD8CZvHjRjcwVZ/xW6Ayk99Wi50CoRrD82c6lm3pJ8VG6zhuJ AEtpfbXGSCdHjHLSdEYEuYAm9bg40Fd4LJGDJsJWHkJoDtiVn8QSVlYHqs+sRRSyz5 Lc/75sPnxAvUhxn8zwyWxs18Wn265U9O5K772l5rXv7YEW2QzzwyKgiD6XIBq1hTyC 5viexfTJR+mb1aOZwYeK+z62TEHCHdWo0kpwlOxs1T22H1/T4i8oWSkqpLprdfPtEa 5Nl91GGt2nboup1JBGyaW7HbJ5IVSwGVkg+9B3xfO8chBD17Ku3rZ2HmqXOwp8Gd6y QtH91Ol403irg== Date: Mon, 17 Aug 2026 13:59:29 +0200 From: Christian Ludwig To: Subject: [PATCH qemu-server 07/13] Add efi-firmware key to VM config schema Message-ID: References: MIME-Version: 1.0 In-Reply-To: X-Originating-IP: [192.168.217.185] X-ClientProxiedBy: kch1-mta07.win.genua.de (10.208.16.107) To kch1-mta07.win.genua.de (10.208.16.107) Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha-256"; boundary="----6D6CA41E2BA0A0EFE23D2DB49E701F95" X-SPAM-LEVEL: Spam detection results: 0 AWL 0.204 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: JPUXBELLCGWYOFUW2DCJDLRNLUFTFPIE X-Message-ID-Hash: JPUXBELLCGWYOFUW2DCJDLRNLUFTFPIE 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-Content-Filtered-By: Mailman/MimeDel 3.3.10 X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: ------6D6CA41E2BA0A0EFE23D2DB49E701F95 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline Add a new config key 'efi-firmware' to the VM config schema. That key points to a firmware content type file. It is restricted to OVMF bios settings. A custom efi-firmware image does not make sense for VMs with legacy BIOS. Signed-off-by: Christian Ludwig --- src/PVE/QemuConfig.pm | 7 +++++++ src/PVE/QemuServer.pm | 30 ++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/PVE/QemuConfig.pm b/src/PVE/QemuConfig.pm index 26f0fda2..d25f2bbb 100644 --- a/src/PVE/QemuConfig.pm +++ b/src/PVE/QemuConfig.pm @@ -112,6 +112,13 @@ sub parse_volume { die $err; } $volume = { 'file' => $volume_string }; + } elsif ($key eq 'efi-firmware') { + eval { PVE::JSONSchema::check_format('pve-volume-id', $volume_string) }; + if (my $err = $@) { + return if $noerr; + die $err; + } + $volume = { 'file' => $volume_string }; } else { $volume = PVE::QemuServer::Drive::parse_drive($key, $volume_string); } diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 2f43faa7..b95fcb8c 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -663,6 +663,14 @@ EODESCR description => "Select BIOS implementation.", default => 'seabios', }, + 'efi-firmware' => { + optional => 1, + type => 'string', + format => 'pve-volume-id', + description => "Custom EFI firmware code image (pflash0). Must be a volid " + . "referencing a 'efi-firmware' content type volume (e.g. " + . "'local:efi-firmware/custom.fd'). Requires bios=ovmf.", + }, vmgenid => { type => 'string', pattern => '(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])', @@ -2078,6 +2086,21 @@ sub parse_vm_config { $res->{pending} = {} if !defined($res->{pending}); + # config sanity checks + if ($res->{'efi-firmware'}) { + if (!$res->{bios} || $res->{bios} ne 'ovmf') { + $handle_error->("vm $vmid - efi-firmware requires bios=ovmf\n"); + } else { + my ($sid, $volname) = PVE::Storage::parse_volume_id($res->{'efi-firmware'}, 1); + if (!$sid || $volname !~ m!^efi-firmware/[^/]+$!) { + $handle_error->( + "vm $vmid - efi-firmware: invalid volid format," + . " expected :efi-firmware/\n" + ); + } + } + } + return $res; } @@ -4568,11 +4591,14 @@ sub foreach_volid { $volhash->{$volid}->{is_tpmstate} //= 0; $volhash->{$volid}->{is_tpmstate} = 1 if $key eq 'tpmstate0'; + $volhash->{$volid}->{is_firmware} //= 0; + $volhash->{$volid}->{is_firmware} = 1 if $key eq 'efi-firmware'; + $volhash->{$volid}->{drivename} = $key if is_valid_drivename($key); }; my $include_opts = { - extra_keys => ['vmstate'], + extra_keys => ['vmstate', 'efi-firmware'], include_unused => 1, }; @@ -6123,7 +6149,7 @@ sub get_current_vm_volumes { PVE::QemuConfig->foreach_volume_full( $conf, - { extra_keys => ['vmstate'] }, + { extra_keys => ['vmstate', 'efi-firmware'] }, sub { my ($ds, $drive) = @_; -- 2.34.1 ------6D6CA41E2BA0A0EFE23D2DB49E701F95--