From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web10.183457.1673911935704512234 for ; Mon, 16 Jan 2023 15:32:24 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Q+w4hMP+; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: min.m.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673911944; x=1705447944; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1wY39PU/DDP9L8cl/i/2nMdMfOranRs946IUWYm0tbc=; b=Q+w4hMP+eu75YDFRidOzpIZ85jrB12+rNmvx9zIaI+TnBrx0W1ILff+Z FIERdynOU3Y9VITfh/r4HmOxmZvHFL7fqEz/gKRWaHpvBS//1POPmHVhE vMXW3BLzy1+RHeg7k4b17iQpmNjkYyMGsUO/24eSSIvGwy0enls9gjCku 2R/ZPcVfP1I6ngn7psaZNoVxessw1SdPwje54vkWY52D3izOQxIKSb+zp CVX5KSrvgMOWI1/n9lcBV6cMEqdLWNC5ih2y+hDDfMC3ww1ewiWwBvLGt vASu+0gbk7N9/c9wzMLfzLeHu9vTRUACHA/SJOoydwI/thLISfIdB2Ap2 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10592"; a="312432556" X-IronPort-AV: E=Sophos;i="5.97,222,1669104000"; d="scan'208";a="312432556" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jan 2023 15:32:23 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10592"; a="987930951" X-IronPort-AV: E=Sophos;i="5.97,222,1669104000"; d="scan'208";a="987930951" Received: from huiyanxi-mobl.ccr.corp.intel.com (HELO mxu9-mobl1.ccr.corp.intel.com) ([10.254.211.139]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jan 2023 15:32:21 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min M Xu , Gerd Hoffmann , Erdem Aktas , James Bottomley , Jiewen Yao , Tom Lendacky Subject: [PATCH V3 4/4] OvmfPkg/PeilessStartupLib: Find NCCFV in non-td guest Date: Tue, 17 Jan 2023 07:31:58 +0800 Message-Id: <20230116233158.1268-5-min.m.xu@intel.com> X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: <20230116233158.1268-1-min.m.xu@intel.com> References: <20230116233158.1268-1-min.m.xu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Min M Xu BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4152 As described in BZ#4152, NCCFV includes the DXE phase drivers for non-cc guest. PeilessStartupLib is updated to find NCCFV for non-cc guest. Cc: Gerd Hoffmann Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Signed-off-by: Min Xu --- OvmfPkg/Library/PeilessStartupLib/DxeLoad.c | 134 +++++++++++++++++- .../PeilessStartupInternal.h | 6 + .../PeilessStartupLib/PeilessStartupLib.inf | 1 + 3 files changed, 140 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c index 6e79c3084672..4b1fefd452dc 100644 --- a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c +++ b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c @@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #define STACK_SIZE 0x20000 +extern EFI_GUID gEfiNonCcFvGuid; /** Transfers control to DxeCore. @@ -136,6 +137,133 @@ FindDxeCore ( return Status; } +/** + * This is a FFS_CHECK_SECTION_HOOK which is defined by caller to check + * if the section is an EFI_SECTION_FIRMWARE_VOLUME_IMAGE and if it is + * a NonCc FV. + * + * @param Section The section in which we're checking for the NonCc FV. + * @return EFI_STATUS The section is the NonCc FV. + */ +EFI_STATUS +EFIAPI +CheckSectionHookForDxeNonCc ( + IN EFI_COMMON_SECTION_HEADER *Section + ) +{ + VOID *Buffer; + EFI_STATUS Status; + EFI_FV_INFO FvImageInfo; + + if (Section->Type != EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { + return EFI_INVALID_PARAMETER; + } + + if (IS_SECTION2 (Section)) { + Buffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + Buffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + + ZeroMem (&FvImageInfo, sizeof (FvImageInfo)); + Status = FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE)(UINTN)Buffer, &FvImageInfo); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Cannot get volume info! %r\n", Status)); + return Status; + } + + return CompareGuid (&FvImageInfo.FvName, &gEfiNonCcFvGuid) ? EFI_SUCCESS : EFI_NOT_FOUND; +} + +/** + * Find the NonCc FV. + * + * @param FvInstance The FvInstance number. + * @return EFI_STATUS Successfuly find the NonCc FV. + */ +EFI_STATUS +EFIAPI +FindDxeNonCc ( + IN INTN FvInstance + ) +{ + EFI_STATUS Status; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + EFI_PEI_FV_HANDLE FvImageHandle; + EFI_FV_INFO FvImageInfo; + UINT32 FvAlignment; + VOID *FvBuffer; + + FileHandle = NULL; + + // + // Caller passed in a specific FV to try, so only try that one + // + Status = FfsFindNextVolume (FvInstance, &VolumeHandle); + ASSERT (Status == EFI_SUCCESS); + + Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, VolumeHandle, &FileHandle); + ASSERT (FileHandle != NULL); + + // + // Find FvImage in FvFile + // + Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, CheckSectionHookForDxeNonCc, FileHandle, (VOID **)&FvImageHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Collect FvImage Info. + // + ZeroMem (&FvImageInfo, sizeof (FvImageInfo)); + Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo); + ASSERT_EFI_ERROR (Status); + + // + // FvAlignment must be more than 8 bytes required by FvHeader structure. + // + FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16); + if (FvAlignment < 8) { + FvAlignment = 8; + } + + // + // Check FvImage + // + if ((UINTN)FvImageInfo.FvStart % FvAlignment != 0) { + FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32)FvImageInfo.FvSize), FvAlignment); + if (FvBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN)FvImageInfo.FvSize); + // + // Update FvImageInfo after reload FvImage to new aligned memory + // + FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE)FvBuffer, &FvImageInfo); + } + + // + // Inform HOB consumer phase, i.e. DXE core, the existence of this FV + // + BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart, FvImageInfo.FvSize); + + // + // Makes the encapsulated volume show up in DXE phase to skip processing of + // encapsulated file again. + // + BuildFv2Hob ( + (EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart, + FvImageInfo.FvSize, + &FvImageInfo.FvName, + &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name) + ); + + return Status; +} + /** This function finds DXE Core in the firmware volume and transfer the control to DXE core. @@ -168,10 +296,14 @@ DxeLoadCore ( return Status; } + if (!TdIsEnabled ()) { + FindDxeNonCc (FvInstance); + } + // // Load the DXE Core from a Firmware Volume. // - Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); + Status = FfsFindSectionData (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage); if (EFI_ERROR (Status)) { return Status; } diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h index 09cac3e26c67..f56bc3578e5e 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h @@ -21,6 +21,12 @@ DxeLoadCore ( IN INTN FvInstance ); +EFI_STATUS +EFIAPI +FindDxeNonCc ( + IN INTN FvInstance + ); + VOID EFIAPI TransferHobList ( diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf index def50b4b019e..5c6eb1597bea 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf @@ -67,6 +67,7 @@ gEfiMemoryTypeInformationGuid gPcdDataBaseHobGuid gCcEventEntryHobGuid + gEfiNonCcFvGuid [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase -- 2.29.2.windows.2