arm64: improved memory map handling for /dev/mem, ACPI etc
Subsystems (5)
cover arm64: improved memory map handling for /dev/mem, ACPI etc
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the /dev/mem and (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.
Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of /dev/mem mappings, both to decide whether it should be mapped as MT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)
Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than _reserves() UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem to memblock_dump_all() output
memblock: introduce memblock_add_phys() and memblock_is_physmem()
of: fdt: register physmem in early_init_dt_scan_memory() arm64/efi: register physmem in reserve_regions()
arm64: use 'physmem' memblock to improve CONFIG_STRICT_DEVMEM handling arm64/efi: memblock_remove rather than _reserve UEFI reserved RAM
arch/arm64/Kconfig | 1 + arch/arm64/kernel/efi.c | 82 +++++++++++++++++++++++++++++++++++++++--------- arch/arm64/mm/mmap.c | 2 +- arch/arm64/mm/mmu.c | 15 ++++++++- drivers/of/fdt.c | 1 + include/linux/memblock.h | 10 ++++++ mm/memblock.c | 18 +++++++++++ 7 files changed, 113 insertions(+), 16 deletions(-)
Signature · 1 line
1.8.3.2
PATCH 1/8 arm64/efi: use UEFI memory map unconditionally if available
On systems that boot via UEFI, all memory nodes are deleted from the device tree, and instead, the size and location of system RAM is derived from the UEFI memory map. This is handled by reserve_regions, which not only reserves parts of memory that UEFI declares as reserved, but also installs the memblocks that cover the remaining usable memory.
Currently, reserve_regions() is only called if uefi_init() succeeds. However, it does not actually depend on anything that uefi_init() does, and not calling reserve_regions() results in a broken boot, so it is better to just call it unconditionally.
--- arch/arm64/kernel/efi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
arch/arm64/kernel/efi.c +4 -7
@@ -208,8 +208,7 @@ void __init efi_init(void) memmap.desc_size = params.desc_size; memmap.desc_version = params.desc_ver; -if (uefi_init () <0 ) -return ; +WARN_ON (uefi_init () <0 );reserve_regions (); }
@@ -218,15 +217,13 @@ static int __init arm64_enter_virtual_mode(void) {u64 mapsize; -if (!efi_enabled (EFI_BOOT )) { -pr_info ("EFI services will not be available.\n" ); -return -1 ; - } +if (!efi_enabled (EFI_MEMMAP )) +return 0 ; mapsize = memmap.map_end - memmap.map;early_memunmap (memmap.map, mapsize); -if (efi_runtime_disabled ()) { +if (!efi_enabled (EFI_BOOT ) ||efi_runtime_disabled ()) {pr_info ("EFI runtime services will be disabled.\n" );return -1 ; }
Signature · 1 line
1.8.3.2
PATCH 1/8 arm64/efi: use UEFI memory map unconditionally if available
Quoted 39 lines · Ard Biesheuvel
On systems that boot via UEFI, all memory nodes are deleted from the device tree, and instead, the size and location of system RAM is derived from the UEFI memory map. This is handled by
reserve_regions, which not only reserves parts of memory that UEFI declares as reserved, but also installs the memblocks that cover the remaining usable memory.Currently,
reserve_regions()is only called ifuefi_init()succeeds. However, it does not actually depend on anything thatuefi_init()does, and not callingreserve_regions()results in a broken boot, so it is better to just call it unconditionally.Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/kernel/efi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)arch/arm64/kernel/efi.c +2
-6@@ -208,8 +208,7 @@ void __init efi_init(void) memmap.desc_size = params.desc_size; memmap.desc_version = params.desc_ver; -if (uefi_init () <0 ) -return ; +WARN_ON (uefi_init () <0 );reserve_regions (); }@@ -218,15 +217,13 @@ static int __init arm64_enter_virtual_mode(void) {u64 mapsize; -if (!efi_enabled (EFI_BOOT )) { -pr_info ("EFI services will not be available.\n" ); -return -1 ; - } +if (!efi_enabled (EFI_MEMMAP ))
arch/arm64/kernel/efi.c static int __init arm64_enter_virtual_mode(void) · line 229
Quoted 10 lines
arch/arm64/kernel/efi.c +2
-1+return 0 ; mapsize = memmap.map_end - memmap.map;early_memunmap (memmap.map, mapsize); -if (efi_runtime_disabled ()) { +if (!efi_enabled (EFI_BOOT ) ||efi_runtime_disabled ()) {pr_info ("EFI runtime services will be disabled.\n" );return -1 ; }
Am I correct in thinking that it's possible to have EFI_MEMMAP set but not EFI_BOOT? That's not how things work on x86. EFI_BOOT means "I am an EFI-enabled platform and I was booted using EFI."
In other words, EFI_MEMMAP should imply EFI_BOOT (how did you get the memmap if you weren't booted using EFI?)
It looks like you should be setting EFI_BOOT (and EFI_64BIT) in efi_init() if efi_get_fdt_params() succeeds.
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
PATCH 1/8 arm64/efi: use UEFI memory map unconditionally if available
Quoted 55 lines · Matt Fleming
Quoted 39 lines · Ard Biesheuvel
On systems that boot via UEFI, all memory nodes are deleted from the device tree, and instead, the size and location of system RAM is derived from the UEFI memory map. This is handled by
reserve_regions, which not only reserves parts of memory that UEFI declares as reserved, but also installs the memblocks that cover the remaining usable memory.Currently,
reserve_regions()is only called ifuefi_init()succeeds. However, it does not actually depend on anything thatuefi_init()does, and not callingreserve_regions()results in a broken boot, so it is better to just call it unconditionally.Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/kernel/efi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)arch/arm64/kernel/efi.c +2
-6@@ -208,8 +208,7 @@ void __init efi_init(void) memmap.desc_size = params.desc_size; memmap.desc_version = params.desc_ver; -if (uefi_init () <0 ) -return ; +WARN_ON (uefi_init () <0 );reserve_regions (); }@@ -218,15 +217,13 @@ static int __init arm64_enter_virtual_mode(void) {u64 mapsize; -if (!efi_enabled (EFI_BOOT )) { -pr_info ("EFI services will not be available.\n" ); -return -1 ; - } +if (!efi_enabled (EFI_MEMMAP ))arch/arm64/kernel/efi.c static int __init arm64_enter_virtual_mode(void) · line 229
Quoted 10 lines
arch/arm64/kernel/efi.c +2
-1+return 0 ; mapsize = memmap.map_end - memmap.map;early_memunmap (memmap.map, mapsize); -if (efi_runtime_disabled ()) { +if (!efi_enabled (EFI_BOOT ) ||efi_runtime_disabled ()) {pr_info ("EFI runtime services will be disabled.\n" );return -1 ; }Am I correct in thinking that it's possible to have
EFI_MEMMAPset but notEFI_BOOT? That's not how things work on x86.EFI_BOOTmeans "I am an EFI-enabled platform and I was booted using EFI."
Quoted 3 lines
In other words,
EFI_MEMMAPshould implyEFI_BOOT(how did you get the memmap if you weren't booted using EFI?)
In the arm64 case, the memory map is retrieved by the stub, and its address is passed via the /chosen DT node, which also contains the address of the EFI system table. In the unlikely event that, for instance, the FEI system table signature is corrupted, we will not set EFI_BOOT (nor EFI_64BIT).
Quoted 3 lines
It looks like you should be setting
EFI_BOOT(andEFI_64BIT) inefi_init()ifefi_get_fdt_params()succeeds.
Yes, I agree. We should probably set EFI_SYSTEM_TABLES in uefi_init() then, and possibly unset it again if we fail to remap it.
Signature · 1 line
Ard.
PATCH 1/8 arm64/efi: use UEFI memory map unconditionally if available
Quoted 7 lines · Ard Biesheuvel
Quoted 3 lines · Matt Fleming
It looks like you should be setting
EFI_BOOT(andEFI_64BIT) inefi_init()ifefi_get_fdt_params()succeeds.Yes, I agree. We should probably set
EFI_SYSTEM_TABLESinuefi_init()then, and possibly unset it again if we fail to remap it.
Yeah, I think that would be more correct.
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
PATCH 1/8 arm64/efi: use UEFI memory map unconditionally if available
In reply to Ard BiesheuvelQuoted 11 lines · Ard Biesheuvel
On systems that boot via UEFI, all memory nodes are deleted from the device tree, and instead, the size and location of system RAM is derived from the UEFI memory map. This is handled by
reserve_regions, which not only reserves parts of memory that UEFI declares as reserved, but also installs the memblocks that cover the remaining usable memory.Currently,
reserve_regions()is only called ifuefi_init()succeeds. However, it does not actually depend on anything thatuefi_init()does, and not callingreserve_regions()results in a broken boot, so it is better to just call it unconditionally.
Quoted 4 lines
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/kernel/efi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
Will
Quoted 37 lines
arch/arm64/kernel/efi.c +4
-7@@ -208,8 +208,7 @@ void __init efi_init(void) memmap.desc_size = params.desc_size; memmap.desc_version = params.desc_ver; -if (uefi_init () <0 ) -return ; +WARN_ON (uefi_init () <0 );reserve_regions (); }@@ -218,15 +217,13 @@ static int __init arm64_enter_virtual_mode(void) {u64 mapsize; -if (!efi_enabled (EFI_BOOT )) { -pr_info ("EFI services will not be available.\n" ); -return -1 ; - } +if (!efi_enabled (EFI_MEMMAP )) +return 0 ; mapsize = memmap.map_end - memmap.map;early_memunmap (memmap.map, mapsize); -if (efi_runtime_disabled ()) { +if (!efi_enabled (EFI_BOOT ) ||efi_runtime_disabled ()) {pr_info ("EFI runtime services will be disabled.\n" );return -1 ; }Signature · 1 line
1.8.3.2
PATCH 2/8 arm64/efi: register UEFI reserved regions as iomem resources
In reply to Ard BiesheuvelTo prevent device drivers from attaching to device or memory regions owned by the firmware, register all UEFI reserved regions in the iomem resource table at init time.
--- arch/arm64/kernel/efi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
arch/arm64/kernel/efi.c +46 -0
@@ -305,6 +305,50 @@ void efi_virtmap_unload(void)efi_set_pgd (current->active_mm); } +static __init void efi_reserve_iomem_resource (efi_memory_desc_t *md) +{ +struct resource *res; + + res =alloc_bootmem_low (sizeof (*res)); + res->start = md->phys_addr; + res->end = md->phys_addr + (md->num_pages <<EFI_PAGE_SHIFT ) -1 ; + res->flags =IORESOURCE_MEM |IORESOURCE_BUSY ; + +if (!is_reserve_region (md)) { +/* +* Non-RAM regions with the EFI_MEMORY_RUNTIME attribute +* are owned by the UEFI firmware, so make sure they are +* tagged as exclusive: this will prevent device drivers +* from binding to the memory region, and will also prevent +* access via /dev/mem if CONFIG_STRICT_DEVMEM is in effect. +*/ + res->name ="UEFI Runtime [MMIO]" ; + res->flags |=IORESOURCE_EXCLUSIVE ; + }else if (md->type ==EFI_RUNTIME_SERVICES_DATA ) { +/* +* UEFI Runtime Services Data regions may be used to store +* configuration tables such as SMBIOS, which are often +* accessed using userland tools such as 'dmidecode', that +* are /dev/mem based. So don't set the exclusive flag in +* this case. +*/ + res->name ="UEFI Runtime [Data]" ; + }else { +/* +* Register all remaining reserved RAM regions as both busy +* and exclusive in the iomem resource table. This prevents +* drivers from claiming the region, and also disallows +* /dev/mem access. +*/ +if (md->type ==EFI_RUNTIME_SERVICES_CODE ) + res->name ="UEFI Runtime [Code]" ; +else + res->name ="UEFI Reserved" ; + res->flags |=IORESOURCE_EXCLUSIVE ; + } +request_resource (&iomem_resource, res); +} +void __init efi_virtmap_init (void ) {efi_memory_desc_t *md;
@@ -316,6 +360,8 @@ void __init efi_virtmap_init(void)u64 paddr, npages, size;pgprot_t prot; +if (is_reserve_region (md) || md->attribute &EFI_MEMORY_RUNTIME ) +efi_reserve_iomem_resource (md);if (!(md->attribute &EFI_MEMORY_RUNTIME ))continue ; if (WARN(md->virt_addr == 0,
Signature · 1 line
1.8.3.2
PATCH 2/8 arm64/efi: register UEFI reserved regions as iomem resources
Quoted 8 lines · Ard Biesheuvel
To prevent device drivers from attaching to device or memory regions owned by the firmware, register all UEFI reserved regions in the iomem resource table at init time.
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/kernel/efi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
Looks nice.
Just curious, have you actually seen drivers trying to claim these regions?
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
PATCH 2/8 arm64/efi: register UEFI reserved regions as iomem resources
Quoted 10 lines · Matt Fleming
Quoted 8 lines · Ard Biesheuvel
To prevent device drivers from attaching to device or memory regions owned by the firmware, register all UEFI reserved regions in the iomem resource table at init time.
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/kernel/efi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
Quoted 5 lines
Looks nice.
Just curious, have you actually seen drivers trying to claim these regions?
Yes. RTC and NOR flash in particular, which should not appear in the device tree in the first place if the firmware owns them, but let's not assume all firmware vendors will get that right first try,
PATCH 3/8 memblock: add physmem to memblock_dump_all() output
In reply to Ard BiesheuvelIf CONFIG_HAVE_MEMBLOCK_PHYS_MAP is set, there is a third memblock map called 'physmem'. Add it to the output of memblock_dump_all().
--- mm/memblock.c | 3 +++ 1 file changed, 3 insertions(+)
mm/memblock.c +3 -0
@@ -1522,6 +1522,9 @@ void __init_memblock __memblock_dump_all(void)memblock_dump (&memblock.memory,"memory" );memblock_dump (&memblock.reserved,"reserved" ); +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +memblock_dump (&memblock.physmem,"physmem" ); +#endif }void __init memblock_allow_resize (void )
Signature · 1 line
1.8.3.2
Re: [PATCH 3/8] memblock: add physmem to memblock_dump_all() output
(Adding Andrew, linux-mm and lkml)
Quoted 25 lines · Ard Biesheuvel
If
CONFIG_HAVE_MEMBLOCK_PHYS_MAPis set, there is a third memblock map called 'physmem'. Add it to the output ofmemblock_dump_all().Signed-off-by Ard Biesheuvel <[email protected]>--- mm/memblock.c | 3 +++ 1 file changed, 3 insertions(+)mm/memblock.c +3
-0@@ -1522,6 +1522,9 @@ void __init_memblock __memblock_dump_all(void)memblock_dump (&memblock.memory,"memory" );memblock_dump (&memblock.reserved,"reserved" ); +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +memblock_dump (&memblock.physmem,"physmem" ); +#endif }void __init memblock_allow_resize (void )Signature · 1 line
1.8.3.2
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
PATCH 4/8 memblock: introduce memblock_add_phys() and memblock_is_physmem()
In reply to Ard BiesheuvelThis introduces the following functions:
- memblock_add_phys(), that registers regions in the 'physmem' memblock map if CONFIG_HAVE_MEMBLOCK_PHYS_MAP is set; otherwise, it is a nop
- memblock_is_physmem(), returns whether a physical address is classified as physical memory.
--- include/linux/memblock.h | 10 ++++++++++ mm/memblock.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+)
include/linux/memblock.h +10 -0
@@ -365,6 +365,16 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo#define __initdata_memblock#endif +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int memblock_add_phys (phys_addr_t base,phys_addr_t size); +int memblock_is_physmem (phys_addr_t addr); +#else +static inline int memblock_add_phys (phys_addr_t base,phys_addr_t size) +{ +return 0 ; +} +#endif /* CONFIG_HAVE_MEMBLOCK_PHYS_MAP */ +#else static inline phys_addr_t memblock_alloc (phys_addr_t size,phys_addr_t align) {
mm/memblock.c +15 -0
@@ -586,6 +586,14 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) MAX_NUMNODES, 0); } +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int __init_memblock memblock_add_phys(phys_addr_t base, phys_addr_t size) +{ +return memblock_add_range (&memblock.physmem, base, size, +MAX_NUMNODES ,0 ); +} +#endif +/** * memblock_isolate_range - isolate given range into disjoint memblocks * @type: memblock type to isolate range for
@@ -1398,6 +1406,13 @@ int __init_memblock memblock_is_memory(phys_addr_t addr)return memblock_search (&memblock.memory, addr) !=-1 ; } +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int __init_memblock memblock_is_physmem(phys_addr_t addr) +{ +return memblock_search (&memblock.physmem, addr) !=-1 ; +} +#endif +#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP int __init_memblock memblock_search_pfn_nid(unsigned long pfn,unsigned long *start_pfn,unsigned long *end_pfn)
Signature · 1 line
1.8.3.2
Re: [PATCH 4/8] memblock: introduce memblock_add_phys() and memblock_is_physmem()
(Moar reviewers)
Quoted 73 lines · Ard Biesheuvel
This introduces the following functions:
-memblock_add_phys(), that registers regions in the 'physmem' memblock map ifCONFIG_HAVE_MEMBLOCK_PHYS_MAPis set; otherwise, it is a nop
-memblock_is_physmem(), returns whether a physical address is classified as physical memory.Signed-off-by Ard Biesheuvel <[email protected]>--- include/linux/memblock.h | 10 ++++++++++ mm/memblock.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+)include/linux/memblock.h +10
-0@@ -365,6 +365,16 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo#define __initdata_memblock#endif +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int memblock_add_phys (phys_addr_t base,phys_addr_t size); +int memblock_is_physmem (phys_addr_t addr); +#else +static inline int memblock_add_phys (phys_addr_t base,phys_addr_t size) +{ +return 0 ; +} +#endif /* CONFIG_HAVE_MEMBLOCK_PHYS_MAP */ +#else static inline phys_addr_t memblock_alloc (phys_addr_t size,phys_addr_t align) {mm/memblock.c +15
-0@@ -586,6 +586,14 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) MAX_NUMNODES, 0); } +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int __init_memblock memblock_add_phys(phys_addr_t base, phys_addr_t size) +{ +return memblock_add_range (&memblock.physmem, base, size, +MAX_NUMNODES ,0 ); +} +#endif +/** * memblock_isolate_range - isolate given range into disjoint memblocks * @type: memblock type to isolate range for @@ -1398,6 +1406,13 @@ int __init_memblock memblock_is_memory(phys_addr_t addr)return memblock_search (&memblock.memory, addr) !=-1 ; } +#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP +int __init_memblock memblock_is_physmem(phys_addr_t addr) +{ +return memblock_search (&memblock.physmem, addr) !=-1 ; +} +#endif +#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP int __init_memblock memblock_search_pfn_nid(unsigned long pfn,unsigned long *start_pfn,unsigned long *end_pfn)Signature · 6 lines
1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
PATCH 5/8 of: fdt: register physmem in early_init_dt_scan_memory()
In reply to Ard BiesheuvelThis patch changes early_init_dt_scan_memory() so that all memory covered by DT memory nodes is registered in the 'physmem' memblock table if CONFIG_HAVE_MEMBLOCK_PHYS_MAP is enabled.
--- drivers/of/fdt.c | 1 + 1 file changed, 1 insertion(+)
drivers/of/fdt.c +1 -0
@@ -894,6 +894,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, (unsigned long long)size);early_init_dt_add_memory_arch (base, size); +memblock_add_phys (base, size); }return 0 ;
Signature · 1 line
1.8.3.2
PATCH 6/8 arm64/efi: register physmem in reserve_regions()
In reply to Ard BiesheuvelAfter traversing the UEFI memory map to discover the regions that are backed by normal RAM, register the resulting minimal memory map into the physmem memblock table.
--- arch/arm64/kernel/efi.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/arm64/kernel/efi.c +9 -0
@@ -155,6 +155,7 @@ static __init void reserve_regions(void) {efi_memory_desc_t *md;u64 paddr, npages, size; +struct memblock_region *r;if (uefi_debug)pr_info ("Processing EFI memory map:\n" );
@@ -187,6 +188,14 @@ static __init void reserve_regions(void)pr_cont ("\n" ); } +/* +* After memblock has stitched all the regions together, copy the +* resulting map of physical memory from the memory memblock table into +* the physmem memblock table. +*/ +for_each_memblock (memory, r) +memblock_add_phys (r->base, r->size); +set_bit (EFI_MEMMAP , &efi.flags); }
Signature · 1 line
1.8.3.2
PATCH 7/8 arm64: use 'physmem' memblock to improve CONFIG_STRICT_DEVMEM handling
In reply to Ard BiesheuvelThe 'physmem' memblock table allows us to classify memory as RAM even if it is not covered by the ordinary 'memory' memblock table.
Under CONFIG_STRICT_DEVMEM, we can use this to:
- allow read-only access to parts of RAM that are not considered memory by the kernel, this is mainly intended for exposing UEFI configuration tables such as SMBIOS to userland;
- avoid using non-cached mappings for those parts of RAM, as it may result in mismatched attributes.
--- arch/arm64/Kconfig | 1 + arch/arm64/mm/mmap.c | 2 +- arch/arm64/mm/mmu.c | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-)
arch/arm64/Kconfig +1 -0
@@ -60,6 +60,7 @@ config ARM64 select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_PHYS_MAP select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_REGS
arch/arm64/mm/mmap.c +1 -1
@@ -126,7 +126,7 @@ int devmem_is_allowed(unsigned long pfn) {if (iomem_is_exclusive (pfn <<PAGE_SHIFT ))return 0 ; -if (!page_is_ram (pfn)) +if (!pfn_valid (pfn))return 1 ;return 0 ; }
arch/arm64/mm/mmu.c +14 -1
@@ -122,7 +122,7 @@ early_param("cachepolicy", early_cachepolicy);pgprot_t phys_mem_access_prot (struct file *file,unsigned long pfn,unsigned long size,pgprot_t vma_prot) { -if (!pfn_valid (pfn)) +if (!memblock_is_physmem (PFN_PHYS (pfn)))return pgprot_noncached (vma_prot);else if (file->f_flags &O_SYNC )return pgprot_writecombine (vma_prot);
@@ -130,6 +130,19 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, }EXPORT_SYMBOL (phys_mem_access_prot); +/* +* This definition of phys_mem_access_prot_allowed() overrides +* the __weak definition in drivers/char/mem.c +*/ +int phys_mem_access_prot_allowed (struct file *file,unsigned long pfn, +unsigned long size,pgprot_t *prot) +{ +/* Disallow read-write access to system RAM */ +if (memblock_is_physmem (PFN_PHYS (pfn)) &&pgprot_val (*prot) &PTE_WRITE ) +return 0 ; +return 1 ; +} +static void __init *early_alloc (unsigned long sz) {void *ptr =__va (memblock_alloc (sz, sz));
Signature · 1 line
1.8.3.2
PATCH 7/8 arm64: use 'physmem' memblock to improve CONFIG_STRICT_DEVMEM handling
Quoted 9 lines · Ard Biesheuvel
The 'physmem' memblock table allows us to classify memory as RAM even if it is not covered by the ordinary 'memory' memblock table.
Under
CONFIG_STRICT_DEVMEM, we can use this to:
- allow read-only access to parts of RAM that are not considered memory by the kernel, this is mainly intended for exposing UEFI configuration tables such as SMBIOS to userland;
- avoid using non-cached mappings for those parts of RAM, as it may result in mismatched attributes.
Looks fine to me assuming that the rest of the series is ok:
Will
Quoted 69 lines
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/Kconfig | 1 + arch/arm64/mm/mmap.c | 2 +- arch/arm64/mm/mmu.c | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-)arch/arm64/Kconfig +1
-0@@ -60,6 +60,7 @@ config ARM64 select HAVE_GENERIC_DMA_COHERENT select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_MEMBLOCK + select HAVE_MEMBLOCK_PHYS_MAP select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_REGSarch/arm64/mm/mmap.c +1
-1@@ -126,7 +126,7 @@ int devmem_is_allowed(unsigned long pfn) {if (iomem_is_exclusive (pfn <<PAGE_SHIFT ))return 0 ; -if (!page_is_ram (pfn)) +if (!pfn_valid (pfn))return 1 ;return 0 ; }arch/arm64/mm/mmu.c +14
-1@@ -122,7 +122,7 @@ early_param("cachepolicy", early_cachepolicy);pgprot_t phys_mem_access_prot (struct file *file,unsigned long pfn,unsigned long size,pgprot_t vma_prot) { -if (!pfn_valid (pfn)) +if (!memblock_is_physmem (PFN_PHYS (pfn)))return pgprot_noncached (vma_prot);else if (file->f_flags &O_SYNC )return pgprot_writecombine (vma_prot);@@ -130,6 +130,19 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, }EXPORT_SYMBOL (phys_mem_access_prot); +/* +* This definition of phys_mem_access_prot_allowed() overrides +* the __weak definition in drivers/char/mem.c +*/ +int phys_mem_access_prot_allowed (struct file *file,unsigned long pfn, +unsigned long size,pgprot_t *prot) +{ +/* Disallow read-write access to system RAM */ +if (memblock_is_physmem (PFN_PHYS (pfn)) &&pgprot_val (*prot) &PTE_WRITE ) +return 0 ; +return 1 ; +} +static void __init *early_alloc (unsigned long sz) {void *ptr =__va (memblock_alloc (sz, sz));Signature · 1 line
1.8.3.2
PATCH 8/8 arm64/efi: memblock_remove rather than _reserve UEFI reserved RAM
In reply to Ard BiesheuvelNow that we have the 'physmem' memblock table to keep track of physical RAM regions, we can start using memblock_remove() to eliminate UEFI reserved regions from the 'memory' memblock table and the kernel direct linear mapping entirely. This makes these regions inaccessible entirely, unless they are remapped explicitly by the UEFI Runtime Services layer, UEFI configuration table drivers or the ACPI layer.
--- arch/arm64/kernel/efi.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
arch/arm64/kernel/efi.c +12 -10
@@ -167,7 +167,7 @@ static __init void reserve_regions(void)if (uefi_debug) {char buf[64 ]; -pr_info (" 0x%012llx-0x%012llx %s" , +pr_info (" 0x%012llx-0x%012llx %s\n" , paddr, paddr + (npages <<EFI_PAGE_SHIFT ) -1 ,efi_md_typeattr_format (buf,sizeof (buf), md)); }
@@ -177,15 +177,6 @@ static __init void reserve_regions(void)if (is_normal_ram (md))early_init_dt_add_memory_arch (paddr, size); - -if (is_reserve_region (md)) { -memblock_reserve (paddr, size); -if (uefi_debug) -pr_cont ("*" ); - } - -if (uefi_debug) -pr_cont ("\n" ); }/*
@@ -196,7 +187,18 @@ static __init void reserve_regions(void)for_each_memblock (memory, r)memblock_add_phys (r->base, r->size); +for_each_efi_memory_desc (&memmap, md) { +if (is_reserve_region (md)) { + paddr = md->phys_addr; + npages = md->num_pages; +memrange_efi_to_native (&paddr, &npages); +memblock_remove (paddr, npages <<PAGE_SHIFT ); + } + } +set_bit (EFI_MEMMAP , &efi.flags); +if (uefi_debug) +__memblock_dump_all (); }void __init efi_init (void )
Signature · 1 line
1.8.3.2
cover arm64: improved memory map handling for /dev/mem, ACPI etc
In reply to Ard BiesheuvelQuoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.
Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAM
Ard, It is much cleaner for this splitting.
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Thanks
Dave
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAM
Quoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to memblock_reserve() the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that memblock_is_physmem() now serves the purpose of page_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.
Thanks,
Ard.
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.
Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 6 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.
I will do some test later along with the stable mapping stuff.
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that virt_to_phys return same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.
Thanks
Dave
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 70 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 1 line
Quoted 8 lines
Quoted 5 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.I will do some test later along with the stable mapping stuff.
Cheers.
Quoted 6 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.
No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
Signature · 1 line
Ard.
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 71 lines · Ard Biesheuvel
Quoted 70 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 1 line
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.I will do some test later along with the stable mapping stuff.
The whole patchset works well without the last patch.
I found that patch 8/8 caused system boot hangs very early. Just after stub print something about virtmap..
Any idea about it? I tested your patches upon 3.18.
Quoted 11 lines
Quoted 1 line
Cheers.
Quoted 6 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.
Quoted 3 lines
No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
It was caused by uefi sys table/mmap start addresses changes.
I generate dtb from acpi=off boot /proc/device-tree, and use the dtb for kexec boot, but seems mmap addresses changes sometimes.
Do you know have plan or status in Linaro for exporting dtb for acpi booting?
Thanks
Dave
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 78 lines · Dave Young
Quoted 77 lines · Ard Biesheuvel
Quoted 76 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 6 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.
Quoted 7 lines
Quoted 1 line
Quoted 1 line
I will do some test later along with the stable mapping stuff.
The whole patchset works well without the last patch.
I found that patch 8/8 caused system boot hangs very early. Just after stub print something about virtmap..
Which platform is this?
Do you have earlycon enabled?
Quoted 2 lines
Any idea about it? I tested your patches upon 3.18.
I suppose you tested both the virtmap series and this one, but did you also take the 3.19 changes we did for UEFI? Not sure it would make a difference, though.
Quoted 11 lines
Quoted 10 lines
Quoted 6 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
Quoted 6 lines
It was caused by uefi sys table/mmap start addresses changes.
I generate dtb from acpi=off boot/proc/device-tree, and use the dtb for kexec boot, but seems mmap addresses changes sometimes.Do you know have plan or status in Linaro for exporting dtb for acpi booting?
We have this patch upstream now
08d53aa58cb1 of/fdt: export fdt blob as /sys/firmware/fdt
which exports whatever FDT the kernel received from the bootloader or the EFI stub, regardless of whether the kernel uses DT or not.
Signature · 1 line
Ard.
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 81 lines · Ard Biesheuvel
Quoted 80 lines · Dave Young
Quoted 78 lines · Ard Biesheuvel
Quoted 77 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 6 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.I will do some test later along with the stable mapping stuff.
Quoted 8 lines
Quoted 5 lines
The whole patchset works well without the last patch.
I found that patch 8/8 caused system boot hangs very early. Just after stub print something about virtmap..
Which platform is this?
Do you have earlycon enabled?
It is apm mustang, earlycon was enabled.
Quoted 7 lines
Quoted 3 lines
Any idea about it? I tested your patches upon 3.18.
I suppose you tested both the virtmap series and this one, but did you also take the 3.19 changes we did for UEFI? Not sure it would make a difference, though.
Yes, both virtmap series and this one, I did not take UEFI 3.19 changes, Which patchset do you have in mind? If no clue I will try rebase to test 3.19
Quoted 19 lines
Quoted 12 lines
Quoted 11 lines
Quoted 7 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
Quoted 6 lines
It was caused by uefi sys table/mmap start addresses changes.
I generate dtb from acpi=off boot/proc/device-tree, and use the dtb for kexec boot, but seems mmap addresses changes sometimes.Do you know have plan or status in Linaro for exporting dtb for acpi booting?
Quoted 6 lines
We have this patch upstream now
08d53aa58cb1of/fdt: export fdt blob as/sys/firmware/fdtwhich exports whatever FDT the kernel received from the bootloader or the EFI stub, regardless of whether the kernel uses DT or not.
Great, will try.
Thanks
Dave
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 84 lines · Dave Young
Quoted 83 lines · Ard Biesheuvel
Quoted 82 lines · Dave Young
Quoted 71 lines · Ard Biesheuvel
Quoted 70 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 1 line
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.I will do some test later along with the stable mapping stuff.
The whole patchset works well without the last patch.
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
I found that patch 8/8 caused system boot hangs very early. Just after stub print something about virtmap..
Which platform is this?
Do you have earlycon enabled?It is apm mustang, earlycon was enabled.
That's odd. reserve_regions() is called after uefi_init(), and the latter prints the EFI: string, so I don't think the patch should affect anything else before that either. Could you please double check if you do see the console enabled/disabled messages?
Quoted 11 lines
Quoted 7 lines
Quoted 3 lines
Any idea about it? I tested your patches upon 3.18.
I suppose you tested both the virtmap series and this one, but did you also take the 3.19 changes we did for UEFI? Not sure it would make a difference, though.
Yes, both virtmap series and this one, I did not take UEFI 3.19 changes, Which patchset do you have in mind? If no clue I will try rebase to test 3.19
Well, there is patch 61139eb04056bba69aeef6c481802c4ea028bf4d that changes the definition of is_reserve_region(), which may or may not be relevant. Other than that, I don't think any of those patches could make a difference here.
Quoted 30 lines
Quoted 19 lines
Quoted 12 lines
Quoted 11 lines
Quoted 7 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
Quoted 6 lines
It was caused by uefi sys table/mmap start addresses changes.
I generate dtb from acpi=off boot/proc/device-tree, and use the dtb for kexec boot, but seems mmap addresses changes sometimes.Do you know have plan or status in Linaro for exporting dtb for acpi booting?
Quoted 6 lines
We have this patch upstream now
08d53aa58cb1of/fdt: export fdt blob as/sys/firmware/fdtwhich exports whatever FDT the kernel received from the bootloader or the EFI stub, regardless of whether the kernel uses DT or not.
Great, will try.
Thanks
Dave
cover arm64: improved memory map handling for /dev/mem, ACPI etc
Quoted 92 lines · Ard Biesheuvel
Quoted 91 lines · Dave Young
Quoted 89 lines · Ard Biesheuvel
Quoted 78 lines · Dave Young
Quoted 77 lines · Ard Biesheuvel
Quoted 76 lines · Dave Young
Quoted 57 lines · Ard Biesheuvel
Quoted 47 lines · Dave Young
Quoted 36 lines · Ard Biesheuvel
This series was split off from the UEFI virtmap for kexec series that I posted earlier today. The main purpose is to deal with the need to classify memory ranges as RAM or non-RAM in a consistent and comprehensive manner. This series applies on top of the other series.
Patch #1 avoids an early panic if the UEFI memory map is available but UEFI support itself fails to initialize. In this case, there is no need to panic early, and we have a better chance of being able to inform the user if we deal with this error condition at a later time.
Patch #2 adds iomem resource registration of UEFI memory regions. This is necessary because otherwise, drivers could potentially claim regions that are in active use by the firmware. This applies to both MMIO (NOR flash, RTC) and RAM ranges (runtime services code and data).
Patch #3-6 adds support to UEFI and non-UEFI code paths to record all memory known to the system in the 'physmem' memblock table (if enabled). This fulfils a need in the
/dev/memand (upcoming) ACPI layers to be able to classify ranges as being backed by normal RAM even if they are not covered by the 'memory' memblock table, and are hence not covered by the linear direct mapping. The physmem code is pre-existing code that only needs minor tweaking to be made suitable for this purpose.Patch #7 enables the 'physmem' memblock table for arm64, and wires it into the handling of
/dev/memmappings, both to decide whether it should be mapped asMT_NORMAL, and whether read-write access can be allowed. (Non-RAM regions can be mapped read-write as long as they are not claimed by a driver in the iomem resource table. RAM regions can only be mapped read-only, and only if they are not covered by the 'memory' memblock table, and hence not covered by the linear mapping)Finally, patch #8 changes the way the virtual memory map is handled by the early UEFI code. Specifically, it memblock_remove()s rather than
_reserves()UEFI reserved RAM regions, so that they are removed entirely from the linear mapping.Quoted 9 lines
Ard Biesheuvel (8):
arm64/efi: use UEFI memory map unconditionally if available arm64/efi: register UEFI reserved regions as iomem resources
memblock: add physmem tomemblock_dump_all()output
memblock: introducememblock_add_phys()andmemblock_is_physmem()
of: fdt: register physmem inearly_init_dt_scan_memory()arm64/efi: register physmem inreserve_regions()
arm64: use 'physmem' memblock to improveCONFIG_STRICT_DEVMEMhandling arm64/efi:memblock_removerather than_reserveUEFI reserved RAMQuoted 2 lines
Ard, It is much cleaner for this splitting.
Thanks for having a look.
Quoted 3 lines
I wonder if some of them can become general code such as register reserved regions as iomem resources?
Quoted 7 lines
AFAICT, the x86 code adds reservations for such regions to the E820 memory map, which in turn is used to
memblock_reserve()the actual memory. Also, sharing of the RTC is handled with a dedicated mutex in the runtime services wrapper code (and x86 does not even use the time related runtime services as they are broken on many firmware implementations) so blindly applying the same logic to x86 or ia64 would likely break stuff.Ok, I think bootloader will pass the E820 ranges though it can not tell which region is for what.
Quoted 6 lines
Do you (or Mark) have any feedback on the utility of this series in the ACPI context? I failed to mention in the cover letter that
memblock_is_physmem()now serves the purpose ofpage_is_ram(), i.e., whether a physical region is backed by a slice of RAM that was left out of the kernel's linear mapping.Quoted 7 lines
Quoted 1 line
Quoted 1 line
I will do some test later along with the stable mapping stuff.
The whole patchset works well without the last patch.
I found that patch 8/8 caused system boot hangs very early. Just after stub print something about virtmap..
Which platform is this?
Do you have earlycon enabled?
Quoted 7 lines
Quoted 2 lines
It is apm mustang, earlycon was enabled.
That's odd.
reserve_regions()is called afteruefi_init(), and the latter prints the EFI: string, so I don't think the patch should affect anything else before that either. Could you please double check if you do see the console enabled/disabled messages?
Will check, but I did not change the kernel params..
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
Any idea about it? I tested your patches upon 3.18.
I suppose you tested both the virtmap series and this one, but did you also take the 3.19 changes we did for UEFI? Not sure it would make a difference, though.
Quoted 8 lines
Quoted 3 lines
Yes, both virtmap series and this one, I did not take UEFI 3.19 changes, Which patchset do you have in mind? If no clue I will try rebase to test 3.19
Well, there is patch
61139eb04056bba69aeef6c481802c4ea028bf4dthat changes the definition ofis_reserve_region(), which may or may not be relevant. Other than that, I don't think any of those patches could make a difference here.
Ok, I have no machine on hand currently, will do some debugging once I have one.
Quoted 31 lines
Quoted 31 lines
Quoted 20 lines
Quoted 13 lines
Quoted 9 lines
Quoted 8 lines
BTW, with previous stable mapping patches on modified 3.18 tree kexec kernel panics because of damaged efi mempry map arrays. It contains some random value instead of right addresses so that
virt_to_physreturn same value for vendor field. Will do more debugging maybe I missed something. Any clue for debugging above issue will be appreciated.Quoted 3 lines
No clues, unfortunately. The memory map is not used after early boot, so it may be getting clobbered at any point between the first boot and the second boot.
Quoted 6 lines
It was caused by uefi sys table/mmap start addresses changes.
I generate dtb from acpi=off boot/proc/device-tree, and use the dtb for kexec boot, but seems mmap addresses changes sometimes.Do you know have plan or status in Linaro for exporting dtb for acpi booting?
Quoted 6 lines
We have this patch upstream now
08d53aa58cb1of/fdt: export fdt blob as/sys/firmware/fdtwhich exports whatever FDT the kernel received from the bootloader or the EFI stub, regardless of whether the kernel uses DT or not.
Great, will try.
Thanks
Dave