mirror of https://github.com/acidanthera/audk.git
IntelFrameworkModulePkg GenericBdsLib: Do not assume perf entry count has no change
Current implementation assumes the performance entry count has no change from multiple GetPerformanceMeasurement() while loops, it may cause the allocated buffer for PerfEntriesAsDxeHandle at the first loop to be overflowed if the following loop has the count changed. This patch is also to sync the change at commit R18417 "MdeModulePkg: Fix a performance data buffer overrun issue". Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18562 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2f931dda52
commit
201d2d21bd
|
@ -168,13 +168,8 @@ WriteBootToOsPerformanceData (
|
||||||
UINT64 StartValue;
|
UINT64 StartValue;
|
||||||
UINT64 EndValue;
|
UINT64 EndValue;
|
||||||
BOOLEAN CountUp;
|
BOOLEAN CountUp;
|
||||||
UINTN EntryIndex;
|
|
||||||
UINTN NumPerfEntries;
|
|
||||||
//
|
|
||||||
// List of flags indicating PerfEntry contains DXE handle
|
|
||||||
//
|
|
||||||
BOOLEAN *PerfEntriesAsDxeHandle;
|
|
||||||
UINTN VarSize;
|
UINTN VarSize;
|
||||||
|
BOOLEAN Found;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Record the performance data for End of BDS
|
// Record the performance data for End of BDS
|
||||||
|
@ -203,6 +198,11 @@ WriteBootToOsPerformanceData (
|
||||||
CountUp = FALSE;
|
CountUp = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reset the entry count
|
||||||
|
//
|
||||||
|
mPerfHeader.Count = 0;
|
||||||
|
|
||||||
if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
|
if (mAcpiLowMemoryBase == 0x0FFFFFFFF) {
|
||||||
VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
|
VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
|
||||||
Status = gRT->GetVariable (
|
Status = gRT->GetVariable (
|
||||||
|
@ -238,7 +238,9 @@ WriteBootToOsPerformanceData (
|
||||||
Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
|
Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));
|
||||||
LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
|
LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
|
||||||
|
|
||||||
NumPerfEntries = 0;
|
//
|
||||||
|
// Get performance data
|
||||||
|
//
|
||||||
LogEntryKey = 0;
|
LogEntryKey = 0;
|
||||||
while ((LogEntryKey = GetPerformanceMeasurement (
|
while ((LogEntryKey = GetPerformanceMeasurement (
|
||||||
LogEntryKey,
|
LogEntryKey,
|
||||||
|
@ -247,76 +249,7 @@ WriteBootToOsPerformanceData (
|
||||||
&Module,
|
&Module,
|
||||||
&StartTicker,
|
&StartTicker,
|
||||||
&EndTicker)) != 0) {
|
&EndTicker)) != 0) {
|
||||||
NumPerfEntries++;
|
if (EndTicker != 0) {
|
||||||
}
|
|
||||||
PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN));
|
|
||||||
ASSERT (PerfEntriesAsDxeHandle != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get DXE drivers performance
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < NoHandles; Index++) {
|
|
||||||
Ticker = 0;
|
|
||||||
LogEntryKey = 0;
|
|
||||||
EntryIndex = 0;
|
|
||||||
while ((LogEntryKey = GetPerformanceMeasurement (
|
|
||||||
LogEntryKey,
|
|
||||||
&Handle,
|
|
||||||
&Token,
|
|
||||||
&Module,
|
|
||||||
&StartTicker,
|
|
||||||
&EndTicker)) != 0) {
|
|
||||||
if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) {
|
|
||||||
PerfEntriesAsDxeHandle[EntryIndex] = TRUE;
|
|
||||||
}
|
|
||||||
EntryIndex++;
|
|
||||||
if ((Handle == Handles[Index]) && (EndTicker != 0)) {
|
|
||||||
if (StartTicker == 1) {
|
|
||||||
StartTicker = StartValue;
|
|
||||||
}
|
|
||||||
if (EndTicker == 1) {
|
|
||||||
EndTicker = StartValue;
|
|
||||||
}
|
|
||||||
Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
|
|
||||||
|
|
||||||
if (Duration > 0) {
|
|
||||||
|
|
||||||
GetNameFromHandle (Handles[Index], GaugeString);
|
|
||||||
|
|
||||||
AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);
|
|
||||||
mPerfData.Duration = Duration;
|
|
||||||
|
|
||||||
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
|
|
||||||
Ptr += sizeof (PERF_DATA);
|
|
||||||
|
|
||||||
mPerfHeader.Count++;
|
|
||||||
if (mPerfHeader.Count == LimitCount) {
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get inserted performance data
|
|
||||||
//
|
|
||||||
LogEntryKey = 0;
|
|
||||||
EntryIndex = 0;
|
|
||||||
while ((LogEntryKey = GetPerformanceMeasurement (
|
|
||||||
LogEntryKey,
|
|
||||||
&Handle,
|
|
||||||
&Token,
|
|
||||||
&Module,
|
|
||||||
&StartTicker,
|
|
||||||
&EndTicker)) != 0) {
|
|
||||||
if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) {
|
|
||||||
|
|
||||||
ZeroMem (&mPerfData, sizeof (PERF_DATA));
|
|
||||||
|
|
||||||
AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);
|
|
||||||
if (StartTicker == 1) {
|
if (StartTicker == 1) {
|
||||||
StartTicker = StartValue;
|
StartTicker = StartValue;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +258,31 @@ WriteBootToOsPerformanceData (
|
||||||
}
|
}
|
||||||
Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
|
Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
|
||||||
|
|
||||||
mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
|
Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
|
||||||
|
if (Duration == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMem (&mPerfData, sizeof (PERF_DATA));
|
||||||
|
|
||||||
|
mPerfData.Duration = Duration;
|
||||||
|
|
||||||
|
//
|
||||||
|
// See if the Handle is in the handle buffer
|
||||||
|
//
|
||||||
|
Found = FALSE;
|
||||||
|
for (Index = 0; Index < NoHandles; Index++) {
|
||||||
|
if (Handle == Handles[Index]) {
|
||||||
|
GetNameFromHandle (Handles[Index], GaugeString);
|
||||||
|
AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString);
|
||||||
|
Found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Found) {
|
||||||
|
AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
|
CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));
|
||||||
Ptr += sizeof (PERF_DATA);
|
Ptr += sizeof (PERF_DATA);
|
||||||
|
@ -335,13 +292,11 @@ WriteBootToOsPerformanceData (
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EntryIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
|
|
||||||
FreePool (Handles);
|
FreePool (Handles);
|
||||||
FreePool (PerfEntriesAsDxeHandle);
|
|
||||||
|
|
||||||
mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
|
mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue