diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index ac0b0f84dc..76c9618e7a 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -217,6 +217,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageLargeAddressLoad ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
index 1652a59c68..929602305c 100644
--- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
+++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c
@@ -236,14 +236,19 @@ ProtectUefiImage (
//
// CPU ARCH present. Update memory attribute directly.
//
- if (AsciiStrStr (PdbPointer, "Fat") != NULL) {
- SetUefiImageProtectionAttributes (ImageRecord, TRUE);
- *IsUserImage = TRUE;
- } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) {
- SetUefiImageProtectionAttributes (ImageRecord, TRUE);
- *IsUserImage = TRUE;
- *IsRing3EntryPoint = TRUE;
- } else {
+ if (PcdGetBool (PcdEnableUserSpace)) {
+ if (AsciiStrStr (PdbPointer, "Fat") != NULL) {
+ SetUefiImageProtectionAttributes (ImageRecord, TRUE);
+ *IsUserImage = TRUE;
+ } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) {
+ SetUefiImageProtectionAttributes (ImageRecord, TRUE);
+ *IsUserImage = TRUE;
+ *IsRing3EntryPoint = TRUE;
+ } else {
+ SetUefiImageProtectionAttributes (ImageRecord, FALSE);
+ *IsUserImage = FALSE;
+ }
+ } else {
SetUefiImageProtectionAttributes (ImageRecord, FALSE);
*IsUserImage = FALSE;
}
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index f51dc7c9a1..335a0d86c9 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1204,6 +1204,12 @@
# @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB).
gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061
+ ## Indicates whether some DXE drivers will be loaded in user memory.
+ # TRUE - Some DXE drivers will be loaded in user memory.
+ # FALSE - All DXE drivers will be loaded in supervisor memory.
+ # @Prompt Enable User Space.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001062
+
[PcdsFixedAtBuild, PcdsPatchableInModule]
## Dynamic type PCD can be registered callback function for Pcd setting action.
# PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 3ce9d08828..a20e45a908 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -628,6 +628,7 @@
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
#
# Firmware volume supports UE, and may require PE.