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

Anup Patel anup at brainfault.org
Mon May 18 05:55:04 PDT 2026


On Sat, May 16, 2026 at 12:59 PM Yu-Chien Peter Lin
<peter.lin at sifive.com> wrote:
>
> 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 at sifive.com>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
> Changes v1->v2:
> - Addressed feedback from Anup: https://lists.infradead.org/pipermail/opensbi/2026-May/009850.html
> Changes v2->v3:
> - Fail early when unsupported value is found
> ---
>  docs/domain_support.md     |  7 +++++
>  lib/utils/fdt/fdt_domain.c | 53 ++++++++++++++++++++++++++++----------
>  2 files changed, 47 insertions(+), 13 deletions(-)
>
> diff --git a/docs/domain_support.md b/docs/domain_support.md
> index 93186c4a..77122330 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 b2fa8633..b31254af 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;
> --
> 2.43.7
>



More information about the opensbi mailing list