mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-12-08 08:13:42 +00:00
ovmf: support secure boot with 4m and 4m-ms efidisk types
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@proxmox.com>
This commit is contained in:
parent
a4d5b84c9c
commit
b5099b4f6c
@ -183,7 +183,8 @@ my $create_disks = sub {
|
|||||||
|
|
||||||
my $volid;
|
my $volid;
|
||||||
if ($ds eq 'efidisk0') {
|
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') {
|
} elsif ($ds eq 'tpmstate0') {
|
||||||
# swtpm can only use raw volumes, and uses a fixed size
|
# swtpm can only use raw volumes, and uses a fixed size
|
||||||
$size = PVE::Tools::convert_size(PVE::QemuServer::Drive::TPMSTATE_DISK_SIZE, 'b' => 'kb');
|
$size = PVE::Tools::convert_size(PVE::QemuServer::Drive::TPMSTATE_DISK_SIZE, 'b' => 'kb');
|
||||||
|
|||||||
@ -63,14 +63,26 @@ eval {
|
|||||||
|
|
||||||
my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/';
|
my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/';
|
||||||
my $OVMF = {
|
my $OVMF = {
|
||||||
x86_64 => [
|
x86_64 => {
|
||||||
"$EDK2_FW_BASE/OVMF_CODE.fd",
|
'4m' => [
|
||||||
"$EDK2_FW_BASE/OVMF_VARS.fd"
|
"$EDK2_FW_BASE/OVMF_CODE_4M.secboot.fd",
|
||||||
],
|
"$EDK2_FW_BASE/OVMF_VARS_4M.fd",
|
||||||
aarch64 => [
|
],
|
||||||
"$EDK2_FW_BASE/AAVMF_CODE.fd",
|
'4m-ms' => [
|
||||||
"$EDK2_FW_BASE/AAVMF_VARS.fd"
|
"$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();
|
my $cpuinfo = PVE::ProcFSTools::read_cpuinfo();
|
||||||
@ -3140,13 +3152,18 @@ sub get_vm_machine {
|
|||||||
return $machine;
|
return $machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_ovmf_files($) {
|
sub get_ovmf_files($$) {
|
||||||
my ($arch) = @_;
|
my ($arch, $efidisk) = @_;
|
||||||
|
|
||||||
my $ovmf = $OVMF->{$arch}
|
my $types = $OVMF->{$arch}
|
||||||
or die "no OVMF images known for architecture '$arch'\n";
|
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 = {
|
my $Arch2Qemu = {
|
||||||
@ -3405,13 +3422,17 @@ sub config_to_command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($conf->{bios} && $conf->{bios} eq 'ovmf') {
|
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;
|
die "uefi base image '$ovmf_code' not found\n" if ! -f $ovmf_code;
|
||||||
|
|
||||||
my ($path, $format);
|
my ($path, $format);
|
||||||
my $read_only_str = '';
|
my $read_only_str = '';
|
||||||
if (my $efidisk = $conf->{efidisk0}) {
|
if ($d) {
|
||||||
my $d = parse_drive('efidisk0', $efidisk);
|
|
||||||
my ($storeid, $volname) = PVE::Storage::parse_volume_id($d->{file}, 1);
|
my ($storeid, $volname) = PVE::Storage::parse_volume_id($d->{file}, 1);
|
||||||
$format = $d->{format};
|
$format = $d->{format};
|
||||||
if ($storeid) {
|
if ($storeid) {
|
||||||
@ -7516,7 +7537,8 @@ sub qemu_use_old_bios_files {
|
|||||||
sub get_efivars_size {
|
sub get_efivars_size {
|
||||||
my ($conf) = @_;
|
my ($conf) = @_;
|
||||||
my $arch = get_vm_arch($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;
|
die "uefi vars image '$ovmf_vars' not found\n" if ! -f $ovmf_vars;
|
||||||
return -s $ovmf_vars;
|
return -s $ovmf_vars;
|
||||||
}
|
}
|
||||||
@ -7541,10 +7563,10 @@ sub update_tpmstate_size {
|
|||||||
$conf->{tpmstate0} = print_drive($disk);
|
$conf->{tpmstate0} = print_drive($disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub create_efidisk($$$$$) {
|
sub create_efidisk($$$$$$) {
|
||||||
my ($storecfg, $storeid, $vmid, $fmt, $arch) = @_;
|
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;
|
die "EFI vars default image not found\n" if ! -f $ovmf_vars;
|
||||||
|
|
||||||
my $vars_size_b = -s $ovmf_vars;
|
my $vars_size_b = -s $ovmf_vars;
|
||||||
|
|||||||
@ -306,6 +306,26 @@ my $virtiodesc = {
|
|||||||
};
|
};
|
||||||
PVE::JSONSchema::register_standard_option("pve-qm-virtio", $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 = {
|
my $efidisk_fmt = {
|
||||||
volume => { alias => 'file' },
|
volume => { alias => 'file' },
|
||||||
file => {
|
file => {
|
||||||
@ -323,6 +343,7 @@ my $efidisk_fmt = {
|
|||||||
description => "Disk size. This is purely informational and has no effect.",
|
description => "Disk size. This is purely informational and has no effect.",
|
||||||
optional => 1,
|
optional => 1,
|
||||||
},
|
},
|
||||||
|
%efitype_fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
my $efidisk_desc = {
|
my $efidisk_desc = {
|
||||||
@ -382,6 +403,7 @@ my $alldrive_fmt = {
|
|||||||
%ssd_fmt,
|
%ssd_fmt,
|
||||||
%wwn_fmt,
|
%wwn_fmt,
|
||||||
%tpmversion_fmt,
|
%tpmversion_fmt,
|
||||||
|
%efitype_fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
my $unused_fmt = {
|
my $unused_fmt = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user