ARM 虚拟中断转换服务 (ITS)

支持的设备类型

KVM_DEV_TYPE_ARM_VGIC_ITS ARM 中断转换服务控制器

ITS 允许将 MSI(-X) 中断注入到客户机中。此扩展是可选的。创建虚拟 ITS 控制器还需要主机 GICv3(请参阅 ARM 虚拟通用中断控制器 v3 及更高版本 (VGICv3)),但不依赖于拥有物理 ITS 控制器。

每个客户机可以有多个 ITS 控制器,每个控制器都必须具有单独的、不重叠的 MMIO 区域。

KVM_DEV_ARM_VGIC_GRP_ADDR

属性
KVM_VGIC_ITS_ADDR_TYPE (rw, 64 位)

GICv3 ITS 控制寄存器帧在客户机物理地址空间中的基地址。该地址需要 64K 对齐,并且该区域覆盖 128K。

错误

-E2BIG

地址超出可寻址 IPA 范围

-EINVAL

地址未正确对齐

-EEXIST

地址已配置

-EFAULT

attr->addr 的用户指针无效。

-ENODEV

属性不正确或不支持 ITS。

KVM_DEV_ARM_VGIC_GRP_CTRL

属性
KVM_DEV_ARM_VGIC_CTRL_INIT

请求初始化 ITS,kvm_device_attr.addr 中没有其他参数。

KVM_DEV_ARM_ITS_CTRL_RESET

重置 ITS,kvm_device_attr.addr 中没有其他参数。请参阅“ITS 重置状态”部分。

KVM_DEV_ARM_ITS_SAVE_TABLES

将 ITS 表数据保存到客户机 RAM 中,保存在客户机在相应寄存器/表条目中提供的位置。如果用户空间需要某种形式的脏跟踪来识别保存过程修改了哪些页面,即使使用其他机制来跟踪 vCPU 弄脏的内存,也应该使用位图。

客户机内存中表的布局定义了一个 ABI。条目以小端格式布局,如最后一段所述。

KVM_DEV_ARM_ITS_RESTORE_TABLES

将 ITS 表从客户机 RAM 恢复到 ITS 内部结构。

必须在 ITS 之前恢复 GICV3,并且必须在恢复 ITS 表之前恢复所有 ITS 寄存器(GITS_CTLR 除外)。

GITS_IIDR 只读寄存器也必须在调用 KVM_DEV_ARM_ITS_RESTORE_TABLES 之前恢复,因为 IIDR 修订字段编码了 ABI 修订。

恢复 GICv3/ITS 时的预期顺序在“ITS 恢复顺序”部分中描述。

错误

-ENXIO

ITS 未按照设置此属性之前的要求正确配置

-ENOMEM

分配 ITS 内部数据时内存短缺

-EINVAL

恢复的数据不一致

-EFAULT

无效的客户机 ram 访问

-EBUSY

一个或多个 VCPU 正在运行

-EACCES

虚拟 ITS 由物理 GICv4 ITS 提供支持,并且在没有 GICv4.1 的情况下状态不可用

KVM_DEV_ARM_VGIC_GRP_ITS_REGS

属性

kvm_device_attr 的 attr 字段编码 ITS 寄存器的偏移量,相对于 ITS 控制帧基地址 (ITS_base)。

无论寻址寄存器的宽度(32/64 位)如何,kvm_device_attr.addr 都指向 __u64 值。只能以完整长度访问 64 位寄存器。

内核忽略对只读寄存器的写入,除了

  • GITS_CREADR。必须恢复它,否则队列中的命令将在恢复 CWRITER 后重新执行。GITS_CREADR 必须在恢复 GITS_CTLR 之前恢复,这可能会启用 ITS。此外,它必须在 GITS_CBASER 之后恢复,因为写入 GITS_CBASER 会重置 GITS_CREADR。

  • GITS_IIDR。Revision 字段编码了表布局 ABI 修订。将来我们可能会实现虚拟 LPI 的直接注入。这将需要升级表布局和 ABI 的发展。GITS_IIDR 必须在调用 KVM_DEV_ARM_ITS_RESTORE_TABLES 之前恢复。

对于其他寄存器,获取或设置寄存器与在真实硬件上读取/写入寄存器具有相同的效果。

错误

-ENXIO

偏移量不对应于任何支持的寄存器

-EFAULT

attr->addr 的用户指针无效

-EINVAL

偏移量未 64 位对齐

-EBUSY

一个或多个 VCPU 正在运行

ITS 恢复顺序:

在恢复 GIC、ITS 和 KVM_IRQFD 分配时,必须遵循以下顺序

  1. 恢复所有客户机内存并创建 vcpu

  2. 恢复所有重新分发器

  3. 提供 ITS 基地址 (KVM_DEV_ARM_VGIC_GRP_ADDR)

  4. 按以下顺序恢复 ITS

    1. 恢复 GITS_CBASER

    2. 恢复所有其他 GITS_ 寄存器,除了 GITS_CTLR!

    3. 加载 ITS 表数据 (KVM_DEV_ARM_ITS_RESTORE_TABLES)

    4. 恢复 GITS_CTLR

  5. 恢复 MSI 的 KVM_IRQFD 分配

然后可以启动 vcpu。

ITS 表 ABI REV0:

ABI 的修订版 0 仅支持虚拟 GICv3 的功能,不支持虚拟 GICv4,该虚拟 GICv4 支持直接注入嵌套虚拟机管理程序的虚拟中断。

设备表和 ITT 分别按 DeviceID 和 EventID 索引。集合表不按 CollectionID 索引,集合中的条目以不特定的顺序排列。所有条目都是 8 个字节。

设备表条目 (DTE)

bits:     | 63| 62 ... 49 | 48 ... 5 | 4 ... 0 |
values:   | V |   next    | ITT_addr |  Size   |

其中

  • V 指示条目是否有效。如果不是,则其他字段没有意义。

  • next:如果此条目是最后一个条目,则等于 0;否则,它对应于到下一个 DTE 的 DeviceID 偏移量,上限为 2^14 -1。

  • ITT_addr 匹配 ITT 地址的位 [51:8](256 字节对齐)。

  • Size 指定 EventID 支持的位数,减一

集合表条目 (CTE)

bits:     | 63| 62 ..  52  | 51 ... 16 | 15  ...   0 |
values:   | V |    RES0    |  RDBase   |    ICID     |

其中

  • V 指示条目是否有效。如果不是,则其他字段没有意义。

  • RES0:保留字段,具有应为零或保留行为。

  • RDBase 是 PE 编号 (GICR_TYPER.Processor_Number 语义),

  • ICID 是集合 ID

中断转换条目 (ITE)

bits:     | 63 ... 48 | 47 ... 16 | 15 ... 0 |
values:   |    next   |   pINTID  |  ICID    |

其中

  • next:如果此条目是最后一个条目,则等于 0;否则,它对应于到下一个 ITE 的 EventID 偏移量,上限为 2^16 -1。

  • pINTID 是物理 LPI ID;如果为零,则表示条目无效,其他字段没有意义。

  • ICID 是集合 ID

ITS 重置状态:

RESET 将 ITS 返回到首次创建和初始化时的状态。当 RESET 命令返回时,保证以下事项

  • ITS 未启用且静态 GITS_CTLR.Enabled = 0 .Quiescent=1

  • 没有内部缓存的状态

  • 未使用任何集合或设备表 GITS_BASER.Valid = 0

  • GITS_CBASER = 0, GITS_CREADR = 0, GITS_CWRITER = 0

  • ABI 版本未更改,并且保持首次创建 ITS 设备时设置的版本。