[pve-devel] [PATCH qemu-server 07/15] introduce OVMF module

Fiona Ebner f.ebner at proxmox.com
Mon Jun 23 17:44:17 CEST 2025


Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
---
 src/PVE/API2/Qemu.pm             |  13 ++-
 src/PVE/QemuMigrate.pm           |   3 +-
 src/PVE/QemuServer.pm            | 168 +---------------------------
 src/PVE/QemuServer/Makefile      |   1 +
 src/PVE/QemuServer/OVMF.pm       | 186 +++++++++++++++++++++++++++++++
 src/test/MigrationTest/Shared.pm |   4 +
 6 files changed, 207 insertions(+), 168 deletions(-)
 create mode 100644 src/PVE/QemuServer/OVMF.pm

diff --git a/src/PVE/API2/Qemu.pm b/src/PVE/API2/Qemu.pm
index ce6f362d..44322db6 100644
--- a/src/PVE/API2/Qemu.pm
+++ b/src/PVE/API2/Qemu.pm
@@ -36,6 +36,7 @@ use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::Machine;
 use PVE::QemuServer::Memory qw(get_current_memory);
 use PVE::QemuServer::MetaInfo;
+use PVE::QemuServer::OVMF;
 use PVE::QemuServer::PCI;
 use PVE::QemuServer::QMPHelpers;
 use PVE::QemuServer::RNG;
@@ -540,8 +541,10 @@ my sub create_disks : prototype($$$$$$$$$$$) {
                             format => $disk->{format},
                         };
 
-                        $dest_info->{efisize} = PVE::QemuServer::get_efivars_size($conf, $disk)
-                            if $ds eq 'efidisk0';
+                        if ($ds eq 'efidisk0') {
+                            $dest_info->{efisize} =
+                                PVE::QemuServer::OVMF::get_efivars_size($conf, $disk);
+                        }
 
                         eval {
                             ($dst_volid, $size) =
@@ -612,7 +615,7 @@ my sub create_disks : prototype($$$$$$$$$$$) {
                         "SEV-SNP uses consolidated read-only firmware and does not require an EFI disk\n"
                         if $amd_sev_type && $amd_sev_type eq 'snp';
 
-                    ($volid, $size) = PVE::QemuServer::create_efidisk(
+                    ($volid, $size) = PVE::QemuServer::OVMF::create_efidisk(
                         $storecfg, $storeid, $vmid, $fmt, $arch, $disk, $smm, $amd_sev_type,
                     );
                 } elsif ($ds eq 'tpmstate0') {
@@ -4455,7 +4458,7 @@ __PACKAGE__->register_method({
                         format => $format,
                     };
 
-                    $dest_info->{efisize} = PVE::QemuServer::get_efivars_size($oldconf)
+                    $dest_info->{efisize} = PVE::QemuServer::OVMF::get_efivars_size($oldconf)
                         if $opt eq 'efidisk0';
 
                     my $newdrive = PVE::QemuServer::clone_disk(
@@ -4733,7 +4736,7 @@ __PACKAGE__->register_method({
                     format => $format,
                 };
 
-                $dest_info->{efisize} = PVE::QemuServer::get_efivars_size($conf)
+                $dest_info->{efisize} = PVE::QemuServer::OVMF::get_efivars_size($conf)
                     if $disk eq 'efidisk0';
 
                 my $newdrive = PVE::QemuServer::clone_disk(
diff --git a/src/PVE/QemuMigrate.pm b/src/PVE/QemuMigrate.pm
index 28d7ac56..9ccaf7e0 100644
--- a/src/PVE/QemuMigrate.pm
+++ b/src/PVE/QemuMigrate.pm
@@ -31,6 +31,7 @@ use PVE::QemuServer::Helpers qw(min_version);
 use PVE::QemuServer::Machine;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::Memory qw(get_current_memory);
+use PVE::QemuServer::OVMF;
 use PVE::QemuServer::QMPHelpers;
 use PVE::QemuServer;
 
@@ -635,7 +636,7 @@ sub config_update_local_disksizes {
     # we want to set the efidisk size in the config to the size of the
     # real OVMF_VARS.fd image, else we can create a too big image, which does not work
     if (defined($conf->{efidisk0})) {
-        PVE::QemuServer::update_efidisk_size($conf);
+        PVE::QemuServer::OVMF::update_efidisk_size($conf);
     }
 
     # TPM state might have an irregular filesize, to avoid problems on transfer
diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm
index 63b4d469..719687dc 100644
--- a/src/PVE/QemuServer.pm
+++ b/src/PVE/QemuServer.pm
@@ -56,7 +56,7 @@ use PVE::QemuServer::Helpers
 use PVE::QemuServer::Cloudinit;
 use PVE::QemuServer::CGroup;
 use PVE::QemuServer::CPUConfig
-    qw(print_cpu_device get_cpu_options get_cpu_bitness is_native_arch get_amd_sev_object get_amd_sev_type);
+    qw(print_cpu_device get_cpu_options is_native_arch get_amd_sev_object get_amd_sev_type);
 use PVE::QemuServer::Drive qw(
     is_valid_drivename
     checked_volume_format
@@ -71,6 +71,7 @@ use PVE::QemuServer::Machine;
 use PVE::QemuServer::Memory qw(get_current_memory);
 use PVE::QemuServer::MetaInfo;
 use PVE::QemuServer::Monitor qw(mon_cmd);
+use PVE::QemuServer::OVMF;
 use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port parse_hostpci);
 use PVE::QemuServer::QemuImage;
 use PVE::QemuServer::QMPHelpers qw(qemu_deviceadd qemu_devicedel qemu_objectadd qemu_objectdel);
@@ -98,41 +99,6 @@ my sub vm_is_ha_managed {
     return PVE::HA::Config::vm_is_ha_managed($vmid);
 }
 
-my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/';
-my $OVMF = {
-    x86_64 => {
-        '4m-no-smm' => [
-            "$EDK2_FW_BASE/OVMF_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.fd",
-        ],
-        '4m-no-smm-ms' => [
-            "$EDK2_FW_BASE/OVMF_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd",
-        ],
-        '4m' => [
-            "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.fd",
-        ],
-        '4m-ms' => [
-            "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd",
-        ],
-        '4m-sev' => [
-            "$EDK2_FW_BASE/OVMF_CVM_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_CVM_VARS_4M.fd",
-        ],
-        '4m-snp' => [
-            "$EDK2_FW_BASE/OVMF_CVM_4M.fd",
-        ],
-        # FIXME: These are legacy 2MB-sized images that modern OVMF doesn't supports to build
-        # anymore. how can we deperacate this sanely without breaking existing instances, or using
-        # older backups and snapshot?
-        default => [
-            "$EDK2_FW_BASE/OVMF_CODE.fd", "$EDK2_FW_BASE/OVMF_VARS.fd",
-        ],
-    },
-    aarch64 => {
-        default => [
-            "$EDK2_FW_BASE/AAVMF_CODE.fd", "$EDK2_FW_BASE/AAVMF_VARS.fd",
-        ],
-    },
-};
-
 my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
 
 # Note about locking: we use flock on the config file protect against concurrent actions.
@@ -3293,36 +3259,6 @@ sub vga_conf_has_spice {
     return $1 || 1;
 }
 
-sub get_ovmf_files($$$$) {
-    my ($arch, $efidisk, $smm, $amd_sev_type) = @_;
-
-    my $types = $OVMF->{$arch}
-        or die "no OVMF images known for architecture '$arch'\n";
-
-    my $type = 'default';
-    if ($arch eq 'x86_64') {
-        if ($amd_sev_type && $amd_sev_type eq 'snp') {
-            $type = "4m-snp";
-            my ($ovmf) = $types->{$type}->@*;
-            die "EFI base image '$ovmf' not found\n" if !-f $ovmf;
-            return ($ovmf);
-        } elsif ($amd_sev_type) {
-            $type = "4m-sev";
-        } elsif (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') {
-            $type = $smm ? "4m" : "4m-no-smm";
-            $type .= '-ms' if $efidisk->{'pre-enrolled-keys'};
-        } else {
-            # TODO: log_warn about use of legacy images for x86_64 with Promxox VE 9
-        }
-    }
-
-    my ($ovmf_code, $ovmf_vars) = $types->{$type}->@*;
-    die "EFI base image '$ovmf_code' not found\n" if !-f $ovmf_code;
-    die "EFI vars image '$ovmf_vars' not found\n" if !-f $ovmf_vars;
-
-    return ($ovmf_code, $ovmf_vars);
-}
-
 # To use query_supported_cpu_flags and query_understood_cpu_flags to get flags
 # to use in a QEMU command line (-cpu element), first array_intersect the result
 # of query_supported_ with query_understood_. This is necessary because:
@@ -3464,48 +3400,6 @@ my sub should_disable_smm {
         && $vga->{type} =~ m/^(serial\d+|none)$/;
 }
 
-my sub print_ovmf_drive_commandlines {
-    my ($conf, $storecfg, $vmid, $arch, $q35, $version_guard) = @_;
-
-    my $d = $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef;
-
-    my $amd_sev_type = get_amd_sev_type($conf);
-    die "Attempting to configure SEV-SNP with pflash devices instead of using `-bios`\n"
-        if $amd_sev_type && $amd_sev_type eq 'snp';
-
-    my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35, $amd_sev_type);
-
-    my $var_drive_str = "if=pflash,unit=1,id=drive-efidisk0";
-    if ($d) {
-        my ($storeid, $volname) = PVE::Storage::parse_volume_id($d->{file}, 1);
-        my ($path, $format) = $d->@{ 'file', 'format' };
-        if ($storeid) {
-            $path = PVE::Storage::path($storecfg, $d->{file});
-            $format //= checked_volume_format($storecfg, $d->{file});
-        } elsif (!defined($format)) {
-            die "efidisk format must be specified\n";
-        }
-        # SPI flash does lots of read-modify-write OPs, without writeback this gets really slow #3329
-        if ($path =~ m/^rbd:/) {
-            $var_drive_str .= ',cache=writeback';
-            $path .= ':rbd_cache_policy=writeback'; # avoid write-around, we *need* to cache writes too
-        }
-        $var_drive_str .= ",format=$format,file=$path";
-
-        $var_drive_str .= ",size=" . (-s $ovmf_vars)
-            if $format eq 'raw' && $version_guard->(4, 1, 2);
-        $var_drive_str .= ',readonly=on' if drive_is_read_only($conf, $d);
-    } else {
-        log_warn("no efidisk configured! Using temporary efivars disk.");
-        my $path = "/tmp/$vmid-ovmf.fd";
-        PVE::Tools::file_copy($ovmf_vars, $path, -s $ovmf_vars);
-        $var_drive_str .= ",format=raw,file=$path";
-        $var_drive_str .= ",size=" . (-s $ovmf_vars) if $version_guard->(4, 1, 2);
-    }
-
-    return ("if=pflash,unit=0,format=raw,readonly=on,file=$ovmf_code", $var_drive_str);
-}
-
 my sub get_vga_properties {
     my ($conf, $arch, $machine_version, $winversion) = @_;
 
@@ -3680,21 +3574,10 @@ sub config_to_command {
     }
 
     if ($conf->{bios} && $conf->{bios} eq 'ovmf') {
-        die "OVMF (UEFI) BIOS is not supported on 32-bit CPU types\n"
-            if !$forcecpu && get_cpu_bitness($conf->{cpu}, $arch) == 32;
-
-        my $amd_sev_type = get_amd_sev_type($conf);
-        if ($amd_sev_type && $amd_sev_type eq 'snp') {
-            if (defined($conf->{efidisk0})) {
-                log_warn("EFI disks are not supported with SEV-SNP and will be ignored");
-            }
-            push $cmd->@*, '-bios', get_ovmf_files($arch, undef, undef, $amd_sev_type);
-        } else {
-            my ($code_drive_str, $var_drive_str) =
-                print_ovmf_drive_commandlines($conf, $storecfg, $vmid, $arch, $q35, $version_guard);
-            push $cmd->@*, '-drive', $code_drive_str;
-            push $cmd->@*, '-drive', $var_drive_str;
-        }
+        my $ovmf_cmd = PVE::QemuServer::OVMF::print_ovmf_commandline(
+            $conf, $storecfg, $vmid, $arch, $q35, $version_guard, $forcecpu,
+        );
+        push $cmd->@*, $ovmf_cmd->@*;
     }
 
     if ($q35) { # tell QEMU to load q35 config early
@@ -8853,29 +8736,6 @@ sub qemu_use_old_bios_files {
     return ($use_old_bios_files, $machine_type);
 }
 
-sub get_efivars_size {
-    my ($conf, $efidisk) = @_;
-
-    my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf);
-    $efidisk //= $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef;
-    my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf);
-    my $amd_sev_type = get_amd_sev_type($conf);
-    my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type);
-    return -s $ovmf_vars;
-}
-
-sub update_efidisk_size {
-    my ($conf) = @_;
-
-    return if !defined($conf->{efidisk0});
-
-    my $disk = PVE::QemuServer::parse_drive('efidisk0', $conf->{efidisk0});
-    $disk->{size} = get_efivars_size($conf);
-    $conf->{efidisk0} = print_drive($disk);
-
-    return;
-}
-
 sub update_tpmstate_size {
     my ($conf) = @_;
 
@@ -8884,22 +8744,6 @@ sub update_tpmstate_size {
     $conf->{tpmstate0} = print_drive($disk);
 }
 
-sub create_efidisk($$$$$$$$) {
-    my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm, $amd_sev_type) = @_;
-
-    my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type);
-
-    my $vars_size_b = -s $ovmf_vars;
-    my $vars_size = PVE::Tools::convert_size($vars_size_b, 'b' => 'kb');
-    my $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, $vars_size);
-    PVE::Storage::activate_volumes($storecfg, [$volid]);
-
-    PVE::QemuServer::QemuImage::convert($ovmf_vars, $volid, $vars_size_b);
-    my $size = PVE::Storage::volume_size_info($storecfg, $volid, 3);
-
-    return ($volid, $size / 1024);
-}
-
 sub vm_iothreads_list {
     my ($vmid) = @_;
 
diff --git a/src/PVE/QemuServer/Makefile b/src/PVE/QemuServer/Makefile
index a34ec83b..dd6fe505 100644
--- a/src/PVE/QemuServer/Makefile
+++ b/src/PVE/QemuServer/Makefile
@@ -14,6 +14,7 @@ SOURCES=Agent.pm	\
 	Memory.pm	\
 	MetaInfo.pm	\
 	Monitor.pm	\
+	OVMF.pm		\
 	PCI.pm		\
 	QemuImage.pm	\
 	QMPHelpers.pm	\
diff --git a/src/PVE/QemuServer/OVMF.pm b/src/PVE/QemuServer/OVMF.pm
new file mode 100644
index 00000000..70c626a5
--- /dev/null
+++ b/src/PVE/QemuServer/OVMF.pm
@@ -0,0 +1,186 @@
+package PVE::QemuServer::OVMF;
+
+use strict;
+use warnings;
+
+use PVE::RESTEnvironment qw(log_warn);
+use PVE::Storage;
+use PVE::Tools;
+
+use PVE::QemuServer::Drive qw(checked_volume_format drive_is_read_only parse_drive print_drive);
+use PVE::QemuServer::CPUConfig qw(get_amd_sev_type get_cpu_bitness);
+use PVE::QemuServer::Helpers;
+use PVE::QemuServer::Machine;
+use PVE::QemuServer::QemuImage;
+
+my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/';
+my $OVMF = {
+    x86_64 => {
+        '4m-no-smm' => [
+            "$EDK2_FW_BASE/OVMF_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.fd",
+        ],
+        '4m-no-smm-ms' => [
+            "$EDK2_FW_BASE/OVMF_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd",
+        ],
+        '4m' => [
+            "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.fd",
+        ],
+        '4m-ms' => [
+            "$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd", "$EDK2_FW_BASE/OVMF_VARS_4M.ms.fd",
+        ],
+        '4m-sev' => [
+            "$EDK2_FW_BASE/OVMF_CVM_CODE_4M.fd", "$EDK2_FW_BASE/OVMF_CVM_VARS_4M.fd",
+        ],
+        '4m-snp' => [
+            "$EDK2_FW_BASE/OVMF_CVM_4M.fd",
+        ],
+        # FIXME: These are legacy 2MB-sized images that modern OVMF doesn't supports to build
+        # anymore. how can we deperacate this sanely without breaking existing instances, or using
+        # older backups and snapshot?
+        default => [
+            "$EDK2_FW_BASE/OVMF_CODE.fd", "$EDK2_FW_BASE/OVMF_VARS.fd",
+        ],
+    },
+    aarch64 => {
+        default => [
+            "$EDK2_FW_BASE/AAVMF_CODE.fd", "$EDK2_FW_BASE/AAVMF_VARS.fd",
+        ],
+    },
+};
+
+my sub get_ovmf_files($$$$) {
+    my ($arch, $efidisk, $smm, $amd_sev_type) = @_;
+
+    my $types = $OVMF->{$arch}
+        or die "no OVMF images known for architecture '$arch'\n";
+
+    my $type = 'default';
+    if ($arch eq 'x86_64') {
+        if ($amd_sev_type && $amd_sev_type eq 'snp') {
+            $type = "4m-snp";
+            my ($ovmf) = $types->{$type}->@*;
+            die "EFI base image '$ovmf' not found\n" if !-f $ovmf;
+            return ($ovmf);
+        } elsif ($amd_sev_type) {
+            $type = "4m-sev";
+        } elsif (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') {
+            $type = $smm ? "4m" : "4m-no-smm";
+            $type .= '-ms' if $efidisk->{'pre-enrolled-keys'};
+        } else {
+            # TODO: log_warn about use of legacy images for x86_64 with Promxox VE 9
+        }
+    }
+
+    my ($ovmf_code, $ovmf_vars) = $types->{$type}->@*;
+    die "EFI base image '$ovmf_code' not found\n" if !-f $ovmf_code;
+    die "EFI vars image '$ovmf_vars' not found\n" if !-f $ovmf_vars;
+
+    return ($ovmf_code, $ovmf_vars);
+}
+
+my sub print_ovmf_drive_commandlines {
+    my ($conf, $storecfg, $vmid, $arch, $q35, $version_guard) = @_;
+
+    my $d = $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef;
+
+    my $amd_sev_type = get_amd_sev_type($conf);
+    die "Attempting to configure SEV-SNP with pflash devices instead of using `-bios`\n"
+        if $amd_sev_type && $amd_sev_type eq 'snp';
+
+    my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d, $q35, $amd_sev_type);
+
+    my $var_drive_str = "if=pflash,unit=1,id=drive-efidisk0";
+    if ($d) {
+        my ($storeid, $volname) = PVE::Storage::parse_volume_id($d->{file}, 1);
+        my ($path, $format) = $d->@{ 'file', 'format' };
+        if ($storeid) {
+            $path = PVE::Storage::path($storecfg, $d->{file});
+            $format //= checked_volume_format($storecfg, $d->{file});
+        } elsif (!defined($format)) {
+            die "efidisk format must be specified\n";
+        }
+        # SPI flash does lots of read-modify-write OPs, without writeback this gets really slow #3329
+        if ($path =~ m/^rbd:/) {
+            $var_drive_str .= ',cache=writeback';
+            $path .= ':rbd_cache_policy=writeback'; # avoid write-around, we *need* to cache writes too
+        }
+        $var_drive_str .= ",format=$format,file=$path";
+
+        $var_drive_str .= ",size=" . (-s $ovmf_vars)
+            if $format eq 'raw' && $version_guard->(4, 1, 2);
+        $var_drive_str .= ',readonly=on' if drive_is_read_only($conf, $d);
+    } else {
+        log_warn("no efidisk configured! Using temporary efivars disk.");
+        my $path = "/tmp/$vmid-ovmf.fd";
+        PVE::Tools::file_copy($ovmf_vars, $path, -s $ovmf_vars);
+        $var_drive_str .= ",format=raw,file=$path";
+        $var_drive_str .= ",size=" . (-s $ovmf_vars) if $version_guard->(4, 1, 2);
+    }
+
+    return ("if=pflash,unit=0,format=raw,readonly=on,file=$ovmf_code", $var_drive_str);
+}
+
+sub get_efivars_size {
+    my ($conf, $efidisk) = @_;
+
+    my $arch = PVE::QemuServer::Helpers::get_vm_arch($conf);
+    $efidisk //= $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef;
+    my $smm = PVE::QemuServer::Machine::machine_type_is_q35($conf);
+    my $amd_sev_type = get_amd_sev_type($conf);
+    my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type);
+    return -s $ovmf_vars;
+}
+
+sub update_efidisk_size {
+    my ($conf) = @_;
+
+    return if !defined($conf->{efidisk0});
+
+    my $disk = parse_drive('efidisk0', $conf->{efidisk0});
+    $disk->{size} = get_efivars_size($conf);
+    $conf->{efidisk0} = print_drive($disk);
+
+    return;
+}
+
+sub create_efidisk($$$$$$$$) {
+    my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm, $amd_sev_type) = @_;
+
+    my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk, $smm, $amd_sev_type);
+
+    my $vars_size_b = -s $ovmf_vars;
+    my $vars_size = PVE::Tools::convert_size($vars_size_b, 'b' => 'kb');
+    my $volid = PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $fmt, undef, $vars_size);
+    PVE::Storage::activate_volumes($storecfg, [$volid]);
+
+    PVE::QemuServer::QemuImage::convert($ovmf_vars, $volid, $vars_size_b);
+    my $size = PVE::Storage::volume_size_info($storecfg, $volid, 3);
+
+    return ($volid, $size / 1024);
+}
+
+sub print_ovmf_commandline {
+    my ($conf, $storecfg, $vmid, $arch, $q35, $version_guard, $forcecpu) = @_;
+
+    my $cmd = [];
+
+    die "OVMF (UEFI) BIOS is not supported on 32-bit CPU types\n"
+        if !$forcecpu && get_cpu_bitness($conf->{cpu}, $arch) == 32;
+
+    my $amd_sev_type = get_amd_sev_type($conf);
+    if ($amd_sev_type && $amd_sev_type eq 'snp') {
+        if (defined($conf->{efidisk0})) {
+            log_warn("EFI disks are not supported with SEV-SNP and will be ignored");
+        }
+        push $cmd->@*, '-bios', get_ovmf_files($arch, undef, undef, $amd_sev_type);
+    } else {
+        my ($code_drive_str, $var_drive_str) =
+            print_ovmf_drive_commandlines($conf, $storecfg, $vmid, $arch, $q35, $version_guard);
+        push $cmd->@*, '-drive', $code_drive_str;
+        push $cmd->@*, '-drive', $var_drive_str;
+    }
+
+    return $cmd;
+}
+
+1;
diff --git a/src/test/MigrationTest/Shared.pm b/src/test/MigrationTest/Shared.pm
index 0b1ac7a0..e29cd1df 100644
--- a/src/test/MigrationTest/Shared.pm
+++ b/src/test/MigrationTest/Shared.pm
@@ -150,6 +150,10 @@ $qemu_server_module->mock(
     vm_stop_cleanup => sub {
         return;
     },
+);
+
+our $qemu_server_ovmf_module = Test::MockModule->new("PVE::QemuServer::OVMF");
+$qemu_server_ovmf_module->mock(
     get_efivars_size => sub {
         return 128 * 1024;
     },
-- 
2.47.2





More information about the pve-devel mailing list