PageDirectoryPointerEntry->Bits.Present = 1;\r
\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {\r
- if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) {\r
+ if ((IsNullDetectionEnabled () && PhysicalAddress == 0)\r
+ || ((PhysicalAddress < StackBase + StackSize)\r
+ && ((PhysicalAddress + SIZE_2MB) > StackBase))) {\r
//\r
// Need to split this 2M page that covers stack range.\r
//\r
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
BOOLEAN BuildPageTablesIa32Pae;\r
\r
+ if (IsNullDetectionEnabled ()) {\r
+ ClearFirst4KPage (HobList.Raw);\r
+ }\r
+\r
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
ASSERT_EFI_ERROR (Status);\r
\r
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
\r
PageTables = 0;\r
- BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());\r
+ BuildPageTablesIa32Pae = (BOOLEAN) (IsIa32PaeSupport () &&\r
+ (IsNullDetectionEnabled () ||\r
+ (PcdGetBool (PcdSetNxForStack) &&\r
+ IsExecuteDisableBitAvailable ())));\r
if (BuildPageTablesIa32Pae) {\r
PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);\r
- EnableExecuteDisableBit ();\r
+ if (IsExecuteDisableBitAvailable ()) {\r
+ EnableExecuteDisableBit();\r
+ }\r
}\r
\r
//\r
#include "DxeIpl.h"\r
#include "VirtualMemory.h"\r
\r
+/**\r
+ Clear legacy memory located at the first 4K-page, if available.\r
+\r
+ This function traverses the whole HOB list to check if memory from 0 to 4095\r
+ exists and has not been allocated, and then clear it if so.\r
+\r
+ @param HoStart The start of HobList passed to DxeCore.\r
+\r
+**/\r
+VOID\r
+ClearFirst4KPage (\r
+ IN VOID *HobStart\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS RscHob;\r
+ EFI_PEI_HOB_POINTERS MemHob;\r
+ BOOLEAN DoClear;\r
+\r
+ RscHob.Raw = HobStart;\r
+ MemHob.Raw = HobStart;\r
+ DoClear = FALSE;\r
+\r
+ //\r
+ // Check if page 0 exists and free\r
+ //\r
+ while ((RscHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,\r
+ RscHob.Raw)) != NULL) {\r
+ if (RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ RscHob.ResourceDescriptor->PhysicalStart == 0) {\r
+ DoClear = TRUE;\r
+ //\r
+ // Make sure memory at 0-4095 has not been allocated.\r
+ //\r
+ while ((MemHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION,\r
+ MemHob.Raw)) != NULL) {\r
+ if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress\r
+ < EFI_PAGE_SIZE) {\r
+ DoClear = FALSE;\r
+ break;\r
+ }\r
+ MemHob.Raw = GET_NEXT_HOB (MemHob);\r
+ }\r
+ break;\r
+ }\r
+ RscHob.Raw = GET_NEXT_HOB (RscHob);\r
+ }\r
+\r
+ if (DoClear) {\r
+ DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n"));\r
+ SetMem (NULL, EFI_PAGE_SIZE, 0);\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+BOOLEAN\r
+IsNullDetectionEnabled (\r
+ VOID\r
+ )\r
+{\r
+ return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);\r
+}\r
\r
/**\r
Enable Execute Disable Bit.\r
//\r
PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;\r
PageTableEntry->Bits.ReadWrite = 1;\r
- PageTableEntry->Bits.Present = 1;\r
- if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) {\r
+\r
+ if (IsNullDetectionEnabled () && PhysicalAddress4K == 0) {\r
+ PageTableEntry->Bits.Present = 0;\r
+ } else {\r
+ PageTableEntry->Bits.Present = 1;\r
+ }\r
+\r
+ if (PcdGetBool (PcdSetNxForStack)\r
+ && (PhysicalAddress4K >= StackBase)\r
+ && (PhysicalAddress4K < StackBase + StackSize)) {\r
//\r
// Set Nx bit for stack.\r
//\r
\r
PhysicalAddress2M = PhysicalAddress;\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {\r
- if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) {\r
+ if ((IsNullDetectionEnabled () && PhysicalAddress2M == 0)\r
+ || (PcdGetBool (PcdSetNxForStack)\r
+ && (PhysicalAddress2M < StackBase + StackSize)\r
+ && ((PhysicalAddress2M + SIZE_2MB) > StackBase))) {\r
//\r
- // Need to split this 2M page that covers stack range.\r
+ // Need to split this 2M page that covers NULL or stack range.\r
//\r
Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);\r
} else {\r
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;\r
\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
- if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) {\r
+ if ((IsNullDetectionEnabled () && PageAddress == 0)\r
+ || (PcdGetBool (PcdSetNxForStack)\r
+ && (PageAddress < StackBase + StackSize)\r
+ && ((PageAddress + SIZE_1GB) > StackBase))) {\r
Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);\r
} else {\r
//\r
PageDirectoryPointerEntry->Bits.Present = 1;\r
\r
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
- if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) {\r
+ if ((IsNullDetectionEnabled () && PageAddress == 0)\r
+ || (PcdGetBool (PcdSetNxForStack)\r
+ && (PageAddress < StackBase + StackSize)\r
+ && ((PageAddress + SIZE_2MB) > StackBase))) {\r
//\r
- // Need to split this 2M page that covers stack range.\r
+ // Need to split this 2M page that covers NULL or stack range.\r
//\r
Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize);\r
} else {\r