]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
authorGerd Hoffmann <kraxel@redhat.com>
Tue, 19 Jul 2022 15:12:48 +0000 (17:12 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 6 Sep 2022 16:55:33 +0000 (16:55 +0000)
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>
OvmfPkg/Include/Library/QemuBootOrderLib.h
OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
OvmfPkg/OvmfPkg.dec

index 9f06439aed1e6b56150c086648b723bf365a4c0a..f0369298a134cb9b5250b0cc309b079de538e186 100644 (file)
@@ -47,6 +47,20 @@ ConnectDevicesFromQemu (
   VOID\r
   );\r
 \r
+/**\r
+  Write qemu boot order to uefi variables.\r
+\r
+  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate\r
+  the OpenFirmware device paths therein to UEFI device path fragments.\r
+\r
+  On Success store the device path in QemuBootOrderNNNN variables.\r
+**/\r
+VOID\r
+EFIAPI\r
+StoreQemuBootOrder (\r
+  VOID\r
+  );\r
+\r
 /**\r
 \r
   Set the boot order based on configuration retrieved from QEMU.\r
index 51016a5548cb68dea4986e5c6c53358a9322ab9f..98f6f07341ec27e54a7607d63f07bab742dd4d4d 100644 (file)
@@ -1694,6 +1694,11 @@ PlatformBootManagerAfterConsole (
   //\r
   PciAcpiInitialization ();\r
 \r
+  //\r
+  // Write qemu bootorder to efi variables\r
+  //\r
+  StoreQemuBootOrder ();\r
+\r
   //\r
   // Process QEMU's -kernel command line option\r
   //\r
index 67d29ac6429fd5130b30bc022de083b1844b89e3..398de7fab4ba8b771c2947a12b43407cb93c9c2d 100644 (file)
@@ -1686,6 +1686,128 @@ FreeFwCfg:
   return Status;\r
 }\r
 \r
+/**\r
+  Write qemu boot order to uefi variables.\r
+\r
+  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate\r
+  the OpenFirmware device paths therein to UEFI device path fragments.\r
+\r
+  On Success store the device path in QemuBootOrderNNNN variables.\r
+**/\r
+VOID\r
+EFIAPI\r
+StoreQemuBootOrder (\r
+  VOID\r
+  )\r
+{\r
+  RETURN_STATUS         Status;\r
+  FIRMWARE_CONFIG_ITEM  FwCfgItem;\r
+  UINTN                 FwCfgSize;\r
+  CHAR8                 *FwCfg;\r
+  EFI_STATUS            EfiStatus;\r
+  EXTRA_ROOT_BUS_MAP    *ExtraPciRoots;\r
+  CONST CHAR8           *FwCfgPtr;\r
+  UINTN                 TranslatedSize;\r
+  CHAR16                Translated[TRANSLATION_OUTPUT_SIZE];\r
+  UINTN                 VariableIndex = 0;\r
+  CHAR16                VariableName[20];\r
+\r
+  Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);\r
+  if (RETURN_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  if (FwCfgSize == 0) {\r
+    return;\r
+  }\r
+\r
+  FwCfg = AllocatePool (FwCfgSize);\r
+  if (FwCfg == NULL) {\r
+    return;\r
+  }\r
+\r
+  QemuFwCfgSelectItem (FwCfgItem);\r
+  QemuFwCfgReadBytes (FwCfgSize, FwCfg);\r
+  if (FwCfg[FwCfgSize - 1] != '\0') {\r
+    Status = RETURN_INVALID_PARAMETER;\r
+    goto FreeFwCfg;\r
+  }\r
+\r
+  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));\r
+  DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));\r
+  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));\r
+\r
+  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {\r
+    EfiStatus = CreateExtraRootBusMap (&ExtraPciRoots);\r
+    if (EFI_ERROR (EfiStatus)) {\r
+      Status = (RETURN_STATUS)EfiStatus;\r
+      goto FreeFwCfg;\r
+    }\r
+  } else {\r
+    ExtraPciRoots = NULL;\r
+  }\r
+\r
+  //\r
+  // Translate each OpenFirmware path to a UEFI devpath prefix.\r
+  //\r
+  FwCfgPtr       = FwCfg;\r
+  TranslatedSize = ARRAY_SIZE (Translated);\r
+  Status         = TranslateOfwPath (\r
+                     &FwCfgPtr,\r
+                     ExtraPciRoots,\r
+                     Translated,\r
+                     &TranslatedSize\r
+                     );\r
+  while (!RETURN_ERROR (Status)) {\r
+    EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+\r
+    //\r
+    // Convert the UEFI devpath prefix to binary representation.\r
+    //\r
+    ASSERT (Translated[TranslatedSize] == L'\0');\r
+    DevicePath = ConvertTextToDevicePath (Translated);\r
+    if (DevicePath == NULL) {\r
+      Status = RETURN_OUT_OF_RESOURCES;\r
+      goto FreeExtraPciRoots;\r
+    }\r
+\r
+    UnicodeSPrint (\r
+      VariableName,\r
+      sizeof (VariableName),\r
+      L"QemuBootOrder%04d",\r
+      VariableIndex++\r
+      );\r
+    DEBUG ((DEBUG_INFO, "%a: %s = %s\n", __FUNCTION__, VariableName, Translated));\r
+    gRT->SetVariable (\r
+           VariableName,\r
+           &gQemuBootOrderGuid,\r
+           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+           GetDevicePathSize (DevicePath),\r
+           DevicePath\r
+           );\r
+    FreePool (DevicePath);\r
+\r
+    //\r
+    // Move to the next OFW devpath.\r
+    //\r
+    TranslatedSize = ARRAY_SIZE (Translated);\r
+    Status         = TranslateOfwPath (\r
+                       &FwCfgPtr,\r
+                       ExtraPciRoots,\r
+                       Translated,\r
+                       &TranslatedSize\r
+                       );\r
+  }\r
+\r
+FreeExtraPciRoots:\r
+  if (ExtraPciRoots != NULL) {\r
+    DestroyExtraRootBusMap (ExtraPciRoots);\r
+  }\r
+\r
+FreeFwCfg:\r
+  FreePool (FwCfg);\r
+}\r
+\r
 /**\r
 \r
   Convert the UEFI DevicePath to full text representation with DevPathToText,\r
index 7c02f04e70095b876e9309a1474e64c71674c76d..211344fb0b8927f282ae6d4f2a9d6b5ab27165b0 100644 (file)
@@ -49,6 +49,7 @@
 [Guids]\r
   gEfiGlobalVariableGuid\r
   gVirtioMmioTransportGuid\r
+  gQemuBootOrderGuid\r
 \r
 [FeaturePcd]\r
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation\r
index 5af76a540529c7bf887a9490319c05de1107fa73..6b1296b15afab1c9ac82e2aa2912ef64d0d0ae19 100644 (file)
   gConfidentialComputingSecretGuid      = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}\r
   gConfidentialComputingSevSnpBlobGuid  = {0x067b1f5f, 0xcf26, 0x44c5, {0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42}}\r
   gUefiOvmfPkgPlatformInfoGuid          = {0xdec9b486, 0x1f16, 0x47c7, {0x8f, 0x68, 0xdf, 0x1a, 0x41, 0x88, 0x8b, 0xa5}}\r
+  gQemuBootOrderGuid                    = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}\r
 \r
 [Ppis]\r
   # PPI whose presence in the PPI database signals that the TPM base address\r