KVM 上的 s390 DIAGNOSE 调用¶
KVM on s390 支持 DIAGNOSE 调用以进行 hypercall,包括原生 hypercall 以及其他 s390 hypervisor 上的选定 hypercall。
请注意,位的编号方式遵循通常的 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 hypervisor 的文档。
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 标准,以讨论此 hypercall。
- 子代码 4 - 存储限制
由用户空间处理。
在 DIAGNOSE 调用完成后,通用寄存器 2 将包含存储限制:在 VM 的整个生命周期中可能用于存储的最大物理地址。
存储限制不指示当前可用的存储,它可能包括空洞、备用存储和为其他目的保留的区域,例如内存热插拔或 virtio-mem 设备。其他用于检测实际可用存储的接口(例如 SCLP)必须与此子功能一起使用。
请注意,存储限制可以大于,但绝不小于 SCLP 通过“最大存储增量”和“增量大小”指示的最大存储地址。
DIAGNOSE 功能代码 ‘X’501’ - KVM 断点¶
如果功能代码指定为 0x501,则可以执行断点功能。此功能代码由用户空间处理。
此 diagnose 功能代码没有子功能,也不使用任何参数。
DIAGNOSE 功能代码 ‘X’9C’ - 自愿时间片让步¶
通用寄存器 1 包含目标 CPU 地址。
在使用共享主机 CPU 的 LPAR、KVM 或 z/VM 等 hypervisor 的访客中,通过将运行访客 CPU 的主机 CPU 让给另一个访客 CPU(最好是包含指定目标 CPU 的逻辑 CPU),使用功能代码 0x9c 的 DIAGNOSE 可以提高系统性能。
DIAG ‘X’9C’ 转发¶
访客可以发送 DIAGNOSE 0x9c 以让步给某个其他 vcpu。例如,Linux 访客会尝试让步给当前持有自旋锁但未运行的 vcpu。
但是,在主机上,支持 vcpu 的实际 cpu 本身可能未运行。转发最初由访客发送的 DIAGNOSE 0x9c 以让步给支持 cpu,有望导致该 cpu 以及随后的访客 vcpu 被调度。
- diag9c_forwarding_hz
KVM 内核参数,允许指定每秒 DIAGNOSE 0x9c 转发的最大数量,目的是避免 DIAGNOSE 0x9c 转发风暴。值为 0 时会关闭转发。