[PATCH v3 0/5] Add WorldGuard support with SiFive WG checker
Yu-Chien Peter Lin
peter.lin at sifive.com
Wed Oct 28 21:28:57 PDT 2026
Hi Raymond,
On Fri, Sep 04, 2026 at 12:29:10PM -0400, Raymond Mao wrote:
> From: Raymond Mao <raymond.mao at riscstar.com>
>
> This series adds WorldGuard support according to the wgchecker2 DT-
> binding proposal from SiFive [1] with QEMU virt integration.
>
> The implementation:
> - reuse sbi_hart_protection for hart-local runtime reconfiguration
> - reuse sbi_domain_data for per-domain WorldGuard state
> - keep WorldGuard-specific setup and checker programming in platform
> code
>
> At boot, the generic platform code invokes a QEMU virt WorldGuard
> setup path which:
> - parses wgchecker2 checker instances
> - parses provider partition at N entries and programs checker MMIO
> - parses per-hart CPU defaults from /cpus
> - parses per-domain WorldGuard metadata under hw-isolation
>
> Checker programming is provider-driven. Consumer-side
> access-controllers references are carried for DT-binding alignment.
>
> During domain transitions, the WorldGuard hart protection
> implementation reprograms MLWID and, when available, MLWIDLIST,
> MWIDDELEG, and SLWID.
>
> The series is split as follows:
> 1. add reusable FDT helpers needed by the WorldGuard parser
> 2. add WorldGuard CSR definitions and hart extension flags
> 3. document the current DT layout consumed by the implementation
> 4. add the wgchecker2 / WorldGuard runtime and QEMU virt integration
>
> Tested with:
> - QEMU riscv-wg-v4-260821 [2] with arg 'worlds=on' and the merged
> WorldGuard test DTB.
>
> [1] dt-bindings: riscv: Add RISC-V Worlds and SiFive WorldGuard DT
> bindings
> https://lore.kernel.org/linux-devicetree/20260812122131.1534906-1-peter.lin@sifive.com/
> [2] https://github.com/cwshu/qemu/tree/riscv-wg-v4-260821
Thanks for working on this series. Could we align the implementation with
the DT proposal on a few key points?
1. Domain WIDs should use wid / widdeleg directly under domain nodes, not
hw-isolation with sifive,wgchecker2.
My patches already handle the WID assignment and switching.
https://patchwork.ozlabs.org/project/opensbi/patch/20261027083509.1076577-10-peter.lin@sifive.com/
2. wgChecker is a static firewall configured once at boot; by design it does
not support efficient dynamic reconfiguration.
3. Unlike sequential first-match PMP, wgChecker slots are strictly accretive
(parallel OR), so overlapping rules cannot restrict access. i.e.
/* PMP (Priority-based, sequential): */
for (i = N-1; i >= 0; i--) {
if (pmp[i].matches(addr))
return pmp[i].perm; // FIRST match wins
}
/* wgChecker (Strictly accretive, parallel): */
perm = NO_ACCESS;
for (i = 0; i < nslots; i++) {
if (slot[i].matches(addr))
perm |= slot[i].perm[wid]; // OR all matches
}
if (perm allows access)
grant_access();
The wgChecker driver should automatically select between NAPOT and TOR
encoding to minimize slot usage.
4. OpenSBI should support use cases below and dump the wgChecker slot info at boot:
========================================================================
Use Case 1: Single-Slot Peripheral Protection (Full Subordinate Range)
========================================================================
0x001c_1000 +---------------------------------------------------+
| partition at 0 : [0x001c_1000, 0x001c_2000) |
| serial at 1c1000 | WID 0,3 RW (perm 0xc3, cfg 0x1f) |
| Slot00..01 : A=TOR (Slot00 base, Slot01 top) |
0x001c_2000 +---------------------------------------------------+
uart: serial at 1c1000 {
reg = <0x001c1000 0x1000>;
access-controllers = <&wgc0 0>;
};
wgc0: access-controller at 1c2000 {
compatible = "qemu,wgchecker2", "sifive,wgchecker2";
reg = <0x0 0x001c2000 0x0 0x1000>;
#access-controller-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
partition at 0 {
reg = <0>;
sifive,wg-region = <0x0 0x001c1000 0x0 0x00001000>;
sifive,slot-permissions = <0x0 0x000000c3>;
sifive,slot-config = <0x1f>;
};
};
Expected OpenSBI boot dump:
wgChecker Base : 0x1c2000
wgChecker Slot00 : 0x00000000001c1000-.................. 00: A:0 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot01 : ..................-0x00000000001c2000 c3: A:1 ER:1 EW:1 IR:1 IW:1 L:1
wgChecker Slot Usage : 1 (total), 1 (used), 0 (free)
========================================================================
Use Case 2: Multi-Region Peripheral Protection (Disjoint Register Groups)
========================================================================
0x0001_0000 +---------------------------------------------------+
| partition at 0 : [0x0001_0000, 0x0001_8000) (32 KiB) |
| reg[0] m_mode | WID 3 RW (perm 0xc0) | Slot01 |
0x0001_8000 +---------------------------------------------------+
: (unreferenced) :
0x00a0_0000 +---------------------------------------------------+
| partition at 1 : [0x00a0_0000, 0x00a0_4000) (16 KiB) |
| reg[1] s_mode | WID 0,3 RW (perm 0xc3) | Slot02 |
0x00a0_4000 +---------------------------------------------------+
device at 10000 {
reg = <0x0 0x00010000 0x0 0x8000>,
<0x0 0x00a00000 0x0 0x4000>;
reg-names = "m_mode", "s_mode";
access-controllers = <&wgc1 0>, <&wgc1 1>;
};
wgc1: access-controller at 35000 {
compatible = "qemu,wgchecker2", "sifive,wgchecker2";
reg = <0x0 0x00035000 0x0 0x1000>;
#access-controller-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
partition at 0 {
reg = <0>;
sifive,wg-region = <0x0 0x00010000 0x0 0x00008000>;
sifive,slot-permissions = <0x0 0x000000c0>;
sifive,slot-config = <0x0f>;
};
partition at 1 {
reg = <1>;
sifive,wg-region = <0x0 0x00a00000 0x0 0x00004000>;
sifive,slot-permissions = <0x0 0x000000c3>;
sifive,slot-config = <0x0f>;
};
};
Expected OpenSBI boot dump:
wgChecker Base : 0x35000
wgChecker Slot00 : 0x0000000000000000-.................. 00: A:0 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot01 : 0x0000000000010000-0x0000000000018000 c0: A:3 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot02 : 0x0000000000a00000-0x0000000000a04000 c3: A:3 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot04 : ..................-0x0000000001000000 00: A:0 ER:0 EW:0 IR:0 IW:0 L:0
wgChecker Slot Usage : 4 (total), 2 (used), 2 (free)
========================================================================
Use Case 3: Multi-Domain DRAM Spatial Partitioning (Hybrid NAPOT + TOR)
========================================================================
OpenSBI: WID3
Linux : WID0
OP-TEE : WID1
0x8000_0000 +---------------------------------------------------+
| partition at 0 : [0x8000_0000, 0xC000_0000) (1024M) |
| Linux / OpenSBI | WID 0,1,3 RW (0xcf) | Slot01 A:3|
0xC000_0000 +---------------------------------------------------+
| partition at 1 : [0xC000_0000, 0xC100_0000) (16M) |
| OP-TEE / OpenSBI| WID 1,3 RW (0xcc) | Slot02 A:3|
0xC100_0000 +---------------------------------------------------+
| partition at 2 : [0xC100_0000, 0x1_0000_0000) (1008M)|
| Linux / OpenSBI | WID 0,1,3 RW (0xcf) | Slot03..04|
0x1_0000_0000 +-------------------------------------------------+
memory: memory at 80000000 {
reg = <0x0 0x80000000 0x0 0x80000000>;
access-controllers = <&wgc2 0>, <&wgc2 1>, <&wgc2 2>;
};
wgc2: access-controller at 50000000 {
compatible = "qemu,wgchecker2", "sifive,wgchecker2";
reg = <0x0 0x50000000 0x0 0x1000>;
#access-controller-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
partition at 0 {
reg = <0>;
sifive,wg-region = <0x0 0x80000000 0x0 0x40000000>;
sifive,slot-permissions = <0x0 0x000000cf>;
sifive,slot-config = <0x0f>;
};
partition at 1 {
reg = <1>;
sifive,wg-region = <0x0 0xc0000000 0x0 0x01000000>;
sifive,slot-permissions = <0x0 0x000000cc>;
sifive,slot-config = <0x0f>;
};
partition at 2 {
reg = <2>;
sifive,wg-region = <0x0 0xc1000000 0x0 0x3f000000>;
sifive,slot-permissions = <0x0 0x000000cf>;
sifive,slot-config = <0x0f>;
};
};
Expected OpenSBI boot dump:
wgChecker Base : 0x50000000
wgChecker Slot00 : 0x0000000000000000-.................. 00: A:0 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot01 : 0x0000000080000000-0x00000000c0000000 cf: A:3 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot02 : 0x00000000c0000000-0x00000000c1000000 cc: A:3 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot03 : 0x00000000c1000000-.................. 00: A:0
wgChecker Slot04 : ..................-0x0000000100000000 cf: A:1 ER:1 EW:1 IR:1 IW:1 L:0
wgChecker Slot16 : ..................-0x0000000100000000 00: A:0 ER:0 EW:0 IR:0 IW:0 L:0
wgChecker Slot Usage : 16 (total), 4 (used), 12 (free)
Best regards,
Peter Lin
More information about the opensbi
mailing list