summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c4
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c221
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.h7
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c114
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c36
5 files changed, 150 insertions, 232 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
index c18671e95f..54c23ecf10 100644
--- a/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/LoongArch64/MpLib.c
@@ -130,8 +130,8 @@ SortApicId (
} else {
for ( ; Index2 <= ApCount; Index2++) {
if (CpuInfoInHob[Index2].ApicId == INVALID_APIC_ID) {
- CopyMem (&CpuInfoInHob[Index2], &CpuInfoInHob[Index1], sizeof (CPU_INFO_IN_HOB));
- CpuMpData->CpuData[Index2] = CpuMpData->CpuData[Index1];
+ CopyMem (CpuInfoInHob + Index2, CpuInfoInHob + Index1, sizeof (CPU_INFO_IN_HOB));
+ CopyMem (CpuMpData->CpuData + Index2, CpuMpData->CpuData + Index1, sizeof (CPU_AP_DATA));
CpuInfoInHob[Index1].ApicId = INVALID_APIC_ID;
break;
}
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 1951922912..4088e76f45 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -41,8 +41,7 @@ SaveVolatileRegisters (
**/
VOID
RestoreVolatileRegisters (
- IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
- IN BOOLEAN IsRestoreDr
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters
);
/**
@@ -118,11 +117,7 @@ FutureBSPProc (
//
SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
- RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE);
- //
- // Update VolatileRegisters saved in CpuMpData->CpuData
- //
- CopyMem (&DataInHob->CpuData[DataInHob->BspNumber].VolatileRegisters, &DataInHob->APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
+ RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
}
/**
@@ -167,16 +162,19 @@ SaveLocalApicTimerSetting (
IN CPU_MP_DATA *CpuMpData
)
{
- //
- // Record the current local APIC timer setting of BSP
- //
- GetApicTimerState (
- &CpuMpData->DivideValue,
- &CpuMpData->PeriodicMode,
- &CpuMpData->Vector
- );
- CpuMpData->CurrentTimerCount = GetApicTimerCurrentCount ();
- CpuMpData->TimerInterruptState = GetApicTimerInterruptState ();
+ CpuMpData->InitTimerCount = GetApicTimerInitCount ();
+ if (CpuMpData->InitTimerCount != 0) {
+ //
+ // Record the current local APIC timer setting of BSP
+ //
+ GetApicTimerState (
+ &CpuMpData->DivideValue,
+ &CpuMpData->PeriodicMode,
+ &CpuMpData->Vector
+ );
+
+ CpuMpData->TimerInterruptState = GetApicTimerInterruptState ();
+ }
}
/**
@@ -189,19 +187,21 @@ SyncLocalApicTimerSetting (
IN CPU_MP_DATA *CpuMpData
)
{
- //
- // Sync local APIC timer setting from BSP to AP
- //
- InitializeApicTimer (
- CpuMpData->DivideValue,
- CpuMpData->CurrentTimerCount,
- CpuMpData->PeriodicMode,
- CpuMpData->Vector
- );
- //
- // Disable AP's local APIC timer interrupt
- //
- DisableApicTimerInterrupt ();
+ if (CpuMpData->InitTimerCount != 0) {
+ //
+ // Sync local APIC timer setting from BSP to AP
+ //
+ InitializeApicTimer (
+ CpuMpData->DivideValue,
+ CpuMpData->InitTimerCount,
+ CpuMpData->PeriodicMode,
+ CpuMpData->Vector
+ );
+ //
+ // Disable AP's local APIC timer interrupt
+ //
+ DisableApicTimerInterrupt ();
+ }
}
/**
@@ -243,13 +243,11 @@ SaveVolatileRegisters (
Restore the volatile registers following INIT IPI.
@param[in] VolatileRegisters Pointer to volatile resisters
- @param[in] IsRestoreDr TRUE: Restore DRx if supported
- FALSE: Do not restore DRx
+
**/
VOID
RestoreVolatileRegisters (
- IN CPU_VOLATILE_REGISTERS *VolatileRegisters,
- IN BOOLEAN IsRestoreDr
+ IN CPU_VOLATILE_REGISTERS *VolatileRegisters
)
{
CPUID_VERSION_INFO_EDX VersionInfoEdx;
@@ -259,20 +257,18 @@ RestoreVolatileRegisters (
AsmWriteCr4 (VolatileRegisters->Cr4);
AsmWriteCr0 (VolatileRegisters->Cr0);
- if (IsRestoreDr) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
- if (VersionInfoEdx.Bits.DE != 0) {
- //
- // If processor supports Debugging Extensions feature
- // by CPUID.[EAX=01H]:EDX.BIT2
- //
- AsmWriteDr0 (VolatileRegisters->Dr0);
- AsmWriteDr1 (VolatileRegisters->Dr1);
- AsmWriteDr2 (VolatileRegisters->Dr2);
- AsmWriteDr3 (VolatileRegisters->Dr3);
- AsmWriteDr6 (VolatileRegisters->Dr6);
- AsmWriteDr7 (VolatileRegisters->Dr7);
- }
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
+ if (VersionInfoEdx.Bits.DE != 0) {
+ //
+ // If processor supports Debugging Extensions feature
+ // by CPUID.[EAX=01H]:EDX.BIT2
+ //
+ AsmWriteDr0 (VolatileRegisters->Dr0);
+ AsmWriteDr1 (VolatileRegisters->Dr1);
+ AsmWriteDr2 (VolatileRegisters->Dr2);
+ AsmWriteDr3 (VolatileRegisters->Dr3);
+ AsmWriteDr6 (VolatileRegisters->Dr6);
+ AsmWriteDr7 (VolatileRegisters->Dr7);
}
AsmWriteGdtr (&VolatileRegisters->Gdtr);
@@ -377,10 +373,9 @@ SortApicId (
UINTN Index3;
UINT32 ApicId;
CPU_INFO_IN_HOB CpuInfo;
+ CPU_AP_DATA CpuApData;
UINT32 ApCount;
CPU_INFO_IN_HOB *CpuInfoInHob;
- volatile UINT32 *StartupApSignal;
- VOID *SevEsSaveArea;
ApCount = CpuMpData->CpuCount - 1;
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
@@ -407,18 +402,13 @@ SortApicId (
);
CopyMem (&CpuInfoInHob[Index1], &CpuInfo, sizeof (CPU_INFO_IN_HOB));
- //
- // Also exchange the StartupApSignal and SevEsSaveArea.
- //
- StartupApSignal = CpuMpData->CpuData[Index3].StartupApSignal;
- CpuMpData->CpuData[Index3].StartupApSignal =
- CpuMpData->CpuData[Index1].StartupApSignal;
- CpuMpData->CpuData[Index1].StartupApSignal = StartupApSignal;
-
- SevEsSaveArea = CpuMpData->CpuData[Index3].SevEsSaveArea;
- CpuMpData->CpuData[Index3].SevEsSaveArea =
- CpuMpData->CpuData[Index1].SevEsSaveArea;
- CpuMpData->CpuData[Index1].SevEsSaveArea = SevEsSaveArea;
+ CopyMem (&CpuApData, &CpuMpData->CpuData[Index3], sizeof (CPU_AP_DATA));
+ CopyMem (
+ &CpuMpData->CpuData[Index3],
+ &CpuMpData->CpuData[Index1],
+ sizeof (CPU_AP_DATA)
+ );
+ CopyMem (&CpuMpData->CpuData[Index1], &CpuApData, sizeof (CPU_AP_DATA));
}
}
@@ -770,11 +760,11 @@ ApWakeupFunction (
BistData = (UINT32)ApStackData->Bist;
//
- // CpuMpData->CpuData[BspNumber].VolatileRegisters is initialized based on BSP environment,
+ // CpuMpData->CpuData[ProcessorNumber].VolatileRegisters is initialized based on BSP environment,
// to initialize AP in InitConfig path.
- // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a different IDT shared by all APs.
+ // NOTE: IDTR.BASE stored in CpuMpData->CpuData[ProcessorNumber].VolatileRegisters points to a different IDT shared by all APs.
//
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
} else {
@@ -801,31 +791,7 @@ ApWakeupFunction (
0
);
- if (CpuMpData->InitFlag == ApInitReconfig) {
- //
- // ApInitReconfig happens when:
- // 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.
- // 2. AP is initialized in DXE phase.
- // In either case, use the volatile registers value derived from BSP.
- // NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a
- // different IDT shared by all APs.
- //
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
- } else {
- if (CpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Restore AP's volatile registers saved before AP is halted
- //
- RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters, TRUE);
- } else {
- //
- // The CPU driver might not flush TLB for APs on spot after updating
- // page attributes. AP in mwait loop mode needs to take care of it when
- // woken up.
- //
- CpuFlushTlb ();
- }
- }
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
if (GetApState (&CpuMpData->CpuData[ProcessorNumber]) == CpuStateReady) {
Procedure = (EFI_AP_PROCEDURE)CpuMpData->CpuData[ProcessorNumber].ApFunction;
@@ -876,12 +842,7 @@ ApWakeupFunction (
}
}
- if (CpuMpData->ApLoopMode == ApInHltLoop) {
- //
- // Save AP volatile registers
- //
- SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
- }
+ SaveVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
//
// AP finished executing C code
@@ -936,7 +897,7 @@ DxeApEntryPoint (
AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64);
}
- RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
+ RestoreVolatileRegisters (&CpuMpData->CpuData[ProcessorNumber].VolatileRegisters);
InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount);
PlaceAPInMwaitLoopOrRunLoop (
CpuMpData->ApLoopMode,
@@ -1258,13 +1219,12 @@ WakeUpAP (
ResetVectorRequired = FALSE;
if (CpuMpData->WakeUpByInitSipiSipi ||
- (CpuMpData->InitFlag != ApInitDone))
+ (CpuMpData->InitFlag == ApInitConfig))
{
ResetVectorRequired = TRUE;
AllocateResetVectorBelow1Mb (CpuMpData);
AllocateSevEsAPMemory (CpuMpData);
FillExchangeInfoData (CpuMpData);
- SaveLocalApicTimerSetting (CpuMpData);
}
if (CpuMpData->ApLoopMode == ApInMwaitLoop) {
@@ -1293,7 +1253,7 @@ WakeUpAP (
CpuData->ApFunction = (UINTN)Procedure;
CpuData->ApFunctionArgument = (UINTN)ProcedureArgument;
SetApState (CpuData, CpuStateReady);
- if (CpuMpData->InitFlag != ApInitConfig) {
+ if (CpuMpData->InitFlag == ApInitDone) {
*(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
}
}
@@ -1411,7 +1371,7 @@ WakeUpAP (
//
// Wakeup specified AP
//
- ASSERT (CpuMpData->InitFlag != ApInitConfig);
+ ASSERT (CpuMpData->InitFlag == ApInitDone);
*(UINT32 *)CpuData->StartupApSignal = WAKEUP_AP_SIGNAL;
if (ResetVectorRequired) {
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
@@ -1683,14 +1643,12 @@ ResetProcessorToIdleState (
CpuMpData = GetCpuMpData ();
- CpuMpData->InitFlag = ApInitReconfig;
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;
WakeUpAP (CpuMpData, FALSE, ProcessorNumber, NULL, NULL, TRUE);
while (CpuMpData->FinishedCount < 1) {
CpuPause ();
}
- CpuMpData->InitFlag = ApInitDone;
-
SetApState (&CpuMpData->CpuData[ProcessorNumber], CpuStateIdle);
}
@@ -2200,7 +2158,25 @@ MpInitLibInitialize (
// Don't pass BSP's TR to APs to avoid AP init failure.
//
VolatileRegisters.Tr = 0;
- CopyMem (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
+ //
+ // Set DR as 0 since DR is set only for BSP.
+ //
+ VolatileRegisters.Dr0 = 0;
+ VolatileRegisters.Dr1 = 0;
+ VolatileRegisters.Dr2 = 0;
+ VolatileRegisters.Dr3 = 0;
+ VolatileRegisters.Dr6 = 0;
+ VolatileRegisters.Dr7 = 0;
+
+ //
+ // Copy volatile registers since either APs are the first time to bring up,
+ // or BSP is in DXE phase but APs are still running in PEI context.
+ // In both cases, APs need use volatile registers from BSP
+ //
+ for (Index = 0; Index < MaxLogicalProcessorNumber; Index++) {
+ CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
+ }
+
//
// Set BSP basic information
//
@@ -2242,6 +2218,7 @@ MpInitLibInitialize (
// Enable the local APIC for Virtual Wire Mode.
//
ProgramVirtualWireMode ();
+ SaveLocalApicTimerSetting (CpuMpData);
if (FirstMpHandOff == NULL) {
if (MaxLogicalProcessorNumber > 1) {
@@ -2255,6 +2232,7 @@ MpInitLibInitialize (
// APs have been wakeup before, just get the CPU Information
// from HOB
//
+ CpuMpData->InitFlag = ApInitDone;
if (CpuMpData->UseSevEsAPMethod) {
AmdSevUpdateCpuMpData (CpuMpData);
}
@@ -2298,7 +2276,6 @@ MpInitLibInitialize (
ASSERT (CpuMpData->ApLoopMode != ApInHltLoop);
CpuMpData->FinishedCount = 0;
- CpuMpData->InitFlag = ApInitDone;
CpuMpData->EnableExecuteDisableForSwitchContext = IsBspExecuteDisableEnabled ();
SaveCpuMpData (CpuMpData);
//
@@ -2331,6 +2308,12 @@ MpInitLibInitialize (
//
InitMpGlobalData (CpuMpData);
return EFI_SUCCESS;
+ } else {
+ //
+ // PEI and DXE are in different Execution Mode
+ // Use Init Sipi Sipi for the first AP wake up in DXE phase.
+ //
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;
}
}
@@ -2359,15 +2342,6 @@ MpInitLibInitialize (
// Wakeup APs to do some AP initialize sync (Microcode & MTRR)
//
if (CpuMpData->CpuCount > 1) {
- if (FirstMpHandOff != NULL) {
- //
- // Only needs to use this flag for DXE phase to update the wake up
- // buffer. Wakeup buffer allocated in PEI phase is no longer valid
- // in DXE.
- //
- CpuMpData->InitFlag = ApInitReconfig;
- }
-
WakeUpAP (CpuMpData, TRUE, 0, ApInitializeSync, CpuMpData, TRUE);
//
// Wait for all APs finished initialization
@@ -2376,10 +2350,6 @@ MpInitLibInitialize (
CpuPause ();
}
- if (FirstMpHandOff != NULL) {
- CpuMpData->InitFlag = ApInitDone;
- }
-
for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
SetApState (&CpuMpData->CpuData[Index], CpuStateIdle);
}
@@ -2618,6 +2588,11 @@ SwitchBSPWorker (
AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);
//
+ // Save BSP's local APIC timer setting.
+ //
+ SaveLocalApicTimerSetting (CpuMpData);
+
+ //
// Need to wakeUp AP (future BSP).
//
WakeUpAP (CpuMpData, FALSE, ProcessorNumber, FutureBSPProc, CpuMpData, TRUE);
@@ -2627,13 +2602,7 @@ SwitchBSPWorker (
//
SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);
- RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE);
- //
- // Update VolatileRegisters saved in CpuMpData->CpuData
- // Don't pass BSP's TR to APs to avoid AP init failure.
- //
- CopyMem (&CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters, &CpuMpData->BSPInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
- CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters.Tr = 0;
+ RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
//
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
//
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index 88b31fecca..e92991d5dc 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -120,9 +120,8 @@ typedef enum {
// AP initialization state during APs wakeup
//
typedef enum {
- ApInitConfig = 1,
- ApInitReconfig = 2,
- ApInitDone = 3
+ ApInitConfig = 1,
+ ApInitDone = 2
} AP_INIT_STATE;
//
@@ -289,7 +288,7 @@ struct _CPU_MP_DATA {
CPU_AP_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
- UINT32 CurrentTimerCount;
+ UINT32 InitTimerCount;
UINTN DivideValue;
UINT8 Vector;
BOOLEAN PeriodicMode;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index b8c356bfe8..6e0c251397 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -1647,115 +1647,49 @@ EdkiiSmmClearMemoryAttributes (
}
/**
- Create page table based on input PagingMode, LinearAddress and Length.
+ Create page table based on input PagingMode and PhysicalAddressBits in smm.
+
+ @param[in] PagingMode The paging mode.
+ @param[in] PhysicalAddressBits The bits of physical address to map.
- @param[in, out] PageTable The pointer to the page table.
- @param[in] PagingMode The paging mode.
- @param[in] LinearAddress The start of the linear address range.
- @param[in] Length The length of the linear address range.
+ @retval PageTable Address
**/
-VOID
-GenPageTable (
- IN OUT UINTN *PageTable,
- IN PAGING_MODE PagingMode,
- IN UINT64 LinearAddress,
- IN UINT64 Length
+UINTN
+GenSmmPageTable (
+ IN PAGING_MODE PagingMode,
+ IN UINT8 PhysicalAddressBits
)
{
- RETURN_STATUS Status;
UINTN PageTableBufferSize;
+ UINTN PageTable;
VOID *PageTableBuffer;
IA32_MAP_ATTRIBUTE MapAttribute;
IA32_MAP_ATTRIBUTE MapMask;
+ RETURN_STATUS Status;
+ UINTN GuardPage;
+ UINTN Index;
+ UINT64 Length;
+ Length = LShiftU64 (1, PhysicalAddressBits);
+ PageTable = 0;
+ PageTableBufferSize = 0;
MapMask.Uint64 = MAX_UINT64;
- MapAttribute.Uint64 = mAddressEncMask|LinearAddress;
+ MapAttribute.Uint64 = mAddressEncMask;
MapAttribute.Bits.Present = 1;
MapAttribute.Bits.ReadWrite = 1;
MapAttribute.Bits.UserSupervisor = 1;
MapAttribute.Bits.Accessed = 1;
MapAttribute.Bits.Dirty = 1;
- PageTableBufferSize = 0;
-
- Status = PageTableMap (
- PageTable,
- PagingMode,
- NULL,
- &PageTableBufferSize,
- LinearAddress,
- Length,
- &MapAttribute,
- &MapMask,
- NULL
- );
- if (Status == RETURN_BUFFER_TOO_SMALL) {
- DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize));
- PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
- ASSERT (PageTableBuffer != NULL);
- Status = PageTableMap (
- PageTable,
- PagingMode,
- PageTableBuffer,
- &PageTableBufferSize,
- LinearAddress,
- Length,
- &MapAttribute,
- &MapMask,
- NULL
- );
- }
+ Status = PageTableMap (&PageTable, PagingMode, NULL, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
+ ASSERT (Status == RETURN_BUFFER_TOO_SMALL);
+ DEBUG ((DEBUG_INFO, "GenSMMPageTable: 0x%x bytes needed for initial SMM page table\n", PageTableBufferSize));
+ PageTableBuffer = AllocatePageTableMemory (EFI_SIZE_TO_PAGES (PageTableBufferSize));
+ ASSERT (PageTableBuffer != NULL);
+ Status = PageTableMap (&PageTable, PagingMode, PageTableBuffer, &PageTableBufferSize, 0, Length, &MapAttribute, &MapMask, NULL);
ASSERT (Status == RETURN_SUCCESS);
ASSERT (PageTableBufferSize == 0);
-}
-
-/**
- Create page table based on input PagingMode and PhysicalAddressBits in smm.
-
- @param[in] PagingMode The paging mode.
- @param[in] PhysicalAddressBits The bits of physical address to map.
-
- @retval PageTable Address
-
-**/
-UINTN
-GenSmmPageTable (
- IN PAGING_MODE PagingMode,
- IN UINT8 PhysicalAddressBits
- )
-{
- UINTN PageTable;
- RETURN_STATUS Status;
- UINTN GuardPage;
- UINTN Index;
- UINT64 Length;
- PAGING_MODE SmramPagingMode;
-
- PageTable = 0;
- Length = LShiftU64 (1, PhysicalAddressBits);
- ASSERT (Length > mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize);
-
- if (sizeof (UINTN) == sizeof (UINT64)) {
- SmramPagingMode = m5LevelPagingNeeded ? Paging5Level4KB : Paging4Level4KB;
- } else {
- SmramPagingMode = PagingPae4KB;
- }
-
- ASSERT (mCpuHotPlugData.SmrrBase % SIZE_4KB == 0);
- ASSERT (mCpuHotPlugData.SmrrSize % SIZE_4KB == 0);
- GenPageTable (&PageTable, PagingMode, 0, mCpuHotPlugData.SmrrBase);
-
- //
- // Map smram range in 4K page granularity to avoid subsequent page split when smm ready to lock.
- // If BSP are splitting the 1G/2M paging entries to 512 2M/4K paging entries, and all APs are
- // still running in SMI at the same time, which might access the affected linear-address range
- // between the time of modification and the time of invalidation access. That will be a potential
- // problem leading exception happen.
- //
- GenPageTable (&PageTable, SmramPagingMode, mCpuHotPlugData.SmrrBase, mCpuHotPlugData.SmrrSize);
-
- GenPageTable (&PageTable, PagingMode, mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize, Length - mCpuHotPlugData.SmrrBase - mCpuHotPlugData.SmrrSize);
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
//
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index 692aad2d15..5c0f9b4a3f 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -438,8 +438,23 @@ InitProtectedMemRange (
&MemorySpaceMap
);
for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
- NumberOfAddedDescriptors++;
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
+ if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ NumberOfAddedDescriptors++;
+ } else {
+ //
+ // Skip the MMIO range that BaseAddress and Length are not 4k aligned since
+ // the minimum granularity of the page table is 4k
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n",
+ MemorySpaceMap[Index].BaseAddress,
+ MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length
+ ));
+ }
}
}
@@ -486,15 +501,16 @@ InitProtectedMemRange (
// Create MMIO ranges which are set to present and execution-disable.
//
for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
- continue;
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
+ ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
+ NumberOfProtectRange++;
}
-
- mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
- NumberOfProtectRange++;
}
//