summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYu-Chien Peter Lin <peter.lin@sifive.com>2026-05-16 15:29:06 +0800
committerAnup Patel <anup@brainfault.org>2026-05-18 18:20:50 +0530
commitf36acaeb80a490339923a5ec01ac3707741f6b90 (patch)
tree181a322d155c433be85d14d43ade64be2495e7b6 /lib
parent22d7e99ed2f9c66012a05a82318785d80dd451a0 (diff)
downloadopensbi-f36acaeb80a490339923a5ec01ac3707741f6b90.tar.gz
opensbi-f36acaeb80a490339923a5ec01ac3707741f6b90.zip
lib: utils: fdt_domain: add root-regions-inheritance policy
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 m-only policy when property is absent. Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260516072906.1427203-1-peter.lin@sifive.com Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/utils/fdt/fdt_domain.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index 1b039533..61627db3 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_M_ONLY 0
+#define FDT_ROOT_REGION_INHERIT_ALL 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,42 @@ 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 if (!strcmp(inherit, "m-only"))
+ inheritance_mode = FDT_ROOT_REGION_INHERIT_M_ONLY;
+ else {
+ sbi_printf("%s: domain \"%s\" has unsupported "
+ "root-regions-inheritance=\"%s\"\n",
+ __func__, dom->name, inherit);
+ err = SBI_EINVAL;
+ goto fail_free_all;
+ }
+ }
+
+ /* 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))
+ bool copy = false;
+
+ switch (inheritance_mode) {
+ case FDT_ROOT_REGION_INHERIT_ALL:
+ copy = true;
+ 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 = true;
+ }
+ break;
+ }
+
+ if (!copy)
continue;
+
if (preg.max_regions <= preg.region_count) {
err = SBI_EINVAL;
goto fail_free_all;