* and if so, populate the supplied memory descriptor with the appropriate
  * data.
  */
-int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
+int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
 {
        efi_memory_desc_t *md;
 
        return -ENOENT;
 }
 
+extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
+       __weak __alias(__efi_mem_desc_lookup);
+
 /*
  * Calculate the highest address of an efi memory descriptor.
  */
 
 
 #include <xen/interface/xen.h>
 #include <xen/interface/platform.h>
+#include <xen/page.h>
 #include <xen/xen.h>
 #include <xen/xen-ops.h>
 
        efi.get_next_high_mono_count    = xen_efi_get_next_high_mono_count;
        efi.reset_system                = xen_efi_reset_system;
 }
+
+int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
+{
+       static_assert(XEN_PAGE_SHIFT == EFI_PAGE_SHIFT,
+                     "Mismatch between EFI_PAGE_SHIFT and XEN_PAGE_SHIFT");
+       struct xen_platform_op op;
+       union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info;
+       int rc;
+
+       if (!efi_enabled(EFI_PARAVIRT) || efi_enabled(EFI_MEMMAP))
+               return __efi_mem_desc_lookup(phys_addr, out_md);
+       phys_addr &= ~(u64)(EFI_PAGE_SIZE - 1);
+       op = (struct xen_platform_op) {
+               .cmd = XENPF_firmware_info,
+               .u.firmware_info = {
+                       .type = XEN_FW_EFI_INFO,
+                       .index = XEN_FW_EFI_MEM_INFO,
+                       .u.efi_info.mem.addr = phys_addr,
+                       .u.efi_info.mem.size = U64_MAX - phys_addr,
+               },
+       };
+
+       rc = HYPERVISOR_platform_op(&op);
+       if (rc) {
+               pr_warn("Failed to lookup header 0x%llx in Xen memory map: error %d\n",
+                       phys_addr, rc);
+       }
+
+       out_md->phys_addr       = info->mem.addr;
+       out_md->num_pages       = info->mem.size >> EFI_PAGE_SHIFT;
+       out_md->type            = info->mem.type;
+       out_md->attribute       = info->mem.attr;
+
+       return 0;
+}
 
 extern int __init efi_uart_console_only (void);
 extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
 extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
+extern int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
 extern void efi_mem_reserve(phys_addr_t addr, u64 size);
 extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
 extern void efi_initialize_iomem_resources(struct resource *code_resource,