From 4c5d9d9f93c77805dbc023cdef6a68c039b87970 Mon Sep 17 00:00:00 2001 From: Ben Zong-You Xie Date: Tue, 28 Jul 2026 16:10:36 +0800 Subject: [PATCH] lib: utils/andes: add the SMU and LLC registers to the root domain When a hart implements Smepmp, S-mode and U-mode cannot reach either device unless its region is shared explicitly. Suspend and resume then take an access violation as soon as the supervisor touches the SMU or the LLC. Share both regions, and take their sizes from the DT nodes rather than ignoring them. Signed-off-by: Ben Zong-You Xie Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260728081041.2724668-3-ben717@andestech.com Signed-off-by: Anup Patel --- lib/utils/cache/fdt_andes_llcache.c | 18 +++++++++++++++--- lib/utils/hsm/fdt_hsm_andes_atcsmu.c | 17 +++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/utils/cache/fdt_andes_llcache.c b/lib/utils/cache/fdt_andes_llcache.c index a3a2d37f..7a61b6ab 100644 --- a/lib/utils/cache/fdt_andes_llcache.c +++ b/lib/utils/cache/fdt_andes_llcache.c @@ -5,8 +5,11 @@ */ #include +#include #include +#include #include +#include #include #include #include @@ -116,13 +119,13 @@ static struct cache_ops andes_llcache_ops = { static int andes_llcache_probe(const void *fdt, int nodeoff, const struct fdt_match *match) { int rc; - u64 llcache_base = 0; + u64 llcache_base = 0, size; struct andes_llcache *llcache; struct cache_device *dev; uint32_t llcache_cfg; - rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, NULL); - if (rc < 0 || !llcache_base) + rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, &size); + if (rc < 0 || !llcache_base || !size) return SBI_ENODEV; llcache = sbi_zalloc(sizeof(*llcache)); @@ -151,6 +154,15 @@ static int andes_llcache_probe(const void *fdt, int nodeoff, const struct fdt_ma llcache->status_core_stride = 4; } + if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SMEPMP)) { + rc = sbi_domain_root_add_memrange( + (unsigned long)llcache->base, (unsigned long)size, PAGE_SIZE, + SBI_DOMAIN_MEMREGION_MMIO | + SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW); + if (rc) + return rc; + } + /* Wait for the hardware initialization done */ while (!andes_llcache_init_done(llcache)) ; diff --git a/lib/utils/hsm/fdt_hsm_andes_atcsmu.c b/lib/utils/hsm/fdt_hsm_andes_atcsmu.c index 115916d5..ae1d8889 100644 --- a/lib/utils/hsm/fdt_hsm_andes_atcsmu.c +++ b/lib/utils/hsm/fdt_hsm_andes_atcsmu.c @@ -184,18 +184,27 @@ static const struct sbi_hsm_device hsm_andes_atcsmu = { static int hsm_andes_atcsmu_probe(const void *fdt, int nodeoff, const struct fdt_match *match) { int poff, rc; - u64 addr; + u64 addr, size; /* Need to find the parent for the address property */ poff = fdt_parent_offset(fdt, nodeoff); if (poff < 0) return SBI_EINVAL; - rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, NULL); - if (rc < 0 || !addr) + rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, &size); + if (rc < 0 || !addr || !size) return SBI_ENODEV; - atcsmu_base = addr; + if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SMEPMP)) { + rc = sbi_domain_root_add_memrange( + (unsigned long)addr, (unsigned long)size, PAGE_SIZE, + SBI_DOMAIN_MEMREGION_MMIO | + SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW); + if (rc) + return rc; + } + + atcsmu_base = addr; sbi_hsm_set_device(&hsm_andes_atcsmu); return 0; }