[PATCH v2 5/9] lib: sbi_hart: add WID protection mechanism
Yu-Chien Peter Lin <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi