From: Julien Grall <julien.grall@linaro.org>
To: Ian Campbell <Ian.Campbell@citrix.com>
Cc: Stefano.Stabellini@eu.citrix.com, patches@linaro.org,
xen-devel@lists.xen.org
Subject: Re: [PATCH v2 1/2] xen/arm: Rework the way to compute dom0 DTB base address
Date: Fri, 31 May 2013 14:28:46 +0100 [thread overview]
Message-ID: <51A8A58E.9090501@linaro.org> (raw)
In-Reply-To: <1370000724.5199.112.camel@zakaz.uk.xensource.com>
On 05/31/2013 12:45 PM, Ian Campbell wrote:
> On Thu, 2013-05-30 at 15:05 +0100, Julien Grall wrote:
>> 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 <julien.grall@linaro.org>
>>
>> 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
> ^from ^uses
>
>> + * the space after it to decompress)
>> + * Load the DTB at the end of the first bank or below 4Gib
> and below?
>
> Perhaps clearer to write "Load the DTB at the end of the first bank,
> while ensure it is also below 4G"
>
Sound goods. I will send a new patch with this change.
>> */
>> - 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 */
>
> Does it? I don't disagree with aligning it to 2MB but I'm sure that e.g.
> CONFIG_APPENDED_DTB handles the unaligned case (perhaps that is
> special)?
I didn't pay attention when I have replaced 4 bytes by 2Mb. Linux only
requires to have an address aligned to 4 bytes.
>
>> + 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;
>
> I had to draw quite a few pictures to convince myself this was right,
> and I'm still not entirely sure ;-)
In fact it's totally wrong :/. What about this check?
if ( (dtb_start < zimage_end) || (dtb_end < zimage_start) )
>
>> +
>> + printk(XENLOG_ERR "The kernel(0x%"PRIpaddr"-0x%"PRIpaddr
>> + ") is overlapping the DTB(0x%"PRIpaddr"-0x%"PRIpaddr":\n",
>
> Missing a closing ) on the DTB range. Also why the trailing ":"?
I planned to have a different sentence. I will replace the ":" by ")".
>
>> + zimage_start, zimage_end, dtb_start, dtb_end);
>> + xfree(kinfo->fdt);
>
> This seems like an odd place to free this.
>
> Returning an error here is only going to cause us to give up and panic
> anyway. I'd suggest to just panic here directly and not bother
> propagating an error code.
>
> Not really sure why construct_dom0 has a return code at all, instead of
> it (or the functions it calls) just panicing. But lets not worry about
> that now.
>
>> +
>> + return -EINVAL;
>> +}
>> +
>> static void dtb_load(struct kernel_info *kinfo)
>> {
>> void * __user dtb_virt = (void * __user)(register_t)kinfo->dtb_paddr;
>
> Blank line here please.
>
>> + 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 <xen/libelf.h>
>> #include <xen/device_tree.h>
>>
>> +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 {
>
>
next prev parent reply other threads:[~2013-05-31 13:28 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-30 14:05 [PATCH v2 0/2] Rework the way to compute dom0 DTB base address Julien Grall
2013-05-30 14:05 ` [PATCH v2 1/2] xen/arm: " Julien Grall
2013-05-31 11:45 ` Ian Campbell
2013-05-31 13:28 ` Julien Grall [this message]
2013-05-31 13:45 ` Julien Grall
2013-05-31 14:14 ` Ian Campbell
2013-05-30 14:05 ` [PATCH v2 2/2] xen/arm: If the DOM0 zImage as a DTB appended replace it Julien Grall
2013-05-30 14:24 ` Ian Campbell
2013-05-30 14:47 ` Julien Grall
2013-05-30 14:52 ` Ian Campbell
2013-05-30 15:01 ` Julien Grall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51A8A58E.9090501@linaro.org \
--to=julien.grall@linaro.org \
--cc=Ian.Campbell@citrix.com \
--cc=Stefano.Stabellini@eu.citrix.com \
--cc=patches@linaro.org \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).