| Message ID | 20260817090503.2104998-6-peter.lin@sifive.com |
|---|---|
| State | New |
| Headers | show |
| Series | Add RISC-V Worlds ISA support to OpenSBI | expand |
On Mon, Aug 17, 2026 at 05:04:59PM +0800, Yu-Chien Peter Lin wrote: > Register a WID-based hart protection mechanism that > configures mlwid and mwiddeleg CSRs on domain entry. > This enables the protection framework reconfigure WID > isolation whenever domains are switched. > > Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com> > --- > Changes v1 -> v2: > - Validate WID against pmlwidlist before writing mlwid CSR (Oza) > --- > include/sbi/sbi_hart_worlds.h | 24 ++++++++++++ > lib/sbi/objects.mk | 1 + > lib/sbi/sbi_hart.c | 5 +++ > lib/sbi/sbi_hart_worlds.c | 72 +++++++++++++++++++++++++++++++++++ > 4 files changed, 102 insertions(+) > create mode 100644 include/sbi/sbi_hart_worlds.h > create mode 100644 lib/sbi/sbi_hart_worlds.c > > diff --git a/include/sbi/sbi_hart_worlds.h b/include/sbi/sbi_hart_worlds.h > new file mode 100644 > index 00000000..2bb35a7e > --- /dev/null > +++ b/include/sbi/sbi_hart_worlds.h > @@ -0,0 +1,24 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (c) 2026 SiFive Inc. > + */ > + > +#ifndef __SBI_HART_WORLDS_H__ > +#define __SBI_HART_WORLDS_H__ > + > +struct sbi_scratch; > + > +/** > + * Initialize WID hart protection for current HART > + * > + * Registers the WID protection mechanism if Smwid/Smlwid > + * extensions are present. Only Smlwid is needed for registration. Will update comment here in the next version.
On Mon, Aug 17, 2026 at 2:05 AM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote: > > Register a WID-based hart protection mechanism that > configures mlwid and mwiddeleg CSRs on domain entry. > This enables the protection framework reconfigure WID > isolation whenever domains are switched. > > Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com> > --- > Changes v1 -> v2: > - Validate WID against pmlwidlist before writing mlwid CSR (Oza) > --- > include/sbi/sbi_hart_worlds.h | 24 ++++++++++++ > lib/sbi/objects.mk | 1 + > lib/sbi/sbi_hart.c | 5 +++ > lib/sbi/sbi_hart_worlds.c | 72 +++++++++++++++++++++++++++++++++++ > 4 files changed, 102 insertions(+) > create mode 100644 include/sbi/sbi_hart_worlds.h > create mode 100644 lib/sbi/sbi_hart_worlds.c > > diff --git a/include/sbi/sbi_hart_worlds.h b/include/sbi/sbi_hart_worlds.h > new file mode 100644 > index 00000000..2bb35a7e > --- /dev/null > +++ b/include/sbi/sbi_hart_worlds.h > @@ -0,0 +1,24 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (c) 2026 SiFive Inc. > + */ > + > +#ifndef __SBI_HART_WORLDS_H__ > +#define __SBI_HART_WORLDS_H__ > + > +struct sbi_scratch; > + > +/** > + * Initialize WID hart protection for current HART > + * > + * Registers the WID protection mechanism if Smwid/Smlwid > + * extensions are present. > + * > + * @param scratch pointer to scratch space of current HART > + * > + * @return 0 on success and negative error code on failure > + */ > +int sbi_hart_worlds_init(struct sbi_scratch *scratch); > + > +#endif /* __SBI_HART_WORLDS_H__ */ > diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk > index c29c888f..ac026dec 100644 > --- a/lib/sbi/objects.mk > +++ b/lib/sbi/objects.mk > @@ -77,6 +77,7 @@ libsbi-objs-y += sbi_fwft.o > libsbi-objs-y += sbi_hart.o > libsbi-objs-y += sbi_hart_pmp.o > libsbi-objs-y += sbi_hart_protection.o > +libsbi-objs-y += sbi_hart_worlds.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_hart.c b/lib/sbi/sbi_hart.c > index 29856c0f..e92f0af3 100644 > --- a/lib/sbi/sbi_hart.c > +++ b/lib/sbi/sbi_hart.c > @@ -17,6 +17,7 @@ > #include <sbi/sbi_error.h> > #include <sbi/sbi_hart.h> > #include <sbi/sbi_hart_pmp.h> > +#include <sbi/sbi_hart_worlds.h> > #include <sbi/sbi_platform.h> > #include <sbi/sbi_pmu.h> > #include <sbi/sbi_string.h> > @@ -762,6 +763,10 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot) > rc = sbi_hart_pmp_init(scratch); > if (rc) > return rc; > + > + rc = sbi_hart_worlds_init(scratch); > + if (rc) > + return rc; > } > > return sbi_hart_reinit(scratch); > diff --git a/lib/sbi/sbi_hart_worlds.c b/lib/sbi/sbi_hart_worlds.c > new file mode 100644 > index 00000000..d9d69b07 > --- /dev/null > +++ b/lib/sbi/sbi_hart_worlds.c > @@ -0,0 +1,72 @@ > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * Copyright (c) 2026 SiFive Inc. > + */ > + > +#include <sbi/riscv_encoding.h> > +#include <sbi/sbi_console.h> > +#include <sbi/sbi_domain.h> > +#include <sbi/sbi_error.h> > +#include <sbi/sbi_hart.h> > +#include <sbi/sbi_hart_protection.h> > +#include <sbi/sbi_hart_worlds.h> > +#include <sbi/sbi_scratch.h> > + > +static int sbi_hart_worlds_configure(struct sbi_scratch *scratch, > + struct sbi_domain *dom) > +{ > + struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch); > + bool wid_found = true; > + u32 wid_val = 0; > + > + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID)) > + return 0; > + > + if (dom->has_wid) { > + wid_val = dom->wid; > + } else if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWID)) { > + wid_val = csr_read(CSR_MWID) & ~MWID_LOCK; > + } else if (hf->has_pmwid) { > + wid_val = hf->pmwid; > + } else { > + /* > + * Smlwid present but no WID source. Without writing > + * mlwid, the hardware reset value is used which may > + * cause a software-check exception on lower-privilege > + * mode entry. > + */ > + wid_found = false; > + } > + > + if (wid_found) { > + if (hf->has_pmlwidlist && > + !(hf->pmlwidlist & BIT_ULL(wid_val))) { > + sbi_printf("%s: domain wid %u not in pmlwidlist\n", > + __func__, wid_val); > + return SBI_EINVAL; > + } > + csr_write(CSR_MLWID, wid_val); > + } > + > + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG)) > + csr_write(CSR_MWIDDELEG, dom->widdeleg); > + > + return 0; > +} > + > +static struct sbi_hart_protection wid_protection = { > + .name = "wid", > + .rating = 100, > + .type = SBI_HART_PROTECTION_TYPE_ID, > + .configure = sbi_hart_worlds_configure, > + .unconfigure = NULL > +}; > + > +int sbi_hart_worlds_init(struct sbi_scratch *scratch) > +{ > + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID)) > + return 0; > + > + return sbi_hart_protection_register(&wid_protection); > +} > -- > 2.43.7 > Oza: except the part that if you decide to remove all the boolenas and figure out from the wid , widlist itslef if that valid or not. Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
diff --git a/include/sbi/sbi_hart_worlds.h b/include/sbi/sbi_hart_worlds.h new file mode 100644 index 00000000..2bb35a7e --- /dev/null +++ b/include/sbi/sbi_hart_worlds.h @@ -0,0 +1,24 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 SiFive Inc. + */ + +#ifndef __SBI_HART_WORLDS_H__ +#define __SBI_HART_WORLDS_H__ + +struct sbi_scratch; + +/** + * Initialize WID hart protection for current HART + * + * Registers the WID protection mechanism if Smwid/Smlwid + * extensions are present. + * + * @param scratch pointer to scratch space of current HART + * + * @return 0 on success and negative error code on failure + */ +int sbi_hart_worlds_init(struct sbi_scratch *scratch); + +#endif /* __SBI_HART_WORLDS_H__ */ diff --git a/lib/sbi/objects.mk b/lib/sbi/objects.mk index c29c888f..ac026dec 100644 --- a/lib/sbi/objects.mk +++ b/lib/sbi/objects.mk @@ -77,6 +77,7 @@ libsbi-objs-y += sbi_fwft.o libsbi-objs-y += sbi_hart.o libsbi-objs-y += sbi_hart_pmp.o libsbi-objs-y += sbi_hart_protection.o +libsbi-objs-y += sbi_hart_worlds.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_hart.c b/lib/sbi/sbi_hart.c index 29856c0f..e92f0af3 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -17,6 +17,7 @@ #include <sbi/sbi_error.h> #include <sbi/sbi_hart.h> #include <sbi/sbi_hart_pmp.h> +#include <sbi/sbi_hart_worlds.h> #include <sbi/sbi_platform.h> #include <sbi/sbi_pmu.h> #include <sbi/sbi_string.h> @@ -762,6 +763,10 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot) rc = sbi_hart_pmp_init(scratch); if (rc) return rc; + + rc = sbi_hart_worlds_init(scratch); + if (rc) + return rc; } return sbi_hart_reinit(scratch); diff --git a/lib/sbi/sbi_hart_worlds.c b/lib/sbi/sbi_hart_worlds.c new file mode 100644 index 00000000..d9d69b07 --- /dev/null +++ b/lib/sbi/sbi_hart_worlds.c @@ -0,0 +1,72 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 SiFive Inc. + */ + +#include <sbi/riscv_encoding.h> +#include <sbi/sbi_console.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_error.h> +#include <sbi/sbi_hart.h> +#include <sbi/sbi_hart_protection.h> +#include <sbi/sbi_hart_worlds.h> +#include <sbi/sbi_scratch.h> + +static int sbi_hart_worlds_configure(struct sbi_scratch *scratch, + struct sbi_domain *dom) +{ + struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch); + bool wid_found = true; + u32 wid_val = 0; + + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID)) + return 0; + + if (dom->has_wid) { + wid_val = dom->wid; + } else if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWID)) { + wid_val = csr_read(CSR_MWID) & ~MWID_LOCK; + } else if (hf->has_pmwid) { + wid_val = hf->pmwid; + } else { + /* + * Smlwid present but no WID source. Without writing + * mlwid, the hardware reset value is used which may + * cause a software-check exception on lower-privilege + * mode entry. + */ + wid_found = false; + } + + if (wid_found) { + if (hf->has_pmlwidlist && + !(hf->pmlwidlist & BIT_ULL(wid_val))) { + sbi_printf("%s: domain wid %u not in pmlwidlist\n", + __func__, wid_val); + return SBI_EINVAL; + } + csr_write(CSR_MLWID, wid_val); + } + + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG)) + csr_write(CSR_MWIDDELEG, dom->widdeleg); + + return 0; +} + +static struct sbi_hart_protection wid_protection = { + .name = "wid", + .rating = 100, + .type = SBI_HART_PROTECTION_TYPE_ID, + .configure = sbi_hart_worlds_configure, + .unconfigure = NULL +}; + +int sbi_hart_worlds_init(struct sbi_scratch *scratch) +{ + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID)) + return 0; + + return sbi_hart_protection_register(&wid_protection); +}
Register a WID-based hart protection mechanism that configures mlwid and mwiddeleg CSRs on domain entry. This enables the protection framework reconfigure WID isolation whenever domains are switched. Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com> --- Changes v1 -> v2: - Validate WID against pmlwidlist before writing mlwid CSR (Oza) --- include/sbi/sbi_hart_worlds.h | 24 ++++++++++++ lib/sbi/objects.mk | 1 + lib/sbi/sbi_hart.c | 5 +++ lib/sbi/sbi_hart_worlds.c | 72 +++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 include/sbi/sbi_hart_worlds.h create mode 100644 lib/sbi/sbi_hart_worlds.c