lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 187/879] of/fdt: Ignore disabled memory nodes
    Date
    From: Andre Przywara <andre.przywara@arm.com>

    [ Upstream commit df5cd369876114f91f9ae60658fea80acfb15890 ]

    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>
    Signed-off-by: Rob Herring <robh@kernel.org>
    Link: https://lore.kernel.org/r/20220517101410.3493781-1-andre.przywara@arm.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/of/fdt.c | 3 +++
    1 file changed, 3 insertions(+)

    diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
    index ec315b060cd5..0f30496ce80b 100644
    --- a/drivers/of/fdt.c
    +++ b/drivers/of/fdt.c
    @@ -1105,6 +1105,9 @@ int __init early_init_dt_scan_memory(void)
    if (type == NULL || strcmp(type, "memory") != 0)
    continue;

    + if (!of_fdt_device_is_available(fdt, node))
    + continue;
    +
    reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l);
    if (reg == NULL)
    reg = of_get_flat_dt_prop(node, "reg", &l);
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-08 00:19    [W:2.979 / U:0.380 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site