diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index e719a168f8..5e07b37279 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -195,6 +195,7 @@ [LibraryClasses]
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
   XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
   XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf
+  XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
 
   Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf
   TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
@@ -583,6 +584,7 @@ [Components]
       NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
 !endif
   }
+  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
   OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/OvmfXen.fdf b/OvmfPkg/OvmfXen.fdf
index 5c1a925d6a..517a492f14 100644
--- a/OvmfPkg/OvmfXen.fdf
+++ b/OvmfPkg/OvmfXen.fdf
@@ -309,6 +309,7 @@ [FV.DXEFV]
 INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
 
+INF  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
 INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
 INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
 INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
new file mode 100644
index 0000000000..5740df6e59
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
@@ -0,0 +1,35 @@
+## @file
+#  Driver for the XenIo protocol
+#
+#  Copyright (c) 2019, Citrix Systems, Inc.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = XenIoPvhDxe
+  FILE_GUID                 = 7a567cc4-0e75-4d7a-a305-c3db109b53ad
+  MODULE_TYPE               = DXE_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = InitializeXenIoPvhDxe
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Sources]
+  XenIoPvhDxe.c
+
+[LibraryClasses]
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  XenIoMmioLib
+  XenPlatformLib
+
+[FixedPcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdXenGrantFrames
+
+[Depex]
+  TRUE
diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
new file mode 100644
index 0000000000..e5699cdd80
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
@@ -0,0 +1,53 @@
+/** @file
+
+  Driver for the XenIo protocol
+
+  This driver simply allocate space for the grant tables.
+
+  Copyright (c) 2019, Citrix Systems, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/XenIoMmioLib.h>
+#include <Library/XenPlatformLib.h>
+
+EFI_STATUS
+EFIAPI
+InitializeXenIoPvhDxe (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  VOID          *Allocation;
+  EFI_STATUS    Status;
+  EFI_HANDLE    XenIoHandle;
+
+  Allocation = NULL;
+  XenIoHandle = NULL;
+
+  if (!XenPvhDetected ()) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Allocation = AllocateReservedPages (FixedPcdGet32 (PcdXenGrantFrames));
+  if (Allocation == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Error;
+  }
+
+  Status = XenIoMmioInstall (&XenIoHandle, (UINTN) Allocation);
+  if (EFI_ERROR (Status)) {
+    goto Error;
+  }
+
+  return EFI_SUCCESS;
+
+Error:
+  if (Allocation != NULL) {
+    FreePages (Allocation, FixedPcdGet32 (PcdXenGrantFrames));
+  }
+  return Status;
+}
diff --git a/Maintainers.txt b/Maintainers.txt
index 78e9f889ab..79defd13bf 100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -382,6 +382,7 @@ F: OvmfPkg/PlatformPei/Xen.*
 F: OvmfPkg/SmbiosPlatformDxe/*Xen.c
 F: OvmfPkg/XenBusDxe/
 F: OvmfPkg/XenIoPciDxe/
+F: OvmfPkg/XenIoPvhDxe/
 F: OvmfPkg/XenPlatformPei/
 F: OvmfPkg/XenPvBlkDxe/
 F: OvmfPkg/XenResetVector/
