[RFC PATCH] arm64: use fixmap region for permanent FDT mapping
Ard Biesheuvel
ard.biesheuvel at linaro.org
Mon Mar 2 06:47:41 PST 2015
On 2 March 2015 at 14:40, Mark Rutland <mark.rutland at arm.com> wrote:
> On Fri, Feb 27, 2015 at 02:53:43PM +0000, Ard Biesheuvel wrote:
>> Currently, the FDT blob needs to be in the same naturally aligned
>> 512 MB region as the kernel, so that it can be mapped into the
>> kernel virtual memory space very early on using a minimal set of
>> statically allocated translation tables.
>>
>> Now that we have early fixmap support, we can relax this restriction,
>> by moving the permanent FDT mapping to the fixmap region instead.
>> This way, the FDT blob may be anywhere in memory.
>
> Neat! I was hoping we'd have the chance to do this at some point.
>
> [...]
>
>> + /*
>> + * 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,
>
> Doesn't the presence of the FIX_HOLE entry mean that this isn't 2MB
> aligned?
>
Well, the fixmap is a bit odd in this respect: FIXADDR_TOP is
exclusive, so FIX_HOLE is only there as a placeholder.
> [...]
>
>> __create_page_tables:
>> - pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
>> + pgtbl x25, x26, x28 // idmap_pg_dir and swapper_pg_dir addresses
>> mov x27, lr
>>
>> /*
>
> This comment should just stay where it was. It aligns with comments
> later within __create_page_tables that are left alone by this patch, so
> we don't gain anything by moving it.
>
I'll drop it.
> [...]
>
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index e8420f635bd4..7ea087d904ad 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -309,12 +309,14 @@ static void __init setup_processor(void)
>>
>> static void __init setup_machine_fdt(phys_addr_t dt_phys)
>> {
>> - if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) {
>> + void *dt_virt = fixmap_remap_fdt(dt_phys);
>> +
>> + if (!dt_phys || !early_init_dt_scan(dt_virt)) {
>> early_print("\n"
>> "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
>> - "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
>> + "The dtb must be 8-byte aligned\n"
>> "\nPlease check your bootloader.\n",
>> - dt_phys, phys_to_virt(dt_phys));
>> + dt_phys, dt_virt);
>
> We should also check that the reported size in the header doesn't cross
> a 2MB PA boundary, or we won't be able to map the whole DTB and the
> crc32 code will explode later.
>
Good point.
> Otherwise this looks good!
>
Actually, there is a bit of a snag:
early_init_fdt_scan_reserved_mem() reserves the FDT region, but does
so by using __pa() to retrieve the physical offset, which doesn't work
now the FDT is not accessed through the linear mapping.
I will try and figure out what the best way is to work around this.
Any and all suggestions appreciated.
--
Ard.
More information about the linux-arm-kernel
mailing list