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