From 7ece048f90223e395001f9fc158c5c2af35ca520 Mon Sep 17 00:00:00 2001 From: Vasiliy Ulyanov Date: Wed, 10 Jul 2024 10:27:15 +0200 Subject: [PATCH] Ensure SEV VMs use stateless OVMF firmware Signed-off-by: Vasiliy Ulyanov Signed-off-by: Caleb Crane --- .../virtwrap/converter/converter.go | 20 ++++++++++++------- pkg/virt-launcher/virtwrap/efi/efi.go | 11 ++++------ pkg/virt-launcher/virtwrap/efi/efi_test.go | 8 +------- rpm/BUILD.bazel | 2 +- 4 files changed, 19 insertions(+), 22 deletions(-) Index: kubevirt-1.5.2/pkg/virt-launcher/virtwrap/converter/converter.go =================================================================== --- kubevirt-1.5.2.orig/pkg/virt-launcher/virtwrap/converter/converter.go +++ kubevirt-1.5.2/pkg/virt-launcher/virtwrap/converter/converter.go @@ -1180,6 +1180,12 @@ func Convert_v1_Firmware_To_related_apis Template: c.EFIConfiguration.EFIVars, NVRam: filepath.Join(services.PathForNVram(vmi), vmi.Name+"_VARS.fd"), } + + if util.IsSEVVMI(vmi) { + // Use stateless firmware for SEV VMs + domain.Spec.OS.BootLoader.Type = "rom" + domain.Spec.OS.NVRam = nil + } } if firmware.Bootloader != nil && firmware.Bootloader.BIOS != nil { @@ -1448,13 +1454,13 @@ func Convert_v1_VirtualMachineInstance_T // Set SEV launch security parameters: https://libvirt.org/formatdomain.html#launch-security if c.UseLaunchSecurity { - sevPolicyBits := launchsecurity.SEVPolicyToBits(vmi.Spec.Domain.LaunchSecurity.SEV.Policy) - // Cbitpos and ReducedPhysBits will be filled automatically by libvirt from the domain capabilities - domain.Spec.LaunchSecurity = &api.LaunchSecurity{ - Type: "sev", - Policy: "0x" + strconv.FormatUint(uint64(sevPolicyBits), 16), - DHCert: vmi.Spec.Domain.LaunchSecurity.SEV.DHCert, - Session: vmi.Spec.Domain.LaunchSecurity.SEV.Session, + sevPolicyBits := launchsecurity.SEVPolicyToBits(vmi.Spec.Domain.LaunchSecurity.SEV.Policy) + // Cbitpos and ReducedPhysBits will be filled automatically by libvirt from the domain capabilities + domain.Spec.LaunchSecurity = &api.LaunchSecurity{ + Type: "sev", + Policy: "0x" + strconv.FormatUint(uint64(sevPolicyBits), 16), + DHCert: vmi.Spec.Domain.LaunchSecurity.SEV.DHCert, + Session: vmi.Spec.Domain.LaunchSecurity.SEV.Session, } controllerDriver = &api.ControllerDriver{ IOMMU: "on", Index: kubevirt-1.5.2/pkg/virt-launcher/virtwrap/efi/efi.go =================================================================== --- kubevirt-1.5.2.orig/pkg/virt-launcher/virtwrap/efi/efi.go +++ kubevirt-1.5.2/pkg/virt-launcher/virtwrap/efi/efi.go @@ -31,8 +31,7 @@ const ( EFIVarsAARCH64 = "AAVMF_VARS.fd" EFICodeSecureBoot = "OVMF_CODE.secboot.fd" EFIVarsSecureBoot = "OVMF_VARS.secboot.fd" - EFICodeSEV = "OVMF_CODE.cc.fd" - EFIVarsSEV = EFIVars + EFICodeSEV = "OVMF.amdsev.fd" ) type EFIEnvironment struct { @@ -41,14 +40,13 @@ type EFIEnvironment struct { codeSecureBoot string varsSecureBoot string codeSEV string - varsSEV string } func (e *EFIEnvironment) Bootable(secureBoot, sev bool) bool { if secureBoot { return e.varsSecureBoot != "" && e.codeSecureBoot != "" } else if sev { - return e.varsSEV != "" && e.codeSEV != "" + return e.codeSEV != "" } else { return e.vars != "" && e.code != "" } @@ -68,7 +66,8 @@ func (e *EFIEnvironment) EFIVars(secureB if secureBoot { return e.varsSecureBoot } else if sev { - return e.varsSEV + // SEV uses stateless firmware + return "" } else { return e.vars } @@ -100,7 +99,6 @@ func DetectEFIEnvironment(arch, ovmfPath // detect EFI with SEV codeWithSEV := getEFIBinaryIfExists(ovmfPath, EFICodeSEV) - varsWithSEV := getEFIBinaryIfExists(ovmfPath, EFIVarsSEV) return &EFIEnvironment{ codeSecureBoot: codeWithSB, @@ -108,7 +106,6 @@ func DetectEFIEnvironment(arch, ovmfPath code: code, vars: vars, codeSEV: codeWithSEV, - varsSEV: varsWithSEV, } } Index: kubevirt-1.5.2/pkg/virt-launcher/virtwrap/efi/efi_test.go =================================================================== --- kubevirt-1.5.2.orig/pkg/virt-launcher/virtwrap/efi/efi_test.go +++ kubevirt-1.5.2/pkg/virt-launcher/virtwrap/efi/efi_test.go @@ -82,7 +82,7 @@ var _ = Describe("EFI environment detect ) It("SEV EFI Roms", func() { - ovmfPath := createEFIRoms(EFICodeSEV, EFIVarsSEV) + ovmfPath := createEFIRoms(EFICodeSEV) defer os.RemoveAll(ovmfPath) efiEnv := DetectEFIEnvironment("x86_64", ovmfPath) @@ -98,11 +98,5 @@ var _ = Describe("EFI environment detect Expect(efiEnv.EFICode(secureBootEnabled, !sevEnabled)).ToNot(Equal(codeSEV)) Expect(efiEnv.EFICode(!secureBootEnabled, sevEnabled)).To(Equal(codeSEV)) Expect(efiEnv.EFICode(!secureBootEnabled, !sevEnabled)).ToNot(Equal(codeSEV)) - - varsSEV := filepath.Join(ovmfPath, EFIVarsSEV) - Expect(efiEnv.EFIVars(secureBootEnabled, sevEnabled)).ToNot(Equal(varsSEV)) - Expect(efiEnv.EFIVars(secureBootEnabled, !sevEnabled)).ToNot(Equal(varsSEV)) - Expect(efiEnv.EFIVars(!secureBootEnabled, sevEnabled)).To(Equal(varsSEV)) - Expect(efiEnv.EFIVars(!secureBootEnabled, !sevEnabled)).To(Equal(varsSEV)) // same as EFIVars }) }) Index: kubevirt-1.5.2/rpm/BUILD.bazel =================================================================== --- kubevirt-1.5.2.orig/rpm/BUILD.bazel +++ kubevirt-1.5.2/rpm/BUILD.bazel @@ -1231,7 +1231,7 @@ rpmtree( "/usr/sbin/iptables": "/usr/sbin/iptables-legacy", "/usr/bin/nc": "/usr/bin/ncat", # Create a symlink to OVMF binary with SEV support (edk2 rpm does not do that for unknown reason) - "/usr/share/OVMF/OVMF_CODE.cc.fd": "../edk2/ovmf/OVMF_CODE.cc.fd", + "/usr/share/OVMF/OVMF.amdsev.fd": "../edk2/ovmf/OVMF.amdsev.fd", }, visibility = ["//visibility:public"], )