All patches automatically rebased Build system: x86_64 Build-tested: bcm2711/RPi4B, mt7622/RT3200 Run-tested: bcm2711/RPi4B, mt7622/RT3200 Signed-off-by: John Audia <therealgraysky@proton.me>
		
			
				
	
	
		
			108 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 48342ae751c797ac73ac9c894b3f312df18ffd21 Mon Sep 17 00:00:00 2001
 | 
						|
From: Geert Uytterhoeven <geert+renesas@glider.be>
 | 
						|
Date: Wed, 15 Sep 2021 13:46:20 +0100
 | 
						|
Subject: [PATCH] ARM: 9124/1: uncompress: Parse "linux,usable-memory-range" DT
 | 
						|
 property
 | 
						|
 | 
						|
Add support for parsing the "linux,usable-memory-range" DT property.
 | 
						|
This property is used to describe the usable memory reserved for the
 | 
						|
crash dump kernel, and thus makes the memory reservation explicit.
 | 
						|
If present, Linux no longer needs to mask the program counter, and rely
 | 
						|
on the "mem=" kernel parameter to obtain the start and size of usable
 | 
						|
memory.
 | 
						|
 | 
						|
For backwards compatibility, the traditional method to derive the start
 | 
						|
of memory is still used if "linux,usable-memory-range" is absent.
 | 
						|
 | 
						|
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
 | 
						|
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
 | 
						|
Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
 | 
						|
---
 | 
						|
 .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++++++++++---
 | 
						|
 1 file changed, 42 insertions(+), 6 deletions(-)
 | 
						|
 | 
						|
--- 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 *c
 | 
						|
  * 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 me
 | 
						|
 	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 me
 | 
						|
 
 | 
						|
 			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 me
 | 
						|
 	}
 | 
						|
 
 | 
						|
 	/*
 | 
						|
-	 * 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.
 | 
						|
 	 */
 |