[PATCH 1/2] sbi: add hardware isolation abstraction framework

Anup Patel anup at brainfault.org
Wed Jul 22 10:23:02 PDT 2026


On Tue, Jul 21, 2026 at 8:51 PM Raymond Mao <raymondmaoca at gmail.com> wrote:
>
> 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?
>

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



More information about the opensbi mailing list