@@ -1040,6 +1040,50 @@ static int xc_dom_build_ramdisk(struct xc_dom_image *dom)
return -1;
}
+static int xc_dom_load_acpi(struct xc_dom_image *dom)
+{
+ int rc, i;
+ uint32_t pages_num = ROUNDUP(dom->acpitable_size, XC_PAGE_SHIFT) >>
+ XC_PAGE_SHIFT;
+ const xen_pfn_t base = GUEST_ACPI_BASE >> XC_PAGE_SHIFT;
+ xen_pfn_t *p2m;
+ void *acpi_pages;
+
+ p2m = malloc(pages_num * sizeof(*p2m));
+ if ( !p2m )
+ return -1;
+
+ for (i = 0; i < pages_num; i++)
+ p2m[i] = base + i;
+
+ rc = xc_domain_populate_physmap_exact(dom->xch, dom->guest_domid,
+ pages_num, 0, 0, p2m);
+ if ( rc )
+ {
+ DOMPRINTF("%s: xc_domain_populate_physmap_exact failed with %d",
+ __FUNCTION__, rc);
+ goto out;
+ }
+
+ acpi_pages = xc_map_foreign_range(dom->xch, dom->guest_domid,
+ PAGE_SIZE * pages_num,
+ PROT_READ | PROT_WRITE, base);
+ if ( !acpi_pages )
+ {
+ DOMPRINTF("%s Can't map acpi_pages", __FUNCTION__);
+ rc = -1;
+ goto out;
+ }
+
+ memcpy(acpi_pages, dom->acpitable_blob, dom->acpitable_size);
+
+out:
+ munmap(acpi_pages, pages_num * PAGE_SIZE);
+ free(p2m);
+
+ return rc;
+}
+
int xc_dom_build_image(struct xc_dom_image *dom)
{
unsigned int page_size;
@@ -1097,6 +1141,13 @@ int xc_dom_build_image(struct xc_dom_image *dom)
memcpy(devicetreemap, dom->devicetree_blob, dom->devicetree_size);
}
+ /* load ACPI tables */
+ if ( dom->acpitable_blob && dom->acpitable_size > 0 )
+ {
+ if ( xc_dom_load_acpi(dom) != 0 )
+ goto err;
+ }
+
/* allocate other pages */
if ( !dom->arch_hooks->p2m_base_supported ||
dom->parms.p2m_base >= dom->parms.virt_base ||