summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2024-02-13 13:09:17 -0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-02-14 17:26:43 +0000
commit72c441df36af347cd54f4ad3869a075b1f34d925 (patch)
tree06d7d15b6f2fcf7619384863028b833ce69b6bc2
parent5fd3078a2e08f607dc86a16c1b184b6e30a34a49 (diff)
downloadedk2-72c441df36af347cd54f4ad3869a075b1f34d925.tar.gz
edk2-72c441df36af347cd54f4ad3869a075b1f34d925.tar.bz2
edk2-72c441df36af347cd54f4ad3869a075b1f34d925.zip
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>
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index cd394826ff..09382945dd 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.
//