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
This commit is contained in:
yshang1 2007-01-12 02:41:42 +00:00
parent affa5a128c
commit 35d4cd92bd
3 changed files with 61 additions and 19 deletions

View File

@ -148,6 +148,9 @@ ReportDispatcher (
IN EFI_STATUS_CODE_DATA *Data OPTIONAL IN EFI_STATUS_CODE_DATA *Data OPTIONAL
) )
{ {
volatile int tt = 1;
while (tt) {
}
// //
// Use atom operation to avoid the reentant of report. // Use atom operation to avoid the reentant of report.
// If current status is not zero, then the function is reentrancy. // If current status is not zero, then the function is reentrancy.

View File

@ -19,11 +19,9 @@
// Initialize FIFO to cache records. // Initialize FIFO to cache records.
// //
STATIC STATIC
EFI_LOCK mFifoLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL); LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo);
STATIC STATIC
LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo); LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);
STATIC
UINTN mNumberOfRecords = 0;
STATIC STATIC
EFI_EVENT mLogDataHubEvent; 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 Can not allocate free memeory for record.
@retval !NULL Point to buffer of record. @retval !NULL Point to buffer of record.
@ -46,17 +46,39 @@ AcquireRecordBuffer (
) )
{ {
DATAHUB_STATUSCODE_RECORD *Record; DATAHUB_STATUSCODE_RECORD *Record;
EFI_TPL CurrentTpl;
LIST_ENTRY *Node;
UINT32 Index;
Record = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD)); CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
if (NULL == Record) {
return NULL; if (!IsListEmpty (&mRecordsBuffer)) {
Node = GetFirstNode (&mRecordsBuffer);
RemoveEntryList (Node);
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); InsertTailList (&mRecordsFifo, &Record->Node);
mNumberOfRecords++;
EfiReleaseLock (&mFifoLock); gBS->RestoreTPL (CurrentTpl);
return Record; return Record;
} }
@ -73,15 +95,16 @@ FreeRecordBuffer (
IN DATAHUB_STATUSCODE_RECORD *Record IN DATAHUB_STATUSCODE_RECORD *Record
) )
{ {
EFI_TPL CurrentTpl;
ASSERT (Record != NULL); ASSERT (Record != NULL);
ASSERT (mNumberOfRecords != 0);
EfiAcquireLock (&mFifoLock); CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
RemoveEntryList (&Record->Node); RemoveEntryList (&Record->Node);
mNumberOfRecords--; InsertTailList (&mRecordsBuffer, &Record->Node);
EfiReleaseLock (&mFifoLock);
FreePool (Record); gBS->RestoreTPL (CurrentTpl);
} }
@ -207,12 +230,15 @@ LogDataHubEventCallBack (
UINT32 Size; UINT32 Size;
UINT64 DataRecordClass; UINT64 DataRecordClass;
LIST_ENTRY *Node; LIST_ENTRY *Node;
EFI_TPL CurrentTpl;
// //
// Log DataRecord in Data Hub. // Log DataRecord in Data Hub.
// Journal records fifo to find all record entry. // Journal records fifo to find all record entry.
// //
// //
CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
for (Node = mRecordsFifo.ForwardLink; Node != &mRecordsFifo;) { for (Node = mRecordsFifo.ForwardLink; Node != &mRecordsFifo;) {
Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE); Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);
Node = Node->ForwardLink; Node = Node->ForwardLink;
@ -251,8 +277,12 @@ LogDataHubEventCallBack (
Size Size
); );
FreeRecordBuffer (Record); FreeRecordBuffer (Record);
} }
gBS->RestoreTPL (CurrentTpl);
} }

View File

@ -90,10 +90,19 @@ SerialStatusCodeReportWorker (
UINTN CharCount; UINTN CharCount;
VA_LIST Marker; VA_LIST Marker;
EFI_DEBUG_INFO *DebugInfo; EFI_DEBUG_INFO *DebugInfo;
EFI_TPL CurrentTpl;
if (FeaturePcdGet (PcdStatusCodeUseEfiSerial) && EfiAtRuntime ()) { if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) {
return EFI_DEVICE_ERROR; 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'; Buffer[0] = '\0';