LoongArch 半虚拟化接口

KVM 超调用使用 HVCL 指令,代码为 0x100,超调用号放在 a0 中。最多可以将五个参数放在寄存器 a1 - a5 中。返回值放在 v0 中(a0 的别名)。

此接口的源代码可以在 arch/loongarch/kvm* 中找到。

查询是否存在

为了确定主机是否在 KVM 上运行,我们可以利用索引为 CPUCFG_KVM_BASE (0x40000000) 的 cpucfg() 函数。

CPUCFG_KVM_BASE 范围从 0x40000000 到 0x400000FF,CPUCFG_KVM_BASE 范围在 0x40000000 - 0x400000FF 之间被标记为保留。因此,所有当前和未来的处理器都不会在此范围内实现任何功能。

在 KVM 虚拟化的 Linux 系统上,读取索引为 CPUCFG_KVM_BASE (0x40000000) 的 cpucfg() 会返回魔术字符串 ‘KVM0’。

一旦您确定您的主机在支持半虚拟化的 KVM 上运行,您就可以使用如下所述的超调用。

KVM 超调用 ABI

KVM 超调用 ABI 很简单,只有一个暂存寄存器 a0 (v0) 和最多五个通用寄存器 (a1 - a5) 用作输入参数。 FP (浮点) 和向量寄存器不作为输入寄存器使用,并且在超调用期间必须保持不变。

超调用函数可以内联,因为它只使用一个暂存寄存器。

参数如下

寄存器

输入

输出

a0

函数号

返回代码

a1

第一个参数

a2

第二个参数

a3

第三个参数

a4

第四个参数

a5

第五个参数

返回代码可能是以下之一

代码

含义

0

成功

-1

超调用未实现

-2

错误的超调用参数

KVM 超调用文档

每个超调用的模板如下

  1. 超调用名称

  2. 目的

1. KVM_HCALL_FUNC_IPI

目的:

向多个 vCPU 发送 IPI。

  • a0: KVM_HCALL_FUNC_IPI

  • a1: 目标物理 CPUID 的位图的低位部分

  • a2: 目标物理 CPUID 的位图的高位部分

  • a3: 位图中最低的物理 CPUID

超调用允许访客每次超调用最多发送 128 个目标的多个 IPI(进程间中断)。目标在包含在头两个输入寄存器(a1 和 a2)中的位图中表示。

a1 的第 0 位对应于第三个输入寄存器 (a3) 中的物理 CPUID,第 1 位对应于 a3+1 中的物理 CPUID,依此类推。

LoongArch 上的 PV IPI 包括 PV IPI 组播发送和 PV IPI 接收,并且 SWI 用于 PV IPI 注入,因为没有访问 SWI 寄存器的 VM-exits。