Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 8: GICv4.1 虚拟中断支持

本章描述 GICv4.1 虚拟中断处理和优先级排序的基本方面:

  • 关于 GICv4.1 虚拟中断支持

  • CPU interface 的变更

  • ITS 命令

  • vPEID 宽度

  • 门铃

  • vPE 驻留和定位数据结构

  • 基于寄存器的 vLPI 失效

  • vSGI 的直接注入

8.1 关于 GICv4.1 虚拟中断支持

GICv4.1 扩展了对 SGI 虚拟中断直接注入的支持。它通过以下变更使直接注入对软件来说更简单、更高效:

  • 跟踪所有活动 vPE 的待处理和配置表的结构。

  • 虚拟中断配置的基于寄存器的失效选项。

  • 简化不再使用时分配给 GIC 的内存回收的修改。

GICv4.1 中传统模式支持已过时,ARE 位为 RES1。

8.2 CPU interface 的变更

GICv4.1 引入了 CPU interface 的变更。

ID_AA64PFR0_EL1.GIC==b0011 表示支持 GICv4.1。

将 vSGI 传递给 ID_AA64PFR0_EL1.GIC==b0001 的 PE 是 CONSTRAINED UNPREDICTABLE:

  • 中断被忽略。

  • 中断被传递。

ICH_HCR_EL2.vSGIEOICount 控制 vSGI 的停用是否增加 ICH_HCR_EL2.EOIcount。

8.3 ITS 命令

在任何 ITS 命令中指定超出实现范围的 vPEID 是 CONSTRAINED UNPREDICTABLE,有两种选择:

  • 生成命令错误。

  • ITS 忽略未实现的 vPEID 位。

在大多数命令中,指定超出配置 vPEID 大小的 vPEID 会生成命令错误。

8.4 vPEID 宽度

GICv4.1 允许 vPEID 宽度在 1 到 16 位之间。GICD_TYPER2 中的 VIL 和 VID 字段一起报告实现的 vPEID 宽度。

软件在分配 Redistributor vPE 配置表和 ITS vPE 表时可以配置较小的 vPEID 宽度。

8.5 门铃

GICv4.0 支持的 门铃 机制在 GICv4.1 中被称为 个人门铃。门铃中断针对 vPE 当前映射到的 Redistributor,基于 vPE 的先前 VMAPP 或 VMOVP 命令。

8.5.1 个人门铃

GICv4.1 中对个人门铃的支持是 IMPLEMENTATION DEFINED,由 GITS_TYPER.nID 报告。连接到单个 GIC 的所有 ITS 具有相同的 GITS_TYPER.nID 值。

当 GITS_TYPER.nID==1 时,VMAPTI 和 VMAPI 中的 Dbell_pINTID 字段被视为 1023。

当来自 ITS 的 vLPI 变为待处理时,如果满足以下所有条件,则生成个人门铃中断:

  • GITS_TYPER.nID==0

  • 目标 vPE 未调度。

  • ITS 为 EventID/DeviceID 组合的映射提供了个人门铃 pINTID。

虚拟 SGI 不能触发个人门铃,触发个人门铃的虚拟中断是否也触发默认门铃是 IMPLEMENTATION DEFINED。

8.5.2 默认门铃

GICv4.1 为每个 vPEID 提供新的默认门铃,作为 VMAPP 命令的一部分指定。

当 EventID 或 DeviceID 映射到虚拟中断时,可以在 VMAPI 或 VMAPTI 命令中指定门铃 INTID。如果未指定门铃,则使用 vPE 的默认门铃(如果已指定)。

当满足以下所有条件时,生成默认门铃中断:

  • 单独启用的虚拟中断变为待处理,或虚拟中断在待处理时变为启用。

    • GIC 是否在 vPE 上次调度时考虑来自 GICR_VPENDBASER 的组启用是 IMPLEMENTATION DEFINED。对于从未调度过的 vPE,组启用被视为 1。
  • vPE 未调度。

  • 当该 vPE 上次变为非调度时,GICR_VPENDBASER.doorbell 被写为 0b1

    • 创建 vPE 时,它被视为变为非调度且 GICR_VPENDBASER.doorbell 被写为 0b1。

注意 在某些情况下,GICR_VPENDBASER.doorbell 即使写为 0b1 也表现为 0b0,请参见寄存器描述。

  • ITS 为 vPEID 的映射提供了默认门铃。

  • 自 vPE 上次变为非驻留以来,此 vPE 的默认门铃尚未被确认。

如果 vPE 的默认门铃待处理,但 vPE 没有单独启用和待处理的中断,则默认门铃的待处理状态是否被清除是 IMPLEMENTATION DEFINED。

如果虚拟中断被单独禁用或属于禁用的组,则不生成默认门铃中断。这与 GICv4.0 不同,在 GICv4.0 中门铃生成独立于 vLPI 的启用状态。

GICR_VPENDBASER.doorbell 允许软件向 IRI 指示是否为 vPE 生成默认门铃。它不影响个人门铃的生成。 在变为非调度和变为调度之间,vPE 的默认门铃最多设置为待处理一次。如果满足除虚拟中断到达之外的所有其他条件,vPE 的默认门铃可能会推测性地设置为待处理。这不会覆盖默认门铃在驻留之间最多仅设置为待处理一次的要求。将 vPE 设置为调度会清除其默认门铃的待处理状态。

8.6 vPE 驻留和定位数据结构

vPE 配置表存储每个 vPE LPI 配置和待处理表的位置。每个 Redistributor 上的 GICR_VPROPBASER 寄存器指向 vPE 配置表,vPEID 索引该表。通过将其 vPEID 写入 GICR_VPENDBASER 来调度 vPE,从 vPE 配置表中选择一个条目。系统可以包含多个 vPE 配置表副本。此结构如图 8-1 所示。

图像文本

vLPI
Configuration
table
vPE Configuration table
vLPI
Valid entry Pending
Redistributor Invalid entry table
Invalid entry
GICR_VPROPBASER Valid entry
vLPI
Configuration
table
vLPI
Pending
table
vPEID

**图 8-1 Redistributor 和 vPE 配置表**

8.6.1 vPE 配置表

vPE 配置表的格式是 IMPLEMENTATION DEFINED。GICR_VPROPBASER.Z 指示表是否包含全零。如果 vPE 配置表在初始分配时不包含全零,则行为是 UNPREDICTABLE。当 GICR_VPROPBASER.Z==0 时,内存内容不为零并包含有效数据。

GICR_VPROPBASER.Valid 指示 vPE 配置表是否有效。如果当任何指向该表的 Redistributor 具有 GICR_VPROPBASER.Valid==1 时,GIC 以外的任何代理写入 vPE 配置表,则行为是 UNPREDICTABLE。当没有具有 GICR_VPROPBASER.Valid==1 的 Redistributor 指向 vPE 配置表时,任何 Redistributor 中都没有该 vPE 配置表的缓存副本。

当 GICR_VPROPBASER.Valid 从 1 写入 0 时,寄存器中的所有其他读/写字段变为 UNKNOWN。在将 GICR_VPROPBASER.Valid 从 1 写入 0 后,当 GICR_CTLR.RWP==0 时,该 Redistributor 不会再访问 vPE 配置表。

当同一 CommonLPIAff 组中的另一个 Redistributor 由于先前将 GICR_VPROPBASER.Valid 从 1 写入 0 而具有 GICR_CTLR.RWP==1 时,可以将 GICR_VPROPBASER.Valid 从 1 写入 0。如果当同一 CommonLPIAff 组中的任何 Redistributor 由于先前将 Valid 从 1 写入 0 而具有 GICR_CTLR.RWP==1 时,将 GICR_VPROPBASER.Valid 从 0 写入 1,结果是 UNPREDICTABLE。

当 GICR_CTLR.RWP==1 是由于在该 Redistributor 上先前将 GICR_VPROPBASER.Valid 从 1 写入 0 时,写入 GICR_VPROPBASER 会导致 UNPREDICTABLE 行为。

注意 vPE 配置表作为通过 ITS 发出的 VMAPP 命令的副作用而填充。它不打算由软件直接访问。

8.6.2 驻留和映射限制

如果目标 Redistributor 具有 GICR_VPROPBASER.Valid==0,则 V==1 的 VMAPP 命令具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 映射被丢弃。

  • 使用来自具有 GICR_VPROPBASER.Valid==1 的 UNKNOWN Redistributor 的 vPE 配置表进行映射。

如果目标 Redistributor 具有 GICR_VPROPBASER.Valid==0,则 VMOVP 命令具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 映射未移动。

  • 映射被移动。

  • 映射被丢弃。

如果指定的 vPEID 超出 vPE 配置表的范围,则 V==1 的 VMAPP 命令具有以下 CONSTRAINED UNPREDICTABLE 效果之一,除非命令导致命令错误:

  • 命令被忽略。

  • vPEID 被视为 UNKNOWN 合法值。

如果指定的 vPEID 超出 vPE 配置表的范围,则 VMOVP 命令具有以下 CONSTRAINED UNPREDICTABLE 效果之一,除非命令导致命令错误:

  • 命令被忽略。

  • vPEID 被视为 UNKNOWN 合法值。

如果有任何针对 Redistributor 的 ITS vPEID 映射,则将 GICR_VPROPBASER.Valid 从 1 清除为 0 的效果是 UNPREDICTABLE。

注意 Arm 强烈建议在清除 GICR_VPROPBASER.Valid 之前从 Redistributor 移除所有 vPE 映射。

如果 vPEID 同时在多个 Redistributor 上调度,则效果是 UNPREDICTABLE。

如果在该 vPEID 没有当前 ITS 映射时在任何 Redistributor 上调度 vPEID,则发生以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • GICR_VPENDBASER.vPEID 被视为具有 UNKNOWN 有效值,除了直接读取寄存器的所有目的。

  • GICR_VPENDBASER.Valid 被视为设置为 0,除了直接读取寄存器的所有目的。

  • vPEID 被视为使用 UNKNOWN 配置进行映射。

vPEID 可以在其在 ITS 中映射到的 Redistributor 上调度,或在同一 CommonLPIAff 组内的任何其他 Redistributor 上调度。在不同 CommonLPIAff 组的 Redistributor 上调度 vPEID 具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 待处理中断未传递。

  • 传递非待处理的中断。

  • 中断可能使用错误的配置。

  • 门铃中断的保证可能不被遵守。

如果在为 vPEID 发出 VMOVP 时该 vPEID 在任何 Redistributor 上调度,结果是 UNPREDICTABLE。

8.7 基于寄存器的 vLPI 失效

可以使用 GICR_INVLPIR 寄存器使特定 LPI 的缓存配置数据失效,或使用 GICR_INVALLR 寄存器使所有 LPI 失效,如下所示:

  • 写入 GICR_INVLPIR.V == 0 或 GICR_INVALLR.V == 0 在物理 INTID 空间上执行失效。

  • 写入 GICR_INVLPIR.V == 1 或 GICR_INVALLR.V == 1 在由 GICR_INVLPIR.vPEID 或 GICR_INVALLR.vPEID 字段分别标识的虚拟 INTID 空间上执行失效。

当写入 GICR_INVLPIR.V == 1 时,当发生以下任何情况时,失效操作无效果:

  • GICR_INVLPIR.INTID 字段超出该 vPE 支持的 LPI 范围。

  • GICR_INVLPIR.INTID 字段不是 LPI。

为未映射到该 Redistributor 或同一 CommonLPIAff 组内另一个 Redistributor 的 vPEID 发出基于寄存器的失效操作具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 操作被忽略。

  • 失效完成,影响 UNKNOWN 的 Redistributor 子集。

  • 失效完成,影响所有 Redistributor。

当写入 GICR_INVLPIR 或 GICR_INVALLR 时,GICR_SYNCR.Busy 跟踪在同一 Redistributor 上发出的失效:

  • GICR_SYNCR.Busy == 1 直到失效完成。

  • 当 GICR_SYNCR.Busy == 0 时,失效完成且失效效果在所有 Redistributor 上可见,除非另有规定。

当 GICR_SYNCR.Busy==1 时写入 GICR_INVLPIR 或 GICR_INVALLR 具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 写入被忽略。

  • 执行写入指定的失效。

基于寄存器的失效效果仅保证在 GICR_SYNCR 记录其完成后对 ITS 命令可见。当受影响的中断有未完成的基于寄存器的失效时发出 ITS 命令具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 失效效果在 ITS 命令之前应用。

  • 失效被忽略。

当受中断影响的未完成 ITS 命令存在时为中断发出基于寄存器的失效具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 失效效果在 ITS 命令之前应用。

  • 失效效果在 ITS 命令之后应用。

  • 失效被忽略。

GICR_INVLPIR、GICR_INVALLR 和 GICR_SYNCR 寄存器在 GICv4.1 中是强制性的。

8.8 vSGI 的直接注入

引入了新机制允许通过 ITS 直接注入 SGI。此机制仍需要在发送 PE 上对 hypervisor 进行陷阱,但消除了在接收 PE 上对 hypervisor 进行陷阱的需要。这些控制有限制:

  • ITS 控制必须仅在具有该 vPEID 映射的 ITS 上使用。

    • 当多个 ITS 具有 vPEID 的映射时,可以使用任何具有映射的 ITS。
  • Redistributor 控制必须仅在当前目标 Redistributor 上或同一 CommonLPIAff 组内的 Redistributor 上使用。vPEID 不需要当前调度,只需映射。

    • 当多个 ITS 具有 vPEID 的映射时,可以使用任何具有映射的 ITS。

不遵循这些指导原则可能导致 UNPREDICTABLE 行为。

没有控制来查询 vSGI 的当前配置。软件必须保留自己的 vSGI 当前配置副本以模拟 GICR_IxxxR0 SGI 配置字段的读取。通过直接注入接收的 vSGI 没有活动状态。

8.8.1 生成 vSGI

当 GITS_CTLR.Enabled==1 且 GITS_CTLR.Quiescent==0 时,对 GITS_SGIR 的写入会导致使用写入中的 vPEID 和 vINTID 生成虚拟中断。如果 vPEID 未在任何 ITS 上映射,则写入被静默丢弃。如果 vPEID 未在此 ITS 上映射但在不同的 ITS 上映射,则中断是传递还是丢弃是 CONSTRAINED UNPREDICTABLE。虚拟 SGI 没有优先级移位。

8.8.2 存储 vSGI 状态和配置

虚拟 LPI 待处理表中 IMPLEMENTATION DEFINED 区域的最后 128 位被重新定义用于存储 SGI 配置和状态。此空间的格式为:

表 8-1 虚拟 LPI 待处理表

| 31 | 24 23 | 16 | 15 | 8 7 | 0 | 从待处理表 开始的偏移 | |—|— Enable RES0 |—|—|— Pending Group |—|— +0x3F0 +0x3F4 | | PRI_7 | PRI_6 PRI_5 | PRI_4 | PRI_3 | PRI_2 PRI_1 | PRI_0 | +0x3F8 | | PRI_15 | PRI_14 PRI_13 | PRI_12 | PRI_11 | PRI_10 PRI_9 | PRI_8 | +0x3FC |

  • Pending[n]:vSGI n 的待处理状态:

    • 0 - 非待处理。

    • 1 - 待处理。

  • Enable[n]:vSGI n 的启用状态:

    • 0 - 禁用。

    • 1 - 启用。

  • Group[n]:vSGI n 的组:

    • Group 0。

    • Group 1。

PRI_:vSGI 优先级的位 [7:4],位 [3:0] 被视为 b0000。

8.8.3 模拟 GICR_I[C|S]PENDR0

写入 GICR_VSGIR 查询属于指定 vPE 的虚拟 SGI 的待处理状态。GICR_VSGIPENDR.Busy 确定查询何时完成,如下所示:

  • GICR_VSGIPENDR.Busy == 1 直到查询完成。

  • 当 GICR_VSGIPENDR.Busy == 0 时,属于该 vPE 的 vSGI 的待处理状态在 GICR_VSGIPENDR.Pending 中报告。

在以下情况下,GICR_VSGIRPEND.Pending 返回 UNKNOWN 值:

  • 当 GICR_VSGIPENDR.Busy == 1 时。

  • 写入无效的或未映射到此 CommonLPIAff Redistributor 组的 vPEID。

当 GICR_VSGIPENDR.Busy == 1 时写入 GICR_VSGIR 具有以下 CONSTRAINED UNPREDICTABLE 效果之一:

  • 写入被忽略。

  • 写入导致新的查找发生。

VSGI 命令允许模拟对 GICR_ISPENDR0 的写入。可以使用 GITS_SGIR 模拟对 GICR_ISPENDR0 的写入。