1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-06-05 02:20:30 +00:00

arm/linux-yocto: refresh skip-unavailable-memory.patch

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Ross Burton
2022-05-17 11:31:12 +01:00
committed by Jon Mason
parent 9ef44ec196
commit a3a6597cfd
@@ -1,38 +1,75 @@
When in secure mode, qemu's devicetree has the following node to mark the
secure memory as off-limits to non-secure environments:
Backported to 5.15.
secram@e000000 {
secure-status = "okay";
status = "disabled";
reg = <0x00 0xe000000 0x00 0x1000000>;
device_type = "memory";
};
However, the kernel doesn't think that means the memory is off-limits:
Early memory node ranges
node 0: [mem 0x000000000e000000-0x000000000e0fffff]
And not far into the boot accesses this region and crashes:
Internal error: synchronous external abort: 96000050 15 PREEMPT SMP
This used to work more through luck than judgement, but recent changes to
memory zoning[1] means this region is accessed more frequently.
At present there is debate between qemu and kernel engineers over whether
the kernel should be ignoring regions marked like this, or if qemu
should block out the region in a different way. Until this is resolved,
we can make a choice and simply ignore memory ranges that are marked
as disabled.
Upstream-Status: Pending [discussion ongoing]
Upstream-Status: Submitted [https://lore.kernel.org/linux-arm-kernel/20220517101410.3493781-1-andre.przywara@arm.com/T/#u]
Signed-off-by: Ross Burton <ross.burton@arm.com>
[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=35ec3d09ff6a49ee90e1bfd09166596f017eb5bb
From 7bfeda1c9224270af97adf799ce0b5a4292bceb6 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Tue, 17 May 2022 11:14:10 +0100
Subject: [PATCH] of/fdt: Ignore disabled memory nodes
When we boot a machine using a devicetree, the generic DT code goes
through all nodes with a 'device_type = "memory"' property, and collects
all memory banks mentioned there. However it does not check for the
status property, so any nodes which are explicitly "disabled" will still
be added as a memblock.
This ends up badly for QEMU, when booting with secure firmware on
arm/arm64 machines, because QEMU adds a node describing secure-only
memory:
===================
secram@e000000 {
secure-status = "okay";
status = "disabled";
reg = <0x00 0xe000000 0x00 0x1000000>;
device_type = "memory";
};
===================
The kernel will eventually use that memory block (which is located below
the main DRAM bank), but accesses to that will be answered with an
SError:
===================
[ 0.000000] Internal error: synchronous external abort: 96000050 [#1] PREEMPT SMP
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc6-00014-g10c8acb8b679 #524
[ 0.000000] Hardware name: linux,dummy-virt (DT)
[ 0.000000] pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.000000] pc : new_slab+0x190/0x340
[ 0.000000] lr : new_slab+0x184/0x340
[ 0.000000] sp : ffff80000a4b3d10
....
==================
The actual crash location and call stack will be somewhat random, and
depend on the specific allocation of that physical memory range.
As the DT spec[1] explicitly mentions standard properties, add a simple
check to skip over disabled memory nodes, so that we only use memory
that is meant for non-secure code to use.
That fixes booting a QEMU arm64 VM with EL3 enabled ("secure=on"), when
not using UEFI. In this case the QEMU generated DT will be handed on
to the kernel, which will see the secram node.
This issue is reproducible when using TF-A together with U-Boot as
firmware, then booting with the "booti" command.
When using U-Boot as an UEFI provider, the code there [2] explicitly
filters for disabled nodes when generating the UEFI memory map, so we
are safe.
EDK/2 only reads the first bank of the first DT memory node [3] to learn
about memory, so we got lucky there.
[1] https://github.com/devicetree-org/devicetree-specification/blob/main/source/chapter3-devicenodes.rst#memory-node (after the table)
[2] https://source.denx.de/u-boot/u-boot/-/blob/master/lib/fdtdec.c#L1061-1063
[3] https://github.com/tianocore/edk2/blob/master/ArmVirtPkg/PrePi/FdtParser.c
Reported-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/of/fdt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 59a7a9ee58ef..d151a31adbf9 100644
index 59a7a9ee58ef..5439c899fe04 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1102,6 +1102,9 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
@@ -45,3 +82,5 @@ index 59a7a9ee58ef..d151a31adbf9 100644
reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
if (reg == NULL)
reg = of_get_flat_dt_prop(node, "reg", &l);
--
2.25.1