MdeModulePkg/Core/Dxe: Add EndOfDxe workaround for NULL pointer detection

One of issue caused by enabling NULL pointer detection is that some PCI
device OptionROM, binary drivers and binary OS boot loaders may have NULL
pointer access bugs, which will prevent BIOS from booting and is almost
impossible to fix. BIT7 of PCD PcdNullPointerDetectionPropertyMask is used
as a workaround to indicate BIOS to disable NULL pointer detection right
after event gEfiEndOfDxeEventGroupGuid, and then let boot continue.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Ayellet Wolman <ayellet.wolman@intel.com>
Suggested-by: Ayellet Wolman <ayellet.wolman@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: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Jian J Wang 2017-10-09 21:58:55 +08:00 committed by Eric Dong
parent 9189ec20b9
commit a7181d952f
3 changed files with 69 additions and 1 deletions

View File

@ -192,6 +192,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
# [Hob]
# RESOURCE_DESCRIPTOR ## CONSUMES

View File

@ -188,7 +188,9 @@ CoreAddRange (
// used for other purposes.
//
if (Type == EfiConventionalMemory && Start == 0 && (End >= EFI_PAGE_SIZE - 1)) {
SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0);
if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) == 0) {
SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0);
}
}
//

View File

@ -995,6 +995,53 @@ MemoryProtectionExitBootServicesCallback (
}
}
/**
Disable NULL pointer detection after EndOfDxe. This is a workaround resort in
order to skip unfixable NULL pointer access issues detected in OptionROM or
boot loaders.
@param[in] Event The Event this notify function registered to.
@param[in] Context Pointer to the context data registered to the Event.
**/
VOID
EFIAPI
DisableNullDetectionAtTheEndOfDxe (
EFI_EVENT Event,
VOID *Context
)
{
EFI_STATUS Status;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR Desc;
DEBUG ((DEBUG_INFO, "DisableNullDetectionAtTheEndOfDxe(): start\r\n"));
//
// Disable NULL pointer detection by enabling first 4K page
//
Status = CoreGetMemorySpaceDescriptor (0, &Desc);
ASSERT_EFI_ERROR (Status);
if ((Desc.Capabilities & EFI_MEMORY_RP) == 0) {
Status = CoreSetMemorySpaceCapabilities (
0,
EFI_PAGE_SIZE,
Desc.Capabilities | EFI_MEMORY_RP
);
ASSERT_EFI_ERROR (Status);
}
Status = CoreSetMemorySpaceAttributes (
0,
EFI_PAGE_SIZE,
Desc.Attributes & ~EFI_MEMORY_RP
);
ASSERT_EFI_ERROR (Status);
CoreCloseEvent (Event);
DEBUG ((DEBUG_INFO, "DisableNullDetectionAtTheEndOfDxe(): end\r\n"));
return;
}
/**
Initialize Memory Protection support.
**/
@ -1006,6 +1053,7 @@ CoreInitializeMemoryProtection (
{
EFI_STATUS Status;
EFI_EVENT Event;
EFI_EVENT EndOfDxeEvent;
VOID *Registration;
mImageProtectionPolicy = PcdGet32(PcdImageProtectionPolicy);
@ -1044,6 +1092,23 @@ CoreInitializeMemoryProtection (
);
ASSERT_EFI_ERROR(Status);
}
//
// Register a callback to disable NULL pointer detection at EndOfDxe
//
if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7))
== (BIT0|BIT7)) {
Status = CoreCreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
DisableNullDetectionAtTheEndOfDxe,
NULL,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
ASSERT_EFI_ERROR (Status);
}
return ;
}