UefiCpuPkg/PiSmmCpuDxeSmm: distinguish GetSmBase() failure modes
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=4682 Commit725acd0b9c
("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 commit725acd0b9c
, "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, commit725acd0b9c
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>
This commit is contained in:
parent
5fd3078a2e
commit
72c441df36
|
@ -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.
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue