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