blob: c5dac6aaf237572852418950588bcec05df34883 [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001Backported to 5.15.
2
3Upstream-Status: Submitted [https://lore.kernel.org/linux-arm-kernel/20220517101410.3493781-1-andre.przywara@arm.com/T/#u]
4Signed-off-by: Ross Burton <ross.burton@arm.com>
5
6From 7bfeda1c9224270af97adf799ce0b5a4292bceb6 Mon Sep 17 00:00:00 2001
7From: Andre Przywara <andre.przywara@arm.com>
8Date: Tue, 17 May 2022 11:14:10 +0100
9Subject: [PATCH] of/fdt: Ignore disabled memory nodes
10
11When we boot a machine using a devicetree, the generic DT code goes
12through all nodes with a 'device_type = "memory"' property, and collects
13all memory banks mentioned there. However it does not check for the
14status property, so any nodes which are explicitly "disabled" will still
15be added as a memblock.
16This ends up badly for QEMU, when booting with secure firmware on
17arm/arm64 machines, because QEMU adds a node describing secure-only
18memory:
19===================
20 secram@e000000 {
21 secure-status = "okay";
22 status = "disabled";
23 reg = <0x00 0xe000000 0x00 0x1000000>;
24 device_type = "memory";
25 };
26===================
27
28The kernel will eventually use that memory block (which is located below
29the main DRAM bank), but accesses to that will be answered with an
30SError:
31===================
32[ 0.000000] Internal error: synchronous external abort: 96000050 [#1] PREEMPT SMP
33[ 0.000000] Modules linked in:
34[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc6-00014-g10c8acb8b679 #524
35[ 0.000000] Hardware name: linux,dummy-virt (DT)
36[ 0.000000] pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
37[ 0.000000] pc : new_slab+0x190/0x340
38[ 0.000000] lr : new_slab+0x184/0x340
39[ 0.000000] sp : ffff80000a4b3d10
40....
41==================
42The actual crash location and call stack will be somewhat random, and
43depend on the specific allocation of that physical memory range.
44
45As the DT spec[1] explicitly mentions standard properties, add a simple
46check to skip over disabled memory nodes, so that we only use memory
47that is meant for non-secure code to use.
48
49That fixes booting a QEMU arm64 VM with EL3 enabled ("secure=on"), when
50not using UEFI. In this case the QEMU generated DT will be handed on
51to the kernel, which will see the secram node.
52This issue is reproducible when using TF-A together with U-Boot as
53firmware, then booting with the "booti" command.
54
55When using U-Boot as an UEFI provider, the code there [2] explicitly
56filters for disabled nodes when generating the UEFI memory map, so we
57are safe.
58EDK/2 only reads the first bank of the first DT memory node [3] to learn
59about memory, so we got lucky there.
60
61[1] https://github.com/devicetree-org/devicetree-specification/blob/main/source/chapter3-devicenodes.rst#memory-node (after the table)
62[2] https://source.denx.de/u-boot/u-boot/-/blob/master/lib/fdtdec.c#L1061-1063
63[3] https://github.com/tianocore/edk2/blob/master/ArmVirtPkg/PrePi/FdtParser.c
64
65Reported-by: Ross Burton <ross.burton@arm.com>
66Signed-off-by: Andre Przywara <andre.przywara@arm.com>
67---
68 drivers/of/fdt.c | 3 +++
69 1 file changed, 3 insertions(+)
70
71diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
72index 59a7a9ee58ef..5439c899fe04 100644
73--- a/drivers/of/fdt.c
74+++ b/drivers/of/fdt.c
75@@ -1102,6 +1102,9 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
76 if (type == NULL || strcmp(type, "memory") != 0)
77 return 0;
78
79+ if (!of_fdt_device_is_available(initial_boot_params, node))
80+ return 0;
81+
82 reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
83 if (reg == NULL)
84 reg = of_get_flat_dt_prop(node, "reg", &l);
85--
862.25.1