public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
	Fiona Ebner <f.ebner@proxmox.com>
Subject: Re: [pve-devel] [PATCH qemu-server 07/15] introduce OVMF module
Date: Tue, 24 Jun 2025 12:23:19 +0200 (CEST)	[thread overview]
Message-ID: <913437457.7163.1750760599763@webmail.proxmox.com> (raw)
In-Reply-To: <20250623154433.449277-8-f.ebner@proxmox.com>


> Fiona Ebner <f.ebner@proxmox.com> hat am 23.06.2025 17:44 CEST geschrieben:

some small nits/questions inline..

> Signed-off-by: Fiona Ebner <f.ebner@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);

we could change this to pass in $amd_sev_type (+ some other things, or leave a wrapper around it
in PVE::QemuServer, see below)

> +                        }
>  
>                          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,

since we already get and pass $amd_sev_type here

>                      );
>                  } 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)

would need to update this

>                          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)

and this as well though

>                      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);

this already returns immediately if no efidisk is defined, so we
could drop the surrounding if here? this is also the only call site,
and we already do plenty of parsing and printing of drives here,
so maybe we could even inline it instead - the only OVMF specific
thing is a call to get_efivars_size

>      }
>  
>      # 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 we keep this

> -        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,

and pass it here (maybe combine amd_sev, forcecpu, smm and q35 into an options hash)?

> +        );
> +        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;

and maybe move just the last two lines here to OVMF.pm, but leave the $conf to options hash part
here for the call above and for other calls to get_efivars_size ?

> -}
> -
> -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);

then we could get rid of this import here. get_cpu_bitness is only used
in one place as well, so we could get of that as well..

the entanglement right now is small, but these things tend to grow over
time..

> +use PVE::QemuServer::Helpers;

only used for determining the arch in get_efivars_size

> +use PVE::QemuServer::Machine;

this one's only used to determine whether the config is q35 in
get_efivars_size, could maybe also be moved to the call site?

so these three use statements could maybe be left in PVE::QemuServer..

> +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
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  reply	other threads:[~2025-06-24 10:23 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-23 15:44 [pve-devel] [PATCH-SERIES qemu-server 00/15] preparation for blockdev, part two Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 01/15] fix #5985: qmp client: increase timeout for {device, netdev, object}_{add, del} commands Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 02/15] qmp client: add default timeouts for more blockdev commands Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 03/15] helpers: add missing includes Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 04/15] helpers: fix perlcritic warning about variables named $a and $b Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 05/15] move helper for iscsi initiator name to helpers module and improve name Fiona Ebner
2025-06-24  9:48   ` Fabian Grünbichler
2025-06-24 10:05     ` Fiona Ebner
2025-06-24 10:10       ` Fabian Grünbichler
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 06/15] introduce QemuImage module Fiona Ebner
2025-06-25 12:54   ` Daniel Kral
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 07/15] introduce OVMF module Fiona Ebner
2025-06-24 10:23   ` Fabian Grünbichler [this message]
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 08/15] blockdev: re-use cache setting from child node Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 09/15] blockdev: add workaround for issue #3229 Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 10/15] blockdev: add support for 'size' option Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 11/15] ovmf: add support for using blockdev Fiona Ebner
2025-06-24  8:38   ` Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [PATCH qemu-server 12/15] cfg2cmd: ovmf: support print_ovmf_commandline() returning machine flags Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [RFC qemu-server 13/15] print drive device: don't reference any drive for 'none' starting with machine version 10.0 Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [RFC qemu-server 14/15] blockdev: add support for NBD paths Fiona Ebner
2025-06-23 15:44 ` [pve-devel] [RFC qemu-server 15/15] command line: switch to blockdev starting with machine version 10.0 Fiona Ebner
2025-06-24 13:53   ` DERUMIER, Alexandre via pve-devel
2025-06-24 14:34     ` Fiona Ebner
2025-06-24 14:41       ` DERUMIER, Alexandre via pve-devel
2025-06-25 11:31       ` DERUMIER, Alexandre via pve-devel
     [not found]       ` <f3d01b2976480800cfa294cf888534aebadec067.camel@groupe-cyllene.com>
2025-06-25 15:42         ` Fiona Ebner
2025-06-24  9:40 ` [pve-devel] [PATCH-SERIES qemu-server 00/15] preparation for blockdev, part two DERUMIER, Alexandre via pve-devel
2025-06-24  9:59   ` Fiona Ebner
2025-06-24 11:25     ` DERUMIER, Alexandre via pve-devel
2025-06-24 11:44 ` [pve-devel] partially-applied: " Fabian Grünbichler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=913437457.7163.1750760599763@webmail.proxmox.com \
    --to=f.gruenbichler@proxmox.com \
    --cc=f.ebner@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal