@@ -1078,7 +1078,16 @@ static int __init pvh_setup_acpi_xsdt(struct domain *d, paddr_t madt_addr,
rc = -EINVAL;
goto out;
}
- xsdt_paddr = rsdp->xsdt_physical_address;
+ /*
+ * Note the header is the same for both RSDT and XSDT, so it's fine to
+ * copy the native RSDT header to the Xen crafted XSDT if no native
+ * XSDT is available.
+ */
+ if ( rsdp->revision > 1 && rsdp->xsdt_physical_address )
+ xsdt_paddr = rsdp->xsdt_physical_address;
+ else
+ xsdt_paddr = rsdp->rsdt_physical_address;
+
acpi_os_unmap_memory(rsdp, sizeof(*rsdp));
table = acpi_os_map_memory(xsdt_paddr, sizeof(*table));
if ( !table )
@@ -1090,6 +1099,12 @@ static int __init pvh_setup_acpi_xsdt(struct domain *d, paddr_t madt_addr,
xsdt->header = *table;
acpi_os_unmap_memory(table, sizeof(*table));
+ /*
+ * In case the header is an RSDT copy, unconditionally ensure it has
+ * an XSDT sig.
+ */
+ xsdt->header.signature[0] = 'X';
+
/* Add the custom MADT. */
xsdt->table_offset_entry[0] = madt_addr;