POWER9 外部中断虚拟化引擎 (XIVE Gen1)¶
- 支持的设备类型
KVM_DEV_TYPE_XIVE POWER9 XIVE 中断控制器第 1 代
此设备充当 VM 中断控制器。它提供 KVM 接口来配置底层 POWER9 XIVE 中断控制器中 VM 的中断源。
只能实例化一个 XIVE 实例。访客 XIVE 设备需要 POWER9 主机,并且访客操作系统应支持 XIVE 原生利用中断模式。如果不支持,则应使用旧的中断模式运行,称为 XICS (POWER7/8)。
设备映射
KVM 设备公开了 XIVE HW 的不同 MMIO 范围,这些范围是中断管理所必需的。这些通过填充自定义 VM 故障处理程序的 VMA 暴露给访客。
线程中断管理区域 (TIMA)
每个线程都有一个关联的线程中断管理上下文,该上下文由一组寄存器组成。这些寄存器允许线程处理优先级管理和中断确认。最重要的是
中断挂起缓冲区 (IPB)
当前处理器优先级 (CPPR)
通知源寄存器 (NSR)
它们以四个不同的页面暴露给软件,每个页面都提供具有不同特权的视图。第一页用于物理线程上下文,第二页用于虚拟机管理程序。只有第三页(操作系统)和第四页(用户级别)暴露给访客。
事件状态缓冲区 (ESB)
每个源都与一个事件状态缓冲区 (ESB) 相关联,该缓冲区具有一对偶数/奇数页,这些页面提供用于管理源的命令:例如,触发、EOI、关闭源。
设备直通
当设备直通到访客时,源中断来自不同的 HW 控制器 (PHB4),并且暴露给访客的 ESB 页面应适应此更改。
当设备 HW irq 映射到访客 IRQ 号空间或从访客 IRQ 号空间取消映射时,将调用 passthru_irq 助手 kvmppc_xive_set_mapped() 和 kvmppc_xive_clr_mapped()。KVM 设备扩展这些助手以清除正在映射的访客 IRQ 号的 ESB 页面,然后让 VM 故障处理程序重新填充。处理程序将插入与正在直通的设备的 HW 中断相对应的 ESB 页面,如果设备已被删除,则插入初始 IPI ESB 页面。
ESB 重新映射对访客和操作系统设备驱动程序完全透明。所有处理都在 VFIO 和 KVM-PPC 中的上述助手内完成。
组
- KVM_DEV_XIVE_GRP_CTRL
提供对设备的全局控制
- 属性
1.1 KVM_DEV_XIVE_RESET(仅写入)重置源和事件队列的中断控制器配置。由 kexec 和 kdump 使用。
错误:无
1.2 KVM_DEV_XIVE_EQ_SYNC(仅写入)同步所有源和队列,并将 EQ 页面标记为脏。这确保在迁移 VM 时捕获一致的内存状态。
错误:无
1.3 KVM_DEV_XIVE_NR_SERVERS(仅写入)kvm_device_attr.addr 指向一个 __u32 值,该值是中断服务器的数量(即,最高可能的 vcpu id 加 1)。
错误
-EINVAL
值大于 KVM_MAX_VCPU_IDS。
-EFAULT
attr->addr 的用户指针无效。
-EBUSY
vCPU 已连接到设备。
- KVM_DEV_XIVE_GRP_SOURCE(仅写入)
在 XIVE 设备中初始化新的源并屏蔽它。
- 属性
中断源编号 (64 位)
kvm_device_attr.addr 指向一个 __u64 值
bits: | 63 .... 2 | 1 | 0 values: | unused | level | type
类型:0:MSI 1:LSI
级别:LSI 情况下的断言级别。
错误
-E2BIG
中断源编号超出范围
-ENOMEM
无法创建新的源块
-EFAULT
attr->addr 的用户指针无效。
-ENXIO
无法分配底层 HW 中断
- KVM_DEV_XIVE_GRP_SOURCE_CONFIG(仅写入)
配置源目标
- 属性
中断源编号 (64 位)
kvm_device_attr.addr 指向一个 __u64 值
bits: | 63 .... 33 | 32 | 31 .. 3 | 2 .. 0 values: | eisn | mask | server | priority
优先级:0-7 中断优先级级别
服务器:选择用于处理中断的 CPU 编号
掩码:掩码标志(未使用)
eisn:有效中断源编号
错误
-ENOENT
未知源编号
-EINVAL
未初始化的源编号
-EINVAL
优先级无效
-EINVAL
CPU 编号无效。
-EFAULT
attr->addr 的用户指针无效。
-ENXIO
CPU 事件队列未配置或底层 HW 中断配置失败
-EBUSY
没有可用于服务中断的 CPU
- KVM_DEV_XIVE_GRP_EQ_CONFIG(读写)
配置 CPU 的事件队列
- 属性
EQ 描述符标识符 (64 位)
EQ 描述符标识符是一个元组 (服务器、优先级)
bits: | 63 .... 32 | 31 .. 3 | 2 .. 0 values: | unused | server | prioritykvm_device_attr.addr 指向
struct kvm_ppc_xive_eq { __u32 flags; __u32 qshift; __u64 qaddr; __u32 qtoggle; __u32 qindex; __u8 pad[40]; };
- 标志:队列标志
- KVM_XIVE_EQ_ALWAYS_NOTIFY(必需)
强制通知,而不使用 XIVE END ESB 提供的合并机制。
qshift:队列大小(2 的幂)
qaddr:队列的实际地址
qtoggle:当前队列切换位
qindex:当前队列索引
pad:保留供将来使用
错误
-ENOENT
CPU 编号无效
-EINVAL
优先级无效
-EINVAL
标志无效
-EINVAL
队列大小无效
-EINVAL
队列地址无效
-EFAULT
attr->addr 的用户指针无效。
-EIO
底层 HW 配置失败
- KVM_DEV_XIVE_GRP_SOURCE_SYNC(仅写入)
同步源以刷新事件通知
- 属性
中断源编号 (64 位)
错误
-ENOENT
未知源编号
-EINVAL
未初始化的源编号
VCPU 状态
XIVE IC 在称为 NVT 的内部结构中维护 VP 中断状态。当 VP 未在 HW 处理器线程上调度时,如果 VP 是事件通知的目标,则 HW 可以更新此结构。
对于迁移来说,捕获 NVT 中的缓存 IPB 非常重要,因为它综合了挂起中断的优先级。我们捕获更多信息以报告调试信息。
KVM_REG_PPC_VP_STATE (2 * 64 位)
bits: | 63 .... 32 | 31 .... 0 | values: | TIMA word0 | TIMA word1 | bits: | 127 .......... 64 | values: | unused |
迁移
使用 XIVE 原生利用模式保存 VM 的状态应遵循特定的顺序。当 VM 停止时
屏蔽所有源 (PQ=01) 以停止事件流。
2. 使用 KVM 控制 KVM_DEV_XIVE_EQ_SYNC 同步 XIVE 设备,以刷新任何正在进行中的事件通知并稳定 EQ。在此阶段,EQ 页面被标记为脏,以确保它们在迁移序列中被传输。
3. 捕获源目标、EQ 配置和线程中断上下文寄存器状态。
恢复类似
恢复 EQ 配置。因为目标依赖于它。
恢复目标
恢复线程中断上下文
恢复源状态
让 vCPU 运行