MdeModulePkg/SmmCore: Add Context in SmiHandlerProfileUnregister.
authorJiewen Yao <jiewen.yao@intel.com>
Fri, 10 Mar 2017 03:45:32 +0000 (11:45 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Mon, 13 Mar 2017 08:04:13 +0000 (16:04 +0800)
The reason is that we observe that a platform may use same Handler
for different context.

In order to support Unregister such handler, we have to input
context information as well.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c

index 45b9d97..c12805a 100644 (file)
@@ -1139,6 +1139,10 @@ SmiHandlerProfileRegisterHandler (
                          For the SmmChildDispatch protocol, the HandlerGuid\r
                          must be the GUID of SmmChildDispatch protocol.\r
   @param Handler         The SMI handler.\r
+  @param Context         The context of the SMI handler.\r
+                         If it is NOT NULL, it will be used to check what is registered.\r
+  @param ContextSize     The size of the context in bytes.\r
+                         If Context is NOT NULL, it will be used to check what is registered.\r
 \r
   @retval EFI_SUCCESS           The original record is removed.\r
   @retval EFI_NOT_FOUND         There is no record for the HandlerGuid and handler.\r
@@ -1148,7 +1152,9 @@ EFIAPI
 SmiHandlerProfileUnregisterHandler (\r
   IN SMI_HANDLER_PROFILE_PROTOCOL   *This,\r
   IN EFI_GUID                       *HandlerGuid,\r
-  IN EFI_SMM_HANDLER_ENTRY_POINT2   Handler\r
+  IN EFI_SMM_HANDLER_ENTRY_POINT2   Handler,\r
+  IN VOID                           *Context, OPTIONAL\r
+  IN UINTN                          ContextSize OPTIONAL\r
   );\r
 \r
 extern UINTN                    mFullSmramRangeCount;\r
index f85c0f0..1e36039 100644 (file)
@@ -1088,6 +1088,40 @@ SmmCoreFindHardwareSmiEntry (
   return SmiEntry;\r
 }\r
 \r
+/**\r
+  Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT.\r
+\r
+  @param UsbContext                   A pointer to EFI_SMM_USB_REGISTER_CONTEXT\r
+  @param UsbContextSize               The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes\r
+  @param SmiHandlerUsbContextSize     The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes\r
+\r
+  @return SmiHandlerUsbContext  A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT\r
+**/\r
+SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *\r
+ConvertSmiHandlerUsbContext (\r
+  IN EFI_SMM_USB_REGISTER_CONTEXT   *UsbContext,\r
+  IN UINTN                          UsbContextSize,\r
+  OUT UINTN                         *SmiHandlerUsbContextSize\r
+  )\r
+{\r
+  UINTN                                     DevicePathSize;\r
+  SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT  *SmiHandlerUsbContext;\r
+\r
+  ASSERT (UsbContextSize == sizeof(EFI_SMM_USB_REGISTER_CONTEXT));\r
+\r
+  DevicePathSize = GetDevicePathSize (UsbContext->Device);\r
+  SmiHandlerUsbContext = AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize);\r
+  if (SmiHandlerUsbContext == NULL) {\r
+    *SmiHandlerUsbContextSize = 0;\r
+    return NULL;\r
+  }\r
+  SmiHandlerUsbContext->Type = UsbContext->Type;\r
+  SmiHandlerUsbContext->DevicePathSize = (UINT32)DevicePathSize;\r
+  CopyMem (SmiHandlerUsbContext + 1, UsbContext->Device, DevicePathSize);\r
+  *SmiHandlerUsbContextSize = sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize;\r
+  return SmiHandlerUsbContext;\r
+}\r
+\r
 /**\r
   This function is called by SmmChildDispatcher module to report\r
   a new SMI handler is registered, to SmmCore.\r
@@ -1123,6 +1157,11 @@ SmiHandlerProfileRegisterHandler (
   SMI_ENTRY    *SmiEntry;\r
   LIST_ENTRY   *List;\r
 \r
+  if (((ContextSize == 0) && (Context != NULL)) ||\r
+      ((ContextSize != 0) && (Context == NULL))) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   SmiHandler = AllocateZeroPool (sizeof (SMI_HANDLER));\r
   if (SmiHandler == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -1131,33 +1170,24 @@ SmiHandlerProfileRegisterHandler (
   SmiHandler->Signature = SMI_HANDLER_SIGNATURE;\r
   SmiHandler->Handler = Handler;\r
   SmiHandler->CallerAddr = (UINTN)CallerAddress;\r
-  if (ContextSize != 0 && Context != NULL) {\r
+  SmiHandler->Context = Context;\r
+  SmiHandler->ContextSize = ContextSize;\r
+\r
+  if (Context != NULL) {\r
     if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
-      EFI_SMM_USB_REGISTER_CONTEXT              *UsbContext;\r
-      UINTN                                     DevicePathSize;\r
-      SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT  *SmiHandlerUsbContext;\r
-\r
-      ASSERT (ContextSize == sizeof(EFI_SMM_USB_REGISTER_CONTEXT));\r
-\r
-      UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context;\r
-      DevicePathSize = GetDevicePathSize (UsbContext->Device);\r
-      SmiHandlerUsbContext = AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize);\r
-      if (SmiHandlerUsbContext != NULL) {\r
-        SmiHandlerUsbContext->Type = UsbContext->Type;\r
-        SmiHandlerUsbContext->DevicePathSize = (UINT32)DevicePathSize;\r
-        CopyMem (SmiHandlerUsbContext + 1, UsbContext->Device, DevicePathSize);\r
-        SmiHandler->Context = SmiHandlerUsbContext;\r
-      }\r
+      SmiHandler->Context = ConvertSmiHandlerUsbContext (Context, ContextSize, &SmiHandler->ContextSize);\r
     } else {\r
       SmiHandler->Context = AllocateCopyPool (ContextSize, Context);\r
     }\r
   }\r
-  if (SmiHandler->Context != NULL) {\r
-    SmiHandler->ContextSize = ContextSize;\r
+  if (SmiHandler->Context == NULL) {\r
+    SmiHandler->ContextSize = 0;\r
   }\r
 \r
   SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, TRUE);\r
   if (SmiEntry == NULL) {\r
+    FreePool (SmiHandler->Context);\r
+    FreePool (SmiHandler);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1178,6 +1208,10 @@ SmiHandlerProfileRegisterHandler (
                          For the SmmChildDispatch protocol, the HandlerGuid\r
                          must be the GUID of SmmChildDispatch protocol.\r
   @param Handler         The SMI handler.\r
+  @param Context         The context of the SMI handler.\r
+                         If it is NOT NULL, it will be used to check what is registered.\r
+  @param ContextSize     The size of the context in bytes.\r
+                         If Context is NOT NULL, it will be used to check what is registered.\r
 \r
   @retval EFI_SUCCESS           The original record is removed.\r
   @retval EFI_NOT_FOUND         There is no record for the HandlerGuid and handler.\r
@@ -1187,7 +1221,9 @@ EFIAPI
 SmiHandlerProfileUnregisterHandler (\r
   IN SMI_HANDLER_PROFILE_PROTOCOL   *This,\r
   IN EFI_GUID                       *HandlerGuid,\r
-  IN EFI_SMM_HANDLER_ENTRY_POINT2   Handler\r
+  IN EFI_SMM_HANDLER_ENTRY_POINT2   Handler,\r
+  IN VOID                           *Context, OPTIONAL\r
+  IN UINTN                          ContextSize OPTIONAL\r
   )\r
 {\r
   LIST_ENTRY   *Link;\r
@@ -1195,21 +1231,46 @@ SmiHandlerProfileUnregisterHandler (
   SMI_HANDLER  *SmiHandler;\r
   SMI_ENTRY    *SmiEntry;\r
   SMI_HANDLER  *TargetSmiHandler;\r
+  VOID         *SearchContext;\r
+  UINTN        SearchContextSize;\r
+\r
+  if (((ContextSize == 0) && (Context != NULL)) ||\r
+      ((ContextSize != 0) && (Context == NULL))) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 \r
   SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, FALSE);\r
   if (SmiEntry == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  SearchContext = Context;\r
+  SearchContextSize = ContextSize;\r
+  if (Context != NULL) {\r
+    if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
+      SearchContext = ConvertSmiHandlerUsbContext (Context, ContextSize, &SearchContextSize);\r
+    }\r
+  }\r
+\r
   TargetSmiHandler = NULL;\r
   Head = &SmiEntry->SmiHandlers;\r
   for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
     SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
     if (SmiHandler->Handler == Handler) {\r
-      TargetSmiHandler = SmiHandler;\r
-      break;\r
+      if ((SearchContext == NULL) ||\r
+          ((SearchContextSize == SmiHandler->ContextSize) && (CompareMem (SearchContext, SmiHandler->Context, SearchContextSize) == 0))) {\r
+        TargetSmiHandler = SmiHandler;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (SearchContext != NULL) {\r
+    if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
+      FreePool (SearchContext);\r
     }\r
   }\r
+\r
   if (TargetSmiHandler == NULL) {\r
     return EFI_NOT_FOUND;\r
   }\r