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 内部结构。

必须先恢复 GICV3,然后才能恢复 ITS,并且必须在恢复 ITS 表之前恢复所有 ITS 寄存器,但 GITS_CTLR 除外。

在调用 KVM_DEV_ARM_ITS_RESTORE_TABLES 之前,还必须恢复 GITS_IIDR 只读寄存器,因为 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。修订字段编码表布局 ABI 修订版。将来我们可能会实现虚拟 LPI 的直接注入。这将需要升级表布局和 ABI 的演变。必须在调用 KVM_DEV_ARM_ITS_RESTORE_TABLES 之前恢复 GITS_IIDR。

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

错误

-ENXIO

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

-EFAULT

attr->addr 的用户指针无效

-EINVAL

偏移量未 64 位对齐

-EBUSY

一个或多个 VCPU 正在运行

ITS 恢复顺序:

恢复 GIC 和 ITS 时必须遵循以下顺序

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

  2. 恢复所有重新分配器

  3. 提供 ITS 基地址 (KVM_DEV_ARM_VGIC_GRP_ADDR)

  4. 按以下顺序恢复 ITS

    1. 恢复 GITS_CBASER

    2. 恢复除 GITS_CTLR 之外的所有其他 GITS_ 寄存器!

    3. 加载 ITS 表数据 (KVM_DEV_ARM_ITS_RESTORE_TABLES)

    4. 恢复 GITS_CTLR

然后可以启动 vcpu。

ITS 表 ABI REV0:

ABI 的修订版 0 仅支持虚拟 GICv3 的功能,并且不支持具有直接注入嵌套虚拟机管理程序虚拟中断功能的虚拟 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<n>.Valid = 0

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

  • ABI 版本保持不变,并且与首次创建 ITS 设备时设置的版本相同。