X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuDxe%2FCpuDxe.c;h=6ae2dcd1c71136bd6fa364ba906dd80a6befcde6;hp=4e8fa100e0e225435d635fd6e4952416f815e4df;hb=147fd35c3e389ecd025dbfd243312bf5b22da7c9;hpb=c1cab54ce57c2608b8b3ea051c7041f036f21153 diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c index 4e8fa100e0..6ae2dcd1c7 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.c +++ b/UefiCpuPkg/CpuDxe/CpuDxe.c @@ -25,6 +25,7 @@ BOOLEAN InterruptState = FALSE; EFI_HANDLE mCpuHandle = NULL; BOOLEAN mIsFlushingGCD; +BOOLEAN mIsAllocatingPageTable = FALSE; UINT64 mValidMtrrAddressMask; UINT64 mValidMtrrBitsMask; UINT64 mTimerPeriod = 0; @@ -407,6 +408,20 @@ CpuSetMemoryAttributes ( return EFI_SUCCESS; } + // + // During memory attributes updating, new pages may be allocated to setup + // smaller granularity of page table. Page allocation action might then cause + // another calling of CpuSetMemoryAttributes() recursively, due to memory + // protection policy configured (such as PcdDxeNxMemoryProtectionPolicy). + // Since this driver will always protect memory used as page table by itself, + // there's no need to apply protection policy requested from memory service. + // So it's safe to just return EFI_SUCCESS if this time of calling is caused + // by page table memory allocation. + // + if (mIsAllocatingPageTable) { + DEBUG((DEBUG_VERBOSE, " Allocating page table memory\n")); + return EFI_SUCCESS; + } CacheAttributes = Attributes & CACHE_ATTRIBUTE_MASK; MemoryAttributes = Attributes & MEMORY_ATTRIBUTE_MASK; @@ -487,7 +502,7 @@ CpuSetMemoryAttributes ( // // Set memory attribute by page table // - return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, AllocatePages); + return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, NULL); } /** @@ -683,7 +698,7 @@ SetGcdMemorySpaceAttributes ( **/ VOID -RefreshGcdMemoryAttributes ( +RefreshMemoryAttributesFromMtrr ( VOID ) { @@ -704,14 +719,9 @@ RefreshGcdMemoryAttributes ( UINT32 FirmwareVariableMtrrCount; UINT8 DefaultMemoryType; - if (!IsMtrrSupported ()) { - return; - } - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - mIsFlushingGCD = TRUE; MemorySpaceMap = NULL; // @@ -862,11 +872,46 @@ RefreshGcdMemoryAttributes ( if (MemorySpaceMap != NULL) { FreePool (MemorySpaceMap); } +} - // - // Update page attributes - // - RefreshGcdMemoryAttributesFromPaging(); +/** + Check if paging is enabled or not. +**/ +BOOLEAN +IsPagingAndPageAddressExtensionsEnabled ( + VOID + ) +{ + IA32_CR0 Cr0; + IA32_CR4 Cr4; + + Cr0.UintN = AsmReadCr0 (); + Cr4.UintN = AsmReadCr4 (); + + return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0)); +} + +/** + Refreshes the GCD Memory Space attributes according to MTRRs and Paging. + + This function refreshes the GCD Memory Space attributes according to MTRRs + and page tables. + +**/ +VOID +RefreshGcdMemoryAttributes ( + VOID + ) +{ + mIsFlushingGCD = TRUE; + + if (IsMtrrSupported ()) { + RefreshMemoryAttributesFromMtrr (); + } + + if (IsPagingAndPageAddressExtensionsEnabled ()) { + RefreshGcdMemoryAttributesFromPaging (); + } mIsFlushingGCD = FALSE; }