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 3FDDA1FF0A7 for ; Mon, 17 Aug 2026 11:37:16 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id B3F7923A44; Mon, 17 Aug 2026 11:36:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=genua.de; s=202307; t=1786958970; bh=Y8yIgL/52aViLcdD7v1tdHRT9tIthOkvfzK1UOVNrKU=; h=Date:From:To:Subject:References:In-Reply-To:From; b=rTE6S6502QWcoPAKlN2XxsJeCw4bYIS3PmT4wBAUwexohGm91C5Y2b42NJ49FQtg7 h5cjIQO4P2k1sqTRG73eC6LNoO3zzQeahhRCB6ewj+nQixYcjrqeIq+9WwTBGKWsjA OiDZ9NRhAMTvnUNN7hcVF2vKrw+P0hG1lidhf/HNmbxRjazMxNBUSUh8QKyzNcDcFW GlMDLA26ESTVXYewbEKUIvQ+iLpR+1PONz9+Ad1cgiA8kwdfHd+NMLtTI4DxrjLXHO ZxacMoaTx3gMbkwklyJMa4OitJVlMtt2HTXnzDD8h56urWMAd6Z6GlTk+aPEvumbbQ D3RRxzaMSjEsw== Date: Mon, 17 Aug 2026 11:29:29 +0200 From: Christian Ludwig To: , <-b@genua.de>, 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="----91897698F537B43AEE7ECFA4BB652CE3" X-SPAM-LEVEL: Spam detection results: 0 DKIM_INVALID 0.1 DKIM or DK signature exists, but is not valid DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DMARC_PASS -0.1 DMARC pass policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) 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: FBZEXLMSRIA37KAY3DPHHVSMT2P7EUM5 X-Message-ID-Hash: FBZEXLMSRIA37KAY3DPHHVSMT2P7EUM5 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: ------91897698F537B43AEE7ECFA4BB652CE3 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 ------91897698F537B43AEE7ECFA4BB652CE3--