• 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, 则可以通过以下方式设置虚拟机内存寻址大小

    1. dev_fd= open("/dev/kvm");
    2. 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 索引太大,无法放入用户指定的数组中。
    1. struct kvm_msr_list {
    2. __u32 nmsrs; /* number of msrs in entries */
    3. __u32 indices[0];
    4. };

    用户在 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 以避免填充问题)

    1. /* for KVM_GET_DIRTY_LOG */
    2. struct kvm_dirty_log {
    3. __u32 slot;
    4. __u32 padding;
    5. union {
    6. void __user *dirty_bitmap; /* one bit per page */
    7. __u64 padding;
    8. };
    9. };

    如果 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.

    1. /* x86 */
    2. struct kvm_regs {
    3. /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
    4. __u64 rax, rbx, rcx, rdx;
    5. __u64 rsi, rdi, rsp, rbp;
    6. __u64 r8, r9, r10, r11;
    7. __u64 r12, r13, r14, r15;
    8. __u64 rip, rflags;
    9. };
    10. /* mips */
    11. struct kvm_regs {
    12. /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
    13. __u64 gpr[32];
    14. __u64 hi;
    15. __u64 lo;
    16. __u64 pc;
    17. };

    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

  • 相关阅读:
    Jmetersphere性能压测执行过程
    RHCSA 03 - 文件的基础权限
    nginx vue2+webpack 和 vue3+vite 配置二级目录访问
    【计算机毕业设计】基于HTML+CSS+JavaScript学生宿舍管理系统
    Python 多进程和多线程【彻底搞懂篇】
    Biotinyl-εAhx-Amyloid β-Protein (1-42),CAS: 1872440-40-8
    高压电气系统验证
    带你手撕八大排序
    cms之帝国cms安装
    三年经验前端vue面试记录
  • 原文地址:https://blog.csdn.net/lingshengxiyou/article/details/127987076