arm64 initrd mapping/relocation
cover arm64 initrd mapping/relocation
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Mostly intended for discussion, not tested at all.
Ard Biesheuvel (3):
memblock: add routine to clear the MEMBLOCK_NOMAP flag for a region
arm64: add the initrd region to the linear mapping explicitly
arm64: remove the now unneeded relocate_initrd()
arch/arm64/kernel/setup.c | 64 -------------------- arch/arm64/mm/init.c | 16 ++++- include/linux/memblock.h | 1 + mm/memblock.c | 12 ++++ 4 files changed, 27 insertions(+), 66 deletions(-)
Signature · 1 line
2.5.0
RFC PATCH 1/3 memblock: add routine to clear the MEMBLOCK_NOMAP flag for a region
In addition to the existing memblock_mark_nomap(), this implements memblock_clear_nomap() to do the converse.
--- include/linux/memblock.h | 1 + mm/memblock.c | 12 ++++++++++++ 2 files changed, 13 insertions(+)
include/linux/memblock.h +1 -0
@@ -92,6 +92,7 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);int memblock_clear_hotplug (phys_addr_t base,phys_addr_t size);int memblock_mark_mirror (phys_addr_t base,phys_addr_t size);int memblock_mark_nomap (phys_addr_t base,phys_addr_t size); +int memblock_clear_nomap (phys_addr_t base,phys_addr_t size);ulong choose_memblock_flags (void );/* Low level functions */
mm/memblock.c +12 -0
@@ -835,6 +835,18 @@ int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size) }/** +* memblock_clear_nomap - Clear flag MEMBLOCK_NOMAP for a specified region. +* @base: the base phys addr of the region +* @size: the size of the region +* +* Return 0 on success, -errno on failure. +*/ +int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size) +{ +return memblock_setclr_flag (base, size,0 ,MEMBLOCK_NOMAP ); +} + +/** * __next_reserved_mem_region - next function for for_each_reserved_region() * @idx: pointer to u64 loop variable * @out_start: ptr to phys_addr_t for start address of the region, can be %NULL
Signature · 1 line
2.5.0
RFC PATCH 2/3 arm64: add the initrd region to the linear mapping explicitly
In reply to Ard BiesheuvelInstead of going out of our way to relocate the initrd if it turns out to occupy memory that is not covered by the linear mapping, just add the initrd to the linear mapping. This puts the burden on the bootloader to pass initrd= and mem= options that are mutually consistent.
--- arch/arm64/mm/init.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/arm64/mm/init.c +14 -2
@@ -167,8 +167,20 @@ void __init arm64_memblock_init(void)*/ memblock_reserve (__pa (_text), _end - _text);#ifdef CONFIG_BLK_DEV_INITRD -if (initrd_start) -memblock_reserve (__virt_to_phys (initrd_start), initrd_end - initrd_start); +if (initrd_start) { +u64 base =__virt_to_phys (initrd_start); +u64 size = initrd_end - initrd_start; + +/* +* The initrd needs to be accessible via the linear mapping. So +* add the memory covered by the initrd explicitly, since it may +* have been clipped or otherwise left out when we traversed the +* DT memory nodes or the UEFI memory map. +*/ +memblock_add (base, size); +memblock_clear_nomap (base, size); +memblock_reserve (base, size); + }#endif early_init_fdt_scan_reserved_mem ();
Signature · 1 line
2.5.0
RFC PATCH 3/3 arm64: remove the now unneeded relocate_initrd()
In reply to Ard Biesheuvel--- arch/arm64/kernel/setup.c | 64 -------------------- 1 file changed, 64 deletions(-)
arch/arm64/kernel/setup.c +0 -64
@@ -223,69 +223,6 @@ static void __init request_standard_resources(void) } } -#ifdef CONFIG_BLK_DEV_INITRD -/* -* Relocate initrd if it is not completely within the linear mapping. -* This would be the case if mem= cuts out all or part of it. -*/ -static void __init relocate_initrd (void ) -{ -phys_addr_t orig_start =__virt_to_phys (initrd_start); -phys_addr_t orig_end =__virt_to_phys (initrd_end); -phys_addr_t ram_end =memblock_end_of_DRAM (); -phys_addr_t new_start; -unsigned long size, to_free =0 ; -void *dest; - -if (orig_end <= ram_end) -return ; - -/* -* Any of the original initrd which overlaps the linear map should -* be freed after relocating. -*/ -if (orig_start < ram_end) - to_free = ram_end - orig_start; - - size = orig_end - orig_start; -if (!size) -return ; - -/* initrd needs to be relocated completely inside linear mapping */ - new_start =memblock_find_in_range (0 ,PFN_PHYS (max_pfn), - size,PAGE_SIZE ); -if (!new_start) -panic ("Cannot relocate initrd of size %ld\n" , size); -memblock_reserve (new_start, size); - - initrd_start =__phys_to_virt (new_start); - initrd_end = initrd_start + size; - -pr_info ("Moving initrd from [%llx-%llx] to [%llx-%llx]\n" , - orig_start, orig_start + size -1 , - new_start, new_start + size -1 ); - - dest = (void *)initrd_start; - -if (to_free) { -memcpy (dest, (void *)__phys_to_virt (orig_start), to_free); - dest += to_free; - } - -copy_from_early_mem (dest, orig_start + to_free, size - to_free); - -if (to_free) { -pr_info ("Freeing original RAMDISK from [%llx-%llx]\n" , - orig_start, orig_start + to_free -1 ); -memblock_free (orig_start, to_free); - } -} -#else -static inline void __init relocate_initrd (void ) -{ -} -#endif -u64 __cpu_logical_map[NR_CPUS ] = { [0 ...NR_CPUS -1 ] =INVALID_HWID };void __init setup_arch (char **cmdline_p)
@@ -320,7 +257,6 @@ void __init setup_arch(char **cmdline_p)acpi_boot_table_init ();paging_init (); -relocate_initrd ();kasan_init ();
Signature · 1 line
2.5.0
cover arm64 initrd mapping/relocation
In reply to Ard BiesheuvelQuoted 9 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Mostly intended for discussion, not tested at all.
Thanks Ard, this looks like a much better approach to me. Mark -- does the general idea work for you too?
Will
cover arm64 initrd mapping/relocation
Quoted 5 lines · Will Deacon
Quoted 4 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Quoted 8 lines
Quoted 5 lines
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Mostly intended for discussion, not tested at all.
Thanks Ard, this looks like a much better approach to me. Mark -- does the general idea work for you too?
I'm not quite the right Mark but Mark Salter is on vacation and I was the one who discovered this bug. These patches do fix the problem and it looks like they tidy up some code. Will they be in v4.5-rc3?
--Mark Langsdorf
cover arm64 initrd mapping/relocation
In reply to Will DeaconQuoted 9 lines · Will Deacon
Quoted 8 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Quoted 6 lines
Quoted 1 line
Mostly intended for discussion, not tested at all.
Thanks Ard, this looks like a much better approach to me. Mark -- does the general idea work for you too?
Will
Yeah, much simpler. I like it in concept but am I missing something or is it adding memory to the system beyond the mem= limit? But even that may not be a big deal. And I need to look at the KASLR work and understand the issues with it and mem= if any. I'm traveling right now and can't really try it out until tomorrow...
cover arm64 initrd mapping/relocation
Quoted 12 lines · Mark Salter
Quoted 11 lines · Will Deacon
Quoted 9 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Mostly intended for discussion, not tested at all.
Quoted 7 lines
Quoted 4 lines
Thanks Ard, this looks like a much better approach to me. Mark -- does the general idea work for you too?
Will
Yeah, much simpler. I like it in concept but am I missing something or is it adding memory to the system beyond the mem= limit?
Indeed. I think it is reasonable to require that if you pass both mem= and initrd= *and* you need your memory limit to be honored strictly, it is up to you to ensure that the initrd does not live in the memory you are throwing away.
Quoted 5 lines
But even that may not be
a big deal. And I need to look at the KASLR work and understand the issues with it and mem= if any. I'm traveling right now and can't really try it out until tomorrow...
No worries. My estimation is that Will is not going to take this as a fix anyway, so we have plenty of time to test and/or discuss
Thanks,
Ard.
cover arm64 initrd mapping/relocation
Quoted 26 lines · Ard Biesheuvel
Quoted 12 lines · Mark Salter
Quoted 11 lines · Will Deacon
Quoted 9 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Mostly intended for discussion, not tested at all.
Quoted 7 lines
Quoted 4 lines
Thanks Ard, this looks like a much better approach to me. Mark -- does the general idea work for you too?
Will
Yeah, much simpler. I like it in concept but am I missing something or is it adding memory to the system beyond the mem= limit?
Indeed. I think it is reasonable to require that if you pass both mem= and initrd= *and* you need your memory limit to be honored strictly, it is up to you to ensure that the initrd does not live in the memory you are throwing away.
Quoted 8 lines
Quoted 5 lines
But even that may not be
a big deal. And I need to look at the KASLR work and understand the issues with it and mem= if any. I'm traveling right now and can't really try it out until tomorrow...No worries. My estimation is that Will is not going to take this as a fix anyway, so we have plenty of time to test and/or discuss
I needed these patches to successfully boot a JunoR2 with a recent tianocore firmware.
Thanks,
cover arm64 initrd mapping/relocation
In reply to Ard BiesheuvelQuoted 8 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is a proposal for dealing with initrd memory that is potentially not covered by the linear region.
Note that this will look slightly differently when some of the KASLR work gets merged, but this should only affect the way we deal with the initrd if it sits outside of the linear region.
Quoted 6 lines
Mostly intended for discussion, not tested at all.
Ard Biesheuvel (3):
memblock: add routine to clear theMEMBLOCK_NOMAPflag for a region
arm64: add the initrd region to the linear mapping explicitly
arm64: remove the now unneededrelocate_initrd()
I discovered the original problem on AMD Seattle and these patches fixed it for me.
cover arm64 initrd mapping/relocation
Quoted 22 lines · Mark Langsdorf
Quoted 13 lines · Ard Biesheuvel
After discussing in linux-efi with Mark, and on #armlinux with Will, this is
a proposal for dealing with initrd memory that is potentially not covered by
the linear region.Note that this will look slightly differently when some of the KASLR work gets
merged, but this should only affect the way we deal with the initrd if it sits
outside of the linear region.Quoted 6 lines
Mostly intended for discussion, not tested at all.
Ard Biesheuvel (3):
memblock: add routine to clear theMEMBLOCK_NOMAPflag for a region
arm64: add the initrd region to the linear mapping explicitly
arm64: remove the now unneededrelocate_initrd()
Quoted 5 lines
I discovered the original problem on AMD Seattle and these patches fixed it for me.
Tested-by Mark Langsdorf <[email protected]>
Thanks Mark.
I will let Will confirm when and how these patches will be merged.
Signature · 1 line
Ard.