diff --git a/MdeModulePkg/Core/PiSmmCore/Smi.c b/MdeModulePkg/Core/PiSmmCore/Smi.c index 3489c130fd..b3a81ac877 100644 --- a/MdeModulePkg/Core/PiSmmCore/Smi.c +++ b/MdeModulePkg/Core/PiSmmCore/Smi.c @@ -8,7 +8,8 @@ #include "PiSmmCore.h" -LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList); +SMI_HANDLER *mCurrentSmiHandler = NULL; +LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList); SMI_ENTRY mRootSmiEntry = { SMI_ENTRY_SIGNATURE, @@ -142,13 +143,18 @@ SmiManage ( // Link points to may be freed if unregister SMI handler. // Link = Link->ForwardLink; - - Status = SmiHandler->Handler ( - (EFI_HANDLE)SmiHandler, - Context, - CommBuffer, - CommBufferSize - ); + // + // Assign gCurrentSmiHandle before calling the SMI handler and + // set to NULL when it returns. + // + mCurrentSmiHandler = SmiHandler; + Status = SmiHandler->Handler ( + (EFI_HANDLE)SmiHandler, + Context, + CommBuffer, + CommBufferSize + ); + mCurrentSmiHandler = NULL; switch (Status) { case EFI_INTERRUPT_PENDING: @@ -328,6 +334,13 @@ SmiHandlerUnRegister ( return EFI_INVALID_PARAMETER; } + // + // Do not allow to unregister SMI Handler inside other SMI Handler + // + if ((mCurrentSmiHandler != NULL) && (mCurrentSmiHandler != SmiHandler)) { + return EFI_INVALID_PARAMETER; + } + SmiEntry = SmiHandler->SmiEntry; RemoveEntryList (&SmiHandler->Link);