Re: [RFC PATCH 3/3] dt-bindings: sifive: Add WorldGuard Checker
Yu-Chien Peter Lin <[email protected]> Wed, 29 Jul 2026 23:30:29 +0800
| Newsgroups | org.infradead.lists.linux-riscv,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <amoclemM+OQbFEHH@plin-1878> |
On Tue, Jul 28, 2026 at 06:34:45PM +0100, Conor Dooley wrote: > On Mon, Jul 27, 2026 at 03:52:46PM +0800, Yu-Chien Peter Lin wrote: > > Hi Conor, > > > > On Mon, Jun 22, 2026 at 06:50:28PM +0100, Conor Dooley wrote: > > > On Fri, Jun 19, 2026 at 06:58:34PM +0800, Yu-Chien Peter Lin wrote: > > > > Add DT binding for SiFive wgChecker2, a hardware firewall enforcing > > > > WID-based access control in RISC-V Worlds. Provides checker slots to > > > > program per-WID permissions for downstream resources, with optional > > > > sub-range partitioning. > > > > > > > > Link: https://github.com/riscvarchive/security/blob/main/papers/worldguard%20proposal.pdf > > > > Signed-off-by: Yu-Chien Peter Lin <[email protected]> > > > > Reviewed-by: Zong Li <[email protected]> > > > > Reviewed-by: Jim Shu <[email protected]> > > > > --- > > > > .../devicetree/bindings/riscv/worlds.yaml | 9 + > > > > .../bindings/sifive/sifive,wgchecker2.yaml | 237 ++++++++++++++++++ > > > > 2 files changed, 246 insertions(+) > > > > create mode 100644 Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml > > > > > > > > diff --git a/Documentation/devicetree/bindings/riscv/worlds.yaml b/Documentation/devicetree/bindings/riscv/worlds.yaml > > > > index cc8b3747591e..c39a06c2dd8d 100644 > > > > --- a/Documentation/devicetree/bindings/riscv/worlds.yaml > > > > +++ b/Documentation/devicetree/bindings/riscv/worlds.yaml > > > > @@ -34,6 +34,14 @@ properties: > > > > minimum: 2 > > > > maximum: 64 > > > > > > > > + sifive,trustedwid: > > > > > > What's sifive specific about this? Wouldn't other vendors also have > > > trusted worlds? > > > > The property is intended to identify the trusted WID, i.e. the > > trusted agent authorized for programming WorldGuard components > > such as wgChecker according to the policy specified in the device > > tree (see sifive,partition-rule below). > > > > wgChecker is a proprietary Worlds-aware firewall and is not part of > > the RISC-V ISA specification, so the Worlds extension itself does > > not define a corresponding concept of a trusted world for this. > > I'm just worried that I am going to see 15 different versions of this > property when 14 other vendors also decide to create support for having > a trusted world. That is a fair concern. However, future RISC-V platforms will likely adopt the IOPMP specification, which may secure its registers via other memory protection mechanism (e.g. PMP) and hardware locks instead of a trusted WID. I expect this property will remain specific to SiFive. > > > > > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > + maximum: 31 > > > > + description: | > > > > + The World ID (WID) designated as the trusted WID for this platform. > > > > + Transactions tagged with this WID are authorized to access and configure > > > > + WorldGuard blocks, including wgCheckers and wgMarkers. > > > > + > > > > additionalProperties: true > > > > > > > > examples: > > > > @@ -44,6 +52,7 @@ examples: > > > > #size-cells = <0>; > > > > timebase-frequency = <1000000>; > > > > riscv,nworlds = <4>; > > > > + sifive,trustedwid = <3>; > > > > > > > > cpu@0 { > > > > device_type = "cpu"; > > > > diff --git a/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml b/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml > > > > new file mode 100644 > > > > index 000000000000..043c748385ed > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/sifive/sifive,wgchecker2.yaml > > > > @@ -0,0 +1,237 @@ > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > > +# Copyright (C) 2026 SiFive, Inc. > > > > +%YAML 1.2 > > > > +--- > > > > +$id: http://devicetree.org/schemas/sifive/sifive,wgchecker2.yaml# > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > + > > > > +title: SiFive WorldGuard Checker > > > > + > > > > +maintainers: > > > > + - Yu-Chien Peter Lin <[email protected]> > > > > + > > > > +description: | > > > > + The RISC-V Worlds ISA extension defines World IDs (WIDs) as architectural > > > > + identifiers that tag each system transaction with its originating context. > > > > + System integrators assign WIDs to execution contexts such as privilege modes, > > > > + trusted execution environments, or other isolation boundaries. > > > > + > > > > + The SiFive WorldGuard Checker is a hardware firewall positioned in the > > > > + system interconnect fabric. It inspects every transaction, evaluating the > > > > + WID against access control policies encoded in checker slots for each > > > > + protected resource. Transactions from unauthorized WIDs are blocked and > > > > + reported as bus errors, interrupts, or both. > > > > + > > > > + This enables spatial partitioning of memory regions and memory-mapped devices > > > > + across execution contexts. Different address ranges can enforce distinct > > > > + policies, allowing isolated workloads to coexist with hardware-enforced > > > > + protection. > > > > + > > > > + The wgChecker acts as an access-controller provider as defined in the > > > > + access-controllers framework. Protected devices are consumers that declare > > > > + their access policy via the access-controllers property. The hardware > > > > + supports up to 32 World IDs. > > > > + > > > > + The World ID authorized to configure WorldGuard blocks is specified by the > > > > + sifive,trustedwid property in the /cpus node. > > > > + > > > > +allOf: > > > > + - $ref: /schemas/access-controllers/access-controllers.yaml# > > > > + > > > > +properties: > > > > + compatible: > > > > + const: sifive,wgchecker2 > > > > > > Missing device specific compatibles. > > > > We will test on qemu, can I add "qemu,wgchecker2" here? > > Sure, with a fallback to the sifive,wgchecker2 compatible. > > > > > + reg: > > > > + maxItems: 1 > > > > + description: > > > > + Base address and size of the wgChecker memory-mapped I/O registers. > > > > + > > > > + interrupts: > > > > + maxItems: 1 > > > > + description: > > > > + Interrupt line asserted when a WID access violation is detected and > > > > + interrupt reporting is enabled in the slot configuration (IR or IW > > > > + bits set). > > > > + > > > > + '#access-controller-cells': > > > > + const: 7 > > > > + description: | > > > > + Specifier for one access-control rule, encoded as seven u32 cells: > > > > + <addr-hi addr-lo size-hi size-lo perm-hi perm-lo config> > > > > + > > > > + where: > > > > + - addr-hi, addr-lo: 64-bit base address of the protected region. > > > > + - size-hi, size-lo: 64-bit size of the protected region in bytes. > > > > > > These two cells effectively just duplicate the reg property. > > > > Agreed, will drop this region encoding. > > > > > > > > > + - perm-hi: Permission bitmap for WIDs 16..31. Two bits per WID: > > > > + bit 2*(WID-16) = Read permission > > > > + bit 2*(WID-16)+1 = Write permission > > > > + Set bits grant access. Use 0x0 for systems with > > > > + riscv,nworlds <= 16. > > > > + - perm-lo: Permission bitmap for WIDs 0..15. Two bits per WID: > > > > + bit 2*WID = Read permission > > > > + bit 2*WID+1 = Write permission > > > > + Set bits grant access. > > > > > > And these two look like a layering violation to me. Why does the > > > consumer contain its own configuration information? If firmware provides > > > this to s-mode, it is either useless (because firmware has already done > > > the configuration) or it makes the access control pointless because > > > s-mode is expected to program its own access. > > > > Yes — DT only describes the access rules. The wgChecker slots are programmed > > by M-mode firmware (OpenSBI), which holds the trusted WID. > > > > riscv,pmwid = <3>; > > sifive,trustedwid = <3> > > M-mode : WID3 (sets mlwid to 0) > > S/U-mode: WID0 > > > > It's fine for Linux to see the access rule, because WID0 is not the trusted > > WID and therefore cannot program the wgChecker configuration registers. > > For denied accesses, reads return zero data and writes are ignored. > > I think you misunderstood, I don't mind linux seeing it, I think having > the configuration information in the consumer node is the problem. > Your example below goes away from that, which I approve of. > > > > > > With that in mind, the first 4 cells can probably just be transmuted to > > > a single cell with platform-specific unique identifiers. > > > > Good point, for memory partition use case, I plan to update the > > encoding to: > > > > ddr: memory@80000000 { > > device_type = "memory"; > > reg = <0x0 0x80000000 0x0 0x80000000>; > > access-controllers = <&wgchecker2 0>, // partition ID: 0 > > <&wgchecker2 1>, // partition ID: 1 > > <&wgchecker2 2>; // partition ID: 2 > > }; > > > > wgchecker2: wgchecker@40000000 { > > compatible = "sifive,wgchecker2"; > > reg = <0x0 0x40000000 0x0 0x1000>; > > #access-controller-cells = <1>; > > #address-cells = <2>; > > #size-cells = <2>; > > interrupts = <82 IRQ_TYPE_LEVEL_HIGH>; > > interrupt-parent = <&aplic_m>; > > > > partition@0 { > > reg = <0x0 0x80000000 0x0 0x40000000>; > > sifive,partition-id = <0>; > > You're gonna cause issues with this because the node address matches > your "partition id" property when it needs to match reg. > Matching "partition id" rather than what you have as "reg" actually > makes more sense though, so I would retain that. > I'd be include to move sifive,partition-id to reg and then rework your > reg property to some new name, because it doesn't describe a register > region belonging to this device. > Possibly I would split what's currently called reg into separate size > and address properties and split partition-rule too. Thanks, Conor, for the suggestions. I’ll address these issues in PATCHv2. Please feel free to point out anything else. > > Does the final "config" bit of partition-rule provide any value to > consumers? The answer is no, right? Cos the interrupts are going to be > reported to m-mode rather than s-mode. Correct. The config flags are only useful to those who are authorized to program the wgChecker slots. > > > /* (perm_hi, perm_lo, config) */ > > sifive,partition-rule = <0x0 0x000000cf 0x0f>; > > }; > > > > partition@1 { > > reg = <0x0 0xc0000000 0x0 0x01000000>; > > sifive,partition-id = <1>; > > /* (perm_hi, perm_lo, config) */ > > sifive,partition-rule = <0x0 0x000000cc 0x0f>; > > }; > > > > partition@2 { > > reg = <0x0 0xc1000000 0x0 0x3f000000>; > > sifive,partition-id = <2>; > > /* (perm_hi, perm_lo, config) */ > > sifive,partition-rule = <0x0 0x000000cf 0x0f>; > > }; > > }; > > > > I hope this work for you. > > > > > Surely the ecall involved with actually requesting access needs > > > something like that anyway? > > > > In this initial support, there is no such interface for S-mode > > to request reconfiguration -- wgCheckers are programmed once at > > boot-time. > > Right, but we need to consider what the final support will look like > when writing the binding! Understood. > > > > The only value I can see in this is if some worlds that a bit of > > > software is running on can access a peripheral (or part thereof) and > > > others can't? Though platforms like that might benefit more from being > > > reworked to have homogeneous access! I've got no idea how a Linux driver > > > etc would handle the only some CPUs being permitted to access a register > > > region. > > > > One use case is APLIC, which naturally has separate root-domain > > and child-domain regions and should be controlled by M-mode and > > S-mode respectively. A wgChecker can protect these regions > > with different access permissions, for example M-mode-only access > > for the root domain and M/S-mode access for the child domain. > > > > The same mechanism can also support multiple supervisor domains > > e.g. for a TEE. As shown in third example, a DRAM sub-region may > > be carved out exclusively for the TEE. > > > > > > > > > + - config: Slot configuration bits: > > > > + Bit 0 (ER): Report read violations as bus errors > > > > + Bit 1 (EW): Report write violations as bus errors > > > > + Bit 2 (IR): Report read violations via interrupt > > > > + Bit 3 (IW): Report write violations via interrupt > > > > + Bit 4 (L): Lock bit - prevents further modification > > > > + Bits 5..31 are reserved and must be zero. > > > > > > For the next revision of this, I really would like to see the access > > > controller driver. > > > > Sure, the fdt driver will be added to OpenSBI. (Not in the kernel which > > runs untrusted WID). > > Whether or not you are trusted, does it not make sense to be able to > request that the firmware give you access to a peripheral? Ultimately > opensbi will be making the configuration edits, but I don't think the > kernel being untrusted precludes it having an access controller driver, > as that driver will just use an ecall rather than manipulate directly. > > That said, I will not expect you to provide that driver now, but unless > reconfiguration at runtime is not supported by hardware this needs to > be considered. That is a very fair point, and TBH, we don't have an answer for now. Currently, our primary use cases for WorldGuard are focused on enforcing M/S-mode access boundary and static partitioning TEEs, S-mode kernels runs transparently within the areas designated by trusted agent. Regards, Peter Lin > > Cheers, > Conor. > > > > > > > > > > + > > > > + Multiple entries may be listed to apply different policies to > > > > + different address ranges, including sub-ranges within a single > > > > + physical resource. > > > > + > > > > +required: > > > > + - compatible > > > > + - reg > > > > + - '#access-controller-cells' > > > > + > > > > +additionalProperties: false > > > > + > > > > +examples: > > > > + - | > > > > + #include <dt-bindings/interrupt-controller/irq.h> > > > > + > > > > + // Example 1: Single device protection > > > > + // WID 0 and WID 3 have RW access to UART; errors and IRQs reported. > > > > + > > > > + cpus { > > > > + #address-cells = <1>; > > > > + #size-cells = <0>; > > > > + timebase-frequency = <1000000>; > > > > + riscv,nworlds = <4>; > > > > + sifive,trustedwid = <3>; > > > > + > > > > + cpu@0 { > > > > + device_type = "cpu"; > > > > + reg = <0>; > > > > + compatible = "riscv"; > > > > + riscv,isa = "rv64imac"; > > > > + }; > > > > + }; > > > > + > > > > + soc { > > > > + #address-cells = <2>; > > > > + #size-cells = <2>; > > > > + > > > > + uart: uart@1c1000 { > > > > + compatible = "ns16550a"; > > > > + reg = <0x0 0x001c1000 0x0 0x1000>; > > > > + reg-names = "control"; > > > > + interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; > > > > + // WID 0,3 RW; report errors+IRQs > > > > + access-controllers = <&wgchecker0 > > > > + 0x0 0x001c1000 0x0 0x00001000 > > > > + 0x0 0x000000c3 0x0f>; > > > > + }; > > > > + > > > > + wgchecker0: wgchecker@1c2000 { > > > > > > I think this should be access-controller@ > > > > Will update. > > > > Thanks, > > Peter Lin _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv