#include <Library/MemoryAllocationLib.h>\r
#include <Library/CpuLib.h>\r
#include <Library/BaseLib.h>\r
+#include <Guid/MigratedFvInfo.h>\r
\r
#include "CpuMpPei.h"\r
\r
-#define IA32_PG_P BIT0\r
-#define IA32_PG_RW BIT1\r
-#define IA32_PG_U BIT2\r
-#define IA32_PG_A BIT5\r
-#define IA32_PG_D BIT6\r
-#define IA32_PG_PS BIT7\r
-#define IA32_PG_NX BIT63\r
+#define IA32_PG_P BIT0\r
+#define IA32_PG_RW BIT1\r
+#define IA32_PG_U BIT2\r
+#define IA32_PG_A BIT5\r
+#define IA32_PG_D BIT6\r
+#define IA32_PG_PS BIT7\r
+#define IA32_PG_NX BIT63\r
\r
-#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P)\r
-#define PAGE_PROGATE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_NX | IA32_PG_U |\\r
+#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P)\r
+#define PAGE_PROGATE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_NX | IA32_PG_U | \\r
PAGE_ATTRIBUTE_BITS)\r
\r
-#define PAGING_PAE_INDEX_MASK 0x1FF\r
-#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull\r
-#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull\r
-#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
-#define PAGING_512G_ADDRESS_MASK_64 0x000FFF8000000000ull\r
+#define PAGING_PAE_INDEX_MASK 0x1FF\r
+#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull\r
+#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull\r
+#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
+#define PAGING_512G_ADDRESS_MASK_64 0x000FFF8000000000ull\r
\r
typedef enum {\r
PageNone = 0,\r
} PAGE_ATTRIBUTE;\r
\r
typedef struct {\r
- PAGE_ATTRIBUTE Attribute;\r
- UINT64 Length;\r
- UINT64 AddressMask;\r
- UINTN AddressBitOffset;\r
- UINTN AddressBitLength;\r
+ PAGE_ATTRIBUTE Attribute;\r
+ UINT64 Length;\r
+ UINT64 AddressMask;\r
+ UINTN AddressBitOffset;\r
+ UINTN AddressBitLength;\r
} PAGE_ATTRIBUTE_TABLE;\r
\r
-PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = {\r
- {PageNone, 0, 0, 0, 0},\r
- {Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64, 12, 9},\r
- {Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64, 21, 9},\r
- {Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64, 30, 9},\r
- {Page512G, SIZE_512GB, PAGING_512G_ADDRESS_MASK_64, 39, 9},\r
+PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = {\r
+ { PageNone, 0, 0, 0, 0 },\r
+ { Page4K, SIZE_4KB, PAGING_4K_ADDRESS_MASK_64, 12, 9 },\r
+ { Page2M, SIZE_2MB, PAGING_2M_ADDRESS_MASK_64, 21, 9 },\r
+ { Page1G, SIZE_1GB, PAGING_1G_ADDRESS_MASK_64, 30, 9 },\r
+ { Page512G, SIZE_512GB, PAGING_512G_ADDRESS_MASK_64, 39, 9 },\r
};\r
\r
EFI_PEI_NOTIFY_DESCRIPTOR mPostMemNotifyList[] = {\r
VOID\r
)\r
{\r
- UINT32 RegEax;\r
- CPUID_VERSION_INFO_EDX RegEdx;\r
+ UINT32 RegEax;\r
+ CPUID_VERSION_INFO_EDX RegEdx;\r
\r
AsmCpuid (CPUID_SIGNATURE, &RegEax, NULL, NULL, NULL);\r
if (RegEax >= CPUID_VERSION_INFO) {\r
**/\r
VOID *\r
AllocatePageTableMemory (\r
- IN UINTN Pages\r
+ IN UINTN Pages\r
)\r
{\r
- VOID *Address;\r
+ VOID *Address;\r
\r
- Address = AllocatePages(Pages);\r
+ Address = AllocatePages (Pages);\r
if (Address != NULL) {\r
- ZeroMem(Address, EFI_PAGES_TO_SIZE (Pages));\r
+ ZeroMem (Address, EFI_PAGES_TO_SIZE (Pages));\r
}\r
\r
return Address;\r
VOID\r
)\r
{\r
- UINT32 RegEax;\r
+ UINT32 RegEax;\r
\r
- if (sizeof(UINTN) == 4) {\r
+ if (sizeof (UINTN) == 4) {\r
return 32;\r
}\r
\r
- AsmCpuid(CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
if (RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &RegEax, NULL, NULL, NULL);\r
RegEax &= 0xFF;\r
Get the type of top level page table.\r
\r
@retval Page512G PML4 paging.\r
- @retval Page1G PAE paing.\r
+ @retval Page1G PAE paging.\r
\r
**/\r
PAGE_ATTRIBUTE\r
VOID\r
)\r
{\r
- MSR_IA32_EFER_REGISTER MsrEfer;\r
+ MSR_IA32_EFER_REGISTER MsrEfer;\r
\r
MsrEfer.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_EFER);\r
\r
**/\r
VOID *\r
GetPageTableEntry (\r
- IN PHYSICAL_ADDRESS Address,\r
- OUT PAGE_ATTRIBUTE *PageAttribute\r
+ IN PHYSICAL_ADDRESS Address,\r
+ OUT PAGE_ATTRIBUTE *PageAttribute\r
)\r
{\r
- INTN Level;\r
- UINTN Index;\r
- UINT64 *PageTable;\r
- UINT64 AddressEncMask;\r
+ INTN Level;\r
+ UINTN Index;\r
+ UINT64 *PageTable;\r
+ UINT64 AddressEncMask;\r
\r
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);\r
- PageTable = (UINT64 *)(UINTN)(AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
+ PageTable = (UINT64 *)(UINTN)(AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
for (Level = (INTN)GetPageTableTopLevelType (); Level > 0; --Level) {\r
- Index = (UINTN)RShiftU64 (Address, mPageAttributeTable[Level].AddressBitOffset);\r
+ Index = (UINTN)RShiftU64 (Address, mPageAttributeTable[Level].AddressBitOffset);\r
Index &= PAGING_PAE_INDEX_MASK;\r
\r
//\r
//\r
// Page memory?\r
//\r
- if ((PageTable[Index] & IA32_PG_PS) != 0 || Level == PageMin) {\r
+ if (((PageTable[Index] & IA32_PG_PS) != 0) || (Level == PageMin)) {\r
*PageAttribute = (PAGE_ATTRIBUTE)Level;\r
return &PageTable[Index];\r
}\r
**/\r
RETURN_STATUS\r
SplitPage (\r
- IN UINT64 *PageEntry,\r
- IN PAGE_ATTRIBUTE PageAttribute,\r
- IN PAGE_ATTRIBUTE SplitAttribute,\r
- IN BOOLEAN Recursively\r
+ IN UINT64 *PageEntry,\r
+ IN PAGE_ATTRIBUTE PageAttribute,\r
+ IN PAGE_ATTRIBUTE SplitAttribute,\r
+ IN BOOLEAN Recursively\r
)\r
{\r
- UINT64 BaseAddress;\r
- UINT64 *NewPageEntry;\r
- UINTN Index;\r
- UINT64 AddressEncMask;\r
- PAGE_ATTRIBUTE SplitTo;\r
+ UINT64 BaseAddress;\r
+ UINT64 *NewPageEntry;\r
+ UINTN Index;\r
+ UINT64 AddressEncMask;\r
+ PAGE_ATTRIBUTE SplitTo;\r
\r
- if (SplitAttribute == PageNone || SplitAttribute >= PageAttribute) {\r
+ if ((SplitAttribute == PageNone) || (SplitAttribute >= PageAttribute)) {\r
ASSERT (SplitAttribute != PageNone);\r
ASSERT (SplitAttribute < PageAttribute);\r
return RETURN_INVALID_PARAMETER;\r
//\r
// One level down each step to achieve more compact page table.\r
//\r
- SplitTo = PageAttribute - 1;\r
+ SplitTo = PageAttribute - 1;\r
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &\r
mPageAttributeTable[SplitTo].AddressMask;\r
- BaseAddress = *PageEntry &\r
- ~PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &\r
- mPageAttributeTable[PageAttribute].AddressMask;\r
- for (Index = 0; Index < SIZE_4KB / sizeof(UINT64); Index++) {\r
+ BaseAddress = *PageEntry &\r
+ ~PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &\r
+ mPageAttributeTable[PageAttribute].AddressMask;\r
+ for (Index = 0; Index < SIZE_4KB / sizeof (UINT64); Index++) {\r
NewPageEntry[Index] = BaseAddress | AddressEncMask |\r
((*PageEntry) & PAGE_PROGATE_BITS);\r
\r
NewPageEntry[Index] |= IA32_PG_PS;\r
}\r
\r
- if (Recursively && SplitTo > SplitAttribute) {\r
+ if (Recursively && (SplitTo > SplitAttribute)) {\r
SplitPage (&NewPageEntry[Index], SplitTo, SplitAttribute, Recursively);\r
}\r
\r
RETURN_STATUS\r
EFIAPI\r
ConvertMemoryPageAttributes (\r
- IN PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 Attributes\r
+ IN PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 Attributes\r
)\r
{\r
- UINT64 *PageEntry;\r
- PAGE_ATTRIBUTE PageAttribute;\r
- RETURN_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS MaximumAddress;\r
-\r
- if (Length == 0 ||\r
- (BaseAddress & (SIZE_4KB - 1)) != 0 ||\r
- (Length & (SIZE_4KB - 1)) != 0) {\r
-\r
+ UINT64 *PageEntry;\r
+ PAGE_ATTRIBUTE PageAttribute;\r
+ RETURN_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS MaximumAddress;\r
+\r
+ if ((Length == 0) ||\r
+ ((BaseAddress & (SIZE_4KB - 1)) != 0) ||\r
+ ((Length & (SIZE_4KB - 1)) != 0))\r
+ {\r
ASSERT (Length > 0);\r
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);\r
ASSERT ((Length & (SIZE_4KB - 1)) == 0);\r
}\r
\r
MaximumAddress = (EFI_PHYSICAL_ADDRESS)MAX_UINT32;\r
- if (BaseAddress > MaximumAddress ||\r
- Length > MaximumAddress ||\r
- (BaseAddress > MaximumAddress - (Length - 1))) {\r
+ if ((BaseAddress > MaximumAddress) ||\r
+ (Length > MaximumAddress) ||\r
+ (BaseAddress > MaximumAddress - (Length - 1)))\r
+ {\r
return RETURN_UNSUPPORTED;\r
}\r
\r
if (RETURN_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// Do it again until the page is 4K.\r
//\r
// Convert success, move to next\r
//\r
BaseAddress += SIZE_4KB;\r
- Length -= SIZE_4KB;\r
+ Length -= SIZE_4KB;\r
}\r
\r
return RETURN_SUCCESS;\r
IN PAGE_ATTRIBUTE TopLevelType\r
)\r
{\r
- UINT32 RegEax;\r
- UINT32 RegEdx;\r
+ UINT32 RegEax;\r
+ UINT32 RegEdx;\r
\r
if (TopLevelType == Page512G) {\r
AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
VOID\r
)\r
{\r
- RETURN_STATUS Status;\r
- UINTN PhysicalAddressBits;\r
- UINTN NumberOfEntries;\r
- PAGE_ATTRIBUTE TopLevelPageAttr;\r
- UINTN PageTable;\r
- PAGE_ATTRIBUTE MaxMemoryPage;\r
- UINTN Index;\r
- UINT64 AddressEncMask;\r
- UINT64 *PageEntry;\r
- EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
-\r
- TopLevelPageAttr = (PAGE_ATTRIBUTE)GetPageTableTopLevelType ();\r
+ RETURN_STATUS Status;\r
+ UINTN PhysicalAddressBits;\r
+ UINTN NumberOfEntries;\r
+ PAGE_ATTRIBUTE TopLevelPageAttr;\r
+ UINTN PageTable;\r
+ PAGE_ATTRIBUTE MaxMemoryPage;\r
+ UINTN Index;\r
+ UINT64 AddressEncMask;\r
+ UINT64 *PageEntry;\r
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
+\r
+ TopLevelPageAttr = (PAGE_ATTRIBUTE)GetPageTableTopLevelType ();\r
PhysicalAddressBits = GetPhysicalAddressWidth ();\r
- NumberOfEntries = (UINTN)1 << (PhysicalAddressBits -\r
- mPageAttributeTable[TopLevelPageAttr].AddressBitOffset);\r
+ NumberOfEntries = (UINTN)1 << (PhysicalAddressBits -\r
+ mPageAttributeTable[TopLevelPageAttr].AddressBitOffset);\r
\r
- PageTable = (UINTN) AllocatePageTableMemory (1);\r
+ PageTable = (UINTN)AllocatePageTableMemory (1);\r
if (PageTable == 0) {\r
return 0;\r
}\r
\r
- AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);\r
+ AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask);\r
AddressEncMask &= mPageAttributeTable[TopLevelPageAttr].AddressMask;\r
- MaxMemoryPage = GetMaxMemoryPage (TopLevelPageAttr);\r
- PageEntry = (UINT64 *)PageTable;\r
+ MaxMemoryPage = GetMaxMemoryPage (TopLevelPageAttr);\r
+ PageEntry = (UINT64 *)PageTable;\r
\r
PhysicalAddress = 0;\r
for (Index = 0; Index < NumberOfEntries; ++Index) {\r
// Split the top page table down to the maximum page size supported\r
//\r
if (MaxMemoryPage < TopLevelPageAttr) {\r
- Status = SplitPage(PageEntry, TopLevelPageAttr, MaxMemoryPage, TRUE);\r
+ Status = SplitPage (PageEntry, TopLevelPageAttr, MaxMemoryPage, TRUE);\r
ASSERT_EFI_ERROR (Status);\r
}\r
\r
*PageEntry &= ~(UINT64)(IA32_PG_RW | IA32_PG_U);\r
}\r
\r
- PageEntry += 1;\r
+ PageEntry += 1;\r
PhysicalAddress += mPageAttributeTable[TopLevelPageAttr].Length;\r
}\r
\r
-\r
return PageTable;\r
}\r
\r
VOID\r
)\r
{\r
- UINTN PageTable;\r
+ UINTN PageTable;\r
\r
PageTable = CreatePageTable ();\r
ASSERT (PageTable != 0);\r
if (PageTable != 0) {\r
- AsmWriteCr3(PageTable);\r
+ AsmWriteCr3 (PageTable);\r
AsmWriteCr4 (AsmReadCr4 () | BIT5); // CR4.PAE\r
AsmWriteCr0 (AsmReadCr0 () | BIT31); // CR0.PG\r
}\r
VOID\r
EFIAPI\r
GetStackBase (\r
- IN OUT VOID *Buffer\r
+ IN OUT VOID *Buffer\r
)\r
{\r
- EFI_PHYSICAL_ADDRESS StackBase;\r
+ EFI_PHYSICAL_ADDRESS StackBase;\r
\r
- StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)&StackBase;\r
+ StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)&StackBase;\r
StackBase += BASE_4KB;\r
StackBase &= ~((EFI_PHYSICAL_ADDRESS)BASE_4KB - 1);\r
- StackBase -= PcdGet32(PcdCpuApStackSize);\r
+ StackBase -= PcdGet32 (PcdCpuApStackSize);\r
\r
*(EFI_PHYSICAL_ADDRESS *)Buffer = StackBase;\r
}\r
VOID\r
)\r
{\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_PHYSICAL_ADDRESS StackBase;\r
- UINTN NumberOfProcessors;\r
- UINTN Bsp;\r
- UINTN Index;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_PHYSICAL_ADDRESS StackBase;\r
+ UINTN NumberOfProcessors;\r
+ UINTN Bsp;\r
+ UINTN Index;\r
\r
//\r
// One extra page at the bottom of the stack is needed for Guard page.\r
//\r
- if (PcdGet32(PcdCpuApStackSize) <= EFI_PAGE_SIZE) {\r
+ if (PcdGet32 (PcdCpuApStackSize) <= EFI_PAGE_SIZE) {\r
DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n"));\r
ASSERT (FALSE);\r
}\r
\r
- MpInitLibGetNumberOfProcessors(&NumberOfProcessors, NULL);\r
+ MpInitLibGetNumberOfProcessors (&NumberOfProcessors, NULL);\r
MpInitLibWhoAmI (&Bsp);\r
for (Index = 0; Index < NumberOfProcessors; ++Index) {\r
StackBase = 0;\r
if (Index == Bsp) {\r
Hob.Raw = GetHobList ();\r
while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
- if (CompareGuid (&gEfiHobMemoryAllocStackGuid,\r
- &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
+ if (CompareGuid (\r
+ &gEfiHobMemoryAllocStackGuid,\r
+ &(Hob.MemoryAllocationStack->AllocDescriptor.Name)\r
+ ))\r
+ {\r
StackBase = Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress;\r
break;\r
}\r
+\r
Hob.Raw = GET_NEXT_HOB (Hob);\r
}\r
} else {\r
//\r
// Ask AP to return is stack base address.\r
//\r
- MpInitLibStartupThisAP(GetStackBase, Index, NULL, 0, (VOID *)&StackBase, NULL);\r
+ MpInitLibStartupThisAP (GetStackBase, Index, NULL, 0, (VOID *)&StackBase, NULL);\r
}\r
+\r
ASSERT (StackBase != 0);\r
//\r
// Set Guard page at stack base address.\r
//\r
- ConvertMemoryPageAttributes(StackBase, EFI_PAGE_SIZE, 0);\r
- DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n",\r
- (UINT64)StackBase, (UINT64)Index));\r
+ ConvertMemoryPageAttributes (StackBase, EFI_PAGE_SIZE, 0);\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "Stack Guard set at %lx [cpu%lu]!\n",\r
+ (UINT64)StackBase,\r
+ (UINT64)Index\r
+ ));\r
}\r
\r
//\r
}\r
\r
/**\r
- Enabl/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.\r
+ Enable/setup stack guard for each processor if PcdCpuStackGuard is set to TRUE.\r
\r
Doing this in the memory-discovered callback is to make sure the Stack Guard\r
feature to cover as most PEI code as possible.\r
IN VOID *Ppi\r
)\r
{\r
- EFI_STATUS Status;\r
- BOOLEAN InitStackGuard;\r
- BOOLEAN InterruptState;\r
-\r
- if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
- InterruptState = SaveAndDisableInterrupts ();\r
- Status = MigrateGdt ();\r
- ASSERT_EFI_ERROR (Status);\r
- SetInterruptState (InterruptState);\r
- }\r
+ EFI_STATUS Status;\r
+ BOOLEAN InitStackGuard;\r
+ EDKII_MIGRATED_FV_INFO *MigratedFvInfo;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
\r
//\r
// Paging must be setup first. Otherwise the exception TSS setup during MP\r
// the task switch (for the sake of stack switch).\r
//\r
InitStackGuard = FALSE;\r
- if (IsIa32PaeSupported () && PcdGetBool (PcdCpuStackGuard)) {\r
+ Hob.Raw = NULL;\r
+ if (IsIa32PaeSupported ()) {\r
+ Hob.Raw = GetFirstGuidHob (&gEdkiiMigratedFvInfoGuid);\r
+ InitStackGuard = PcdGetBool (PcdCpuStackGuard);\r
+ }\r
+\r
+ if (InitStackGuard || (Hob.Raw != NULL)) {\r
EnablePaging ();\r
- InitStackGuard = TRUE;\r
}\r
\r
Status = InitializeCpuMpWorker ((CONST EFI_PEI_SERVICES **)PeiServices);\r
SetupStackGuardPage ();\r
}\r
\r
+ while (Hob.Raw != NULL) {\r
+ MigratedFvInfo = GET_GUID_HOB_DATA (Hob);\r
+\r
+ //\r
+ // Enable #PF exception, so if the code access SPI after disable NEM, it will generate\r
+ // the exception to avoid potential vulnerability.\r
+ //\r
+ ConvertMemoryPageAttributes (MigratedFvInfo->FvOrgBase, MigratedFvInfo->FvLength, 0);\r
+\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ Hob.Raw = GetNextGuidHob (&gEdkiiMigratedFvInfoGuid, Hob.Raw);\r
+ }\r
+\r
+ CpuFlushTlb ();\r
+\r
return Status;\r
}\r
-\r