From 331dae1bc184986038fba62504bb129563f53143 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Mon, 23 Feb 2026 16:55:00 +0200 Subject: [PATCH] platform: generic: mips eyeq7h: prohibit accessing memory beyond DRAM 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 Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260223-for-upstream-eyeq7h-v3-21-621d004d1a21@mobileye.com Signed-off-by: Anup Patel --- 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 04ab5286..f09ec5f0 100644 --- a/platform/generic/mips/eyeq7h.c +++ b/platform/generic/mips/eyeq7h.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -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)