KVM 上的 s390 DIAGNOSE 调用¶
s390 上的 KVM 支持 DIAGNOSE 调用以进行超调用(hypercalls),包括原生超调用和在其他 s390 虚拟机监控程序上发现的特定超调用。
请注意,位(bit)的编号遵循通常的 s390 约定(最高有效位在左侧)。
一般说明¶
客户机发出的 DIAGNOSE 调用会引起强制拦截。这意味着所有受支持的 DIAGNOSE 调用都需要由 KVM 或其用户空间处理。
KVM 支持的所有 DIAGNOSE 调用都使用 RS-a 格式
--------------------------------------
| '83' | R1 | R3 | B2 | D2 |
--------------------------------------
0 8 12 16 20 31
第二个操作数地址(通过基址/位移计算获得)不用于寻址数据。相反,该地址的位 48-63 指定功能代码,而位 0-47 被忽略。
受支持的 DIAGNOSE 功能代码因所使用的用户空间而异。对于非 KVM 特定的 DIAGNOSE 功能代码,请参阅定义它们的 s390 虚拟机监控程序的文档。
DIAGNOSE 功能代码 'X'500' - KVM 功能¶
如果功能代码指定为 0x500,则会执行各种 KVM 特定功能,包括 virtio 功能。
通用寄存器 1 包含子功能代码。受支持的子功能取决于 KVM 的用户空间。关于 virtio 子功能,用户空间通常提供 s390-virtio(子代码 0-2)或 virtio-ccw(子代码 3)。
DIAGNOSE 指令完成后,通用寄存器 2 包含功能的返回代码,该代码可以是返回代码,也可以是子代码特定值。
如果指定的子功能不受支持,将触发 SPECIFICATION 异常。
- 子代码 0 - s390-virtio 通知和早期控制台 printk
由用户空间处理。
- 子代码 1 - s390-virtio 重置
由用户空间处理。
- 子代码 2 - s390-virtio 设置状态
由用户空间处理。
- 子代码 3 - virtio-ccw 通知
由用户空间或 KVM 处理(ioeventfd 情况)。
通用寄存器 2 包含一个子通道识别字,表示要通知的 virtio-ccw 代理设备的子通道。
通用寄存器 3 包含要通知的 virtqueue 编号。
通用寄存器 4 包含一个用于 KVM 使用的 64 位标识符(kvm_io_bus cookie)。如果通用寄存器 4 不包含有效标识符,则忽略它。
DIAGNOSE 调用完成后,如果发生内部错误,通用寄存器 2 可能包含一个 64 位标识符(在 kvm_io_bus cookie 情况下),或者一个负错误值。
另请参阅 virtio 标准中对此超调用的讨论。
- 子代码 4 - 存储限制
由用户空间处理。
DIAGNOSE 调用完成后,通用寄存器 2 将包含存储限制:虚拟机生命周期内可能用于存储的最大物理地址。
存储限制不表示当前可用的存储空间,它可能包括空洞、备用存储以及为其他目的保留的区域,例如内存热插拔或 virtio-mem 设备。其他用于检测实际可用存储的接口,例如 SCLP,必须与此子功能结合使用。
请注意,存储限制可以大于,但绝不能小于 SCLP 通过“最大存储增量”和“增量大小”指示的最大存储地址。
DIAGNOSE 功能代码 'X'501 - KVM 断点¶
如果功能代码指定为 0x501,则可能执行断点功能。此功能代码由用户空间处理。
此诊断功能代码没有子功能,也不使用任何参数。
DIAGNOSE 功能代码 'X'9C - 自愿时间片让出¶
通用寄存器 1 包含目标 CPU 地址。
在 LPAR、KVM 或 z/VM 等使用共享宿主机 CPU 的虚拟机监控程序客户机中,功能代码为 0x9c 的 DIAGNOSE 可以通过让出客户机 CPU 正在运行的宿主机 CPU,以便将其分配给另一个客户机 CPU(最好是包含指定目标 CPU 的逻辑 CPU),从而提高系统性能。
DIAG 'X'9C 转发¶
客户机可能会发送 DIAGNOSE 0x9c 以让出给某个其他 vcpu。例如,一个 Linux 客户机试图让出给当前持有自旋锁但未运行的 vcpu。
然而,在宿主机上,支持该 vcpu 的真实 CPU 本身可能没有运行。将客户机最初发送的 DIAGNOSE 0x9c 转发给支持 CPU,有望导致该 CPU(以及随后客户机的 vcpu)被调度。
- diag9c_forwarding_hz
KVM 内核参数,允许指定每秒 DIAGNOSE 0x9c 转发的最大次数,以避免 DIAGNOSE 0x9c 转发风暴。值为 0 会关闭转发功能。