From: Aaron Antone <aan...@microsoft.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1416

After ExitBootServices, some pointer would be invalid such as
the Protocol pointer and gBS. The function depend on those should
be prevent. So disable the related function while after
ExitBootServices.
Change the gST to a internal one, because there will be a cycle
consume between UefiBootServicesTableLib and DebugLib due to the
library constructors.
Also remove the SMM support for this instance.

Cc: Jian J Wang <jian.j.w...@intel.com>
Cc: Ray Ni <ray...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Liming Gao <liming....@intel.com>
Cc: Sean Brogan <sean.bro...@microsoft.com>
Cc: Michael Turner <michael.tur...@microsoft.com>
Cc: Bret Barkelew <bret.barke...@microsoft.com>
Signed-off-by: Zhichao Gao <zhichao....@intel.com>
---
 MdePkg/Library/UefiDebugLibConOut/DebugLib.c  | 116 +++++++++---------
 .../UefiDebugLibConOut/DebugLibConstructor.c  |  72 +++++++++++
 .../UefiDebugLibConOut/UefiDebugLibConOut.inf |  12 +-
 3 files changed, 142 insertions(+), 58 deletions(-)
 create mode 100644 MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c

diff --git a/MdePkg/Library/UefiDebugLibConOut/DebugLib.c 
b/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
index c430419c99..cf168d05cf 100644
--- a/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
+++ b/MdePkg/Library/UefiDebugLibConOut/DebugLib.c
@@ -9,7 +9,6 @@
 #include <Uefi.h>
 
 #include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
 #include <Library/PrintLib.h>
 #include <Library/PcdLib.h>
 #include <Library/BaseLib.h>
@@ -27,6 +26,9 @@
 //
 VA_LIST     mVaListNull;
 
+extern BOOLEAN                mPostEBS;
+extern EFI_SYSTEM_TABLE       *mDebugST;
+
 /**
   Prints a debug message to the debug output device if the specified error 
level is enabled.
 
@@ -85,33 +87,35 @@ DebugPrintMarker (
 {
   CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];
 
-  //
-  // If Format is NULL, then ASSERT().
-  //
-  ASSERT (Format != NULL);
-
-  //
-  // Check driver debug mask value and global mask
-  //
-  if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
-    return;
-  }
-
-  //
-  // Convert the DEBUG() message to a Unicode String
-  //
-  if (BaseListMarker == NULL) {
-    UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, 
VaListMarker);
-  } else {
-    UnicodeBSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, 
BaseListMarker);
-  }
-
-
-  //
-  // Send the print string to the Console Output device
-  //
-  if ((gST != NULL) && (gST->ConOut != NULL)) {
-    gST->ConOut->OutputString (gST->ConOut, Buffer);
+  if (!mPostEBS) {
+    //
+    // If Format is NULL, then ASSERT().
+    //
+    ASSERT (Format != NULL);
+
+    //
+    // Check driver debug mask value and global mask
+    //
+    if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
+      return;
+    }
+
+    //
+    // Convert the DEBUG() message to a Unicode String
+    //
+    if (BaseListMarker == NULL) {
+      UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, 
VaListMarker);
+    } else {
+      UnicodeBSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, 
BaseListMarker);
+    }
+
+
+    //
+    // Send the print string to the Console Output device
+    //
+    if ((mDebugST != NULL) && (mDebugST->ConOut != NULL)) {
+      mDebugST->ConOut->OutputString (mDebugST->ConOut, Buffer);
+    }
   }
 }
 
@@ -205,33 +209,35 @@ DebugAssert (
 {
   CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];
 
-  //
-  // Generate the ASSERT() message in Unicode format
-  //
-  UnicodeSPrintAsciiFormat (
-    Buffer,
-    sizeof (Buffer),
-    "ASSERT [%a] %a(%d): %a\n",
-    gEfiCallerBaseName,
-    FileName,
-    LineNumber,
-    Description
-    );
-
-  //
-  // Send the print string to the Console Output device
-  //
-  if ((gST != NULL) && (gST->ConOut != NULL)) {
-    gST->ConOut->OutputString (gST->ConOut, Buffer);
-  }
-
-  //
-  // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
-  //
-  if ((PcdGet8(PcdDebugPropertyMask) & 
DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
-    CpuBreakpoint ();
-  } else if ((PcdGet8(PcdDebugPropertyMask) & 
DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
-    CpuDeadLoop ();
+  if (!mPostEBS) {
+    //
+    // Generate the ASSERT() message in Unicode format
+    //
+    UnicodeSPrintAsciiFormat (
+      Buffer,
+      sizeof (Buffer),
+      "ASSERT [%a] %a(%d): %a\n",
+      gEfiCallerBaseName,
+      FileName,
+      LineNumber,
+      Description
+      );
+
+    //
+    // Send the print string to the Console Output device
+    //
+    if ((mDebugST != NULL) && (mDebugST->ConOut != NULL)) {
+      mDebugST->ConOut->OutputString (mDebugST->ConOut, Buffer);
+    }
+
+    //
+    // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
+    //
+    if ((PcdGet8(PcdDebugPropertyMask) & 
DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
+      CpuBreakpoint ();
+    } else if ((PcdGet8(PcdDebugPropertyMask) & 
DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
+      CpuDeadLoop ();
+    }
   }
 }
 
diff --git a/MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c 
b/MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c
new file mode 100644
index 0000000000..48a761a71e
--- /dev/null
+++ b/MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c
@@ -0,0 +1,72 @@
+/** @file
+  UEFI Dxe DebugLib constructor that prevent some debug service after 
ExitBootServices event,
+  because some pointer is nulled at that phase.
+
+  Copyright (c) 2018, Microsoft Corporation
+  Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// BOOLEAN value to indicate if it is at the post ExitBootServices pahse
+//
+BOOLEAN     mPostEBS = FALSE;
+
+EFI_EVENT   mExitBootServicesEvent;
+
+//
+// Pointer to SystemTable
+// This library instance may have a cycle consume with UefiBootServicesTableLib
+// because of the constructors.
+//
+EFI_SYSTEM_TABLE      *mDebugST;
+
+/**
+  This routine sets the mPostEBS for exit boot servies true
+  to prevent DebugPort protocol dereferences when the pointer is nulled
+**/
+VOID
+EFIAPI
+ExitBootServicesCallback (
+  EFI_EVENT   Event,
+  VOID*       Context
+  )
+{
+  mPostEBS = TRUE;
+  return;
+}
+
+/**
+  The constructor gets the pointers to the system table and boot services table
+
+  @param  ImageHandle     The firmware allocated handle for the EFI image.
+  @param  SystemTable     A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS     The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeDebugLibConstructor(
+  IN EFI_HANDLE                 ImageHandle,
+  IN EFI_SYSTEM_TABLE           *SystemTable
+  )
+{
+  mDebugST = SystemTable;
+
+  SystemTable->BootServices->CreateEventEx (
+                                EVT_NOTIFY_SIGNAL,
+                                TPL_NOTIFY,
+                                ExitBootServicesCallback,
+                                NULL,
+                                &gEfiEventExitBootServicesGuid,
+                                &mExitBootServicesEvent
+                                );
+
+  return EFI_SUCCESS;
+}
diff --git a/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf 
b/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
index 12af4a9e98..4c279a5bf2 100644
--- a/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+++ b/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
@@ -3,7 +3,9 @@
 #
 #  Debug Lib that sends messages to the Console Output Device in the EFI 
System Table.
 #
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018, Microsoft Corporation
+#
+#  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -17,8 +19,9 @@
   FILE_GUID                      = 5cddfaf3-e9a7-4d16-bdce-1e002df475bb
   MODULE_TYPE                    = UEFI_DRIVER
   VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = DebugLib|DXE_CORE DXE_DRIVER 
DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+  LIBRARY_CLASS                  = DebugLib|DXE_CORE DXE_DRIVER 
DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER
 
+  CONSTRUCTOR                    = DxeDebugLibConstructor
 
 #
 #  VALID_ARCHITECTURES           = IA32 X64 EBC
@@ -27,6 +30,7 @@
 
 [Sources]
   DebugLib.c
+  DebugLibConstructor.c
 
 
 
@@ -39,9 +43,11 @@
   BaseLib
   PcdLib
   PrintLib
-  UefiBootServicesTableLib
   DebugPrintErrorLevelLib
 
+[Guids]
+  gEfiEventExitBootServicesGuid                 ## CONSUMES
+
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue        ## 
SOMETIMES_CONSUMES
   gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask            ## CONSUMES
-- 
2.21.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#38782): https://edk2.groups.io/g/devel/message/38782
Mute This Topic: https://groups.io/mt/31016460/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to