[PATCH v3 0/5] Add WorldGuard support with SiFive WG checker
Raymond Mao
raymond.mao at riscstar.com
Thu Oct 29 14:52:15 PDT 2026
Hi Peter,
On Thu, Oct 29, 2026 at 12:29 AM Yu-Chien Peter Lin
<peter.lin at sifive.com> wrote:
>
> 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)
>
Thanks for these comments. In v4, I will address them and rebase on
your series [1].
Hopefully I will post v4 after [1] is merged into the mainline.
Regards,
Raymond
[1] https://lore.kernel.org/opensbi/20261027083509.1076577-1-peter.lin@sifive.com/
> Best regards,
> Peter Lin
More information about the opensbi
mailing list