From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.groups.io with SMTP id smtpd.web10.41961.1658243574635426846 for ; Tue, 19 Jul 2022 08:12:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NJcIA16k; spf=pass (domain: redhat.com, ip: 170.10.133.124, mailfrom: kraxel@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1658243573; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=g1P3MrgpbVrjbe6c3/4IL/ceXkLNp2ox+iI7M9R2XL8=; b=NJcIA16kthJMqi43vyj4wNnfGeSCojhC+lVOxwykVmrL1j+URRUTcnSbxghZxJEmvmA6FY RqoZ+s4usiY8NcCYzF6oPtVbm+ALsybVoScFN/7upko7lirZqYda1cUdLlnH52NYxJwLfw 9Jna1TtHTFIEy5SG0OMPIOSZ/cR4eK8= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-58-aiFiM_xNPCOWoW2jnUP6Qg-1; Tue, 19 Jul 2022 11:12:51 -0400 X-MC-Unique: aiFiM_xNPCOWoW2jnUP6Qg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AD6E03C0CD46; Tue, 19 Jul 2022 15:12:50 +0000 (UTC) Received: from sirius.home.kraxel.org (unknown [10.39.192.134]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 19712C28133; Tue, 19 Jul 2022 15:12:50 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 96B0818000A3; Tue, 19 Jul 2022 17:12:48 +0200 (CEST) From: "Gerd Hoffmann" To: devel@edk2.groups.io Cc: Anthony Perard , Jiewen Yao , Ard Biesheuvel , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Oliver Steffen , Jordan Justen , Stefan Berger , Gerd Hoffmann , Julien Grall , Pawel Polawski Subject: [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder() Date: Tue, 19 Jul 2022 17:12:48 +0200 Message-Id: <20220719151248.824512-1-kraxel@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.8 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=kraxel@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true 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 --- 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: \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