QemuVideoDxe driver will install VBE SHIM into page 0. If NULL pointer
detection is enabled, this driver will fail to load. NULL pointer detection
bypassing code is added to prevent such problem during boot.

Please note that Windows 7 will try to access VBE SHIM during boot if it's
installed, and then cause boot failure. This can be fixed by setting BIT7
of PcdNullPointerDetectionPropertyMask to disable NULL pointer detection
after EndOfDxe. As far as we know, there's no other OSs has such issue.

Cc: Star Zeng <[email protected]>
Cc: Eric Dong <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Jiewen Yao <[email protected]>
Cc: Michael Kinney <[email protected]>
Cc: Jordan Justen <[email protected]>
Cc: Ayellet Wolman <[email protected]>
Suggested-by: Ayellet Wolman <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <[email protected]>
---
 OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf |  2 ++
 OvmfPkg/QemuVideoDxe/VbeShim.c        | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf 
b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
index 577e07b0a8..8078232ded 100644
--- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -67,6 +67,7 @@
   UefiBootServicesTableLib
   UefiDriverEntryPoint
   UefiLib
+  DxeServicesTableLib
 
 [Protocols]
   gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED
@@ -77,3 +78,4 @@
 [Pcd]
   gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c
index e45a08e887..c3fb6d8d3c 100644
--- a/OvmfPkg/QemuVideoDxe/VbeShim.c
+++ b/OvmfPkg/QemuVideoDxe/VbeShim.c
@@ -21,10 +21,13 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
+#include <Pi/PiDxeCis.h>
 #include <IndustryStandard/LegacyVgaBios.h>
 #include <Library/DebugLib.h>
 #include <Library/PciLib.h>
 #include <Library/PrintLib.h>
+#include <Library/DxeServicesTableLib.h>
+
 #include <OvmfPlatforms.h>
 
 #include "Qemu.h"
@@ -74,11 +77,21 @@ InstallVbeShim (
   UINT8                *Ptr;
   UINTN                Printed;
   VBE_MODE_INFO        *VbeModeInfo;
+  EFI_STATUS           Status;
 
   Segment0 = 0x00000;
   SegmentC = 0xC0000;
   SegmentF = 0xF0000;
 
+  //
+  // Disable NULL pointer detection temporarily. Otherwise the installation
+  // will fail due to the lack of memory access right.
+  //
+  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) {
+    Status = gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE (1), 0);
+    ASSERT_EFI_ERROR (Status);
+  }
+
   //
   // Attempt to cover the real mode IVT with an allocation. This is a UEFI
   // driver, hence the arch protocols have been installed previously. Among
@@ -304,5 +317,14 @@ InstallVbeShim (
   Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
   Int0x10->Offset  = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);
 
+  //
+  // Get NULL pointer detection back
+  //
+  if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) {
+    Status = gDS->SetMemorySpaceAttributes (0, EFI_PAGES_TO_SIZE(1),
+                                            EFI_MEMORY_RP);
+    ASSERT_EFI_ERROR (Status);
+  }
+
   DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));
 }
-- 
2.14.1.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to