diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index b4ad1f5629..b9da62843c 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -216,6 +216,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 e8b0bbb847..616d8ae25f 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1156,6 +1156,12 @@
# @Prompt Delay access XHCI register after it issues HCRST (us)
gEfiMdeModulePkgTokenSpaceGuid.PcdDelayXhciHCReset|2000|UINT16|0x30001060
+ ## 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|0x30001061
+
[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 e704a4699f..40c5612650 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -622,6 +622,7 @@
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
#
# Firmware volume supports UE, and may require PE.