KVM API docs

1. General description

kvm API 接口就是一组 ioctl 集合,用来控制虚拟机的各个方面。这些 ioctl 可以分为四类:

  • system ioctl ,这些ioctl的查询与设置会影响整个虚拟机子系统,它们主要用来创建虚拟机。
  • vm ioctl, VM即是 Virtual Machine; 这些ioctl接口主要用于查询/设置虚拟机。例如设置内存布局。此外,VM ioctl 还用于创建虚拟 CPU (vcpus) 和设备(device)。
  • vcpu ioctl, 这些接口主要用来操控单个vcpu
  • device ioctl, 与vcpu ioctl类似,主要用于操控单个虚拟机设备。

2. File descriptors

kvm API 以文件描述符为中心。

通过 open("/dev/kvm") 获得 kvm 子系统的句柄;此句柄可用于调用系统 ioctl。通过调用ioctl KVM_CREATE_VM 将创建一个 VM 文件描述符,该描述符可用于发出 VM ioctl(第二类 ioctl)。 VM fd 上的 KVM_CREATE_VCPU 或 KVM_CREATE_DEVICE ioctl 将创建一个虚拟 cpu 或虚拟设备 device,并返回对应的文件描述符。使用 vcpu 或 device fd 可以执行对应的 ioctl (第三类,四类 ioctl)。

需要注意的是,虽然 VM ioctl 只能从创建 VM 的进程发出,但 VM 的生命周期与其文件描述符相关联,而不是与其创建者(进程)相关联。换句话说,直到最后一个对 VM 文件描述符的引用被释放后,VM 及其资源(包括相关的地址空间)才会被释放。例如,如果在 ioctl(KVM_CREATE_VM) 之后发出 fork(),则在父(原始)进程及其子进程都将其引用 VM 的文件描述符释放后,才会释放 VM资源。

由于必须释放文件描述符的所有饮用才会释放 VM 资源,因此强烈建议不要轻易通过 fork()、dup() 等创建 VM 的引用,这可能会产生不必要的副作用,例如当虚拟机关闭时,由虚拟机进程分配的内存可能不会被释放/取消。

3. Extensions

从 Linux 2.6.22 开始,KVM ABI 已经稳定:不允许向后不兼容的更改。但是,有一个扩展工具允许查询和使用 API 的向后兼容扩展。

扩展机制不基于 Linux 版本号。相反,kvm 定义了扩展标识符和一个查询特定扩展标识符是否可用的工具。如果是,则对应的 ioctl 是可用的。

4. API description

本节介绍 kvm guest 的 ioctl api。对于每个 ioctl,都提供了以下信息和描述:

guest 与 host: 一般来说,host 是虚拟机的宿主机,对虚拟机进行管理,而 guest 即虚拟机,这个是相当host 的一个概念。
  • Capability: 即哪个 KVM 扩展提供了这个 ioctl。它可以是以下值
    • basic:它将由任何支持 API 版本 12(参见第 4.1 节)的内核提供。即一种基础能力。
    • KVM_CAP_xyz: 需要使用 KVM_CHECK_EXTENSION(参见第 4.4 节)检查当前内核可用性。
    • none:不是所有内核都支持这个 ioctl,但没有对应的接口来检查它的可用性,在不支持的内核上调用这个ioctl, 它将返回 ENOTTY
  • Architectures: 即这个 ioctl 适用于哪些指令集架构,x86 包括 i386 和 x86_64
  • Type: 按照第一节对ioctl 的分类,systemvmvcpudevice
  • Parameters: ioctl 的参数
  • Returns:ioctl 的返回值; 对于一般性的错误,会返回编号 EBADFENOMEMEINVAL

4.1 KVM_GET_API_VERSION

获取当前 kvm 的接口版本

Capability:basic

Architectures:all

Type:system ioctl

Parameters:none

Returns:the constant KVM_API_VERSION (=12)

这个ioctl的返回值预期就是12,如果返回值为12,说明这个是符合预期的,所有 Capability 为 basic 的 ioctl 都是可用的。

4.2 KVM_CREATE_VM

创建虚拟机

Capability:basic

Architectures:all

Type:system ioctl

Parameters:machine type identifier (KVM_VM_*)

Returns:a VM fd that can be used to control the new virtual machine.

如果我们想先创建一个即没有虚拟 CPU,也没有内存的虚拟机,那可以使用 0 作为机器类型。

如果是在 S390 上创建虚拟机,请先执行 KVM_CAP_S390_UCONTROL检查,并使用标志 `KVM_VM_S390_UCONTROL` 作为特权用户。

这里标注  KVM_CREATE_VM 是一种 basic 能力,实际在 s390 上不一定是100%支持的,如果在 s390 上使用, 需要执行 KVM_CAP_S390_UCONTROL 进行检查。

在 arm64 上,VM 的物理地址大小(IPA 大小限制)默认限制为 40 位(即 1TB )。如果主机支持扩展 KVM_CAP_ARM_VM_IPA_SIZE,则可以配置限制。如果支持,请使用 KVM_VM_TYPE_ARM_IPA_SIZE(IPA_Bits) 设置机器类型标识符中的大小.

例如已知某arm单板支持 KVM_CAP_ARM_VM_IPA_SIZE, 则可以通过以下方式设置虚拟机内存寻址大小

dev_fd= open("/dev/kvm");

vm_fd = ioctl(dev_fd, KVM_CREATE_VM, KVM_VM_TYPE_ARM_IPA_SIZE(48));

如果配置的 IPA_SIZE 大小是不被支持的,则 create vm将失败。

4.3 KVM_GET_MSR_INDEX_LIST, KVM_GET_MSR_FEATURE_INDEX_LIST

Capability: basic, KVM_CAP_GET_MSR_FEATURES for KVM_GET_MSR_FEATURE_INDEX_LIST

Architectures:x86

Type:system ioctl

Parameters:struct kvm_msr_list (in/out)

Returns:0 on success; -1 on error

Errors:

EFAULT 无法读取或写入 msr 索引列表
E2BIG msr 索引太大,无法放入用户指定的数组中。
struct kvm_msr_list {
      __u32 nmsrs; /* number of msrs in entries */
      __u32 indices[0];
};

用户在 nmsrs 中填写索引数组的大小, kvm 调整 nmsrs 以反映 msrs 的实际数量,并用它们的数字填充索引数组。

4.4 KVM_CHECK_EXTENSION

查询当前内核对 kvm API 的扩展支持。

Capability: basic, KVM_CAP_CHECK_EXTENSION_VM for vm ioctl

Architectures: all

Type: system ioctl, vm ioctl

Parameters: extension identifier (KVM_CAP_*)

Returns: 0 表示不支持; 1或其它数字表示支持

其参数为一个扩展标识符KVM_CAP_*, 返回0表示不支持, 1或其它数表示支持。

4.5 KVM_GET_VCPU_MMAP_SIZE

获取 vcpu 的控制内存区域大小。

KVM_RUN ioctl 通过共享内存区域与用户空间通信。此 ioctl 返回该区域的大小。

Capability:basic

Architectures: all

Type:system ioctl

Parameters:none

Returns:size of vcpu mmap area, in bytes

此内存空间是用户可以控制的 vcpu 内存。其与cpu构架是无关的,所以这是个 system ioctl, 我们调用 ioctl 时需要穿入  dev_fd ,而不是  vcpu_fd

除了 KVM_RUN 通信区域的大小, 此接口返回的 mmap 还包含了VCPU 文件描述符的其他区域,如:

  • 如果扩展 KVM_CAP_COALESCED_MMIO 是可用的,则内存页 KVM_COALESCED_MMIO_PAGE_OFFSET * PAGE_SIZE 也包含在此 mmap 内存区域内。
  • 如果扩展 KVM_CAP_DIRTY_LOG_RING 是可用的,则 KVM_DIRTY_LOG_PAGE_OFFSET * PAGE_SIZE 的一些页也是在该 mmap 内存区域,8.3 节有更详细的描述。

4.6 KVM_SET_MEMORY_REGION

此 ioctl 已过时并已删除

Capability:basic

Architectures:all

Type:vm ioctl

Parameters:struct kvm_memory_region (in)

Returns:0 on success, -1 on error

4.7 KVM_CREATE_VCPU

创建 vcpu

Capability: basic

Architectures: all

Type: vm ioctl

Parameters: vcpu id (apic id on x86)

Returns: vcpu fd on success, -1 on error

新增一个 vcpu 到虚拟机。最多可以添加 max_vcpus。 vcpu id 是 [0, max_vcpu_id) 范围内的整数。

如何获取 max_vcpus 值:

可以在运行时使用 KVM_CHECK_EXTENSION ioctl, 传入参数 KVM_CAP_NR_VCPUS, 返回推荐的 max_vcpus 值。传入参数 KVM_CAP_MAX_VCPUS, 返回最大可能的 max_vcpus 值。

如果 KVM_CAP_NR_VCPUS 不存在,您应该假设 max_vcpus 为 4, 如果 KVM_CAP_MAX_VCPUS 不存在,您应该假设 max_vcpus 与 KVM_CAP_NR_VCPUS 返回的值相同.

可以在运行时使用 KVM_CHECK_EXTENSION ioctl, 传入参数 KVM_CAP_MAX_VCPU_ID , 获取 max_vcpu_id 的最大可能值。

4.8 KVM_GET_DIRTY_LOG (vm ioctl)

获取所有脏页的位图

Capability:basic

Architectures:all

Type:vm ioctl

Parameters:struct kvm_dirty_log (in/out)

Returns:0 on success, -1 on error

给定一个 memory solt,返回自上次调用此 ioctl 以来所有脏页的位图。位 0 是内存插槽中的第一页。

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !   

(确保清除整个 kvm_dirty_log 以避免填充问题)

/* for KVM_GET_DIRTY_LOG */
struct kvm_dirty_log {
      __u32 slot;
      __u32 padding;
      union {
              void __user *dirty_bitmap; /* one bit per page */
              __u64 padding;
      };
};

如果 KVM_CAP_MULTI_ADDRESS_SPACE 可用,slot 字段的第 16-31 位指定要返回脏位图的地址空间。有关 slot 字段使用的详细信息,请参阅 KVM_SET_USER_MEMORY_REGION。

4.9 KVM_SET_MEMORY_ALIAS

此 ioctl 已过时并已被删除。

4.10 KVM_RUN

运行 guest vcpu。

Capability: basic

Architectures: all

Type: vcpu ioctl

Parameters: none

Returns: 0 on success, -1 on error

虽然该接口没有显示指定参数,但是需要我们事先配置好 struct kvm_run

4.11 KVM_GET_REGS

获取CPU的通用寄存器信息,参数 struct kvm_regs, 该接口不支持 arm64 构架

Capability: basic

Architectures: all except arm64

Type: vcpu ioctl

Parameters: struct kvm_regs (out)

Returns: 0 on success, -1 on error

Reads the general purpose registers from the vcpu.

/* x86 */
struct kvm_regs {
      /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
      __u64 rax, rbx, rcx, rdx;
      __u64 rsi, rdi, rsp, rbp;
      __u64 r8,  r9,  r10, r11;
      __u64 r12, r13, r14, r15;
      __u64 rip, rflags;
};

/* mips */
struct kvm_regs {
      /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
      __u64 gpr[32];
      __u64 hi;
      __u64 lo;
      __u64 pc;
};

4.12 KVM_SET_REGS

设置CPU的通用寄存器信息,参数 struct kvm_regs, 该接口不支持 arm64 构架

Capability: basic

Architectures: all except arm64

Type: vcpu ioctl

Parameters: struct kvm_regs (in)

Returns: 0 on success, -1 on error

Writes the general purpose registers into the vcpu.

See KVM_GET_REGS for the data structure.

4.13 KVM_GET_SREGS</

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值