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
)
{
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.

View File

@ -19,11 +19,9 @@
// 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);
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;
Record = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD));
CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
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;
}
Record->Signature = DATAHUB_STATUS_CODE_SIGNATURE;
EfiAcquireLock (&mFifoLock);
CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
for (Index = 1; Index < 16; Index++) {
InsertTailList (&mRecordsBuffer, &Record[Index].Node);
}
}
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);
}

View File

@ -90,11 +90,20 @@ SerialStatusCodeReportWorker (
UINTN CharCount;
VA_LIST Marker;
EFI_DEBUG_INFO *DebugInfo;
EFI_TPL CurrentTpl;
if (FeaturePcdGet (PcdStatusCodeUseEfiSerial) && EfiAtRuntime ()) {
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';