summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Core/PiSmmCore/Smi.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Core/PiSmmCore/Smi.c')
-rw-r--r--MdeModulePkg/Core/PiSmmCore/Smi.c29
1 files changed, 21 insertions, 8 deletions
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);