OvmfPkg/PeilessStartupLib: Find NCCFV in non-td guest

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 <kraxel@redhat.com>
Cc: Erdem Aktas <erdemaktas@google.com>
Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Min Xu <min.m.xu@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Min M Xu 2023-01-17 07:31:58 +08:00 committed by mergify[bot]
parent c3f4f5a949
commit 70d1481b55
3 changed files with 140 additions and 1 deletions

View File

@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/ReportStatusCodeLib.h> #include <Library/ReportStatusCodeLib.h>
#define STACK_SIZE 0x20000 #define STACK_SIZE 0x20000
extern EFI_GUID gEfiNonCcFvGuid;
/** /**
Transfers control to DxeCore. Transfers control to DxeCore.
@ -136,6 +137,133 @@ FindDxeCore (
return Status; 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 This function finds DXE Core in the firmware volume and transfer the control to
DXE core. DXE core.
@ -168,10 +296,14 @@ DxeLoadCore (
return Status; return Status;
} }
if (!TdIsEnabled ()) {
FindDxeNonCc (FvInstance);
}
// //
// Load the DXE Core from a Firmware Volume. // 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)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }

View File

@ -21,6 +21,12 @@ DxeLoadCore (
IN INTN FvInstance IN INTN FvInstance
); );
EFI_STATUS
EFIAPI
FindDxeNonCc (
IN INTN FvInstance
);
VOID VOID
EFIAPI EFIAPI
TransferHobList ( TransferHobList (

View File

@ -67,6 +67,7 @@
gEfiMemoryTypeInformationGuid gEfiMemoryTypeInformationGuid
gPcdDataBaseHobGuid gPcdDataBaseHobGuid
gCcEventEntryHobGuid gCcEventEntryHobGuid
gEfiNonCcFvGuid
[Pcd] [Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase