Re: [RFC PATCH v2 2/5] mpt: Add Smsdid and Smmpt supervisor domain core
Rahul Pathak <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <CAFR3w34PZq2jCg2vZcZKm8OY3jtSHkXgz0o+c5CTZw4tMm6PNA@mail.gmail.com> |
On Fri, Aug 14, 2026 at 11:58 PM Pawandeep Oza <[email protected]> wrote: > > On Mon, Jul 27, 2026 at 6:56 AM Rahul Pathak > <[email protected]> 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 <[email protected]> > > --- > > 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)); > > +} > > + -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi