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 暴露给访客。

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

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

    • 中断挂起缓冲区 (IPB)

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

    • 通知源寄存器 (NSR)

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

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

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

    1. 设备直通

    当设备直通到访客时,源中断来自不同的 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 中的上述助手内完成。

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

  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

  • 级别:LSI 情况下的断言级别。

错误

-E2BIG

中断源编号超出范围

-ENOMEM

无法创建新的源块

-EFAULT

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

-ENXIO

无法分配底层 HW 中断

  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
  • 优先级:0-7 中断优先级级别

  • 服务器:选择用于处理中断的 CPU 编号

  • 掩码:掩码标志(未使用)

  • eisn:有效中断源编号

错误

-ENOENT

未知源编号

-EINVAL

未初始化的源编号

-EINVAL

优先级无效

-EINVAL

CPU 编号无效。

-EFAULT

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

-ENXIO

CPU 事件队列未配置或底层 HW 中断配置失败

-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];
};
  • 标志:队列标志
    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 配置失败

  1. 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 停止时

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

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

    3. 捕获源目标、EQ 配置和线程中断上下文寄存器状态。

    恢复类似

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

    2. 恢复目标

    3. 恢复线程中断上下文

    4. 恢复源状态

    5. 让 vCPU 运行