[pve-devel] [PATCH qemu-server] ovmf: support secure boot with 4m and 4m-ms efidisk types
Stefan Reiter
s.reiter at proxmox.com
Tue Oct 5 18:02:42 CEST 2021
Provide support for secure boot by using the new "4m" and "4m-ms"
variants of the OVMF code/vars templates. This is specified on the
efidisk via the 'efitype' and 'ms-keys' parameters.
Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
Should depend on updated pve-edk2-firmware.
PVE/API2/Qemu.pm | 3 ++-
PVE/QemuServer.pm | 60 ++++++++++++++++++++++++++++-------------
PVE/QemuServer/Drive.pm | 22 +++++++++++++++
3 files changed, 65 insertions(+), 20 deletions(-)
diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 367d6ca..cc2a543 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -183,7 +183,8 @@ my $create_disks = sub {
my $volid;
if ($ds eq 'efidisk0') {
- ($volid, $size) = PVE::QemuServer::create_efidisk($storecfg, $storeid, $vmid, $fmt, $arch);
+ ($volid, $size) = PVE::QemuServer::create_efidisk(
+ $storecfg, $storeid, $vmid, $fmt, $arch, $disk);
} elsif ($ds eq 'tpmstate0') {
# swtpm can only use raw volumes, and uses a fixed size
$size = PVE::Tools::convert_size(PVE::QemuServer::Drive::TPMSTATE_DISK_SIZE, 'b' => 'kb');
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 076ce59..3c0ecf5 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -63,14 +63,26 @@ eval {
my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/';
my $OVMF = {
- x86_64 => [
- "$EDK2_FW_BASE/OVMF_CODE.fd",
- "$EDK2_FW_BASE/OVMF_VARS.fd"
- ],
- aarch64 => [
- "$EDK2_FW_BASE/AAVMF_CODE.fd",
- "$EDK2_FW_BASE/AAVMF_VARS.fd"
- ],
+ x86_64 => {
+ '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",
+ ],
+ 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();
@@ -3140,13 +3152,18 @@ sub get_vm_machine {
return $machine;
}
-sub get_ovmf_files($) {
- my ($arch) = @_;
+sub get_ovmf_files($$) {
+ my ($arch, $efidisk) = @_;
- my $ovmf = $OVMF->{$arch}
+ my $types = $OVMF->{$arch}
or die "no OVMF images known for architecture '$arch'\n";
- return @$ovmf;
+ my $type = 'default';
+ if (defined($efidisk->{efitype}) && $efidisk->{efitype} eq '4m') {
+ $type = $efidisk->{'ms-keys'} ? "4m-ms" : "4m";
+ }
+
+ return $types->{$type}->@*;
}
my $Arch2Qemu = {
@@ -3405,13 +3422,17 @@ sub config_to_command {
}
if ($conf->{bios} && $conf->{bios} eq 'ovmf') {
- my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch);
+ my $d;
+ if (my $efidisk = $conf->{efidisk0}) {
+ $d = parse_drive('efidisk0', $efidisk);
+ }
+
+ my ($ovmf_code, $ovmf_vars) = get_ovmf_files($arch, $d);
die "uefi base image '$ovmf_code' not found\n" if ! -f $ovmf_code;
my ($path, $format);
my $read_only_str = '';
- if (my $efidisk = $conf->{efidisk0}) {
- my $d = parse_drive('efidisk0', $efidisk);
+ if ($d) {
my ($storeid, $volname) = PVE::Storage::parse_volume_id($d->{file}, 1);
$format = $d->{format};
if ($storeid) {
@@ -7516,7 +7537,8 @@ sub qemu_use_old_bios_files {
sub get_efivars_size {
my ($conf) = @_;
my $arch = get_vm_arch($conf);
- my (undef, $ovmf_vars) = get_ovmf_files($arch);
+ my $efidisk = $conf->{efidisk0} ? parse_drive('efidisk0', $conf->{efidisk0}) : undef;
+ my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk);
die "uefi vars image '$ovmf_vars' not found\n" if ! -f $ovmf_vars;
return -s $ovmf_vars;
}
@@ -7541,10 +7563,10 @@ sub update_tpmstate_size {
$conf->{tpmstate0} = print_drive($disk);
}
-sub create_efidisk($$$$$) {
- my ($storecfg, $storeid, $vmid, $fmt, $arch) = @_;
+sub create_efidisk($$$$$$) {
+ my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk) = @_;
- my (undef, $ovmf_vars) = get_ovmf_files($arch);
+ my (undef, $ovmf_vars) = get_ovmf_files($arch, $efidisk);
die "EFI vars default image not found\n" if ! -f $ovmf_vars;
my $vars_size_b = -s $ovmf_vars;
diff --git a/PVE/QemuServer/Drive.pm b/PVE/QemuServer/Drive.pm
index 6389dbb..57d26f5 100644
--- a/PVE/QemuServer/Drive.pm
+++ b/PVE/QemuServer/Drive.pm
@@ -306,6 +306,26 @@ my $virtiodesc = {
};
PVE::JSONSchema::register_standard_option("pve-qm-virtio", $virtiodesc);
+my %efitype_fmt = (
+ efitype => {
+ type => 'string',
+ enum => [qw(2m 4m)],
+ description => "Size and type of the OVMF EFI vars. '4m' is newer and recommended,"
+ . " and required for Secure Boot. For backwards compatibility, '2m' is used"
+ . " if not otherwise specified.",
+ optional => 1,
+ default => '2m',
+ },
+ 'ms-keys' => {
+ type => 'boolean',
+ description => "Pre-enroll the Microsoft Standard UEFI Secure Boot keys if"
+ . " used with 'efitype=4m'. Note that this will enable Secure Boot by"
+ . " default, though it can still be turned off from within the VM.",
+ optional => 1,
+ default => 0,
+ },
+);
+
my $efidisk_fmt = {
volume => { alias => 'file' },
file => {
@@ -323,6 +343,7 @@ my $efidisk_fmt = {
description => "Disk size. This is purely informational and has no effect.",
optional => 1,
},
+ %efitype_fmt,
};
my $efidisk_desc = {
@@ -382,6 +403,7 @@ my $alldrive_fmt = {
%ssd_fmt,
%wwn_fmt,
%tpmversion_fmt,
+ %efitype_fmt,
};
my $unused_fmt = {
--
2.30.2
More information about the pve-devel
mailing list