summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2022-07-19 17:12:48 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-09-06 16:55:33 +0000
commit5eeb088ad64124229b32a5593fada578b935e207 (patch)
treef58e93ffd1eb3120e04e70da64cd66a20497f306
parentdb463e8e9da6f19becb336645dad3718de0743d3 (diff)
downloadedk2-5eeb088ad64124229b32a5593fada578b935e207.tar.gz
edk2-5eeb088ad64124229b32a5593fada578b935e207.tar.bz2
edk2-5eeb088ad64124229b32a5593fada578b935e207.zip
OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
The function reads the boot order from qemu fw_cfg, translates it into device paths and stores them in 'QemuBootOrderNNNN' variables. In case there is no boot ordering configured the function will do nothing. Use case: Allow applications loaded via 'qemu -kernel bootloader.efi' obey the boot order. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
-rw-r--r--OvmfPkg/Include/Library/QemuBootOrderLib.h14
-rw-r--r--OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c5
-rw-r--r--OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c122
-rw-r--r--OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf1
-rw-r--r--OvmfPkg/OvmfPkg.dec1
5 files changed, 143 insertions, 0 deletions
diff --git a/OvmfPkg/Include/Library/QemuBootOrderLib.h b/OvmfPkg/Include/Library/QemuBootOrderLib.h
index 9f06439aed..f0369298a1 100644
--- a/OvmfPkg/Include/Library/QemuBootOrderLib.h
+++ b/OvmfPkg/Include/Library/QemuBootOrderLib.h
@@ -48,6 +48,20 @@ ConnectDevicesFromQemu (
);
/**
+ Write qemu boot order to uefi variables.
+
+ Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate
+ the OpenFirmware device paths therein to UEFI device path fragments.
+
+ On Success store the device path in QemuBootOrderNNNN variables.
+**/
+VOID
+EFIAPI
+StoreQemuBootOrder (
+ VOID
+ );
+
+/**
Set the boot order based on configuration retrieved from QEMU.
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 51016a5548..98f6f07341 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1695,6 +1695,11 @@ PlatformBootManagerAfterConsole (
PciAcpiInitialization ();
//
+ // Write qemu bootorder to efi variables
+ //
+ StoreQemuBootOrder ();
+
+ //
// Process QEMU's -kernel command line option
//
TryRunningQemuKernel ();
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
index 67d29ac642..398de7fab4 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
@@ -1687,6 +1687,128 @@ FreeFwCfg:
}
/**
+ Write qemu boot order to uefi variables.
+
+ Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate
+ the OpenFirmware device paths therein to UEFI device path fragments.
+
+ On Success store the device path in QemuBootOrderNNNN variables.
+**/
+VOID
+EFIAPI
+StoreQemuBootOrder (
+ VOID
+ )
+{
+ RETURN_STATUS Status;
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
+ UINTN FwCfgSize;
+ CHAR8 *FwCfg;
+ EFI_STATUS EfiStatus;
+ EXTRA_ROOT_BUS_MAP *ExtraPciRoots;
+ CONST CHAR8 *FwCfgPtr;
+ UINTN TranslatedSize;
+ CHAR16 Translated[TRANSLATION_OUTPUT_SIZE];
+ UINTN VariableIndex = 0;
+ CHAR16 VariableName[20];
+
+ Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
+ if (RETURN_ERROR (Status)) {
+ return;
+ }
+
+ if (FwCfgSize == 0) {
+ return;
+ }
+
+ FwCfg = AllocatePool (FwCfgSize);
+ if (FwCfg == NULL) {
+ return;
+ }
+
+ QemuFwCfgSelectItem (FwCfgItem);
+ QemuFwCfgReadBytes (FwCfgSize, FwCfg);
+ if (FwCfg[FwCfgSize - 1] != '\0') {
+ Status = RETURN_INVALID_PARAMETER;
+ goto FreeFwCfg;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));
+ DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));
+ DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));
+
+ if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
+ EfiStatus = CreateExtraRootBusMap (&ExtraPciRoots);
+ if (EFI_ERROR (EfiStatus)) {
+ Status = (RETURN_STATUS)EfiStatus;
+ goto FreeFwCfg;
+ }
+ } else {
+ ExtraPciRoots = NULL;
+ }
+
+ //
+ // Translate each OpenFirmware path to a UEFI devpath prefix.
+ //
+ FwCfgPtr = FwCfg;
+ TranslatedSize = ARRAY_SIZE (Translated);
+ Status = TranslateOfwPath (
+ &FwCfgPtr,
+ ExtraPciRoots,
+ Translated,
+ &TranslatedSize
+ );
+ while (!RETURN_ERROR (Status)) {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Convert the UEFI devpath prefix to binary representation.
+ //
+ ASSERT (Translated[TranslatedSize] == L'\0');
+ DevicePath = ConvertTextToDevicePath (Translated);
+ if (DevicePath == NULL) {
+ Status = RETURN_OUT_OF_RESOURCES;
+ goto FreeExtraPciRoots;
+ }
+
+ UnicodeSPrint (
+ VariableName,
+ sizeof (VariableName),
+ L"QemuBootOrder%04d",
+ VariableIndex++
+ );
+ DEBUG ((DEBUG_INFO, "%a: %s = %s\n", __FUNCTION__, VariableName, Translated));
+ gRT->SetVariable (
+ VariableName,
+ &gQemuBootOrderGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ GetDevicePathSize (DevicePath),
+ DevicePath
+ );
+ FreePool (DevicePath);
+
+ //
+ // Move to the next OFW devpath.
+ //
+ TranslatedSize = ARRAY_SIZE (Translated);
+ Status = TranslateOfwPath (
+ &FwCfgPtr,
+ ExtraPciRoots,
+ Translated,
+ &TranslatedSize
+ );
+ }
+
+FreeExtraPciRoots:
+ if (ExtraPciRoots != NULL) {
+ DestroyExtraRootBusMap (ExtraPciRoots);
+ }
+
+FreeFwCfg:
+ FreePool (FwCfg);
+}
+
+/**
Convert the UEFI DevicePath to full text representation with DevPathToText,
then match the UEFI device path fragment in Translated against it.
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
index 7c02f04e70..211344fb0b 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
@@ -49,6 +49,7 @@
[Guids]
gEfiGlobalVariableGuid
gVirtioMmioTransportGuid
+ gQemuBootOrderGuid
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 5af76a5405..6b1296b15a 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -146,6 +146,7 @@
gConfidentialComputingSecretGuid = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
gConfidentialComputingSevSnpBlobGuid = {0x067b1f5f, 0xcf26, 0x44c5, {0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42}}
gUefiOvmfPkgPlatformInfoGuid = {0xdec9b486, 0x1f16, 0x47c7, {0x8f, 0x68, 0xdf, 0x1a, 0x41, 0x88, 0x8b, 0xa5}}
+ gQemuBootOrderGuid = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
[Ppis]
# PPI whose presence in the PPI database signals that the TPM base address