[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