POWER9 外部中断虚拟化引擎 (XIVE Gen1)

支持的设备类型
  • KVM_DEV_TYPE_XIVE POWER9 XIVE 中断控制器第一代

此设备用作虚拟机中断控制器。它提供 KVM 接口,用于在底层 POWER9 XIVE 中断控制器中配置虚拟机的中断源。

只能实例化一个 XIVE 实例。客户机 XIVE 设备需要 POWER9 主机,并且客户机操作系统应支持 XIVE 本机利用中断模式。否则,它应使用旧版中断模式运行,即 XICS (POWER7/8)。

  • 设备映射

    KVM 设备公开了 XIVE 硬件的不同 MMIO 范围,这些范围是中断管理所需的。这些范围通过填充了自定义虚拟机故障处理程序的 VMA 暴露给客户机。

    1. 线程中断管理区域 (TIMA)

    每个线程都有一个关联的线程中断管理上下文,由一组寄存器组成。这些寄存器允许线程处理优先级管理和中断确认。最重要的有

    • 中断待处理缓冲区 (IPB)

    • 当前处理器优先级 (CPPR)

    • 通知源寄存器 (NSR)

    它们以四种不同的页面形式暴露给软件,每种页面提供不同权限的视图。第一页用于物理线程上下文,第二页用于虚拟机监控程序。只有第三页(操作系统)和第四页(用户级别)暴露给客户机。

    1. 事件状态缓冲区 (ESB)

    每个源都关联一个事件状态缓冲区 (ESB),带有一对偶数/奇数页面,提供用于管理源的命令:例如,触发、EOI、关闭源。

    1. 设备直通

    当设备直通给客户机时,源中断来自不同的硬件控制器 (PHB4),并且暴露给客户机的 ESB 页面应适应此更改。

    当设备的硬件中断被映射到或从客户机中断号空间解除映射时,会调用 passthru_irq 辅助函数 kvmppc_xive_set_mapped() 和 kvmppc_xive_clr_mapped()。KVM 设备扩展这些辅助函数以清除正在映射的客户机中断号的 ESB 页面,然后让虚拟机故障处理程序重新填充。如果设备已被移除,处理程序将插入对应于直通设备的硬件中断的 ESB 页面,或者初始的 IPI ESB 页面。

    ESB 重映射对客户机和操作系统设备驱动程序完全透明。所有处理均在 VFIO 和 KVM-PPC 中的上述辅助函数内完成。

  1. 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 已连接到设备。

  1. 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

无法分配底层硬件中断

  1. 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

  1. KVM_DEV_XIVE_GRP_EQ_CONFIG(读写)

    配置 CPU 的事件队列

属性

EQ 描述符标识符(64位)

EQ 描述符标识符是一个元组(服务器,优先级)

bits:     | 63   ....  32 | 31 .. 3 |  2 .. 0
values:   |    unused     |  server | priority

kvm_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

底层硬件配置失败

  1. 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 本机利用模式保存虚拟机状态应遵循特定序列。当虚拟机停止时

    1. 屏蔽所有源 (PQ=01) 以停止事件流。

    2. 使用 KVM 控制 KVM_DEV_XIVE_EQ_SYNC 同步 XIVE 设备,以刷新任何正在传输的事件通知并稳定 EQ。在此阶段,EQ 页面被标记为脏页,以确保它们在迁移序列中被传输。

    3. 捕获源目标的状态、EQs 配置以及线程中断上下文寄存器的状态。

    恢复类似

    1. 恢复 EQ 配置。因为目标设置依赖于它。

    2. 恢复目标设置

    3. 恢复线程中断上下文

    4. 恢复源状态

    5. 让 vCPU 运行