diff --git a/component_versions/version_map.yml b/component_versions/version_map.yml index f1dd5cd5b3..ee322375d1 100644 --- a/component_versions/version_map.yml +++ b/component_versions/version_map.yml @@ -1,6 +1,6 @@ firmware: qemu: 9.2.0 libvirt: 10.9.0 - edk2: stable202411 + edk2: stable202502 package: swtpm: 0.10.0 diff --git a/images/edk2/build.sh b/images/edk2/build.sh index 18bb70f939..07173120a3 100755 --- a/images/edk2/build.sh +++ b/images/edk2/build.sh @@ -28,6 +28,13 @@ EOF exit 0 } +echo_dbg() { + local str=$1 + echo "" + echo "===$str===" + echo "" +} + parse_args() { while [[ $# -gt 0 ]]; do case "$1" in @@ -81,22 +88,13 @@ fi EDK2_DIR="/${gitRepoName}-${edk2Branch}" FIRMWARE="/FIRMWARE" -mv -f Logo.bmp $EDK2_DIR/MdeModulePkg/Logo/ +mv -f /Logo.bmp $EDK2_DIR/MdeModulePkg/Logo/ echo "=== cd $EDK2_DIR ===" -cd $EDK2_DIR -echo "= pwd =" -pwd +cd $EDK2_DIR mkdir -p ${FIRMWARE} -echo_dbg() { - local str=$1 - echo "" - echo "===$str===" - echo "" -} - # compiler CC_FLAGS="-t GCC5" CC_FLAGS="${CC_FLAGS} -b RELEASE" @@ -109,7 +107,6 @@ CC_FLAGS="${CC_FLAGS} -D TPM1_ENABLE=FALSE" CC_FLAGS="${CC_FLAGS} -D CAVIUM_ERRATUM_27456=TRUE" # ovmf features -OVMF_2M_FLAGS="${CC_FLAGS} -D FD_SIZE_2MB=TRUE -D NETWORK_TLS_ENABLE=FALSE -D NETWORK_ISCSI_ENABLE=FALSE" OVMF_4M_FLAGS="${CC_FLAGS} -D FD_SIZE_4MB=TRUE -D NETWORK_TLS_ENABLE=TRUE -D NETWORK_ISCSI_ENABLE=TRUE" # secure boot features @@ -117,10 +114,11 @@ OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SECURE_BOOT_ENABLE=TRUE" OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D SMM_REQUIRE=TRUE" OVMF_SB_FLAGS="${OVMF_SB_FLAGS} -D EXCLUDE_SHELL_FROM_FD=TRUE -D BUILD_SHELL=FALSE" -# unset MAKEFLAGS -echo "run source edksetup.sh" -source ./edksetup.sh BaseTools -source ./edksetup.sh +if ! command -v build 2>&1 >/dev/null +then + echo "build could not be found" + exit 1 +fi build_iso() { dir="$1" @@ -156,42 +154,107 @@ build_iso() { -o "$ISO_IMAGE" "$UEFI_SHELL_IMAGE" } +prep() { + build -a X64 -p MdeModulePkg/MdeModulePkg.dsc -t GCC5 -b RELEASE +} + # Build with SB and SMM; exclude UEFI shell. + build_ovmf() { - echo_dbg "build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc" - build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc - cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.fd - cp -p Build/OvmfX64/*/FV/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.fd + # echo_dbg "build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc" + build -a X64 \ + -t GCC5 \ + -p OvmfPkg/OvmfPkgX64.dsc \ + -DCC_MEASUREMENT_ENABLE=TRUE -DNETWORK_HTTP_BOOT_ENABLE=TRUE -DNETWORK_IP6_ENABLE=TRUE -DNETWORK_TLS_ENABLE --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" --pcd PcdFirmwareVersionString=L"2025.02-1\\0" --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" -DTPM2_ENABLE=TRUE -DFD_SIZE_4MB -b RELEASE + cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.fd + cp -p Build/OvmfX64/*/FV/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.fd + rm -rf Build/OvmfX64 + # build ${OVMF_4M_FLAGS} \ + # -a X64 -p OvmfPkg/OvmfPkgX64.dsc \ + # -DCC_MEASUREMENT_ENABLE=TRUE \ + # --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" \ + # --pcd PcdFirmwareVersionString=L"2025.02-1\\0" \ + # --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" + + # cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.fd + # cp -p Build/OvmfX64/*/FV/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.fd } # Build with SB and SMM with secure boot; exclude UEFI shell. build_ovmf_secboot() { - echo_dbg "build ${OVMF_4M_FLAGS} ${OVMF_SB_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc" - build ${OVMF_4M_FLAGS} ${OVMF_SB_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc - cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.secboot.fd + # echo_dbg "build ${OVMF_4M_FLAGS} ${OVMF_SB_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc" + build -a X64 \ + -t GCC5 \ + -b RELEASE \ + -p OvmfPkg/OvmfPkgX64.dsc \ + -DCC_MEASUREMENT_ENABLE=TRUE \ + -DNETWORK_HTTP_BOOT_ENABLE=TRUE \ + -DNETWORK_IP6_ENABLE=TRUE \ + -DNETWORK_TLS_ENABLE \ + -DTPM_ENABLE=TRUE \ + -DTPM2_ENABLE=TRUE \ + -DFD_SIZE_4MB \ + -DBUILD_SHELL=FALSE \ + -DSECURE_BOOT_ENABLE=TRUE \ + -DSMM_REQUIRE=TRUE \ + --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" \ + --pcd PcdFirmwareVersionString=L"2025.02-1\\0" \ + --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" + + cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.secboot.fd + cp -p Build/OvmfX64/*/FV/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.secboot.fd + rm -rf Build/OvmfX64 + # cp -p Build/OvmfX64/*/X64/EnrollDefaultKeys.efi $FIRMWARE/ + # cp -p Build/OvmfX64/*/X64/Shell.efi $FIRMWARE/ + # build ${OVMF_4M_FLAGS} ${OVMF_SB_FLAGS} \ + # -a X64 -p OvmfPkg/OvmfPkgX64.dsc \ + # --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" \ + # --pcd PcdFirmwareVersionString=L"2025.02-1\\0" \ + # --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" + + # cp -p Build/OvmfX64/*/FV/OVMF_CODE.fd $FIRMWARE/OVMF_CODE.secboot.fd + # cp -p Build/OvmfX64/*/FV/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.secboot.fd + # cp -p Build/OvmfX64/*/X64/EnrollDefaultKeys.efi $FIRMWARE/ + # cp -p Build/OvmfX64/*/X64/Shell.efi $FIRMWARE/ } # Build AmdSev and IntelTdx variants build_ovmf_amdsev() { touch OvmfPkg/AmdSev/Grub/grub.efi - echo_dbg "build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/AmdSev/AmdSevX64.dsc" - build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/AmdSev/AmdSevX64.dsc + build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/AmdSev/AmdSevX64.dsc \ + --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" \ + --pcd PcdFirmwareVersionString=L"2025.02-1\\0" \ + --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" + cp -p Build/AmdSev/*/FV/OVMF.fd $FIRMWARE/OVMF.amdsev.fd +} - echo_dbg "build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/IntelTdx/IntelTdxX64.dsc" - build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/IntelTdx/IntelTdxX64.dsc +build_ovmf_inteltdx() { + build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/IntelTdx/IntelTdxX64.dsc \ + --pcd PcdFirmwareVendor=L"DVP distribution of EDK II\\0" \ + --pcd PcdFirmwareVersionString=L"2025.02-1\\0" \ + --pcd PcdFirmwareReleaseDateString=L"03/02/2025\\0" cp -p Build/IntelTdx/*/FV/OVMF.fd $FIRMWARE/OVMF.inteltdx.fd + rm -rf Build/IntelTdx } +build_EnrollDefaultKeys() { + build ${OVMF_4M_FLAGS} -a X64 -p OvmfPkg/OvmfPkgX64.dsc -D ENROLL_DEFAULT_KEYS + cp Build/OvmfX64/*/X64/EnrollDefaultKeys.efi $FIRMWARE/ + rm -rf Build/OvmfX64 +} # Build ovmf (x64) shell iso with EnrollDefaultKeys build_shell() { echo_dbg "build shell" build ${OVMF_4M_FLAGS} -a X64 -p ShellPkg/ShellPkg.dsc - build ${OVMF_4M_FLAGS} -a IA32 -p ShellPkg/ShellPkg.dsc + + cp Build/Shell/*/X64/Shell.efi $$FIRMWARE/ + rm -rf Build/Shell + # build ${OVMF_4M_FLAGS} -a IA32 -p ShellPkg/ShellPkg.dsc - cp -p Build/Shell/*/X64/ShellPkg/Application/Shell/Shell/OUTPUT/Shell.efi $FIRMWARE/ - cp -p Build/OvmfX64/*/X64/EnrollDefaultKeys.efi $FIRMWARE/ + # cp -p Build/Shell/*/X64/ShellPkg/Application/Shell/Shell/OUTPUT/Shell.efi $FIRMWARE/ + # cp -p Build/OvmfX64/*/X64/EnrollDefaultKeys.efi $FIRMWARE/ } @@ -199,23 +262,56 @@ enroll() { virt-fw-vars --input $FIRMWARE/OVMF_VARS.fd \ --output $FIRMWARE/OVMF_VARS.secboot.fd \ --set-dbx $FIRMWARE/DBXUpdate-20230509.x64.bin \ - --secure-boot + --secure-boot \ + --enroll-altlinux + # --enroll-generate dvp.deckhouse.io virt-fw-vars --input $FIRMWARE/OVMF.inteltdx.fd \ --output $FIRMWARE/OVMF.inteltdx.secboot.fd \ --set-dbx $FIRMWARE/DBXUpdate-20230509.x64.bin \ - --secure-boot + --secure-boot \ + --enroll-altlinux + # --enroll-generate dvp.deckhouse.io } +# no sec boot but makes json happy no_enroll() { cp -p $FIRMWARE/OVMF_VARS.fd $FIRMWARE/OVMF_VARS.secboot.fd cp -p $FIRMWARE/OVMF.inteltdx.fd $FIRMWARE/OVMF.inteltdx.secboot.fd } + +echo_dbg "prep" +prep 2>&1 > /dev/null + +echo_dbg "build_ovmf" build_ovmf 2>&1 > /dev/null + +echo_dbg "build_ovmf_secboot" build_ovmf_secboot 2>&1 > /dev/null + +echo_dbg "build_ovmf_amdsev" build_ovmf_amdsev 2>&1 > /dev/null + +echo_dbg "build_ovmf_inteltdx" +build_ovmf_inteltdx 2>&1 > /dev/null + +echo_dbg "build_EnrollDefaultKeys" +build_EnrollDefaultKeys 2>&1 > /dev/null + +echo_dbg "build_shell" build_shell 2>&1 > /dev/null build_iso $FIRMWARE -no_enroll +enroll + +ls -la $FIRMWARE + +# no_enroll + +# echo_dbg "run edk2-vars-generator.py" +# /edk2-vars-generator.py -d \ +# -f OVMF_4M -e $FIRMWARE/EnrollDefaultKeys.efi -s $FIRMWARE/Shell.efi \ +# -c $FIRMWARE/OVMF_CODE.secboot.fd \ +# -V $FIRMWARE/OVMF_VARS.fd \ +# -C `< debian/oem-string-vendor` -o $FIRMWARE/OVMF_VARS.ms.fd \ No newline at end of file diff --git a/images/edk2/edk2-vars-generator.py b/images/edk2/edk2-vars-generator.py new file mode 100755 index 0000000000..c598a656ed --- /dev/null +++ b/images/edk2/edk2-vars-generator.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 + +# Copyright 2024 Flant JSC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Copyright 2021 Canonical Ltd. +# Authors: +# - dann frazier + + +import argparse +import os.path +import pexpect +import shutil +import sys +from UEFI.Filesystems import FatFsImage, EfiBootableIsoImage +from UEFI.Qemu import QemuEfiMachine, QemuEfiVariant, QemuEfiFlashSize +from UEFI import Qemu + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + "-f", "--flavor", help="UEFI Flavor", + choices=['AAVMF', 'OVMF', 'OVMF_4M'], + required=True, + ) + parser.add_argument( + "-e", "--enrolldefaultkeys", + help='Path to "EnrollDefaultKeys" EFI binary', + required=True, + ) + parser.add_argument( + "-s", "--shell", + help='Path to "Shell" EFI binary', + required=True, + ) + parser.add_argument( + "-C", "--certificate", + help='base64-encoded PK/KEK1 certificate', + required=True, + ) + parser.add_argument( + "-c", "--code", + help='UEFI code image', + required=True, + ) + parser.add_argument( + "--no-default", + action="store_true", + help='Do not enroll the default keys, just the PK/KEK1 certificate', + ) + parser.add_argument( + "-V", "--vars-template", + help='UEFI vars template', + required=True, + ) + parser.add_argument( + "-o", "--out-file", + help="Output file for generated vars template", + required=True, + ) + parser.add_argument("-d", "--debug", action="store_true", + help="Emit debug messages") + args = parser.parse_args() + + FlavorConfig = { + 'AAVMF': { + 'EfiArch': 'AA64', + 'QemuCommand': Qemu.QemuCommand( + QemuEfiMachine.AAVMF, + code_path=args.code, + vars_template_path=args.vars_template, + ), + }, + 'OVMF': { + 'EfiArch': 'X64', + 'QemuCommand': Qemu.QemuCommand( + QemuEfiMachine.OVMF_Q35, + variant=QemuEfiVariant.SECBOOT, + flash_size=QemuEfiFlashSize.SIZE_4MB, + code_path=args.code, + vars_template_path=args.vars_template, + ), + }, + 'OVMF_4M': { + 'EfiArch': 'X64', + 'QemuCommand': Qemu.QemuCommand( + QemuEfiMachine.OVMF_Q35, + variant=QemuEfiVariant.SECBOOT, + flash_size=QemuEfiFlashSize.SIZE_4MB, + code_path=args.code, + vars_template_path=args.vars_template, + ), + }, + } + + eltorito = FatFsImage(64) + eltorito.makedirs(os.path.join('EFI', 'BOOT')) + removable_media_path = os.path.join( + 'EFI', 'BOOT', f"BOOT{FlavorConfig[args.flavor]['EfiArch']}.EFI" + ) + eltorito.insert_file(args.shell, removable_media_path) + eltorito.insert_file( + args.enrolldefaultkeys, + args.enrolldefaultkeys.split(os.path.sep)[-1] + ) + iso = EfiBootableIsoImage(eltorito) + + q = FlavorConfig[args.flavor]['QemuCommand'] + q.add_disk(iso.path) + q.add_oem_string(11, args.certificate) + + child = pexpect.spawn(' '.join(q.command)) + if args.debug: + child.logfile = sys.stdout.buffer + child.expect(['Press .* or any other key to continue'], timeout=None) + child.sendline('\x1b') + child.expect(['Shell> '], timeout=None) + child.sendline('FS0:\r') + child.expect(['FS0:\\\\> '], timeout=None) + enrollcmd = ['EnrollDefaultKeys.efi'] + if args.no_default: + enrollcmd.append("--no-default") + child.sendline(f'{" ".join(enrollcmd)}\r') + child.expect(['FS0:\\\\> '], timeout=None) + # Clear the BootOrder. See #1015759 + child.sendline('setvar BootOrder =\r') + child.expect(['FS0:\\\\> '], timeout=None) + child.sendline('reset -s\r') + child.wait() + shutil.copy(q.pflash.varfile_path, args.out_file) diff --git a/images/edk2/json/30-edk2-ovmf-x64-sb-enrolled.json b/images/edk2/json/30-edk2-ovmf-x64-sb-enrolled.json new file mode 100644 index 0000000000..74c8c55b3f --- /dev/null +++ b/images/edk2/json/30-edk2-ovmf-x64-sb-enrolled.json @@ -0,0 +1,36 @@ +{ + "description": "OVMF with SB+SMM, SB enabled, MS certs enrolled", + "interface-types": [ + "uefi" + ], + "mapping": { + "device": "flash", + "mode": "split", + "executable": { + "filename": "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd", + "format": "raw" + }, + "nvram-template": { + "filename": "/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd", + "format": "raw" + } + }, + "targets": [ + { + "architecture": "x86_64", + "machines": [ + "pc-q35-*" + ] + } + ], + "features": [ + "acpi-s3", + "enrolled-keys", + "requires-smm", + "secure-boot", + "verbose-dynamic" + ], + "tags": [ + + ] +} \ No newline at end of file diff --git a/images/edk2/patches/0001-OvmfPkg-Use-user-specified-opt-ovmf-X-PciMmio64Mb-va.patch b/images/edk2/patches/0001-OvmfPkg-Use-user-specified-opt-ovmf-X-PciMmio64Mb-va.patch new file mode 100644 index 0000000000..1c715f4f71 --- /dev/null +++ b/images/edk2/patches/0001-OvmfPkg-Use-user-specified-opt-ovmf-X-PciMmio64Mb-va.patch @@ -0,0 +1,93 @@ +From 9ac1704af6645da45d20fb545294e308ef9c887e Mon Sep 17 00:00:00 2001 +From: Mitchell Augustin +Date: Thu, 13 Mar 2025 08:52:03 -0500 +Subject: [PATCH] OvmfPkg: Use user-specified opt/ovmf/X-PciMmio64Mb value + unconditionally + +Prior to this change, OVMF considers opt/ovmf/X-PciMmio64Mb the +minimum aperture size, allowing us to force the window to be larger +but not smaller than what PlatformDynamicMmioWindow calculates. + +Adjust OVMF so that a smaller value for the aperture is honored. + +Context: +Due to an inefficiency in the way older host kernels manage +pfnmaps for guest VM memory ranges [0], guests with large-BAR +GPUs passed-through have a very long (multiple minutes) initialization +time when the MMIO window advertised by OVMF is sufficiently sized for +the passed-through BARs (i.e., the correct OVMF behavior). However, on +older distro series such as Ubuntu Jammy, users have benefited from fast +guest boot times when OVMF advertised an MMIO window that was too small +to accommodate the full BAR, since this resulted in the long PCI initialization +process being skipped (and retried later, if pci=realloc pci=nocrs were set). + +While the root cause is being fully addressed in the upstream kernel [1], +the solution relies on huge pfnmap support, which is a substantial series +with many ABI changes that is unlikely to land in many LTS and legacy distro kernels, +including those of Ubuntu Noble. As a result, the only kernel improvement +supported on those kernels is this patch [2], which reduces the extra boot +time by about half. Unfortunately, that boot time is still an average of +1-3 minutes longer per-VM-boot than what can be achieved when the host is +running a version of OVMF without PlatformDynamicMmioWindow (PDMW) support +(introduced in [3]) + +Since there is no way to force the use of the classic MMIO window size[4] +in any version of OVMF after [3], and since we have a use case for such +functionality on legacy distro kernels that would yield significant, +recurring compute time savings across all impacted VMs, this change to +this knob's behavior seems appropriate. + +[0]: https://lore.kernel.org/all/CAHTA-uYp07FgM6T1OZQKqAdSA5JrZo0ReNEyZgQZub4mDRrV5w@mail.gmail.com/ +[1]: https://lore.kernel.org/all/20250205231728.2527186-1-alex.williamson@redhat.com/ +[2]: https://lore.kernel.org/all/20250111210652.402845-1-alex.williamson@redhat.com/ +[3]: ecb778d +[4]: https://edk2.groups.io/g/devel/topic/109651206?p=Created,,,20,1,0,0 + +Signed-off-by: Mitchell Augustin + +Bug-Ubuntu: https://launchpad.net/bugs/2101903 +Last-Update: 2025-03-15 + + +diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h +index 57b18b94d9..ce5af42e09 100644 +--- a/OvmfPkg/Include/Library/PlatformInitLib.h ++++ b/OvmfPkg/Include/Library/PlatformInitLib.h +@@ -37,6 +37,7 @@ typedef struct { + + UINT64 PcdPciMmio64Base; + UINT64 PcdPciMmio64Size; ++ BOOLEAN PcdPciMmio64Override; + UINT32 PcdPciMmio32Base; + UINT32 PcdPciMmio32Size; + UINT64 PcdPciIoBase; +diff --git a/OvmfPkg/Library/PlatformInitLib/MemDetect.c b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +index 1f987f2efd..44b2e0d24f 100644 +--- a/OvmfPkg/Library/PlatformInitLib/MemDetect.c ++++ b/OvmfPkg/Library/PlatformInitLib/MemDetect.c +@@ -556,7 +556,8 @@ PlatformGetFirstNonAddress ( + break; + case EFI_SUCCESS: + if (FwCfgPciMmio64Mb <= 0x1000000) { +- PlatformInfoHob->PcdPciMmio64Size = LShiftU64 (FwCfgPciMmio64Mb, 20); ++ PlatformInfoHob->PcdPciMmio64Size = LShiftU64 (FwCfgPciMmio64Mb, 20); ++ PlatformInfoHob->PcdPciMmio64Override = TRUE; + break; + } + +@@ -795,8 +796,10 @@ PlatformDynamicMmioWindow ( + AddrSpace = LShiftU64 (1, PlatformInfoHob->PhysMemAddressWidth); + MmioSpace = LShiftU64 (1, PlatformInfoHob->PhysMemAddressWidth - 3); + +- if ((PlatformInfoHob->PcdPciMmio64Size < MmioSpace) && +- (PlatformInfoHob->PcdPciMmio64Base + MmioSpace < AddrSpace)) ++ if (PlatformInfoHob->PcdPciMmio64Override) { ++ DEBUG ((DEBUG_INFO, "%a: using fwcfg override for mmio window\n", __func__)); ++ } else if ((PlatformInfoHob->PcdPciMmio64Size < MmioSpace) && ++ (PlatformInfoHob->PcdPciMmio64Base + MmioSpace < AddrSpace)) + { + DEBUG ((DEBUG_INFO, "%a: using dynamic mmio window\n", __func__)); + DEBUG ((DEBUG_INFO, "%a: Addr Space 0x%Lx (%Ld GB)\n", __func__, AddrSpace, RShiftU64 (AddrSpace, 30))); +-- +2.47.2 + diff --git a/images/edk2/patches/ArmVirtPkg-disable-the-EFI_MEMORY_ATTRIBUTE-protocol.patch b/images/edk2/patches/ArmVirtPkg-disable-the-EFI_MEMORY_ATTRIBUTE-protocol.patch new file mode 100644 index 0000000000..38b232c37f --- /dev/null +++ b/images/edk2/patches/ArmVirtPkg-disable-the-EFI_MEMORY_ATTRIBUTE-protocol.patch @@ -0,0 +1,52 @@ +Description: ArmVirtPkg: Disable the EFI memory attributes protocol + Temporarily disable the EFI_MEMORY_ATTRIBUTE_PROTOCOL to workaround + a bug in shim until distributions have had a chance to fix it. +Author: dann frazier +Bug-Debian: https://bugs.debian.org/1042438 +Bug-Ubuntu: https://launchpad.net/bugs/2036604 +Last-Update: 2025-03-01 + +--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c ++++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c +@@ -429,8 +429,6 @@ + &CpuHandle, + &gEfiCpuArchProtocolGuid, + &mCpu, +- &gEfiMemoryAttributeProtocolGuid, +- &mMemoryAttribute, + NULL + ); + if (EFI_ERROR (Status)) { +--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h ++++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h +@@ -30,12 +30,9 @@ + #include + #include + #include +-#include + + extern BOOLEAN mIsFlushingGCD; + +-extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute; +- + /** + This function registers and enables the handler specified by InterruptHandler for a processor + interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the +--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf ++++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf +@@ -23,7 +23,6 @@ + CpuDxe.h + CpuMmuCommon.c + Exception.c +- MemoryAttribute.c + + [Sources.ARM] + Arm/Mmu.c +@@ -55,7 +54,6 @@ + + [Protocols] + gEfiCpuArchProtocolGuid +- gEfiMemoryAttributeProtocolGuid + gHardwareInterruptProtocolGuid + + [Guids] diff --git a/images/edk2/patches/OvmfPkg-X64-add-opt-org.tianocore-UninstallMemAttrPr.patch b/images/edk2/patches/OvmfPkg-X64-add-opt-org.tianocore-UninstallMemAttrPr.patch new file mode 100644 index 0000000000..95d55ea2ec --- /dev/null +++ b/images/edk2/patches/OvmfPkg-X64-add-opt-org.tianocore-UninstallMemAttrPr.patch @@ -0,0 +1,127 @@ +From: Gerd Hoffmann +Date: Thu, 16 Jan 2025 17:20:38 +0100 +Subject: [PATCH] OvmfPkg/X64: add opt/org.tianocore/UninstallMemAttrProtocol + support + +Add support for opt/org.tianocore/UninstallMemAttrProtocol, to allow +turning off EFI_MEMORY_ATTRIBUTE_PROTOCOL, simliar to ArmVirtPkg. + +Signed-off-by: Gerd Hoffmann + +Origin: https://github.com/tianocore/edk2/pull/10667/commits/aa7f29a9e92b9e6f8b2e56bacaef6c96b8dc80ed +Bug-Debian: https://bugs.debian.org/1099500 +Bug-Ubuntu: https://launchpad.net/bugs/2104316 +Last-Updated: 2025-03-28 +--- + .../Library/PlatformBootManagerLib/BdsPlatform.c | 63 ++++++++++++++++++++++ + .../PlatformBootManagerLib.inf | 2 + + 2 files changed, 65 insertions(+) + +diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +index e666938..f4ae8dc 100644 +--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c ++++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +@@ -1836,6 +1836,49 @@ SaveS3BootScript ( + ASSERT_EFI_ERROR (Status); + } + ++/** ++ Uninstall the EFI memory attribute protocol if it exists. ++**/ ++STATIC ++VOID ++UninstallEfiMemoryAttributesProtocol ( ++ VOID ++ ) ++{ ++ EFI_STATUS Status; ++ EFI_HANDLE Handle; ++ UINTN Size; ++ VOID *MemoryAttributeProtocol; ++ ++ Size = sizeof (Handle); ++ Status = gBS->LocateHandle ( ++ ByProtocol, ++ &gEfiMemoryAttributeProtocolGuid, ++ NULL, ++ &Size, ++ &Handle ++ ); ++ ++ if (EFI_ERROR (Status)) { ++ ASSERT (Status == EFI_NOT_FOUND); ++ return; ++ } ++ ++ Status = gBS->HandleProtocol ( ++ Handle, ++ &gEfiMemoryAttributeProtocolGuid, ++ &MemoryAttributeProtocol ++ ); ++ ASSERT_EFI_ERROR (Status); ++ ++ Status = gBS->UninstallProtocolInterface ( ++ Handle, ++ &gEfiMemoryAttributeProtocolGuid, ++ MemoryAttributeProtocol ++ ); ++ ASSERT_EFI_ERROR (Status); ++} ++ + /** + Do the platform specific action after the console is ready + +@@ -1856,6 +1899,7 @@ PlatformBootManagerAfterConsole ( + ) + { + EFI_BOOT_MODE BootMode; ++ BOOLEAN Uninstall; + + DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n")); + +@@ -1900,6 +1944,25 @@ PlatformBootManagerAfterConsole ( + // + StoreQemuBootOrder (); + ++ // ++ // Work around shim's terminally broken use of the EFI memory attributes ++ // protocol, by uninstalling it if requested on the QEMU command line. ++ // ++ // E.g., ++ // -fw_cfg opt/org.tianocore/UninstallMemAttrProtocol,string=y ++ // ++ Uninstall = FixedPcdGetBool (PcdUninstallMemAttrProtocol); ++ QemuFwCfgParseBool ("opt/org.tianocore/UninstallMemAttrProtocol", &Uninstall); ++ DEBUG (( ++ DEBUG_WARN, ++ "%a: %auninstalling EFI memory protocol\n", ++ __func__, ++ Uninstall ? "" : "not " ++ )); ++ if (Uninstall) { ++ UninstallEfiMemoryAttributesProtocol (); ++ } ++ + // + // Process QEMU's -kernel command line option + // +diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +index 1a422eb..73190a3 100644 +--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf ++++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf +@@ -63,6 +63,7 @@ + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId + gUefiOvmfPkgTokenSpaceGuid.PcdBootRestrictToFirmware ++ gUefiOvmfPkgTokenSpaceGuid.PcdUninstallMemAttrProtocol + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## CONSUMES +@@ -81,6 +82,7 @@ + gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED ++ gEfiMemoryAttributeProtocolGuid + + [Guids] + gEfiEndOfDxeEventGroupGuid diff --git a/images/edk2/patches/Revert-ArmVirtPkg-make-EFI_LOADER_DATA-non-executabl.patch b/images/edk2/patches/Revert-ArmVirtPkg-make-EFI_LOADER_DATA-non-executabl.patch new file mode 100644 index 0000000000..3d1a9dae8a --- /dev/null +++ b/images/edk2/patches/Revert-ArmVirtPkg-make-EFI_LOADER_DATA-non-executabl.patch @@ -0,0 +1,20 @@ +Description: Revert "ArmVirtPkg: make EFI_LOADER_DATA non-executable" + The versions of GRUB most distros are shipping still depend on executable + EFI_LOADER_DATA. Revert this upstream change until the necessary fixes are + more generally available. +Author: dann frazier +Bug-Debian: https://bugs.debian.org/1025656 +Forwarded: https://edk2.groups.io/g/devel/message/97814 +Last-Update: 2023-07-21 + +--- a/ArmVirtPkg/ArmVirt.dsc.inc ++++ b/ArmVirtPkg/ArmVirt.dsc.inc +@@ -398,7 +398,7 @@ + # build command line you can allow code execution in EfiLoaderData. This is + # required when using some outdated GRUB versions. + # +- gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5 ++ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1 + + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-accept-absolute-path.Nopatch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-accept-absolute-path.Nopatch new file mode 100644 index 0000000000..9a13178437 --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-accept-absolute-path.Nopatch @@ -0,0 +1,25 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:22 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: accept absolute paths" + +This reverts commit 46ae4e4b9574530e5081e98af0495d6f6d28379f. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 5b90420..3e1a876 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -806,11 +806,6 @@ QemuKernelStubFileOpen ( + // + // Locate the file. + // +- if (FileName[0] == '\\') { +- // also accept absolute paths, i.e. '\kernel' for 'kernel' +- FileName++; +- } +- + Blob = FindKernelBlob (FileName); + + if (Blob == NULL) { diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-add-support-for-name.Nopatch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-add-support-for-name.Nopatch new file mode 100644 index 0000000000..3ee548dd86 --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-add-support-for-name.Nopatch @@ -0,0 +1,163 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:25 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: add support for named blobs" + +This reverts commit 20df7c42bd446fe725bfc78cdb40577456c421d8. +--- + .../QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 94 +++------------------- + .../QemuKernelLoaderFsDxe.inf | 1 - + 2 files changed, 11 insertions(+), 84 deletions(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 1f63add..7ad1b38 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -33,12 +32,12 @@ + // Static data that hosts the fw_cfg blobs and serves file requests. + // + typedef struct { +- CHAR16 Name[8]; ++ CONST CHAR16 Name[8]; + struct { +- FIRMWARE_CONFIG_ITEM SizeKey; +- FIRMWARE_CONFIG_ITEM DataKey; +- UINT32 Size; +- } FwCfgItem[2]; ++ FIRMWARE_CONFIG_ITEM CONST SizeKey; ++ FIRMWARE_CONFIG_ITEM CONST DataKey; ++ UINT32 Size; ++ } FwCfgItem[2]; + } KERNEL_BLOB_ITEMS; + + typedef struct KERNEL_BLOB KERNEL_BLOB; +@@ -990,23 +989,15 @@ QemuKernelFetchBlob ( + + // + // Read blob size. +- // Size != 0 -> use size as-is +- // SizeKey != 0 -> read size from fw_cfg +- // both are 0 -> unused entry + // + for (Size = 0, Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) { +- if ((BlobItems->FwCfgItem[Idx].SizeKey == 0) && +- (BlobItems->FwCfgItem[Idx].Size == 0)) +- { ++ if (BlobItems->FwCfgItem[Idx].SizeKey == 0) { + break; + } + +- if (BlobItems->FwCfgItem[Idx].SizeKey) { +- QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey); +- BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 (); +- } +- +- Size += BlobItems->FwCfgItem[Idx].Size; ++ QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey); ++ BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 (); ++ Size += BlobItems->FwCfgItem[Idx].Size; + } + + if (Size == 0) { +@@ -1092,55 +1083,6 @@ QemuKernelVerifyBlob ( + return Status; + } + +-STATIC +-EFI_STATUS +-QemuKernelFetchNamedBlobs ( +- VOID +- ) +-{ +- struct { +- UINT32 FileSize; +- UINT16 FileSelect; +- UINT16 Reserved; +- CHAR8 FileName[QEMU_FW_CFG_FNAME_SIZE]; +- } *DirEntry; +- KERNEL_BLOB_ITEMS Items; +- EFI_STATUS Status; +- EFI_STATUS FetchStatus; +- UINT32 Count; +- UINT32 Idx; +- +- QemuFwCfgSelectItem (QemuFwCfgItemFileDir); +- Count = SwapBytes32 (QemuFwCfgRead32 ()); +- +- DirEntry = AllocatePool (sizeof (*DirEntry) * Count); +- QemuFwCfgReadBytes (sizeof (*DirEntry) * Count, DirEntry); +- +- for (Idx = 0; Idx < Count; ++Idx) { +- if (AsciiStrnCmp (DirEntry[Idx].FileName, "etc/boot/", 9) != 0) { +- continue; +- } +- +- ZeroMem (&Items, sizeof (Items)); +- UnicodeSPrint (Items.Name, sizeof (Items.Name), L"%a", DirEntry[Idx].FileName + 9); +- Items.FwCfgItem[0].DataKey = SwapBytes16 (DirEntry[Idx].FileSelect); +- Items.FwCfgItem[0].Size = SwapBytes32 (DirEntry[Idx].FileSize); +- +- FetchStatus = QemuKernelFetchBlob (&Items); +- Status = QemuKernelVerifyBlob ( +- (CHAR16 *)Items.Name, +- FetchStatus +- ); +- if (EFI_ERROR (Status)) { +- FreePool (DirEntry); +- return Status; +- } +- } +- +- FreePool (DirEntry); +- return EFI_SUCCESS; +-} +- + // + // The entry point of the feature. + // +@@ -1184,24 +1126,10 @@ QemuKernelLoaderFsDxeEntrypoint ( + } + + // +- // Fetch named blobs. ++ // Fetch all blobs. + // +- DEBUG ((DEBUG_INFO, "%a: named blobs (etc/boot/*)\n", __func__)); +- Status = QemuKernelFetchNamedBlobs (); +- if (EFI_ERROR (Status)) { +- goto FreeBlobs; +- } +- +- // +- // Fetch traditional blobs. +- // +- DEBUG ((DEBUG_INFO, "%a: traditional blobs\n", __func__)); + for (BlobIdx = 0; BlobIdx < ARRAY_SIZE (mKernelBlobItems); ++BlobIdx) { +- BlobItems = &mKernelBlobItems[BlobIdx]; +- if (FindKernelBlob (BlobItems->Name)) { +- continue; +- } +- ++ BlobItems = &mKernelBlobItems[BlobIdx]; + FetchStatus = QemuKernelFetchBlob (BlobItems); + + Status = QemuKernelVerifyBlob ( +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf +index a2f44bb..7b35adb 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf +@@ -30,7 +30,6 @@ + DebugLib + DevicePathLib + MemoryAllocationLib +- PrintLib + QemuFwCfgLib + UefiBootServicesTableLib + UefiDriverEntryPoint diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-allow-longer-file-na.patch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-allow-longer-file-na.patch new file mode 100644 index 0000000000..9f510f282d --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-allow-longer-file-na.patch @@ -0,0 +1,31 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:24 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: allow longer file names" + +This reverts commit adf385ecab69631952bdc8b774ebd77e82b94a00. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 0947b6b..1f63add 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -33,7 +33,7 @@ + // Static data that hosts the fw_cfg blobs and serves file requests. + // + typedef struct { +- CHAR16 Name[48]; ++ CHAR16 Name[8]; + struct { + FIRMWARE_CONFIG_ITEM SizeKey; + FIRMWARE_CONFIG_ITEM DataKey; +@@ -43,7 +43,7 @@ typedef struct { + + typedef struct KERNEL_BLOB KERNEL_BLOB; + struct KERNEL_BLOB { +- CHAR16 Name[48]; ++ CHAR16 Name[8]; + UINT32 Size; + UINT8 *Data; + KERNEL_BLOB *Next; diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-don-t-quit-when-name.patch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-don-t-quit-when-name.patch new file mode 100644 index 0000000000..1f15d5d752 --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-don-t-quit-when-name.patch @@ -0,0 +1,42 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:22 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: don't quit when named blobs + are present" + +This reverts commit c45051450efbdae4a38f07998b3e7b77abe7173a. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index add914d..5b90420 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -71,7 +71,6 @@ STATIC KERNEL_BLOB_ITEMS mKernelBlobItems[] = { + + STATIC KERNEL_BLOB *mKernelBlobs; + STATIC UINT64 mKernelBlobCount; +-STATIC UINT64 mKernelNamedBlobCount; + STATIC UINT64 mTotalBlobBytes; + + // +@@ -1140,8 +1139,6 @@ QemuKernelFetchNamedBlobs ( + FreePool (DirEntry); + return Status; + } +- +- mKernelNamedBlobCount++; + } + + FreePool (DirEntry); +@@ -1221,8 +1218,8 @@ QemuKernelLoaderFsDxeEntrypoint ( + } + + Blob = FindKernelBlob (L"kernel"); +- if ((Blob == NULL) && (mKernelNamedBlobCount == 0)) { +- DEBUG ((DEBUG_INFO, "%a: no kernel and no named blobs present -> quit\n", __func__)); ++ if (Blob == NULL) { ++ DEBUG ((DEBUG_INFO, "%a: no kernel present -> quit\n", __func__)); + Status = EFI_NOT_FOUND; + goto FreeBlobs; + } diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-drop-bogus-assert.Nopatch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-drop-bogus-assert.Nopatch new file mode 100644 index 0000000000..4af20d37ce --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-drop-bogus-assert.Nopatch @@ -0,0 +1,21 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:23 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: drop bogus assert" + +This reverts commit 1111e9fe7078eed9e5c50e1808776ee40a629e16. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 3e1a876..0947b6b 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -290,6 +290,7 @@ QemuKernelBlobTypeToFileInfo ( + + NameSize = (StrLen (Name) + 1) * 2; + FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize; ++ ASSERT (FileInfoSize >= sizeof *FileInfo); + + OriginalBufferSize = *BufferSize; + *BufferSize = FileInfoSize; diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-rework-direct-kernel.patch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-rework-direct-kernel.patch new file mode 100644 index 0000000000..45d2cd3090 --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-rework-direct-kernel.patch @@ -0,0 +1,740 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:25 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: rework direct kernel boot + filesystem" + +This reverts commit 459f5ffa24ae8574657c4105af0ff7dc30ac428d. +--- + .../QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 345 +++++++++------------ + 1 file changed, 140 insertions(+), 205 deletions(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 7ad1b38..cf58c97 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -31,6 +31,13 @@ + // + // Static data that hosts the fw_cfg blobs and serves file requests. + // ++typedef enum { ++ KernelBlobTypeKernel, ++ KernelBlobTypeInitrd, ++ KernelBlobTypeCommandLine, ++ KernelBlobTypeMax ++} KERNEL_BLOB_TYPE; ++ + typedef struct { + CONST CHAR16 Name[8]; + struct { +@@ -38,17 +45,11 @@ typedef struct { + FIRMWARE_CONFIG_ITEM CONST DataKey; + UINT32 Size; + } FwCfgItem[2]; +-} KERNEL_BLOB_ITEMS; +- +-typedef struct KERNEL_BLOB KERNEL_BLOB; +-struct KERNEL_BLOB { +- CHAR16 Name[8]; +- UINT32 Size; +- UINT8 *Data; +- KERNEL_BLOB *Next; +-}; ++ UINT32 Size; ++ UINT8 *Data; ++} KERNEL_BLOB; + +-STATIC KERNEL_BLOB_ITEMS mKernelBlobItems[] = { ++STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = { + { + L"kernel", + { +@@ -68,9 +69,7 @@ STATIC KERNEL_BLOB_ITEMS mKernelBlobItems[] = { + } + }; + +-STATIC KERNEL_BLOB *mKernelBlobs; +-STATIC UINT64 mKernelBlobCount; +-STATIC UINT64 mTotalBlobBytes; ++STATIC UINT64 mTotalBlobBytes; + + // + // Device path for the handle that incorporates our "EFI stub filesystem". +@@ -118,7 +117,7 @@ STATIC EFI_TIME mInitTime; + typedef struct { + UINT64 Signature; // Carries STUB_FILE_SIG. + +- KERNEL_BLOB *Blob; // Index into mKernelBlob. KernelBlobTypeMax ++ KERNEL_BLOB_TYPE BlobType; // Index into mKernelBlob. KernelBlobTypeMax + // denotes the root directory of the filesystem. + + UINT64 Position; // Byte position for regular files; +@@ -178,7 +177,7 @@ typedef struct { + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileOpen ( ++StubFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, +@@ -197,7 +196,7 @@ QemuKernelStubFileOpen ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileClose ( ++StubFileClose ( + IN EFI_FILE_PROTOCOL *This + ) + { +@@ -220,7 +219,7 @@ QemuKernelStubFileClose ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileDelete ( ++StubFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) + { +@@ -230,17 +229,18 @@ QemuKernelStubFileDelete ( + + /** + Helper function that formats an EFI_FILE_INFO structure into the +- user-allocated buffer, for any valid KERNEL_BLOB (including NULL, +- which stands for the root directory). ++ user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including ++ KernelBlobTypeMax, which stands for the root directory). + + The interface follows the EFI_FILE_GET_INFO -- and for directories, the + EFI_FILE_READ -- interfaces. + +- @param[in] Blob The KERNEL_BLOB identifying the fw_cfg ++ @param[in] BlobType The KERNEL_BLOB_TYPE value identifying the fw_cfg + blob backing the STUB_FILE that information is +- being requested about. If Blob is NULL, +- then information will be provided about the root +- directory of the filesystem. ++ being requested about. If BlobType equals ++ KernelBlobTypeMax, then information will be ++ provided about the root directory of the ++ filesystem. + + @param[in,out] BufferSize On input, the size of Buffer. On output, the + amount of data returned in Buffer. In both cases, +@@ -257,10 +257,10 @@ QemuKernelStubFileDelete ( + **/ + STATIC + EFI_STATUS +-QemuKernelBlobTypeToFileInfo ( +- IN KERNEL_BLOB *Blob, +- IN OUT UINTN *BufferSize, +- OUT VOID *Buffer ++ConvertKernelBlobTypeToFileInfo ( ++ IN KERNEL_BLOB_TYPE BlobType, ++ IN OUT UINTN *BufferSize, ++ OUT VOID *Buffer + ) + { + CONST CHAR16 *Name; +@@ -272,16 +272,17 @@ QemuKernelBlobTypeToFileInfo ( + EFI_FILE_INFO *FileInfo; + UINTN OriginalBufferSize; + +- if (Blob == NULL) { ++ if (BlobType == KernelBlobTypeMax) { + // + // getting file info about the root directory + // +- DEBUG ((DEBUG_INFO, "%a: file info: directory\n", __func__)); + Name = L"\\"; +- FileSize = mKernelBlobCount; ++ FileSize = KernelBlobTypeMax; + Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; + } else { +- DEBUG ((DEBUG_INFO, "%a: file info: \"%s\"\n", __func__, Blob->Name)); ++ CONST KERNEL_BLOB *Blob; ++ ++ Blob = &mKernelBlob[BlobType]; + Name = Blob->Name; + FileSize = Blob->Size; + Attribute = EFI_FILE_READ_ONLY; +@@ -311,23 +312,6 @@ QemuKernelBlobTypeToFileInfo ( + return EFI_SUCCESS; + } + +-STATIC +-KERNEL_BLOB * +-FindKernelBlob ( +- CHAR16 *FileName +- ) +-{ +- KERNEL_BLOB *Blob; +- +- for (Blob = mKernelBlobs; Blob != NULL; Blob = Blob->Next) { +- if (StrCmp (FileName, Blob->Name) == 0) { +- return Blob; +- } +- } +- +- return NULL; +-} +- + /** + Reads data from a file, or continues scanning a directory. + +@@ -365,25 +349,25 @@ FindKernelBlob ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileRead ( ++StubFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) + { +- STUB_FILE *StubFile; +- KERNEL_BLOB *Blob; +- UINT64 Left, Pos; ++ STUB_FILE *StubFile; ++ CONST KERNEL_BLOB *Blob; ++ UINT64 Left; + + StubFile = STUB_FILE_FROM_FILE (This); + + // + // Scanning the root directory? + // +- if (StubFile->Blob == NULL) { ++ if (StubFile->BlobType == KernelBlobTypeMax) { + EFI_STATUS Status; + +- if (StubFile->Position == mKernelBlobCount) { ++ if (StubFile->Position == KernelBlobTypeMax) { + // + // Scanning complete. + // +@@ -391,16 +375,8 @@ QemuKernelStubFileRead ( + return EFI_SUCCESS; + } + +- for (Pos = 0, Blob = mKernelBlobs; +- Pos < StubFile->Position; +- Pos++, Blob = Blob->Next) +- { +- } +- +- DEBUG ((DEBUG_INFO, "%a: file list: #%d \"%s\"\n", __func__, Pos, Blob->Name)); +- +- Status = QemuKernelBlobTypeToFileInfo ( +- Blob, ++ Status = ConvertKernelBlobTypeToFileInfo ( ++ (KERNEL_BLOB_TYPE)StubFile->Position, + BufferSize, + Buffer + ); +@@ -415,7 +391,7 @@ QemuKernelStubFileRead ( + // + // Reading a file. + // +- Blob = StubFile->Blob; ++ Blob = &mKernelBlob[StubFile->BlobType]; + if (StubFile->Position > Blob->Size) { + return EFI_DEVICE_ERROR; + } +@@ -426,7 +402,6 @@ QemuKernelStubFileRead ( + } + + if (Blob->Data != NULL) { +- DEBUG ((DEBUG_INFO, "%a: file read: \"%s\", %d bytes\n", __func__, Blob->Name, *BufferSize)); + CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize); + } + +@@ -460,7 +435,7 @@ QemuKernelStubFileRead ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileWrite ( ++StubFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer +@@ -469,7 +444,7 @@ QemuKernelStubFileWrite ( + STUB_FILE *StubFile; + + StubFile = STUB_FILE_FROM_FILE (This); +- return (StubFile->Blob == NULL) ? ++ return (StubFile->BlobType == KernelBlobTypeMax) ? + EFI_UNSUPPORTED : + EFI_WRITE_PROTECTED; + } +@@ -491,7 +466,7 @@ QemuKernelStubFileWrite ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileGetPosition ( ++StubFileGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +@@ -499,7 +474,7 @@ QemuKernelStubFileGetPosition ( + STUB_FILE *StubFile; + + StubFile = STUB_FILE_FROM_FILE (This); +- if (StubFile->Blob == NULL) { ++ if (StubFile->BlobType == KernelBlobTypeMax) { + return EFI_UNSUPPORTED; + } + +@@ -526,7 +501,7 @@ QemuKernelStubFileGetPosition ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileSetPosition ( ++StubFileSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +@@ -536,7 +511,7 @@ QemuKernelStubFileSetPosition ( + + StubFile = STUB_FILE_FROM_FILE (This); + +- if (StubFile->Blob == NULL) { ++ if (StubFile->BlobType == KernelBlobTypeMax) { + if (Position == 0) { + // + // rewinding a directory scan is allowed +@@ -551,7 +526,7 @@ QemuKernelStubFileSetPosition ( + // + // regular file seek + // +- Blob = StubFile->Blob; ++ Blob = &mKernelBlob[StubFile->BlobType]; + if (Position == MAX_UINT64) { + // + // seek to end +@@ -608,7 +583,7 @@ QemuKernelStubFileSetPosition ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileGetInfo ( ++StubFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, +@@ -621,8 +596,8 @@ QemuKernelStubFileGetInfo ( + StubFile = STUB_FILE_FROM_FILE (This); + + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { +- return QemuKernelBlobTypeToFileInfo ( +- StubFile->Blob, ++ return ConvertKernelBlobTypeToFileInfo ( ++ StubFile->BlobType, + BufferSize, + Buffer + ); +@@ -710,7 +685,7 @@ QemuKernelStubFileGetInfo ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileSetInfo ( ++StubFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, +@@ -737,7 +712,7 @@ QemuKernelStubFileSetInfo ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileFlush ( ++StubFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) + { +@@ -749,16 +724,16 @@ QemuKernelStubFileFlush ( + // + STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = { + EFI_FILE_PROTOCOL_REVISION, // revision 1 +- QemuKernelStubFileOpen, +- QemuKernelStubFileClose, +- QemuKernelStubFileDelete, +- QemuKernelStubFileRead, +- QemuKernelStubFileWrite, +- QemuKernelStubFileGetPosition, +- QemuKernelStubFileSetPosition, +- QemuKernelStubFileGetInfo, +- QemuKernelStubFileSetInfo, +- QemuKernelStubFileFlush, ++ StubFileOpen, ++ StubFileClose, ++ StubFileDelete, ++ StubFileRead, ++ StubFileWrite, ++ StubFileGetPosition, ++ StubFileSetPosition, ++ StubFileGetInfo, ++ StubFileSetInfo, ++ StubFileFlush, + NULL, // OpenEx, revision 2 + NULL, // ReadEx, revision 2 + NULL, // WriteEx, revision 2 +@@ -768,7 +743,7 @@ STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = { + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileOpen ( ++StubFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, +@@ -777,7 +752,7 @@ QemuKernelStubFileOpen ( + ) + { + CONST STUB_FILE *StubFile; +- KERNEL_BLOB *Blob; ++ UINTN BlobType; + STUB_FILE *NewStubFile; + + // +@@ -799,20 +774,21 @@ QemuKernelStubFileOpen ( + // Only the root directory supports opening files in it. + // + StubFile = STUB_FILE_FROM_FILE (This); +- if (StubFile->Blob != NULL) { ++ if (StubFile->BlobType != KernelBlobTypeMax) { + return EFI_UNSUPPORTED; + } + + // + // Locate the file. + // +- Blob = FindKernelBlob (FileName); ++ for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) { ++ if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) { ++ break; ++ } ++ } + +- if (Blob == NULL) { +- DEBUG ((DEBUG_INFO, "%a: file not found: \"%s\"\n", __func__, FileName)); ++ if (BlobType == KernelBlobTypeMax) { + return EFI_NOT_FOUND; +- } else { +- DEBUG ((DEBUG_INFO, "%a: file opened: \"%s\"\n", __func__, FileName)); + } + + // +@@ -824,7 +800,7 @@ QemuKernelStubFileOpen ( + } + + NewStubFile->Signature = STUB_FILE_SIG; +- NewStubFile->Blob = Blob; ++ NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType; + NewStubFile->Position = 0; + CopyMem ( + &NewStubFile->File, +@@ -866,7 +842,7 @@ QemuKernelStubFileOpen ( + STATIC + EFI_STATUS + EFIAPI +-QemuKernelStubFileSystemOpenVolume ( ++StubFileSystemOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +@@ -879,7 +855,7 @@ QemuKernelStubFileSystemOpenVolume ( + } + + StubFile->Signature = STUB_FILE_SIG; +- StubFile->Blob = NULL; ++ StubFile->BlobType = KernelBlobTypeMax; + StubFile->Position = 0; + CopyMem ( + &StubFile->File, +@@ -893,13 +869,13 @@ QemuKernelStubFileSystemOpenVolume ( + + STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, +- QemuKernelStubFileSystemOpenVolume ++ StubFileSystemOpenVolume + }; + + STATIC + EFI_STATUS + EFIAPI +-QemuKernelInitrdLoadFile2 ( ++InitrdLoadFile2 ( + IN EFI_LOAD_FILE2_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN BOOLEAN BootPolicy, +@@ -907,11 +883,8 @@ QemuKernelInitrdLoadFile2 ( + OUT VOID *Buffer OPTIONAL + ) + { +- KERNEL_BLOB *InitrdBlob; ++ CONST KERNEL_BLOB *InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd]; + +- DEBUG ((DEBUG_INFO, "%a: initrd read\n", __func__)); +- InitrdBlob = FindKernelBlob (L"initrd"); +- ASSERT (InitrdBlob != NULL); + ASSERT (InitrdBlob->Size > 0); + + if (BootPolicy) { +@@ -940,33 +913,17 @@ QemuKernelInitrdLoadFile2 ( + } + + STATIC CONST EFI_LOAD_FILE2_PROTOCOL mInitrdLoadFile2 = { +- QemuKernelInitrdLoadFile2, ++ InitrdLoadFile2, + }; + + // + // Utility functions. + // + +-STATIC VOID +-QemuKernelChunkedRead ( +- UINT8 *Dest, +- UINT32 Bytes +- ) +-{ +- UINT32 Chunk; +- +- while (Bytes > 0) { +- Chunk = (Bytes < SIZE_1MB) ? Bytes : SIZE_1MB; +- QemuFwCfgReadBytes (Chunk, Dest); +- Bytes -= Chunk; +- Dest += Chunk; +- } +-} +- + /** + Populate a blob in mKernelBlob. + +- param[in,out] Blob Pointer to the KERNEL_BLOB_ITEMS that is ++ param[in,out] Blob Pointer to the KERNEL_BLOB element in mKernelBlob that is + to be filled from fw_cfg. + + @retval EFI_SUCCESS Blob has been populated. If fw_cfg reported a +@@ -977,46 +934,35 @@ QemuKernelChunkedRead ( + **/ + STATIC + EFI_STATUS +-QemuKernelFetchBlob ( +- IN KERNEL_BLOB_ITEMS *BlobItems ++FetchBlob ( ++ IN OUT KERNEL_BLOB *Blob + ) + { +- UINT32 Size; +- UINTN Idx; +- UINT8 *ChunkData; +- KERNEL_BLOB *Blob; +- EFI_STATUS Status; ++ UINT32 Left; ++ UINTN Idx; ++ UINT8 *ChunkData; + + // + // Read blob size. + // +- for (Size = 0, Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) { +- if (BlobItems->FwCfgItem[Idx].SizeKey == 0) { ++ Blob->Size = 0; ++ for (Idx = 0; Idx < ARRAY_SIZE (Blob->FwCfgItem); Idx++) { ++ if (Blob->FwCfgItem[Idx].SizeKey == 0) { + break; + } + +- QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].SizeKey); +- BlobItems->FwCfgItem[Idx].Size = QemuFwCfgRead32 (); +- Size += BlobItems->FwCfgItem[Idx].Size; ++ QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].SizeKey); ++ Blob->FwCfgItem[Idx].Size = QemuFwCfgRead32 (); ++ Blob->Size += Blob->FwCfgItem[Idx].Size; + } + +- if (Size == 0) { ++ if (Blob->Size == 0) { + return EFI_SUCCESS; + } + +- Blob = AllocatePool (sizeof (*Blob)); +- if (Blob->Data == NULL) { +- return EFI_OUT_OF_RESOURCES; +- } +- +- ZeroMem (Blob, sizeof (*Blob)); +- + // + // Read blob. + // +- Status = StrCpyS (Blob->Name, sizeof (Blob->Name), BlobItems->Name); +- ASSERT (!EFI_ERROR (Status)); +- Blob->Size = Size; + Blob->Data = AllocatePool (Blob->Size); + if (Blob->Data == NULL) { + DEBUG (( +@@ -1026,7 +972,6 @@ QemuKernelFetchBlob ( + (INT64)Blob->Size, + Blob->Name + )); +- FreePool (Blob); + return EFI_OUT_OF_RESOURCES; + } + +@@ -1039,48 +984,34 @@ QemuKernelFetchBlob ( + )); + + ChunkData = Blob->Data; +- for (Idx = 0; Idx < ARRAY_SIZE (BlobItems->FwCfgItem); Idx++) { +- if (BlobItems->FwCfgItem[Idx].DataKey == 0) { ++ for (Idx = 0; Idx < ARRAY_SIZE (Blob->FwCfgItem); Idx++) { ++ if (Blob->FwCfgItem[Idx].DataKey == 0) { + break; + } + +- QemuFwCfgSelectItem (BlobItems->FwCfgItem[Idx].DataKey); +- QemuKernelChunkedRead (ChunkData, BlobItems->FwCfgItem[Idx].Size); +- ChunkData += BlobItems->FwCfgItem[Idx].Size; +- } ++ QemuFwCfgSelectItem (Blob->FwCfgItem[Idx].DataKey); + +- Blob->Next = mKernelBlobs; +- mKernelBlobs = Blob; +- mKernelBlobCount++; +- mTotalBlobBytes += Blob->Size; +- return EFI_SUCCESS; +-} ++ Left = Blob->FwCfgItem[Idx].Size; ++ while (Left > 0) { ++ UINT32 Chunk; + +-STATIC +-EFI_STATUS +-QemuKernelVerifyBlob ( +- CHAR16 *FileName, +- EFI_STATUS FetchStatus +- ) +-{ +- KERNEL_BLOB *Blob; +- EFI_STATUS Status; ++ Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB; ++ QemuFwCfgReadBytes (Chunk, ChunkData + Blob->FwCfgItem[Idx].Size - Left); ++ Left -= Chunk; ++ DEBUG (( ++ DEBUG_VERBOSE, ++ "%a: %Ld bytes remaining for \"%s\" (%d)\n", ++ __func__, ++ (INT64)Left, ++ Blob->Name, ++ (INT32)Idx ++ )); ++ } + +- if ((StrCmp (FileName, L"kernel") != 0) && +- (StrCmp (FileName, L"initrd") != 0) && +- (StrCmp (FileName, L"cmdline") != 0)) +- { +- return EFI_SUCCESS; ++ ChunkData += Blob->FwCfgItem[Idx].Size; + } + +- Blob = FindKernelBlob (FileName); +- Status = VerifyBlob ( +- FileName, +- Blob ? Blob->Data : NULL, +- Blob ? Blob->Size : 0, +- FetchStatus +- ); +- return Status; ++ return EFI_SUCCESS; + } + + // +@@ -1107,13 +1038,13 @@ QemuKernelLoaderFsDxeEntrypoint ( + IN EFI_SYSTEM_TABLE *SystemTable + ) + { +- UINTN BlobIdx; +- KERNEL_BLOB_ITEMS *BlobItems; +- KERNEL_BLOB *Blob; +- EFI_STATUS Status; +- EFI_STATUS FetchStatus; +- EFI_HANDLE FileSystemHandle; +- EFI_HANDLE InitrdLoadFile2Handle; ++ UINTN BlobType; ++ KERNEL_BLOB *CurrentBlob; ++ KERNEL_BLOB *KernelBlob; ++ EFI_STATUS Status; ++ EFI_STATUS FetchStatus; ++ EFI_HANDLE FileSystemHandle; ++ EFI_HANDLE InitrdLoadFile2Handle; + + if (!QemuFwCfgIsAvailable ()) { + return EFI_NOT_FOUND; +@@ -1128,22 +1059,26 @@ QemuKernelLoaderFsDxeEntrypoint ( + // + // Fetch all blobs. + // +- for (BlobIdx = 0; BlobIdx < ARRAY_SIZE (mKernelBlobItems); ++BlobIdx) { +- BlobItems = &mKernelBlobItems[BlobIdx]; +- FetchStatus = QemuKernelFetchBlob (BlobItems); +- +- Status = QemuKernelVerifyBlob ( +- (CHAR16 *)BlobItems->Name, ++ for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) { ++ CurrentBlob = &mKernelBlob[BlobType]; ++ FetchStatus = FetchBlob (CurrentBlob); ++ ++ Status = VerifyBlob ( ++ CurrentBlob->Name, ++ CurrentBlob->Data, ++ CurrentBlob->Size, + FetchStatus + ); + if (EFI_ERROR (Status)) { + goto FreeBlobs; + } ++ ++ mTotalBlobBytes += CurrentBlob->Size; + } + +- Blob = FindKernelBlob (L"kernel"); +- if (Blob == NULL) { +- DEBUG ((DEBUG_INFO, "%a: no kernel present -> quit\n", __func__)); ++ KernelBlob = &mKernelBlob[KernelBlobTypeKernel]; ++ ++ if (KernelBlob->Data == NULL) { + Status = EFI_NOT_FOUND; + goto FreeBlobs; + } +@@ -1171,9 +1106,7 @@ QemuKernelLoaderFsDxeEntrypoint ( + goto FreeBlobs; + } + +- Blob = FindKernelBlob (L"initrd"); +- if (Blob != NULL) { +- DEBUG ((DEBUG_INFO, "%a: initrd setup\n", __func__)); ++ if (KernelBlob[KernelBlobTypeInitrd].Size > 0) { + InitrdLoadFile2Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &InitrdLoadFile2Handle, +@@ -1208,11 +1141,13 @@ UninstallFileSystemHandle: + ASSERT_EFI_ERROR (Status); + + FreeBlobs: +- while (mKernelBlobs != NULL) { +- Blob = mKernelBlobs; +- mKernelBlobs = Blob->Next; +- FreePool (Blob->Data); +- FreePool (Blob); ++ while (BlobType > 0) { ++ CurrentBlob = &mKernelBlob[--BlobType]; ++ if (CurrentBlob->Data != NULL) { ++ FreePool (CurrentBlob->Data); ++ CurrentBlob->Size = 0; ++ CurrentBlob->Data = NULL; ++ } + } + + return Status; diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-root-directory-name-.patch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-root-directory-name-.patch new file mode 100644 index 0000000000..b4e63ce0aa --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-root-directory-name-.patch @@ -0,0 +1,23 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:21 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: root directory name should be + """ + +This reverts commit b873e8b8e3717880578dd2894bc85a5035363027. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index 570193e..add914d 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -279,7 +279,7 @@ QemuKernelBlobTypeToFileInfo ( + // getting file info about the root directory + // + DEBUG ((DEBUG_INFO, "%a: file info: directory\n", __func__)); +- Name = L""; ++ Name = L"\\"; + FileSize = mKernelBlobCount; + Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; + } else { diff --git a/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-use-SIZE_OF_EFI_FILE.patch b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-use-SIZE_OF_EFI_FILE.patch new file mode 100644 index 0000000000..68fe38b7cf --- /dev/null +++ b/images/edk2/patches/Revert-OvmfPkg-QemuKernelLoaderFsDxe-use-SIZE_OF_EFI_FILE.patch @@ -0,0 +1,22 @@ +From: Mate Kukri +Date: Thu, 20 Mar 2025 10:49:19 +0000 +Subject: Revert "OvmfPkg/QemuKernelLoaderFsDxe: use SIZE_OF_EFI_FILE_INFO" + +This reverts commit bba72ffbe1d1a8f6f94b0c14489bfcf08617fe1f. +--- + OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +index df6364c..570193e 100644 +--- a/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c ++++ b/OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.c +@@ -290,7 +290,7 @@ QemuKernelBlobTypeToFileInfo ( + } + + NameSize = (StrLen (Name) + 1) * 2; +- FileInfoSize = SIZE_OF_EFI_FILE_INFO + NameSize; ++ FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize; + + OriginalBufferSize = *BufferSize; + *BufferSize = FileInfoSize; diff --git a/images/edk2/patches/brotlicompress-disable.diff b/images/edk2/patches/brotlicompress-disable.diff new file mode 100644 index 0000000000..ea632e18b0 --- /dev/null +++ b/images/edk2/patches/brotlicompress-disable.diff @@ -0,0 +1,20 @@ +Description: Do not attempt to compile removed BrotliCompress source + BrotliCompress is not currently used, and including an embedded + copy of its source could cause false-positives when scanning for + security issues. This code is stripped from our orig.tar (at the request + of the Ubuntu security team), so we also need to disable the build. +Author: dann frazier +Forwarded: not-needed +Last-Update: 2023-03-09 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/BaseTools/Source/C/GNUmakefile ++++ b/BaseTools/Source/C/GNUmakefile +@@ -51,7 +51,6 @@ + LIBRARIES = Common + VFRAUTOGEN = VfrCompile/VfrLexer.h + APPLICATIONS = \ +- BrotliCompress \ + VfrCompile \ + EfiRom \ + GenFfs \ diff --git a/images/edk2/patches/no-stack-protector-all-archs.diff b/images/edk2/patches/no-stack-protector-all-archs.diff new file mode 100644 index 0000000000..bc9ddebc32 --- /dev/null +++ b/images/edk2/patches/no-stack-protector-all-archs.diff @@ -0,0 +1,17 @@ +Author: Steve Langasek +Description: pass -fno-stack-protector to all GCC toolchains + The upstream build rules inexplicably pass -fno-stack-protector only + when building for i386 and amd64. Add this essential argument to the + generic rules for gcc 4.8 and later. +Last-Updated: 2023-07-21 +--- a/BaseTools/Conf/tools_def.template ++++ b/BaseTools/Conf/tools_def.template +@@ -959,7 +959,7 @@ + # GCC Build Flag for included header file list generation + DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps + +-DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings ++DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -fno-stack-protector -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20 + DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer + DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer diff --git a/images/edk2/patches/series b/images/edk2/patches/series new file mode 100644 index 0000000000..7803a05eee --- /dev/null +++ b/images/edk2/patches/series @@ -0,0 +1,15 @@ +no-stack-protector-all-archs.diff +brotlicompress-disable.diff +x64-baseline-abi.patch +Revert-ArmVirtPkg-make-EFI_LOADER_DATA-non-executabl.patch +ArmVirtPkg-disable-the-EFI_MEMORY_ATTRIBUTE-protocol.patch +0001-OvmfPkg-Use-user-specified-opt-ovmf-X-PciMmio64Mb-va.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-use-SIZE_OF_EFI_FILE.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-root-directory-name-.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-don-t-quit-when-name.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-accept-absolute-path.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-drop-bogus-assert.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-allow-longer-file-na.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-add-support-for-name.patch +Revert-OvmfPkg-QemuKernelLoaderFsDxe-rework-direct-kernel.patch +OvmfPkg-X64-add-opt-org.tianocore-UninstallMemAttrPr.patch diff --git a/images/edk2/patches/x64-baseline-abi.patch b/images/edk2/patches/x64-baseline-abi.patch new file mode 100644 index 0000000000..b3e1369752 --- /dev/null +++ b/images/edk2/patches/x64-baseline-abi.patch @@ -0,0 +1,20 @@ +Description: Explicitly target generic x86-64 ABI + The system compiler may be configured to target a higher x86-64 psABI by + default, so explicitly target the generic psABI to retain compatibility + with older machine types. +Author: dann frazier +Bug-Ubuntu: http://launchpad.net/bugs/1976267 +Forwarded: https://edk2.groups.io/g/devel/message/90447 +Last-Update: 2024-11-24 + +--- a/BaseTools/Conf/tools_def.template ++++ b/BaseTools/Conf/tools_def.template +@@ -962,7 +962,7 @@ + DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -fno-stack-protector -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20 + DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer +-DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer ++DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 -march=x86-64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer + DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable + DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive + DEFINE GCC48_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(GCC_DLINK2_FLAGS_COMMON) diff --git a/images/edk2/python/UEFI/Filesystems.py b/images/edk2/python/UEFI/Filesystems.py new file mode 100644 index 0000000000..923db30a19 --- /dev/null +++ b/images/edk2/python/UEFI/Filesystems.py @@ -0,0 +1,101 @@ +# +# Copyright 2019-2022 Canonical Ltd. +# Authors: +# - dann frazier +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# + +import os +import shutil +import subprocess +import tempfile + + +class FatFsImage: + def __init__(self, size_in_mb): + with tempfile.NamedTemporaryFile(delete=False) as f: + self.path = f.name + + subprocess.check_call( + [ + 'dd', 'if=/dev/zero', 'of=%s' % (self.path), + 'count=0', 'bs=1M', 'seek=%d' % (size_in_mb), 'status=none' + ] + ) + new_env = os.environ.copy() + new_env['PATH'] = f"{os.environ['PATH']}:/sbin" + subprocess.check_call(['mkdosfs', '-F', '32', self.path], env=new_env) + + def __del__(self): + os.unlink(self.path) + + def mkdir(self, dir): + subprocess.run(['mmd', '-i', self.path, dir]) + + def makedirs(self, dir): + dirs = dir.split(os.path.sep) + for dir_idx in range(1, len(dirs)+1): + next_dir = os.path.sep.join(dirs[:dir_idx]) + self.mkdir(next_dir) + + def insert_file(self, src, dest): + subprocess.check_call( + [ + 'mcopy', '-i', self.path, src, '::%s' % (dest) + ] + ) + + +class EfiBootableIsoImage: + def __init__(self, eltorito_img): + with tempfile.TemporaryDirectory() as iso_root: + eltorito_iso_root = 'boot' + eltorito_iso_path = os.path.join(eltorito_iso_root, 'efi.img') + eltorito_local_root = os.path.join(iso_root, eltorito_iso_root) + eltorito_local_path = os.path.join(iso_root, eltorito_iso_path) + + os.makedirs(eltorito_local_root) + shutil.copyfile(eltorito_img.path, eltorito_local_path) + + with tempfile.NamedTemporaryFile(delete=False) as f: + self.path = f.name + + subprocess.check_call( + [ + 'xorriso', '-as', 'mkisofs', '-J', '-l', + '-c', 'boot/boot.cat', + '-partition_offset', '16', '-append_partition', '2', + '0xef', eltorito_local_path, + '-e', '--interval:appended_partition_2:all::', + '-no-emul-boot', '-o', self.path, iso_root + ] + ) + + def __del__(self): + os.unlink(self.path) + + +class GrubShellBootableIsoImage(EfiBootableIsoImage): + def __init__(self, efi_arch, shim_path, grub_path): + efi_img = FatFsImage(64) + efi_img.makedirs(os.path.join('EFI', 'BOOT')) + removable_media_path = os.path.join( + 'EFI', 'BOOT', 'BOOT%s.EFI' % (efi_arch.upper()) + ) + grub_dest = os.path.join( + 'EFI', 'BOOT', 'GRUB%s.EFI' % (efi_arch.upper()) + ) + efi_img.insert_file(shim_path, removable_media_path) + efi_img.insert_file(grub_path, grub_dest) + super().__init__(efi_img) diff --git a/images/edk2/python/UEFI/Qemu.py b/images/edk2/python/UEFI/Qemu.py new file mode 100644 index 0000000000..13d2b3cdf5 --- /dev/null +++ b/images/edk2/python/UEFI/Qemu.py @@ -0,0 +1,216 @@ +# +# Copyright 2019-2021 Canonical Ltd. +# Authors: +# - dann frazier +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# + +import enum +import os +import shutil +import tempfile + + +class QemuEfiMachine(enum.Enum): + OVMF_PC = enum.auto() + OVMF_Q35 = enum.auto() + OVMF32_PC = enum.auto() + OVMF32_Q35 = enum.auto() + AAVMF = enum.auto() + AAVMF32 = enum.auto() + RISCV64 = enum.auto() + LOONGARCH64 = enum.auto() + + +class QemuEfiVariant(enum.Enum): + MS = enum.auto() + SECBOOT = enum.auto() + SNAKEOIL = enum.auto() + + +class QemuEfiFlashSize(enum.Enum): + DEFAULT = enum.auto() + SIZE_4MB = enum.auto() + + +class QemuCommand: + Qemu_Common_Params = [ + '-no-user-config', '-nodefaults', + '-m', '256', + '-smp', '1,sockets=1,cores=1,threads=1', + '-display', 'none', + '-serial', 'stdio', + ] + Aavmf_Common_Params = Qemu_Common_Params + [ + '-machine', 'virt', '-device', 'virtio-serial-device', + ] + LoongArch_Common_Params = Qemu_Common_Params + [ + '-machine', 'virt', + ] + Ovmf_Common_Params = Qemu_Common_Params + [ + '-chardev', 'pty,id=charserial1', + '-device', 'isa-serial,chardev=charserial1,id=serial1', + ] + RiscV_Common_Params = Qemu_Common_Params + [ + '-machine', 'virt', '-device', 'virtio-serial-device', + ] + Machine_Base_Command = { + QemuEfiMachine.AAVMF: [ + 'qemu-system-aarch64', '-cpu', 'cortex-a57', + ] + Aavmf_Common_Params, + QemuEfiMachine.AAVMF32: [ + 'qemu-system-aarch64', '-cpu', 'cortex-a15', + ] + Aavmf_Common_Params, + QemuEfiMachine.LOONGARCH64: [ + 'qemu-system-loongarch64', + ] + LoongArch_Common_Params, + QemuEfiMachine.OVMF_PC: [ + 'qemu-system-x86_64', '-machine', 'pc,accel=tcg', + ] + Ovmf_Common_Params, + QemuEfiMachine.OVMF_Q35: [ + 'qemu-system-x86_64', '-machine', 'q35,accel=tcg', + ] + Ovmf_Common_Params, + QemuEfiMachine.OVMF32_PC: [ + 'qemu-system-i386', '-machine', 'pc,accel=tcg', + ] + Ovmf_Common_Params, + QemuEfiMachine.OVMF32_Q35: [ + 'qemu-system-i386', '-machine', 'q35,accel=tcg', + ] + Ovmf_Common_Params, + QemuEfiMachine.RISCV64: [ + 'qemu-system-riscv64', + ] + RiscV_Common_Params, + } + + def _get_default_flash_paths(self, machine, variant, flash_size): + assert(machine in QemuEfiMachine) + assert(variant is None or variant in QemuEfiVariant) + assert(flash_size in QemuEfiFlashSize) + + code_ext = '.no-secboot' if machine == QemuEfiMachine.AAVMF else '' + vars_ext = '' + if variant == QemuEfiVariant.MS: + code_ext = vars_ext = '.ms' + elif variant == QemuEfiVariant.SECBOOT: + code_ext = '.secboot' + elif variant == QemuEfiVariant.SNAKEOIL: + code_ext = vars_ext = '.snakeoil' + + if variant == QemuEfiVariant.SNAKEOIL: + # We provide one size - you don't get to pick. + assert(flash_size == QemuEfiFlashSize.DEFAULT) + + if machine == QemuEfiMachine.AAVMF: + assert(flash_size == QemuEfiFlashSize.DEFAULT) + return ( + f'/usr/share/AAVMF/AAVMF_CODE{code_ext}.fd', + f'/usr/share/AAVMF/AAVMF_VARS{vars_ext}.fd', + ) + if machine == QemuEfiMachine.AAVMF32: + assert(variant is None) + assert(flash_size == QemuEfiFlashSize.DEFAULT) + return ( + '/usr/share/AAVMF/AAVMF32_CODE.fd', + '/usr/share/AAVMF/AAVMF32_VARS.fd' + ) + if machine == QemuEfiMachine.LOONGARCH64: + assert(variant is None) + assert(flash_size == QemuEfiFlashSize.DEFAULT) + return ( + '/usr/share/qemu-efi-loongarch64/QEMU_EFI.fd', + '/usr/share/qemu-efi-loongarch64/QEMU_VARS.fd', + ) + if machine == QemuEfiMachine.RISCV64: + assert(variant is None) + assert(flash_size == QemuEfiFlashSize.DEFAULT) + return ( + '/usr/share/qemu-efi-riscv64/RISCV_VIRT_CODE.fd', + '/usr/share/qemu-efi-riscv64/RISCV_VIRT_VARS.fd', + ) + # Remaining possibilities are OVMF variants + assert( + flash_size in [ + QemuEfiFlashSize.DEFAULT, QemuEfiFlashSize.SIZE_4MB + ] + ) + size_ext = '_4M' + if machine in [QemuEfiMachine.OVMF_PC, QemuEfiMachine.OVMF32_PC]: + assert(variant is None) + if machine == QemuEfiMachine.OVMF32_Q35: + assert(variant is None or variant == QemuEfiVariant.SECBOOT) + if machine in [QemuEfiMachine.OVMF32_PC, QemuEfiMachine.OVMF32_Q35]: + OVMF_ARCH = "OVMF32" + else: + OVMF_ARCH = "OVMF" + return ( + f'/usr/share/OVMF/{OVMF_ARCH}_CODE{size_ext}{code_ext}.fd', + f'/usr/share/OVMF/{OVMF_ARCH}_VARS{size_ext}{vars_ext}.fd' + ) + + def __init__( + self, machine, variant=None, + code_path=None, vars_template_path=None, + flash_size=QemuEfiFlashSize.DEFAULT, + ): + assert( + (code_path and vars_template_path) or + (not code_path and not vars_template_path) + ) + + if not code_path: + (code_path, vars_template_path) = self._get_default_flash_paths( + machine, variant, flash_size) + + self.pflash = self.PflashParams(code_path, vars_template_path) + self.command = self.Machine_Base_Command[machine] + self.pflash.params + + def add_disk(self, path): + self.command = self.command + [ + '-drive', 'file=%s,format=raw' % (path) + ] + + def add_oem_string(self, type, string): + string = string.replace(",", ",,") + self.command = self.command + [ + '-smbios', f'type={type},value={string}' + ] + + class PflashParams: + ''' + Used to generate the appropriate -pflash arguments for QEMU. Mostly + used as a fancy way to generate a per-instance vars file and have it + be automatically cleaned up when the object is destroyed. + ''' + def __init__(self, code_path, vars_template_path): + self.params = [ + '-drive', + 'file=%s,if=pflash,format=raw,unit=0,readonly=on' % + (code_path), + ] + if vars_template_path is None: + self.varfile_path = None + return + with tempfile.NamedTemporaryFile(delete=False) as varfile: + self.varfile_path = varfile.name + with open(vars_template_path, 'rb') as template: + shutil.copyfileobj(template, varfile) + self.params = self.params + [ + '-drive', + 'file=%s,if=pflash,format=raw,unit=1,readonly=off' % + (varfile.name) + ] + + def __del__(self): + if self.varfile_path is None: + return + os.unlink(self.varfile_path) diff --git a/images/edk2/python/UEFI/SignedBinary.py b/images/edk2/python/UEFI/SignedBinary.py new file mode 100644 index 0000000000..5bb33aae30 --- /dev/null +++ b/images/edk2/python/UEFI/SignedBinary.py @@ -0,0 +1,52 @@ +# +# Copyright 2022 Canonical Ltd. +# Authors: +# - dann frazier +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, +# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . +# + +import os +import subprocess +import tempfile + + +class SignedBinary: + def __init__(self, binary_path, key_path, cert_path, password=None): + openssl_password_args = [] + if password: + openssl_password_args = [ + "-passin", f"pass:{password}" + ] + with tempfile.NamedTemporaryFile() as keytmp: + subprocess.check_call( + [ + "openssl", "rsa", + ] + openssl_password_args + [ + "-in", f"{key_path}", + "-out", f"{keytmp.name}", + ] + ) + with tempfile.NamedTemporaryFile(delete=False) as f: + self.path = f.name + + subprocess.check_call( + [ + "sbsign", "--key", f"{keytmp.name}", + "--cert", f"{cert_path}", + binary_path, "--output", f"{self.path}" + ] + ) + + def __del__(self): + os.unlink(self.path) diff --git a/images/edk2/werf.inc.yaml b/images/edk2/werf.inc.yaml index 4eae5c7630..4cd8c40be9 100644 --- a/images/edk2/werf.inc.yaml +++ b/images/edk2/werf.inc.yaml @@ -11,9 +11,22 @@ git: to: / includePaths: - build.sh + - edk2-vars-generator.py + - python stageDependencies: setup: - build.sh +# add ubuntu patches +- add: /images/{{ $.ImageName }} + to: / + stageDependencies: + install: + - '**/*' + includePaths: + - patches + excludePaths: + - patches/README.md + - add: /images/{{ $.ImageName }}/logo to: / includePaths: @@ -52,7 +65,9 @@ shell: dosfstools mtools genisoimage binutils-devel \ qemu-kvm-core \ iasl \ - python3-modules-sqlite3 python3-module-virt-firmware libuuid-devel \ + python3-modules-sqlite3 python3-module-virt-firmware \ + python3-module-pexpect python3-module-ptyprocess \ + libuuid-devel \ qemu-img xorriso libssl-devel \ bc zlib-devel perl-PathTools perl-IPC-Cmd perl-JSON @@ -68,7 +83,16 @@ shell: cd {{ $gitRepoName }}-{{ $version }} git submodule update --init --recursive + # apply patches + for p in /patches/*.patch ; do + echo -n "Apply ${p} ... " + git apply --ignore-space-change --ignore-whitespace ${p} && echo OK || (echo FAIL ; exit 1) + done + + setup: + - | # Set env edk + cd {{ $gitRepoName }}-{{ $version }} export EDK_TOOLS_PATH=$(pwd)/BaseTools export PACKAGES_PATH=$(pwd)/BaseTools:/edk2-platforms @@ -76,7 +100,11 @@ shell: ln /usr/bin/python3 /usr/bin/python make -C BaseTools -j$(nproc) 2>&1 > /dev/null - setup: - - | + echo "run . edksetup.sh" + . ./edksetup.sh + /build.sh --repo-name {{ $gitRepoName }} --branch {{ $version }} + echo "List /FIRMWARE" + ls -lah /FIRMWARE + diff --git a/images/virt-artifact/patches/029-use-OFVM_CODE-for-linux.patch b/images/virt-artifact/patches/029-use-OFVM_CODE-for-linux.off_patch similarity index 100% rename from images/virt-artifact/patches/029-use-OFVM_CODE-for-linux.patch rename to images/virt-artifact/patches/029-use-OFVM_CODE-for-linux.off_patch diff --git a/images/virt-artifact/patches/037-set-ReadOnlyRootFilesystem-to-virt-launcher.patch b/images/virt-artifact/patches/037-set-ReadOnlyRootFilesystem-to-virt-launcher.off_patch similarity index 100% rename from images/virt-artifact/patches/037-set-ReadOnlyRootFilesystem-to-virt-launcher.patch rename to images/virt-artifact/patches/037-set-ReadOnlyRootFilesystem-to-virt-launcher.off_patch diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index b541c06774..cb7c9b9f17 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -29,6 +29,7 @@ packages: image: {{ $.ImageName }} final: false fromImage: base-alt-p11 +cacheVersion: "11042025.2" mount: - fromPath: ~/go-pkg-cache to: /go/pkg diff --git a/images/virt-launcher/configs/qemu.conf b/images/virt-launcher/configs/qemu.conf index 4e4c59e393..225231e80e 100644 --- a/images/virt-launcher/configs/qemu.conf +++ b/images/virt-launcher/configs/qemu.conf @@ -4,6 +4,8 @@ vnc_tls = 0 vnc_sasl = 0 user = "qemu" group = "qemu" +swtpm_user = "root" +swtpm_group = "root" dynamic_ownership = 1 remember_owner = 0 namespaces = [ ] diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 1a3ff8b1b0..5b96818a66 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -103,9 +103,9 @@ libs: - libbsd-devel - libsystemd-devel - libjson-c-devel + - libjson-glib - systemtap-sdt-devel - libacl-devel - - libtpms-devel libtpms - glib2-devel - libgio-devel - libxml2-devel @@ -113,7 +113,6 @@ libs: - libtirpc-devel - libclocale - libLLVMSPIRVLib-devel - - libswtpm-devel packages: - acl - attr @@ -239,8 +238,8 @@ import: - vlctl - image: packages/binaries/swtpm add: /swtpm - to: /relocate - after: setup + to: /VBINS + before: install - image: {{ $.ImageName }}-cbuilder add: /bins to: /relocate/usr/bin @@ -252,12 +251,24 @@ shell: - | apt-get update && apt-get install -y {{ $virtLauncherDependencies.libs | join " " }} {{ $virtLauncherDependencies.packages | join " " }} + # libtpms libtpms-devel requares version 0.10 that in sisyphus repo + cat >/etc/apt/sources.list.d/alt-sisyphus.list<