diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
index 3a2e3af481..0fe9186916 100644
--- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
+++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc
@@ -88,9 +88,9 @@ APRIORI DXE {
   #
   INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
   INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
-  INF FatPkg/EnhancedFatDxe/Fat.inf
+  INF USER FatPkg/EnhancedFatDxe/Fat.inf
   INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
-  INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
   INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
   INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
 
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 4df7d6596b..8b06fd17ee 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -286,8 +286,6 @@ extern LOADED_IMAGE_PRIVATE_DATA  *                mCurrentImage;
 
 extern RING3_DATA                        *gRing3Data;
 extern VOID                              *gRing3Interfaces;
-extern UINTN                             gCoreSysCallStackTop;
-extern UINTN                             gRing3CallStackTop;
 extern VOID                              *gRing3EntryPoint;
 extern UINTN                             gUserPageTable;
 extern UINTN                             gCorePageTable;
@@ -2744,12 +2742,6 @@ CallBootService (
   IN RING3_STACK *UserRsp
   );
 
-EFI_STATUS
-EFIAPI
-CallRing3 (
-  IN RING3_CALL_DATA *Data
-  );
-
 VOID
 EFIAPI
 AllowSupervisorAccessToUserMemory (
@@ -2765,8 +2757,10 @@ ForbidSupervisorAccessToUserMemory (
 EFI_STATUS
 EFIAPI
 GoToRing3 (
-  IN UINT8 Number,
-  IN VOID  *EntryPoint,
+  IN UINT8  Number,
+  IN VOID   *EntryPoint,
+  IN UINTN  UserStackTop,
+  IN UINTN  SysCallStackTop,
   ...
   );
 
diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c
index 4b076ec213..74b989e1bb 100644
--- a/MdeModulePkg/Core/Dxe/Image/Image.c
+++ b/MdeModulePkg/Core/Dxe/Image/Image.c
@@ -1741,16 +1741,16 @@ CoreStartImage (
         gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes);
         ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
 
-        gUserPageTable       = Image->UserPageTable;
-        gRing3CallStackTop   = Image->UserStackTop;
-        gCoreSysCallStackTop = Image->SysCallStackTop;
+        gUserPageTable = Image->UserPageTable;
 
         Image->Status = GoToRing3 (
-          2,
-          (VOID *)Image->EntryPoint,
-          ImageHandle,
-          gRing3Data
-        );
+                          2,
+                          (VOID *)Image->EntryPoint,
+                          Image->UserStackTop,
+                          Image->SysCallStackTop,
+                          ImageHandle,
+                          gRing3Data
+                          );
       }
     } else {
       Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
index f6de8c0a71..45264f3197 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
+++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S
@@ -60,13 +60,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
 // EFI_STATUS
 // EFIAPI
 // CallRing3 (
-//   IN RING3_CALL_DATA *Data
+//   IN RING3_CALL_DATA *Data,
+//   IN UINTN            UserStackTop,
+//   IN UINTN            SysCallStackTop
 //   );
 //
 //   (x0) Data
-//   (x1) gRing3CallStackTop
+//   (x1) UserStackTop
 //   (x2) gRing3EntryPoint
-//   (x3) gCoreSysCallStackTop
+//   (x3) SysCallStackTop
 //   (x4) &CoreSp
 //   (x5) gUserPageTable
 //------------------------------------------------------------------------------
diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
index 73400bfa43..94321306b9 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c
@@ -14,6 +14,8 @@
 
 STATIC UINTN  mCoreSp;
 UINTN         gUserPageTable;
+UINTN         mRing3CallStackTop;
+UINTN         mCoreSysCallStackTop;
 
 EFI_STATUS
 EFIAPI
@@ -167,8 +169,13 @@ ForbidSupervisorAccessToUserMemory (
 EFI_STATUS
 EFIAPI
 CallRing3 (
-  IN RING3_CALL_DATA *Data
+  IN RING3_CALL_DATA *Data,
+  IN UINTN            UserStackTop,
+  IN UINTN            SysCallStackTop
   )
 {
-  return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
+  mRing3CallStackTop   = UserStackTop;
+  mCoreSysCallStackTop = SysCallStackTop;
+
+  return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable);
 }
diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
index df40693d20..03b326f20d 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
+++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S
@@ -56,13 +56,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096)
 // EFI_STATUS
 // EFIAPI
 // CallRing3 (
-//   IN RING3_CALL_DATA *Data
+//   IN RING3_CALL_DATA *Data,
+//   IN UINTN            UserStackTop,
+//   IN UINTN            SysCallStackTop
 //   );
 //
 //   (r0) Data
-//   (r1) gRing3CallStackTop
+//   (r1) UserStackTop
 //   (r2) gRing3EntryPoint
-//   (r3) gCoreSysCallStackTop
+//   (r3) SysCallStackTop
 //
 //   (On Core Stack) &CoreSp, gUserPageTable
 //------------------------------------------------------------------------------
@@ -84,7 +86,7 @@ ASM_FUNC(ArmCallRing3)
   cpsid if
   isb
 
-  // Set SP_usr to gRing3CallStackTop.
+  // Set SP_usr to UserStackTop.
   push  {R1}
   mov   R1, SP
   ldmia R1, {SP}^
diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
index becb1812c2..2c20160c34 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c
@@ -13,6 +13,8 @@
 
 STATIC UINTN  mCoreSp;
 UINTN         gUserPageTable;
+UINTN         mRing3CallStackTop;
+UINTN         mCoreSysCallStackTop;
 
 EFI_STATUS
 EFIAPI
@@ -162,8 +164,13 @@ ForbidSupervisorAccessToUserMemory (
 EFI_STATUS
 EFIAPI
 CallRing3 (
-  IN RING3_CALL_DATA *Data
+  IN RING3_CALL_DATA *Data,
+  IN UINTN            UserStackTop,
+  IN UINTN            SysCallStackTop
   )
 {
-  return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable);
+  mRing3CallStackTop   = UserStackTop;
+  mCoreSysCallStackTop = SysCallStackTop;
+
+  return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable);
 }
diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
index deb8ef83c0..8da430831c 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c
@@ -8,6 +8,9 @@
 #include "DxeMain.h"
 #include "SupportedProtocols.h"
 
+extern UINTN  mRing3CallStackTop;
+extern UINTN  mCoreSysCallStackTop;
+
 LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead);
 
 typedef struct {
@@ -479,6 +482,8 @@ CallBootService (
         UserDriver->CoreWrapper     = CoreArgList[Index + 1];
         UserDriver->UserSpaceDriver = UserArgList[Index + 1];
         UserDriver->UserPageTable   = gUserPageTable;
+        UserDriver->SysCallStackTop = mCoreSysCallStackTop;
+        UserDriver->UserStackTop    = mRing3CallStackTop;
 
         InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
 
diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm
index 3c26b07179..303a18360d 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm
+++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm
@@ -8,8 +8,6 @@
 #include <Register/Intel/ArchitecturalMsr.h>
 
 extern ASM_PFX(CallBootService)
-extern ASM_PFX(gCoreSysCallStackTop)
-extern ASM_PFX(gRing3CallStackTop)
 extern ASM_PFX(gRing3EntryPoint)
 
 extern ASM_PFX(AsmReadMsr64)
@@ -174,7 +172,9 @@ ASM_PFX(CoreBootServices):
 ; EFI_STATUS
 ; EFIAPI
 ; CallRing3 (
-;   IN RING3_CALL_DATA *Data
+;   IN RING3_CALL_DATA *Data,
+;   IN UINTN            UserStackTop,
+;   IN UINTN            SysCallStackTop
 ;   );
 ;
 ;   (On User Stack) Data
@@ -191,8 +191,17 @@ ASM_PFX(CallRing3):
     ; Save Core Stack pointer.
     mov     [ASM_PFX(CoreEsp)], esp
 
+    mov     ebx, [esp + 4 * 6] ; UserStackTop
+    mov     [ASM_PFX(mRing3CallStackTop)], ebx
+    mov     ebx, [esp + 4 * 7] ; SysCallStackTop
+    mov     [ASM_PFX(mCoreSysCallStackTop)], ebx
+    mov     edx, 0
+    mov     eax, ebx
+    mov     ecx, MSR_IA32_SYSENTER_ESP
+    wrmsr
+
     push dword [ASM_PFX(gRing3EntryPoint)]
-    push dword [ASM_PFX(gRing3CallStackTop)]
+    push dword [ASM_PFX(mRing3CallStackTop)]
 
     SetRing3DataSegmentSelectors
 
@@ -249,3 +258,11 @@ ASM_PFX(gUserPageTable):
 ALIGN   4096
 ASM_PFX(CoreEsp):
   resd 1
+
+global ASM_PFX(mRing3CallStackTop)
+ASM_PFX(mRing3CallStackTop):
+  resd 1
+
+global ASM_PFX(mCoreSysCallStackTop)
+ASM_PFX(mCoreSysCallStackTop):
+  resd 1
diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c
index 60a9672e47..84714cdf34 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c
@@ -153,8 +153,5 @@ InitializeMsr (
   Msr = (UINT64)(UINTN)CoreBootServices;
   AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr);
 
-  Msr = (UINT64)(UINTN)gCoreSysCallStackTop;
-  AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr);
-
   gCorePageTable = AsmReadCr3 ();
 }
diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c
index c1e6e927fc..275647f1d4 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c
@@ -9,8 +9,6 @@
 
 #include "DxeMain.h"
 
-UINTN       gCoreSysCallStackTop;
-UINTN       gRing3CallStackTop;
 VOID        *gRing3EntryPoint;
 RING3_DATA  *gRing3Data;
 VOID        *gRing3Interfaces;
diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
index b263030aad..89cdd3a70b 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
+++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c
@@ -10,11 +10,21 @@
 
 LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead);
 
+EFI_STATUS
+EFIAPI
+CallRing3 (
+  IN RING3_CALL_DATA  *Data,
+  IN UINTN            UserStackTop,
+  IN UINTN            SysCallStackTop
+  );
+
 EFI_STATUS
 EFIAPI
 GoToRing3 (
-  IN UINT8 Number,
-  IN VOID  *EntryPoint,
+  IN UINT8  Number,
+  IN VOID   *EntryPoint,
+  IN UINTN  UserStackTop,
+  IN UINTN  SysCallStackTop,
   ...
   )
 {
@@ -43,14 +53,14 @@ GoToRing3 (
   Input->NumberOfArguments = Number;
   Input->EntryPoint        = EntryPoint;
 
-  VA_START (Marker, EntryPoint);
+  VA_START (Marker, SysCallStackTop);
   for (Index = 0; Index < Number; ++Index) {
     Input->Arguments[Index] = VA_ARG (Marker, UINTN);
   }
   VA_END (Marker);
   ForbidSupervisorAccessToUserMemory ();
 
-  Status = CallRing3 (Input);
+  Status = CallRing3 (Input, UserStackTop, SysCallStackTop);
 
   CoreFreePages (Ring3Pages, PagesNumber);
 
@@ -71,6 +81,7 @@ FindUserSpaceDriver (
     UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link);
 
     if (UserDriver->CoreWrapper == CoreWrapper) {
+      gUserPageTable = UserDriver->UserPageTable;
       return UserDriver;
     }
   }
@@ -93,8 +104,7 @@ CoreDriverBindingSupported (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->Supported;
@@ -103,6 +113,8 @@ CoreDriverBindingSupported (
   Status = GoToRing3 (
              3,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              ControllerHandle,
              RemainingDevicePath
@@ -126,8 +138,7 @@ CoreDriverBindingStart (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->Start;
@@ -136,6 +147,8 @@ CoreDriverBindingStart (
   Status = GoToRing3 (
              3,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              ControllerHandle,
              RemainingDevicePath
@@ -160,8 +173,7 @@ CoreDriverBindingStop (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->Stop;
@@ -170,6 +182,8 @@ CoreDriverBindingStop (
   Status = GoToRing3 (
              4,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              ControllerHandle,
              NumberOfChildren,
@@ -193,8 +207,7 @@ CoreFileClose (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->Close;
@@ -203,10 +216,13 @@ CoreFileClose (
   Status = GoToRing3 (
              1,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This
              );
 
   FreePool (UserDriver->CoreWrapper);
+  RemoveEntryList (&UserDriver->Link);
 
   return Status;
 }
@@ -241,6 +257,13 @@ CoreFileRead (
   if ((This == NULL) || (BufferSize == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
+  //
+  // gUserPageTable must be set before alloctation of EfiRing3MemoryType pages.
+  //
+  UserDriver = FindUserSpaceDriver (This);
+  ASSERT (UserDriver != NULL);
+
+  This = UserDriver->UserSpaceDriver;
 
   Ring3Buffer = NULL;
   Ring3Pages  = 0;
@@ -258,12 +281,6 @@ CoreFileRead (
 
   Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages;
 
-  UserDriver = FindUserSpaceDriver (This);
-  ASSERT (UserDriver != NULL);
-
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
-
   AllowSupervisorAccessToUserMemory ();
   *Ring3BufferSize = *BufferSize;
   EntryPoint       = (VOID *)This->Read;
@@ -276,6 +293,8 @@ CoreFileRead (
   Status = GoToRing3 (
              3,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3BufferSize,
              Ring3Buffer
@@ -320,8 +339,7 @@ CoreFileSetPosition (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->SetPosition;
@@ -331,6 +349,8 @@ CoreFileSetPosition (
   return GoToRing3 (
            2,
            EntryPoint,
+           UserDriver->UserStackTop,
+           UserDriver->SysCallStackTop,
            This,
            Position
            );
@@ -341,17 +361,21 @@ CoreFileSetPosition (
   return GoToRing3 (
            3,
            EntryPoint,
+           UserDriver->UserStackTop,
+           UserDriver->SysCallStackTop,
            This,
            Position
            );
 #elif defined (MDE_CPU_ARM)
   //
   // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes.
-  // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High.
+  // R0 == This, R1 == NULL, R2 == Position_Low, R3 == Position_High.
   //
   return GoToRing3 (
            4,
            EntryPoint,
+           UserDriver->UserStackTop,
+           UserDriver->SysCallStackTop,
            This,
            Position
            );
@@ -376,6 +400,11 @@ CoreFileGetPosition (
     return EFI_INVALID_PARAMETER;
   }
 
+  UserDriver = FindUserSpaceDriver (This);
+  ASSERT (UserDriver != NULL);
+
+  This = UserDriver->UserSpaceDriver;
+
   Status = CoreAllocatePages (
              AllocateAnyPages,
              EfiRing3MemoryType,
@@ -386,12 +415,6 @@ CoreFileGetPosition (
     return Status;
   }
 
-  UserDriver = FindUserSpaceDriver (This);
-  ASSERT (UserDriver != NULL);
-
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
-
   AllowSupervisorAccessToUserMemory ();
   *(UINT64 *)(UINTN)Ring3Position = *Position;
   EntryPoint                      = (VOID *)This->GetPosition;
@@ -400,6 +423,8 @@ CoreFileGetPosition (
   Status = GoToRing3 (
              2,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3Position
              );
@@ -436,6 +461,11 @@ CoreFileGetInfo (
     return EFI_INVALID_PARAMETER;
   }
 
+  UserDriver = FindUserSpaceDriver (This);
+  ASSERT (UserDriver != NULL);
+
+  This = UserDriver->UserSpaceDriver;
+
   Ring3Buffer          = NULL;
   Ring3InformationType = NULL;
   Ring3Pages           = 0;
@@ -454,12 +484,6 @@ CoreFileGetInfo (
 
   Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages;
 
-  UserDriver = FindUserSpaceDriver (This);
-  ASSERT (UserDriver != NULL);
-
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
-
   AllowSupervisorAccessToUserMemory ();
   *Ring3BufferSize = *BufferSize;
   EntryPoint       = (VOID *)This->GetInfo;
@@ -480,6 +504,8 @@ CoreFileGetInfo (
   Status = GoToRing3 (
              4,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3InformationType,
              Ring3BufferSize,
@@ -588,12 +614,18 @@ CoreFileOpen (
   EFI_PHYSICAL_ADDRESS  Ring3Pages;
   UINT32                PagesNumber;
   USER_SPACE_DRIVER     *UserDriver;
+  USER_SPACE_DRIVER     *NewDriver;
   VOID                  *EntryPoint;
 
   if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
 
+  UserDriver = FindUserSpaceDriver (This);
+  ASSERT (UserDriver != NULL);
+
+  This = UserDriver->UserSpaceDriver;
+
   Ring3NewHandle = NULL;
   Ring3FileName  = NULL;
   Ring3Pages     = 0;
@@ -614,12 +646,6 @@ CoreFileOpen (
   Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages;
   Ring3FileName  = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1);
 
-  UserDriver = FindUserSpaceDriver (This);
-  ASSERT (UserDriver != NULL);
-
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
-
   AllowSupervisorAccessToUserMemory ();
   Status     = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName);
   EntryPoint = (VOID *)This->Open;
@@ -634,6 +660,8 @@ CoreFileOpen (
   Status = GoToRing3 (
              5,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3NewHandle,
              Ring3FileName,
@@ -647,6 +675,8 @@ CoreFileOpen (
   Status = GoToRing3 (
              7,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3NewHandle,
              Ring3FileName,
@@ -657,12 +687,14 @@ CoreFileOpen (
   //
   // UINT64 OpenMode and Attributes are each passed as 2 words on stack.
   // Each of them is aligned on 8 bytes.
-  // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL,
+  // R0 == This, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL,
   // [SP] == OpenMode, [SP + 8] == Attributes.
   //
   Status = GoToRing3 (
              8,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3NewHandle,
              Ring3FileName,
@@ -683,16 +715,22 @@ CoreFileOpen (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UserDriver                = AllocatePool (sizeof (USER_SPACE_DRIVER));
-  UserDriver->CoreWrapper   = NewFile;
-  UserDriver->UserPageTable = gUserPageTable;
+  NewDriver                  = AllocatePool (sizeof (USER_SPACE_DRIVER));
+  NewDriver->CoreWrapper     = NewFile;
+  NewDriver->UserPageTable   = UserDriver->UserPageTable;
+  //
+  // TODO: Allocate new stacks, because UserDriver can be interrupted
+  // and interrupt handler may call the same UserDriver again.
+  //
+  NewDriver->UserStackTop    = UserDriver->UserStackTop;
+  NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
 
   AllowSupervisorAccessToUserMemory ();
-  UserDriver->UserSpaceDriver = *Ring3NewHandle;
-  NewFile->Revision           = (*Ring3NewHandle)->Revision;
+  NewDriver->UserSpaceDriver = *Ring3NewHandle;
+  NewFile->Revision          = (*Ring3NewHandle)->Revision;
   ForbidSupervisorAccessToUserMemory ();
 
-  InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
+  InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link);
 
   NewFile->Open        = CoreFileOpen;
   NewFile->Close       = CoreFileClose;
@@ -728,6 +766,7 @@ CoreOpenVolume (
   EFI_FILE_PROTOCOL     *File;
   EFI_PHYSICAL_ADDRESS  Physical;
   USER_SPACE_DRIVER     *UserDriver;
+  USER_SPACE_DRIVER     *NewDriver;
   VOID                  *EntryPoint;
 
   if (Root == NULL) {
@@ -737,8 +776,7 @@ CoreOpenVolume (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   AllowSupervisorAccessToUserMemory ();
   EntryPoint = (VOID *)This->OpenVolume;
@@ -760,6 +798,8 @@ CoreOpenVolume (
   Status = GoToRing3 (
              2,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              Ring3Root
              );
@@ -776,16 +816,18 @@ CoreOpenVolume (
     return EFI_OUT_OF_RESOURCES;
   }
 
-  UserDriver                = AllocatePool (sizeof (USER_SPACE_DRIVER));
-  UserDriver->CoreWrapper   = File;
-  UserDriver->UserPageTable = gUserPageTable;
+  NewDriver                  = AllocatePool (sizeof (USER_SPACE_DRIVER));
+  NewDriver->CoreWrapper     = File;
+  NewDriver->UserPageTable   = UserDriver->UserPageTable;
+  NewDriver->UserStackTop    = UserDriver->UserStackTop;
+  NewDriver->SysCallStackTop = UserDriver->SysCallStackTop;
 
   AllowSupervisorAccessToUserMemory ();
-  UserDriver->UserSpaceDriver = *Ring3Root;
-  File->Revision              = (*Ring3Root)->Revision;
+  NewDriver->UserSpaceDriver = *Ring3Root;
+  File->Revision             = (*Ring3Root)->Revision;
   ForbidSupervisorAccessToUserMemory ();
 
-  InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link);
+  InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link);
 
   File->Open        = CoreFileOpen;
   File->Close       = CoreFileClose;
@@ -827,8 +869,7 @@ CoreUnicodeCollationStriColl (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Size1 = StrSize (Str1);
   Size2 = StrSize (Str2);
@@ -852,6 +893,8 @@ CoreUnicodeCollationStriColl (
   Status = GoToRing3 (
              3,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              (UINTN)UserMem,
              (UINTN)UserMem + Size1
@@ -880,8 +923,7 @@ CoreUnicodeCollationMetaiMatch (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Size1 = StrSize (String);
   Size2 = StrSize (Pattern);
@@ -905,6 +947,8 @@ CoreUnicodeCollationMetaiMatch (
   Status = GoToRing3 (
              3,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              (UINTN)UserMem,
              (UINTN)UserMem + Size1
@@ -931,8 +975,7 @@ CoreUnicodeCollationStrLwr (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Size1 = StrSize (Str);
 
@@ -954,6 +997,8 @@ CoreUnicodeCollationStrLwr (
   Status = GoToRing3 (
              2,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              (UINTN)UserMem
              );
@@ -981,8 +1026,7 @@ CoreUnicodeCollationStrUpr (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Size1 = StrSize (Str);
 
@@ -1004,6 +1048,8 @@ CoreUnicodeCollationStrUpr (
   Status = GoToRing3 (
              2,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              (UINTN)UserMem
              );
@@ -1032,8 +1078,7 @@ CoreUnicodeCollationFatToStr (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Status = CoreAllocatePages (
              AllocateAnyPages,
@@ -1053,6 +1098,8 @@ CoreUnicodeCollationFatToStr (
   Status = GoToRing3 (
              4,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              FatSize,
              (UINTN)UserMem,
@@ -1084,8 +1131,7 @@ CoreUnicodeCollationStrToFat (
   UserDriver = FindUserSpaceDriver (This);
   ASSERT (UserDriver != NULL);
 
-  This           = UserDriver->UserSpaceDriver;
-  gUserPageTable = UserDriver->UserPageTable;
+  This = UserDriver->UserSpaceDriver;
 
   Size1 = StrSize (String);
 
@@ -1107,6 +1153,8 @@ CoreUnicodeCollationStrToFat (
   Status = GoToRing3 (
              4,
              EntryPoint,
+             UserDriver->UserStackTop,
+             UserDriver->SysCallStackTop,
              This,
              (UINTN)UserMem,
              FatSize,
diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
index 4507db4a89..b3f8ba397f 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
+++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h
@@ -15,6 +15,8 @@ typedef struct {
   VOID        *CoreWrapper;
   VOID        *UserSpaceDriver;
   UINTN       UserPageTable;
+  UINTN       UserStackTop;
+  UINTN       SysCallStackTop;
   LIST_ENTRY  Link;
 } USER_SPACE_DRIVER;
 
diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm
index 6d079ee860..349708f761 100644
--- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm
+++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm
@@ -8,8 +8,6 @@
 #include <Register/Intel/ArchitecturalMsr.h>
 
 extern ASM_PFX(CallBootService)
-extern ASM_PFX(gCoreSysCallStackTop)
-extern ASM_PFX(gRing3CallStackTop)
 extern ASM_PFX(gRing3EntryPoint)
 
 DEFAULT REL
@@ -140,7 +138,7 @@ ASM_PFX(CoreBootServices):
     mov     gs, ax
 
     ; Save User Stack pointers and switch to Core SysCall Stack.
-    mov     rax, [ASM_PFX(gCoreSysCallStackTop)]
+    mov     rax, [ASM_PFX(mCoreSysCallStackTop)]
     sub     rax, 8
     mov     [rax], rsp
     mov     rsp, rax
@@ -192,10 +190,14 @@ o64 sysret
 ; EFI_STATUS
 ; EFIAPI
 ; CallRing3 (
-;   IN RING3_CALL_DATA *Data
+;   IN RING3_CALL_DATA *Data,
+;   IN UINTN            UserStackTop,
+;   IN UINTN            SysCallStackTop
 ;   );
 ;
 ;   (rcx) Data
+;   (rdx) UserStackTop
+;   (r8)  SysCallStackTop
 ;------------------------------------------------------------------------------
 global ASM_PFX(CallRing3)
 ASM_PFX(CallRing3):
@@ -216,7 +218,9 @@ ASM_PFX(CallRing3):
     mov     [ASM_PFX(CoreRsp)], rsp
 
     ; Save input Arguments.
-    mov     r8, [ASM_PFX(gRing3CallStackTop)]
+    mov     [ASM_PFX(mRing3CallStackTop)], rdx
+    mov     [ASM_PFX(mCoreSysCallStackTop)], r8
+    mov     r8, [ASM_PFX(mRing3CallStackTop)]
     mov     r9, [ASM_PFX(gRing3EntryPoint)]
     mov     r10, rcx
 
@@ -276,3 +280,11 @@ ASM_PFX(gUserPageTable):
 ALIGN   4096
 ASM_PFX(CoreRsp):
   resq 1
+
+global ASM_PFX(mRing3CallStackTop)
+ASM_PFX(mRing3CallStackTop):
+  resq 1
+
+global ASM_PFX(mCoreSysCallStackTop)
+ASM_PFX(mCoreSysCallStackTop):
+  resq 1
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index b2a176f324..768a7dd1a8 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -265,7 +265,7 @@ INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
 INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
 INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
 INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
-INF USER  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
 INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
@@ -291,7 +291,7 @@ INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
 
-INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF USER FatPkg/EnhancedFatDxe/Fat.inf
 INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
 INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
 INF  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 07c817a87c..42b7b1a45e 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -266,7 +266,7 @@ INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
 INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
 INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
 INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
-INF USER  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
 INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
@@ -292,7 +292,7 @@ INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
 
-INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF USER FatPkg/EnhancedFatDxe/Fat.inf
 INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
 INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
 INF  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 42a15d5596..1c243ee618 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -295,7 +295,7 @@ INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
 INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
 INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
 INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
-INF USER  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
 INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
 INF  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
@@ -321,7 +321,7 @@ INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
 INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf
 
-INF  FatPkg/EnhancedFatDxe/Fat.inf
+INF USER FatPkg/EnhancedFatDxe/Fat.inf
 INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf
 INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf
 INF  OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf