From patchwork Thu May 30 14:05:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 17301 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f199.google.com (mail-qc0-f199.google.com [209.85.216.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 30E4E25C6D for ; Thu, 30 May 2013 14:05:30 +0000 (UTC) Received: by mail-qc0-f199.google.com with SMTP id s1sf316722qcw.2 for ; Thu, 30 May 2013 07:05:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-beenthere:x-forwarded-to:x-forwarded-for :delivered-to:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=hJaaZMcNURjvbrMR1otC5OpXtCWJUZcCvFTZTrmi4Tw=; b=oX3V9PTXYcVaVVcLL5/AwTwLI9q4OSWu90RMpWLkAK62wtwmsrjR+Vkqjh2tWslC/o XwQoJM79uOU+lVdeBcm/PMJTnwPPcIDH6s6WuwTd2eAvHs7ePpnSQ+zYNkA0UaehHIIq ufRn1etv2yiS/jZTa5WjOlUKbbAt4xZh7WXoenU2X/aqRrcVmjYvmadbl+Pj9utMf5mv 5Q7A6xXvXb9a99LVtGPEbTTZnGtRPEEbwh6ClcuclLxQ4FU+KlKAb/9XVB2HBZfQyTgZ 6hUh2vh9D362S7/aE0k21yHCQZsMW1FvM+Eeq9fx0na6kgxFXeEA7rukmTbx16J/++7z vX4w== X-Received: by 10.236.142.11 with SMTP id h11mr3856283yhj.55.1369922730003; Thu, 30 May 2013 07:05:30 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.62.138 with SMTP id y10ls351328qer.74.gmail; Thu, 30 May 2013 07:05:29 -0700 (PDT) X-Received: by 10.58.88.4 with SMTP id bc4mr5540327veb.48.1369922729828; Thu, 30 May 2013 07:05:29 -0700 (PDT) Received: from mail-vb0-x22a.google.com (mail-vb0-x22a.google.com [2607:f8b0:400c:c02::22a]) by mx.google.com with ESMTPS id u5si10876686vet.0.2013.05.30.07.05.29 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 30 May 2013 07:05:29 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c02::22a is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c02::22a; Received: by mail-vb0-f42.google.com with SMTP id w15so186987vbf.29 for ; Thu, 30 May 2013 07:05:29 -0700 (PDT) X-Received: by 10.52.34.114 with SMTP id y18mr4779747vdi.56.1369922729632; Thu, 30 May 2013 07:05:29 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.229.199 with SMTP id jj7csp9427vcb; Thu, 30 May 2013 07:05:28 -0700 (PDT) X-Received: by 10.180.14.199 with SMTP id r7mr4831691wic.6.1369922728356; Thu, 30 May 2013 07:05:28 -0700 (PDT) Received: from mail-wg0-x229.google.com (mail-wg0-x229.google.com [2a00:1450:400c:c00::229]) by mx.google.com with ESMTPS id uc6si8391228wjc.247.2013.05.30.07.05.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 30 May 2013 07:05:28 -0700 (PDT) Received-SPF: neutral (google.com: 2a00:1450:400c:c00::229 is neither permitted nor denied by best guess record for domain of julien.grall@linaro.org) client-ip=2a00:1450:400c:c00::229; Received: by mail-wg0-f41.google.com with SMTP id k13so5132340wgh.2 for ; Thu, 30 May 2013 07:05:28 -0700 (PDT) X-Received: by 10.194.21.138 with SMTP id v10mr4980025wje.16.1369922727937; Thu, 30 May 2013 07:05:27 -0700 (PDT) Received: from belegaer.uk.xensource.com. (firewall.ctxuk.citrix.com. [46.33.159.2]) by mx.google.com with ESMTPSA id f2sm38153571wiv.11.2013.05.30.07.05.25 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 30 May 2013 07:05:27 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Cc: Stefano.Stabellini@eu.citrix.com, ian.campbell@citrix.com, patches@linaro.org, Julien Grall Subject: [PATCH v2 1/2] xen/arm: Rework the way to compute dom0 DTB base address Date: Thu, 30 May 2013 15:05:18 +0100 Message-Id: <1369922720-10015-2-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1369922720-10015-1-git-send-email-julien.grall@linaro.org> References: <1369922720-10015-1-git-send-email-julien.grall@linaro.org> X-Gm-Message-State: ALoCoQnCKJSAeHP2u7PZr71cLL9B0MuXmvjUe/AK+cPz5LzyJFqs8iey7asyML9W3jNl10dDHvue X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c02::22a is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , If the DTB is loading right the after the kernel, on some setup, Linux will overwrite the DTB during the decompression step. To be sure the DTB won't be overwritten by the decompression stage, load the DTB near the end of the first memory bank and below 4Gib (if memory range is greater). Signed-off-by: Julien Grall Changes in v2: - Align the DTB base address to 2Mib - Add dtb_check_overlap to check if the kernel will overlap the DTB - Fix typo --- xen/arch/arm/domain_build.c | 51 ++++++++++++++++++++++++++++++++++++++----- xen/arch/arm/kernel.c | 2 ++ xen/arch/arm/kernel.h | 7 ++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index b92c64b..515fabe 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -477,6 +477,7 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) void *fdt; int new_size; int ret; + paddr_t end; kinfo->unassigned_mem = dom0_mem; @@ -502,17 +503,25 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) goto err; /* - * Put the device tree at the beginning of the first bank. It - * must be below 4 GiB. + * DTB must be load below 4GiB and far enough to linux (Linux use + * the space after it to decompress) + * Load the DTB at the end of the first bank or below 4Gib */ - kinfo->dtb_paddr = kinfo->mem.bank[0].start + 0x100; - if ( kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt) > (1ull << 32) ) + end = kinfo->mem.bank[0].start + kinfo->mem.bank[0].size; + end = MIN(1ull << 32, end); + kinfo->dtb_paddr = end - fdt_totalsize(kinfo->fdt); + /* Linux requires the address to be aligned to 2Mb */ + kinfo->dtb_paddr &= ~((2 << 20) - 1); + + if ( fdt_totalsize(kinfo->fdt) > end ) { - printk("Not enough memory below 4 GiB for the device tree."); + printk(XENLOG_ERR "Not enough memory in the first bank for " + "the device tree."); ret = -FDT_ERR_XEN(EINVAL); goto err; } + return 0; err: @@ -521,9 +530,36 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo) return -EINVAL; } +static int dtb_check_overlap(struct kernel_info *kinfo) +{ + paddr_t zimage_start = kinfo->zimage.load_addr; + paddr_t zimage_end = kinfo->zimage.load_addr + kinfo->zimage.len; + paddr_t dtb_start = kinfo->dtb_paddr; + paddr_t dtb_end = kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt); + + /* + * Check the kernel won't overlap the kernel + * Only when it's a ZIMAGE + */ + if ( kinfo->type != KERNEL_ZIMAGE ) + return 0; + + if ( !(MAX(zimage_start, dtb_end) < MIN(zimage_end, dtb_start)) ) + return 0; + + printk(XENLOG_ERR "The kernel(0x%"PRIpaddr"-0x%"PRIpaddr + ") is overlapping the DTB(0x%"PRIpaddr"-0x%"PRIpaddr":\n", + zimage_start, zimage_end, dtb_start, dtb_end); + xfree(kinfo->fdt); + + return -EINVAL; +} + static void dtb_load(struct kernel_info *kinfo) { void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr; + printk("Loading dom0 DTB to 0x%"PRIpaddr"-0x%"PRIpaddr"\n", + kinfo->dtb_paddr, kinfo->dtb_paddr + fdt_totalsize(kinfo->fdt)); raw_copy_to_guest(dtb_virt, kinfo->fdt, fdt_totalsize(kinfo->fdt)); xfree(kinfo->fdt); @@ -559,10 +595,13 @@ int construct_dom0(struct domain *d) if ( rc < 0 ) return rc; + rc = dtb_check_overlap(&kinfo); + if ( rc < 0 ) + return rc; + /* The following loads use the domain's p2m */ p2m_load_VTTBR(d); - kinfo.dtb_paddr = kinfo.zimage.load_addr + kinfo.zimage.len; kernel_load(&kinfo); dtb_load(&kinfo); diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index 8f4a60d..f8c8850 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -152,6 +152,7 @@ static int kernel_try_zimage_prepare(struct kernel_info *info, info->entry = info->zimage.load_addr; info->load = kernel_zimage_load; + info->type = KERNEL_ZIMAGE; return 0; } @@ -193,6 +194,7 @@ static int kernel_try_elf_prepare(struct kernel_info *info, */ info->entry = info->elf.parms.virt_entry; info->load = kernel_elf_load; + info->type = KERNEL_ELF; return 0; err: diff --git a/xen/arch/arm/kernel.h b/xen/arch/arm/kernel.h index 1776a4d..b4ecd30 100644 --- a/xen/arch/arm/kernel.h +++ b/xen/arch/arm/kernel.h @@ -9,6 +9,12 @@ #include #include +enum kernel_type +{ + KERNEL_ELF, + KERNEL_ZIMAGE, +}; + struct kernel_info { #ifdef CONFIG_ARM_64 enum domain_type type; @@ -23,6 +29,7 @@ struct kernel_info { void *kernel_img; unsigned kernel_order; + enum kernel_type type; union { struct {