diff options
author | Laszlo Ersek <lersek@redhat.com> | 2024-02-13 13:09:17 -0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-02-14 17:26:43 +0000 |
commit | 72c441df36af347cd54f4ad3869a075b1f34d925 (patch) | |
tree | 06d7d15b6f2fcf7619384863028b833ce69b6bc2 /UefiCpuPkg | |
parent | 5fd3078a2e08f607dc86a16c1b184b6e30a34a49 (diff) | |
download | edk2-72c441df36af347cd54f4ad3869a075b1f34d925.zip edk2-72c441df36af347cd54f4ad3869a075b1f34d925.tar.gz edk2-72c441df36af347cd54f4ad3869a075b1f34d925.tar.bz2 |
UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682
Commit 725acd0b9cc0 ("UefiCpuPkg: Avoid assuming only one smmbasehob",
2023-12-12) introduced a helper function called GetSmBase(), replacing
the lookup of the first and only "gSmmBaseHobGuid" GUID HOB and
unconditional "mCpuHotPlugData.SmBase" allocation, with iterated lookups
plus conditional memory allocation.
This introduced a new failure mode for setting "mCpuHotPlugData.SmBase".
Namely, before commit 725acd0b9cc0, "mCpuHotPlugData.SmBase" would be
allocated regardless of the GUID HOB being absent. After the commit,
"mCpuHotPlugData.SmBase" could remain NULL if the GUID HOB was absent,
*or* one of the memory allocations inside GetSmBase() failed; and in the
former case, we'd even proceed to the rest of PiCpuSmmEntry().
In relation to this conflation of distinct failure modes, commit
725acd0b9cc0 actually introduced a NULL pointer dereference. Namely, a
NULL "mCpuHotPlugData.SmBase" is not handled properly at all now. We're
going to fix that NULL pointer dereference in a subsequent patch; however,
as a pre-requisite for that we need to tell apart the failure modes of
GetSmBase().
For memory allocation failures, return EFI_OUT_OF_RESOURCES. Move the
"assertion" that SMRAM cannot be exhausted happen out to the caller
(PiCpuSmmEntry()). Strengthen the assertion by adding an explicit
CpuDeadLoop() call. (Note: GetSmBase() *already* calls CpuDeadLoop() if
(NumberOfProcessors != MaxNumberOfCpus).)
For the absence of the GUID HOB, return EFI_NOT_FOUND.
For good measure, make GetSmBase() STATIC (it should have been STATIC from
the start).
This is just a refactoring, no behavioral difference is intended (beyond
the explicit CpuDeadLoop() upon SMRAM exhaustion).
Cc: Dun Tan <dun.tan@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Rahul Kumar <rahul1.kumar@intel.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index cd39482..0938294 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -620,14 +620,21 @@ SmBaseHobCompare ( /**
Extract SmBase for all CPU from SmmBase HOB.
- @param[in] MaxNumberOfCpus Max NumberOfCpus.
+ @param[in] MaxNumberOfCpus Max NumberOfCpus.
- @retval SmBaseBuffer Pointer to SmBase Buffer.
- @retval NULL gSmmBaseHobGuid was not been created.
+ @param[out] AllocatedSmBaseBuffer Pointer to SmBase Buffer allocated
+ by this function. Only set if the
+ function returns EFI_SUCCESS.
+
+ @retval EFI_SUCCESS SmBase Buffer output successfully.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_NOT_FOUND gSmmBaseHobGuid was never created.
**/
-UINTN *
+STATIC
+EFI_STATUS
GetSmBase (
- IN UINTN MaxNumberOfCpus
+ IN UINTN MaxNumberOfCpus,
+ OUT UINTN **AllocatedSmBaseBuffer
)
{
UINTN HobCount;
@@ -650,7 +657,7 @@ GetSmBase ( FirstSmmBaseGuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);
if (FirstSmmBaseGuidHob == NULL) {
- return NULL;
+ return EFI_NOT_FOUND;
}
GuidHob = FirstSmmBaseGuidHob;
@@ -672,9 +679,8 @@ GetSmBase ( }
SmBaseHobs = AllocatePool (sizeof (SMM_BASE_HOB_DATA *) * HobCount);
- ASSERT (SmBaseHobs != NULL);
if (SmBaseHobs == NULL) {
- return NULL;
+ return EFI_OUT_OF_RESOURCES;
}
//
@@ -692,7 +698,7 @@ GetSmBase ( ASSERT (SmBaseBuffer != NULL);
if (SmBaseBuffer == NULL) {
FreePool (SmBaseHobs);
- return NULL;
+ return EFI_OUT_OF_RESOURCES;
}
QuickSort (SmBaseHobs, HobCount, sizeof (SMM_BASE_HOB_DATA *), (BASE_SORT_COMPARE)SmBaseHobCompare, &SortBuffer);
@@ -714,7 +720,8 @@ GetSmBase ( }
FreePool (SmBaseHobs);
- return SmBaseBuffer;
+ *AllocatedSmBaseBuffer = SmBaseBuffer;
+ return EFI_SUCCESS;
}
/**
@@ -1111,8 +1118,15 @@ PiCpuSmmEntry ( // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,
// means the SmBase relocation has been done.
//
- mCpuHotPlugData.SmBase = GetSmBase (mMaxNumberOfCpus);
- if (mCpuHotPlugData.SmBase != NULL) {
+ mCpuHotPlugData.SmBase = NULL;
+ Status = GetSmBase (mMaxNumberOfCpus, &mCpuHotPlugData.SmBase);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ ASSERT (Status != EFI_OUT_OF_RESOURCES);
+ CpuDeadLoop ();
+ }
+
+ if (!EFI_ERROR (Status)) {
+ ASSERT (mCpuHotPlugData.SmBase != NULL);
//
// Check whether the Required TileSize is enough.
//
@@ -1126,6 +1140,8 @@ PiCpuSmmEntry ( mSmmRelocated = TRUE;
} else {
+ ASSERT (Status == EFI_NOT_FOUND);
+ ASSERT (mCpuHotPlugData.SmBase == NULL);
//
// When the HOB doesn't exist, allocate new SMBASE itself.
//
|