All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.