From 1f9677582af552bfaaf87579bb28b864d4b4130f Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 21 Nov 2025 11:37:51 -0800 Subject: [PATCH] lib: sbi_domain: Allow MMIO access to non-MMIO ranges Currently, platforms do not provide complete memory region information to OpenSBI. Generally, memory regions are only created for the few MMIO devices that have M-mode drivers. As a result, most MMIO devices fall inside the default S-mode RWX memory region, which does _not_ have the MMIO flag set. In fact, OpenSBI relies on certain S-mode MMIO devices being inside non-MMIO memory regions. Both fdt_domain_based_fixup_one() and mpxy_rpmi_sysmis_xfer() call sbi_domain_check_addr() with the MMIO flag cleared, and that function currently requires an exact flag match. Those access checks will thus erroneously fail if the platform creates memory regions with the correct flags for these devices (or for a larger MMIO region containing these devices). We should not ignore the MMIO flag entirely, because sbi_domain_check_addr() is also used to check the permissions of S-mode shared memory buffers, and S-mode should not be using MMIO device addresses as memory buffers. But when checking if S-mode is allowed to do MMIO accesses, we need to recognize that MMIO devices appear in memory regions both with and without the MMIO flag set. Signed-off-by: Samuel Holland Reviewed-by: Yu-Chien Peter Lin Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20251121193808.1528050-2-samuel.holland@sifive.com Signed-off-by: Anup Patel --- lib/sbi/sbi_domain.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 99f453f9..96d10c76 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -235,7 +235,11 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom, rstart + ((1UL << reg->order) - 1) : -1UL; if (rstart <= addr && addr <= rend) { rmmio = (rflags & SBI_DOMAIN_MEMREGION_MMIO) ? true : false; - if (mmio != rmmio) + /* + * MMIO devices may appear in regions without the flag set (such as the + * default region), but MMIO device regions should not be used as memory. + */ + if (!mmio && rmmio) return false; return ((rrwx & rwx) == rwx) ? true : false; }