Skip to content

Commit

Permalink
MdeModulePkg/DxeIpl: support more NX related PCDs
Browse files Browse the repository at this point in the history
BZ#1116: https://bugzilla.tianocore.org/show_bug.cgi?id=1116

Currently IA32_EFER.NXE is only set against PcdSetNxForStack. This
confuses developers because following two other PCDs also need NXE
to be set, but actually not.

    PcdDxeNxMemoryProtectionPolicy
    PcdImageProtectionPolicy

This patch solves this issue by adding logic to enable IA32_EFER.NXE
if any of those PCDs have anything enabled.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
  • Loading branch information
jwang36 committed Sep 26, 2018
1 parent b888c57 commit 5267926
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 34 deletions.
2 changes: 2 additions & 0 deletions MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
Expand Up @@ -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
Expand Down
35 changes: 2 additions & 33 deletions MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
Expand Up @@ -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.
Expand Down Expand Up @@ -245,7 +214,7 @@ ToBuildPageTable (
return TRUE;
}

if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {
if (IsEnableNonExecNeeded ()) {
return TRUE;
}

Expand Down Expand Up @@ -436,7 +405,7 @@ HandOffToDxeCore (
BuildPageTablesIa32Pae = ToBuildPageTable ();
if (BuildPageTablesIa32Pae) {
PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
if (IsExecuteDisableBitAvailable ()) {
if (IsEnableNonExecNeeded ()) {
EnableExecuteDisableBit();
}
}
Expand Down
61 changes: 60 additions & 1 deletion MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
Expand Up @@ -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.
Expand Down Expand Up @@ -755,7 +811,10 @@ CreateIdentityMappingPageTables (
//
EnablePageTableProtection ((UINTN)PageMap, TRUE);

if (PcdGetBool (PcdSetNxForStack)) {
//
// Set IA32_EFER.NXE if necessary.
//
if (IsEnableNonExecNeeded ()) {
EnableExecuteDisableBit ();
}

Expand Down
12 changes: 12 additions & 0 deletions MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
Expand Up @@ -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.
Expand Down

0 comments on commit 5267926

Please sign in to comment.