X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;ds=sidebyside;f=OvmfPkg%2FLibrary%2FPlatformInitLib%2FIntelTdx.c;fp=OvmfPkg%2FLibrary%2FPlatformInitLib%2FIntelTdx.c;h=ada8592ddd5a5c7d3b461b2e3ea462ef4e59973f;hb=c0984d1ff28325a8f1c76e23a79141cbb12c3e4f;hp=6cb63139cba0da5858afe15ae36294053983227a;hpb=852ae4cd80f37e2521160e5b1f12c7dcca2d6048;p=mirror_edk2.git diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c index 6cb63139cb..ada8592ddd 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -16,779 +16,11 @@ #include #include #include -#include -#include #include -#include -#include -#include #include #include #include -#define ALIGNED_2MB_MASK 0x1fffff -#define MEGABYTE_SHIFT 20 - -#define ACCEPT_CHUNK_SIZE SIZE_32MB -#define AP_STACK_SIZE SIZE_16KB -#define APS_STACK_SIZE(CpusNum) (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB)) - -/** - This function will be called to accept pages. Only BSP accepts pages. - - TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To - simplify the implementation, the Memory to be accpeted is splitted - into 3 parts: - ----------------- <-- StartAddress1 (not 2M aligned) - | part 1 | Length1 < 2M - |---------------| <-- StartAddress2 (2M aligned) - | | Length2 = Integer multiples of 2M - | part 2 | - | | - |---------------| <-- StartAddress3 - | part 3 | Length3 < 2M - |---------------| - - @param[in] PhysicalAddress Start physical adress - @param[in] PhysicalEnd End physical address - - @retval EFI_SUCCESS Accept memory successfully - @retval Others Other errors as indicated -**/ -EFI_STATUS -EFIAPI -BspAcceptMemoryResourceRange ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN EFI_PHYSICAL_ADDRESS PhysicalEnd - ) -{ - EFI_STATUS Status; - UINT32 AcceptPageSize; - UINT64 StartAddress1; - UINT64 StartAddress2; - UINT64 StartAddress3; - UINT64 TotalLength; - UINT64 Length1; - UINT64 Length2; - UINT64 Length3; - UINT64 Pages; - - AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize); - TotalLength = PhysicalEnd - PhysicalAddress; - StartAddress1 = 0; - StartAddress2 = 0; - StartAddress3 = 0; - Length1 = 0; - Length2 = 0; - Length3 = 0; - - if (TotalLength == 0) { - return EFI_SUCCESS; - } - - if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) { - StartAddress1 = PhysicalAddress; - Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress; - if (Length1 >= TotalLength) { - Length1 = TotalLength; - } - - PhysicalAddress += Length1; - TotalLength -= Length1; - } - - if (TotalLength > SIZE_2MB) { - StartAddress2 = PhysicalAddress; - Length2 = TotalLength & ~(UINT64)ALIGNED_2MB_MASK; - PhysicalAddress += Length2; - TotalLength -= Length2; - } - - if (TotalLength) { - StartAddress3 = PhysicalAddress; - Length3 = TotalLength; - } - - Status = EFI_SUCCESS; - if (Length1 > 0) { - Pages = Length1 / SIZE_4KB; - Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB); - if (EFI_ERROR (Status)) { - return Status; - } - } - - if (Length2 > 0) { - Pages = Length2 / AcceptPageSize; - Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize); - if (EFI_ERROR (Status)) { - return Status; - } - } - - if (Length3 > 0) { - Pages = Length3 / SIZE_4KB; - Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB); - ASSERT (!EFI_ERROR (Status)); - if (EFI_ERROR (Status)) { - return Status; - } - } - - return Status; -} - -/** - * This function is called by BSP and APs to accept memory. - * Note: - * The input PhysicalStart/PhysicalEnd indicates the whole memory region - * to be accepted. BSP or AP only accepts one piece in the whole memory region. - * - * @param CpuIndex vCPU index - * @param CpusNum Total vCPU number of a Tdx guest - * @param PhysicalStart Start address of a memory region which is to be accepted - * @param PhysicalEnd End address of a memory region which is to be accepted - * - * @retval EFI_SUCCESS Successfully accept the memory - * @retval Other Other errors as indicated - */ -STATIC -EFI_STATUS -EFIAPI -BspApAcceptMemoryResourceRange ( - UINT32 CpuIndex, - UINT32 CpusNum, - EFI_PHYSICAL_ADDRESS PhysicalStart, - EFI_PHYSICAL_ADDRESS PhysicalEnd - ) -{ - UINT64 Status; - UINT64 Pages; - UINT64 Stride; - UINT64 AcceptPageSize; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - - AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize); - - Status = EFI_SUCCESS; - Stride = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE; - PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex; - - while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) { - Pages = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize; - Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize); - ASSERT (!EFI_ERROR (Status)); - PhysicalAddress += Stride; - } - - return EFI_SUCCESS; -} - -/** - * This function is called by APs to accept memory. - * - * @param CpuIndex vCPU index of an AP - * @param PhysicalStart Start address of a memory region which is to be accepted - * @param PhysicalEnd End address of a memory region which is to be accepted - * - * @retval EFI_SUCCESS Successfully accept the memory - * @retval Others Other errors as indicated - */ -STATIC -EFI_STATUS -EFIAPI -ApAcceptMemoryResourceRange ( - UINT32 CpuIndex, - EFI_PHYSICAL_ADDRESS PhysicalStart, - EFI_PHYSICAL_ADDRESS PhysicalEnd - ) -{ - UINT64 Status; - TD_RETURN_DATA TdReturnData; - - Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); - if (Status != TDX_EXIT_REASON_SUCCESS) { - ASSERT (FALSE); - return EFI_ABORTED; - } - - if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) { - ASSERT (FALSE); - return EFI_ABORTED; - } - - return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd); -} - -/** - * This function is called by BSP. It coordinates BSP/APs to accept memory together. - * - * @param PhysicalStart Start address of a memory region which is to be accepted - * @param PhysicalEnd End address of a memory region which is to be accepted - * @param APsStackAddress APs stack address - * @param CpusNum Total vCPU number of the Tdx guest - * - * @retval EFI_SUCCESS Successfully accept the memory - * @retval Others Other errors as indicated - */ -EFI_STATUS -EFIAPI -MpAcceptMemoryResourceRange ( - IN EFI_PHYSICAL_ADDRESS PhysicalStart, - IN EFI_PHYSICAL_ADDRESS PhysicalEnd, - IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress, - IN UINT32 CpusNum - ) -{ - UINT64 Length; - EFI_STATUS Status; - - Length = PhysicalEnd - PhysicalStart; - - DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length)); - - if (Length == 0) { - return EFI_SUCCESS; - } - - // - // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned. - // - if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) { - Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length); - Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length); - ASSERT (Status == EFI_SUCCESS); - - PhysicalStart += Length; - Length = PhysicalEnd - PhysicalStart; - } - - if (Length == 0) { - return EFI_SUCCESS; - } - - // - // BSP will accept the memory by itself if the memory is not big enough compared with a chunk. - // - if (Length <= ACCEPT_CHUNK_SIZE) { - return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd); - } - - // - // Now APs are asked to accept the memory together. - // - MpSerializeStart (); - - MpSendWakeupCommand ( - MpProtectedModeWakeupCommandAcceptPages, - (UINT64)(UINTN)ApAcceptMemoryResourceRange, - PhysicalStart, - PhysicalEnd, - APsStackAddress, - AP_STACK_SIZE - ); - - // - // Now BSP does its job. - // - BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd); - - MpSerializeEnd (); - - return EFI_SUCCESS; -} - -/** - BSP accept a small piece of memory which will be used as APs stack. - - @param[in] VmmHobList The Hoblist pass the firmware - @param[in] APsStackSize APs stack size - @param[out] PhysicalAddressEnd The physical end address of accepted memory in phase-1 - - @retval EFI_SUCCESS Process the HobList successfully - @retval Others Other errors as indicated -**/ -EFI_STATUS -EFIAPI -AcceptMemoryForAPsStack ( - IN CONST VOID *VmmHobList, - IN UINT32 APsStackSize, - OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd - ) -{ - EFI_STATUS Status; - EFI_PEI_HOB_POINTERS Hob; - EFI_PHYSICAL_ADDRESS PhysicalEnd; - EFI_PHYSICAL_ADDRESS PhysicalStart; - UINT64 ResourceLength; - BOOLEAN MemoryRegionFound; - - ASSERT (VmmHobList != NULL); - - Status = EFI_SUCCESS; - Hob.Raw = (UINT8 *)VmmHobList; - MemoryRegionFound = FALSE; - - DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize)); - - // - // Parse the HOB list until end of list or matching type is found. - // - while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) { - if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); - - if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) { - ResourceLength = Hob.ResourceDescriptor->ResourceLength; - PhysicalStart = Hob.ResourceDescriptor->PhysicalStart; - PhysicalEnd = PhysicalStart + ResourceLength; - - DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); - DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart)); - DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength)); - DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); - - if (ResourceLength >= APsStackSize) { - MemoryRegionFound = TRUE; - if (ResourceLength > ACCEPT_CHUNK_SIZE) { - PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize; - } - } - - Status = BspAcceptMemoryResourceRange ( - Hob.ResourceDescriptor->PhysicalStart, - PhysicalEnd - ); - if (EFI_ERROR (Status)) { - break; - } - } - } - - Hob.Raw = GET_NEXT_HOB (Hob); - } - - ASSERT (MemoryRegionFound); - *PhysicalAddressEnd = PhysicalEnd; - - return Status; -} - -/** - BSP and APs work togeter to accept memory which is under the address of 4G. - - @param[in] VmmHobList The Hoblist pass the firmware - @param[in] CpusNum Number of vCPUs - @param[in] APsStackStartAddres Start address of APs stack - @param[in] PhysicalAddressStart Start physical address which to be accepted - - @retval EFI_SUCCESS Process the HobList successfully - @retval Others Other errors as indicated -**/ -EFI_STATUS -EFIAPI -AcceptMemory ( - IN CONST VOID *VmmHobList, - IN UINT32 CpusNum, - IN EFI_PHYSICAL_ADDRESS APsStackStartAddress, - IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart - ) -{ - EFI_STATUS Status; - EFI_PEI_HOB_POINTERS Hob; - EFI_PHYSICAL_ADDRESS PhysicalStart; - EFI_PHYSICAL_ADDRESS PhysicalEnd; - EFI_PHYSICAL_ADDRESS AcceptMemoryEndAddress; - - Status = EFI_SUCCESS; - AcceptMemoryEndAddress = BASE_4GB; - - ASSERT (VmmHobList != NULL); - Hob.Raw = (UINT8 *)VmmHobList; - - DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n")); - - // - // Parse the HOB list until end of list or matching type is found. - // - while (!END_OF_HOB_LIST (Hob)) { - if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) { - PhysicalStart = Hob.ResourceDescriptor->PhysicalStart; - PhysicalEnd = PhysicalStart + Hob.ResourceDescriptor->ResourceLength; - - if (PhysicalEnd <= PhysicalAddressStart) { - // this memory region has been accepted. Skipped it. - Hob.Raw = GET_NEXT_HOB (Hob); - continue; - } - - if (PhysicalStart >= AcceptMemoryEndAddress) { - // this memory region is not to be accepted. And we're done. - break; - } - - if (PhysicalStart >= PhysicalAddressStart) { - // this memory region has not been acceted. - } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) { - // part of the memory region has been accepted. - PhysicalStart = PhysicalAddressStart; - } - - // then compare the PhysicalEnd with AcceptMemoryEndAddress - if (PhysicalEnd >= AcceptMemoryEndAddress) { - PhysicalEnd = AcceptMemoryEndAddress; - } - - DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); - DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart)); - DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength)); - DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); - - // Now we're ready to accept memory [PhysicalStart, PhysicalEnd) - if (CpusNum == 1) { - Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd); - } else { - Status = MpAcceptMemoryResourceRange ( - PhysicalStart, - PhysicalEnd, - APsStackStartAddress, - CpusNum - ); - } - - if (EFI_ERROR (Status)) { - ASSERT (FALSE); - break; - } - - if (PhysicalEnd == AcceptMemoryEndAddress) { - break; - } - } - } - - Hob.Raw = GET_NEXT_HOB (Hob); - } - - return Status; -} - -/** - Check the value whether in the valid list. - - @param[in] Value A value - @param[in] ValidList A pointer to valid list - @param[in] ValidListLength Length of valid list - - @retval TRUE The value is in valid list. - @retval FALSE The value is not in valid list. - -**/ -BOOLEAN -EFIAPI -IsInValidList ( - IN UINT32 Value, - IN UINT32 *ValidList, - IN UINT32 ValidListLength - ) -{ - UINT32 index; - - if (ValidList == NULL) { - return FALSE; - } - - for (index = 0; index < ValidListLength; index++) { - if (ValidList[index] == Value) { - return TRUE; - } - } - - return FALSE; -} - -/** - Check the integrity of VMM Hob List. - - @param[in] VmmHobList A pointer to Hob List - - @retval TRUE The Hob List is valid. - @retval FALSE The Hob List is invalid. - -**/ -BOOLEAN -EFIAPI -ValidateHobList ( - IN CONST VOID *VmmHobList - ) -{ - EFI_PEI_HOB_POINTERS Hob; - UINT32 EFI_BOOT_MODE_LIST[] = { - BOOT_WITH_FULL_CONFIGURATION, - BOOT_WITH_MINIMAL_CONFIGURATION, - BOOT_ASSUMING_NO_CONFIGURATION_CHANGES, - BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS, - BOOT_WITH_DEFAULT_SETTINGS, - BOOT_ON_S4_RESUME, - BOOT_ON_S5_RESUME, - BOOT_WITH_MFG_MODE_SETTINGS, - BOOT_ON_S2_RESUME, - BOOT_ON_S3_RESUME, - BOOT_ON_FLASH_UPDATE, - BOOT_IN_RECOVERY_MODE - }; - - UINT32 EFI_RESOURCE_TYPE_LIST[] = { - EFI_RESOURCE_SYSTEM_MEMORY, - EFI_RESOURCE_MEMORY_MAPPED_IO, - EFI_RESOURCE_IO, - EFI_RESOURCE_FIRMWARE_DEVICE, - EFI_RESOURCE_MEMORY_MAPPED_IO_PORT, - EFI_RESOURCE_MEMORY_RESERVED, - EFI_RESOURCE_IO_RESERVED, - BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED - }; - - if (VmmHobList == NULL) { - DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n")); - return FALSE; - } - - Hob.Raw = (UINT8 *)VmmHobList; - - // - // Parse the HOB list until end of list or matching type is found. - // - while (!END_OF_HOB_LIST (Hob)) { - if (Hob.Header->Reserved != (UINT32)0) { - DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n")); - return FALSE; - } - - if (Hob.Header->HobLength == 0) { - DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n")); - return FALSE; - } - - switch (Hob.Header->HobType) { - case EFI_HOB_TYPE_HANDOFF: - if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF)); - return FALSE; - } - - if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) { - DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode)); - return FALSE; - } - - if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) { - DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\ - Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop)); - return FALSE; - } - - break; - - case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR: - if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)); - return FALSE; - } - - if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) { - DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType)); - return FALSE; - } - - if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT | - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | - EFI_RESOURCE_ATTRIBUTE_TESTED | - EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | - EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | - EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | - EFI_RESOURCE_ATTRIBUTE_PERSISTENT | - EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC | - EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC | - EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 | - EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 | - EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | - EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | - EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | - EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | - EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED | - EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE | - EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE | - EFI_RESOURCE_ATTRIBUTE_PERSISTABLE | - EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | - EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE | - EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0) - { - DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute)); - return FALSE; - } - - break; - - // EFI_HOB_GUID_TYPE is variable length data, so skip check - case EFI_HOB_TYPE_GUID_EXTENSION: - break; - - case EFI_HOB_TYPE_FV: - if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV)); - return FALSE; - } - - break; - - case EFI_HOB_TYPE_FV2: - if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2)); - return FALSE; - } - - break; - - case EFI_HOB_TYPE_FV3: - if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3)); - return FALSE; - } - - break; - - case EFI_HOB_TYPE_CPU: - if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) { - DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU)); - return FALSE; - } - - for (UINT32 index = 0; index < 6; index++) { - if (Hob.Cpu->Reserved[index] != 0) { - DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n")); - return FALSE; - } - } - - break; - - default: - DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType)); - return FALSE; - } - - // Get next HOB - Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength); - } - - return TRUE; -} - -/** - Processing the incoming HobList for the TDX - - Firmware must parse list, and accept the pages of memory before their can be - use by the guest. - - @param[in] VmmHobList The Hoblist pass the firmware - - @retval EFI_SUCCESS Process the HobList successfully - @retval Others Other errors as indicated - -**/ -EFI_STATUS -EFIAPI -ProcessHobList ( - IN CONST VOID *VmmHobList - ) -{ - EFI_STATUS Status; - UINT32 CpusNum; - EFI_PHYSICAL_ADDRESS PhysicalEnd; - EFI_PHYSICAL_ADDRESS APsStackStartAddress; - - CpusNum = GetCpusNum (); - - // - // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases. - // Phase-1 accepts a small piece of memory by BSP. This piece of memory - // is used to setup AP's stack. - // After that phase-2 accepts a big piece of memory by BSP/APs. - // - // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted - // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align - // APsStackSize to 2M size aligned. - // - if (CpusNum > 1) { - Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd); - ASSERT (Status == EFI_SUCCESS); - APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum); - } else { - PhysicalEnd = 0; - APsStackStartAddress = 0; - } - - Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd); - ASSERT (Status == EFI_SUCCESS); - - return Status; -} - -/** - In Tdx guest, some information need to be passed from host VMM to guest - firmware. For example, the memory resource, etc. These information are - prepared by host VMM and put in HobList which is described in TdxMetadata. - - Information in HobList is treated as external input. From the security - perspective before it is consumed, it should be validated. - - @retval EFI_SUCCESS Successfully process the hoblist - @retval Others Other error as indicated -**/ -EFI_STATUS -EFIAPI -ProcessTdxHobList ( - VOID - ) -{ - EFI_STATUS Status; - VOID *TdHob; - TD_RETURN_DATA TdReturnData; - - TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase); - Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG (( - DEBUG_INFO, - "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n", - TdReturnData.TdInfo.Gpaw, - TdReturnData.TdInfo.NumVcpus - )); - - // - // Validate HobList - // - if (ValidateHobList (TdHob) == FALSE) { - return EFI_INVALID_PARAMETER; - } - - // - // Process Hoblist to accept memory - // - Status = ProcessHobList (TdHob); - - return Status; -} - /** * Build ResourceDescriptorHob for the unaccepted memory region. * This memory region may be splitted into 2 parts because of lazy accept.