diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index fd82657404..068e700074 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -117,6 +117,8 @@ [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES [Depex] gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c index d28baa3615..0bf99bc77e 100644 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c +++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c @@ -186,37 +186,6 @@ IsIa32PaeSupport ( return Ia32PaeSupport; } -/** - The function will check if Execute Disable Bit is available. - - @retval TRUE Execute Disable Bit is available. - @retval FALSE Execute Disable Bit is not available. - -**/ -BOOLEAN -IsExecuteDisableBitAvailable ( - VOID - ) -{ - UINT32 RegEax; - UINT32 RegEdx; - BOOLEAN Available; - - Available = FALSE; - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000001) { - AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT20) != 0) { - // - // Bit 20: Execute Disable Bit available. - // - Available = TRUE; - } - } - - return Available; -} - /** The function will check if page table should be setup or not. @@ -245,7 +214,7 @@ ToBuildPageTable ( return TRUE; } - if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) { + if (IsEnableNonExecNeeded ()) { return TRUE; } @@ -436,7 +405,7 @@ HandOffToDxeCore ( BuildPageTablesIa32Pae = ToBuildPageTable (); if (BuildPageTablesIa32Pae) { PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE); - if (IsExecuteDisableBitAvailable ()) { + if (IsEnableNonExecNeeded ()) { EnableExecuteDisableBit(); } } diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 496e219913..cf3c3f94d8 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -106,6 +106,62 @@ IsNullDetectionEnabled ( return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0); } +/** + The function will check if Execute Disable Bit is available. + + @retval TRUE Execute Disable Bit is available. + @retval FALSE Execute Disable Bit is not available. + +**/ +BOOLEAN +IsExecuteDisableBitAvailable ( + VOID + ) +{ + UINT32 RegEax; + UINT32 RegEdx; + BOOLEAN Available; + + Available = FALSE; + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT20) != 0) { + // + // Bit 20: Execute Disable Bit available. + // + Available = TRUE; + } + } + + return Available; +} + +/** + Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not. + + @retval TRUE IA32_EFER.NXE should be enabled. + @retval FALSE IA32_EFER.NXE should not be enabled. + +**/ +BOOLEAN +IsEnableNonExecNeeded ( + VOID + ) +{ + if (!IsExecuteDisableBitAvailable ()) { + return FALSE; + } + + // + // XD flag (BIT63) in page table entry is only valid if IA32_EFER.NXE is set. + // Features controlled by Following PCDs need this feature to be enabled. + // + return (PcdGetBool (PcdSetNxForStack) || + PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 || + PcdGet32 (PcdImageProtectionPolicy) != 0); +} + /** Enable Execute Disable Bit. @@ -755,7 +811,10 @@ CreateIdentityMappingPageTables ( // EnablePageTableProtection ((UINTN)PageMap, TRUE); - if (PcdGetBool (PcdSetNxForStack)) { + // + // Set IA32_EFER.NXE if necessary. + // + if (IsEnableNonExecNeeded ()) { EnableExecuteDisableBit (); } diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h index 85457ff937..8ae92d3bf6 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h @@ -179,6 +179,18 @@ typedef struct { UINTN FreePages; } PAGE_TABLE_POOL; +/** + Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not. + + @retval TRUE IA32_EFER.NXE should be enabled. + @retval FALSE IA32_EFER.NXE should not be enabled. + +**/ +BOOLEAN +IsEnableNonExecNeeded ( + VOID + ); + /** Enable Execute Disable Bit.