From nobody Tue Feb 10 16:22:09 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+106328+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+106328+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1687704021; cv=none; d=zohomail.com; s=zohoarc; b=AaA+tO3nleP7KfzuHlxTXpW+SU9tBx9iFKBJtmcsvwMCEIC9CbJMU8Mz2x+p0TkjKW9aBjGxLjKc+1WyxyGpY+b8I0Ae1/w0Cz7aVb/+MdDMcXVViFoyNxv0HEAl7K3UDsKq/FfdTWt51oKhZSrzr3jSvpBQktpintbI/F4v5yw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1687704021; 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=jEy0CzuDaFL6ZoOzWqTC7Q/zAz10hKX0Bz3+PMQAgH0=; b=Gv1bqAyBWUWeO1UEREStMtsmaNTuhVnnulysH5zOT0B6JF2zF4nLuwXSpAPMR8/iOlHYoWIC9emw9nCo28qYkqp+9C6EedtKB8fU6rte8DR3EvAOYrR+ifEiS4t6+dgMPJoLgpdAHCKuXBkuZ+Ht9bWeqDMpz6YyGirSxwwsRys= 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+106328+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 1687704020930522.165699012664; Sun, 25 Jun 2023 07:40:20 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ITGZYY1788612xoA4vNyOqLb; Sun, 25 Jun 2023 07:40:20 -0700 X-Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.12343.1687704019653525203 for ; Sun, 25 Jun 2023 07:40:20 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10752"; a="363624393" X-IronPort-AV: E=Sophos;i="6.01,157,1684825200"; d="scan'208";a="363624393" X-Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jun 2023 07:39:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10752"; a="785871869" X-IronPort-AV: E=Sophos;i="6.01,157,1684825200"; d="scan'208";a="785871869" X-Received: from shwdeopenlab705.ccr.corp.intel.com ([10.239.55.55]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Jun 2023 07:39:49 -0700 From: "Yuanhao Xie" To: devel@edk2.groups.io Cc: Gerd Hoffmann , Eric Dong , Ray Ni , Rahul Kumar , Tom Lendacky , Yuanhao Xie Subject: [edk2-devel] [Patch V2 6/6] UefiCpuPkg: Enhance MpHandOff Handling. Date: Sun, 25 Jun 2023 22:39:20 +0800 Message-Id: <20230625143920.57095-7-yuanhao.xie@intel.com> In-Reply-To: <20230625143920.57095-1-yuanhao.xie@intel.com> References: <20230625143920.57095-1-yuanhao.xie@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,yuanhao.xie@intel.com X-Gm-Message-State: QIOyzCkJRF6VtTNL3oahW4aIx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1687704020; bh=HCgFoC0SU0Te4eIEVu/cCPv6Osr5KMxDkTjlk93e3B4=; h=Cc:Date:From:Reply-To:Subject:To; b=cdyL1e8uw+zL8ilDkEXVJGn6XiOVVMJT20FIXYMiA+oI+l2seG3jhvpNG7D6HeR01Qg +RuLQgnm/QImfBLPEmoVtVup29mgU8auSclO5bFFegVdpE57q8Ej99XWeD3CBC7+CmtbW AAo9hrrACt0i4VIiqdzfn/PxOe9iwd6QLHs= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1687704023167100003 Content-Type: text/plain; charset="utf-8" Enhance MpHandOff Handling for Systems with a Large Number of Processors. Cc: Gerd Hoffmann Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Tom Lendacky Signed-off-by: Yuanhao Xie --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 128 ++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++-----------------------------------= ------------------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 22 +++++++++------------- UefiCpuPkg/Library/MpInitLib/PeiMpLib.c | 56 ++++++++++++++++++++++++++++= +++++++++++----------------- 3 files changed, 116 insertions(+), 90 deletions(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpIn= itLib/MpLib.c index 391e6f19ef..087bf3ea92 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -1528,32 +1528,48 @@ SwitchContextPerAp ( This procedure allows the AP to switch to another section of memory and continue its loop there. =20 - @param[in] MpHandOff Pointer to MP hand-off data structure. + @param[in] BspNumber Bsp Number **/ VOID SwitchApContext ( - IN MP_HAND_OFF *MpHandOff + IN UINT32 BspNumber ) { - UINTN Index; - UINT32 BspNumber; - - BspNumber =3D GetBspNumber (MpHandOff); + UINTN Index; + UINTN LimitationOfMpHandOffHob; + UINTN NumberOfProcessorsInCurrentHob; + UINTN CpuCountInCurrentHob; + MP_HAND_OFF *MpHandOff; + BOOLEAN BspFound; + + BspFound =3D FALSE; + + MpHandOff =3D GetMpHandOffHob (); + CpuCountInCurrentHob =3D 0; + LimitationOfMpHandOffHob =3D (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE) - size= of (MP_HAND_OFF)) / sizeof (PROCESSOR_HAND_OFF); + while (CpuCountInCurrentHob < MpHandOff->CpuCount) { + // + // Get the processor number for the BSP + // + NumberOfProcessorsInCurrentHob =3D MIN (MpHandOff->CpuCount - CpuCount= InCurrentHob, LimitationOfMpHandOffHob); =20 - for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { - if (Index !=3D BspNumber) { - *(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress =3D = (UINTN)SwitchContextPerAp; - *(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress =3D = MpHandOff->StartupSignalValue; + for (Index =3D 0; Index < NumberOfProcessorsInCurrentHob; Index++) { + if ((Index =3D=3D BspNumber) && (BspFound =3D=3D FALSE)) { + BspFound =3D TRUE; + } else { + *(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress = =3D (UINTN)SwitchContextPerAp; + *(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress = =3D MpHandOff->StartupSignalValue; + WaitApWakeup ((UINT32 *)(UINTN)(MpHandOff->Info[Index].StartupSign= alAddress)); + } } - } =20 - // - // Wait all APs waken up if this is not the 1st broadcast of SIPI - // - for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { - if (Index !=3D BspNumber) { - WaitApWakeup ((UINT32 *)(UINTN)(MpHandOff->Info[Index].StartupSignal= Address)); + if (CpuCountInCurrentHob + NumberOfProcessorsInCurrentHob >=3D MpHandO= ff->CpuCount) { + break; } + + MpHandOff =3D (MP_HAND_OFF *)((UINT8 *)MpHandOff + sizeof (MP_HAND_OFF= ) + sizeof (EFI_HOB_GUID_TYPE) + sizeof (PROCESSOR_HAND_OFF) * NumberOfProc= essorsInCurrentHob); + + CpuCountInCurrentHob +=3D NumberOfProcessorsInCurrentHob; } } =20 @@ -1909,37 +1925,6 @@ CheckAllAPs ( return EFI_NOT_READY; } =20 -/** - This function Get BspNumber. - - @param[in] MpHandOff Pointer to MpHandOff - @return BspNumber -**/ -UINT32 -GetBspNumber ( - IN CONST MP_HAND_OFF *MpHandOff - ) -{ - UINT32 ApicId; - UINT32 BspNumber; - UINT32 Index; - - // - // Get the processor number for the BSP - // - BspNumber =3D MAX_UINT32; - ApicId =3D GetInitialApicId (); - for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { - if (MpHandOff->Info[Index].ApicId =3D=3D ApicId) { - BspNumber =3D Index; - } - } - - ASSERT (BspNumber !=3D MAX_UINT32); - - return BspNumber; -} - /** Get pointer to CPU MP Data structure from GUIDed HOB. =20 @@ -1994,8 +1979,13 @@ MpInitLibInitialize ( UINTN ApResetVectorSizeAbove1Mb; UINTN BackupBufferAddr; UINTN ApIdtBase; + UINTN LimitationOfMpHandOffHob; + UINTN NumberOfProcessorsInCurrentHob; + UINTN ProcessedCpuCount; + UINTN CurrentProcessorIndex; =20 MpHandOff =3D GetMpHandOffHob (); + if (MpHandOff =3D=3D NULL) { MaxLogicalProcessorNumber =3D PcdGet32 (PcdCpuMaxLogicalProcessorNumbe= r); } else { @@ -2156,17 +2146,35 @@ MpInitLibInitialize ( // from HOB // AmdSevUpdateCpuMpData (CpuMpData); - CpuMpData->CpuCount =3D MpHandOff->CpuCount; - CpuMpData->BspNumber =3D GetBspNumber (MpHandOff); - CpuInfoInHob =3D (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoI= nHob; - for (Index =3D 0; Index < CpuMpData->CpuCount; Index++) { - InitializeSpinLock (&CpuMpData->CpuData[Index].ApLock); - CpuMpData->CpuData[Index].CpuHealthy =3D (MpHandOff->Info[Index].Hea= lth =3D=3D 0) ? TRUE : FALSE; - CpuMpData->CpuData[Index].ApFunction =3D 0; - CpuInfoInHob[Index].InitialApicId =3D MpHandOff->Info[Index].Apic= Id; - CpuInfoInHob[Index].ApTopOfStack =3D CpuMpData->Buffer + (Index = + 1) * CpuMpData->CpuApStackSize; - CpuInfoInHob[Index].ApicId =3D MpHandOff->Info[Index].Apic= Id; - CpuInfoInHob[Index].Health =3D MpHandOff->Info[Index].Heal= th; + CpuMpData->CpuCount =3D MpHandOff->CpuCount; + CpuInfoInHob =3D (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoIn= Hob; + + LimitationOfMpHandOffHob =3D (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE) - si= zeof (MP_HAND_OFF)) / sizeof (PROCESSOR_HAND_OFF); + ProcessedCpuCount =3D 0; + while (ProcessedCpuCount < MpHandOff->CpuCount) { + NumberOfProcessorsInCurrentHob =3D MIN (MpHandOff->CpuCount - Proces= sedCpuCount, LimitationOfMpHandOffHob); + + for (Index =3D 0; Index < NumberOfProcessorsInCurrentHob; Index++) { + CurrentProcessorIndex =3D Index+MpHandOff->ProcessorIndex; + if (MpHandOff->Info[Index].ApicId =3D=3D GetInitialApicId ()) { + CpuMpData->BspNumber =3D (UINT32)Index; + } + + InitializeSpinLock (&CpuMpData->CpuData[CurrentProcessorIndex].ApL= ock); + CpuMpData->CpuData[CurrentProcessorIndex].CpuHealthy =3D (MpHandOf= f->Info[Index].Health =3D=3D 0) ? TRUE : FALSE; + CpuMpData->CpuData[CurrentProcessorIndex].ApFunction =3D 0; + CpuInfoInHob[CurrentProcessorIndex].InitialApicId =3D MpHandOff= ->Info[Index].ApicId; + CpuInfoInHob[CurrentProcessorIndex].ApTopOfStack =3D CpuMpData= ->Buffer + (Index + 1) * CpuMpData->CpuApStackSize; + CpuInfoInHob[CurrentProcessorIndex].ApicId =3D MpHandOff= ->Info[Index].ApicId; + CpuInfoInHob[CurrentProcessorIndex].Health =3D MpHandOff= ->Info[Index].Health; + } + + if (ProcessedCpuCount+NumberOfProcessorsInCurrentHob >=3D MpHandOff-= >CpuCount) { + break; + } + + MpHandOff =3D (MP_HAND_OFF *)((UINT8 *)MpHandOff + sizeof (= MP_HAND_OFF) + sizeof (EFI_HOB_GUID_TYPE) + sizeof (PROCESSOR_HAND_OFF) * N= umberOfProcessorsInCurrentHob); + ProcessedCpuCount +=3D NumberOfProcessorsInCurrentHob; } =20 DEBUG ((DEBUG_INFO, "MpHandOff->WaitLoopExecutionMode: %04d, sizeof (V= OID *): %04d\n", MpHandOff->WaitLoopExecutionMode, sizeof (VOID *))); @@ -2183,7 +2191,7 @@ MpInitLibInitialize ( CpuMpData->FinishedCount =3D 0; CpuMpData->InitFlag =3D ApInitDone; SaveCpuMpData (CpuMpData); - SwitchApContext (MpHandOff); + SwitchApContext (CpuMpData->BspNumber); ASSERT (CpuMpData->FinishedCount =3D=3D (CpuMpData->CpuCount - 1)); =20 // diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpIn= itLib/MpLib.h index 468d3a5925..6af635a80c 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -497,17 +497,6 @@ SaveCpuMpData ( IN CPU_MP_DATA *CpuMpData ); =20 -/** - This function Get BspNumber. - - @param[in] MpHandOff Pointer to MpHandOff - @return BspNumber -**/ -UINT32 -GetBspNumber ( - IN CONST MP_HAND_OFF *MpHandOff - ); - /** Get available system memory below 1MB by specified size. =20 @@ -522,12 +511,19 @@ GetWakeupBuffer ( ); =20 /** - Switch Context for each AP. + This function is intended to be invoked by the BSP in order + to wake up the AP. The BSP accomplishes this by triggering a + start-up signal, which in turn causes any APs that are + currently in a loop on the PEI-prepared memory to awaken and + begin running the procedure called SwitchContextPerAp. + This procedure allows the AP to switch to another section of + memory and continue its loop there. =20 + @param[in] BspNumber Bsp Number **/ VOID SwitchApContext ( - IN MP_HAND_OFF *MpHandOff + IN UINT32 BspNumber ); =20 /** diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/M= pInitLib/PeiMpLib.c index f80e00edcf..18f83d9ed5 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -131,31 +131,53 @@ SaveCpuMpData ( CPU_INFO_IN_HOB *CpuInfoInHob; MP_HAND_OFF *MpHandOff; UINTN MpHandOffSize; + UINT32 LimitationOfMpHandOffHob; + UINT32 NumberOfProcessorsInCurrentHob; + UINT32 ProcessedCpuCount; + UINTN CurrentProcessorIndex; =20 // // When APs are in a state that can be waken up by a store operation to = a memory address, // report the MP_HAND_OFF data for DXE to use. // - CpuInfoInHob =3D (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; - MpHandOffSize =3D sizeof (MP_HAND_OFF) + sizeof (PROCESSOR_HAND_OFF) * C= puMpData->CpuCount; - MpHandOff =3D (MP_HAND_OFF *)BuildGuidHob (&mMpHandOffGuid, MpHandOf= fSize); - ASSERT (MpHandOff !=3D NULL); - ZeroMem (MpHandOff, MpHandOffSize); - MpHandOff->ProcessorIndex =3D 0; - - MpHandOff->CpuCount =3D CpuMpData->CpuCount; - if (CpuMpData->ApLoopMode !=3D ApInHltLoop) { - MpHandOff->StartupSignalValue =3D MP_HAND_OFF_SIGNAL; - MpHandOff->WaitLoopExecutionMode =3D sizeof (VOID *); - } + CpuInfoInHob =3D (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob; + // + // Maximum number of processor could be saved in the HOB. + // + LimitationOfMpHandOffHob =3D (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE) - size= of (MP_HAND_OFF)) / sizeof (PROCESSOR_HAND_OFF); + ProcessedCpuCount =3D 0; + while (ProcessedCpuCount < CpuMpData->CpuCount) { + NumberOfProcessorsInCurrentHob =3D MIN ((UINT32)CpuMpData->CpuCount - = ProcessedCpuCount, LimitationOfMpHandOffHob); + MpHandOffSize =3D sizeof (MP_HAND_OFF) + sizeof (PROC= ESSOR_HAND_OFF) * NumberOfProcessorsInCurrentHob; + MpHandOff =3D (MP_HAND_OFF *)BuildGuidHob ( + &mMpHandOffGuid, + MpHandOffSize + ); + ASSERT (MpHandOff !=3D NULL); + ZeroMem (MpHandOff, MpHandOffSize); + // + // Each individual processor can be uniquely identified by + // combining the processorIndex with the mMpHandOffGuid. + // + MpHandOff->ProcessorIndex =3D ProcessedCpuCount; + MpHandOff->CpuCount =3D CpuMpData->CpuCount; =20 - for (Index =3D 0; Index < MpHandOff->CpuCount; Index++) { - MpHandOff->Info[Index].ApicId =3D CpuInfoInHob[Index].ApicId; - MpHandOff->Info[Index].Health =3D CpuInfoInHob[Index].Health; if (CpuMpData->ApLoopMode !=3D ApInHltLoop) { - MpHandOff->Info[Index].StartupSignalAddress =3D (UINT64)(UINTN)Cp= uMpData->CpuData[Index].StartupApSignal; - MpHandOff->Info[Index].StartupProcedureAddress =3D (UINT64)(UINTN)&C= puMpData->CpuData[Index].ApFunction; + MpHandOff->StartupSignalValue =3D MP_HAND_OFF_SIGNAL; + MpHandOff->WaitLoopExecutionMode =3D sizeof (VOID *); } + + for (Index =3D MpHandOff->ProcessorIndex; Index < NumberOfProcessorsIn= CurrentHob + MpHandOff->ProcessorIndex; Index++) { + CurrentProcessorIndex =3D Index-MpHandOff->P= rocessorIndex; + MpHandOff->Info[CurrentProcessorIndex].ApicId =3D CpuInfoInHob[Index= ].ApicId; + MpHandOff->Info[CurrentProcessorIndex].Health =3D CpuInfoInHob[Index= ].Health; + if (CpuMpData->ApLoopMode !=3D ApInHltLoop) { + MpHandOff->Info[CurrentProcessorIndex].StartupSignalAddress =3D= (UINT64)(UINTN)CpuMpData->CpuData[Index].StartupApSignal; + MpHandOff->Info[CurrentProcessorIndex].StartupProcedureAddress =3D= (UINT64)(UINTN)&CpuMpData->CpuData[Index].ApFunction; + } + } + + ProcessedCpuCount +=3D LimitationOfMpHandOffHob; } =20 // --=20 2.36.1.windows.1 -=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 (#106328): https://edk2.groups.io/g/devel/message/106328 Mute This Topic: https://groups.io/mt/99769836/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-