[PATCH 1/2] ARM: take memreserve FDT entries into account when discovering base of RAM
Ard Biesheuvel
ardb at kernel.org
Mon Jan 11 05:30:19 EST 2021
As an enhancement to the newly added logic to cross-reference the base
of DRAM calculated by rounding the decompressor load address against the
memory nodes in the DT, take /memreserve/ entries into account as well.
This ensures that DT platforms that currently rely on TEXT_OFFSET to be
increased in order to stay clear of memory reservations no longer need
this hack in the future.
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
arch/arm/boot/compressed/Makefile | 2 ++
arch/arm/boot/compressed/fdt_check_mem_start.c | 35 +++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index fd94e27ba4fa..cf8cfe3f286c 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -96,6 +96,8 @@ endif
$(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \
$(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector))
+CFLAGS_fdt_check_mem_start.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+
# These were previously generated C files. When you are building the kernel
# with O=, make sure to remove the stale files in the output tree. Otherwise,
# the build system wrongly compiles the stale ones.
diff --git a/arch/arm/boot/compressed/fdt_check_mem_start.c b/arch/arm/boot/compressed/fdt_check_mem_start.c
index 62450d824c3c..f81ed6ae9776 100644
--- a/arch/arm/boot/compressed/fdt_check_mem_start.c
+++ b/arch/arm/boot/compressed/fdt_check_mem_start.c
@@ -4,6 +4,19 @@
#include <linux/libfdt.h>
#include <linux/sizes.h>
+/*
+ * The ARM kernel only uses part of the 32 KiB TEXT_OFFSET window at the start
+ * of the uncompressed image, and some platforms rely on this, and have placed
+ * reserved regions right before it. This means we should only consider an
+ * overlap to be a collision if the reserved region covers the area that we
+ * actually use for page tables.
+ */
+#ifdef CONFIG_ARM_LPAE
+#define TEXT_OFFSET_FREE (TEXT_OFFSET - 0x5000)
+#else
+#define TEXT_OFFSET_FREE (TEXT_OFFSET - 0x4000)
+#endif
+
static const void *get_prop(const void *fdt, const char *node_path,
const char *property, int minlen)
{
@@ -44,6 +57,24 @@ static uint64_t get_val(const fdt32_t *cells, uint32_t ncells)
return r;
}
+static void clip_reserved_regions(const void *fdt, uint32_t *base, uint64_t *end)
+{
+ int i;
+
+ for (i = 0; i < fdt_num_mem_rsv(fdt); i++) {
+ uint64_t address, size;
+
+ if (fdt_get_mem_rsv(fdt, i, &address, &size))
+ return;
+
+ if (*base >= address && *base < (address + size))
+ *base = address + size;
+
+ if (*end >= address && *end < (address + size))
+ *end = address;
+ }
+}
+
/*
* Check the start of physical memory
*
@@ -107,7 +138,9 @@ 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) {
+ clip_reserved_regions(fdt, &base, &end);
+ if (mem_start + TEXT_OFFSET_FREE >= base &&
+ mem_start < end) {
/* Calculated address is valid, use it */
return mem_start;
}
--
2.17.1
More information about the linux-arm-kernel
mailing list