summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDun Tan <dun.tan@intel.com>2023-11-24 15:55:34 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-12-12 01:37:41 +0000
commitbe44fff7237a79726bdf144f86e434debaa3868a (patch)
tree1693e2298398115bdf56969db8cb4e1ce4134018
parente10f1f5a043a402fb2daf2091b8f725fd2951743 (diff)
downloadedk2-be44fff7237a79726bdf144f86e434debaa3868a.tar.gz
edk2-be44fff7237a79726bdf144f86e434debaa3868a.tar.bz2
edk2-be44fff7237a79726bdf144f86e434debaa3868a.zip
UefiCpuPkg: Consume MpInfo2Hob in PiSmmCpuDxe
Consume MpInfo2Hob in PiSmmCpuDxe driver to get NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from the MpInformation2 HOB. This can avoid calling MP service. Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c209
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h2
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf8
3 files changed, 168 insertions, 51 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 1d022a7051..53f67d544d 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -99,8 +99,8 @@ UINTN mSmmStackSize;
UINTN mSmmShadowStackSize;
BOOLEAN mCetSupported = TRUE;
-UINTN mMaxNumberOfCpus = 1;
-UINTN mNumberOfCpus = 1;
+UINTN mMaxNumberOfCpus = 0;
+UINTN mNumberOfCpus = 0;
//
// SMM ready to lock flag
@@ -587,6 +587,146 @@ SmmReadyToLockEventNotify (
}
/**
+ Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
+
+ @param[in] Buffer1 pointer to MP_INFORMATION2_HOB_DATA poiner to compare
+ @param[in] Buffer2 pointer to second MP_INFORMATION2_HOB_DATA pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+MpInformation2HobCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex > (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return 1;
+ } else if ((*(MP_INFORMATION2_HOB_DATA **)Buffer1)->ProcessorIndex < (*(MP_INFORMATION2_HOB_DATA **)Buffer2)->ProcessorIndex) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
+
+ @param[out] NumberOfCpus Pointer to NumberOfCpus.
+ @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
+
+ @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
+**/
+EFI_PROCESSOR_INFORMATION *
+GetMpInformation (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxNumberOfCpus
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_HOB_GUID_TYPE *FirstMpInfo2Hob;
+ MP_INFORMATION2_HOB_DATA *MpInformation2HobData;
+ UINTN HobCount;
+ UINTN HobIndex;
+ MP_INFORMATION2_HOB_DATA **MpInfo2Hobs;
+ UINTN SortBuffer;
+ UINTN ProcessorIndex;
+ UINT64 PrevProcessorIndex;
+ MP_INFORMATION2_ENTRY *MpInformation2Entry;
+ EFI_PROCESSOR_INFORMATION *ProcessorInfo;
+
+ GuidHob = NULL;
+ MpInformation2HobData = NULL;
+ FirstMpInfo2Hob = NULL;
+ MpInfo2Hobs = NULL;
+ HobIndex = 0;
+ HobCount = 0;
+
+ FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformationHobGuid2);
+ ASSERT (FirstMpInfo2Hob != NULL);
+ GuidHob = FirstMpInfo2Hob;
+ while (GuidHob != NULL) {
+ MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob);
+
+ //
+ // This is the last MpInformationHob in the HOB list.
+ //
+ if (MpInformation2HobData->NumberOfProcessors == 0) {
+ ASSERT (HobCount != 0);
+ break;
+ }
+
+ HobCount++;
+ *NumberOfCpus += MpInformation2HobData->NumberOfProcessors;
+ GuidHob = GetNextGuidHob (&gMpInformationHobGuid2, GET_NEXT_HOB (GuidHob));
+ }
+
+ ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+
+ //
+ // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
+ //
+ if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
+ *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ } else {
+ *MaxNumberOfCpus = *NumberOfCpus;
+ }
+
+ MpInfo2Hobs = AllocatePool (sizeof (MP_INFORMATION2_HOB_DATA *) * HobCount);
+ ASSERT (MpInfo2Hobs != NULL);
+ if (MpInfo2Hobs == NULL) {
+ return NULL;
+ }
+
+ //
+ // Record each MpInformation2Hob pointer in the MpInfo2Hobs.
+ // The FirstMpInfo2Hob is to speed up this while-loop without
+ // needing to look for MpInfo2Hob from beginning.
+ //
+ GuidHob = FirstMpInfo2Hob;
+ while (HobIndex < HobCount) {
+ MpInfo2Hobs[HobIndex++] = GET_GUID_HOB_DATA (GuidHob);
+ GuidHob = GetNextGuidHob (&gMpInformationHobGuid2, GET_NEXT_HOB (GuidHob));
+ }
+
+ ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * (*MaxNumberOfCpus));
+ ASSERT (ProcessorInfo != NULL);
+ if (ProcessorInfo == NULL) {
+ FreePool (MpInfo2Hobs);
+ return NULL;
+ }
+
+ QuickSort (MpInfo2Hobs, HobCount, sizeof (MP_INFORMATION2_HOB_DATA *), (BASE_SORT_COMPARE)MpInformation2HobCompare, &SortBuffer);
+ PrevProcessorIndex = 0;
+ for (HobIndex = 0; HobIndex < HobCount; HobIndex++) {
+ //
+ // Make sure no overlap and no gap in the CPU range covered by each HOB
+ //
+ ASSERT (MpInfo2Hobs[HobIndex]->ProcessorIndex == PrevProcessorIndex);
+
+ //
+ // Cache each EFI_PROCESSOR_INFORMATION in order.
+ //
+ for (ProcessorIndex = 0; ProcessorIndex < MpInfo2Hobs[HobIndex]->NumberOfProcessors; ProcessorIndex++) {
+ MpInformation2Entry = GET_MP_INFORMATION_ENTRY (MpInfo2Hobs[HobIndex], ProcessorIndex);
+ CopyMem (
+ &ProcessorInfo[PrevProcessorIndex + ProcessorIndex],
+ &MpInformation2Entry->ProcessorInfo,
+ sizeof (EFI_PROCESSOR_INFORMATION)
+ );
+ }
+
+ PrevProcessorIndex += MpInfo2Hobs[HobIndex]->NumberOfProcessors;
+ }
+
+ FreePool (MpInfo2Hobs);
+ return ProcessorInfo;
+}
+
+/**
The module Entry Point of the CPU SMM driver.
@param ImageHandle The firmware allocated handle for the EFI image.
@@ -603,26 +743,24 @@ PiCpuSmmEntry (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- EFI_STATUS Status;
- EFI_MP_SERVICES_PROTOCOL *MpServices;
- UINTN NumberOfEnabledProcessors;
- UINTN Index;
- VOID *Buffer;
- UINTN BufferPages;
- UINTN TileCodeSize;
- UINTN TileDataSize;
- UINTN TileSize;
- UINT8 *Stacks;
- VOID *Registration;
- UINT32 RegEax;
- UINT32 RegEbx;
- UINT32 RegEcx;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
- UINT32 Cr3;
- EFI_HOB_GUID_TYPE *GuidHob;
- SMM_BASE_HOB_DATA *SmmBaseHobData;
+ EFI_STATUS Status;
+ UINTN Index;
+ VOID *Buffer;
+ UINTN BufferPages;
+ UINTN TileCodeSize;
+ UINTN TileDataSize;
+ UINTN TileSize;
+ UINT8 *Stacks;
+ VOID *Registration;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+ UINT32 Cr3;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ SMM_BASE_HOB_DATA *SmmBaseHobData;
GuidHob = NULL;
SmmBaseHobData = NULL;
@@ -654,17 +792,10 @@ PiCpuSmmEntry (
FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize);
//
- // Get MP Services Protocol
- //
- Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Use MP Services Protocol to retrieve the number of processors and number of enabled processors
+ // Retrive NumberOfProcessors, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
//
- Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfCpus, &NumberOfEnabledProcessors);
- ASSERT_EFI_ERROR (Status);
- ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ gSmmCpuPrivate->ProcessorInfo = GetMpInformation (&mNumberOfCpus, &mMaxNumberOfCpus);
+ ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL);
//
// If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
@@ -690,15 +821,6 @@ PiCpuSmmEntry (
mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask));
- //
- // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
- //
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- mMaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
- } else {
- mMaxNumberOfCpus = mNumberOfCpus;
- }
-
gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;
PERF_CODE (
@@ -908,9 +1030,6 @@ PiCpuSmmEntry (
//
// Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA.
//
- gSmmCpuPrivate->ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL);
-
gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus);
ASSERT (gSmmCpuPrivate->Operation != NULL);
@@ -945,8 +1064,6 @@ PiCpuSmmEntry (
gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
if (Index < mNumberOfCpus) {
- Status = MpServices->GetProcessorInfo (MpServices, Index | CPU_V2_EXTENDED_TOPOLOGY, &gSmmCpuPrivate->ProcessorInfo[Index]);
- ASSERT_EFI_ERROR (Status);
mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId;
DEBUG ((
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index 20ada465c2..f18345881b 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -14,7 +14,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <PiSmm.h>
-#include <Protocol/MpService.h>
#include <Protocol/SmmConfiguration.h>
#include <Protocol/SmmCpu.h>
#include <Protocol/SmmAccess2.h>
@@ -27,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/MemoryAttributesTable.h>
#include <Guid/PiSmmMemoryAttributesTable.h>
#include <Guid/SmmBaseHob.h>
+#include <Guid/MpInformation2.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index 5d52ed7d13..372596f24c 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -106,7 +106,6 @@
[Protocols]
gEfiSmmAccess2ProtocolGuid ## CONSUMES
- gEfiMpServiceProtocolGuid ## CONSUMES
gEfiSmmConfigurationProtocolGuid ## PRODUCES
gEfiSmmCpuProtocolGuid ## PRODUCES
gEfiSmmReadyToLockProtocolGuid ## NOTIFY
@@ -120,6 +119,7 @@
gEdkiiPiSmmMemoryAttributesTableGuid ## CONSUMES ## SystemTable
gEfiMemoryAttributesTableGuid ## CONSUMES ## SystemTable
gSmmBaseHobGuid ## CONSUMES
+ gMpInformationHobGuid2 ## CONSUMES # Assume the HOB must has been created
[FeaturePcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES
@@ -153,11 +153,11 @@
[FixedPcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmMpTokenCountPerChunk ## CONSUMES
+[Depex]
+ TRUE
+
[Pcd.X64]
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess ## CONSUMES
-[Depex]
- gEfiMpServiceProtocolGuid
-
[UserExtensions.TianoCore."ExtraFiles"]
PiSmmCpuDxeSmmExtra.uni