From bce0328431f6c26e9de591be50beeab9be802f63 Mon Sep 17 00:00:00 2001 From: Ray Ni Date: Fri, 2 Apr 2021 00:32:44 +0800 Subject: UefiCpuPkg/MpInitLib: Consume MicrocodeLib to remove duplicated code Signed-off-by: Ray Ni Reviewed-by: Eric Dong Acked-by: Laszlo Ersek Cc: Rahul Kumar --- UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 1 + UefiCpuPkg/Library/MpInitLib/Microcode.c | 484 +++++--------------------- UefiCpuPkg/Library/MpInitLib/MpLib.h | 1 + UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 1 + 4 files changed, 96 insertions(+), 391 deletions(-) (limited to 'UefiCpuPkg') diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf index 860a9750e2..d34419c2a5 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -52,6 +52,7 @@ SynchronizationLib PcdLib VmgExitLib + MicrocodeLib [Protocols] gEfiTimerArchProtocolGuid ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/Microcode.c b/UefiCpuPkg/Library/MpInitLib/Microcode.c index 297c2abcd1..105a9f84bf 100644 --- a/UefiCpuPkg/Library/MpInitLib/Microcode.c +++ b/UefiCpuPkg/Library/MpInitLib/Microcode.c @@ -1,70 +1,16 @@ /** @file Implementation of loading microcode on processors. - Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "MpLib.h" -/** - Get microcode update signature of currently loaded microcode update. - - @return Microcode signature. -**/ -UINT32 -GetCurrentMicrocodeSignature ( - VOID - ) -{ - MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr; - - AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); - AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); - BiosSignIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); - return BiosSignIdMsr.Bits.MicrocodeUpdateSignature; -} - /** Detect whether specified processor can find matching microcode patch and load it. - Microcode Payload as the following format: - +----------------------------------------+------------------+ - | CPU_MICROCODE_HEADER | | - +----------------------------------------+ CheckSum Part1 | - | Microcode Binary | | - +----------------------------------------+------------------+ - | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | - +----------------------------------------+ CheckSum Part2 | - | CPU_MICROCODE_EXTENDED_TABLE | | - | ... | | - +----------------------------------------+------------------+ - - There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. - The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignatureCount - of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. - - When we are trying to verify the CheckSum32 with extended table. - We should use the fields of exnteded table to replace the corresponding - fields in CPU_MICROCODE_HEADER structure, and recalculate the - CheckSum32 with CPU_MICROCODE_HEADER + Microcode Binary. We named - it as CheckSum Part3. - - The CheckSum Part2 is used to verify the CPU_MICROCODE_EXTENDED_TABLE_HEADER - and CPU_MICROCODE_EXTENDED_TABLE parts. We should make sure CheckSum Part2 - is correct before we are going to verify each CPU_MICROCODE_EXTENDED_TABLE. - - Only ProcessorSignature, ProcessorFlag and CheckSum are different between - CheckSum Part1 and CheckSum Part3. To avoid multiple computing CheckSum Part3. - Save an in-complete CheckSum32 from CheckSum Part1 for common parts. - When we are going to calculate CheckSum32, just should use the corresponding part - of the ProcessorSignature, ProcessorFlag and CheckSum with in-complete CheckSum32. - - Notes: CheckSum32 is not a strong verification. - It does not guarantee that the data has not been modified. - CPU has its own mechanism to verify Microcode Binary part. - @param[in] CpuMpData The pointer to CPU MP Data structure. @param[in] ProcessorNumber The handle number of the processor. The range is from 0 to the total number of logical processors @@ -76,26 +22,13 @@ MicrocodeDetect ( IN UINTN ProcessorNumber ) { - UINT32 ExtendedTableLength; - UINT32 ExtendedTableCount; - CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; - CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; - CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + CPU_MICROCODE_HEADER *Microcode; UINTN MicrocodeEnd; - UINTN Index; - UINT8 PlatformId; - CPUID_VERSION_INFO_EAX Eax; - CPU_AP_DATA *CpuData; - UINT32 CurrentRevision; + CPU_AP_DATA *BspData; UINT32 LatestRevision; - UINTN TotalSize; - UINT32 CheckSum32; - UINT32 InCompleteCheckSum32; - BOOLEAN CorrectMicrocode; - VOID *MicrocodeData; - MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr; + CPU_MICROCODE_HEADER *LatestMicrocode; UINT32 ThreadId; - BOOLEAN IsBspCallIn; + EDKII_PEI_MICROCODE_CPU_ID MicrocodeCpuId; if (CpuMpData->MicrocodePatchRegionSize == 0) { // @@ -104,9 +37,6 @@ MicrocodeDetect ( return; } - CurrentRevision = GetCurrentMicrocodeSignature (); - IsBspCallIn = (ProcessorNumber == (UINTN)CpuMpData->BspNumber) ? TRUE : FALSE; - GetProcessorLocationByApicId (GetInitialApicId (), NULL, NULL, &ThreadId); if (ThreadId != 0) { // @@ -115,156 +45,35 @@ MicrocodeDetect ( return; } - ExtendedTableLength = 0; - // - // Here data of CPUID leafs have not been collected into context buffer, so - // GetProcessorCpuid() cannot be used here to retrieve CPUID data. - // - AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL); + GetProcessorMicrocodeCpuId (&MicrocodeCpuId); - // - // The index of platform information resides in bits 50:52 of MSR IA32_PLATFORM_ID - // - PlatformIdMsr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID); - PlatformId = (UINT8) PlatformIdMsr.Bits.PlatformId; - - - // - // Check whether AP has same processor with BSP. - // If yes, direct use microcode info saved by BSP. - // - if (!IsBspCallIn) { + if (ProcessorNumber != (UINTN) CpuMpData->BspNumber) { // - // Get the CPU data for BSP + // Direct use microcode of BSP if AP is the same as BSP. + // Assume BSP calls this routine() before AP. // - CpuData = &(CpuMpData->CpuData[CpuMpData->BspNumber]); - if ((CpuData->ProcessorSignature == Eax.Uint32) && - (CpuData->PlatformId == PlatformId) && - (CpuData->MicrocodeEntryAddr != 0)) { - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(UINTN) CpuData->MicrocodeEntryAddr; - MicrocodeData = (VOID *) (MicrocodeEntryPoint + 1); - LatestRevision = MicrocodeEntryPoint->UpdateRevision; - goto Done; + BspData = &(CpuMpData->CpuData[CpuMpData->BspNumber]); + if ((BspData->ProcessorSignature == MicrocodeCpuId.ProcessorSignature) && + (BspData->PlatformId == MicrocodeCpuId.PlatformId) && + (BspData->MicrocodeEntryAddr != 0)) { + LatestMicrocode = (CPU_MICROCODE_HEADER *)(UINTN) BspData->MicrocodeEntryAddr; + LatestRevision = LatestMicrocode->UpdateRevision; + goto LoadMicrocode; } } - LatestRevision = 0; - MicrocodeData = NULL; - MicrocodeEnd = (UINTN) (CpuMpData->MicrocodePatchAddress + CpuMpData->MicrocodePatchRegionSize); - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->MicrocodePatchAddress; + // + // BSP or AP which is different from BSP runs here + // Use 0 as the starting revision to search for microcode because MicrocodePatchInfo HOB needs + // the latest microcode location even it's loaded to the processor. + // + LatestRevision = 0; + LatestMicrocode = NULL; + Microcode = (CPU_MICROCODE_HEADER *) (UINTN) CpuMpData->MicrocodePatchAddress; + MicrocodeEnd = (UINTN) Microcode + (UINTN) CpuMpData->MicrocodePatchRegionSize; do { - // - // Check if the microcode is for the Cpu and the version is newer - // and the update can be processed on the platform - // - CorrectMicrocode = FALSE; - - if (MicrocodeEntryPoint->DataSize == 0) { - TotalSize = sizeof (CPU_MICROCODE_HEADER) + 2000; - } else { - TotalSize = sizeof (CPU_MICROCODE_HEADER) + MicrocodeEntryPoint->DataSize; - } - - /// - /// 0x0 MicrocodeBegin MicrocodeEntry MicrocodeEnd 0xffffffff - /// |--------------|---------------|---------------|---------------| - /// valid TotalSize - /// TotalSize is only valid between 0 and (MicrocodeEnd - MicrocodeEntry). - /// And it should be aligned with 4 bytes. - /// If the TotalSize is invalid, skip 1KB to check next entry. - /// - if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || - ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || - (TotalSize & 0x3) != 0 - ) { - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); - continue; - } - - // - // Save an in-complete CheckSum32 from CheckSum Part1 for common parts. - // - InCompleteCheckSum32 = CalculateSum32 ( - (UINT32 *) MicrocodeEntryPoint, - TotalSize - ); - InCompleteCheckSum32 -= MicrocodeEntryPoint->ProcessorSignature.Uint32; - InCompleteCheckSum32 -= MicrocodeEntryPoint->ProcessorFlags; - InCompleteCheckSum32 -= MicrocodeEntryPoint->Checksum; - - if (MicrocodeEntryPoint->HeaderVersion == 0x1) { - // - // It is the microcode header. It is not the padding data between microcode patches - // because the padding data should not include 0x00000001 and it should be the repeated - // byte format (like 0xXYXYXYXY....). - // - if (MicrocodeEntryPoint->ProcessorSignature.Uint32 == Eax.Uint32 && - MicrocodeEntryPoint->UpdateRevision > LatestRevision && - (MicrocodeEntryPoint->ProcessorFlags & (1 << PlatformId)) - ) { - // - // Calculate CheckSum Part1. - // - CheckSum32 = InCompleteCheckSum32; - CheckSum32 += MicrocodeEntryPoint->ProcessorSignature.Uint32; - CheckSum32 += MicrocodeEntryPoint->ProcessorFlags; - CheckSum32 += MicrocodeEntryPoint->Checksum; - if (CheckSum32 == 0) { - CorrectMicrocode = TRUE; - } - } else if ((MicrocodeEntryPoint->DataSize != 0) && - (MicrocodeEntryPoint->UpdateRevision > LatestRevision)) { - ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + - sizeof (CPU_MICROCODE_HEADER)); - if (ExtendedTableLength != 0) { - // - // Extended Table exist, check if the CPU in support list - // - ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) - + MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)); - // - // Calculate Extended Checksum - // - if ((ExtendedTableLength % 4) == 0) { - // - // Calculate CheckSum Part2. - // - CheckSum32 = CalculateSum32 ((UINT32 *) ExtendedTableHeader, ExtendedTableLength); - if (CheckSum32 == 0) { - // - // Checksum correct - // - ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; - ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1); - for (Index = 0; Index < ExtendedTableCount; Index ++) { - // - // Calculate CheckSum Part3. - // - CheckSum32 = InCompleteCheckSum32; - CheckSum32 += ExtendedTable->ProcessorSignature.Uint32; - CheckSum32 += ExtendedTable->ProcessorFlag; - CheckSum32 += ExtendedTable->Checksum; - if (CheckSum32 == 0) { - // - // Verify Header - // - if ((ExtendedTable->ProcessorSignature.Uint32 == Eax.Uint32) && - (ExtendedTable->ProcessorFlag & (1 << PlatformId)) ) { - // - // Find one - // - CorrectMicrocode = TRUE; - break; - } - } - ExtendedTable ++; - } - } - } - } - } - } else { + if (!IsValidMicrocode (Microcode, MicrocodeEnd - (UINTN) Microcode, LatestRevision, &MicrocodeCpuId, 1, TRUE)) { // // It is the padding data between the microcode patches for microcode patches alignment. // Because the microcode patch is the multiple of 1-KByte, the padding data should not @@ -272,156 +81,40 @@ MicrocodeDetect ( // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to // find the next possible microcode patch header. // - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + Microcode = (CPU_MICROCODE_HEADER *) ((UINTN) Microcode + SIZE_1KB); continue; } - // - // Get the next patch. - // - if (MicrocodeEntryPoint->DataSize == 0) { - TotalSize = 2048; - } else { - TotalSize = MicrocodeEntryPoint->TotalSize; - } + LatestMicrocode = Microcode; + LatestRevision = LatestMicrocode->UpdateRevision; - if (CorrectMicrocode) { - LatestRevision = MicrocodeEntryPoint->UpdateRevision; - MicrocodeData = (VOID *) ((UINTN) MicrocodeEntryPoint + sizeof (CPU_MICROCODE_HEADER)); - } - - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); - } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + Microcode = (CPU_MICROCODE_HEADER *) (((UINTN) Microcode) + GetMicrocodeLength (Microcode)); + } while ((UINTN) Microcode < MicrocodeEnd); -Done: +LoadMicrocode: if (LatestRevision != 0) { // - // Save the detected microcode patch entry address (including the - // microcode patch header) for each processor. + // Save the detected microcode patch entry address (including the microcode + // patch header) for each processor even it's the same as the loaded one. // It will be used when building the microcode patch cache HOB. // - CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr = - (UINTN) MicrocodeData - sizeof (CPU_MICROCODE_HEADER); + CpuMpData->CpuData[ProcessorNumber].MicrocodeEntryAddr = (UINTN) LatestMicrocode; } - if (LatestRevision > CurrentRevision) { + if (LatestRevision > GetProcessorMicrocodeSignature ()) { // // BIOS only authenticate updates that contain a numerically larger revision // than the currently loaded revision, where Current Signature < New Update // Revision. A processor with no loaded update is considered to have a // revision equal to zero. // - ASSERT (MicrocodeData != NULL); - AsmWriteMsr64 ( - MSR_IA32_BIOS_UPDT_TRIG, - (UINT64) (UINTN) MicrocodeData - ); - } - CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision = GetCurrentMicrocodeSignature (); -} - -/** - Determine if a microcode patch matchs the specific processor signature and flag. - - @param[in] CpuMpData The pointer to CPU MP Data structure. - @param[in] ProcessorSignature The processor signature field value - supported by a microcode patch. - @param[in] ProcessorFlags The prcessor flags field value supported by - a microcode patch. - - @retval TRUE The specified microcode patch will be loaded. - @retval FALSE The specified microcode patch will not be loaded. -**/ -BOOLEAN -IsProcessorMatchedMicrocodePatch ( - IN CPU_MP_DATA *CpuMpData, - IN UINT32 ProcessorSignature, - IN UINT32 ProcessorFlags - ) -{ - UINTN Index; - CPU_AP_DATA *CpuData; - - for (Index = 0; Index < CpuMpData->CpuCount; Index++) { - CpuData = &CpuMpData->CpuData[Index]; - if ((ProcessorSignature == CpuData->ProcessorSignature) && - (ProcessorFlags & (1 << CpuData->PlatformId)) != 0) { - return TRUE; - } + LoadMicrocode (LatestMicrocode); } - - return FALSE; -} - -/** - Check the 'ProcessorSignature' and 'ProcessorFlags' of the microcode - patch header with the CPUID and PlatformID of the processors within - system to decide if it will be copied into memory. - - @param[in] CpuMpData The pointer to CPU MP Data structure. - @param[in] MicrocodeEntryPoint The pointer to the microcode patch header. - - @retval TRUE The specified microcode patch need to be loaded. - @retval FALSE The specified microcode patch dosen't need to be loaded. -**/ -BOOLEAN -IsMicrocodePatchNeedLoad ( - IN CPU_MP_DATA *CpuMpData, - CPU_MICROCODE_HEADER *MicrocodeEntryPoint - ) -{ - BOOLEAN NeedLoad; - UINTN DataSize; - UINTN TotalSize; - CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; - UINT32 ExtendedTableCount; - CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; - UINTN Index; - // - // Check the 'ProcessorSignature' and 'ProcessorFlags' in microcode patch header. + // It's possible that the microcode fails to load. Just capture the CPU microcode revision after loading. // - NeedLoad = IsProcessorMatchedMicrocodePatch ( - CpuMpData, - MicrocodeEntryPoint->ProcessorSignature.Uint32, - MicrocodeEntryPoint->ProcessorFlags - ); - - // - // If the Extended Signature Table exists, check if the processor is in the - // support list - // - DataSize = MicrocodeEntryPoint->DataSize; - TotalSize = (DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize; - if ((!NeedLoad) && (DataSize != 0) && - (TotalSize - DataSize > sizeof (CPU_MICROCODE_HEADER) + - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER))) { - ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) - + DataSize + sizeof (CPU_MICROCODE_HEADER)); - ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; - ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1); - - for (Index = 0; Index < ExtendedTableCount; Index ++) { - // - // Check the 'ProcessorSignature' and 'ProcessorFlag' of the Extended - // Signature Table entry with the CPUID and PlatformID of the processors - // within system to decide if it will be copied into memory - // - NeedLoad = IsProcessorMatchedMicrocodePatch ( - CpuMpData, - ExtendedTable->ProcessorSignature.Uint32, - ExtendedTable->ProcessorFlag - ); - if (NeedLoad) { - break; - } - ExtendedTable ++; - } - } - - return NeedLoad; + CpuMpData->CpuData[ProcessorNumber].MicrocodeRevision = GetProcessorMicrocodeSignature (); } - /** Actual worker function that shadows the required microcode patches into memory. @@ -491,14 +184,16 @@ ShadowMicrocodePatchByPcd ( IN OUT CPU_MP_DATA *CpuMpData ) { + UINTN Index; CPU_MICROCODE_HEADER *MicrocodeEntryPoint; UINTN MicrocodeEnd; - UINTN DataSize; UINTN TotalSize; MICROCODE_PATCH_INFO *PatchInfoBuffer; UINTN MaxPatchNumber; UINTN PatchCount; UINTN TotalLoadSize; + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds; + BOOLEAN Valid; // // Initialize the microcode patch related fields in CpuMpData as the values @@ -526,12 +221,34 @@ ShadowMicrocodePatchByPcd ( return; } + MicrocodeCpuIds = AllocatePages ( + EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID)) + ); + if (MicrocodeCpuIds == NULL) { + FreePool (PatchInfoBuffer); + return; + } + + for (Index = 0; Index < CpuMpData->CpuCount; Index++) { + MicrocodeCpuIds[Index].PlatformId = CpuMpData->CpuData[Index].PlatformId; + MicrocodeCpuIds[Index].ProcessorSignature = CpuMpData->CpuData[Index].ProcessorSignature; + } + // // Process the header of each microcode patch within the region. // The purpose is to decide which microcode patch(es) will be loaded into memory. + // Microcode checksum is not verified because it's slow when performing on flash. // do { - if (MicrocodeEntryPoint->HeaderVersion != 0x1) { + Valid = IsValidMicrocode ( + MicrocodeEntryPoint, + MicrocodeEnd - (UINTN) MicrocodeEntryPoint, + 0, + MicrocodeCpuIds, + CpuMpData->CpuCount, + FALSE + ); + if (!Valid) { // // Padding data between the microcode patches, skip 1KB to check next entry. // @@ -539,59 +256,44 @@ ShadowMicrocodePatchByPcd ( continue; } - DataSize = MicrocodeEntryPoint->DataSize; - TotalSize = (DataSize == 0) ? 2048 : MicrocodeEntryPoint->TotalSize; - if ( (UINTN)MicrocodeEntryPoint > (MAX_ADDRESS - TotalSize) || - ((UINTN)MicrocodeEntryPoint + TotalSize) > MicrocodeEnd || - (DataSize & 0x3) != 0 || - (TotalSize & (SIZE_1KB - 1)) != 0 || - TotalSize < DataSize - ) { + PatchCount++; + if (PatchCount > MaxPatchNumber) { // - // Not a valid microcode header, skip 1KB to check next entry. + // Current 'PatchInfoBuffer' cannot hold the information, double the size + // and allocate a new buffer. // - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); - continue; - } - - if (IsMicrocodePatchNeedLoad (CpuMpData, MicrocodeEntryPoint)) { - PatchCount++; - if (PatchCount > MaxPatchNumber) { + if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) { // - // Current 'PatchInfoBuffer' cannot hold the information, double the size - // and allocate a new buffer. + // Overflow check for MaxPatchNumber // - if (MaxPatchNumber > MAX_UINTN / 2 / sizeof (MICROCODE_PATCH_INFO)) { - // - // Overflow check for MaxPatchNumber - // - goto OnExit; - } - - PatchInfoBuffer = ReallocatePool ( - MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), - 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), - PatchInfoBuffer - ); - if (PatchInfoBuffer == NULL) { - goto OnExit; - } - MaxPatchNumber = MaxPatchNumber * 2; + goto OnExit; } - // - // Store the information of this microcode patch - // - PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint; - PatchInfoBuffer[PatchCount - 1].Size = TotalSize; - TotalLoadSize += TotalSize; + PatchInfoBuffer = ReallocatePool ( + MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + 2 * MaxPatchNumber * sizeof (MICROCODE_PATCH_INFO), + PatchInfoBuffer + ); + if (PatchInfoBuffer == NULL) { + goto OnExit; + } + MaxPatchNumber = MaxPatchNumber * 2; } + TotalSize = GetMicrocodeLength (MicrocodeEntryPoint); + + // + // Store the information of this microcode patch + // + PatchInfoBuffer[PatchCount - 1].Address = (UINTN) MicrocodeEntryPoint; + PatchInfoBuffer[PatchCount - 1].Size = TotalSize; + TotalLoadSize += TotalSize; + // // Process the next microcode patch // - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); - } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) ((UINTN) MicrocodeEntryPoint + TotalSize); + } while ((UINTN) MicrocodeEntryPoint < MicrocodeEnd); if (PatchCount != 0) { DEBUG (( @@ -607,7 +309,7 @@ OnExit: if (PatchInfoBuffer != NULL) { FreePool (PatchInfoBuffer); } - return; + FreePages (MicrocodeCpuIds, EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * sizeof (EDKII_PEI_MICROCODE_CPU_ID))); } /** diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index 66f9eb2304..e88a5355c9 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index 49b0ffe8be..36fcb96b58 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -51,6 +51,7 @@ PeiServicesLib PcdLib VmgExitLib + MicrocodeLib [Pcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES -- cgit v1.2.3