diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-02 11:33:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-11-02 11:33:15 -0700 |
commit | ab2e7f4b46bf8fccf088ec496b3bb26b43e91340 (patch) | |
tree | 0a3010aa08436bdee650fbf4d0371b8d17555ff3 /arch/arm/boot/compressed | |
parent | d7e0a795bf37a13554c80cfc5ba97abedf53f391 (diff) | |
parent | 11779842dd6f59505f5685bdd6ebaaa7a5bc1d94 (diff) |
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King:
- Rejig task/thread info to place thread info in task struct
- Amba bus cleanups (removing unused functions)
- Handle Amba device probe without IRQ domains
- Parse linux,usable-memory-range in decompressor
- Mark OCRAM as read-only after initialisation
- Refactor page fault handling
- Fix PXN handling with LPAE kernels
- Warning and build fixes from Arnd
* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm: (32 commits)
ARM: 9151/1: Thumb2: avoid __builtin_thread_pointer() on Clang
ARM: 9150/1: Fix PID_IN_CONTEXTIDR regression when THREAD_INFO_IN_TASK=y
ARM: 9147/1: add printf format attribute to early_print()
ARM: 9146/1: RiscPC needs older gcc version
ARM: 9145/1: patch: fix BE32 compilation
ARM: 9144/1: forbid ftrace with clang and thumb2_kernel
ARM: 9143/1: add CONFIG_PHYS_OFFSET default values
ARM: 9142/1: kasan: work around LPAE build warning
ARM: 9140/1: allow compile-testing without machine record
ARM: 9137/1: disallow CONFIG_THUMB with ARMv4
ARM: 9136/1: ARMv7-M uses BE-8, not BE-32
ARM: 9135/1: kprobes: address gcc -Wempty-body warning
ARM: 9101/1: sa1100/assabet: convert LEDs to gpiod APIs
ARM: 9131/1: mm: Fix PXN process with LPAE feature
ARM: 9130/1: mm: Provide die_kernel_fault() helper
ARM: 9126/1: mm: Kill page table base print in show_pte()
ARM: 9127/1: mm: Cleanup access_error()
ARM: 9129/1: mm: Kill task_struct argument for __do_page_fault()
ARM: 9128/1: mm: Refactor the __do_page_fault()
ARM: imx6: mark OCRAM mapping read-only
...
Diffstat (limited to 'arch/arm/boot/compressed')
-rw-r--r-- | arch/arm/boot/compressed/fdt_check_mem_start.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/arch/arm/boot/compressed/fdt_check_mem_start.c b/arch/arm/boot/compressed/fdt_check_mem_start.c index 62450d824c3c..9291a2661bdf 100644 --- a/arch/arm/boot/compressed/fdt_check_mem_start.c +++ b/arch/arm/boot/compressed/fdt_check_mem_start.c @@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *cells, uint32_t ncells) * DTB, and, if out-of-range, replace it by the real start address. * To preserve backwards compatibility (systems reserving a block of memory * at the start of physical memory, kdump, ...), the traditional method is - * always used if it yields a valid address. + * used if it yields a valid address, unless the "linux,usable-memory-range" + * property is present. * * Return value: start address of physical memory to use */ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt) { - uint32_t addr_cells, size_cells, base; + uint32_t addr_cells, size_cells, usable_base, base; uint32_t fdt_mem_start = 0xffffffff; - const fdt32_t *reg, *endp; - uint64_t size, end; + const fdt32_t *usable, *reg, *endp; + uint64_t size, usable_end, end; const char *type; int offset, len; @@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt) if (addr_cells > 2 || size_cells > 2) return mem_start; + /* + * Usable memory in case of a crash dump kernel + * This property describes a limitation: memory within this range is + * only valid when also described through another mechanism + */ + usable = get_prop(fdt, "/chosen", "linux,usable-memory-range", + (addr_cells + size_cells) * sizeof(fdt32_t)); + if (usable) { + size = get_val(usable + addr_cells, size_cells); + if (!size) + return mem_start; + + if (addr_cells > 1 && fdt32_ld(usable)) { + /* Outside 32-bit address space */ + return mem_start; + } + + usable_base = fdt32_ld(usable + addr_cells - 1); + usable_end = usable_base + size; + } + /* Walk all memory nodes and regions */ for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0; offset = fdt_next_node(fdt, offset, NULL)) { @@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt) base = fdt32_ld(reg + addr_cells - 1); end = base + size; - if (mem_start >= base && mem_start < end) { + if (usable) { + /* + * Clip to usable range, which takes precedence + * over mem_start + */ + if (base < usable_base) + base = usable_base; + + if (end > usable_end) + end = usable_end; + + if (end <= base) + continue; + } else if (mem_start >= base && mem_start < end) { /* Calculated address is valid, use it */ return mem_start; } @@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt) } /* - * The calculated address is not usable. + * The calculated address is not usable, or was overridden by the + * "linux,usable-memory-range" property. * Use the lowest usable physical memory address from the DTB instead, * and make sure this is a multiple of 2 MiB for phys/virt patching. */ |