From nobody Mon Feb 9 08:57:04 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+97624+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97624+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1671525817; cv=none; d=zohomail.com; s=zohoarc; b=L6UhkYovdbhHWP1pvczxU5dpaeBlbANCtMKBl3KIztUrbJWJ2IFiaBQR1nZfBHjsnCCLjCpA+TN/lZMAUryQDJfvc1tKhth54CsPqHARDiateH93AUHeuDTp8MTbhIOHY9VMIw5g/iAUK9yEW1VibljtOiyE3QT3sDNQadMNl8A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1671525817; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=JFuGOYRlu1S+tDp15VNPDF//GesnuC47ERdJSCAbIVY=; b=Csvo1C0waQdWUBrbWzKy9ax0OqB3g+BswLT0CLZaypDSIoq9IEp7IpL4WZUK91Mk2Z7FcJCn82NC5QoP+DCt+Nl59s7WJRMdMEdE2m2JBKD02tFh8uPmYR5rMIawwg9TJIisCzT6Nv7xUpb9CqbwC5ny7ce1kySfbnBrHmIvE3w= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+97624+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1671525817544234.80373404061504; Tue, 20 Dec 2022 00:43:37 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id XUHZYY1788612xWdUW5BpZ1U; Tue, 20 Dec 2022 00:43:37 -0800 X-Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web11.46066.1671525816147549841 for ; Tue, 20 Dec 2022 00:43:36 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10566"; a="383908321" X-IronPort-AV: E=Sophos;i="5.96,259,1665471600"; d="scan'208";a="383908321" X-Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2022 00:43:09 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10566"; a="628644663" X-IronPort-AV: E=Sophos;i="5.96,259,1665471600"; d="scan'208";a="628644663" X-Received: from mxu9-mobl1.ccr.corp.intel.com ([10.255.29.12]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2022 00:43:06 -0800 From: "Min Xu" To: devel@edk2.groups.io Cc: Min M Xu , Erdem Aktas , Gerd Hoffmann , James Bottomley , Jiewen Yao , Tom Lendacky Subject: [edk2-devel] [PATCH V2 6/6] OvmfPkg/PlatformInitLib: Implement multi-core accept memory for TDVF Date: Tue, 20 Dec 2022 16:42:40 +0800 Message-Id: <20221220084240.1922-7-min.m.xu@intel.com> In-Reply-To: <20221220084240.1922-1-min.m.xu@intel.com> References: <20221220084240.1922-1-min.m.xu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,min.m.xu@intel.com X-Gm-Message-State: dP2oGpGmK8mnzsrabsk0wWUfx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1671525817; bh=rf4rBEHyGY/efyoYLYk4g2lQpYmBkfoOxKNNJzLsZvY=; h=Cc:Date:From:Reply-To:Subject:To; b=sLIEj43pCf8j2/L6jbulg1IJX3OgqsExDO4RMwXwudIjwcuGyw1eRwZoDGjzq+YfCYY VXJxYPkgPAwZk58R9wIMqTcnzbyJoQ8IpgaWTCtM+ar/SLqPj4CUby9RHsJ3+fFj3ZC51 frU3bKrP3XrVeUD6o+e0C/qZR6v/7zUmvUE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1671525818964100003 Content-Type: text/plain; charset="utf-8" From: Min M Xu BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4172 TDVF once accepts memory only by BSP. To improve the boot performance this patch introduce the multi-core accpet memory. Multi-core means BSP and APs work together to accept memory. TDVF leverages mailbox to wake up APs. It is not enabled in MpInitLib (Which requires SIPI). So multi-core accept memory cannot leverages MpInitLib to coordinate BSP and APs to work together. So TDVF split the accept memory into 2 phases. - AcceptMemoryForAPsStack: BSP accepts a small piece of memory which is then used by APs to setup stack. We assign a 16KB stack for each AP. So a td-guest with 256 vCPU requires 255*16KB =3D 4080KB. - AcceptMemory: After above small piece of memory is accepted, BSP commands APs to accept memory by sending AcceptPages command in td-mailbox. Together with the command and accpet-function, the APsStack address is send as well. APs then set the stack and jump to accept-function to accept memory. AcceptMemoryForAPsStack accepts as small memory as possible and then jump to AcceptMemory. It fully takes advantage of BSP/APs to work together. After accept memory is done, the memory region for APsStack is not used anymore. It can be used as other private memory. Because accept-memory is in the very beginning of boot process and it will not impact other phases. Cc: Erdem Aktas Cc: Gerd Hoffmann Cc: James Bottomley Cc: Jiewen Yao Cc: Tom Lendacky Signed-off-by: Min Xu --- OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 411 +++++++++++++++--- .../PlatformInitLib/PlatformInitLib.inf | 1 + 2 files changed, 363 insertions(+), 49 deletions(-) diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/P= latformInitLib/IntelTdx.c index 55ca3ecaa13d..6cb63139cba0 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,10 @@ #define ALIGNED_2MB_MASK 0x1fffff #define MEGABYTE_SHIFT 20 =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. =20 @@ -81,8 +86,6 @@ BspAcceptMemoryResourceRange ( return EFI_SUCCESS; } =20 - DEBUG ((DEBUG_INFO, "TdAccept: 0x%llx - 0x%llx\n", PhysicalAddress, Tota= lLength)); - if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) !=3D PhysicalAddress) { StartAddress1 =3D PhysicalAddress; Length1 =3D ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAd= dress; @@ -106,11 +109,6 @@ BspAcceptMemoryResourceRange ( Length3 =3D TotalLength; } =20 - DEBUG ((DEBUG_INFO, " Part1: 0x%llx - 0x%llx\n", StartAddress1, Length= 1)); - DEBUG ((DEBUG_INFO, " Part2: 0x%llx - 0x%llx\n", StartAddress2, Length= 2)); - DEBUG ((DEBUG_INFO, " Part3: 0x%llx - 0x%llx\n", StartAddress3, Length= 3)); - DEBUG ((DEBUG_INFO, " Page : 0x%x\n", AcceptPageSize)); - Status =3D EFI_SUCCESS; if (Length1 > 0) { Pages =3D Length1 / SIZE_4KB; @@ -140,6 +138,342 @@ BspAcceptMemoryResourceRange ( return Status; } =20 +/** + * 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 re= gion. + * + * @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 ac= cepted + * + * @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 =3D (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize); + + Status =3D EFI_SUCCESS; + Stride =3D (UINTN)CpusNum * ACCEPT_CHUNK_SIZE; + PhysicalAddress =3D PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex; + + while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) { + Pages =3D MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / Ac= ceptPageSize; + Status =3D TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)Accep= tPageSize); + ASSERT (!EFI_ERROR (Status)); + PhysicalAddress +=3D 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 ac= cepted + * + * @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 =3D TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData); + if (Status !=3D TDX_EXIT_REASON_SUCCESS) { + ASSERT (FALSE); + return EFI_ABORTED; + } + + if ((CpuIndex =3D=3D 0) || (CpuIndex >=3D TdReturnData.TdInfo.NumVcpus))= { + ASSERT (FALSE); + return EFI_ABORTED; + } + + return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.Num= Vcpus, 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 b= e 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 =3D PhysicalEnd - PhysicalStart; + + DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalSta= rt, PhysicalEnd, Length)); + + if (Length =3D=3D 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) !=3D PhysicalStart) { + Length =3D MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart,= Length); + Status =3D BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart = + Length); + ASSERT (Status =3D=3D EFI_SUCCESS); + + PhysicalStart +=3D Length; + Length =3D PhysicalEnd - PhysicalStart; + } + + if (Length =3D=3D 0) { + return EFI_SUCCESS; + } + + // + // BSP will accept the memory by itself if the memory is not big enough = compared with a chunk. + // + if (Length <=3D 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 m= emory 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 !=3D NULL); + + Status =3D EFI_SUCCESS; + Hob.Raw =3D (UINT8 *)VmmHobList; + MemoryRegionFound =3D FALSE; + + DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=3D0x%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 =3D=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor= ->ResourceType)); + + if (Hob.ResourceDescriptor->ResourceType =3D=3D BZ3937_EFI_RESOURCE_= MEMORY_UNACCEPTED) { + ResourceLength =3D Hob.ResourceDescriptor->ResourceLength; + PhysicalStart =3D Hob.ResourceDescriptor->PhysicalStart; + PhysicalEnd =3D PhysicalStart + ResourceLength; + + DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescr= iptor->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->Owne= r)); + + if (ResourceLength >=3D APsStackSize) { + MemoryRegionFound =3D TRUE; + if (ResourceLength > ACCEPT_CHUNK_SIZE) { + PhysicalEnd =3D Hob.ResourceDescriptor->PhysicalStart + APsSta= ckSize; + } + } + + Status =3D BspAcceptMemoryResourceRange ( + Hob.ResourceDescriptor->PhysicalStart, + PhysicalEnd + ); + if (EFI_ERROR (Status)) { + break; + } + } + } + + Hob.Raw =3D GET_NEXT_HOB (Hob); + } + + ASSERT (MemoryRegionFound); + *PhysicalAddressEnd =3D 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 accep= ted + + @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 =3D EFI_SUCCESS; + AcceptMemoryEndAddress =3D BASE_4GB; + + ASSERT (VmmHobList !=3D NULL); + Hob.Raw =3D (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 =3D=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { + if (Hob.ResourceDescriptor->ResourceType =3D=3D BZ3937_EFI_RESOURCE_= MEMORY_UNACCEPTED) { + PhysicalStart =3D Hob.ResourceDescriptor->PhysicalStart; + PhysicalEnd =3D PhysicalStart + Hob.ResourceDescriptor->Resource= Length; + + if (PhysicalEnd <=3D PhysicalAddressStart) { + // this memory region has been accepted. Skipped it. + Hob.Raw =3D GET_NEXT_HOB (Hob); + continue; + } + + if (PhysicalStart >=3D AcceptMemoryEndAddress) { + // this memory region is not to be accepted. And we're done. + break; + } + + if (PhysicalStart >=3D PhysicalAddressStart) { + // this memory region has not been acceted. + } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd = > PhysicalAddressStart)) { + // part of the memory region has been accepted. + PhysicalStart =3D PhysicalAddressStart; + } + + // then compare the PhysicalEnd with AcceptMemoryEndAddress + if (PhysicalEnd >=3D AcceptMemoryEndAddress) { + PhysicalEnd =3D AcceptMemoryEndAddress; + } + + DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescr= iptor->ResourceAttribute)); + DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescrip= tor->PhysicalStart)); + DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescri= ptor->ResourceLength)); + DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owne= r)); + + // Now we're ready to accept memory [PhysicalStart, PhysicalEnd) + if (CpusNum =3D=3D 1) { + Status =3D BspAcceptMemoryResourceRange (PhysicalStart, Physical= End); + } else { + Status =3D MpAcceptMemoryResourceRange ( + PhysicalStart, + PhysicalEnd, + APsStackStartAddress, + CpusNum + ); + } + + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + break; + } + + if (PhysicalEnd =3D=3D AcceptMemoryEndAddress) { + break; + } + } + } + + Hob.Raw =3D GET_NEXT_HOB (Hob); + } + + return Status; +} + /** Check the value whether in the valid list. =20 @@ -375,55 +709,34 @@ ProcessHobList ( ) { EFI_STATUS Status; - EFI_PEI_HOB_POINTERS Hob; + UINT32 CpusNum; EFI_PHYSICAL_ADDRESS PhysicalEnd; - UINT64 ResourceLength; - UINT64 AccumulateAcceptedMemory; + EFI_PHYSICAL_ADDRESS APsStackStartAddress; =20 - Status =3D EFI_SUCCESS; - ASSERT (VmmHobList !=3D NULL); - Hob.Raw =3D (UINT8 *)VmmHobList; - - AccumulateAcceptedMemory =3D 0; + CpusNum =3D GetCpusNum (); =20 // - // Parse the HOB list until end of list or matching type is found. + // 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. // - while (!END_OF_HOB_LIST (Hob)) { - if (Hob.Header->HobType =3D=3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor= ->ResourceType)); - - if (Hob.ResourceDescriptor->ResourceType =3D=3D BZ3937_EFI_RESOURCE_= MEMORY_UNACCEPTED) { - DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescr= iptor->ResourceAttribute)); - DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescrip= tor->PhysicalStart)); - DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescri= ptor->ResourceLength)); - DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owne= r)); - - PhysicalEnd =3D Hob.ResourceDescriptor->PhysicalStart + Hob.Res= ourceDescriptor->ResourceLength; - ResourceLength =3D Hob.ResourceDescriptor->ResourceLength; - - if (Hob.ResourceDescriptor->PhysicalStart >=3D BASE_4GB) { - // - // In current stage, we only accept the memory under 4G - // - break; - } - - Status =3D BspAcceptMemoryResourceRange ( - Hob.ResourceDescriptor->PhysicalStart, - PhysicalEnd - ); - if (EFI_ERROR (Status)) { - break; - } - - AccumulateAcceptedMemory +=3D ResourceLength; - } - } - - Hob.Raw =3D GET_NEXT_HOB (Hob); + // TDVF supports 4K and 2M accept-page-size. The memory which can be acc= peted + // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align + // APsStackSize to 2M size aligned. + // + if (CpusNum > 1) { + Status =3D AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNu= m), &PhysicalEnd); + ASSERT (Status =3D=3D EFI_SUCCESS); + APsStackStartAddress =3D PhysicalEnd - APS_STACK_SIZE (CpusNum); + } else { + PhysicalEnd =3D 0; + APsStackStartAddress =3D 0; } =20 + Status =3D AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, Phys= icalEnd); + ASSERT (Status =3D=3D EFI_SUCCESS); + return Status; } =20 diff --git a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf b/OvmfPkg/= Library/PlatformInitLib/PlatformInitLib.inf index 86a82ad3e084..140216979a54 100644 --- a/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf +++ b/OvmfPkg/Library/PlatformInitLib/PlatformInitLib.inf @@ -52,6 +52,7 @@ PcdLib PciLib PeiHardwareInfoLib + TdxMailboxLib =20 [LibraryClasses.X64] TdxLib --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#97624): https://edk2.groups.io/g/devel/message/97624 Mute This Topic: https://groups.io/mt/95782438/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-