From 35d4cd92bd21a3538f6c300723b715b1df6911bb Mon Sep 17 00:00:00 2001 From: yshang1 Date: Fri, 12 Jan 2007 02:41:42 +0000 Subject: [PATCH] Fix EDKT497. In the patch: 1) Check TPL<=TPL_CALLBACK prior to invoking SerialIO protocol. 2) Check TPL <= TPL_NOTIFY prior to allocate memory in datahub status code driver. 3) Add lock to prevent the critical data. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2225 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Dxe/Common/DxeStatusCodeCommon.c | 3 + .../StatusCode/Dxe/DataHubStatusCodeWorker.c | 64 ++++++++++++++----- .../StatusCode/Dxe/SerialStatusCodeWorker.c | 13 +++- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c b/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c index 43fe3fdfda..1ac1c74a5e 100644 --- a/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c +++ b/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c @@ -148,6 +148,9 @@ ReportDispatcher ( IN EFI_STATUS_CODE_DATA *Data OPTIONAL ) { + volatile int tt = 1; + while (tt) { + } // // Use atom operation to avoid the reentant of report. // If current status is not zero, then the function is reentrancy. diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c b/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c index c5da3220ce..28714365a6 100644 --- a/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c +++ b/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c @@ -18,12 +18,10 @@ // // Initialize FIFO to cache records. // -STATIC -EFI_LOCK mFifoLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL); STATIC -LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo); +LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo); STATIC -UINTN mNumberOfRecords = 0; +LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer); STATIC EFI_EVENT mLogDataHubEvent; // @@ -34,7 +32,9 @@ EFI_DATA_HUB_PROTOCOL *mDataHubProtocol; /** - Return buffer of length DATAHUB_STATUSCODE_RECORD + Return one DATAHUB_STATUSCODE_RECORD space. + The size of free record pool would be extend, if the pool is empty. + @retval NULL Can not allocate free memeory for record. @retval !NULL Point to buffer of record. @@ -46,17 +46,39 @@ AcquireRecordBuffer ( ) { DATAHUB_STATUSCODE_RECORD *Record; + EFI_TPL CurrentTpl; + LIST_ENTRY *Node; + UINT32 Index; + + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + + if (!IsListEmpty (&mRecordsBuffer)) { + Node = GetFirstNode (&mRecordsBuffer); + RemoveEntryList (Node); - Record = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD)); - if (NULL == Record) { - return NULL; + Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE); + } else { + if (CurrentTpl > EFI_TPL_NOTIFY) { + gBS->RestoreTPL (CurrentTpl); + return NULL; + } + + gBS->RestoreTPL (CurrentTpl); + Record = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD) * 16); + if (NULL == Record) { + return NULL; + } + + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + for (Index = 1; Index < 16; Index++) { + InsertTailList (&mRecordsBuffer, &Record[Index].Node); + } } - Record->Signature = DATAHUB_STATUS_CODE_SIGNATURE; - EfiAcquireLock (&mFifoLock); + Record->Signature = DATAHUB_STATUS_CODE_SIGNATURE; InsertTailList (&mRecordsFifo, &Record->Node); - mNumberOfRecords++; - EfiReleaseLock (&mFifoLock); + + gBS->RestoreTPL (CurrentTpl); return Record; } @@ -73,15 +95,16 @@ FreeRecordBuffer ( IN DATAHUB_STATUSCODE_RECORD *Record ) { + EFI_TPL CurrentTpl; + ASSERT (Record != NULL); - ASSERT (mNumberOfRecords != 0); - EfiAcquireLock (&mFifoLock); + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + RemoveEntryList (&Record->Node); - mNumberOfRecords--; - EfiReleaseLock (&mFifoLock); + InsertTailList (&mRecordsBuffer, &Record->Node); - FreePool (Record); + gBS->RestoreTPL (CurrentTpl); } @@ -207,12 +230,15 @@ LogDataHubEventCallBack ( UINT32 Size; UINT64 DataRecordClass; LIST_ENTRY *Node; + EFI_TPL CurrentTpl; // // Log DataRecord in Data Hub. // Journal records fifo to find all record entry. // // + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + for (Node = mRecordsFifo.ForwardLink; Node != &mRecordsFifo;) { Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE); Node = Node->ForwardLink; @@ -251,8 +277,12 @@ LogDataHubEventCallBack ( Size ); + + FreeRecordBuffer (Record); } + + gBS->RestoreTPL (CurrentTpl); } diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c b/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c index d4912836bc..0b16dfeadb 100644 --- a/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c +++ b/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c @@ -90,10 +90,19 @@ SerialStatusCodeReportWorker ( UINTN CharCount; VA_LIST Marker; EFI_DEBUG_INFO *DebugInfo; + EFI_TPL CurrentTpl; - if (FeaturePcdGet (PcdStatusCodeUseEfiSerial) && EfiAtRuntime ()) { - return EFI_DEVICE_ERROR; + if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) { + if (EfiAtRuntime ()) { + return EFI_DEVICE_ERROR; + } + CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); + gBS->RestoreTPL (CurrentTpl); + + if (CurrentTpl > EFI_TPL_CALLBACK ) { + return EFI_DEVICE_ERROR; + } } Buffer[0] = '\0'; -- 2.39.2