[PATCH v2] lib: utils: fdt_domain: add root-regions-inheritance policy

Yu-Chien Peter Lin peter.lin at sifive.com
Fri May 15 04:12:21 PDT 2026


Introduce root-regions-inheritance DT property to control
copying of root domain memregions. Support 'all' and 'm-only'
modes, always inheriting firmware and M-only regions; behavior
matches existing policy when property is absent.

Signed-off-by: Yu-Chien Peter Lin <peter.lin at sifive.com>
---
Changes v1->v2:
- Addressed feedback from Anup: https://lists.infradead.org/pipermail/opensbi/2026-May/009850.html
---
 docs/domain_support.md     |  7 ++++++
 lib/utils/fdt/fdt_domain.c | 49 ++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/docs/domain_support.md b/docs/domain_support.md
index c01e445f..e267a9f7 100644
--- a/docs/domain_support.md
+++ b/docs/domain_support.md
@@ -159,6 +159,13 @@ The DT properties of a domain instance DT node are as follows:
 * **possible-harts** (Optional) - The list of CPU DT node phandles for the
   the domain instance. This list represents the possible HARTs of the
   domain instance.
+* **root-regions-inheritance** (Optional) - A string property controlling
+  how memory regions are inherited from **the ROOT domain**, which are then
+  overlaid with regions specified in the **regions** property for additional
+  restrictions. The allowed values are:
+  * "all" - inherit all memory regions from **the ROOT domain**
+  * "m-only" - inherit M-mode only memory regions from **the ROOT domain**
+  If this DT property is absent, behavior is the same as "m-only".
 * **regions** (Optional) - The list of domain memory region DT node phandle
   and access permissions for the domain instance. Each list entry is a pair
   of DT node phandle and access permissions. The access permissions are
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index 1b039533..2357346b 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -10,6 +10,7 @@
 
 #include <libfdt.h>
 #include <libfdt_env.h>
+#include <sbi/sbi_console.h>
 #include <sbi/sbi_domain.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hartmask.h>
@@ -237,7 +238,9 @@ skip_device_disable:
 	fdt_nop_node(fdt, poffset);
 }
 
-#define FDT_DOMAIN_REGION_MAX_COUNT	16
+#define FDT_DOMAIN_REGION_MAX_COUNT		16
+#define FDT_ROOT_REGION_INHERIT_ALL		0
+#define FDT_ROOT_REGION_INHERIT_M_ONLY		1
 
 struct parse_region_data {
 	struct sbi_domain *dom;
@@ -309,12 +312,14 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 	u32 val32;
 	u64 val64;
 	const u32 *val;
+	const char *inherit;
 	struct sbi_domain *dom;
 	struct sbi_hartmask *mask;
 	struct sbi_hartmask assign_mask;
 	struct parse_region_data preg;
 	int *cold_domain_offset = opaque;
 	struct sbi_domain_memregion *reg;
+	int inheritance_mode = FDT_ROOT_REGION_INHERIT_M_ONLY;
 	int i, err = 0, len, cpus_offset, cpu_offset, doffset;
 
 	dom = sbi_zalloc(sizeof(*dom));
@@ -373,20 +378,38 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 	if (err)
 		goto fail_free_all;
 
-	/*
-	 * Copy over root domain memregions which don't allow
-	 * read, write and execute from lower privilege modes.
-	 *
-	 * These root domain memregions without read, write,
-	 * and execute permissions include:
-	 * 1) firmware region protecting the firmware memory
-	 * 2) mmio regions protecting M-mode only mmio devices
-	 */
+	/* Determine root domain regions inheritance behavior. */
+	inherit = fdt_getprop(fdt, domain_offset,
+			       "root-regions-inheritance", &len);
+	if (inherit && len > 0) {
+		if (!strcmp(inherit, "all"))
+			inheritance_mode = FDT_ROOT_REGION_INHERIT_ALL;
+		else {
+			sbi_printf("%s: domain \"%s\" has unsupported "
+				   "root-regions-inheritance=\"%s\", using \"m-only\"\n",
+				   __func__, dom->name, inherit);
+		}
+	}
+
+	/* Copy over root domain memregions according to inheritance_mode. */
 	sbi_domain_for_each_memregion(&root, reg) {
-		if ((reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) ||
-		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) ||
-		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
+		int copy = 0;
+
+		switch (inheritance_mode) {
+		case FDT_ROOT_REGION_INHERIT_ALL:
+			copy = 1;
+			break;
+		case FDT_ROOT_REGION_INHERIT_M_ONLY:
+			if (SBI_DOMAIN_MEMREGION_IS_FIRMWARE(reg->flags) ||
+			    SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) {
+				copy = 1;
+			}
+			break;
+		}
+
+		if (!copy)
 			continue;
+
 		if (preg.max_regions <= preg.region_count) {
 			err = SBI_EINVAL;
 			goto fail_free_all;
-- 
2.34.1




More information about the opensbi mailing list