From 77bb186c8a25859e466ad5f586cc0cedb264bfa6 Mon Sep 17 00:00:00 2001
From: Mikhail Krichanov <mikhailkrichanov@gmail.com>
Date: Fri, 16 Feb 2024 14:57:30 +0300
Subject: [PATCH] Ring3: Refactored AllocateRing3CopyPages() and
 mUserDriverBinding.

---
 MdeModulePkg/Core/Dxe/DxeMain.h               |  7 +++--
 MdeModulePkg/Core/Dxe/Image/Image.c           | 28 ++++++++++++-------
 MdeModulePkg/Core/Dxe/SysCall/BootServices.c  | 16 ++++++-----
 .../Core/Dxe/SysCall/SupportedProtocols.c     | 10 +++----
 .../Core/Dxe/SysCall/SupportedProtocols.h     |  4 +--
 5 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 09e9a37d1a..8be0a8e523 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -1176,9 +1176,10 @@ CoreAllocatePages (
 
 VOID *
 EFIAPI
-AllocateRing3CopyPages (
-  IN VOID    *MemoryCore,
-  IN UINT32  MemoryCoreSize
+AllocateRing3Copy (
+  IN VOID    *Source,
+  IN UINT32  AllocationSize,
+  IN UINT32  CopySize
   );
 
 /**
diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c
index b508682c4a..f9d1520705 100644
--- a/MdeModulePkg/Core/Dxe/Image/Image.c
+++ b/MdeModulePkg/Core/Dxe/Image/Image.c
@@ -1571,21 +1571,24 @@ CoreLoadImage (
 
 VOID *
 EFIAPI
-AllocateRing3CopyPages (
-  IN VOID    *MemoryCore,
-  IN UINT32  MemoryCoreSize
+AllocateRing3Copy (
+  IN VOID    *Source,
+  IN UINT32  AllocationSize,
+  IN UINT32  CopySize
   )
 {
-  VOID  *MemoryRing3;
+  EFI_STATUS Status;
+  VOID       *MemoryRing3;
 
-  MemoryRing3 = AllocatePages (EFI_SIZE_TO_PAGES (MemoryCoreSize));
-  if (MemoryRing3 == NULL) {
+  Status = CoreAllocatePool (EfiRing3MemoryType, AllocationSize, &MemoryRing3);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Core: Failed to allocate %d bytes for Ring3.\n", AllocationSize));
     return NULL;
   }
 
-  CopyMem (MemoryRing3, MemoryCore, MemoryCoreSize);
+  ASSERT (CopySize <= AllocationSize);
 
-  SetUefiImageMemoryAttributes ((UINTN)MemoryRing3, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (MemoryCoreSize)), EFI_MEMORY_USER);
+  CopyMem (MemoryRing3, Source, CopySize);
 
   return MemoryRing3;
 }
@@ -1613,8 +1616,13 @@ InitializeRing3 (
   //
   // Set Ring3 EntryPoint and BootServices.
   //
-  mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA));
-
+  mRing3Data = AllocateRing3Copy (
+                 (VOID *)Image->Info.SystemTable,
+                 sizeof (RING3_DATA),
+                 sizeof (EFI_SYSTEM_TABLE)
+                 );
+  ASSERT (mRing3Data != NULL);
+  
   Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data);
 
   gRing3EntryPoint = mRing3Data->EntryPoint;
diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
index 4ae6c6d5ad..92f931f0a1 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
@@ -92,13 +92,14 @@ CallBootService (
                       &Interface
                       );
 
-      Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize);
+      DisableSMAP ();
+      Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize);
       if (Interface == NULL) {
         DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n"));
+        EnableSMAP ();
         return EFI_OUT_OF_RESOURCES;
       }
 
-      DisableSMAP ();
       *(VOID **)CoreRbp->Argument3 = Interface;
       EnableSMAP ();
 
@@ -137,13 +138,14 @@ CallBootService (
                       Argument6
                       );
 
-      Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize);
+      DisableSMAP ();
+      Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize);
       if (Interface == NULL) {
         DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n"));
+        EnableSMAP ();
         return EFI_OUT_OF_RESOURCES;
       }
 
-      DisableSMAP ();
       *(VOID **)CoreRbp->Argument3 = Interface;
       EnableSMAP ();
 
@@ -184,9 +186,9 @@ CallBootService (
         if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) {
           CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1];
 
-          mUserDriverBindingSupported = CoreDriverBinding->Supported;
-          mUserDriverBindingStart     = CoreDriverBinding->Start;
-          mUserDriverBindingStop      = CoreDriverBinding->Stop;
+          mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported;
+          mRing3DriverBindingProtocol.Start     = CoreDriverBinding->Start;
+          mRing3DriverBindingProtocol.Stop      = CoreDriverBinding->Stop;
 
           CoreDriverBinding->Supported = CoreDriverBindingSupported;
           CoreDriverBinding->Start     = CoreDriverBindingStart;
diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
index e40e26cb5d..9140ce7ec1 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
@@ -7,9 +7,7 @@
 
 #include "DxeMain.h"
 
-EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported;
-EFI_DRIVER_BINDING_START     mUserDriverBindingStart;
-EFI_DRIVER_BINDING_STOP      mUserDriverBindingStop;
+EFI_DRIVER_BINDING_PROTOCOL  mRing3DriverBindingProtocol;
 
 EFI_STATUS
 EFIAPI
@@ -59,7 +57,7 @@ CoreDriverBindingSupported (
 {
   return GoToRing3 (
            3,
-           (VOID *)mUserDriverBindingSupported,
+           (VOID *)mRing3DriverBindingProtocol.Supported,
            This,
            ControllerHandle,
            RemainingDevicePath
@@ -76,7 +74,7 @@ CoreDriverBindingStart (
 {
   return GoToRing3 (
            3,
-           (VOID *)mUserDriverBindingStart,
+           (VOID *)mRing3DriverBindingProtocol.Start,
            This,
            ControllerHandle,
            RemainingDevicePath
@@ -94,7 +92,7 @@ CoreDriverBindingStop (
 {
   return GoToRing3 (
            4,
-           (VOID *)mUserDriverBindingStop,
+           (VOID *)mRing3DriverBindingProtocol.Stop,
            This,
            ControllerHandle,
            NumberOfChildren,
diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
index 4737cc696e..5e7e8b3a7a 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
+++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
@@ -5,9 +5,7 @@
 
 **/
 
-extern EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported;
-extern EFI_DRIVER_BINDING_START     mUserDriverBindingStart;
-extern EFI_DRIVER_BINDING_STOP      mUserDriverBindingStop;
+extern EFI_DRIVER_BINDING_PROTOCOL  mRing3DriverBindingProtocol;
 
 EFI_STATUS
 EFIAPI