From patchwork Mon Mar 14 17:55:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony PERARD X-Patchwork-Id: 8582601 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 13DC3C0553 for ; Mon, 14 Mar 2016 17:58:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0BF432013D for ; Mon, 14 Mar 2016 17:58:38 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id 0501E2015E for ; Mon, 14 Mar 2016 17:58:36 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1afWiz-0004sR-8f; Mon, 14 Mar 2016 17:56:13 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.84) (envelope-from ) id 1afWix-0004rJ-DN for xen-devel@lists.xen.org; Mon, 14 Mar 2016 17:56:11 +0000 Received: from [85.158.139.211] by server-9.bemta-5.messagelabs.com id 95/FF-22144-A3BF6E65; Mon, 14 Mar 2016 17:56:10 +0000 X-Env-Sender: prvs=874c279eb=anthony.perard@citrix.com X-Msg-Ref: server-13.tower-206.messagelabs.com!1457978168!28652985!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 35922 invoked from network); 14 Mar 2016 17:56:09 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-13.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 14 Mar 2016 17:56:09 -0000 X-IronPort-AV: E=Sophos;i="5.24,336,1454976000"; d="scan'208";a="345467609" From: Anthony PERARD To: Date: Mon, 14 Mar 2016 17:55:36 +0000 Message-ID: <1457978150-27201-2-git-send-email-anthony.perard@citrix.com> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1457978150-27201-1-git-send-email-anthony.perard@citrix.com> References: <1457978150-27201-1-git-send-email-anthony.perard@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Anthony PERARD , Wei Liu , Ian Jackson , Stefano Stabellini Subject: [Xen-devel] [PATCH v4 01/14] libxc: Rework extra module initialisation 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: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch use xc_dom_alloc_segment() to allocate the memory space for the ACPI modules and the SMBIOS modules. This is to replace the arbitrary placement of 1MB after the hvmloader image. In later patches, while trying to load a firmware such as OVMF, the later could easily be loaded past the address 4MB (OVMF is a 2MB binary), but hvmloader use a range of memory from 4MB to 8MB to perform tests and in the process, clear the memory, before loading the modules. Signed-off-by: Anthony PERARD --- Changes in V4: - check that guest_addr_out have a reasonable value. New patch in V3. --- tools/libxc/xc_dom_hvmloader.c | 131 ++++++++++++----------------------------- 1 file changed, 38 insertions(+), 93 deletions(-) diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c index 330d5e8..7cf5854 100644 --- a/tools/libxc/xc_dom_hvmloader.c +++ b/tools/libxc/xc_dom_hvmloader.c @@ -129,98 +129,52 @@ static elf_errorstatus xc_dom_parse_hvm_kernel(struct xc_dom_image *dom) return rc; } -static int modules_init(struct xc_dom_image *dom, - uint64_t vend, struct elf_binary *elf, - uint64_t *mstart_out, uint64_t *mend_out) +static int module_init_one(struct xc_dom_image *dom, + struct xc_hvm_firmware_module *module, + char *name) { -#define MODULE_ALIGN 1UL << 7 -#define MB_ALIGN 1UL << 20 -#define MKALIGN(x, a) (((uint64_t)(x) + (a) - 1) & ~(uint64_t)((a) - 1)) - uint64_t total_len = 0, offset1 = 0; + struct xc_dom_seg seg; + void *dest; - if ( dom->acpi_module.length == 0 && dom->smbios_module.length == 0 ) - return 0; - - /* Find the total length for the firmware modules with a reasonable large - * alignment size to align each the modules. - */ - total_len = MKALIGN(dom->acpi_module.length, MODULE_ALIGN); - offset1 = total_len; - total_len += MKALIGN(dom->smbios_module.length, MODULE_ALIGN); - - /* Want to place the modules 1Mb+change behind the loader image. */ - *mstart_out = MKALIGN(elf->pend, MB_ALIGN) + (MB_ALIGN); - *mend_out = *mstart_out + total_len; - - if ( *mend_out > vend ) - return -1; - - if ( dom->acpi_module.length != 0 ) - dom->acpi_module.guest_addr_out = *mstart_out; - if ( dom->smbios_module.length != 0 ) - dom->smbios_module.guest_addr_out = *mstart_out + offset1; + if ( module->length ) + { + if ( xc_dom_alloc_segment(dom, &seg, name, 0, module->length) ) + goto err; + dest = xc_dom_seg_to_ptr(dom, &seg); + if ( dest == NULL ) + { + DOMPRINTF("%s: xc_dom_seg_to_ptr(dom, &seg) => NULL", + __FUNCTION__); + goto err; + } + memcpy(dest, module->data, module->length); + module->guest_addr_out = seg.vstart; + if ( module->guest_addr_out > UINT32_MAX || + module->guest_addr_out + module->length > UINT32_MAX ) + { + DOMPRINTF("%s: Module %s would be loaded abrove 4GB", + __FUNCTION__, name); + goto err; + } + } return 0; +err: + return -1; } -static int loadmodules(struct xc_dom_image *dom, - uint64_t mstart, uint64_t mend, - uint32_t domid) +static int modules_init(struct xc_dom_image *dom) { - privcmd_mmap_entry_t *entries = NULL; - unsigned long pfn_start; - unsigned long pfn_end; - size_t pages; - uint32_t i; - uint8_t *dest; - int rc = -1; - xc_interface *xch = dom->xch; - - if ( mstart == 0 || mend == 0 ) - return 0; - - pfn_start = (unsigned long)(mstart >> PAGE_SHIFT); - pfn_end = (unsigned long)((mend + PAGE_SIZE - 1) >> PAGE_SHIFT); - pages = pfn_end - pfn_start; - - /* Map address space for module list. */ - entries = calloc(pages, sizeof(privcmd_mmap_entry_t)); - if ( entries == NULL ) - goto error_out; - - for ( i = 0; i < pages; i++ ) - entries[i].mfn = (mstart >> PAGE_SHIFT) + i; - - dest = xc_map_foreign_ranges( - xch, domid, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 1 << PAGE_SHIFT, - entries, pages); - if ( dest == NULL ) - goto error_out; - - /* Zero the range so padding is clear between modules */ - memset(dest, 0, pages << PAGE_SHIFT); - - /* Load modules into range */ - if ( dom->acpi_module.length != 0 ) - { - memcpy(dest, - dom->acpi_module.data, - dom->acpi_module.length); - } - if ( dom->smbios_module.length != 0 ) - { - memcpy(dest + (dom->smbios_module.guest_addr_out - mstart), - dom->smbios_module.data, - dom->smbios_module.length); - } - - munmap(dest, pages << PAGE_SHIFT); - rc = 0; + int rc; - error_out: - free(entries); + rc = module_init_one(dom, &dom->acpi_module, "acpi module"); + if ( rc ) goto err; + rc = module_init_one(dom, &dom->smbios_module, "smbios module"); + if ( rc ) goto err; - return rc; + return 0; +err: + return -1; } static elf_errorstatus xc_dom_load_hvm_kernel(struct xc_dom_image *dom) @@ -229,7 +183,6 @@ static elf_errorstatus xc_dom_load_hvm_kernel(struct xc_dom_image *dom) privcmd_mmap_entry_t *entries = NULL; size_t pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT; elf_errorstatus rc; - uint64_t m_start = 0, m_end = 0; int i; /* Map address space for initial elf image. */ @@ -262,15 +215,7 @@ static elf_errorstatus xc_dom_load_hvm_kernel(struct xc_dom_image *dom) munmap(elf->dest_base, elf->dest_size); - rc = modules_init(dom, dom->total_pages << PAGE_SHIFT, elf, &m_start, - &m_end); - if ( rc != 0 ) - { - DOMPRINTF("%s: insufficient space to load modules.", __func__); - goto error; - } - - rc = loadmodules(dom, m_start, m_end, dom->guest_domid); + rc = modules_init(dom); if ( rc != 0 ) { DOMPRINTF("%s: unable to load modules.", __func__);