mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-05-23 14:21:32 +01:00
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>
This commit is contained in:
committed by
Anup Patel
parent
22d7e99ed2
commit
f36acaeb80
@@ -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
|
* **possible-harts** (Optional) - The list of CPU DT node phandles for the
|
||||||
the domain instance. This list represents the possible HARTs of the
|
the domain instance. This list represents the possible HARTs of the
|
||||||
domain instance.
|
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
|
* **regions** (Optional) - The list of domain memory region DT node phandle
|
||||||
and access permissions for the domain instance. Each list entry is a pair
|
and access permissions for the domain instance. Each list entry is a pair
|
||||||
of DT node phandle and access permissions. The access permissions are
|
of DT node phandle and access permissions. The access permissions are
|
||||||
|
|||||||
+39
-12
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <libfdt.h>
|
#include <libfdt.h>
|
||||||
#include <libfdt_env.h>
|
#include <libfdt_env.h>
|
||||||
|
#include <sbi/sbi_console.h>
|
||||||
#include <sbi/sbi_domain.h>
|
#include <sbi/sbi_domain.h>
|
||||||
#include <sbi/sbi_error.h>
|
#include <sbi/sbi_error.h>
|
||||||
#include <sbi/sbi_hartmask.h>
|
#include <sbi/sbi_hartmask.h>
|
||||||
@@ -238,6 +239,8 @@ skip_device_disable:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#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 parse_region_data {
|
||||||
struct sbi_domain *dom;
|
struct sbi_domain *dom;
|
||||||
@@ -309,12 +312,14 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
|
|||||||
u32 val32;
|
u32 val32;
|
||||||
u64 val64;
|
u64 val64;
|
||||||
const u32 *val;
|
const u32 *val;
|
||||||
|
const char *inherit;
|
||||||
struct sbi_domain *dom;
|
struct sbi_domain *dom;
|
||||||
struct sbi_hartmask *mask;
|
struct sbi_hartmask *mask;
|
||||||
struct sbi_hartmask assign_mask;
|
struct sbi_hartmask assign_mask;
|
||||||
struct parse_region_data preg;
|
struct parse_region_data preg;
|
||||||
int *cold_domain_offset = opaque;
|
int *cold_domain_offset = opaque;
|
||||||
struct sbi_domain_memregion *reg;
|
struct sbi_domain_memregion *reg;
|
||||||
|
int inheritance_mode = FDT_ROOT_REGION_INHERIT_M_ONLY;
|
||||||
int i, err = 0, len, cpus_offset, cpu_offset, doffset;
|
int i, err = 0, len, cpus_offset, cpu_offset, doffset;
|
||||||
|
|
||||||
dom = sbi_zalloc(sizeof(*dom));
|
dom = sbi_zalloc(sizeof(*dom));
|
||||||
@@ -373,20 +378,42 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
|
|||||||
if (err)
|
if (err)
|
||||||
goto fail_free_all;
|
goto fail_free_all;
|
||||||
|
|
||||||
/*
|
/* Determine root domain regions inheritance behavior. */
|
||||||
* Copy over root domain memregions which don't allow
|
inherit = fdt_getprop(fdt, domain_offset,
|
||||||
* read, write and execute from lower privilege modes.
|
"root-regions-inheritance", &len);
|
||||||
*
|
if (inherit && len > 0) {
|
||||||
* These root domain memregions without read, write,
|
if (!strcmp(inherit, "all"))
|
||||||
* and execute permissions include:
|
inheritance_mode = FDT_ROOT_REGION_INHERIT_ALL;
|
||||||
* 1) firmware region protecting the firmware memory
|
else if (!strcmp(inherit, "m-only"))
|
||||||
* 2) mmio regions protecting M-mode only mmio devices
|
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) {
|
sbi_domain_for_each_memregion(&root, reg) {
|
||||||
if ((reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) ||
|
bool copy = false;
|
||||||
(reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) ||
|
|
||||||
(reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
|
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;
|
continue;
|
||||||
|
|
||||||
if (preg.max_regions <= preg.region_count) {
|
if (preg.max_regions <= preg.region_count) {
|
||||||
err = SBI_EINVAL;
|
err = SBI_EINVAL;
|
||||||
goto fail_free_all;
|
goto fail_free_all;
|
||||||
|
|||||||
Reference in New Issue
Block a user