[RFC PATCH v2 2/5] mpt: Add Smsdid and Smmpt supervisor domain core
Rahul Pathak
rahul.pathak at oss.qualcomm.com
Sat Aug 22 05:18:42 PDT 2026
On Fri, Aug 14, 2026 at 11:58 PM Pawandeep Oza
<pawandeep.oza at oss.qualcomm.com> wrote:
>
> On Mon, Jul 27, 2026 at 6:56 AM Rahul Pathak
> <rahul.pathak at oss.qualcomm.com> wrote:
> >
> > Introduce the supervisord omain memory-protection (Smmpt) table
> Oza: typo: "supervisord omain"
Rahul: Sure, will update
> > management core. This adds the mode agnostic core layer and the
> > per mode table walkers/builder.
> >
> > Add defines for the mmpt CSR encoding, MPTE bit layout, permission flags,
> > structures, fence helpers and the public interfaces.
> >
> > It implements the RV64 supported modes (Smmpt43/52/64) and
> > the RV32 mode (Smmpt34), its MPT table support.
> >
> > Also implements mpt core which integrates Smmpt with SBI domains and
> > other core layers.
> >
> > Signed-off-by: Rahul Pathak <rahul.pathak at oss.qualcomm.com>
> > ---
> > include/sbi/sbi_mpt.h | 334 ++++++++++++++
> > lib/sbi/objects.mk | 2 +
> > lib/sbi/sbi_mpt.c | 926 ++++++++++++++++++++++++++++++++++++++
> > lib/sbi/sbi_mpt_mode.c | 997 +++++++++++++++++++++++++++++++++++++++++
> > 4 files changed, 2259 insertions(+)
> > create mode 100644 include/sbi/sbi_mpt.h
> > create mode 100644 lib/sbi/sbi_mpt.c
> > create mode 100644 lib/sbi/sbi_mpt_mode.c
> >
> > + return xwr;
> > +}
> > +
> > +/*
> > + * sbi_mpt_domain_create(): Create a Supervisor Domain
> Oza: "Create a Supervisor Domain" ? You probably meant "Create an mpt domain" !
Rahul: Yes, will change
>
> > + */
> > +int sbi_mpt_domain_create(const struct sbi_mpt_domain_config *cfg,
> > + u32 *out_sdid)
> > +{
> > + int rc;
> > + u32 sdid, i;
> > + unsigned long root_pa;
> > + struct sbi_mpt_mode *sch;
> > + struct sbi_mpt_domain *dom;
> > + const struct sbi_domain_memregion *mr;
> > + struct sbi_mpt_ctrl *ctrl = &mpt_ctrl;
> > + u8 base_xwr = SBI_MPT_PERM_NONE;
> > +
> > + if (!ctrl->ready)
> > + return SBI_ENODEV;
> > +
> > + if (cfg->sbi_dom && cfg->nregions) {
> > + sbi_printf("sbi_mpt: sbi_dom and explicit regions are mutually exclusive\n");
> > + return SBI_EINVAL;
> > + }
> > +
> > + /*
> > + * sdid_bitmap empty means every available SDID is
> > + * currently in use and no domain can be created.
> > + */
> > + if (bitmap_empty(ctrl->sdid_bitmap, ctrl->max_domains))
> > + return SBI_ENOMEM;
> > +
> > + sch = ctrl->mode;
> > +
> > + root_pa = sbi_mpt_pool_alloc(sch->root_table_size(),
> > + sch->root_table_align());
> > + if (!root_pa) {
rv64_write_mpte(grp_base + i * RV64_MPTE_SIZE, leaf);
> > +}
> > +
> > +/*
> > + * MPT table best-level selection
> > + *
> > + * Returns the highest level at which the range [pa, pa+size] can be
> > + * covered by a single leaf MPTE. Level 0 is always valid because thats
> > + * the last resort.
> > + */
> > +static u32 rv64_best_level(unsigned long pa, unsigned long size,
> > + u32 top_level)
> > +{
> > + u32 lvl;
> > + unsigned long range;
> Oza: need to validate ?? or trust top_level her ?
> if (!top_level) return 0;
Rahul: This if condition will be redundant since below for
loop will not enter if top_level == 0
> > +
> > + for (lvl = top_level; lvl >= 1; lvl--) {
> > + range = rv64_mpte_range(lvl);
> > +
> > + if (size >= range && (pa & (range - 1)) == 0)
> > + return lvl;
> > + }
> > + return 0;
> > +}
> > +
> > +/*
> > + * Generic N-level walk with lazy table allocation
> > + */
> > +static unsigned long rv64_split_leaf(unsigned long parent_ep)
> > +{
> > + u64 parent = rv64_read_mpte(parent_ep);
> > + unsigned long sub;
> > + u32 j, pg, sh;
> > + u8 xwr;
> > + u64 child;
> > +
> > + sub = sbi_mpt_pool_alloc(RV64_TABLE_SIZE, SBI_MPT_PAGE_SIZE);
> > + if (!sub)
> > + return 0;
> > +
> > + for (j = 0; j < RV64_INNER_ENTRIES; j++) {
> > + sh = sbi_mpte_xwr_shift(j >> 5);
> Oza: can we define 5 ?
Rahul: Sure, will define a macro for it
> > + xwr = (((unsigned long)parent >> sh) & SBI_MPTE_XWR_MASK);
> > + child = SBI_MPTE_V | SBI_MPTE_L; /* N=0 uniform leaf */
> > +
> > + for (pg = 0; pg < RV64_PAGES_PER_MPTE; pg++)
> > + child = sbi_mpte_leaf_set_xwr(child, pg, xwr);
> > +
> > + rv64_write_mpte(sub + j * RV64_MPTE_SIZE, child);
> > + }
> > +
> > + /* parent leaf -> non-leaf pointer to MPT sub table. */
> > + rv64_write_mpte(parent_ep, sbi_mpte_nonleaf(sub));
> > +
> > + return sub;
> > +}
> > +
> > +/*
> > + * Walk a MPT table and return MPTE PA and its suitable level
> > + */
> > +static unsigned long rv64_walk_alloc(struct sbi_mpt_domain *dom,
> > + unsigned long pa,
> > + unsigned long size,
> > + u32 *out_level,
> > + u32 top_level)
> > +{
> > + u32 lvl, idx;
> > + u64 mpte;
> > + unsigned long ep, sub, new_pa;
> > + const struct sbi_mpt_mode *sch = dom->mode;
> > + unsigned long table_pa = dom->root_pa;
> > + u32 best_lvl = rv64_best_level(pa, size, top_level);
> > +
> > +
> > + for (lvl = top_level; lvl >= 1; lvl--) {
> > + idx = rv64_table_idx(pa, lvl, sch);
> > + ep = rv64_mpte_pa(table_pa, idx);
> > + mpte = rv64_read_mpte(ep);
> > +
> > + if (mpte & SBI_MPTE_L) {
> > + if (lvl > best_lvl) {
> > + sub = rv64_split_leaf(ep);
> > + if (!sub)
> > + return 0;
> > +
> > + table_pa = sub;
> Oza: do you need to decrement lvl here since you are splitting ? e.g. lvl--
Rahul: below continue make sure that lvl is decremented in next pass of for loop
Do you mean I have to decrement lvl again here though due to below continue,
it will be decremented twice?
>
> > + continue;
> > + }
> > +
> > + *out_level = lvl;
> > + return ep;
> > + }
> > +
> > + if (!(mpte & SBI_MPTE_V)) {
> > + if (lvl <= best_lvl) {
> > + *out_level = lvl;
> > + return ep;
> > + }
> > + /* Allocate inner table (always 4KiB, all levels, all modes) */
> > + new_pa = sbi_mpt_pool_alloc(RV64_TABLE_SIZE,
> > + SBI_MPT_PAGE_SIZE);
> > + if (!new_pa)
> > + return 0;
> > +
> > + rv64_write_mpte(ep, (u64)sbi_mpte_nonleaf(new_pa));
> > + table_pa = new_pa;
> > + }
> > + else {
> > + table_pa = rv64_next_table_pa(mpte);
> > + }
> > + }
> > +
> > + *out_level = 0;
> > +
> > + return rv64_mpte_pa(table_pa, rv64_table_idx(pa, 0, sch));
> > +}
> > +
More information about the opensbi
mailing list