Skip to contentSkip to conversation

sbi: add hardware isolation abstraction framework

PATCH In review Raymond Mao 2 participants 8 messages May 4 – Jul 25

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 sbi: add hardware isolation abstraction framework

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +4 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;
@@ -199,6 +200,9 @@ struct sbi_domain {
 	bool system_reset_allowed;
 	/** Is domain allowed to suspend the system */
 	bool system_suspend_allowed;
+	/** Hardware isolation contexts for registered mechanisms */
+	struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+	u32 hwiso_ctx_count;
 	/** Identifies whether to include the firmware region */
 	bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0

56 lines not on this page · raw message

lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +175 -0

175 lines not on this page · raw message

Signature · 7 lines
2.25.1


-- 
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#1 lore raw

PATCH 2/2 sbi: route domain lifecycle transitions through hwiso hooks

From: Raymond Mao <[email protected]>

Invoke HWISO boot/domain initialization during domain finalization and FDT domain population, and call mechanism exit/enter hooks around domain context switches and secondary hart bring-up.

This makes hardware-isolation state follow the same lifecycle as PMP and domain assignment.

---
 lib/sbi/sbi_domain.c         | 19 +++++++++++++++++++
 lib/sbi/sbi_domain_context.c | 10 ++++++++++
 lib/sbi/sbi_hsm.c            |  5 +++++
 lib/utils/fdt/fdt_domain.c   |  7 +++++++
 4 files changed, 41 insertions(+)
lib/sbi/sbi_domain.c +19 -0
index 374ac36b..ef308925 100644
@@ -17,6 +17,8 @@
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi_utils/fdt/fdt_helper.h>
 
 /*
  * We allocate an extra element because sbi_domain_for_each() expects
@@ -695,6 +697,15 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
 	u32 i, dhart;
 	struct sbi_domain *dom;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
+	void *fdt = fdt_get_address();
+
+	/* Configure system-level hardware isolation mechanisms at boot */
+	rc = sbi_hwiso_init(fdt);
+	if (rc) {
+		sbi_printf("%s: hw isolation init failed (error %d)\n",
+			   __func__, rc);
+		return rc;
+	}
 
 	/* Initialize and populate domains for the platform */
 	rc = sbi_platform_domains_init(plat);
@@ -704,6 +715,14 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
 		return rc;
 	}
 
+	/* Prepare root domain hwiso contexts even without DT parsing */
+	rc = sbi_hwiso_domain_init(fdt, -1, &root);
+	if (rc) {
+		sbi_printf("%s: root hw isolation init failed (error %d)\n",
+			   __func__, rc);
+		return rc;
+	}
+
 	/* Startup boot HART of domains */
 	sbi_domain_for_each(i, dom) {
 		/* Domain boot HART index */
lib/sbi/sbi_domain_context.c +10 -0
index a3d3988d..aa7eb01b 100755
@@ -11,6 +11,7 @@
 #include <sbi/sbi_hsm.h>
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
 #include <sbi/sbi_domain_context.h>
@@ -33,6 +34,9 @@ static void switch_to_next_domain_context(struct sbi_context *ctx,
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 	unsigned int pmp_count = sbi_hart_pmp_count(scratch);
 
+	/* Exit first so mechanisms can tear down current domain state. */
+	sbi_hwiso_domain_exit(current_dom, target_dom);
+
 	/* Assign current hart to target domain */
 	spin_lock(&current_dom->assigned_harts_lock);
 	sbi_hartmask_clear_hartindex(hartindex, &current_dom->assigned_harts);
@@ -50,6 +54,12 @@ static void switch_to_next_domain_context(struct sbi_context *ctx,
 	}
 	sbi_hart_pmp_configure(scratch);
 
+	/*
+	 * Enter after PMP reconfiguration so mechanisms can rely on the
+	 * target domain's base isolation being in effect.
+	 */
+	sbi_hwiso_domain_enter(target_dom, current_dom);
+
 	/* Save current CSR context and restore target domain's CSR context */
 	ctx->sstatus	= csr_swap(CSR_SSTATUS, dom_ctx->sstatus);
 	ctx->sie	= csr_swap(CSR_SIE, dom_ctx->sie);
lib/sbi/sbi_hsm.c +5 -0
index 35c84de2..69d70304 100644
@@ -19,6 +19,7 @@
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_hsm.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_init.h>
 #include <sbi/sbi_ipi.h>
 #include <sbi/sbi_platform.h>
@@ -145,6 +146,7 @@ void __noreturn sbi_hsm_hart_start_finish(struct sbi_scratch *scratch,
 	unsigned long next_arg1;
 	unsigned long next_addr;
 	unsigned long next_mode;
+	struct sbi_domain *dom = sbi_domain_thishart_ptr();
 	struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch,
 							    hart_data_offset);
 
@@ -157,6 +159,9 @@ void __noreturn sbi_hsm_hart_start_finish(struct sbi_scratch *scratch,
 	next_mode = scratch->next_mode;
 	hsm_start_ticket_release(hdata);
 
+	if (dom)
+		sbi_hwiso_domain_enter(dom, NULL);
+
 	sbi_hart_switch_mode(hartid, next_arg1, next_addr, next_mode, false);
 }
 
lib/utils/fdt/fdt_domain.c +7 -0
index fa1c3575..ac0074ed 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi_utils/fdt/fdt_domain.h>
 #include <sbi_utils/fdt/fdt_helper.h>
@@ -439,6 +440,11 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 	else
 		dom->system_suspend_allowed = false;
 
+	/* Parse per-domain hardware isolation configuration */
+	err = sbi_hwiso_domain_init(fdt, domain_offset, dom);
+	if (err)
+		goto fail_free_all;
+
 	/* Find /cpus DT node */
 	cpus_offset = fdt_path_offset(fdt, "/cpus");
 	if (cpus_offset < 0) {
@@ -483,6 +489,7 @@ static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
 	return 0;
 
 fail_free_all:
+	sbi_hwiso_domain_cleanup(dom);
 	sbi_free(mask);
 fail_free_regions:
 	sbi_free(dom->regions);
Signature · 7 lines
2.25.1


-- 
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#2 lore raw
In reply to Raymond Mao
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 259 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +175 -1
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
+       dom->hwiso_ctx_count = 0;
+}
--
Quoted 2 lines

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#3 lore raw
Quoted 316 lines · Anup Patel
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 256 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +173 -0
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
Quoted 9 lines
Quoted 5 lines
lib/sbi/sbi_hwiso.c new file +2 -1
+       dom->hwiso_ctx_count = 0;
+}
--

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

I just posted the series to extend the existing hart protection abstraction.

Refer, patch series "[PATCH 0/5] Extend hart protection abstraction for ID configuration"

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#4 lore raw

Hi Anup,

Quoted 328 lines · Anup Patel
Quoted 316 lines · Anup Patel
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 256 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +173 -0
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
Quoted 9 lines
Quoted 5 lines
lib/sbi/sbi_hwiso.c new file +2 -1
+       dom->hwiso_ctx_count = 0;
+}
--

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

Quoted 6 lines

I just posted the series to extend the existing hart protection abstraction.

Refer, patch series "[PATCH 0/5] Extend hart protection abstraction for ID configuration"

I am planning to post a v2 to rebase on your hart protection abstraction, and squash the hooks of my v1 as helper functions for isolation mechanisms (e.g. WG, PMP, ...) to use.
Is this plan good for you?

Thanks and regards,
Raymond

Quoted 2 lines

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#5 lore raw
Quoted 335 lines · Raymond Mao

Hi Anup,

Quoted 331 lines · Anup Patel
Quoted 316 lines · Anup Patel
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 256 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +173 -0
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
Quoted 9 lines
Quoted 5 lines
lib/sbi/sbi_hwiso.c new file +2 -1
+       dom->hwiso_ctx_count = 0;
+}
--

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

I just posted the series to extend the existing hart protection abstraction.

Quoted 9 lines
Quoted 3 lines

Refer, patch series "[PATCH 0/5] Extend hart protection abstraction for ID configuration"

I am planning to post a v2 to rebase on your hart protection abstraction, and squash the hooks of my v1 as helper functions for isolation mechanisms (e.g. WG, PMP, ...) to use.
Is this plan good for you?

The sbi_domain_data hooks are quiet suitable for WG checker and sbi_hart_protection hooks are quiet suitable for WG ISA support. I don't believe we need any other hooks

Also, we have kept FDT usage and FDT based drivers contained under lib/utils so hooks in lib/sbi taking fdt parameter does not align with current way of implementing FDT based drivers.

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#6 lore raw

Hi Anup,

Quoted 347 lines · Anup Patel
Quoted 335 lines · Raymond Mao

Hi Anup,

Quoted 331 lines · Anup Patel
Quoted 316 lines · Anup Patel
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 256 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +173 -0
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
Quoted 9 lines
Quoted 5 lines
lib/sbi/sbi_hwiso.c new file +2 -1
+       dom->hwiso_ctx_count = 0;
+}
--

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

I just posted the series to extend the existing hart protection abstraction.

Quoted 9 lines
Quoted 3 lines

Refer, patch series "[PATCH 0/5] Extend hart protection abstraction for ID configuration"

I am planning to post a v2 to rebase on your hart protection abstraction, and squash the hooks of my v1 as helper functions for isolation mechanisms (e.g. WG, PMP, ...) to use.
Is this plan good for you?

Quoted 9 lines

The sbi_domain_data hooks are quiet suitable for WG checker and sbi_hart_protection hooks are quiet suitable for WG ISA support. I don't believe we need any other hooks

Also, we have kept FDT usage and FDT based drivers contained under lib/utils so hooks in lib/sbi taking fdt parameter does not align with current way of implementing FDT based drivers.

I mean, the rework series will implement the reusable helpers on top of sbi_domain_data and sbi_hart_protection, covering common domain-data registration, domain-to-hart membership checks. These helpers will collect all reusable logics for multiple mechanisms to use sbi_domain_data and sbi_hart_protection other than only for WG. And yes, the domain DT node lookup and generic u32/u32-list property parsing will remain under lib/utils, not lib/sbi.

Raymond

Quoted 2 lines

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
#7 lore raw
In reply to Anup Patel

Hi Anup,

Quoted 328 lines · Anup Patel
Quoted 316 lines · Anup Patel
Quoted 10 lines · Raymond Mao

From: Raymond Mao <[email protected]>

Introduce a generic hardware-isolation registration and dispatch framework for OpenSBI domains.

Add boot-time init, per-domain init, domain exit, domain enter and cleanup callbacks, and store per-domain mechanism contexts in struct sbi_domain.

Quoted 6 lines

This establishes an abstraction that allows multiple hardware isolation mechanisms to be composed while keeping core domain model and data structures independent from any single platform implementation.

We don't need yet another hart-level abstraction for things like WorldGuard, Supervisor Domain ID, and QoS ID configuration at hart-level.

The existing hart protection abstraction can be easily extended to support both memory protection mechanisms (PMP, ePMP, Smmpt, etc) and ID configurations (WorldGuard, Domain ID, etc).

Quoted 22 lines
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  56 +++++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 175 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c
include/sbi/sbi_domain.h +1 -0
index 02765777..fc7330a6 100644
@@ -14,6 +14,7 @@
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_domain_context.h>
+#include <sbi/sbi_hwiso.h>
 #include <sbi/sbi_rpxy.h>
 
 struct sbi_scratch;

include/sbi/sbi_domain.h struct sbi_domain { · line 205

Quoted 6 lines
include/sbi/sbi_domain.h +3 -0
@@ -199,6 +200,9 @@ struct sbi_domain {
        bool system_reset_allowed;
        /** Is domain allowed to suspend the system */
        bool system_suspend_allowed;
+       /** Hardware isolation contexts for registered mechanisms */
+       struct sbi_hwiso_domain_ctx *hwiso_ctxs;
+       u32 hwiso_ctx_count;

We already have sbi_domain_data APIs to allow any part of OpenSBI create per-domain data so we should re-use APIs for adding more information parsed from DT at boot-time.

Quoted 256 lines
include/sbi/sbi_domain.h +0 -0
        /** Identifies whether to include the firmware region */
        bool fw_region_inited;
 };
include/sbi/sbi_hwiso.h new file +56 -0
new file mode 100644
index 00000000..1efdb8c1
@@ -0,0 +1,56 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+#include <sbi/sbi_domain.h>
+
+struct sbi_hwiso_ops {
+       const char *name;
+
+       /* Boot-time init */
+       int (*init)(void *fdt);
+
+       /* Per-domain init (domain_offset refers to domain instance node) */
+       int (*domain_init)(void *fdt, int domain_offset,
+                          struct sbi_domain *dom, void **ctx);
+
+       /* Before switching away from a domain */
+       void (*domain_exit)(const struct sbi_domain *src,
+                           const struct sbi_domain *dst, void *ctx);
+
+       /* After switching into a domain */
+       void (*domain_enter)(const struct sbi_domain *dst,
+                            const struct sbi_domain *src, void *ctx);
+
+       /* Optional cleanup */
+       void (*domain_cleanup)(struct sbi_domain *dom, void *ctx);
+};
+
+struct sbi_hwiso_domain_ctx {
+       const struct sbi_hwiso_ops *ops;
+       void *ctx;
+};
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops);
+
+int sbi_hwiso_init(void *fdt);
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom);
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst);
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src);
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom);
+
+#endif /* __SBI_HWISO_H__ */
lib/sbi/objects.mk +1 -0
index ca312ee2..6091499a 100644
@@ -72,6 +72,7 @@ libsbi-objs-y += sbi_domain.o
 libsbi-objs-y += sbi_emulate_csr.o
 libsbi-objs-y += sbi_fifo.o
 libsbi-objs-y += sbi_hart.o
+libsbi-objs-y += sbi_hwiso.o
 libsbi-objs-y += sbi_heap.o
 libsbi-objs-y += sbi_math.o
 libsbi-objs-y += sbi_hfence.o
lib/sbi/sbi_hwiso.c new file +173 -0
new file mode 100644
index 00000000..6c96dc3e
@@ -0,0 +1,175 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <[email protected]>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_heap.h>
+#include <sbi/sbi_hwiso.h>
+#include <sbi/sbi_list.h>
+
+struct sbi_hwiso_node {
+       const struct sbi_hwiso_ops *ops;
+       struct sbi_dlist node;
+};
+
+static SBI_LIST_HEAD(hwiso_ops_list);
+static u32 hwiso_ops_count;
+
+static bool hwiso_ops_registered(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *entry;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (entry->ops == ops)
+                       return true;
+       }
+
+       return false;
+}
+
+int sbi_hwiso_register(const struct sbi_hwiso_ops *ops)
+{
+       struct sbi_hwiso_node *node;
+
+       if (!ops || !ops->name)
+               return SBI_EINVAL;
+
+       if (hwiso_ops_registered(ops))
+               return SBI_EALREADY;
+
+       node = sbi_zalloc(sizeof(*node));
+       if (!node)
+               return SBI_ENOMEM;
+
+       node->ops = ops;
+       SBI_INIT_LIST_HEAD(&node->node);
+       sbi_list_add_tail(&node->node, &hwiso_ops_list);
+       hwiso_ops_count++;
+
+       return 0;
+}
+
+int sbi_hwiso_init(void *fdt)
+{
+       struct sbi_hwiso_node *entry;
+       int rc;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               if (!entry->ops->init)
+                       continue;
+
+               rc = entry->ops->init(fdt);
+               if (rc)
+                       return rc;
+       }
+
+       return 0;
+}
+
+int sbi_hwiso_domain_init(void *fdt, int domain_offset,
+                         struct sbi_domain *dom)
+{
+       struct sbi_hwiso_node *entry;
+       struct sbi_hwiso_domain_ctx *ctxs;
+       void *ctx;
+       u32 idx = 0;
+       int rc;
+
+       if (!dom)
+               return 0;
+
+       if (!hwiso_ops_count)
+               return 0;
+
+       ctxs = sbi_calloc(sizeof(*ctxs), hwiso_ops_count);
+       if (!ctxs)
+               return SBI_ENOMEM;
+
+       dom->hwiso_ctxs = ctxs;
+       dom->hwiso_ctx_count = hwiso_ops_count;
+
+       sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+               ctxs[idx].ops = entry->ops;
+               ctxs[idx].ctx = NULL;
+               ctx = NULL;
+
+               if (entry->ops->domain_init) {
+                       rc = entry->ops->domain_init(fdt, domain_offset,
+                                                    dom, &ctx);
+                       ctxs[idx].ctx = ctx;
+                       if (rc) {
+                               sbi_hwiso_domain_cleanup(dom);
+                               return rc;
+                       }
+               }
+
+               ctxs[idx].ctx = ctx;
+               idx++;
+       }
+
+       return 0;
+}
+
+void sbi_hwiso_domain_exit(const struct sbi_domain *src,
+                          const struct sbi_domain *dst)
+{
+       u32 i;
+
+       if (!src || !src->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < src->hwiso_ctx_count; i++) {
+               if (!src->hwiso_ctxs[i].ops ||
+                   !src->hwiso_ctxs[i].ops->domain_exit)
+                       continue;
+
+               src->hwiso_ctxs[i].ops->domain_exit(
+                                       src, dst, src->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_enter(const struct sbi_domain *dst,
+                           const struct sbi_domain *src)
+{
+       u32 i;
+
+       if (!dst || !dst->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dst->hwiso_ctx_count; i++) {
+               if (!dst->hwiso_ctxs[i].ops ||
+                   !dst->hwiso_ctxs[i].ops->domain_enter)
+                       continue;
+
+               dst->hwiso_ctxs[i].ops->domain_enter(
+                                       dst, src, dst->hwiso_ctxs[i].ctx);
+       }
+}
+
+void sbi_hwiso_domain_cleanup(struct sbi_domain *dom)
+{
+       u32 i;
+
+       if (!dom || !dom->hwiso_ctxs)
+               return;
+
+       for (i = 0; i < dom->hwiso_ctx_count; i++) {
+               if (!dom->hwiso_ctxs[i].ops ||
+                   !dom->hwiso_ctxs[i].ops->domain_cleanup)
+                       continue;
+
+               dom->hwiso_ctxs[i].ops->domain_cleanup(
+                                       dom, dom->hwiso_ctxs[i].ctx);
+       }
+
+       sbi_free(dom->hwiso_ctxs);
+       dom->hwiso_ctxs = NULL;
Quoted 9 lines
Quoted 5 lines
lib/sbi/sbi_hwiso.c new file +2 -1
+       dom->hwiso_ctx_count = 0;
+}
--

2.25.1

Let me send a separate series showing how to extend sbi_hart_isolation as suggested above.

Quoted 6 lines

I just posted the series to extend the existing hart protection abstraction.

Refer, patch series "[PATCH 0/5] Extend hart protection abstraction for ID configuration"

I have posted a v2 series "[PATCH v2 0/4] Add WorldGuard support with wgchecker2" [1] based on your series.
All implementations of WG are on top of sbi_hart_protection and sbi_domain_data. Please kindly provide your feedback.

[1] https://lore.kernel.org/opensbi/[email protected]/

Thanks and regards,
Raymond

Quoted 2 lines

Regards,
Anup

Signature · 3 lines
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi