UINTN mFullSmramRangeCount;\r
EFI_SMRAM_DESCRIPTOR *mFullSmramRanges;\r
\r
+//\r
+// Maximum support address used to check input CommunicationBuffer\r
+//\r
+UINTN mMaximumSupportAddress = 0;\r
+\r
/**\r
Place holder function until all the SMM System Table Service are available.\r
\r
return Status;\r
}\r
\r
+/**\r
+ Caculate and save the maximum support address.\r
+\r
+**/\r
+VOID\r
+CaculateMaximumSupportAddress (\r
+ VOID\r
+ )\r
+{\r
+ VOID *Hob;\r
+ UINT32 RegEax;\r
+ UINT8 PhysicalAddressBits;\r
+\r
+ //\r
+ // Get physical address bits supported.\r
+ //\r
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
+ if (Hob != NULL) {\r
+ PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
+ } else {\r
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+ if (RegEax >= 0x80000008) {\r
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+ PhysicalAddressBits = (UINT8) RegEax;\r
+ } else {\r
+ PhysicalAddressBits = 36;\r
+ }\r
+ }\r
+ //\r
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
+ //\r
+ ASSERT (PhysicalAddressBits <= 52);\r
+ if (PhysicalAddressBits > 48) {\r
+ PhysicalAddressBits = 48;\r
+ }\r
+ \r
+ //\r
+ // Save the maximum support address in one global variable \r
+ //\r
+ mMaximumSupportAddress = (UINTN) (LShiftU64 (1, PhysicalAddressBits) - 1);\r
+ DEBUG ((EFI_D_INFO, "mMaximumSupportAddress = 0x%lx\n", mMaximumSupportAddress));\r
+}\r
+\r
+/**\r
+ Check if input buffer is in valid address scope or not.\r
+\r
+ @param[in] Pointer Pointer to the input buffer.\r
+ @param[in] BufferSize Input buffer size in bytes.\r
+\r
+ @retval TRUE The input buffer is in valid address scope. \r
+ @retval FALSE The input buffer is not in valid address scope. \r
+\r
+**/\r
+BOOLEAN\r
+IsValidPointer (\r
+ IN VOID *Pointer,\r
+ IN UINTN BufferSize\r
+ )\r
+{\r
+ if ((UINTN) Pointer > mMaximumSupportAddress) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (BufferSize > (mMaximumSupportAddress - (UINTN) Pointer)) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
/**\r
The main entry point to SMM Foundation.\r
\r
//\r
// Synchronous SMI for SMM Core or request from Communicate protocol\r
//\r
- CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;\r
- gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
- Status = SmiManage (\r
- &CommunicateHeader->HeaderGuid, \r
- NULL, \r
- CommunicateHeader->Data, \r
- &gSmmCorePrivate->BufferSize\r
- );\r
-\r
- //\r
- // Update CommunicationBuffer, BufferSize and ReturnStatus\r
- // Communicate service finished, reset the pointer to CommBuffer to NULL\r
- //\r
- gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
- gSmmCorePrivate->CommunicationBuffer = NULL;\r
- gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;\r
+ if (!IsValidPointer (gSmmCorePrivate->CommunicationBuffer, gSmmCorePrivate->BufferSize)) {\r
+ //\r
+ // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER\r
+ //\r
+ gSmmCorePrivate->CommunicationBuffer = NULL;\r
+ gSmmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;\r
+ } else {\r
+ CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;\r
+ gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+ Status = SmiManage (\r
+ &CommunicateHeader->HeaderGuid, \r
+ NULL, \r
+ CommunicateHeader->Data, \r
+ &gSmmCorePrivate->BufferSize\r
+ );\r
+ //\r
+ // Update CommunicationBuffer, BufferSize and ReturnStatus\r
+ // Communicate service finished, reset the pointer to CommBuffer to NULL\r
+ //\r
+ gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
+ gSmmCorePrivate->CommunicationBuffer = NULL;\r
+ gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;\r
+ }\r
}\r
}\r
\r
\r
RegisterSmramProfileHandler ();\r
\r
+ //\r
+ // Caculate and save maximum support address used in SmmEntryPoint().\r
+ //\r
+ CaculateMaximumSupportAddress ();\r
+\r
return EFI_SUCCESS;\r
}\r