[PATCH 4/5] lib: sbi: Extend hart protection abstraction to allow ID configuration
Anup Patel
anup.patel at oss.qualcomm.com
Fri Jul 24 08:04:00 PDT 2026
On Wed, Jul 22, 2026 at 4:52 PM Rahul Pathak
<rahul.pathak at oss.qualcomm.com> wrote:
>
> On Fri, Jul 17, 2026 at 1:15 PM Anup Patel <anup.patel at oss.qualcomm.com> wrote:
> >
> > There are various ID configuration ISA extensions such as RISC-V Worlds,
> > Supervisor domain ID, QoS ID, etc which need to be re-configured upon
> > domain context switch on a hart. Extend hart protection abstraction to
> > support both memory protection and ID configuration ISA extensions.
> >
> > Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> > ---
> > include/sbi/sbi_hart_protection.h | 16 +++++-
> > lib/sbi/sbi_hart_pmp.c | 2 +
> > lib/sbi/sbi_hart_protection.c | 94 ++++++++++++++++++++++++++-----
> > lib/sbi/sbi_init.c | 2 +-
> > platform/generic/eswin/eic770x.c | 1 +
> > 5 files changed, 98 insertions(+), 17 deletions(-)
> >
> > diff --git a/include/sbi/sbi_hart_protection.h b/include/sbi/sbi_hart_protection.h
> > index 5e170f05..1358b5be 100644
> > --- a/include/sbi/sbi_hart_protection.h
> > +++ b/include/sbi/sbi_hart_protection.h
> > @@ -13,6 +13,13 @@
> > struct sbi_scratch;
> > struct sbi_domain;
> >
> > +/** Different types of hart protection mechanisms */
> > +enum sbi_hart_protection_type {
> > + SBI_HART_PROTECTION_TYPE_MEMORY = 0,
> > + SBI_HART_PROTECTION_TYPE_ID,
> > + SBI_HART_PROTECTIOn_TYPE_MAX
> Typo here "n"
Okay, I will update.
>
> > +};
> > +
> > /** Representation of hart protection mechanism */
> > struct sbi_hart_protection {
> > /** List head */
> > @@ -21,6 +28,9 @@ struct sbi_hart_protection {
> > /** Name of the hart protection mechanism */
> > char name[32];
> >
> > + /** Type of the hart protection mechanism */
> > + enum sbi_hart_protection_type type;
> > +
> > /** Ratings of the hart protection mechanism (higher is better) */
> > unsigned long rating;
> >
> > @@ -40,11 +50,11 @@ struct sbi_hart_protection {
> > };
> >
> > /**
> > - * Get the best hart protection mechanism
> > + * Get the best hart memory protection mechanism
> > *
> > - * @return pointer to best hart protection mechanism
> > + * @return pointer to best hart memory protection mechanism
> > */
> > -struct sbi_hart_protection *sbi_hart_protection_best(void);
> > +struct sbi_hart_protection *sbi_hart_memory_protection_best(void);
> >
> > /**
> > * Register a hart protection mechanism
> > diff --git a/lib/sbi/sbi_hart_pmp.c b/lib/sbi/sbi_hart_pmp.c
> > index 5ede3cc1..c0a4ce1b 100644
> > --- a/lib/sbi/sbi_hart_pmp.c
> > +++ b/lib/sbi/sbi_hart_pmp.c
> > @@ -425,6 +425,7 @@ static void sbi_hart_pmp_unconfigure(struct sbi_scratch *scratch,
> > static struct sbi_hart_protection pmp_protection = {
> > .name = "pmp",
> > .rating = 100,
> > + .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> > .configure = sbi_hart_oldpmp_configure,
> > .unconfigure = sbi_hart_pmp_unconfigure,
> > };
> > @@ -432,6 +433,7 @@ static struct sbi_hart_protection pmp_protection = {
> > static struct sbi_hart_protection epmp_protection = {
> > .name = "epmp",
> > .rating = 200,
> > + .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> > .configure = sbi_hart_smepmp_configure,
> > .unconfigure = sbi_hart_pmp_unconfigure,
> > .map_range = sbi_hart_smepmp_map_range,
> > diff --git a/lib/sbi/sbi_hart_protection.c b/lib/sbi/sbi_hart_protection.c
> > index fecefde8..d31e9938 100644
> > --- a/lib/sbi/sbi_hart_protection.c
> > +++ b/lib/sbi/sbi_hart_protection.c
> > @@ -10,12 +10,16 @@
> >
> > static SBI_LIST_HEAD(hart_protection_list);
> >
> > -struct sbi_hart_protection *sbi_hart_protection_best(void)
> > +struct sbi_hart_protection *sbi_hart_memory_protection_best(void)
> > {
> > - if (sbi_list_empty(&hart_protection_list))
> > - return NULL;
> > + struct sbi_hart_protection *pos;
> >
> > - return sbi_list_first_entry(&hart_protection_list, struct sbi_hart_protection, head);
> > + sbi_list_for_each_entry(pos, &hart_protection_list, head) {
> > + if (pos->type == SBI_HART_PROTECTION_TYPE_MEMORY)
> > + return pos;
> > + }
> > +
> > + return NULL;
> > }
> >
> > int sbi_hart_protection_register(struct sbi_hart_protection *hprot)
> > @@ -74,33 +78,97 @@ static void __hart_protection_unconfigure(struct sbi_scratch *scratch,
> > int sbi_hart_protection_configure(struct sbi_scratch *scratch,
> > struct sbi_domain *dom)
> > {
> > - return __hart_protection_configure(scratch, sbi_hart_protection_best(), dom);
> > + bool do_configure, memory_protect_done = false;
> > + struct sbi_hart_protection *hprot;
> > + int ret;
> > +
> > + sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > + do_configure = false;
> > + switch (hprot->type) {
> While reading the code found that hprot->type checking is not done
> in the early stage in sbi_hart_protection_register itself. If firmware
> has to explicitly check and fail upon invalid type then why not fail
> while registering the protection mechanism itself.
Indeed, the sbi_hart_protection_register () should also check type.
>
>
> > + case SBI_HART_PROTECTION_TYPE_MEMORY:
> > + do_configure = !memory_protect_done;
> > + memory_protect_done = true;
> > + break;
> > + case SBI_HART_PROTECTION_TYPE_ID:
> > + do_configure = true;
> > + break;
> > + default:
> > + break;
> > + }
> > + if (!do_configure)
> > + continue;
> > +
> > + ret = __hart_protection_configure(scratch, hprot, dom);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > }
> >
> > void sbi_hart_protection_unconfigure(struct sbi_scratch *scratch,
> > struct sbi_domain *dom)
> > {
> > - __hart_protection_unconfigure(scratch, sbi_hart_protection_best(), dom);
> > +
> > + bool do_unconfigure, memory_protect_done = false;
> > + struct sbi_hart_protection *hprot;
> > +
> > + sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > + do_unconfigure = false;
> > + switch (hprot->type) {
> > + case SBI_HART_PROTECTION_TYPE_MEMORY:
> > + do_unconfigure = !memory_protect_done;
> > + memory_protect_done = true;
> > + break;
> > + case SBI_HART_PROTECTION_TYPE_ID:
> > + do_unconfigure = true;
> > + break;
> > + default:
> > + break;
> > + }
> > + if (!do_unconfigure)
> > + continue;
> > +
> > + __hart_protection_unconfigure(scratch, hprot, dom);
> > + }
> > }
> >
> > int sbi_hart_protection_reconfigure(struct sbi_scratch *scratch,
> > struct sbi_domain *current_dom,
> > struct sbi_domain *next_dom)
> > {
> > - struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > + bool do_reconfigure, memory_protect_done = false;
> > + struct sbi_hart_protection *hprot;
> > int ret;
> >
> > - __hart_protection_unconfigure(scratch, hprot, current_dom);
> > - ret = __hart_protection_configure(scratch, hprot, next_dom);
> > - if (ret)
> > - return ret;
> > + sbi_list_for_each_entry(hprot, &hart_protection_list, head) {
> > + do_reconfigure = false;
> > + switch (hprot->type) {
> > + case SBI_HART_PROTECTION_TYPE_MEMORY:
> > + do_reconfigure = !memory_protect_done;
> > + memory_protect_done = true;
> > + break;
> > + case SBI_HART_PROTECTION_TYPE_ID:
> > + do_reconfigure = true;
> > + break;
> > + default:
> > + break;
> > + }
> > + if (!do_reconfigure)
> > + continue;
> > +
> > + __hart_protection_unconfigure(scratch, hprot, current_dom);
> > + ret = __hart_protection_configure(scratch, hprot, next_dom);
> > + if (ret)
> > + return ret;
> > + }
> >
> > return 0;
> > }
> >
> > int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
> > {
> > - struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > + struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
> >
> > if (!hprot || !hprot->map_range)
> > return 0;
> > @@ -110,7 +178,7 @@ int sbi_hart_protection_map_range(unsigned long base, unsigned long size)
> >
> > int sbi_hart_protection_unmap_range(unsigned long base, unsigned long size)
> > {
> > - struct sbi_hart_protection *hprot = sbi_hart_protection_best();
> > + struct sbi_hart_protection *hprot = sbi_hart_memory_protection_best();
> >
> > if (!hprot || !hprot->unmap_range)
> > return 0;
> > diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> > index d74dc67c..3f1f136a 100644
> > --- a/lib/sbi/sbi_init.c
> > +++ b/lib/sbi/sbi_init.c
> > @@ -93,7 +93,7 @@ static void sbi_boot_print_general(struct sbi_scratch *scratch)
> > sbi_printf("Platform Features : %s\n", str);
> > sbi_printf("Platform HART Count : %u\n",
> > sbi_platform_hart_count(plat));
> > - hprot = sbi_hart_protection_best();
> > + hprot = sbi_hart_memory_protection_best();
> > sbi_printf("Platform HART Protection : %s\n",
> > (hprot) ? hprot->name : "---");
> > idev = sbi_ipi_get_device();
> > diff --git a/platform/generic/eswin/eic770x.c b/platform/generic/eswin/eic770x.c
> > index da4d0e34..c71198a8 100644
> > --- a/platform/generic/eswin/eic770x.c
> > +++ b/platform/generic/eswin/eic770x.c
> > @@ -470,6 +470,7 @@ static void eswin_eic7700_pmp_unconfigure(struct sbi_scratch *scratch,
> > static struct sbi_hart_protection eswin_eic7700_pmp_protection = {
> > .name = "eic7700_pmp",
> > .rating = -1UL,
> > + .type = SBI_HART_PROTECTION_TYPE_MEMORY,
> > .configure = eswin_eic7700_pmp_configure,
> > .unconfigure = eswin_eic7700_pmp_unconfigure,
> > };
> > --
> > 2.43.0
> >
> >
> > --
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi
Regards,
Anup
More information about the opensbi
mailing list