[PATCH v3 21/23] platform: generic: mips eyeq7h: prohibit accessing memory beyond DRAM

Vladimir Kondratiev vladimir.kondratiev at mobileye.com
Mon Feb 23 06:55:00 PST 2026


SBI code arranges domain PMP regions in a way that last entry is
all-inclusive "0..~0 RWX" and the rest of entries are not programmed.
This causes a problem for the eyeq7h.

CPU can issue speculative prefetches to non-existent addresses. If this
access goes to the system NOC, it is mis-interpreted as an access
violation and error is reported, forcing system reset.

To prevent such a speculative transaction to leave a CPU cluster,
block it using PMP, by restricting memory region to physically present
memory. To achieve this, on early init:

- update flags for the last all-inclusive "0..~0 RWX" entry to be
  inaccessible MMIO. MMIO serves to set up PMA attributes to uncached
  non-prefetchable, preventing transactions to reach system NOC
- add an all-permissive entry matching DRAM.

Resulting memory regions:

Domain0 Region00            : 0x0000000800100000-0x000000080013ffff M: (F,R,X) S/U: ()
Domain0 Region01            : 0x0000000800100000-0x00000008001fffff M: (F,R,W) S/U: ()
Domain0 Region02            : 0x0000000048700000-0x000000004870ffff M: (I,R,W) S/U: ()
Domain0 Region03            : 0x0000000067480000-0x000000006748ffff M: (I,R,W) S/U: ()
Domain0 Region04            : 0x0000000067500000-0x000000006750ffff M: (I,R,W) S/U: ()
Domain0 Region05            : 0x0000000048740000-0x000000004875ffff M: (I,R,W) S/U: ()
Domain0 Region06            : 0x00000000674c0000-0x00000000674dffff M: (I,R,W) S/U: ()
Domain0 Region07            : 0x0000000067540000-0x000000006755ffff M: (I,R,W) S/U: ()
Domain0 Region08            : 0x0000000000000000-0x000000007fffffff M: (I,R,W) S/U: (R,W)
Domain0 Region09            : 0x0000000800000000-0x00000008ffffffff M: () S/U: (R,W,X)
Domain0 Region10            : 0x0000001000000000-0x0000001fffffffff M: (I) S/U: (R,W)
Domain0 Region11            : 0x0000000000000000-0xffffffffffffffff M: (I) S/U: ()

Here Region09 covers DRAM, region 11 set to non-accessible
uncached no-prefetch for the entire address range

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>
---
 platform/generic/mips/eyeq7h.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/platform/generic/mips/eyeq7h.c b/platform/generic/mips/eyeq7h.c
index 04ab5286ed95284f737b7a1dd0ba035d42e58949..f09ec5f0fae4abec29ec9c15080411b0da7bbbde 100644
--- a/platform/generic/mips/eyeq7h.c
+++ b/platform/generic/mips/eyeq7h.c
@@ -14,6 +14,7 @@
 #include <sbi/sbi_timer.h>
 #include <sbi/sbi_hart_pmp.h>
 #include <sbi/riscv_io.h>
+#include <libfdt.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/fdt/fdt_fixup.h>
 #include <mips/p8700.h>
@@ -121,6 +122,31 @@ static struct sbi_domain_memregion *find_last_memregion(const struct sbi_domain
 	return --reg;
 }
 
+static int fixup_dram_region(const struct sbi_domain *dom,
+			     struct sbi_domain_memregion *reg)
+{
+	const void *fdt = fdt_get_address();
+	int node;
+	int ret;
+	uint64_t mem_addr, mem_size;
+	static const char mem_str[] = "memory";
+
+	if (!reg || !fdt)
+		return SBI_EINVAL;
+
+	/* Find the memory range */
+	node = fdt_node_offset_by_prop_value(fdt, -1, "device_type",
+					     mem_str, sizeof(mem_str));
+	ret = fdt_get_node_addr_size(fdt, node, 0, &mem_addr, &mem_size);
+	if (ret)
+		return ret;
+	reg->flags = SBI_DOMAIN_MEMREGION_MMIO; /* disable cache & prefetch */
+	return sbi_domain_root_add_memrange(mem_addr, mem_size, mem_size,
+					    (SBI_DOMAIN_MEMREGION_SU_READABLE |
+					     SBI_DOMAIN_MEMREGION_SU_WRITABLE |
+					     SBI_DOMAIN_MEMREGION_SU_EXECUTABLE));
+}
+
 static void fdt_disable_by_compat(void *fdt, const char *compatible)
 {
 	int node = 0;
@@ -265,6 +291,8 @@ static void eyeq7h_init_clusters(void)
 
 static int eyeq7h_early_init(bool cold_boot)
 {
+	const struct sbi_domain *dom;
+	struct sbi_domain_memregion *reg;
 	int rc;
 	unsigned long cm_base;
 
@@ -310,7 +338,14 @@ static int eyeq7h_early_init(bool cold_boot)
 					  SBI_DOMAIN_MEMREGION_SU_READABLE |
 					  SBI_DOMAIN_MEMREGION_SU_WRITABLE);
 
-	return 0;
+	/*
+	 * sbi_domain_init adds last "all-inclusive" memory region
+	 * 0 .. ~0 RWX
+	 * Find this region (it is the last one) and update size according to DRAM
+	 */
+	dom = sbi_domain_thishart_ptr();
+	reg = find_last_memregion(dom);
+	return fixup_dram_region(dom, reg);
 }
 
 static int eyeq7h_nascent_init(void)

-- 
2.43.0




More information about the opensbi mailing list