public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "duntan" <dun.tan@intel.com>
To: devel@edk2.groups.io
Cc: Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Rahul Kumar <rahul1.kumar@intel.com>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: [edk2-devel] [PATCH 6/6] UefiCpuPkg: Avoid assuming only one smmbasehob
Date: Tue,  5 Dec 2023 13:49:00 +0800	[thread overview]
Message-ID: <20231205054900.926-7-dun.tan@intel.com> (raw)
In-Reply-To: <20231205054900.926-1-dun.tan@intel.com>

Modify the gSmmBaseHobGuid consumption code to
remove the asuumption that there is only one
gSmmBaseHobGuid. If the CPU number is big enough,
there will be more than one SmmBaseHob in the
HOB list.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
---
 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 130 insertions(+), 12 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index d8d488b253..36fa5e779a 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -586,6 +586,130 @@ SmmReadyToLockEventNotify (
   return EFI_SUCCESS;
 }
 
+/**
+  Function to compare 2 SMM_BASE_HOB_DATA pointer based on ProcessorIndex.
+
+  @param[in] Buffer1            pointer to SMM_BASE_HOB_DATA poiner to compare
+  @param[in] Buffer2            pointer to second SMM_BASE_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
+SmBaseHobCompare (
+  IN  CONST VOID  *Buffer1,
+  IN  CONST VOID  *Buffer2
+  )
+{
+  if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex > (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
+    return 1;
+  } else if ((*(SMM_BASE_HOB_DATA **)Buffer1)->ProcessorIndex < (*(SMM_BASE_HOB_DATA **)Buffer2)->ProcessorIndex) {
+    return -1;
+  }
+
+  return 0;
+}
+
+/**
+  Extract SmBase for all CPU from SmmBase HOB.
+
+  @param[in]  FirstSmmBaseGuidHob    Pointer to First SmmBaseGuidHob.
+  @param[in]  MaxNumberOfCpus        Max NumberOfCpus.
+  @param[out] SmBaseBufferPointer    Pointer to SmBase buffer pointer.
+
+  @retval EFI_SUCCESS                Successfully extract SmBase for all CPU from SmmBase HOB.
+  @retval RETURN_BUFFER_TOO_SMALL    Fail to allocate memory.
+**/
+EFI_STATUS
+GetSmBaseFromSmmBaseHob (
+  IN  EFI_HOB_GUID_TYPE  *FirstSmmBaseGuidHob,
+  IN  UINTN              MaxNumberOfCpus,
+  OUT UINTN              **SmBaseBufferPointer
+  )
+{
+  UINTN              HobCount;
+  EFI_HOB_GUID_TYPE  *GuidHob;
+  SMM_BASE_HOB_DATA  *SmmBaseHobData;
+  UINTN              NumberOfProcessors;
+  SMM_BASE_HOB_DATA  **SmBaseHobPointerBuffer;
+  UINTN              *SmBaseBuffer;
+  UINTN              Index;
+  UINTN              SortBuffer;
+  UINTN              ProcessorIndex;
+  UINT64             PrevProcessorIndex;
+
+  SmmBaseHobData     = NULL;
+  Index              = 0;
+  ProcessorIndex     = 0;
+  PrevProcessorIndex = 0;
+  HobCount           = 0;
+  NumberOfProcessors = 0;
+  GuidHob            = FirstSmmBaseGuidHob;
+
+  while (GuidHob != NULL) {
+    HobCount++;
+    SmmBaseHobData      = GET_GUID_HOB_DATA (GuidHob);
+    NumberOfProcessors += SmmBaseHobData->NumberOfProcessors;
+    GuidHob             = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
+  }
+
+  ASSERT (NumberOfProcessors == MaxNumberOfCpus);
+
+  SmBaseHobPointerBuffer = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
+  ASSERT (SmBaseHobPointerBuffer != NULL);
+  if (SmBaseHobPointerBuffer == NULL) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // Record each SmmBaseHob pointer in the SmBaseHobPointerBuffer.
+  //
+  GuidHob = FirstSmmBaseGuidHob;
+  ASSERT (GuidHob != NULL);
+  while (Index < HobCount) {
+    SmBaseHobPointerBuffer[Index++] = GET_GUID_HOB_DATA (GuidHob);
+    GuidHob                         = GetNextGuidHob (&gSmmBaseHobGuid, GET_NEXT_HOB (GuidHob));
+  }
+
+  SmBaseBuffer = (UINTN *)AllocatePool (sizeof (UINTN) * (MaxNumberOfCpus));
+  ASSERT (SmBaseBuffer != NULL);
+  if (SmBaseBuffer == NULL) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  QuickSort (SmBaseHobPointerBuffer, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
+  for (Index = 0; Index < HobCount; Index++) {
+    //
+    // Make sure no overlap and no gap in the CPU range covered by each HOB
+    //
+    ASSERT (SmBaseHobPointerBuffer[Index]->ProcessorIndex == PrevProcessorIndex);
+
+    //
+    // Cache each SmBase in order.
+    //
+    if (sizeof (UINTN) == sizeof (UINT64)) {
+      CopyMem (
+        SmBaseBuffer + PrevProcessorIndex,
+        &SmBaseHobPointerBuffer[Index]->SmBase,
+        sizeof (UINT64) * SmBaseHobPointerBuffer[Index]->NumberOfProcessors
+        );
+    } else {
+      for (ProcessorIndex = 0; ProcessorIndex < SmBaseHobPointerBuffer[Index]->NumberOfProcessors; ProcessorIndex++) {
+        SmBaseBuffer[PrevProcessorIndex + ProcessorIndex] = (UINTN)SmBaseHobPointerBuffer[Index]->SmBase[ProcessorIndex];
+      }
+    }
+
+    PrevProcessorIndex += SmBaseHobPointerBuffer[Index]->NumberOfProcessors;
+  }
+
+  FreePool (SmBaseHobPointerBuffer);
+
+  *SmBaseBufferPointer = SmBaseBuffer;
+  return EFI_SUCCESS;
+}
+
 /**
   Function to compare 2 MP_INFORMATION2_HOB_DATA pointer based on ProcessorIndex.
 
@@ -766,10 +890,8 @@ PiCpuSmmEntry (
   UINTN              ModelId;
   UINT32             Cr3;
   EFI_HOB_GUID_TYPE  *GuidHob;
-  SMM_BASE_HOB_DATA  *SmmBaseHobData;
 
-  GuidHob        = NULL;
-  SmmBaseHobData = NULL;
+  GuidHob = NULL;
 
   PERF_FUNCTION_BEGIN ();
 
@@ -1002,12 +1124,8 @@ PiCpuSmmEntry (
       return RETURN_BUFFER_TOO_SMALL;
     }
 
-    SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob);
-
-    //
-    // Assume single instance of HOB produced, expect the HOB.NumberOfProcessors equals to the mMaxNumberOfCpus.
-    //
-    ASSERT (SmmBaseHobData->NumberOfProcessors == (UINT32)mMaxNumberOfCpus && SmmBaseHobData->ProcessorIndex == 0);
+    Status = GetSmBaseFromSmmBaseHob (GuidHob, mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
+    ASSERT_EFI_ERROR (Status);
     mSmmRelocated = TRUE;
   } else {
     //
@@ -1053,8 +1171,6 @@ PiCpuSmmEntry (
   //
   mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus);
   ASSERT (mCpuHotPlugData.ApicId != NULL);
-  mCpuHotPlugData.SmBase = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
-  ASSERT (mCpuHotPlugData.SmBase != NULL);
   mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus;
 
   //
@@ -1063,7 +1179,9 @@ PiCpuSmmEntry (
   // size for each CPU in the platform
   //
   for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
-    mCpuHotPlugData.SmBase[Index] = mSmmRelocated ? (UINTN)SmmBaseHobData->SmBase[Index] : (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET;
+    if (!mSmmRelocated) {
+      mCpuHotPlugData.SmBase[Index] = (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET;
+    }
 
     gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP);
     gSmmCpuPrivate->CpuSaveState[Index]     = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET);
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112068): https://edk2.groups.io/g/devel/message/112068
Mute This Topic: https://groups.io/mt/102987142/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2023-12-05  5:49 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-05  5:48 [edk2-devel] [PATCH 0/6] Create and consume a new gMpInformationHobGuid2 in UefiCpuPkg duntan
2023-12-05  5:48 ` [edk2-devel] [PATCH 1/6] UefiCpuPkg: Create " duntan
2023-12-06  9:09   ` Ni, Ray
2023-12-07  0:21     ` duntan
2023-12-05  5:48 ` [edk2-devel] [PATCH 2/6] UefiCpuPkg: Build MpInfo2HOB in CpuMpPei duntan
2023-12-06  9:24   ` Ni, Ray
2023-12-07  0:21     ` duntan
2023-12-05  5:48 ` [edk2-devel] [PATCH 3/6] UefiCpuPkg: Consume MpInfo2Hob in PiSmmCpuDxe duntan
2023-12-06  9:55   ` Ni, Ray
2023-12-07  0:22     ` duntan
2023-12-07  1:26       ` Ni, Ray
2023-12-05  5:48 ` [edk2-devel] [PATCH 4/6] UefiCpuPkg: Add a new field in MpInfo2 HOB duntan
2023-12-06  9:55   ` Ni, Ray
2023-12-05  5:48 ` [edk2-devel] [PATCH 5/6] UefiCpuPkg: Cache core type " duntan
2023-12-06 10:01   ` Ni, Ray
2023-12-07  0:23     ` duntan
2023-12-05  5:49 ` duntan [this message]
2023-12-06 10:14   ` [edk2-devel] [PATCH 6/6] UefiCpuPkg: Avoid assuming only one smmbasehob Ni, Ray
2023-12-07  0:37     ` duntan
2023-12-07  1:25       ` Ni, Ray

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231205054900.926-7-dun.tan@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox