public inbox for opensbi@lists.infradead.org
 help / color / mirror / Atom feed
* [RFC PATCH] sbi: add hardware isolation abstraction framework
@ 2026-03-17 20:18 Raymond Mao
  2026-04-05  7:24 ` Yu-Chien Peter Lin
  0 siblings, 1 reply; 3+ messages in thread
From: Raymond Mao @ 2026-03-17 20:18 UTC (permalink / raw)
  To: opensbi
  Cc: scott, dave.patel, raymond.mao, robin.randhawa, samuel.holland,
	anup.patel, anuppate, anup, dhaval, peter.lin

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

Introduce a system-level hardware isolation framework with a
registration API and per-domain context tracking.
This establishes an abstraction that allows multiple mechanisms to
be composed while keeping core domain data structures independent
of any single platform implementation.

Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
---
 include/sbi/sbi_domain.h |   4 +
 include/sbi/sbi_hwiso.h  |  57 +++++++++++
 lib/sbi/objects.mk       |   1 +
 lib/sbi/sbi_hwiso.c      | 215 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 277 insertions(+)
 create mode 100644 include/sbi/sbi_hwiso.h
 create mode 100644 lib/sbi/sbi_hwiso.c

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 02765777..fc7330a6 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -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;
 };
diff --git a/include/sbi/sbi_hwiso.h b/include/sbi/sbi_hwiso.h
new file mode 100644
index 00000000..adbeb715
--- /dev/null
+++ b/include/sbi/sbi_hwiso.h
@@ -0,0 +1,57 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <raymond.mao@riscstar.com>
+ */
+
+#ifndef __SBI_HWISO_H__
+#define __SBI_HWISO_H__
+
+#include <sbi/sbi_types.h>
+
+struct sbi_domain;
+
+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__ */
diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk
index ca312ee2..6091499a 100644
--- a/lib/sbi/objects.mk
+++ b/lib/sbi/objects.mk
@@ -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
diff --git a/lib/sbi/sbi_hwiso.c b/lib/sbi/sbi_hwiso.c
new file mode 100644
index 00000000..5f876b33
--- /dev/null
+++ b/lib/sbi/sbi_hwiso.c
@@ -0,0 +1,215 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * System-level hardware isolation framework
+ *
+ * Copyright (c) 2026 RISCstar Solutions Corporation.
+ *
+ * Author: Raymond Mao <raymond.mao@riscstar.com>
+ */
+
+#include <libfdt.h>
+#include <sbi/sbi_console.h>
+#include <sbi/sbi_domain.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 == SBI_ENOMEM)
+			return rc;
+		if (rc)
+			sbi_printf("hwiso: %s init failed (error %d)\n",
+				   entry->ops->name, rc);
+	}
+
+	return 0;
+}
+
+static void hwiso_warn_unknown_nodes(void *fdt, int domain_offset)
+{
+	int hoff, child;
+	struct sbi_hwiso_node *entry;
+	bool known;
+
+	if (!fdt || (domain_offset < 0))
+		return;
+
+	hoff = fdt_subnode_offset(fdt, domain_offset, "hw-isolation");
+	if (hoff < 0)
+		return;
+
+	fdt_for_each_subnode(child, fdt, hoff) {
+		known = false;
+		sbi_list_for_each_entry(entry, &hwiso_ops_list, node) {
+			if (!fdt_node_check_compatible(
+					fdt, child, entry->ops->name)) {
+				known = true;
+				break;
+			}
+		}
+
+		if (!known)
+			sbi_printf("hwiso: unknown mechanism at %s\n",
+				   fdt_get_name(fdt, child, NULL));
+	}
+}
+
+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) {
+		hwiso_warn_unknown_nodes(fdt, domain_offset);
+		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);
+			if (rc == SBI_ENOMEM) {
+				sbi_hwiso_domain_cleanup(dom);
+				return rc;
+			}
+			if (rc) {
+				sbi_printf("hwiso: %s domain init failed"
+					   " (error %d)\n",
+					   entry->ops->name, rc);
+				ctx = NULL;
+			}
+		}
+
+		ctxs[idx].ctx = ctx;
+		idx++;
+	}
+
+	hwiso_warn_unknown_nodes(fdt, domain_offset);
+
+	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;
+}
-- 
2.25.1


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] sbi: add hardware isolation abstraction framework
  2026-03-17 20:18 [RFC PATCH] sbi: add hardware isolation abstraction framework Raymond Mao
@ 2026-04-05  7:24 ` Yu-Chien Peter Lin
  2026-04-07 15:46   ` Raymond Mao
  0 siblings, 1 reply; 3+ messages in thread
From: Yu-Chien Peter Lin @ 2026-04-05  7:24 UTC (permalink / raw)
  To: Raymond Mao, opensbi
  Cc: scott, dave.patel, raymond.mao, robin.randhawa, samuel.holland,
	anup.patel, anuppate, anup, dhaval

Hi Raymond,

On 3/17/26 4:18 PM, Raymond Mao wrote:
> From: Raymond Mao <raymond.mao@riscstar.com>
> 
> Introduce a system-level hardware isolation framework with a
> registration API and per-domain context tracking.
> This establishes an abstraction that allows multiple mechanisms to
> be composed while keeping core domain data structures independent
> of any single platform implementation.
> 
> Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>

Thank you for the RFC patch on the hardware isolation framework. I'm 
currently
reworking our internal WorldGuard patches and plan to share them for 
development
with Jim's WG QEMU simulation.

I wanted to offer some personal input based on my exploration of an 
alternative
approach which might be useful as we gather community feedback.

The goal is to utilize WorldGuard for system-level protection in static
partitioning TEE scenarios (e.g., OP-TEE). To achieve this, we need to
work on two components:

1. RISC-V Worlds ISA Extension

The Worlds ISA extension [1] introduces per-hart World ID (WID) 
management via
CSRs like `mlwid` and `mwiddeleg`. These concepts should integrate naturally
with OpenSBI's domain framework:

- Each domain can be assigned a `next_wid` (corresponding to `mlwid`)
- Each domain can be assigned a `next_widlist` (corresponding to 
`mwiddeleg`)

When OpenSBI switches to a target domain, it assigns the domain's 
`next_wid` to
`mlwid`, effectively enabling hardware-enforced physical address space 
isolation
for that supervisor domain.

2. WorldGuard Checker Driver

The WG checker driver parses device-tree information and programs the 
WorldGuard
checkers to create access control rules associating memory/device 
regions with
allowed World IDs.
(We SiFive will also propose DT formats for this.)

Device Isolation Example:

deviceA: [0x10000000, 0x20000000) WID3
deviceB: [0x20000000, 0x30000000) WID0, WID3 (shared)
deviceC: [0x30000000, 0x40000000) WID0

Memory Partitioning Example:

Given a DRAM range `[0x8000_0000, 0x1_0000_0000)`, we can partition it 
as follows:

| Mode    | Main User | WID      | Physical Address Range 
                    |
|---------|-----------|----------|----------------------------------------------------------|
| M-mode  | OpenSBI   |       3  | [0x8000_0000, 0x800C_0000) 
                    |
| SU-mode | Linux     | 0, 1, 3  | [0x800C_0000, 0xC000_0000), 
[0xC100_0000, 0x1_0000_0000) |
| SU-mode | OP-TEE    |    1, 3  | [0xC000_0000, 0xC100_0000) 
                    |

During a domain context switch, OpenSBI assigns the target domain's 
`next_wid`
to `mlwid`. This ensures that the hart can only access memory regions 
associated
with the active WID, providing hardware-enforced isolation.

One open question I'm exploring is whether to extend 
`sbi_domain_memregion` with
WorldGuard-specific fields (flags, permissions, allowed WIDs) as bus checker
region descriptor for following considerations:
- WorldGuard checker slots will make use of TOR addressing mode, which
   PMP does not
- WorldGuard slots do not have execute permission semantics, unlike PMP
- Reusing PMP-style flags directly may cause logic errors in functions like
   `sbi_domain_check_addr()`

I haven't fully implemented this yet, so the design may change as I work 
through
the details.

In addition to the RISC-V Worlds ISA specification, I'd like to share 
resources/
found helpful for understanding WorldGuard and system-level protection:
- [1] RISC-V Worlds ISA Extension:
  
https://github.com/riscv/riscv-worlds/releases/download/riscv-isa-release-4ae2105-2026-01-09/riscv-privileged.pdf

- [2] RISC-V Secure System Partitioning with Worlds and TrustZone (v0.7.2):
   https://github.com/MIPS/riscv-partitioning/releases/tag/v0.7.2

- [3] RISC-V Platform Security Model (v0.5):
   https://github.com/riscv/riscv-security-model/releases/tag/v.05

- [4] RISC-V Implementing Application Processor TEEs (Whitepaper):
  
https://riscv.org/wp-content/uploads/2025/10/RISC-V-Implementing-Application-Processor-TEEs-REV-1.pdf

Again, these are just my quick notes and personal input for this milestone.
We should keep talking with the community to ensure our plan is on the right
direction.

Looking forward to collaborating on this!

Best regards,
Peter Lin

-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC PATCH] sbi: add hardware isolation abstraction framework
  2026-04-05  7:24 ` Yu-Chien Peter Lin
@ 2026-04-07 15:46   ` Raymond Mao
  0 siblings, 0 replies; 3+ messages in thread
From: Raymond Mao @ 2026-04-07 15:46 UTC (permalink / raw)
  To: Yu-Chien Peter Lin
  Cc: opensbi, scott, dave.patel, raymond.mao, robin.randhawa,
	samuel.holland, anup.patel, anuppate, anup, dhaval

Hi Peter,

On Sun, Apr 5, 2026 at 3:24 AM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> Hi Raymond,
>
> On 3/17/26 4:18 PM, Raymond Mao wrote:
> > From: Raymond Mao <raymond.mao@riscstar.com>
> >
> > Introduce a system-level hardware isolation framework with a
> > registration API and per-domain context tracking.
> > This establishes an abstraction that allows multiple mechanisms to
> > be composed while keeping core domain data structures independent
> > of any single platform implementation.
> >
> > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
>
> Thank you for the RFC patch on the hardware isolation framework. I'm
> currently
> reworking our internal WorldGuard patches and plan to share them for
> development
> with Jim's WG QEMU simulation.
>
> I wanted to offer some personal input based on my exploration of an
> alternative
> approach which might be useful as we gather community feedback.
>
> The goal is to utilize WorldGuard for system-level protection in static
> partitioning TEE scenarios (e.g., OP-TEE). To achieve this, we need to
> work on two components:
>
> 1. RISC-V Worlds ISA Extension
>
> The Worlds ISA extension [1] introduces per-hart World ID (WID)
> management via
> CSRs like `mlwid` and `mwiddeleg`. These concepts should integrate naturally
> with OpenSBI's domain framework:
>
> - Each domain can be assigned a `next_wid` (corresponding to `mlwid`)
> - Each domain can be assigned a `next_widlist` (corresponding to
> `mwiddeleg`)
>
> When OpenSBI switches to a target domain, it assigns the domain's
> `next_wid` to
> `mlwid`, effectively enabling hardware-enforced physical address space
> isolation
> for that supervisor domain.
>
> 2. WorldGuard Checker Driver
>
> The WG checker driver parses device-tree information and programs the
> WorldGuard
> checkers to create access control rules associating memory/device
> regions with
> allowed World IDs.
> (We SiFive will also propose DT formats for this.)
>
> Device Isolation Example:
>
> deviceA: [0x10000000, 0x20000000) WID3
> deviceB: [0x20000000, 0x30000000) WID0, WID3 (shared)
> deviceC: [0x30000000, 0x40000000) WID0
>
> Memory Partitioning Example:
>
> Given a DRAM range `[0x8000_0000, 0x1_0000_0000)`, we can partition it
> as follows:
>
> | Mode    | Main User | WID      | Physical Address Range
>                     |
> |---------|-----------|----------|----------------------------------------------------------|
> | M-mode  | OpenSBI   |       3  | [0x8000_0000, 0x800C_0000)
>                     |
> | SU-mode | Linux     | 0, 1, 3  | [0x800C_0000, 0xC000_0000),
> [0xC100_0000, 0x1_0000_0000) |
> | SU-mode | OP-TEE    |    1, 3  | [0xC000_0000, 0xC100_0000)
>                     |
>
> During a domain context switch, OpenSBI assigns the target domain's
> `next_wid`
> to `mlwid`. This ensures that the hart can only access memory regions
> associated
> with the active WID, providing hardware-enforced isolation.
>
> One open question I'm exploring is whether to extend
> `sbi_domain_memregion` with
> WorldGuard-specific fields (flags, permissions, allowed WIDs) as bus checker
> region descriptor for following considerations:
> - WorldGuard checker slots will make use of TOR addressing mode, which
>    PMP does not
> - WorldGuard slots do not have execute permission semantics, unlike PMP
> - Reusing PMP-style flags directly may cause logic errors in functions like
>    `sbi_domain_check_addr()`
>
> I haven't fully implemented this yet, so the design may change as I work
> through
> the details.
>
> In addition to the RISC-V Worlds ISA specification, I'd like to share
> resources/
> found helpful for understanding WorldGuard and system-level protection:
> - [1] RISC-V Worlds ISA Extension:
>
> https://github.com/riscv/riscv-worlds/releases/download/riscv-isa-release-4ae2105-2026-01-09/riscv-privileged.pdf
>
> - [2] RISC-V Secure System Partitioning with Worlds and TrustZone (v0.7.2):
>    https://github.com/MIPS/riscv-partitioning/releases/tag/v0.7.2
>
> - [3] RISC-V Platform Security Model (v0.5):
>    https://github.com/riscv/riscv-security-model/releases/tag/v.05
>
> - [4] RISC-V Implementing Application Processor TEEs (Whitepaper):
>
> https://riscv.org/wp-content/uploads/2025/10/RISC-V-Implementing-Application-Processor-TEEs-REV-1.pdf
>
> Again, these are just my quick notes and personal input for this milestone.
> We should keep talking with the community to ensure our plan is on the right
> direction.
>
> Looking forward to collaborating on this!
>

Thanks for the detailed feedback and the WG/Worlds context — very helpful.

The proposed HWISO is meant to be a generic framework for isolation
management across domain lifecycle phases (boot, domain_init, domain
exit/enter). The intent is to keep this layer mechanism‑agnostic, and
have specific technologies (like WG/Worlds) plug in as one of the
registered mechanisms.

From your description, WG fits well: a WG mechanism can parse its own
DT binding, keep per‑domain context (next_wid/next_widlist, checker
config), and program hardware on domain enter/exit. This avoids
forcing WG into PMP semantics or sbi_domain_memregion.

So for this phase I plan to keep the HWISO abstraction minimal and
mechanism-driven. When you share the WG DT format and implementation,
we can integrate it as another registered mechanism under HWISO
without refactoring the framework itself. If we discover we need
multi‑instance support or richer matching at the framework level, we
can evolve it then.

Looking forward to continuing the discussion.

Thanks and regards,
Raymond

> Best regards,
> Peter Lin

-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-07 15:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-17 20:18 [RFC PATCH] sbi: add hardware isolation abstraction framework Raymond Mao
2026-04-05  7:24 ` Yu-Chien Peter Lin
2026-04-07 15:46   ` Raymond Mao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox