]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.c
MdeModulePkg/Universal: Fix typos in comments
[mirror_edk2.git] / MdeModulePkg / Universal / FaultTolerantWriteDxe / FaultTolerantWriteSmm.c
index 13c709658f255f5bb5ec61218065d6372f67bc67..1e75328f9b9057dbb4896bd13a26a849fafe180d 100644 (file)
@@ -43,7 +43,7 @@
   Caution: This module requires additional review when modified.\r
   This driver need to make sure the CommBuffer is not in the SMRAM range. \r
 \r
-Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -56,16 +56,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <PiSmm.h>\r
 #include <Library/SmmServicesTableLib.h>\r
+#include <Library/SmmMemLib.h>\r
 #include <Protocol/SmmSwapAddressRange.h>\r
 #include "FaultTolerantWrite.h"\r
 #include "FaultTolerantWriteSmmCommon.h"\r
-#include <Protocol/SmmAccess2.h>\r
 #include <Protocol/SmmEndOfDxe.h>\r
 \r
 EFI_EVENT                                 mFvbRegistration = NULL;\r
 EFI_FTW_DEVICE                            *mFtwDevice      = NULL;\r
-EFI_SMRAM_DESCRIPTOR                      *mSmramRanges;\r
-UINTN                                     mSmramRangeCount;\r
 \r
 ///\r
 /// The flag to indicate whether the platform has left the DXE phase of execution.\r
@@ -73,35 +71,7 @@ UINTN                                     mSmramRangeCount;
 BOOLEAN                                   mEndOfDxe = FALSE;\r
 \r
 /**\r
-  This function check if the address is in SMRAM.\r
-\r
-  @param Buffer  the buffer address to be checked.\r
-  @param Length  the buffer length to be checked.\r
-\r
-  @retval TRUE  this address is in SMRAM.\r
-  @retval FALSE this address is NOT in SMRAM.\r
-**/\r
-BOOLEAN\r
-InternalIsAddressInSmram (\r
-  IN EFI_PHYSICAL_ADDRESS  Buffer,\r
-  IN UINT64                Length\r
-  )\r
-{\r
-  UINTN  Index;\r
-\r
-  for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
-    if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||\r
-        ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  Retrive the SMM FVB protocol interface by HANDLE.\r
+  Retrieve the SMM FVB protocol interface by HANDLE.\r
 \r
   @param[in]  FvBlockHandle     The handle of SMM FVB protocol that provides services for\r
                                 reading, writing, and erasing the target block.\r
@@ -129,7 +99,7 @@ FtwGetFvbByHandle (
 }\r
 \r
 /**\r
-  Retrive the SMM Swap Address Range protocol interface.\r
+  Retrieve the SMM Swap Address Range protocol interface.\r
 \r
   @param[out] SarProtocol       The interface of SMM SAR protocol\r
 \r
@@ -248,6 +218,8 @@ GetFvbByAddressAndAttribute (
   EFI_FVB_ATTRIBUTES_2                FvbAttributes;\r
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;\r
 \r
+  HandleBuffer = NULL;\r
+\r
   //\r
   // Locate all handles of SMM Fvb protocol.\r
   //\r
@@ -343,7 +315,10 @@ SmmFaultTolerantWriteHandler (
   VOID                                             *PrivateData;\r
   EFI_HANDLE                                       SmmFvbHandle;\r
   UINTN                                            InfoSize;\r
-\r
+  UINTN                                            CommBufferPayloadSize;\r
+  UINTN                                            PrivateDataSize;\r
+  UINTN                                            Length;\r
+  UINTN                                            TempCommBufferSize;\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
@@ -352,12 +327,16 @@ SmmFaultTolerantWriteHandler (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (*CommBufferSize < SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
+  TempCommBufferSize = *CommBufferSize;\r
+\r
+  if (TempCommBufferSize < SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
+    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer size invalid!\n"));\r
     return EFI_SUCCESS;\r
   }\r
+  CommBufferPayloadSize = TempCommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE;\r
 \r
-  if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication buffer size is in SMRAM!\n"));\r
+  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+    DEBUG ((EFI_D_ERROR, "SmmFtwHandler: SMM communication buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -374,17 +353,11 @@ SmmFaultTolerantWriteHandler (
 \r
   switch (SmmFtwFunctionHeader->Function) {\r
     case FTW_FUNCTION_GET_MAX_BLOCK_SIZE:\r
-      SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      InfoSize = sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER);\r
-\r
-      //\r
-      // SMRAM range check already covered before\r
-      //\r
-      if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
-        DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
-        Status = EFI_ACCESS_DENIED;\r
-        break;\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "GetMaxBlockSize: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
       }\r
+      SmmGetMaxBlockSizeHeader = (SMM_FTW_GET_MAX_BLOCK_SIZE_HEADER *) SmmFtwFunctionHeader->Data;\r
 \r
       Status = FtwGetMaxBlockSize (\r
                  &mFtwDevice->FtwInstance,\r
@@ -393,6 +366,10 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_ALLOCATE:\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_ALLOCATE_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "Allocate: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwAllocateHeader = (SMM_FTW_ALLOCATE_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = FtwAllocate (\r
                  &mFtwDevice->FtwInstance,\r
@@ -403,11 +380,36 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_WRITE:\r
+      if (CommBufferPayloadSize < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data)) {\r
+        DEBUG ((EFI_D_ERROR, "Write: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwWriteHeader = (SMM_FTW_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      if (SmmFtwWriteHeader->PrivateDataSize == 0) {\r
+      Length = SmmFtwWriteHeader->Length;\r
+      PrivateDataSize = SmmFtwWriteHeader->PrivateDataSize;\r
+      if (((UINTN)(~0) - Length < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data)) ||\r
+        ((UINTN)(~0) - PrivateDataSize < OFFSET_OF (SMM_FTW_WRITE_HEADER, Data) + Length)) {\r
+        //\r
+        // Prevent InfoSize overflow\r
+        //\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      }\r
+      InfoSize = OFFSET_OF (SMM_FTW_WRITE_HEADER, Data) + Length + PrivateDataSize;\r
+\r
+      //\r
+      // SMRAM range check already covered before\r
+      //\r
+      if (InfoSize > CommBufferPayloadSize) {\r
+        DEBUG ((EFI_D_ERROR, "Write: Data size exceed communication buffer size limit!\n"));\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      }\r
+\r
+      if (PrivateDataSize == 0) {\r
         PrivateData = NULL;\r
       } else {\r
-        PrivateData = (VOID *)&SmmFtwWriteHeader->Data[SmmFtwWriteHeader->Length];\r
+        PrivateData = (VOID *)&SmmFtwWriteHeader->Data[Length];\r
       }\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwWriteHeader->FvbBaseAddress, \r
@@ -419,7 +421,7 @@ SmmFaultTolerantWriteHandler (
                    &mFtwDevice->FtwInstance,\r
                    SmmFtwWriteHeader->Lba,\r
                    SmmFtwWriteHeader->Offset,\r
-                   SmmFtwWriteHeader->Length,\r
+                   Length,\r
                    PrivateData,\r
                    SmmFvbHandle,\r
                    SmmFtwWriteHeader->Data\r
@@ -428,6 +430,10 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_RESTART:\r
+      if (CommBufferPayloadSize < sizeof (SMM_FTW_RESTART_HEADER)) {\r
+        DEBUG ((EFI_D_ERROR, "Restart: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwRestartHeader = (SMM_FTW_RESTART_HEADER *) SmmFtwFunctionHeader->Data;\r
       Status = GetFvbByAddressAndAttribute (\r
                  SmmFtwRestartHeader->FvbBaseAddress, \r
@@ -444,20 +450,25 @@ SmmFaultTolerantWriteHandler (
       break;\r
       \r
     case FTW_FUNCTION_GET_LAST_WRITE:\r
+      if (CommBufferPayloadSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)) {\r
+        DEBUG ((EFI_D_ERROR, "GetLastWrite: SMM communication buffer size invalid!\n"));\r
+        return EFI_SUCCESS;\r
+      }\r
       SmmFtwGetLastWriteHeader = (SMM_FTW_GET_LAST_WRITE_HEADER *) SmmFtwFunctionHeader->Data;\r
-      if ((UINTN)(~0) - SmmFtwGetLastWriteHeader->PrivateDataSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)){\r
+      PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;\r
+      if ((UINTN)(~0) - PrivateDataSize < OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data)){\r
         //\r
         // Prevent InfoSize overflow\r
         //\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
       }\r
-      InfoSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) + SmmFtwGetLastWriteHeader->PrivateDataSize;\r
+      InfoSize = OFFSET_OF (SMM_FTW_GET_LAST_WRITE_HEADER, Data) + PrivateDataSize;\r
 \r
       //\r
       // SMRAM range check already covered before\r
       //\r
-      if (InfoSize > *CommBufferSize - SMM_FTW_COMMUNICATE_HEADER_SIZE) {\r
+      if (InfoSize > CommBufferPayloadSize) {\r
         DEBUG ((EFI_D_ERROR, "Data size exceed communication buffer size limit!\n"));\r
         Status = EFI_ACCESS_DENIED;\r
         break;\r
@@ -469,10 +480,11 @@ SmmFaultTolerantWriteHandler (
                  &SmmFtwGetLastWriteHeader->Lba,\r
                  &SmmFtwGetLastWriteHeader->Offset,\r
                  &SmmFtwGetLastWriteHeader->Length,\r
-                 &SmmFtwGetLastWriteHeader->PrivateDataSize,\r
+                 &PrivateDataSize,\r
                  (VOID *)SmmFtwGetLastWriteHeader->Data,\r
                  &SmmFtwGetLastWriteHeader->Complete\r
                  );\r
+      SmmFtwGetLastWriteHeader->PrivateDataSize = PrivateDataSize;\r
       break;\r
 \r
     default:\r
@@ -506,6 +518,7 @@ FvbNotificationEvent (
   EFI_STATUS                              Status;\r
   EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL   *FtwProtocol;\r
   EFI_HANDLE                              SmmFtwHandle;\r
+  EFI_HANDLE                              FtwHandle;\r
   \r
   //\r
   // Just return to avoid install SMM FaultTolerantWriteProtocol again\r
@@ -527,7 +540,7 @@ FvbNotificationEvent (
   if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Install protocol interface\r
   //\r
@@ -539,12 +552,18 @@ FvbNotificationEvent (
                     );\r
   ASSERT_EFI_ERROR (Status); \r
 \r
+  ///\r
+  /// Register SMM FTW SMI handler\r
+  ///\r
+  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &SmmFtwHandle);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
   // Notify the Ftw wrapper driver SMM Ftw is ready\r
   //\r
-  SmmFtwHandle = NULL;\r
+  FtwHandle = NULL;\r
   Status = gBS->InstallProtocolInterface (\r
-                  &SmmFtwHandle,\r
+                  &FtwHandle,\r
                   &gEfiSmmFaultTolerantWriteProtocolGuid,\r
                   EFI_NATIVE_INTERFACE,\r
                   NULL\r
@@ -595,9 +614,6 @@ SmmFaultTolerantWriteInitialize (
   )\r
 {\r
   EFI_STATUS                              Status;\r
-  EFI_HANDLE                              FtwHandle;\r
-  EFI_SMM_ACCESS2_PROTOCOL                *SmmAccess;\r
-  UINTN                                   Size;\r
   VOID                                    *SmmEndOfDxeRegistration;\r
 \r
   //\r
@@ -608,28 +624,6 @@ SmmFaultTolerantWriteInitialize (
     return Status;\r
   }\r
 \r
-  //\r
-  // Get SMRAM information\r
-  //\r
-  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Size = 0;\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-  Status = gSmst->SmmAllocatePool (\r
-                    EfiRuntimeServicesData,\r
-                    Size,\r
-                    (VOID **)&mSmramRanges\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
-\r
   //\r
   // Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.\r
   //\r
@@ -651,12 +645,6 @@ SmmFaultTolerantWriteInitialize (
   ASSERT_EFI_ERROR (Status);\r
 \r
   FvbNotificationEvent (NULL, NULL, NULL);\r
-\r
-  ///\r
-  /// Register SMM FTW SMI handler\r
-  ///\r
-  Status = gSmst->SmiHandlerRegister (SmmFaultTolerantWriteHandler, &gEfiSmmFaultTolerantWriteProtocolGuid, &FtwHandle);\r
-  ASSERT_EFI_ERROR (Status);\r
   \r
   return EFI_SUCCESS;\r
 }\r