[PATCH v3 2/5] arm64: use fixmap region for permanent FDT mapping
Mark Rutland
mark.rutland at arm.com
Thu Apr 9 04:49:12 PDT 2015
Hi Ard,
This looks good to me (with some minor comments below).
As a heads-up, this clashes with other changes in the arm64
for-next/core branch due to some unrelated changes in head.S and
setup.c.
> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
> index f3c05b5f9f08..ab5a90adece3 100644
> --- a/Documentation/arm64/booting.txt
> +++ b/Documentation/arm64/booting.txt
> @@ -45,11 +45,13 @@ sees fit.)
>
> Requirement: MANDATORY
>
> -The device tree blob (dtb) must be placed on an 8-byte boundary within
> -the first 512 megabytes from the start of the kernel image and must not
> -cross a 2-megabyte boundary. This is to allow the kernel to map the
> -blob using a single section mapping in the initial page tables.
> +The device tree blob (dtb) must be placed on an 8-byte boundary and must
> +not cross a 2-megabyte boundary. This is to allow the kernel to map the
> +blob using a single section mapping in the fixmap region.
Please drop the mention of the fixmap. If we ever move this out of the
fixmap I don't want to have to update booting.txt again, and it
shouldn't matter to bootloader authors either way.
> +NOTE: versions prior to v4.1 require, in addition to the requirements
> +listed above, that the dtb be placed above the kernel Image inside the
> +same naturally aligned 512 MB region.
Minor nit: This would read a little better if we just said "versions
prior to v4.1 also require that ...", dropping "in addition to the
requirements listed above".
[...]
> enum fixed_addresses {
> FIX_HOLE,
> +
> + /*
> + * Reserve 2 MB of virtual space for the FDT at the top of the fixmap
> + * region. Keep this at the top so it remains 2 MB aligned.
> + */
> +#define FIX_FDT_SIZE SZ_2M
> + FIX_FDT_END,
> + FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
> +
> FIX_EARLYCON_MEM_BASE,
> FIX_TEXT_POKE0,
> __end_of_permanent_fixed_addresses,
[...]
> +static void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
> +{
> + const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
> + phys_addr_t dt_phys_base = dt_phys & ~(FIX_FDT_SIZE - 1);
> +
> + /*
> + * Make sure that the FDT region can be mapped without the need to
> + * allocate additional translation table pages, so that it is safe
> + * to call create_pgd_mapping() this early.
> + * On 4k pages, we'll use section mappings for the region so we
> + * only have to be in the same PUD as the rest of the fixmap.
> + * On 64k pages, we need to be in the same PMD as well, as the region
> + * will be mapped using PTEs.
> + */
> + BUILD_BUG_ON(dt_virt_base & (SZ_2M - 1));
s/SZ_2M/FIX_FDT_SIZE/
Perhaps we should also have:
BUILD_BUG_ON_NOT_POWER_OF_2(FIX_FDT_SIZE);
... given it's necessary for the address masking we do here.
[...]
> + /*
> + * Before passing the dt_virt pointer to early_init_dt_scan(), we have
> + * to ensure that the FDT size as reported in the FDT itself does not
> + * exceed the 2 MB window we just mapped for it.
> + */
> + if (!dt_virt ||
> + fdt_check_header(dt_virt) != 0 ||
> + (dt_phys & (SZ_2M - 1)) + fdt_totalsize(dt_virt) > SZ_2M ||
> + !early_init_dt_scan(dt_virt)) {
> + pr_crit("\n"
> + "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
> + "The dtb must be 8-byte aligned and must not cross a 2 MB alignment boundary\n"
> "\nPlease check your bootloader.\n",
> - dt_phys, phys_to_virt(dt_phys));
> + &dt_phys, dt_virt);
Nit: drop the leading '\n' on the last line. There's no need for it.
I've tested this on my Juno (atop of arm64 for-next/core), and all seems
well, so with those points addressed:
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Tested-by: Mark Rutland <mark.rutland at arm.com>
Thanks,
Mark.
More information about the linux-arm-kernel
mailing list