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>
This commit is contained in:
Gerd Hoffmann 2022-07-19 17:12:48 +02:00 committed by mergify[bot]
parent db463e8e9d
commit 5eeb088ad6
5 changed files with 143 additions and 0 deletions

View File

@ -47,6 +47,20 @@ ConnectDevicesFromQemu (
VOID
);
/**
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.

View File

@ -1694,6 +1694,11 @@ PlatformBootManagerAfterConsole (
//
PciAcpiInitialization ();
//
// Write qemu bootorder to efi variables
//
StoreQemuBootOrder ();
//
// Process QEMU's -kernel command line option
//

View File

@ -1686,6 +1686,128 @@ FreeFwCfg:
return Status;
}
/**
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,

View File

@ -49,6 +49,7 @@
[Guids]
gEfiGlobalVariableGuid
gVirtioMmioTransportGuid
gQemuBootOrderGuid
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation

View File

@ -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