MdeModulePkg/UefiBootManagerLib: limit recursive call depth
Function BmRepairAllControllers may recursively call itself if some driver health protocol returns EfiDriverHealthStatusReconnectRequired. However, driver health protocol of some buggy third party driver may always return such status even after one and another reconnect. The endless iteration will cause stack overflow and then system exception, and it may be not easy to find that the exception is actually caused by stack overflow. So we limit the number of reconnect retry to 10 to improve code robustness, and DEBUG_CODE is moved ahead before recursive repair to track the repair result. We also remove a duplicated declaration of BmRepairAllControllers() in InternalBm.h in this patch, for it is only a trivial change. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Heyi Guo <heyi.guo@linaro.org> Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
@@ -423,10 +423,13 @@ EfiBootManagerFreeDriverHealthInfo (
|
||||
|
||||
/**
|
||||
Repair all the controllers according to the Driver Health status queried.
|
||||
|
||||
@param ReconnectRepairCount To record the number of recursive call of
|
||||
this function itself.
|
||||
**/
|
||||
VOID
|
||||
BmRepairAllControllers (
|
||||
VOID
|
||||
UINTN ReconnectRepairCount
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
@@ -548,10 +551,6 @@ BmRepairAllControllers (
|
||||
EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);
|
||||
|
||||
|
||||
if (ReconnectRequired) {
|
||||
BmRepairAllControllers ();
|
||||
}
|
||||
|
||||
DEBUG_CODE (
|
||||
CHAR16 *ControllerName;
|
||||
|
||||
@@ -576,6 +575,15 @@ BmRepairAllControllers (
|
||||
EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);
|
||||
);
|
||||
|
||||
if (ReconnectRequired) {
|
||||
if (ReconnectRepairCount < MAX_RECONNECT_REPAIR) {
|
||||
BmRepairAllControllers (ReconnectRepairCount + 1);
|
||||
} else {
|
||||
DEBUG ((DEBUG_ERROR, "[%a:%d] Repair failed after %d retries.\n",
|
||||
__FUNCTION__, __LINE__, ReconnectRepairCount));
|
||||
}
|
||||
}
|
||||
|
||||
if (RebootRequired) {
|
||||
DEBUG ((EFI_D_INFO, "[BDS] One of the Driver Health instances requires rebooting.\n"));
|
||||
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
||||
|
Reference in New Issue
Block a user