* [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
@ 2022-07-19 15:12 Gerd Hoffmann
2022-09-06 16:56 ` Ard Biesheuvel
0 siblings, 1 reply; 2+ messages in thread
From: Gerd Hoffmann @ 2022-07-19 15:12 UTC (permalink / raw)
To: devel
Cc: Anthony Perard, Jiewen Yao, Ard Biesheuvel,
Marc-André Lureau, Oliver Steffen, Jordan Justen,
Stefan Berger, Gerd Hoffmann, Julien Grall, Pawel Polawski
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>
---
OvmfPkg/OvmfPkg.dec | 1 +
.../QemuBootOrderLib/QemuBootOrderLib.inf | 1 +
OvmfPkg/Include/Library/QemuBootOrderLib.h | 14 ++
.../PlatformBootManagerLib/BdsPlatform.c | 5 +
.../QemuBootOrderLib/QemuBootOrderLib.c | 122 ++++++++++++++++++
5 files changed, 143 insertions(+)
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 5af76a540529..6b1296b15afa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -146,6 +146,7 @@ [Guids]
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
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
index 7c02f04e7009..211344fb0b89 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
@@ -49,6 +49,7 @@ [LibraryClasses]
[Guids]
gEfiGlobalVariableGuid
gVirtioMmioTransportGuid
+ gQemuBootOrderGuid
[FeaturePcd]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
diff --git a/OvmfPkg/Include/Library/QemuBootOrderLib.h b/OvmfPkg/Include/Library/QemuBootOrderLib.h
index 9f06439aed1e..f0369298a134 100644
--- a/OvmfPkg/Include/Library/QemuBootOrderLib.h
+++ b/OvmfPkg/Include/Library/QemuBootOrderLib.h
@@ -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.
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 51016a5548cb..98f6f07341ec 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1694,6 +1694,11 @@ PlatformBootManagerAfterConsole (
//
PciAcpiInitialization ();
+ //
+ // Write qemu bootorder to efi variables
+ //
+ StoreQemuBootOrder ();
+
//
// Process QEMU's -kernel command line option
//
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
index 67d29ac6429f..398de7fab4ba 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
@@ -1686,6 +1686,128 @@ ConnectDevicesFromQemu (
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,
--
2.36.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
2022-07-19 15:12 [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder() Gerd Hoffmann
@ 2022-09-06 16:56 ` Ard Biesheuvel
0 siblings, 0 replies; 2+ messages in thread
From: Ard Biesheuvel @ 2022-09-06 16:56 UTC (permalink / raw)
To: Gerd Hoffmann
Cc: devel, Anthony Perard, Jiewen Yao, Marc-André Lureau,
Oliver Steffen, Jordan Justen, Stefan Berger, Julien Grall,
Pawel Polawski
On Tue, 19 Jul 2022 at 17:12, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> 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
Merged as #3298
> ---
> OvmfPkg/OvmfPkg.dec | 1 +
> .../QemuBootOrderLib/QemuBootOrderLib.inf | 1 +
> OvmfPkg/Include/Library/QemuBootOrderLib.h | 14 ++
> .../PlatformBootManagerLib/BdsPlatform.c | 5 +
> .../QemuBootOrderLib/QemuBootOrderLib.c | 122 ++++++++++++++++++
> 5 files changed, 143 insertions(+)
>
> diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
> index 5af76a540529..6b1296b15afa 100644
> --- a/OvmfPkg/OvmfPkg.dec
> +++ b/OvmfPkg/OvmfPkg.dec
> @@ -146,6 +146,7 @@ [Guids]
> 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
> diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
> index 7c02f04e7009..211344fb0b89 100644
> --- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
> +++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
> @@ -49,6 +49,7 @@ [LibraryClasses]
> [Guids]
> gEfiGlobalVariableGuid
> gVirtioMmioTransportGuid
> + gQemuBootOrderGuid
>
> [FeaturePcd]
> gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
> diff --git a/OvmfPkg/Include/Library/QemuBootOrderLib.h b/OvmfPkg/Include/Library/QemuBootOrderLib.h
> index 9f06439aed1e..f0369298a134 100644
> --- a/OvmfPkg/Include/Library/QemuBootOrderLib.h
> +++ b/OvmfPkg/Include/Library/QemuBootOrderLib.h
> @@ -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.
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index 51016a5548cb..98f6f07341ec 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -1694,6 +1694,11 @@ PlatformBootManagerAfterConsole (
> //
> PciAcpiInitialization ();
>
> + //
> + // Write qemu bootorder to efi variables
> + //
> + StoreQemuBootOrder ();
> +
> //
> // Process QEMU's -kernel command line option
> //
> diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
> index 67d29ac6429f..398de7fab4ba 100644
> --- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
> +++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
> @@ -1686,6 +1686,128 @@ ConnectDevicesFromQemu (
> 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,
> --
> 2.36.1
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-09-06 16:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-19 15:12 [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder() Gerd Hoffmann
2022-09-06 16:56 ` Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox