[PATCH 1/2] sbi: add hardware isolation abstraction framework
Raymond Mao
raymondmaoca at gmail.com
Tue Jul 21 08:20:52 PDT 2026
Hi Anup,
On Fri, Jul 17, 2026 at 3:54 AM Anup Patel <anup at brainfault.org> wrote:
>
> On Thu, Jul 16, 2026 at 7:09 PM Anup Patel <anup at brainfault.org> wrote:
> >
> > 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.
> >
>
> 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
> Regards,
> Anup
More information about the opensbi
mailing list