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

Raymond Mao raymondmaoca at gmail.com
Mon May 4 10:39:48 PDT 2026


From: Raymond Mao <raymond.mao at riscstar.com>

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.

Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
---
 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(+)

diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 374ac36b..ef308925 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -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 */
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index a3d3988d..aa7eb01b 100755
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -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);
diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c
index 35c84de2..69d70304 100644
--- a/lib/sbi/sbi_hsm.c
+++ b/lib/sbi/sbi_hsm.c
@@ -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);
 }
 
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index fa1c3575..ac0074ed 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -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);
-- 
2.25.1




More information about the opensbi mailing list