Loading

RISC-V IOPMP

RISC-V IOPMP Architecture Specification

RISC-V IOPMP Spec 官方文档 https://github.com/riscv-non-isa/iopmp-spec
整理自 Version 0.7, Feb, 2025

Introduction

  • 在 RISC-V 平台中,bus initiators(like RISC-V hart) 可以访问目标设备。引入 I/O agents(like DMA) 提高性能的同时也使系统易受到 DMA 攻击。在 RISC-V 生态系统中,PMP/ePMP 为从 RISC-V hart 到物理地址空间的访问提供了标准的保护方案。 但是,没有用于保护 non-CPU initiators 的等效标准。IOPMP(Physical Memory Protection Unit of Input/Output devices) 通过控制 bus initiators 发出的访问来解决这一问题。
  • IOPMP 是总线结构中的硬件组件,用于解决纯软件解决方案不足的情况。对于基于 RISC-V 的平台,软件解决方案通常涉及 Security Monitor(SM),这是一个在 M-mode 下运行的特权程序,用于处理与安全相关的请求。当发出 DMA 传输请求时,SM 检查它是否满足所有安全规则,并决定它是否合法,仅执行合法的请求。然而,这种检查可能很耗时,特别是对于来自 GPU 的复杂请求,这可能涉及运行程序。判断一个程序是否违反了访问规则通常是一个 NP-hard 问题。即使只考虑平均执行时间,延迟通常也是不可接受的。可以实时检查访问的硬件组件是更实用的解决方案。本文档重点介绍 IOPMP。下图从概念上演示了将 IOPMP 集成到系统中。图1(a)显示了部署两个 IOPMP(destination-enforcement) 的系统,IOPMP 采用三个输入:RRID、transaction type(read/write)、request range(address/len);图1(B)显示了部署两个 IOPMP(source-enforcement) 的系统,在此部署中,RRID 被忽略。
  • 总线矩阵中的另一个硬件组件是 输入输出内存管理单元(IOMMU),它使用一级或多级页表将设备的虚拟地址转换为总线矩阵中的物理地址。 IOMMU 可以在可信和不可信环境中运行,通常由虚拟机管理程序或操作系统使用。它提供了出色的灵活性并减少了外部内存碎片。然而,它可能不适用于在 M-mode 下运行的安全软件,因为与典型的 Security Monitor 相比,它需要相对较大的内存和复杂的软件。此外,页表通常存储在 DRAM 中,DRAM 在芯片外部,并且可能需要外部信号保护。对于简单的系统来说,这种负担可能是无法承受的。相比之下,IOPMP 消耗的内存要少得多,并且将规则存储在芯片内。IOMMU 和 IOPMP 都有各自的应用,它们可以共存和协作。IOPMP 可供 Security Monitor 使用,以检查来自其他软件控制的设备访问,而 IOMMU 可供资源更丰富的特权软件使用。

Terminology and Concepts

  • 本文档将术语 *Security Monitor* 称为负责管理安全相关任务(包括 IOPMP programming)的软件。 SM 不限于在单个 CPU 或 hart 上操作; 相反,它可以分布在多个 CPU 上。
    Table 1. Glossary and Acronyms

    Term Description
    DC do not care
    IMP implementation-dependent
    MMIO memory mapped input/output devices
    N/A not available
    NA4 naturally aligned four-byte region, one of the address matching mode used in RISCV PMP and IOPMP
    NAPOT naturally aligned power-of-2 region, one of the address matching mode used in RISC-V PMP and IOPMP
    TOR top boundary of an arbitrary range, one of the address matching mode used in RISC-V PMP and IOPMP
    RX receiver
    TX transmitter
    WPRI/WLRL/WARL CSR Field Access:
    W=write, R=read, P=preserve, I=ignore, L=legal, A=any
    W1C write '1' clear
    W1CS write '1' clear and sticky to 0
    W1S write '1' set
    W1SS write '1' set and sticky to 1
    X(n) the n-th register in the register array X, which starts from 0
    X[n] the n-th bit of a register X or register field X
    X(n:m) the n-th to m-th registers of a register X
    X[n:m] the n-th to m-th bits of a register X or register field X

Request-Role-ID 和 Transaction
  • Request Role ID,简称 RRID,是系统定义的安全上下文的唯一标识。 它可以是具有相同权限的事务请求者或一组事务请求者。根据 IOPMP 集成的不同,事务可能会用 RRID 标记以标识请求者。用 RRID 标记请求者以及 RRID 的位数均取决于实现。如果请求者的不同通道或模式可以被授予不同的访问权限,则它们可以具有自己的 RRID。
  • Transaction,将 Bus Master 向 Bus Slave 发送一次请求的完整动作称为一条 Transaction。 它是 IOPMP 的检查对象,通过拦截 Bus Master 发送的每条 Transaction,然后利用 Transaction 内包含的请求类型、地址信息和数据位宽等信息,进行地址访问范围和访问权限的检查,只有符合 IOPMP 表项规定的 Legal Transaction 才会被转发给 Bus Slave,并继续完成后续的数据传输动作。反之,不符合表项规定的 Illegal Transaction 则会被 IOPMP 无视,或者 IOPMP 会伪造假的总线响应信号给 Bus Master,而 Bus Slave 几乎察觉不到非法事务的发生。
Source-Enforcement
  • 如果通过 IOPMP 的所有事务都是由同一事务请求者或具有相同权限的一组事务请求者发出的,则事务请求者端和上述事务可以忽略 RRID。在这种情况下,表示 IOPMP 执行源强制,简称 IOPMP-SE。
Requestor Port, Receiver Port and Control Port
  • 一个 IOPMP 有一个或多个请求端口、一个或多个接收端口和一个控制端口。接收端端口是事务进入 IOPMP 的地方,请求端端口是事务通过所有检查后离开的地方。控制接口用于对 IOPMP 进行编程。
Memory Domain
  • RRID 是事务请求者的抽象表示,它包含一个或多个被授予相同权限的事务请求者。Memory Domain(MD) 是事务目的地的抽象表示,它将一组用于特定目的的内存区域分组。 MDs 从 0 开始索引。例如,一个网络接口控制器 NIC,可能有三个 memory regions:一个 RX region,一个 TX region 和一个控制寄存器 region。将它们组合成一个 MD,如果一个处理器可以完全控制 NIC,则该处理器可以与 MD 相关联。
  • 一般来说,单个 RRID 可以与多个 Memory Domains(MDs) 相关联,而一个 MD 可以与多个 RRID 相关联。SRCMD Table 是 IOPMP 中表示 RRID 和 MDs 之间关联的基本结构之一。MDCFG Table 也是 IOPMP 中定义 MD 中一组 memory regions 的基本结构之一。每个 IOPMP Entry 定义一个单独的 memory region。
  • 与 MD 相关联的 RRID 可能不会对 MD 的所有 memory regions 具有完全的权限,因为每个 region 的权限是在相应的 IOPMP Entry 中定义的。此外,SRCMD 表的一些特定配置可以在 SRCMD Table Format 2 中定义对整个 MD 的权限。

IOPMP Entry and IOPMP Entry Array
  • IOPMP Entry Array 包含 HWCFG1.entry_num 个 IOPMP Entry。每个 Entry 从索引 0 开始,包括指定的 memory region、相应的权限以及有关错误响应和用户自定义属性的可选特性。
  • 对于索引为 i 的 Entry,ENTRY_ADDR(i), ENTRY_ADDRH(i), ENTRY_CFG(i).a 对 memory region 的编码方式与 RISC-V PMP 相同。ENTRY_ADDR(i) 和 ENTRY_ADDRH(i) 是大于 34 位的 IOPMP 编码地址。对于小于等于 34 位的地址,只使用 ENTRY_ADDR(i)。ENTRY_CFG(i).a 为地址模式,分别为 OFF、NA4、NAPOT、TOR。如 HWCFG0.tor_en = 1 表示 IOPMP 支持 TOR 地址模式。

    由于 TOR 的地址编码方案引用的是前一个表项的 memory region,而这两个表项不在同一个 memory domain 中,因此会导致意想不到的结果。如果 memory domain 的第一个表项选择 TOR,当先前的内存域发生意外变化时,该表项的 region 也会发生变化。为了防止 memory region 的意外变化,软件应该: 避免对 memory domain 的第一个入口采用TOR;或在编程 IOPMP 时,为 memory domain 中具有最大地址的最后一个条目设置一个 OFF。

  • ENTRY_CFG(i).r/w/x 表示读、写、取指令权限,为 WARL。也就是说,实现可以决定哪些位是可编程的或硬连接的,哪些位组合是不需要的。当 HWCFG0.chk_x = 1 时,IOPMP 可以区分读访问和取指令访问。
  • ENTRY_CFG(i) 还包含可选的 WARL 字段:sire, siwe, sixe, sere, sewe和sexe。这些字段用于控制每个 Entry 的错误反应,例如中断触发和总线错误响应。可选的寄存器 ENTRY_USER_CFG(i) 存储 Entry 的自定义属性,可以通过 HWCFG0.user_cfg_en 查看是否实现该寄存器。索引 ≥ HWCFG1.entry_num 的表项不可用。即:表项的寄存器没有实现。当 IOPMP 在权限检查中检索到该表项时,该表项的地址模式被视为 OFF。memory domain 是将 IOPMP entry array 划分为不同子数组的一种方法。每个子数组是一个 memory domain。每个 IOPMP entry 最多只能属于一个 memory domain,而一个 memory domain 可以有多个 IOPMP entries。
  • 当一个 RRID 与一个 memory domain 相关联时,则它也自动与属于该 memory domain 的所有 entries 相关联。
Priority and Matching Logic
  • 只读位 HWCFG0.no_w 和 HWCFG0.no_x,分别用于决定 IOPMP 是否拒绝一切写和取指 transaction。当 HWCFG0.no_w=1 时,IOPMP 总是写事务失败。当 HWCFG0.no_x=1 时取指令事务失败。错误类型为 "not hit any rule"(0x05)。
  • 当一个 transaction 到达 IOPMP 时,IOPMP 首先检查 transaction 携带的 RRID 是否合法。如果 RRID 不合法,则 transaction 不合法,错误类型为 "Unknown RRID" (0x06)。
  • IOPMP entry 支持部分优先级。索引 < HWCFG2.Prio_entry 定义值的 entry 根据它们各自的索引值进行优先级排序。具体来说,索引越低的 entry 优先级越高。这些表项称为优先级表项。相反,索引 >=prio_entry 的 entry 被平等对待,并被分配最低优先级, 这些 entry 被称为非优先级条目。prio_entry 的值与实现有关。此外, HWCFG0.prient_prog 表示 prio_entry 是否可编程。
  • 一个 entry 可作为 incoming transaction 的匹配条目(matching entry),当
    • 对于 priority entry,它的区域覆盖事务的任何(any)字节
    • 对于 non-priority entry,它的区域覆盖事务的所有(all)字节
    • 它与事务携带的 RRID 相关联
    • 它在满足前面标准的条目中拥有最高优先级
  • 匹配条目可以根据其 access type 授予事务。如果任何匹配条目允许该 access type,则该事务是合法的。每个条目可以分别允许事务的读、写和取指令的r、w和x位。如果 IOPMP 支持 SRCMD Table Format 2 或 SPS 扩展,则它可以将可选权限从 SRCMD Table 携带到相应内存域的 IOPMP 条目数组。
  • 如果匹配条目是 priority entry,则匹配条目必须匹配事务的所有字节,否则该事务是非法的,错误类型="partial hit on a priority rule"(0x04),而不管其权限如何。如果匹配了 priority entry,但没有授予事务操作权限,则该事务是非法的:
    • 对于读访问,错误类型="illegal read access"(0x01)
    • 对于写访问/原子内存操作(AMO),错误类型="illegal write access/AMO”(0x02)
    • 对于取指令,错误类型="illegal instruction fetch”(0x03)
  • 如果匹配条目是 non-priority 的且任何匹配条目都允许其 access type,则该事务是合法的。如果没有匹配条目允许,则该事务是非法的:
    • 对于读访问,错误类型="illegal read access"(0x01)
    • 对于写访问/原子内存操作(AMO),错误类型="illegal write access/AMO”(0x02)
    • 对于取指令,错误类型="illegal instruction fetch”(0x03)
  • 最后,如果不存在匹配条目,则该事务是非法的,错误类型="not hit any rule"(0x05)
Error Reactions
  • 一旦检测到非法 transaction,IOPMP 可以启动以下三个操作:
    • 触发中断以通知系统违规
    • 返回总线错误(或解码错误)或一个未被 implementation 定义的值
    • 在 IOPMP 错误记录寄存器中记录错误详细信息
  • IOPMP 可以在访问违规时触发中断。ERR_CFG 寄存器配置全局中断,而每个条目有局部字段在本地配置中断行为。ERR_CFG.ie 位作为全局中断使能配置位。每个 entry i 在寄存器 ENTRY_CFG(i)中都有三个可选的中断抑制位 sire、siwe和sixe,分别抑制由于非法读取、非法写入和非法获取指令而引起的中断触发。如果实现支持sire、siwe或sixe,则 HWCFG0.peis=1。中断挂起指示等效于错误有效指示;两者都通过 ERR_INFO.v 位进行标记。在错误类型为“非法读取访问”(0x01)、“非法写入访问/AMO”(0x02)或“非法指令获取”(0x03)的非法事务上,如果全局中断被启用(ie)并且没有被所有匹配的条目抑制(sire、siwe或sixe),则会触发中断。对于peis为0,sire、siwe和sixe应连接到0。在具有其他类型的非法事务上,IOPMP仅在ie=1时触发中断。考虑到条目i与非法事务匹配,每种类型的非法访问的中断条件可以描述如下:
    • 非法读访问(0x01):ERR_CFG.ie&&!ENTRY_CFG(i).sire
    • 非法写访问/AMO(0x02):ERR_CFG.ie&&!ENTRY_CFG(i).siwe
    • 非法指令获取(0x03):ERR_CFG.ie&&!ENTRY_CFG(i).sixe
  • 对于 \(i_0, i_1,…,i_N\) 索引的多个匹配的非优先级条目的情况,条件是:
    • 非法读访问(0x01):ENTRY_CFG && (!ENTRY_CFG(i0).sire||!ENTRY_CFG(i1).sire || … ||!ENTRY_CFG(iN).sire)
    • 非法写访问/AMO(0x02):ERR_CFG.ie && (!ENTRY_CFG(i0).siwe||!ENTRY_CFG(i1).siwe || … ||!ENTRY_CFG(iN).siwe)
    • 非法指令获取(0x03):ERR_CFG.ie && (!ENTRY_CFG(i0)
  • 默认情况下,违反 IOPMP 规则的事务将产生总线错误。此外,IOPMP 违规的总线错误响应行为可以通过 ERR_CFG 寄存器全局配置,也可以通过每个 ENTRY_CFG 寄存器本地配置。IOPMP 将向总线发出违规存在的信号,但如果在违规时实现ERR_CFG.rs 并设置为 1,则会抑制总线错误。用户定义的抑制行为允许例如0x0的读取响应。非法写入或取指令时的总线错误响应类似。
  • 以同样的方式,总线错误响应行为可以全局地和单独地为每个 IOPMP entry 设置。 ERR_CFG.rs 全局抑制在非法访问时返回总线错误。当禁用全局抑制时,可以分别使用sere、sewe和sexe对非法读取、非法写入和非法指令获取进行单独的每个条目抑制。如果 IOPMP 实现sere、sewe和sexe,则 HWCFG0.pees=1。当事务非法且总线错误未被抑制时,IOPMP将响应总线错误。如果事务仅违反条目权限且 pees为1,则 IOPMP 的总线错误响应行为由条目中的全局总线错误响应抑制配置位rs和抑制位(sere、sewe或sexe)控制。另一方面,如果事务不仅违反条目的权限,IOPMP的总线错误响应行为仅由总线错误响应抑制配置位rs控制。权限包括条目中的权限位(ENTRY_CFG(i).r/w/x)和来自SRCMD表(详见SRCMD表格式)的相应条目的权限位。考虑到条目i匹配非法事务,每个存取类型的总线错误响应条件可以描述如下:
    • 非法读访问(0x01):!ERR_CFG.rs&&!ENTRY_CFG(i).sere
    • 非法写访问/AMO(0x02):!ERR_CFG.rs&&!ENTRY_CFG(i).sewe
    • 非法指令获取(0x03):!ERR_CFG.rs&&!ENTRY_CFG(i).sexe
  • 对于 \(i_0,i_1,…,i_N\) 索引多个匹配的非优先级条目的情况,条件是:
    • 非法读取访问(0x01):!ERR_CFG.rs && (!ENTRY_CFG(i0).sere||!ENTRY_CFG(i1).sere || … ||!ENTRY_CFG(iN).sere)
    • 非法写入访问/AMO(0x02):!ERR_CFG.rs && (!ENTRY_CFG(i0).sewe||!ENTRY_CFG(i1).sewe || … ||!ENTRY_CFG(iN).sewe)
    • 非法指令获取(0x03):!ERR_CFG.rs && (!ENTRY_CFG(i0).sexe||!ENTRY_CFG(i1).sexe || … ||!ENTRY_CFG(iN).sexe)
  • 错误捕获记录维护检测到的第一个非法访问的细节,除了以下条件:⚫没有触发有关访问的中断,⚫没有返回总线错误。
  • 错误捕获仅在没有挂起错误时发生,即 ERR_INFO.v='0'。如果存在挂起错误(v='1'),则不会更新记录,即使检测到新的非法访问。换句话说,v 表示捕获记录的内容是否有效,并且应该有意清除,以便捕获后续的非法访问。可以将 1 写入该位以清除它。错误捕获记录是可选的。如果没有实现,v 应该连接到零。可以实现错误捕获记录,但不实现错误条目索引记录(ERR_REQID.eid)。在这种情况下,eid 应该连接到 0xffff。对于匹配多个非优先级条目的非法事务,如果触发中断或返回总线错误响应,ERR_REQID.eid 存储其中任何一个的索引。
  • 下表显示了如果实现了每个 Entry control bits(HWCFG0.peis=1 或 HWCFG0.pees=1),则每个错误类型的控制类型:
    Table 2. Error types and corresponding control bits
    Error Type Control Bits Description
    0x00 N/A No error
    0x01 Global¹² and local² Illegal read access
    0x02 Global and local Illegal write access/AMO
    0x03 Global and local Illegal instruction fetch
    0x04 Global Partial hit on a priority rule
    0x05 Global Not hit any rule:
    1.No entry matches all bytes of a transaction
    2.Receives a write access transaction when HWCFGO.no_w=1
    3.Receives an instruction fetch transaction when HWCFGO.no_x=1
    0x06 Global Unknown RRID
    0x07 Global Error due to a stalled transaction
    0x08 ~ 0x0D N/A Reserved for future
    0x0E ~ 0x0F Implementation-dependent User-defined error
    • Notes:
      1. Global: Bit ie or is in ERR_cfg. Depends on reaction type (interrupt or bus error response)
      2. Local: Bits sire siwe sixe sere sewe sexe in ENTRY_CFG(i). Depends on:
        • Reaction type (interrupt or bus error response)
        • Transaction type of the illegal transaction (read/write/instruction fetch)

IOPMP Tables and Configuration Protection

spec 提供多种 IOPMP 配置以适应不同的平台。用户可以选择最适合其设计要求的一种,例如面积、功耗、延迟、吞吐量、灵活性和可移植性。

SRCMD Table and MDCFG Table
  • 当 IOPMP 接收到带有 RRID=s 的 transaction 时,IOPMP 首先查找 SRCMD Table,找出与请求者 s 相关联的所有 memory domains 以及相应的 permissions。一个 IOPMP 实例最多可以支持 65,535 个请求者,请求者的实际数量可以 implementation-defined,并在 HWCFG1 寄存器中指示。SRCMD Table 定义了从 transaction requestor 到其关联的 memory domains 的映射以及相应的权限。映射可以是只读字段 HWCFG0.srcmd_fmt 中指定的三种格式之一。此外,SPS 扩展可以限制与 RRID 相关联的权限(附录 A3 中描述)。
  • 当检索到关联的 memory domains 时,IOPMP 会找到 entries。MDCFG 定义每个 entry 属于哪个 memory domain。一个 entry 最多只能属于一个 memory domain,但是一个 memory domain 可以拥有零个或多个 entry。MDCFG 可以是只读字段 HWCFG0.mdcfg_fmt 中指定的三种格式之一。检索到所有相关条目后,IOPMP 会根据它们检查事务。
SRCMD Table Formats
  • SRCMD Table Format 0 使用位图(bit map)将每个 RRID 与 memory domains 相关联。 Format 1 是一个简化版本,它使用 RRID 作为 memory domain 的索引。也就是说,RRIDs 和 MDs index 是一一映射。 Format 2 中,每个RRID 隐式关联所有实现的(all implemented) memory domains,使用位图(bit map) 根据 RRID 输出每个 memory domain 的 permission。
    • SRCMD Table Format 0

      • 在格式 0 中,SRCMD Table 是一个以 RRID 为索引的数组,数组中的每个 entry 都是一组寄存器。对于 RRID=s ,必须实现寄存器 SRCMD_EN(s) 。31位字段 SRCMD_EN(s).md 中的每一位表示一个 memory domain。SRCMD_EN(s).md 中的位 j 表示 MD j 是否与 RRID s 相关联。如果 MD 的数量超过 31 个,则寄存器 SRCMD_ENH 及其 32 位字段 SRCMD_ENH.mdh 可以实现为最多支持 63 个 memory domain。SRCMD_ENH.mdh 中的位 j 表示 MD (j+31) 是否与 RRID s 相关联。对于未实现的 memory domain,相应的位应该是硬连线只读零。每个 SRCMD_EN 都有 1 位字段 l 用于 SRCMD Table protection。对于超过 63 个 memory domain 的系统,请参阅附录A2 耗尽内存域。如果支持 SPS 扩展,则 entry 具有额外的寄存器,这些寄存器在附录 A3 辅助权限设置中描述。
    • SRCMD Table Format 1
      • Format 1 的位图(bitmap)实现专门为最小到没有共享区域的场景量身定制。在这种格式中,每个 RRID 都与单个 MD 精确关联,无需 SRCMD Table 查找。每个 RRID i 都与 MD i 直接关联,从而在面积、延迟和系统复杂性方面具有优势。但是,当场景需要共享区域时,重复的条目设置代表了一个潜在的缺点。在该格式中,不支持 SPS 扩展。
    • SRCMD Table Format 2

      • 这种格式的 SRCMD Table 是一个以 MD index 为索引的数组。对于 MD m,SRCMD_PERM(m)和SRCMD_PERMH(m)在与SRCMD_EN(s)和SRCMD_ENH(s)相同的地址实现。也就是说,格式中没有 SRCMD_EN(H),每个 RRID 隐式关联所有实现的 MDs。也就是说,该格式根据 RRID 输出每个 MD 的权限。因此,这种格式不支持 SPS 扩展。
      • SRCMD_PERM(m).r[s] 表示 RRID=s 的读权限和取指令权限属于 MD m。SRCMD_PERM(m).w[s] 表示 RRID=s 的写权限属于 MD m。SRCMD_PERM(m).r 和 SRCMD_PERM(m).w 相邻。即 SRCMD_PERM(m).r[s] 和SRCMD_PERM(m).w[s] 分别位于位(s2)和(s2+1)。对于索引>15 的 RRID,使用 SRCMD_PERMH(m)。IOPMP 查看 SRCMD_PERM(H) 和 ENTRY_CFG.r/w/x 中的权限。只要其中一个授予正在检查的事务,就是合法的。如果只想使用SRCMD_PERM(H),所有 ENTRY_CFG.r/w/x 都可以连接到零。
MDCFG Table Formats

MDCFG Table 用于将 MD 映射到它自己的 entry。它可以被视为 IOPMP 中所有 entry 的分区。它的三种格式旨在适应不同的设计目标。

  • MDCFG Table Format 0
    • 该格式中,每个 MD m 都有一个寄存器 MDCFG(m)。当 m>0 时,字段 MDCFG(m).t 表示上限(不包括在内),字段 MDCFG(m-1).t 表示下限(包括在内)。它们构成了属于 MD m 的 IOPMP entry 的索引范围。也就是说,
      • 如果 MDCFG(m-1).t≤j<MDCFG(m).t 其中 m>0,则索引为 j 的 entry 属于 MD m
      • 如果 j<MDCFG(0).t,则索引为j的 entry 属于 MD 0
    • 程序员应该在 MDCFG Table 中保持正确的设置,其中对于任何合法的 MD m,MDCFG(m+1).t 应该 >= MDCFG(m).t。否则,MDCFG Tabel 有一个不正确的设置,即同时存在两个合法的 MD m 和 MD k,对于k<m,有 MDCFG(k).t>MDCFG(m).t。在这种情况下,我们表示 MD m 有一个不正确的设置。当 MDCFG Table 有任何不正确的设置时,IOPMP Entry 的归属 implementation-dependent,但应满足以下条件:
      • 一个 entry 必须最多属于一个 memory domain
      • 低索引 memory domain 中 entry 的索引应低于高索引 memory domain 中 entry 的索引
  • MDCFG Table Format 1
    • 该格式中没有物理 MDCFG Table。每个 memory domain 恰好有 k 个 entries,其中 k 是 implementation-dependent 且 non-programmable。只读字段 HWCFG0.md_entry_num 的值是 k-1。寄存器 MDCFGLCK 不应实现。

      (HWCFG0.md_entry_num+1)*HWCFG0.md_num 可以大于 HWCFG1.num_entry。索引 ≥ HWCFG1.num_entry 的任何 entry 的行为在 IOPMP Entry and IOPMP Entry Array 上进行了描述。

    • 对于 k=1(HWCFG0.md_entry_num=0) 的特定情况,每个 memory domain 恰好有一个 entry。使用这样的 IOPMP 时可以跳过 memory domain 的概念。
  • MDCFG Table Format 2
    • 此格式基于 Format 1,但 HWCFG0.md_entry_num 是可编程的。当 HWCFG0 被锁定时,md_entry_num 也被锁定,即 HWCFG0.enable=1。
IOPMP Models

为了便于讨论,一些使用频率较高的 HWCFG0 组合给出如下别名: k = (md_entry_num+1)

Model SRCMD Table Format MDCFG Table Format Example
full model 0 0
rapid-k model 0 1
dynamic-k model 0 2
isolation model 1 0
compact-k model 1 1
2 1
Configuration Protection

术语 "lock" 是指在 IOPMP 复位之前使一个或多个字段或寄存器不可编程的硬件功能。此功能用于在安全软件受损的情况下保持基本配置的完整性。在锁位可编程的情况下,它预计将被重置为“0”,并且是 W1SS 字段。

  • SRCMD Table Protection
    • 在格式0中,每个 SRCMD_EN(s) 寄存器在第0位有一个l位,用于锁定寄存器 SRCMD_EN(s),SRCMD_ENH(s)。MDLCK.md 和 MDLCKH.mdh 两个字段共63位。每个位用于锁定 SRCMD Table 中具有 MD 的关联位。在格式0中,对于 MD 0≤m≤30,MDLCK.md[m] 锁定所有现有 RRID s 的 SRCMD(s).md[m]。在格式1中,没有 MDLCK。在格式2中,MDLCK.md[m] 锁定 SRCMD_PERM(m) 和 SRCMD_PERMH(m)。对于 MD 31≤m≤62,应该使用 MDLCKH.mdh 锁定相应的位。位 MDLCK.l 是1的粘性,指示 MDLCK 和 MDLCKH 是否被锁定。MDLCK.md 是可选的,如果未实现,MDLCK.md 应该连接到 0,MDLCK.l 应该连接到 1。MDLCKH是可选的。
  • MDCFG Table Protection
    • 寄存器 MDCFGLCK 设计用于部分或完全锁定格式0的 MDCFG 表。MDCFGLCK 由两个字段组成:MDCFGLCK.l 和 MDCFGLCK.f。如果 m<MDCFGLCK.f,则锁定 MDCFG(m)。MDCFGLCK.f仅增量。任何较小的值都不能写入其中。MDCFGLCK.l 位用于锁定 MDCFGLCK。格式1和2不实现寄存器 MDCFGLCK。
  • Entry Protection
    • IOPMP 条目保护也与属于同一内存域的其他 IOPMP 条目有关。对于 MD,锁定的条目应该放在更高的优先级中。否则,当 SM 受到威胁,一个较高优先级的解锁条目可能会覆盖所有其他较低优先级的锁定或非锁定条目。定义了一个寄存器 ENTRYLCK 来指示不可编程条目的数量。ENTRYLCK 寄存器有两个字段:ENTRYLCK.l 和 ENTRYLCK.f。任何索引为 i≤ENTRYLCK.f 的 IOPMP 条目都是不可编程的。ENTRYLCK.f 是增量的。任何较小的值都不能写入其中。此外,ENTRYLCK.l 是ENTRYLCK.f 及其本身的锁。如果 ENTRYLCK 是硬连线的,ENTRYLCK.l 应该连接到1。
Prelocked Configurations
  • spec 中的预锁定配置意味着字段或寄存器在复位后立即被锁定。实际上,它们可以是硬连线的和/或由只读存储器实现的。本章中的每个锁定机制都可以选择预锁定。MDCFGLCK.f 的非零复位值反映了预锁定的 MDCFG(j),其中 j<MDCFGLCK.f。ENTRYLCK.f 的非零复位值反映了现有的预锁定条目。SRCMD_EN(H)可以完全或部分基于 MDLCK.md 和 SRCMD_EN.l 的预置位。类似地,SRCMD_PERM(H) 也可以完全或部分基于 MDLCK.md 的预置位。其余的锁定位也可以预设。它们是 ERR_CFG. l、MDLCK.l、MDCFGLCK.l和ENTRYLCK.l。

Programming IOPMPs

有时,在系统启动时配置所有 IOPMP 设置可能很困难,甚至不可能,尤其是在 I/O Agents 处于活动状态或连接到系统之前。因此,当设备启用、禁用、添加、删除或设备的可访问区域发生变化时,有必要在运行时动态更新 IOPMP 设置。更新时,重要的是避免在不完整的设置中检查 transaction。 然而,更新 IOPMP 设置通常涉及一系列控制访问,如果在更新期间发生 transaction 检查,则可能会潜在地创建漏洞。对于安全软件来说,保证所有 related initiators 都没有正在进行的 transaction 可能是一个沉重的负担。本章描述了一种更新 IOPMP 设置的可选方法,以避免在不完整的设置中检查 transaction 并增加安全软件的负担。

Atomicity Requirement
  • 原子性要求是,在更新 IOPMP 时,必须在 进行任何更新前或完成所有更新后 检查来自 receiver ports 的所有 transactions。本质上,应避免在 partial setting 中检查事务。 以下部分将描述帮助安全软件满足此要求的机制。
Programming Steps
  • 安全软件满足原子性要求的一般方法有三个主要步骤,概念性描述如下:
    • step1:暂停(stall) 后续对 IOPMP 更新可能影响的相关 transaction
    • step2:更新(update) IOPMP 的设置
    • step3:恢复(resume) step1 中暂停的 transaction
  • 停止事务意味着 IOPMP 停止检查其权限(permission),直到它被恢复。与此同时,事务应该等待。对于 step1,可能需要验证是否发生了暂停,因为某些实现无法立即从接收器端口停止所需的事务。

在某些情况下,只要在 step2 中没有执行事务检查,就可以跳过 step1 和 step3。写入 RRID 的 SRCMD 就是一个例子,因为它涉及一次写入。
停止事务可以通过但不限于以下方式实现:

  • IOPMP 将 transaction 入队来停止检查
  • 发送 retry 消息要求事务发起者 retry transaction
  • 先将 transaction 入队,队列满时,进行 retry
Stall Transactions
  • 对于 step1,可以推迟所有事务,直到所有更新完成。但是,这可能会导致不相关的事务遇到不必要的延迟。对于需要低延迟的设备来说,这可能是不可容忍的,例如定期从视频中检索帧的显示控制器缓冲区。本节描述 仅暂停特定事务的机制,以防止上述场景并确保原子性要求。 下面提到的所有功能都是可选的。
  • 在 step2 中,transaction 是否应该 stall 的决定不能参考当前处于更新中的设置。因此,该决定的唯一可靠信息是 transaction 携带的 RRID。为了简化以下描述,我们使用 rrid_stall 来表示一个抽象 bit 数组,其中 rrid_stall[s]=1 表示带有 RRID=s 的 transaction 必须暂停。IOPMP 根据其对应的 rrid_stall 来暂停事务。请注意,实际上它可能不是一个实际的位数组,只是为了更容易表达,并且不能被软件直接访问。
  • 寄存器 MDSTALL 和 MDSTALLH 控制 rrid_stall。MDSTALL.md 和 MDSTALLH.mdh 用于选择 MDs。stall_by_md 表示 MDSTALL.mdh 和 MDSTALL.md 的串联。即 stall_by_md[30:0]=MDSTALL.md[30:0],stall_by_md[62:31]=MDSTALLH.mdh[31:0]。当 stall_by_md[m]=1 时选择一个 MD m。MDSTALL.exempt 控制选择的极性。IOPMP 仅在写入 MDSTALL.exempt 时 rrid_stall 更新。当 MDSTALL.exempt=0 时,如果 RRID s 与选定的 MD m 相关联(stall_by_md[m]=1),则设置 rrid_stall[s]。SRCMD Table 定义 RRID s 和 MD m 的关联。相反,当 MDSTALL.exempt=1 时,如果 RRID s 不与任何选定的 MD 关联,则必须设置 rrid_stall[s]。这种关系可以表述如下: rrid_stall[s] ⇐ MDSTALL.exempt ^ ( Reduction_OR(SRCMD(s).md & stall_by_md) ) 其中:^是按位逻辑异或运算符,& 是按位逻辑与运算符,Reduction_OR() 是对所有输入值应用按位逻辑或的函数。
  • 至于 SRCMD Table Format2,上述等式中的 SRCMD(s).md[m] 是:"0"表示所有未实现的 MD m,"1"表示已实现的MD m,因为每个 RRID 都关联了所有已实现的 MD。对于任何未实现的 MD,MDSTALL.md 或 MDSTALLH.mdh 中的相应位应=0。rrid_stall 应仅在写入 MDSTALL.exempt 时更新,即写入 MDSTALL/MDSTALLH 时,唯一的操作是保存该值。

虽然 rrid_stall 是从 SRCMD Table 派生出来的,但只有在写入 MDSTALL.exempt 时才应该更新它。我们不能在暂停 transaction 时使用该表,因为当 IOPMP 决定是否应该停止事务时,表更新可能仍在进行中。写 MDSTALL 就像在更新任何设置之前捕获表的快照一样。rrid_stall 在任何更新之前反映 SRCMD Table。
在写 MDSTALL 时,spec 只定义了 RRID=s 的 transaction 必须为所有 rrid_stall[s]=1 停止。它不要求其余 transaction 停止或不停止。它只要求在写入 MDSTALL=0 时恢复所有 transaction。

Cherry Pick
Faulting stalled transactions
Resume Stall
The Order to Stall
Implementation Options

Registers


RISC-V IOPMP Implementation

Manufacturer SoC System Integration IOPMP Design/Architecture Availability
Andes Rapid-k Model N/A
SiFive WorldGuard N/A
StarFive Rapid-1 Model N/A
SpaceMit N/A
XuanTie N/A
Lattice Semiconductor AXI4 interface bridge
AXI-Lite interface memory-mapped registers
Compact-K model-based controller
Lightweight interrupt merge controller module
Up to four IOPMP entries with TOR support
IP
zero-day-labs https://github.com/zero-day-labs/riscv-iopmp
ETH Zürich - Protego https://github.com/pulp-platform/axi-io-pmp

Reference

[1] https://lf-rise.atlassian.net/wiki/spaces/HOME/pages/8588693/SE_01_004+-+QEMU+IOPMP+support
[2] https://zhuanlan.zhihu.com/p/601083468
[3] https://liguangzhang.github.io/2023/08/18/hxd new/安全/riscv 硬件安全机制/
[4] https://forum.spacemit.com/u/zhengwenbin/activity
[5] J.H.Ng, C.H.Ang and H.C.Law, "A Realization of IO Physical Memory Protection for RISC-V Systems," 2022 IEEE 15th International Symposium on Embedded Multicore/Many-core Systems-on-Chip (MCSoC), Penang,Malaysia, 2022, pp. 375-380, doi: 10.1109/MCSoC57363.2022.00066. keywords: {Multicore processing;Scalability;Memory management;Random access memory;Malware;Hardware;Computer security;IOPMP;PMP;memory protection}

posted @ 2025-05-15 18:18  Avalon-Nausica  阅读(337)  评论(0)    收藏  举报