* [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI
@ 2026-10-30 10:45 Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions Yu-Chien Peter Lin
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
This patch series adds support for the RISC-V Worlds ISA extensions in
OpenSBI, introducing a WID-based hart protection backend to enforce
hardware isolation boundaries across domains.
Trust Model and Boot-time Roles
-------------------------------
The implementation adheres to the two-phase M-mode trust model:
- RoT M-mode phase: An earlier boot stage (e.g., ROM or SPL) may program
mwid and mlwidlist, locking mwid prior to handing off execution to
OpenSBI.
- Regular M-mode phase (OpenSBI): OpenSBI treats the non-ISA platform
constraints (pmwid, pmwidlist, pmlwidlist) and CSR states (mwid,
mlwidlist) as immutable input policies from the hardware/RoT. It locks
mwid if still unlocked, preventing subsequent M-mode software from
altering its own WID, and programs per-domain mlwid and mwiddeleg based
on device tree configuration.
Device Tree Bindings
--------------------
Per-hart properties defined in Linux kernel DT bindings v3 [1]:
- riscv,pmwid: M-mode World ID
- riscv,pmwidlist: M-mode permitted WID bitmap
- riscv,pmlwidlist: S/U-mode permitted WID bitmap
Per-domain properties (see docs/domain_support.md):
- wid: World ID assigned to this domain for S/U-mode
- widdeleg: WID delegation bitmap for this domain
[1] https://patchwork.kernel.org/project/linux-riscv/cover/20260812122131.1534906-1-peter.lin@sifive.com/
Yu-Chien Peter Lin (9):
lib: sbi_hart: add RISC-V Worlds ISA extensions
lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties
lib: fdt_domain: parse domain WID properties
lib: sbi_hart: lock mwid CSR for RoT immutability
lib: sbi_domain_context: propagate error from
sbi_hart_protection_reconfigure
lib: sbi_hart_worlds: Implement WID hart protection backend
include: sbi_types: add PRIx64 format macro
lib: sbi: display World ID configuration at boot
docs: document WID DT properties
docs/domain_support.md | 38 ++++++
include/sbi/riscv_encoding.h | 12 ++
include/sbi/sbi_domain.h | 6 +
include/sbi/sbi_hart.h | 15 +++
include/sbi/sbi_hart_worlds.h | 24 ++++
include/sbi/sbi_types.h | 2 +
lib/sbi/objects.mk | 1 +
lib/sbi/sbi_domain.c | 20 ++++
lib/sbi/sbi_domain_context.c | 5 +-
lib/sbi/sbi_hart.c | 17 +++
lib/sbi/sbi_hart_worlds.c | 210 ++++++++++++++++++++++++++++++++++
lib/sbi/sbi_init.c | 13 +++
lib/utils/fdt/fdt_domain.c | 87 ++++++++++++++
lib/utils/fdt/fdt_helper.c | 69 +++++++++--
14 files changed, 511 insertions(+), 8 deletions(-)
create mode 100644 include/sbi/sbi_hart_worlds.h
create mode 100644 lib/sbi/sbi_hart_worlds.c
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-31 12:48 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties Yu-Chien Peter Lin
` (7 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Add CSR definitions for RISC-V Worlds (mwid, mlwid, mlwidlist,
mwiddeleg, slwid).
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
Change v3->v4:
- Drop trap based extension detection (Anup)
- Drop RB-tag from Oza
---
include/sbi/riscv_encoding.h | 12 ++++++++++++
include/sbi/sbi_hart.h | 10 ++++++++++
lib/sbi/sbi_hart.c | 5 +++++
3 files changed, 27 insertions(+)
diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
index ffe7666c..e0262bfc 100644
--- a/include/sbi/riscv_encoding.h
+++ b/include/sbi/riscv_encoding.h
@@ -400,6 +400,9 @@
/* Supervisor Resource Management Configuration CSRs */
#define CSR_SRMCFG 0x181
+/* Supervisor lower-privilege mode World ID CSR (Sswid) */
+#define CSR_SLWID 0x190
+
/* Machine-Level Control transfer records CSRs */
#define CSR_MCTRCTL 0x34e
@@ -520,6 +523,15 @@
#define CSR_MTINST 0x34a
#define CSR_MTVAL2 0x34b
+/* Machine World ID CSRs (Smwid, Smlwid, Smlwidlist, Smwiddeleg) */
+#define CSR_MLWID 0x390
+#define CSR_MWID 0x749
+#define CSR_MWIDDELEG 0x748
+#define CSR_MLWIDLIST 0x74A
+
+/* mwid lock bit */
+#define MWID_LOCK (_UL(1) << (__riscv_xlen - 1))
+
/* Machine Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index a020cf03..ed344783 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -97,6 +97,16 @@ enum sbi_hart_extensions {
SBI_HART_EXT_F,
/** Hart has D extension */
SBI_HART_EXT_D,
+ /** Hart has Smwid extension */
+ SBI_HART_EXT_SMWID,
+ /** Hart has Smlwid extension */
+ SBI_HART_EXT_SMLWID,
+ /** Hart has Smlwidlist extension */
+ SBI_HART_EXT_SMLWIDLIST,
+ /** Hart has Smwiddeleg extension */
+ SBI_HART_EXT_SMWIDDELEG,
+ /** Hart has Sswid extension */
+ SBI_HART_EXT_SSWID,
/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 925cfe96..77ef1a70 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -355,6 +355,11 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
__SBI_HART_EXT_DATA(v, SBI_HART_EXT_V),
__SBI_HART_EXT_DATA(f, SBI_HART_EXT_F),
__SBI_HART_EXT_DATA(d, SBI_HART_EXT_D),
+ __SBI_HART_EXT_DATA(smwid, SBI_HART_EXT_SMWID),
+ __SBI_HART_EXT_DATA(smlwid, SBI_HART_EXT_SMLWID),
+ __SBI_HART_EXT_DATA(smlwidlist, SBI_HART_EXT_SMLWIDLIST),
+ __SBI_HART_EXT_DATA(smwiddeleg, SBI_HART_EXT_SMWIDDELEG),
+ __SBI_HART_EXT_DATA(sswid, SBI_HART_EXT_SSWID),
};
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-31 12:48 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 3/9] lib: fdt_domain: parse domain " Yu-Chien Peter Lin
` (6 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Extend fdt_parse_isa_extensions_all_harts() to also parse the
platform-defined RISC-V Worlds DT properties in /cpus/cpu@X:
- riscv,pmwid: M-mode World ID
- riscv,pmwidlist: bitmap of permitted M-mode WIDs
- riscv,pmlwidlist: bitmap of permitted lower-privilege WIDs
and store the parsed values in struct sbi_hart_features.
These platform-defined values serve as the root-of-trust constraints
for per-domain WID assignment during domain creation and context
switching.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
Change v3->v4:
- Parse Worlds properties in fdt_parse_isa_extensions_all_harts()
instead of a separate fdt_parse_worlds_all_harts() (Anup).
- Drop RB-tag from Oza
---
include/sbi/sbi_hart.h | 5 +++
lib/utils/fdt/fdt_helper.c | 69 ++++++++++++++++++++++++++++++++++----
2 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index ed344783..629e3f64 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -138,6 +138,11 @@ struct sbi_hart_features {
unsigned int mhpm_mask;
unsigned int mhpm_bits;
unsigned long expected_trap;
+ u32 pmwid;
+ u64 pmwidlist;
+ u64 pmlwidlist;
+ bool has_pmwid;
+ bool has_pmlwidlist;
};
extern unsigned long hart_features_offset;
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 747ba028..fdd25648 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -442,16 +442,71 @@ int fdt_parse_isa_extensions_all_harts(const void *fdt)
if (val && len > 0) {
fdt_parse_isa_extensions_one_hart((const char *)val,
hfeatures->extensions, len);
- continue;
+ } else {
+ val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
+ if (!val || len <= 0)
+ return SBI_ENOENT;
+
+ err = fdt_parse_isa_one_hart((const char *)val,
+ hfeatures->extensions);
+ if (err)
+ return err;
}
- val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
- if (!val || len <= 0)
- return SBI_ENOENT;
+ val = fdt_getprop(fdt, cpu_offset, "riscv,pmwid", &len);
+ if (val && len == sizeof(fdt32_t)) {
+ hfeatures->pmwid = fdt32_to_cpu(*val);
+ hfeatures->has_pmwid = true;
+ }
- err = fdt_parse_isa_one_hart((const char *)val, hfeatures->extensions);
- if (err)
- return err;
+ val = fdt_getprop(fdt, cpu_offset, "riscv,pmwidlist", &len);
+ if (val && len == 2 * sizeof(fdt32_t)) {
+ hfeatures->pmwidlist = ((u64)fdt32_to_cpu(val[0]) << 32) |
+ fdt32_to_cpu(val[1]);
+ if (!hfeatures->pmwidlist) {
+ sbi_printf("%s: hart%u riscv,pmwidlist is empty\n",
+ __func__, hartid);
+ return SBI_EINVAL;
+ }
+ }
+
+ val = fdt_getprop(fdt, cpu_offset, "riscv,pmlwidlist", &len);
+ if (val && len == 2 * sizeof(fdt32_t)) {
+ hfeatures->pmlwidlist = ((u64)fdt32_to_cpu(val[0]) << 32) |
+ fdt32_to_cpu(val[1]);
+ hfeatures->has_pmlwidlist = true;
+ }
+
+ /* Sanity checks */
+#if __riscv_xlen == 32
+ if (hfeatures->pmwidlist &&
+ (hfeatures->pmwidlist >> 32)) {
+ sbi_printf("%s: hart%u riscv,pmwidlist has bits beyond XLEN\n",
+ __func__, hartid);
+ return SBI_EINVAL;
+ }
+
+ if (hfeatures->has_pmlwidlist &&
+ (hfeatures->pmlwidlist >> 32)) {
+ sbi_printf("%s: hart%u riscv,pmlwidlist has bits beyond XLEN\n",
+ __func__, hartid);
+ return SBI_EINVAL;
+ }
+#endif
+
+ if (hfeatures->has_pmwid &&
+ hfeatures->pmwid >= __riscv_xlen) {
+ sbi_printf("%s: hart%u riscv,pmwid (%u) exceeds max WID\n",
+ __func__, hartid, hfeatures->pmwid);
+ return SBI_EINVAL;
+ }
+
+ if (hfeatures->pmwidlist && hfeatures->has_pmwid &&
+ !(hfeatures->pmwidlist & BIT_ULL(hfeatures->pmwid))) {
+ sbi_printf("%s: hart%u riscv,pmwid (%u) not in pmwidlist\n",
+ __func__, hartid, hfeatures->pmwid);
+ return SBI_EINVAL;
+ }
}
return 0;
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 3/9] lib: fdt_domain: parse domain WID properties
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-31 12:49 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 4/9] lib: sbi_hart: lock mwid CSR for RoT immutability Yu-Chien Peter Lin
` (5 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Add wid and widdeleg fields to struct sbi_domain to store the
RISC-V Worlds mlwid and mwiddeleg CSR values for each domain.
Also, parse the root and user-defined domains' WID during
fdt_domains_populate().
The root domain WID is described in the "root" subnode, which
carries the "opensbi,domain,instance" compatible string. Skip
this node in fdt_iterate_each_domain() so that it is not
treated as a regular domain instance.
When Smlwid is implemented, the "wid" property is mandatory
for all domains; fail domain population if it is missing.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
Change v3->v4:
- Skip the "root" node in fdt_iterate_each_domain() so it is not
treated as a regular domain instance (suggested by Anup).
- Drop RB-tag from Oza
---
include/sbi/sbi_domain.h | 6 +++
lib/sbi/sbi_domain.c | 2 +
lib/utils/fdt/fdt_domain.c | 87 ++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 56a21397..5a291d1f 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -19,6 +19,8 @@
struct sbi_scratch;
+#define INVALID_WID ((unsigned int)~0U)
+
/** Domain access types */
enum sbi_domain_access {
SBI_DOMAIN_READ = (1UL << 0),
@@ -218,6 +220,10 @@ struct sbi_domain {
bool system_reset_allowed;
/** Is domain allowed to suspend the system */
bool system_suspend_allowed;
+ /** World ID for this domain (mlwid value) */
+ u32 wid;
+ /** World ID delegation bitmask for this domain (mwiddeleg value) */
+ u64 widdeleg;
/** Identifies whether to include the firmware region */
bool fw_region_inited;
};
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 42fe5632..be9020d0 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -30,6 +30,8 @@ struct sbi_domain root = {
.possible_harts = NULL,
.system_reset_allowed = true,
.system_suspend_allowed = true,
+ .wid = INVALID_WID,
+ .widdeleg = 0,
.fw_region_inited = false,
};
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index e4cce8c3..a2bc002e 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -13,6 +13,7 @@
#include <sbi/sbi_console.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
+#include <sbi/sbi_hart.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_scratch.h>
@@ -37,6 +38,9 @@ int fdt_iterate_each_domain(void *fdt, void *opaque,
return 0;
fdt_for_each_subnode(doffset, fdt, poffset) {
+ if (!strcmp(fdt_get_name(fdt, doffset, NULL), "root"))
+ continue;
+
if (fdt_node_check_compatible(fdt, doffset,
"opensbi,domain,instance"))
continue;
@@ -290,6 +294,42 @@ static int __fdt_parse_region(const void *fdt, int domain_offset,
return 0;
}
+static void fdt_parse_domain_wid_props(const void *fdt, int offset,
+ struct sbi_domain *dom)
+{
+ const fdt32_t *val;
+ int len;
+ u64 val64;
+
+ val = fdt_getprop(fdt, offset, "wid", &len);
+ if (val && len == sizeof(fdt32_t)) {
+ dom->wid = fdt32_to_cpu(val[0]);
+ }
+
+ val = fdt_getprop(fdt, offset, "widdeleg", &len);
+ if (val && (len == (2 * sizeof(fdt32_t)))) {
+ val64 = fdt32_to_cpu(val[0]);
+ val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
+ dom->widdeleg = val64;
+ }
+}
+
+static int validate_domain_wid(const struct sbi_domain *dom)
+{
+ if (dom->wid != INVALID_WID)
+ return 0;
+
+ if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
+ SBI_HART_EXT_SMLWID)) {
+ sbi_printf("%s: domain \"%s\": missing \"wid\""
+ " property (required by Smlwid)\n",
+ __func__, dom->name);
+ return SBI_EINVAL;
+ }
+
+ return 0;
+}
+
static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
{
u32 val32;
@@ -306,6 +346,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
dom = sbi_zalloc(sizeof(*dom));
if (!dom)
return SBI_ENOMEM;
+ dom->wid = INVALID_WID;
preg.dom = dom;
preg.region_count = 0;
@@ -449,6 +490,12 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
}
dom->next_mode = val32;
+ /* Read "wid" and "widdeleg" DT properties */
+ fdt_parse_domain_wid_props(fdt, domain_offset, dom);
+ err = validate_domain_wid(dom);
+ if (err)
+ goto fail_free_all;
+
/* Read "system-reset-allowed" DT property */
if (fdt_get_property(fdt, domain_offset,
"system-reset-allowed", NULL))
@@ -477,12 +524,52 @@ fail_free_domain:
return err;
}
+static int fdt_root_domain_offset(const void *fdt)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, "/chosen");
+ if (offset < 0)
+ return offset;
+
+ offset = fdt_node_offset_by_compatible(fdt, offset,
+ "opensbi,domain,config");
+ if (offset < 0)
+ return offset;
+
+ return fdt_subnode_offset(fdt, offset, "root");
+}
+
+static int fdt_parse_root_domain(const void *fdt)
+{
+ int offset;
+
+ if (fdt) {
+ offset = fdt_root_domain_offset(fdt);
+ if (offset >= 0)
+ fdt_parse_domain_wid_props(fdt, offset, &root);
+ }
+
+ /*
+ * Ensure root domain has a valid WID
+ * even if FDT or root subnode is absent
+ */
+ return validate_domain_wid(&root);
+}
+
int fdt_domains_populate(const void *fdt)
{
+ int err;
+
/* Sanity checks */
if (!fdt)
return SBI_EINVAL;
+ /* Parse root domain config from "root" subnode */
+ err = fdt_parse_root_domain(fdt);
+ if (err)
+ return err;
+
/* Iterate over each domain in FDT and populate details */
return fdt_iterate_each_domain_ro(fdt, NULL, __fdt_parse_domain);
}
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 4/9] lib: sbi_hart: lock mwid CSR for RoT immutability
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (2 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 3/9] lib: fdt_domain: parse domain " Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 5/9] lib: sbi_domain_context: propagate error from sbi_hart_protection_reconfigure Yu-Chien Peter Lin
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Lock the M-mode World ID (mwid) CSR during hart re-initialization
to enforce immutability of the WID established by the root-of-trust.
OpenSBI does not assign the WID value itself; it only sets MWID_LOCK
to freeze the value established by prior RoT stage. The MWID_LOCK bit
at XLEN-1 is sticky and makes the CSR read-only until reset, enforcing
a temporal security boundary per the RISC-V Worlds specification.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
lib/sbi/sbi_hart.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 77ef1a70..611c97bf 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -705,6 +705,13 @@ int sbi_hart_reinit(struct sbi_scratch *scratch)
if (rc)
return rc;
+ /*
+ * Assume MWID is restored by root-of-trust M-mode in previous
+ * stage. Lock mwid so RoT-defined WID remains immutable.
+ */
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWID))
+ csr_set(CSR_MWID, MWID_LOCK);
+
return 0;
}
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 5/9] lib: sbi_domain_context: propagate error from sbi_hart_protection_reconfigure
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (3 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 4/9] lib: sbi_hart: lock mwid CSR for RoT immutability Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend Yu-Chien Peter Lin
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Propagate the return value of sbi_hart_protection_reconfigure in
switch_to_next_domain_context to ensure that domain transition
failures are correctly handled by the caller.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
lib/sbi/sbi_domain_context.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 987ac7fa..1751d016 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -110,6 +110,7 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
MUST_NOT_HOLD(&ctx->dom->assigned_harts_lock)
MUST_NOT_HOLD(&dom_ctx->dom->assigned_harts_lock)
{
+ int rc;
u32 hartindex = current_hartindex();
struct sbi_trap_context *trap_ctx;
struct sbi_domain *current_dom, *target_dom;
@@ -173,7 +174,9 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
* is also required for some of the above CSR updates (such
* as satp CSR).
*/
- sbi_hart_protection_reconfigure(scratch, current_dom, target_dom);
+ rc = sbi_hart_protection_reconfigure(scratch, current_dom, target_dom);
+ if (rc)
+ return rc;
/* Mark current context structure initialized because context saved */
ctx->initialized = true;
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (4 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 5/9] lib: sbi_domain_context: propagate error from sbi_hart_protection_reconfigure Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-11-10 3:36 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 7/9] include: sbi_types: add PRIx64 format macro Yu-Chien Peter Lin
` (2 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Introduce a WID-based hart protection backend that switches World ID
configurations across domains.
Access to slwid is gated by mwiddeleg (Sswid), which means slwid cannot
be handled by generic hart_context save/restore. Instead, manage slwid as
domain state with explicit sequencing:
- configure:
- Validate and program mlwid and mwiddeleg according to domain policy
and platform constraints (pmlwidlist/mlwidlist).
- Restore slwid after mwiddeleg is enabled.
- unconfigure:
- Save slwid prior to clearing mwiddeleg.
- Reset mwiddeleg to 0 to disable Sswid.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
include/sbi/sbi_hart_worlds.h | 24 ++++
lib/sbi/objects.mk | 1 +
lib/sbi/sbi_hart.c | 5 +
lib/sbi/sbi_hart_worlds.c | 210 ++++++++++++++++++++++++++++++++++
4 files changed, 240 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..91b11023
--- /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 Smlwid
+ * extension is 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 ae27d0c5..355ae6e9 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 611c97bf..f7408f51 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>
@@ -742,6 +743,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..6f582bd2
--- /dev/null
+++ b/lib/sbi/sbi_hart_worlds.c
@@ -0,0 +1,210 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 SiFive Inc.
+ */
+
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_bitops.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>
+
+/**
+ * Initialize the per-hart slwid values of a domain using
+ * the lowest delegated WID as the initial value.
+ *
+ * S-mode OS should choose the desire slwid for it's
+ * U-mode.
+ */
+static int sbi_hart_worlds_state_setup(struct sbi_domain *dom,
+ struct sbi_domain_state *state,
+ void *state_ptr)
+{
+ unsigned long widdeleg = dom->widdeleg;
+ unsigned long *slwid = state_ptr;
+ unsigned long init_wid;
+
+ if (!widdeleg)
+ return SBI_OK;
+
+ init_wid = sbi_ffs(widdeleg);
+ sbi_for_each_hartindex(i)
+ slwid[i] = init_wid;
+
+ return SBI_OK;
+}
+
+static struct sbi_domain_state wid_state = {
+ .state_setup = sbi_hart_worlds_state_setup,
+};
+
+static unsigned long *sbi_hart_worlds_slwid_ptr(struct sbi_domain *dom)
+{
+ unsigned long *slwid;
+
+ slwid = sbi_domain_state_ptr(dom, &wid_state);
+ if (!slwid || !sbi_hartindex_valid(current_hartindex()))
+ return NULL;
+
+ return &slwid[current_hartindex()];
+}
+
+static int hart_worlds_validate_wid(struct sbi_scratch *scratch,
+ struct sbi_domain *dom,
+ unsigned long mlwidlist)
+{
+ struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch);
+
+ if (hf->has_pmlwidlist && !(hf->pmlwidlist & BIT_ULL(dom->wid))) {
+ sbi_printf("%s: domain%d WID %u not permitted by"
+ " pmlwidlist\n",
+ __func__, dom->index, dom->wid);
+ return SBI_EINVAL;
+ }
+
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST) &&
+ !(mlwidlist & BIT_ULL(dom->wid))) {
+ sbi_printf("%s: domain%d WID %u not permitted by"
+ " mlwidlist 0x%lx\n",
+ __func__, dom->index, dom->wid, mlwidlist);
+ return SBI_EINVAL;
+ }
+
+ return SBI_OK;
+}
+
+/*
+ * Validate that a domain's widdeleg value, parsed from the
+ * "widdeleg" DT property, is permitted on this hart.
+ *
+ * mwiddeleg is a M-mode WARL register, so an S-mode OS must rely
+ * on the "widdeleg" DT property to determine which WIDs it may
+ * delegate to U-mode via slwid. If pmwidlist or mlwidlist silently
+ * filters out any of those WIDs, the S-mode OS's view of the WIDs
+ * available for delegation would be incorrect. Treat this mismatch
+ * as a misconfiguration.
+ */
+static int hart_worlds_validate_widdeleg(struct sbi_scratch *scratch,
+ struct sbi_domain *dom,
+ unsigned long mlwidlist)
+{
+ struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch);
+ unsigned long widdeleg = dom->widdeleg;
+
+ if (!widdeleg)
+ return SBI_OK;
+
+ if (hf->has_pmlwidlist && (widdeleg & ~hf->pmlwidlist)) {
+ sbi_printf("%s: domain%d widdeleg 0x%lx has WID(s)"
+ " outside pmlwidlist 0x%lx\n",
+ __func__, dom->index, widdeleg,
+ (unsigned long)hf->pmlwidlist);
+ return SBI_EINVAL;
+ }
+
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST) &&
+ (widdeleg & ~mlwidlist)) {
+ sbi_printf("%s: domain%d widdeleg 0x%lx has WID(s)"
+ " outside mlwidlist 0x%lx\n",
+ __func__, dom->index, widdeleg, mlwidlist);
+ return SBI_EINVAL;
+ }
+
+ return SBI_OK;
+}
+
+static int sbi_hart_worlds_configure(struct sbi_scratch *scratch,
+ struct sbi_domain *dom)
+{
+ unsigned long *slwid = NULL;
+ unsigned long mlwidlist = 0;
+ int rc;
+
+ if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID))
+ return SBI_OK;
+
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST))
+ mlwidlist = csr_read(CSR_MLWIDLIST);
+
+ rc = hart_worlds_validate_wid(scratch, dom, mlwidlist);
+ if (rc)
+ return rc;
+
+ csr_write(CSR_MLWID, dom->wid);
+
+ if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG))
+ return SBI_OK;
+
+ rc = hart_worlds_validate_widdeleg(scratch, dom, mlwidlist);
+ if (rc)
+ return rc;
+
+ /*
+ * Enable Sswid before restoring slwid. A zero mwiddeleg
+ * disables access to slwid, so the order here is required.
+ */
+ csr_write(CSR_MWIDDELEG, dom->widdeleg);
+
+ if (dom->widdeleg) {
+ slwid = sbi_hart_worlds_slwid_ptr(dom);
+ if (!slwid)
+ return SBI_EINVAL;
+ csr_write(CSR_SLWID, *slwid);
+ }
+
+ return SBI_OK;
+}
+
+static void sbi_hart_worlds_unconfigure(struct sbi_scratch *scratch,
+ struct sbi_domain *dom)
+{
+ unsigned long *slwid;
+
+ if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG) ||
+ !dom->widdeleg)
+ return;
+
+ /*
+ * Save slwid value before disabling Sswid since the
+ * CSR value may not retain through the disabled period.
+ */
+ slwid = sbi_hart_worlds_slwid_ptr(dom);
+ if (!slwid) {
+ sbi_panic("%s: domain%d has no slwid state\n",
+ __func__, dom->index);
+ }
+ *slwid = csr_read(CSR_SLWID);
+
+ /* Disable Sswid */
+ csr_write(CSR_MWIDDELEG, 0);
+}
+
+static struct sbi_hart_protection wid_protection = {
+ .name = "wid",
+ .rating = 100,
+ .type = SBI_HART_PROTECTION_TYPE_ID,
+ .configure = sbi_hart_worlds_configure,
+ .unconfigure = sbi_hart_worlds_unconfigure
+};
+
+int sbi_hart_worlds_init(struct sbi_scratch *scratch)
+{
+ int rc;
+
+ if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID))
+ return 0;
+
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG)) {
+ wid_state.state_size = sizeof(unsigned long) * sbi_hart_count();
+ rc = sbi_domain_register_state(&wid_state);
+ if (rc)
+ return rc;
+ }
+
+ return sbi_hart_protection_register(&wid_protection);
+}
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 7/9] include: sbi_types: add PRIx64 format macro
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (5 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 8/9] lib: sbi: display World ID configuration at boot Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 9/9] docs: document WID DT properties Yu-Chien Peter Lin
8 siblings, 0 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Add PRIx64 for portable 64-bit hex printing. Expands
to 016lx on RV64 and 016llx on RV32, enabling consistent
printf-style formatting of uint64_t values.
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
include/sbi/sbi_types.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/sbi/sbi_types.h b/include/sbi/sbi_types.h
index b8a7e6cb..780a4c2a 100644
--- a/include/sbi/sbi_types.h
+++ b/include/sbi/sbi_types.h
@@ -34,12 +34,14 @@ typedef unsigned long u64;
typedef long int64_t;
typedef unsigned long uint64_t;
#define PRILX "016lx"
+#define PRIx64 "016lx"
#elif __riscv_xlen == 32
typedef long long s64;
typedef unsigned long long u64;
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define PRILX "08lx"
+#define PRIx64 "016llx"
#else
#error "Unexpected __riscv_xlen"
#endif
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 8/9] lib: sbi: display World ID configuration at boot
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (6 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 7/9] include: sbi_types: add PRIx64 format macro Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 9/9] docs: document WID DT properties Yu-Chien Peter Lin
8 siblings, 0 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Print per-domain Wid/Widdeleg and boot HART's M-mode
World ID (mwid/pmwid fallback).
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
---
lib/sbi/sbi_domain.c | 18 ++++++++++++++++++
lib/sbi/sbi_init.c | 13 +++++++++++++
2 files changed, 31 insertions(+)
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index be9020d0..f92ebc2f 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -10,6 +10,7 @@
#include <sbi/riscv_asm.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_domain.h>
+#include <sbi/sbi_hart.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_hsm.h>
@@ -613,6 +614,7 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
u32 i, j, k;
unsigned long rstart, rend;
const struct sbi_domain_memregion *reg;
+ struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
sbi_printf("Domain%d Name %s: %s\n",
dom->index, suffix, dom->name);
@@ -691,6 +693,22 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
break;
}
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID)) {
+ sbi_printf("Domain%d Wid %s: %u\n",
+ dom->index, suffix, dom->wid);
+ } else {
+ sbi_printf("Domain%d Wid %s: unsupported\n",
+ dom->index, suffix);
+ }
+
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWIDDELEG)) {
+ sbi_printf("Domain%d Widdeleg %s: 0x%" PRIx64 "\n",
+ dom->index, suffix, dom->widdeleg);
+ } else {
+ sbi_printf("Domain%d Widdeleg %s: unsupported\n",
+ dom->index, suffix);
+ }
+
sbi_printf("Domain%d SysReset %s: %s\n",
dom->index, suffix, (dom->system_reset_allowed) ? "yes" : "no");
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index acd2f8b6..f771f548 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -167,6 +167,7 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
int xlen;
char str[256];
const struct sbi_domain *dom = sbi_domain_thishart_ptr();
+ struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch);
if (scratch->options & SBI_SCRATCH_NO_BOOT_PRINTS)
return;
@@ -199,6 +200,18 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
sbi_printf("Boot HART Debug Triggers : %d triggers\n",
sbi_dbtr_get_total_triggers());
sbi_hart_delegation_dump(scratch, "Boot HART ", " ");
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMWID)) {
+ ulong mwid = csr_read(CSR_MWID);
+
+ sbi_printf("Boot HART M-mode World ID : %lu (%s)\n",
+ mwid & ~MWID_LOCK,
+ (mwid & MWID_LOCK) ? "locked" : "unlocked");
+ } else if (hf->has_pmwid) {
+ sbi_printf("Boot HART M-mode World ID : %u (pmwid)\n",
+ hf->pmwid);
+ } else {
+ sbi_printf("Boot HART M-mode World ID : unsupported\n");
+ }
}
static unsigned long coldboot_done;
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 9/9] docs: document WID DT properties
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
` (7 preceding siblings ...)
2026-10-30 10:45 ` [PATCH v4 8/9] lib: sbi: display World ID configuration at boot Yu-Chien Peter Lin
@ 2026-10-30 10:45 ` Yu-Chien Peter Lin
2026-10-31 12:49 ` Anup Patel
8 siblings, 1 reply; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-10-30 10:45 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu, Yu-Chien Peter Lin
Add "wid" and "widdeleg" properties to domain instance node
documentation and example DT. Add a "Root Domain Node" section
describing the "root" subnode under the domain configuration
node for root domain WID configuration
Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
Change v3->v4:
- Make compatible string mandatory for root node
- Drop RB-tag from Oza
---
docs/domain_support.md | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/docs/domain_support.md b/docs/domain_support.md
index 51737218..ed62a6cd 100644
--- a/docs/domain_support.md
+++ b/docs/domain_support.md
@@ -56,6 +56,8 @@ has following details:
domain. This can be either S-mode or U-mode.
* **system_reset_allowed** - Is domain allowed to reset the system?
* **system_suspend_allowed** - Is domain allowed to suspend the system?
+* **wid** - World ID for the domain
+* **widdeleg** - World ID delegation bitmask for the domain
The memory regions represented by **regions** in **struct sbi_domain** have
following additional constraints to align with RISC-V PMP requirements:
@@ -98,6 +100,8 @@ following manner:
is the next mode for the ROOT domain
* **system_reset_allowed** - The ROOT domain is allowed to reset the system
* **system_suspend_allowed** - The ROOT domain is allowed to suspend the system
+* **wid** - Configurable World ID for the ROOT domain
+* **widdeleg** - Configurable World ID delegation bitmask for the ROOT domain
Domain Effects
--------------
@@ -131,6 +135,23 @@ The DT properties of a domain configuration DT node are as follows:
* **compatible** (Mandatory) - The compatible string of the domain
configuration. This DT property should have value *"opensbi,domain,config"*
+### Root Domain Node
+
+The root domain WID configuration is described in a **root** subnode under
+the domain configuration DT node.
+
+The DT properties of the root domain node are as follows:
+
+* **compatible** (Mandatory) - The compatible string of the root domain node.
+ This DT property should have value *"opensbi,domain,instance"*.
+* **wid** (Mandatory if Smlwid is present) - The 32-bit World ID for
+ lower-privilege modes (S/U-mode) for the ROOT domain. If the hart
+ supports the Smlwid extension, this property must be provided.
+* **widdeleg** (Optional) - The 64 bit World ID delegation bitmask for
+ the ROOT domain. If present, OpenSBI writes this value to **mwiddeleg**
+ when entering the ROOT domain (requires Smwiddeleg extension). If absent,
+ clears **mwiddeleg** to disable S-mode WID delegation.
+
### Domain Memory Region Node
The domain memory region DT node describes details of a memory region and
@@ -205,6 +226,13 @@ The DT properties of a domain instance DT node are as follows:
whether the domain instance is allowed to do system reset.
* **system-suspend-allowed** (Optional) - A boolean flag representing
whether the domain instance is allowed to do system suspend.
+* **wid** (Mandatory if Smlwid is present) - The 32-bit World ID for
+ lower-privilege modes (S/U-mode) for the domain instance. If the hart
+ supports the Smlwid extension, this property must be provided.
+* **widdeleg** (Optional) - The 64 bit World ID delegation bitmask for
+ the domain instance. If present, OpenSBI writes this value to **mwiddeleg**
+ on context switch into this domain (requires Smwiddeleg extension). If absent,
+ clears **mwiddeleg** to disable S-mode WID delegation.
### Assigning HART To Domain Instance
@@ -260,6 +288,12 @@ be done:
order = <64>;
};
+ root {
+ compatible = "opensbi,domain,instance";
+ wid = <3>;
+ widdeleg = <0x0 0x0>;
+ };
+
tdomain: trusted-domain {
compatible = "opensbi,domain,instance";
possible-harts = <&cpu0>;
@@ -268,6 +302,8 @@ be done:
next-arg1 = <0x0 0x0>;
next-addr = <0x0 0x80100000>;
next-mode = <0x0>;
+ wid = <1>;
+ widdeleg = <0x0 0x6>;
system-reset-allowed;
system-suspend-allowed;
};
@@ -276,6 +312,8 @@ be done:
compatible = "opensbi,domain,instance";
possible-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;
regions = <&tmem 0x0>, <&tuart 0x0>, <&allmem 0x3f>;
+ wid = <0>;
+ widdeleg = <0x0 0x1>;
};
};
};
--
2.43.7
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions
2026-10-30 10:45 ` [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions Yu-Chien Peter Lin
@ 2026-10-31 12:48 ` Anup Patel
0 siblings, 0 replies; 15+ messages in thread
From: Anup Patel @ 2026-10-31 12:48 UTC (permalink / raw)
To: Yu-Chien Peter Lin
Cc: opensbi, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu
On Fri, Oct 30, 2026 at 4:15 PM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> Add CSR definitions for RISC-V Worlds (mwid, mlwid, mlwidlist,
> mwiddeleg, slwid).
>
> Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup@brainfault.org>
Thanks,
Anup
> ---
> Change v3->v4:
> - Drop trap based extension detection (Anup)
> - Drop RB-tag from Oza
> ---
> include/sbi/riscv_encoding.h | 12 ++++++++++++
> include/sbi/sbi_hart.h | 10 ++++++++++
> lib/sbi/sbi_hart.c | 5 +++++
> 3 files changed, 27 insertions(+)
>
> diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
> index ffe7666c..e0262bfc 100644
> --- a/include/sbi/riscv_encoding.h
> +++ b/include/sbi/riscv_encoding.h
> @@ -400,6 +400,9 @@
> /* Supervisor Resource Management Configuration CSRs */
> #define CSR_SRMCFG 0x181
>
> +/* Supervisor lower-privilege mode World ID CSR (Sswid) */
> +#define CSR_SLWID 0x190
> +
> /* Machine-Level Control transfer records CSRs */
> #define CSR_MCTRCTL 0x34e
>
> @@ -520,6 +523,15 @@
> #define CSR_MTINST 0x34a
> #define CSR_MTVAL2 0x34b
>
> +/* Machine World ID CSRs (Smwid, Smlwid, Smlwidlist, Smwiddeleg) */
> +#define CSR_MLWID 0x390
> +#define CSR_MWID 0x749
> +#define CSR_MWIDDELEG 0x748
> +#define CSR_MLWIDLIST 0x74A
> +
> +/* mwid lock bit */
> +#define MWID_LOCK (_UL(1) << (__riscv_xlen - 1))
> +
> /* Machine Memory Protection */
> #define CSR_PMPCFG0 0x3a0
> #define CSR_PMPCFG1 0x3a1
> diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
> index a020cf03..ed344783 100644
> --- a/include/sbi/sbi_hart.h
> +++ b/include/sbi/sbi_hart.h
> @@ -97,6 +97,16 @@ enum sbi_hart_extensions {
> SBI_HART_EXT_F,
> /** Hart has D extension */
> SBI_HART_EXT_D,
> + /** Hart has Smwid extension */
> + SBI_HART_EXT_SMWID,
> + /** Hart has Smlwid extension */
> + SBI_HART_EXT_SMLWID,
> + /** Hart has Smlwidlist extension */
> + SBI_HART_EXT_SMLWIDLIST,
> + /** Hart has Smwiddeleg extension */
> + SBI_HART_EXT_SMWIDDELEG,
> + /** Hart has Sswid extension */
> + SBI_HART_EXT_SSWID,
>
> /** Maximum index of Hart extension */
> SBI_HART_EXT_MAX,
> diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
> index 925cfe96..77ef1a70 100644
> --- a/lib/sbi/sbi_hart.c
> +++ b/lib/sbi/sbi_hart.c
> @@ -355,6 +355,11 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
> __SBI_HART_EXT_DATA(v, SBI_HART_EXT_V),
> __SBI_HART_EXT_DATA(f, SBI_HART_EXT_F),
> __SBI_HART_EXT_DATA(d, SBI_HART_EXT_D),
> + __SBI_HART_EXT_DATA(smwid, SBI_HART_EXT_SMWID),
> + __SBI_HART_EXT_DATA(smlwid, SBI_HART_EXT_SMLWID),
> + __SBI_HART_EXT_DATA(smlwidlist, SBI_HART_EXT_SMLWIDLIST),
> + __SBI_HART_EXT_DATA(smwiddeleg, SBI_HART_EXT_SMWIDDELEG),
> + __SBI_HART_EXT_DATA(sswid, SBI_HART_EXT_SSWID),
> };
>
> _Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),
> --
> 2.43.7
>
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties
2026-10-30 10:45 ` [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties Yu-Chien Peter Lin
@ 2026-10-31 12:48 ` Anup Patel
0 siblings, 0 replies; 15+ messages in thread
From: Anup Patel @ 2026-10-31 12:48 UTC (permalink / raw)
To: Yu-Chien Peter Lin
Cc: opensbi, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu
On Fri, Oct 30, 2026 at 4:15 PM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> Extend fdt_parse_isa_extensions_all_harts() to also parse the
> platform-defined RISC-V Worlds DT properties in /cpus/cpu@X:
> - riscv,pmwid: M-mode World ID
> - riscv,pmwidlist: bitmap of permitted M-mode WIDs
> - riscv,pmlwidlist: bitmap of permitted lower-privilege WIDs
> and store the parsed values in struct sbi_hart_features.
>
> These platform-defined values serve as the root-of-trust constraints
> for per-domain WID assignment during domain creation and context
> switching.
>
> Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup@brainfault.org>
Thanks,
Anup
> ---
> Change v3->v4:
> - Parse Worlds properties in fdt_parse_isa_extensions_all_harts()
> instead of a separate fdt_parse_worlds_all_harts() (Anup).
> - Drop RB-tag from Oza
> ---
> include/sbi/sbi_hart.h | 5 +++
> lib/utils/fdt/fdt_helper.c | 69 ++++++++++++++++++++++++++++++++++----
> 2 files changed, 67 insertions(+), 7 deletions(-)
>
> diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
> index ed344783..629e3f64 100644
> --- a/include/sbi/sbi_hart.h
> +++ b/include/sbi/sbi_hart.h
> @@ -138,6 +138,11 @@ struct sbi_hart_features {
> unsigned int mhpm_mask;
> unsigned int mhpm_bits;
> unsigned long expected_trap;
> + u32 pmwid;
> + u64 pmwidlist;
> + u64 pmlwidlist;
> + bool has_pmwid;
> + bool has_pmlwidlist;
> };
>
> extern unsigned long hart_features_offset;
> diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
> index 747ba028..fdd25648 100644
> --- a/lib/utils/fdt/fdt_helper.c
> +++ b/lib/utils/fdt/fdt_helper.c
> @@ -442,16 +442,71 @@ int fdt_parse_isa_extensions_all_harts(const void *fdt)
> if (val && len > 0) {
> fdt_parse_isa_extensions_one_hart((const char *)val,
> hfeatures->extensions, len);
> - continue;
> + } else {
> + val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
> + if (!val || len <= 0)
> + return SBI_ENOENT;
> +
> + err = fdt_parse_isa_one_hart((const char *)val,
> + hfeatures->extensions);
> + if (err)
> + return err;
> }
>
> - val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
> - if (!val || len <= 0)
> - return SBI_ENOENT;
> + val = fdt_getprop(fdt, cpu_offset, "riscv,pmwid", &len);
> + if (val && len == sizeof(fdt32_t)) {
> + hfeatures->pmwid = fdt32_to_cpu(*val);
> + hfeatures->has_pmwid = true;
> + }
>
> - err = fdt_parse_isa_one_hart((const char *)val, hfeatures->extensions);
> - if (err)
> - return err;
> + val = fdt_getprop(fdt, cpu_offset, "riscv,pmwidlist", &len);
> + if (val && len == 2 * sizeof(fdt32_t)) {
> + hfeatures->pmwidlist = ((u64)fdt32_to_cpu(val[0]) << 32) |
> + fdt32_to_cpu(val[1]);
> + if (!hfeatures->pmwidlist) {
> + sbi_printf("%s: hart%u riscv,pmwidlist is empty\n",
> + __func__, hartid);
> + return SBI_EINVAL;
> + }
> + }
> +
> + val = fdt_getprop(fdt, cpu_offset, "riscv,pmlwidlist", &len);
> + if (val && len == 2 * sizeof(fdt32_t)) {
> + hfeatures->pmlwidlist = ((u64)fdt32_to_cpu(val[0]) << 32) |
> + fdt32_to_cpu(val[1]);
> + hfeatures->has_pmlwidlist = true;
> + }
> +
> + /* Sanity checks */
> +#if __riscv_xlen == 32
> + if (hfeatures->pmwidlist &&
> + (hfeatures->pmwidlist >> 32)) {
> + sbi_printf("%s: hart%u riscv,pmwidlist has bits beyond XLEN\n",
> + __func__, hartid);
> + return SBI_EINVAL;
> + }
> +
> + if (hfeatures->has_pmlwidlist &&
> + (hfeatures->pmlwidlist >> 32)) {
> + sbi_printf("%s: hart%u riscv,pmlwidlist has bits beyond XLEN\n",
> + __func__, hartid);
> + return SBI_EINVAL;
> + }
> +#endif
> +
> + if (hfeatures->has_pmwid &&
> + hfeatures->pmwid >= __riscv_xlen) {
> + sbi_printf("%s: hart%u riscv,pmwid (%u) exceeds max WID\n",
> + __func__, hartid, hfeatures->pmwid);
> + return SBI_EINVAL;
> + }
> +
> + if (hfeatures->pmwidlist && hfeatures->has_pmwid &&
> + !(hfeatures->pmwidlist & BIT_ULL(hfeatures->pmwid))) {
> + sbi_printf("%s: hart%u riscv,pmwid (%u) not in pmwidlist\n",
> + __func__, hartid, hfeatures->pmwid);
> + return SBI_EINVAL;
> + }
> }
>
> return 0;
> --
> 2.43.7
>
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 3/9] lib: fdt_domain: parse domain WID properties
2026-10-30 10:45 ` [PATCH v4 3/9] lib: fdt_domain: parse domain " Yu-Chien Peter Lin
@ 2026-10-31 12:49 ` Anup Patel
0 siblings, 0 replies; 15+ messages in thread
From: Anup Patel @ 2026-10-31 12:49 UTC (permalink / raw)
To: Yu-Chien Peter Lin
Cc: opensbi, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu
On Fri, Oct 30, 2026 at 4:15 PM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> Add wid and widdeleg fields to struct sbi_domain to store the
> RISC-V Worlds mlwid and mwiddeleg CSR values for each domain.
> Also, parse the root and user-defined domains' WID during
> fdt_domains_populate().
>
> The root domain WID is described in the "root" subnode, which
> carries the "opensbi,domain,instance" compatible string. Skip
> this node in fdt_iterate_each_domain() so that it is not
> treated as a regular domain instance.
>
> When Smlwid is implemented, the "wid" property is mandatory
> for all domains; fail domain population if it is missing.
>
> Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup@brainfault.org>
Thanks,
Anup
> ---
> Change v3->v4:
> - Skip the "root" node in fdt_iterate_each_domain() so it is not
> treated as a regular domain instance (suggested by Anup).
> - Drop RB-tag from Oza
> ---
> include/sbi/sbi_domain.h | 6 +++
> lib/sbi/sbi_domain.c | 2 +
> lib/utils/fdt/fdt_domain.c | 87 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 95 insertions(+)
>
> diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> index 56a21397..5a291d1f 100644
> --- a/include/sbi/sbi_domain.h
> +++ b/include/sbi/sbi_domain.h
> @@ -19,6 +19,8 @@
>
> struct sbi_scratch;
>
> +#define INVALID_WID ((unsigned int)~0U)
> +
> /** Domain access types */
> enum sbi_domain_access {
> SBI_DOMAIN_READ = (1UL << 0),
> @@ -218,6 +220,10 @@ struct sbi_domain {
> bool system_reset_allowed;
> /** Is domain allowed to suspend the system */
> bool system_suspend_allowed;
> + /** World ID for this domain (mlwid value) */
> + u32 wid;
> + /** World ID delegation bitmask for this domain (mwiddeleg value) */
> + u64 widdeleg;
> /** Identifies whether to include the firmware region */
> bool fw_region_inited;
> };
> diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> index 42fe5632..be9020d0 100644
> --- a/lib/sbi/sbi_domain.c
> +++ b/lib/sbi/sbi_domain.c
> @@ -30,6 +30,8 @@ struct sbi_domain root = {
> .possible_harts = NULL,
> .system_reset_allowed = true,
> .system_suspend_allowed = true,
> + .wid = INVALID_WID,
> + .widdeleg = 0,
> .fw_region_inited = false,
> };
>
> diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
> index e4cce8c3..a2bc002e 100644
> --- a/lib/utils/fdt/fdt_domain.c
> +++ b/lib/utils/fdt/fdt_domain.c
> @@ -13,6 +13,7 @@
> #include <sbi/sbi_console.h>
> #include <sbi/sbi_domain.h>
> #include <sbi/sbi_error.h>
> +#include <sbi/sbi_hart.h>
> #include <sbi/sbi_hartmask.h>
> #include <sbi/sbi_heap.h>
> #include <sbi/sbi_scratch.h>
> @@ -37,6 +38,9 @@ int fdt_iterate_each_domain(void *fdt, void *opaque,
> return 0;
>
> fdt_for_each_subnode(doffset, fdt, poffset) {
> + if (!strcmp(fdt_get_name(fdt, doffset, NULL), "root"))
> + continue;
> +
> if (fdt_node_check_compatible(fdt, doffset,
> "opensbi,domain,instance"))
> continue;
> @@ -290,6 +294,42 @@ static int __fdt_parse_region(const void *fdt, int domain_offset,
> return 0;
> }
>
> +static void fdt_parse_domain_wid_props(const void *fdt, int offset,
> + struct sbi_domain *dom)
> +{
> + const fdt32_t *val;
> + int len;
> + u64 val64;
> +
> + val = fdt_getprop(fdt, offset, "wid", &len);
> + if (val && len == sizeof(fdt32_t)) {
> + dom->wid = fdt32_to_cpu(val[0]);
> + }
> +
> + val = fdt_getprop(fdt, offset, "widdeleg", &len);
> + if (val && (len == (2 * sizeof(fdt32_t)))) {
> + val64 = fdt32_to_cpu(val[0]);
> + val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
> + dom->widdeleg = val64;
> + }
> +}
> +
> +static int validate_domain_wid(const struct sbi_domain *dom)
> +{
> + if (dom->wid != INVALID_WID)
> + return 0;
> +
> + if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
> + SBI_HART_EXT_SMLWID)) {
> + sbi_printf("%s: domain \"%s\": missing \"wid\""
> + " property (required by Smlwid)\n",
> + __func__, dom->name);
> + return SBI_EINVAL;
> + }
> +
> + return 0;
> +}
> +
> static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> {
> u32 val32;
> @@ -306,6 +346,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> dom = sbi_zalloc(sizeof(*dom));
> if (!dom)
> return SBI_ENOMEM;
> + dom->wid = INVALID_WID;
>
> preg.dom = dom;
> preg.region_count = 0;
> @@ -449,6 +490,12 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> }
> dom->next_mode = val32;
>
> + /* Read "wid" and "widdeleg" DT properties */
> + fdt_parse_domain_wid_props(fdt, domain_offset, dom);
> + err = validate_domain_wid(dom);
> + if (err)
> + goto fail_free_all;
> +
> /* Read "system-reset-allowed" DT property */
> if (fdt_get_property(fdt, domain_offset,
> "system-reset-allowed", NULL))
> @@ -477,12 +524,52 @@ fail_free_domain:
> return err;
> }
>
> +static int fdt_root_domain_offset(const void *fdt)
> +{
> + int offset;
> +
> + offset = fdt_path_offset(fdt, "/chosen");
> + if (offset < 0)
> + return offset;
> +
> + offset = fdt_node_offset_by_compatible(fdt, offset,
> + "opensbi,domain,config");
> + if (offset < 0)
> + return offset;
> +
> + return fdt_subnode_offset(fdt, offset, "root");
> +}
> +
> +static int fdt_parse_root_domain(const void *fdt)
> +{
> + int offset;
> +
> + if (fdt) {
> + offset = fdt_root_domain_offset(fdt);
> + if (offset >= 0)
> + fdt_parse_domain_wid_props(fdt, offset, &root);
> + }
> +
> + /*
> + * Ensure root domain has a valid WID
> + * even if FDT or root subnode is absent
> + */
> + return validate_domain_wid(&root);
> +}
> +
> int fdt_domains_populate(const void *fdt)
> {
> + int err;
> +
> /* Sanity checks */
> if (!fdt)
> return SBI_EINVAL;
>
> + /* Parse root domain config from "root" subnode */
> + err = fdt_parse_root_domain(fdt);
> + if (err)
> + return err;
> +
> /* Iterate over each domain in FDT and populate details */
> return fdt_iterate_each_domain_ro(fdt, NULL, __fdt_parse_domain);
> }
> --
> 2.43.7
>
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 9/9] docs: document WID DT properties
2026-10-30 10:45 ` [PATCH v4 9/9] docs: document WID DT properties Yu-Chien Peter Lin
@ 2026-10-31 12:49 ` Anup Patel
0 siblings, 0 replies; 15+ messages in thread
From: Anup Patel @ 2026-10-31 12:49 UTC (permalink / raw)
To: Yu-Chien Peter Lin
Cc: opensbi, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu
On Fri, Oct 30, 2026 at 4:15 PM Yu-Chien Peter Lin <peter.lin@sifive.com> wrote:
>
> Add "wid" and "widdeleg" properties to domain instance node
> documentation and example DT. Add a "Root Domain Node" section
> describing the "root" subnode under the domain configuration
> node for root domain WID configuration
>
> Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
LGTM.
Reviewed-by: Anup Patel <anup@brainfault.org>
Thanks,
Anup
> ---
> Change v3->v4:
> - Make compatible string mandatory for root node
> - Drop RB-tag from Oza
> ---
> docs/domain_support.md | 38 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/docs/domain_support.md b/docs/domain_support.md
> index 51737218..ed62a6cd 100644
> --- a/docs/domain_support.md
> +++ b/docs/domain_support.md
> @@ -56,6 +56,8 @@ has following details:
> domain. This can be either S-mode or U-mode.
> * **system_reset_allowed** - Is domain allowed to reset the system?
> * **system_suspend_allowed** - Is domain allowed to suspend the system?
> +* **wid** - World ID for the domain
> +* **widdeleg** - World ID delegation bitmask for the domain
>
> The memory regions represented by **regions** in **struct sbi_domain** have
> following additional constraints to align with RISC-V PMP requirements:
> @@ -98,6 +100,8 @@ following manner:
> is the next mode for the ROOT domain
> * **system_reset_allowed** - The ROOT domain is allowed to reset the system
> * **system_suspend_allowed** - The ROOT domain is allowed to suspend the system
> +* **wid** - Configurable World ID for the ROOT domain
> +* **widdeleg** - Configurable World ID delegation bitmask for the ROOT domain
>
> Domain Effects
> --------------
> @@ -131,6 +135,23 @@ The DT properties of a domain configuration DT node are as follows:
> * **compatible** (Mandatory) - The compatible string of the domain
> configuration. This DT property should have value *"opensbi,domain,config"*
>
> +### Root Domain Node
> +
> +The root domain WID configuration is described in a **root** subnode under
> +the domain configuration DT node.
> +
> +The DT properties of the root domain node are as follows:
> +
> +* **compatible** (Mandatory) - The compatible string of the root domain node.
> + This DT property should have value *"opensbi,domain,instance"*.
> +* **wid** (Mandatory if Smlwid is present) - The 32-bit World ID for
> + lower-privilege modes (S/U-mode) for the ROOT domain. If the hart
> + supports the Smlwid extension, this property must be provided.
> +* **widdeleg** (Optional) - The 64 bit World ID delegation bitmask for
> + the ROOT domain. If present, OpenSBI writes this value to **mwiddeleg**
> + when entering the ROOT domain (requires Smwiddeleg extension). If absent,
> + clears **mwiddeleg** to disable S-mode WID delegation.
> +
> ### Domain Memory Region Node
>
> The domain memory region DT node describes details of a memory region and
> @@ -205,6 +226,13 @@ The DT properties of a domain instance DT node are as follows:
> whether the domain instance is allowed to do system reset.
> * **system-suspend-allowed** (Optional) - A boolean flag representing
> whether the domain instance is allowed to do system suspend.
> +* **wid** (Mandatory if Smlwid is present) - The 32-bit World ID for
> + lower-privilege modes (S/U-mode) for the domain instance. If the hart
> + supports the Smlwid extension, this property must be provided.
> +* **widdeleg** (Optional) - The 64 bit World ID delegation bitmask for
> + the domain instance. If present, OpenSBI writes this value to **mwiddeleg**
> + on context switch into this domain (requires Smwiddeleg extension). If absent,
> + clears **mwiddeleg** to disable S-mode WID delegation.
>
> ### Assigning HART To Domain Instance
>
> @@ -260,6 +288,12 @@ be done:
> order = <64>;
> };
>
> + root {
> + compatible = "opensbi,domain,instance";
> + wid = <3>;
> + widdeleg = <0x0 0x0>;
> + };
> +
> tdomain: trusted-domain {
> compatible = "opensbi,domain,instance";
> possible-harts = <&cpu0>;
> @@ -268,6 +302,8 @@ be done:
> next-arg1 = <0x0 0x0>;
> next-addr = <0x0 0x80100000>;
> next-mode = <0x0>;
> + wid = <1>;
> + widdeleg = <0x0 0x6>;
> system-reset-allowed;
> system-suspend-allowed;
> };
> @@ -276,6 +312,8 @@ be done:
> compatible = "opensbi,domain,instance";
> possible-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;
> regions = <&tmem 0x0>, <&tuart 0x0>, <&allmem 0x3f>;
> + wid = <0>;
> + widdeleg = <0x0 0x1>;
> };
> };
> };
> --
> 2.43.7
>
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend
2026-10-30 10:45 ` [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend Yu-Chien Peter Lin
@ 2026-11-10 3:36 ` Yu-Chien Peter Lin
0 siblings, 0 replies; 15+ messages in thread
From: Yu-Chien Peter Lin @ 2026-11-10 3:36 UTC (permalink / raw)
To: opensbi
Cc: anup, pawandeep.oza, rkrcmar, raymond.mao, robin.randhawa,
samuel.holland, zong.li, greentime.hu
On Fri, Oct 30, 2026 at 06:45:15PM +0800, Yu-Chien Peter Lin wrote:
> Introduce a WID-based hart protection backend that switches World ID
> configurations across domains.
>
> Access to slwid is gated by mwiddeleg (Sswid), which means slwid cannot
> be handled by generic hart_context save/restore. Instead, manage slwid as
> domain state with explicit sequencing:
>
> - configure:
> - Validate and program mlwid and mwiddeleg according to domain policy
> and platform constraints (pmlwidlist/mlwidlist).
> - Restore slwid after mwiddeleg is enabled.
> - unconfigure:
> - Save slwid prior to clearing mwiddeleg.
> - Reset mwiddeleg to 0 to disable Sswid.
>
> Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
> Reviewed-by: Pawandeep Oza <pawandeep.oza@oss.qualcomm.com>
> Reviewed-by: Anup Patel <anup@brainfault.org>
> ---
> include/sbi/sbi_hart_worlds.h | 24 ++++
> lib/sbi/objects.mk | 1 +
> lib/sbi/sbi_hart.c | 5 +
> lib/sbi/sbi_hart_worlds.c | 210 ++++++++++++++++++++++++++++++++++
> 4 files changed, 240 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..91b11023
> --- /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 Smlwid
> + * extension is 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 ae27d0c5..355ae6e9 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 611c97bf..f7408f51 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>
> @@ -742,6 +743,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..6f582bd2
> --- /dev/null
> +++ b/lib/sbi/sbi_hart_worlds.c
> @@ -0,0 +1,210 @@
> +/*
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2026 SiFive Inc.
> + */
> +
> +#include <sbi/riscv_encoding.h>
> +#include <sbi/sbi_bitops.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>
> +
> +/**
> + * Initialize the per-hart slwid values of a domain using
> + * the lowest delegated WID as the initial value.
> + *
> + * S-mode OS should choose the desire slwid for it's
> + * U-mode.
> + */
> +static int sbi_hart_worlds_state_setup(struct sbi_domain *dom,
> + struct sbi_domain_state *state,
> + void *state_ptr)
> +{
> + unsigned long widdeleg = dom->widdeleg;
> + unsigned long *slwid = state_ptr;
> + unsigned long init_wid;
> +
> + if (!widdeleg)
> + return SBI_OK;
> +
> + init_wid = sbi_ffs(widdeleg);
> + sbi_for_each_hartindex(i)
> + slwid[i] = init_wid;
> +
> + return SBI_OK;
> +}
> +
> +static struct sbi_domain_state wid_state = {
> + .state_setup = sbi_hart_worlds_state_setup,
> +};
> +
> +static unsigned long *sbi_hart_worlds_slwid_ptr(struct sbi_domain *dom)
> +{
> + unsigned long *slwid;
> +
> + slwid = sbi_domain_state_ptr(dom, &wid_state);
> + if (!slwid || !sbi_hartindex_valid(current_hartindex()))
> + return NULL;
> +
> + return &slwid[current_hartindex()];
> +}
> +
> +static int hart_worlds_validate_wid(struct sbi_scratch *scratch,
> + struct sbi_domain *dom,
> + unsigned long mlwidlist)
> +{
> + struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch);
> +
> + if (hf->has_pmlwidlist && !(hf->pmlwidlist & BIT_ULL(dom->wid))) {
> + sbi_printf("%s: domain%d WID %u not permitted by"
> + " pmlwidlist\n",
> + __func__, dom->index, dom->wid);
> + return SBI_EINVAL;
> + }
> +
> + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST) &&
> + !(mlwidlist & BIT_ULL(dom->wid))) {
> + sbi_printf("%s: domain%d WID %u not permitted by"
> + " mlwidlist 0x%lx\n",
> + __func__, dom->index, dom->wid, mlwidlist);
> + return SBI_EINVAL;
> + }
> +
> + return SBI_OK;
> +}
> +
> +/*
> + * Validate that a domain's widdeleg value, parsed from the
> + * "widdeleg" DT property, is permitted on this hart.
> + *
> + * mwiddeleg is a M-mode WARL register, so an S-mode OS must rely
> + * on the "widdeleg" DT property to determine which WIDs it may
> + * delegate to U-mode via slwid. If pmwidlist or mlwidlist silently
> + * filters out any of those WIDs, the S-mode OS's view of the WIDs
> + * available for delegation would be incorrect. Treat this mismatch
> + * as a misconfiguration.
> + */
> +static int hart_worlds_validate_widdeleg(struct sbi_scratch *scratch,
> + struct sbi_domain *dom,
> + unsigned long mlwidlist)
> +{
> + struct sbi_hart_features *hf = sbi_hart_features_ptr(scratch);
> + unsigned long widdeleg = dom->widdeleg;
> +
> + if (!widdeleg)
> + return SBI_OK;
> +
> + if (hf->has_pmlwidlist && (widdeleg & ~hf->pmlwidlist)) {
> + sbi_printf("%s: domain%d widdeleg 0x%lx has WID(s)"
> + " outside pmlwidlist 0x%lx\n",
> + __func__, dom->index, widdeleg,
> + (unsigned long)hf->pmlwidlist);
> + return SBI_EINVAL;
> + }
> +
> + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST) &&
> + (widdeleg & ~mlwidlist)) {
> + sbi_printf("%s: domain%d widdeleg 0x%lx has WID(s)"
> + " outside mlwidlist 0x%lx\n",
> + __func__, dom->index, widdeleg, mlwidlist);
> + return SBI_EINVAL;
> + }
> +
> + return SBI_OK;
> +}
> +
> +static int sbi_hart_worlds_configure(struct sbi_scratch *scratch,
> + struct sbi_domain *dom)
> +{
> + unsigned long *slwid = NULL;
> + unsigned long mlwidlist = 0;
> + int rc;
> +
> + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWID))
> + return SBI_OK;
> +
> + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMLWIDLIST))
> + mlwidlist = csr_read(CSR_MLWIDLIST);
> +
> + rc = hart_worlds_validate_wid(scratch, dom, mlwidlist);
> + if (rc)
> + return rc;
> +
> + csr_write(CSR_MLWID, dom->wid);
Need to validate widdelg and bail out before updating mlwid, so mlwid
isn't left holding an invalid target world state on failure. Will fix
in PATCHv5.
Regards,
Peter Lin
> + rc = hart_worlds_validate_widdeleg(scratch, dom, mlwidlist);
> + if (rc)
> + return rc;
> +
> + /*
> + * Enable Sswid before restoring slwid. A zero mwiddeleg
> + * disables access to slwid, so the order here is required.
> + */
> + csr_write(CSR_MWIDDELEG, dom->widdeleg);
> +
> + if (dom->widdeleg) {
> + slwid = sbi_hart_worlds_slwid_ptr(dom);
> + if (!slwid)
> + return SBI_EINVAL;
> + csr_write(CSR_SLWID, *slwid);
> + }
> +
> + return SBI_OK;
> +}
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-11-10 3:36 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 10:45 [PATCH v4 0/9] Add RISC-V Worlds ISA support to OpenSBI Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 1/9] lib: sbi_hart: add RISC-V Worlds ISA extensions Yu-Chien Peter Lin
2026-10-31 12:48 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 2/9] lib: utils: fdt_helper: parse RISC-V Worlds per-hart WID properties Yu-Chien Peter Lin
2026-10-31 12:48 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 3/9] lib: fdt_domain: parse domain " Yu-Chien Peter Lin
2026-10-31 12:49 ` Anup Patel
2026-10-30 10:45 ` [PATCH v4 4/9] lib: sbi_hart: lock mwid CSR for RoT immutability Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 5/9] lib: sbi_domain_context: propagate error from sbi_hart_protection_reconfigure Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 6/9] lib: sbi_hart_worlds: Implement WID hart protection backend Yu-Chien Peter Lin
2026-11-10 3:36 ` Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 7/9] include: sbi_types: add PRIx64 format macro Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 8/9] lib: sbi: display World ID configuration at boot Yu-Chien Peter Lin
2026-10-30 10:45 ` [PATCH v4 9/9] docs: document WID DT properties Yu-Chien Peter Lin
2026-10-31 12:49 ` Anup Patel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox