[PATCH 1/2] sbi: add hardware isolation abstraction framework
Anup Patel
anup at brainfault.org
Thu Jul 16 06:39:10 PDT 2026
On Mon, May 4, 2026 at 11:09 PM Raymond Mao <raymondmaoca at gmail.com> wrote:
>
> From: Raymond Mao <raymond.mao at riscstar.com>
>
> 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.
>
> Signed-off-by: Raymond Mao <raymond.mao at riscstar.com>
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).
> ---
> 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
>
> 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;
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.
> /** 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..1efdb8c1
> --- /dev/null
> +++ b/include/sbi/sbi_hwiso.h
> @@ -0,0 +1,56 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * System-level hardware isolation framework
> + *
> + * Copyright (c) 2026 RISCstar Solutions Corporation.
> + *
> + * Author: Raymond Mao <raymond.mao at riscstar.com>
> + */
> +
> +#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__ */
> 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..6c96dc3e
> --- /dev/null
> +++ b/lib/sbi/sbi_hwiso.c
> @@ -0,0 +1,175 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * System-level hardware isolation framework
> + *
> + * Copyright (c) 2026 RISCstar Solutions Corporation.
> + *
> + * Author: Raymond Mao <raymond.mao at riscstar.com>
> + */
> +
> +#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;
> +}
> --
> 2.25.1
>
Let me send a separate series showing how to extend
sbi_hart_isolation as suggested above.
Regards,
Anup
More information about the opensbi
mailing list