\r
SmmPerformanceHandlerEx(), SmmPerformanceHandler() will receive untrusted input and do basic validation.\r
\r
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
SPIN_LOCK mSmmFpdtLock;\r
PERFORMANCE_PROPERTY mPerformanceProperty;\r
UINT32 mCachedLength = 0;\r
+UINT32 mBootRecordSize = 0;\r
\r
//\r
// Interfaces for SMM PerformanceMeasurement Protocol.\r
}\r
\r
/**\r
- SmmReadyToBoot protocol notification event handler.\r
+ Communication service SMI Handler entry.\r
\r
- @param Protocol Points to the protocol's unique identifier\r
- @param Interface Points to the interface instance\r
- @param Handle The handle on which the interface was installed\r
+ This SMI handler provides services for report MM boot records.\r
\r
- @retval EFI_SUCCESS SmmReadyToBootCallback runs successfully\r
+ Caution: This function may receive untrusted input.\r
+ Communicate buffer and buffer size are external input, so this function will do basic validation.\r
+\r
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
+ @param[in] RegisterContext Points to an optional handler context which was specified when the\r
+ handler was registered.\r
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-MM environment into an MM environment.\r
+ @param[in, out] CommBufferSize The size of the CommBuffer.\r
+\r
+ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers\r
+ should still be called.\r
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should\r
+ still be called.\r
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still\r
+ be called.\r
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-SmmReportFpdtRecordData (\r
- IN CONST EFI_GUID *Protocol,\r
- IN VOID *Interface,\r
- IN EFI_HANDLE Handle\r
+FpdtSmiHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *RegisterContext,\r
+ IN OUT VOID *CommBuffer,\r
+ IN OUT UINTN *CommBufferSize\r
)\r
{\r
- UINT64 SmmBPDTddr;\r
-\r
- if (!mFpdtDataIsReported && mSmmBootPerformanceTable != NULL) {\r
- SmmBPDTddr = (UINT64)(UINTN)mSmmBootPerformanceTable;\r
- REPORT_STATUS_CODE_EX (\r
- EFI_PROGRESS_CODE,\r
- EFI_SOFTWARE_SMM_DRIVER,\r
- 0,\r
- NULL,\r
- &gEdkiiFpdtExtendedFirmwarePerformanceGuid,\r
- &SmmBPDTddr,\r
- sizeof (UINT64)\r
+ EFI_STATUS Status;\r
+ SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;\r
+ UINTN BootRecordOffset;\r
+ UINTN BootRecordSize;\r
+ VOID *BootRecordData;\r
+ UINTN TempCommBufferSize;\r
+ UINT8 *BootRecordBuffer;\r
+\r
+ //\r
+ // If input is invalid, stop processing this SMI\r
+ //\r
+ if (CommBuffer == NULL || CommBufferSize == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ TempCommBufferSize = *CommBufferSize;\r
+\r
+ if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+ DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM communication data buffer in MMRAM or overflow!\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)CommBuffer;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ switch (SmmCommData->Function) {\r
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :\r
+ if (mSmmBootPerformanceTable != NULL) {\r
+ mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);\r
+ }\r
+ SmmCommData->BootRecordSize = mBootRecordSize;\r
+ break;\r
+\r
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET :\r
+ BootRecordOffset = SmmCommData->BootRecordOffset;\r
+ BootRecordData = SmmCommData->BootRecordData;\r
+ BootRecordSize = SmmCommData->BootRecordSize;\r
+ if (BootRecordData == NULL || BootRecordOffset >= mBootRecordSize) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Sanity check\r
+ //\r
+ if (BootRecordSize > mBootRecordSize - BootRecordOffset) {\r
+ BootRecordSize = mBootRecordSize - BootRecordOffset;\r
+ }\r
+ SmmCommData->BootRecordSize = BootRecordSize;\r
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {\r
+ DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM Data buffer in MMRAM or overflow!\n"));\r
+ Status = EFI_ACCESS_DENIED;\r
+ break;\r
+ }\r
+ BootRecordBuffer = ((UINT8 *) (mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);\r
+ CopyMem (\r
+ (UINT8*)BootRecordData,\r
+ BootRecordBuffer + BootRecordOffset,\r
+ BootRecordSize\r
);\r
- //\r
- // Set FPDT report state to TRUE.\r
- //\r
- mFpdtDataIsReported = TRUE;\r
+ mFpdtDataIsReported = TRUE;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_UNSUPPORTED;\r
}\r
+\r
+ SmmCommData->ReturnStatus = Status;\r
+\r
return EFI_SUCCESS;\r
}\r
\r
)\r
{\r
EFI_HANDLE Handle;\r
+ EFI_HANDLE SmiHandle;\r
EFI_STATUS Status;\r
- VOID *SmmReadyToBootRegistration;\r
PERFORMANCE_PROPERTY *PerformanceProperty;\r
\r
//\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = gSmst->SmmRegisterProtocolNotify (\r
- &gEdkiiSmmReadyToBootProtocolGuid,\r
- SmmReportFpdtRecordData,\r
- &SmmReadyToBootRegistration\r
- );\r
+ //\r
+ // Register SMI handler.\r
+ //\r
+ SmiHandle = NULL;\r
+ Status = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &SmiHandle);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **) &PerformanceProperty);\r
if (EFI_ERROR (Status)) {\r
//\r