From patchwork Tue Jul 5 19:05:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Ostrovsky X-Patchwork-Id: 9215143 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DA28960752 for ; Tue, 5 Jul 2016 19:14:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CB49328333 for ; Tue, 5 Jul 2016 19:14:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF5B528338; Tue, 5 Jul 2016 19:14:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BB7D928333 for ; Tue, 5 Jul 2016 19:14:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKVl5-0004AL-9V; Tue, 05 Jul 2016 19:11:47 +0000 Received: from mail6.bemta6.messagelabs.com ([85.158.143.247]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKVl3-00046Q-J9 for xen-devel@lists.xen.org; Tue, 05 Jul 2016 19:11:45 +0000 Received: from [85.158.143.35] by server-1.bemta-6.messagelabs.com id 72/44-09256-1760C775; Tue, 05 Jul 2016 19:11:45 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrNLMWRWlGSWpSXmKPExsXSO6nOVTePrSb coOufosWSj4tZHBg9ju7+zRTAGMWamZeUX5HAmvFruXxB+yTGikvLRBsYN+d2MXJxCAm0M0ms uXOAFcL5yihxY+M1NghnA6PE0x2XoJweRokHU++xdzFycrAJGEmcPTqdEcQWEZCWuPb5MiNIE bPALUaJ7b/vMIMkhAW8JB7//cfSxcjBwSKgKnForjJImBcoPH/BCbASCQE5iR2rnzCB2JxA8f WNr1hAbCEBT4lNT86yQ9QYS/TN6mOZwMi3gJFhFaN6cWpRWWqRrqFeUlFmekZJbmJmjq6hgZl ebmpxcWJ6ak5iUrFecn7uJkZgoDAAwQ7Gnc+dDjFKcjApifKyfKsOF+JLyk+pzEgszogvKs1J LT7EKMPBoSTBW85aEy4kWJSanlqRlpkDDFmYtAQHj5IIbzdImre4IDG3ODMdInWKUVFKnLcZJ CEAksgozYNrg8XJJUZZKWFeRqBDhHgKUotyM0tQ5V8xinMwKgnzpoFM4cnMK4Gb/gpoMRPQ4p 8u1SCLSxIRUlINjIa6F8wfLb128F96nvBj//ytWnuZy868+1re9EUt52H4Qm62k9r/bn+9YvU kJorp42KjWacm7rzxLUhBiG1jBMdLszC3KadWHzL5uu2RvJroIY8/n32uBNjdSftZu2/G62k7 mbqPBc9QXfHyQ8upcLuaaWavlcycYiL7mz2WLfoiay68IOvivU1KLMUZiYZazEXFiQBW+UVTj gIAAA== X-Env-Sender: boris.ostrovsky@oracle.com X-Msg-Ref: server-9.tower-21.messagelabs.com!1467745901!22391700!1 X-Originating-IP: [141.146.126.69] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTQxLjE0Ni4xMjYuNjkgPT4gMjc3MjE4\n X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 16330 invoked from network); 5 Jul 2016 19:11:42 -0000 Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by server-9.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 5 Jul 2016 19:11:42 -0000 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u65JBViZ009159 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 5 Jul 2016 19:11:31 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id u65JBV5H001206 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 5 Jul 2016 19:11:31 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u65JBUGF004812; Tue, 5 Jul 2016 19:11:30 GMT Received: from ovs104.us.oracle.com (/10.149.76.204) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 05 Jul 2016 19:11:30 +0000 From: Boris Ostrovsky To: xen-devel@lists.xen.org Date: Tue, 5 Jul 2016 15:05:19 -0400 Message-Id: <1467745519-9868-21-git-send-email-boris.ostrovsky@oracle.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1467745519-9868-1-git-send-email-boris.ostrovsky@oracle.com> References: <1467745519-9868-1-git-send-email-boris.ostrovsky@oracle.com> X-Source-IP: aserv0021.oracle.com [141.146.126.233] Cc: wei.liu2@citrix.com, andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com, julien.grall@arm.com, jbeulich@suse.com, zhaoshenglong@huawei.com, boris.ostrovsky@oracle.com, roger.pau@citrix.com Subject: [Xen-devel] [PATCH v1 20/20] libxl/acpi: Build ACPI tables for HVMlite guests X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Boris Ostrovsky --- Changes in v1: * Move to libxl * Added populate_acpi_pages() * Stash location/size of tables in xc_dom_image (to be used in constructing e820 map) * Use libxl allocator * Only set XEN_X86_EMU_LAPIC flag if 'apic' option is set. * Make acpi_build_tables() return error code .gitignore | 4 + tools/libacpi/build.c | 7 +- tools/libacpi/libacpi.h | 15 ++- tools/libxl/Makefile | 17 +++- tools/libxl/libxl_arch.h | 3 + tools/libxl/libxl_dom.c | 1 + tools/libxl/libxl_x86.c | 29 +++-- tools/libxl/libxl_x86_acpi.c | 292 ++++++++++++++++++++++++++++++++++++++++++ tools/libxl/libxl_x86_acpi.h | 21 +++ 9 files changed, 373 insertions(+), 16 deletions(-) create mode 100644 tools/libxl/libxl_x86_acpi.c create mode 100644 tools/libxl/libxl_x86_acpi.h diff --git a/.gitignore b/.gitignore index 9dd2086..d4da37f 100644 --- a/.gitignore +++ b/.gitignore @@ -179,6 +179,10 @@ tools/libxl/testenum.c tools/libxl/tmp.* tools/libxl/_libxl.api-for-check tools/libxl/*.api-ok +tools/libxl/mk_dsdt +tools/libxl/dsdt*.c +tools/libxl/dsdt_*.asl +tools/libxl/ssdt_*.h tools/misc/cpuperf/cpuperf-perfcntr tools/misc/cpuperf/cpuperf-xen tools/misc/xc_shadow diff --git a/tools/libacpi/build.c b/tools/libacpi/build.c index 290f005..a6ddf53 100644 --- a/tools/libacpi/build.c +++ b/tools/libacpi/build.c @@ -23,6 +23,7 @@ #include "ssdt_tpm.h" #include "ssdt_pm.h" #include "x86.h" +#include #include #include @@ -473,7 +474,7 @@ static int new_vm_gid(struct acpi_ctxt *ctxt, return 1; } -void acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) +int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) { struct acpi_20_rsdp *rsdp; struct acpi_20_rsdt *rsdt; @@ -594,11 +595,11 @@ void acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) *(struct acpi_info *)config->ainfop = config->ainfo; - return; + return 0; oom: printf("unable to build ACPI tables: out of memory\n"); - + return -1; } /* diff --git a/tools/libacpi/libacpi.h b/tools/libacpi/libacpi.h index 87a2937..791ebac 100644 --- a/tools/libacpi/libacpi.h +++ b/tools/libacpi/libacpi.h @@ -69,6 +69,15 @@ struct acpi_ctxt { void *(*alloc)(struct acpi_ctxt *ctxt, uint32_t size, uint32_t align); unsigned long (*v2p)(struct acpi_ctxt *ctxt, void *v); } mem_ops; + + unsigned int page_size; + unsigned int page_shift; + + /* Memory allocator */ + unsigned long alloc_base_paddr; + unsigned long alloc_base_vaddr; + unsigned long alloc_currp; + unsigned long alloc_end; }; struct acpi_config { @@ -98,13 +107,13 @@ struct acpi_config { * This must match the OperationRegion(BIOS, SystemMemory, ....) * definition in the DSDT */ - unsigned int ainfop; + unsigned long ainfop; /* RSDP address */ - unsigned int rsdp; + unsigned long rsdp; }; -void acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config); +int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config); #endif /* __LIBACPI_H__ */ diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 3a2d64a..18be2e7 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -75,7 +75,20 @@ else LIBXL_OBJS-y += libxl_no_colo.o endif -LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o libxl_psr.o +ACPI_PATH = $(XEN_ROOT)/tools/libacpi +ACPI_FILES = dsdt_pvh.c build.c static_tables.c +ACPI_OBJS = $(patsubst %.c,%.o,$(ACPI_FILES)) +$(ACPI_FILES): acpi +$(ACPI_OBJS): CFLAGS += -I. -DSTDUTILS=\"$(CURDIR)/libxl_x86_acpi.h\" +vpath build.c $(ACPI_PATH)/ +vpath static_tables.c $(ACPI_PATH)/ +LIBXL_OBJS-$(CONFIG_X86) += $(ACPI_OBJS) + +.PHONY: acpi +acpi: + $(MAKE) -C $(ACPI_PATH) ACPI_BUILD_DIR=$(shell pwd) + +LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o libxl_psr.o libxl_x86_acpi.o LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o libxl_arm.o libxl_libfdt_compat.o ifeq ($(CONFIG_NetBSD),y) @@ -166,6 +179,7 @@ $(XL_OBJS): CFLAGS += $(CFLAGS_XL) $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs it. libxl_dom.o: CFLAGS += -I$(XEN_ROOT)/tools # include libacpi/x86.h +libxl_x86_acpi.o: CFLAGS += -I$(XEN_ROOT)/tools SAVE_HELPER_OBJS = libxl_save_helper.o _libxl_save_msgs_helper.o $(SAVE_HELPER_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) @@ -308,6 +322,7 @@ clean: $(RM) -f testidl.c.new testidl.c *.api-ok $(RM) -f xenlight.pc $(RM) -f xlutil.pc + $(MAKE) -C $(ACPI_PATH) ACPI_BUILD_DIR=$(shell pwd) clean distclean: clean $(RM) -f xenlight.pc.in xlutil.pc.in diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h index 34a853c..7c6536b 100644 --- a/tools/libxl/libxl_arch.h +++ b/tools/libxl/libxl_arch.h @@ -62,4 +62,7 @@ int libxl__arch_domain_construct_memmap(libxl__gc *gc, uint32_t domid, struct xc_dom_image *dom); +int libxl__dom_load_acpi(libxl__gc *gc, + libxl_domain_build_info *info, + struct xc_dom_image *dom); #endif diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index ba3472e..7e4e289 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -657,6 +657,7 @@ static int libxl__build_dom(libxl__gc *gc, uint32_t domid, LOGE(ERROR, "xc_dom_build_image failed"); goto out; } + if ( (ret = xc_dom_boot_image(dom)) != 0 ) { LOGE(ERROR, "xc_dom_boot_image failed"); goto out; diff --git a/tools/libxl/libxl_x86.c b/tools/libxl/libxl_x86.c index 32ce1d2..7201dbb 100644 --- a/tools/libxl/libxl_x86.c +++ b/tools/libxl/libxl_x86.c @@ -8,15 +8,18 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, xc_domain_configuration_t *xc_config) { - if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM && - d_config->b_info.device_model_version != - LIBXL_DEVICE_MODEL_VERSION_NONE) { - /* HVM domains with a device model. */ - xc_config->emulation_flags = XEN_X86_EMU_ALL; - } else { - /* PV or HVM domains without a device model. */ + if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) { + if (d_config->b_info.device_model_version != + LIBXL_DEVICE_MODEL_VERSION_NONE) + xc_config->emulation_flags = XEN_X86_EMU_ALL; + else if (libxl_defbool_val(d_config->b_info.u.hvm.apic)) + /* + * HVM guests without device model may want + * to have LAPIC emulation. + */ + xc_config->emulation_flags = XEN_X86_EMU_LAPIC; + } else xc_config->emulation_flags = 0; - } return 0; } @@ -366,7 +369,15 @@ int libxl__arch_domain_finalise_hw_description(libxl__gc *gc, libxl_domain_build_info *info, struct xc_dom_image *dom) { - return 0; + int ret = 0; + + if ((info->type == LIBXL_DOMAIN_TYPE_HVM) && + (info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE)) { + if ( (ret = libxl__dom_load_acpi(gc, info, dom)) != 0 ) + LOGE(ERROR, "libxl_dom_load_acpi failed"); + } + + return ret; } /* Return 0 on success, ERROR_* on failure. */ diff --git a/tools/libxl/libxl_x86_acpi.c b/tools/libxl/libxl_x86_acpi.c new file mode 100644 index 0000000..144f063 --- /dev/null +++ b/tools/libxl/libxl_x86_acpi.c @@ -0,0 +1,292 @@ +/****************************************************************************** + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + */ + +#include "libxl_internal.h" +#include "libxl_arch.h" +#include +#include +#include "libacpi/libacpi.h" + +#include + +#define NUM_ACPI_PAGES 16 /* Number of pages holding ACPI tables */ +#define RSDP_ADDRESS (0xffffful - 64) /* Last doubleword of BIOS RO memory */ +#define ACPI_INFO_PHYSICAL_ADDRESS 0xfc000000 + +extern const unsigned char dsdt_pvh[]; +extern const unsigned int dsdt_pvh_len; + +/* Assumes contiguous physical space */ +static unsigned long virt_to_phys(struct acpi_ctxt *ctxt, void *v) +{ + return (((unsigned long)v - ctxt->alloc_base_vaddr) + + ctxt->alloc_base_paddr); +} + +static void *mem_alloc(struct acpi_ctxt *ctxt, uint32_t size, uint32_t align) +{ + unsigned long s, e; + + /* Align to at least 16 bytes. */ + if (align < 16) + align = 16; + + s = (ctxt->alloc_currp + align) & ~((unsigned long)align - 1); + e = s + size - 1; + + /* TODO: Reallocate memory */ + if ((e < s) || (e >= ctxt->alloc_end)) return NULL; + + while (ctxt->alloc_currp >> ctxt->page_shift != + e >> ctxt->page_shift) + ctxt->alloc_currp += ctxt->page_size; + + ctxt->alloc_currp = e; + + return (void *)s; +} + +static int init_acpi_config(libxl__gc *gc, + struct xc_dom_image *dom, + libxl_domain_build_info *b_info, + struct acpi_config *config) +{ + xc_interface *xch = dom->xch; + uint32_t domid = dom->guest_domid; + xc_dominfo_t info; + int i, rc; + + config->dsdt_anycpu = config->dsdt_15cpu = dsdt_pvh; + config->dsdt_anycpu_len = config->dsdt_15cpu_len = dsdt_pvh_len; + + rc = xc_domain_getinfo(xch, domid, 1, &info); + if (rc < 0) { + LOG(ERROR, "%s: getdomaininfo failed (rc=%d)", __FUNCTION__, rc); + return rc; + } + + config->hvminfo = libxl__zalloc(gc, sizeof(*config->hvminfo)); + + config->hvminfo->apic_mode = libxl_defbool_val(b_info->u.hvm.apic); + + if (dom->nr_vnodes) { + struct acpi_numa *numa = &config->numa; + + rc = xc_domain_getvnuma(xch, domid, &numa->nr_vnodes, + &numa->nr_vmemranges, + &config->hvminfo->nr_vcpus, NULL, NULL, NULL); + if (rc) { + LOG(ERROR, "%s: xc_domain_getvnuma failed (rc=%d)", + __FUNCTION__, rc); + return rc; + } + + numa->vmemrange = libxl__zalloc(gc, dom->nr_vmemranges * + sizeof(*numa->vmemrange)); + numa->vdistance = libxl__zalloc(gc, dom->nr_vnodes * + sizeof(*numa->vdistance)); + numa->vcpu_to_vnode = libxl__zalloc(gc, config->hvminfo->nr_vcpus * + sizeof(*numa->vcpu_to_vnode)); + rc = xc_domain_getvnuma(xch, domid, &numa->nr_vnodes, + &numa->nr_vmemranges, + &config->hvminfo->nr_vcpus, numa->vmemrange, + numa->vdistance, numa->vcpu_to_vnode); + if (rc) { + LOG(ERROR, "%s: xc_domain_getvnuma failed (rc=%d)", + __FUNCTION__, rc); + return rc; + } + } + else + config->hvminfo->nr_vcpus = info.max_vcpu_id + 1; + + for (i=0; ihvminfo->nr_vcpus; i++) + config->hvminfo->vcpu_online[i / 8] |= 1 << (i & 7); + + return 0; +} + +static int populate_acpi_pages(struct xc_dom_image *dom, + xen_pfn_t *extents, + unsigned int num_pages, + struct acpi_ctxt *ctxt) +{ + int rc; + xc_interface *xch = dom->xch; + uint32_t domid = dom->guest_domid; + unsigned long idx, first_high_idx = (1ull << (32 - ctxt->page_shift)); + + for (; num_pages; num_pages--, extents++) { + + if (xc_domain_populate_physmap(xch, domid, 1, 0, 0, extents) == 1) + continue; + + if (dom->highmem_end) { + idx = --dom->highmem_end; + if ( idx == first_high_idx ) + dom->highmem_end = 0; + } else + idx = --dom->lowmem_end; + + rc = xc_domain_add_to_physmap(xch, domid, + XENMAPSPACE_gmfn, + idx, *extents); + if (rc) + return rc; + } + + return 0; +} + +int libxl__dom_load_acpi(libxl__gc *gc, + libxl_domain_build_info *info, + struct xc_dom_image *dom) +{ + struct acpi_config config = {0}; + struct acpi_ctxt ctxt; + uint32_t domid = dom->guest_domid; + xc_interface *xch = dom->xch; + int rc, i, acpi_pages_num; + xen_pfn_t extent, *extents; + void *acpi_pages, *guest_acpi_pages = NULL; + unsigned long page_mask; + + if ((info->type != LIBXL_DOMAIN_TYPE_HVM) || + (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE)) + return 0; + + ctxt.page_size = XC_DOM_PAGE_SIZE(dom); + ctxt.page_shift = XC_DOM_PAGE_SHIFT(dom); + page_mask = (1UL << ctxt.page_shift) - 1; + + ctxt.mem_ops.alloc = mem_alloc; + ctxt.mem_ops.v2p = virt_to_phys; + + rc = init_acpi_config(gc, dom, info, &config); + if (rc) { + LOG(ERROR, "%s: init_acpi_config failed (rc=%d)", __FUNCTION__, rc); + return rc; + } + + /* Map page that will hold RSDP */ + extent = RSDP_ADDRESS >> ctxt.page_shift; + rc = populate_acpi_pages(dom, &extent, 1, &ctxt); + if (rc) { + LOG(ERROR, "%s: populate_acpi_pages for rsdp failed with %d", + __FUNCTION__, rc); + goto out; + } + config.rsdp = (unsigned long)xc_map_foreign_range(xch, domid, + ctxt.page_size, + PROT_READ | PROT_WRITE, + RSDP_ADDRESS >> ctxt.page_shift); + if (!config.rsdp) { + LOG(ERROR, "%s: Can't map acpi_physical", __FUNCTION__); + rc = -1; + goto out; + } + + /* Map acpi_info page */ + extent = ACPI_INFO_PHYSICAL_ADDRESS >> ctxt.page_shift; + rc = populate_acpi_pages(dom, &extent, 1, &ctxt); + if (rc) { + LOG(ERROR, "%s: populate_acpi_pages for acpi_info failed with %d", + __FUNCTION__, rc); + goto out; + } + + config.ainfop = (unsigned long)xc_map_foreign_range(xch, domid, + ctxt.page_size, + PROT_READ | PROT_WRITE, + ACPI_INFO_PHYSICAL_ADDRESS >> ctxt.page_shift); + if (!config.ainfop) { + LOG(ERROR, "%s: Can't map acpi_info_page", __FUNCTION__); + rc = -1; + goto out; + } + + /* Pages to hold ACPI tables */ + acpi_pages = libxl__malloc(gc, (NUM_ACPI_PAGES + 1) * ctxt.page_size); + while ((unsigned long)acpi_pages & page_mask) + acpi_pages++; + + /* + * Set up allocator memory. + * Start next to acpi_info page to avoid fracturing e820. + */ + ctxt.alloc_base_paddr = ACPI_INFO_PHYSICAL_ADDRESS + ctxt.page_size; + ctxt.alloc_base_vaddr = ctxt.alloc_currp = (unsigned long)acpi_pages; + ctxt.alloc_end = (unsigned long)acpi_pages + + (NUM_ACPI_PAGES * ctxt.page_size); + + /* Build the tables */ + rc = acpi_build_tables(&ctxt, &config); + if (rc) { + LOG(ERROR, "%s: acpi_build_tables failed with %d", + __FUNCTION__, rc); + goto out; + } + + /* Copy ACPI tables into guest's memory */ + acpi_pages_num = + ((ctxt.alloc_currp - (unsigned long)acpi_pages) >> ctxt.page_shift) + + ((ctxt.alloc_currp & page_mask) ? 1 : 0); + extents = libxl__malloc(gc, acpi_pages_num * sizeof(*extents)); + for (i = 0; i < acpi_pages_num; i++) + extents[i] = (ctxt.alloc_base_paddr >> ctxt.page_shift) + i; + rc = populate_acpi_pages(dom, extents, acpi_pages_num, &ctxt); + if (rc) { + LOG(ERROR, "%s: populate_acpi_pages for APCI tables failed with %d", + __FUNCTION__, rc); + goto out; + } + guest_acpi_pages = xc_map_foreign_range(xch, domid, + ctxt.page_size * acpi_pages_num, + PROT_READ | PROT_WRITE, + ctxt.alloc_base_paddr >> ctxt.page_shift); + if (!guest_acpi_pages) { + LOG(ERROR, "%s Can't map guest_acpi_pages", __FUNCTION__); + rc = -1; + goto out; + } + + memcpy(guest_acpi_pages, acpi_pages, acpi_pages_num * ctxt.page_size); + + dom->acpi_pfn = ACPI_INFO_PHYSICAL_ADDRESS >> ctxt.page_shift; + dom->acpi_pages = acpi_pages_num + 1; + +out: + munmap(guest_acpi_pages, acpi_pages_num * ctxt.page_size); + munmap((void *)config.ainfop, ctxt.page_size); + munmap((void *)config.rsdp, ctxt.page_size); + + return rc; + +} +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxl/libxl_x86_acpi.h b/tools/libxl/libxl_x86_acpi.h new file mode 100644 index 0000000..1899ec1 --- /dev/null +++ b/tools/libxl/libxl_x86_acpi.h @@ -0,0 +1,21 @@ +#ifndef LIBXL_X86_ACPI_H +#define LIBXL_X86_ACPI_H + +#include "libxl_internal.h" + +#define ASSERT(x) assert(x) + +static inline int test_bit(unsigned int b, void *p) +{ + return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7))); +} + +#endif /* LIBXL_X_86_ACPI_H */ + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */