google翻译,部分人工修改

最终KVM(基于内核的虚拟机)API文档
===================================================================

1.一般说明
----------------------

kvm API是一组ioctl,用于控制虚拟机的各个方面。 ioctls接口有三大类:

-  System ioctls:这些查询和设置影响整个kvm子系统的全局属性。此外,系统ioctl用于创建虚拟机。

-  VM ioctls:这些查询和设置属性会影响整个虚拟机器,例如内存布局。此外,VM ioctl用于创建虚拟cpu(vcpus)和设备。

必须从用于创建VM的相同进程(地址空间)发出VM ioctl。

-  vcpu ioctls:这些查询和设置属性,用于控制单个虚拟cpu的操作。

vcpu ioctls应该从用于创建vcpu的同一个线程发出,除了在文档中标记为的异步vcpu ioctl。
    否则,切换线程后的第一个ioctl可能会对性能产生影响。

-  device ioctls:这些查询和设置属性,用于控制单个设备的操作。

必须从用于创建VM的同一进程(地址空间)发出设备ioctl。

2.文件描述符
-------------------

kvm API以文件描述符为中心。 
初始打开(“/ dev / kvm”)获取kvm子系统的句柄; 此句柄可用于发出系统ioctl。 
此句柄上的KVM_CREATE_VM ioctl将创建一个VM文件描述符,可用于发出VM ioctl.
VM fd上的KVM_CREATE_VCPU或KVM_CREATE_DEVICE ioctl将创建虚拟cpu或设备,并返回指向新资源的文件描述符。 
最后,vcpu或设备fd上的ioctls可用于控制vcpu或设备。 对于vcpus,这包括实际运行guest代码的重要任务。

通常,文件描述符可以通过fork()和unix域套接字的SCM_RIGHTS工具在进程之间迁移。kvm明确不支持这些技巧。 
虽然它们不会对主机造成伤害,但API无法保证它们的实际行为。有关KVM支持的ioctl使用模型的详细信息,请参阅“常规说明”。

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

因为在释放对其文件描述符的最后一次引用之前不会释放VM的资源,所以强烈建议不要通过fork(),dup()等创建对VM的
其他引用。若不经过仔细考虑,可能会产生不必要的副作。例如,当VM关闭时,由VM的进程分配的内存可能无法释放/解除。

3.扩展
-------------

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

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

4. API描述
------------------

本节介绍可用于控制kvm guest虚拟机的ioctl。对于每个ioctl,提供以下信息以及描述:

功能:哪个KVM扩展提供此ioctl。可以是“基本的”,
      这意味着任何支持的内核都将提供
      API版本12(参见4.1节),一个KVM_CAP_xyz常量,其中
      表示需要使用KVM_CHECK_EXTENSION检查可用性
      (参见4.4节)或'none'表示虽然不是所有内核
      支持这个ioctl,没有能力来检查它的可用性:对于不支持ioctl的内核,ioctl返回-ENOTTY。

架构:哪些指令集架构提供此ioctl。
      x86包括i386和x86_64。

键入:system,vm或vcpu。

参数:ioctl接受的参数。

返回:返回值。一般错误编号(EBADF,ENOMEM,EINVAL)不详细,但具有特定含义。

4.1 KVM_GET_API_VERSION

能力:基本
架构:全部
输入:system ioctl
参数:无
返回:常量KVM_API_VERSION(= 12)

这将API版本标识为稳定的kvm API。 预计这个数字不会改变。 但是,Linux 2.6.20和2.6.21报告了早期版本; 
这些没有记录,也不受支持。 如果KVM_GET_API_VERSION返回12以外的值,应用程序应拒绝运行。
如果此检查通过,则所有描述为“基本”的ioctl都将可用。

4.2 KVM_CREATE_VM

能力:基本
架构:全部
输入:system ioctl
参数:机器类型标识符(KVM_VM_ *)
返回:可用于控制新虚拟机的VM fd。

新VM没有虚拟cpu,也没有内存。
您可能希望使用0作为计算机类型。

要在S390上创建用户控制的虚拟机,请检查
KVM_CAP_S390_UCONTROL并使用标志KVM_VM_S390_UCONTROL作为特权用户(CAP_SYS_ADMIN)。

在MIPS(VZ ASE)上使用硬件辅助虚拟化而不是使用默认陷阱和模拟实现(更改虚拟内存布局以适应用户模式),
检查KVM_CAP_MIPS_VZ并使用标志KVM_VM_MIPS_VZ。

在arm64上,VM的物理地址大小(IPA大小限制)是有限的,默认为40位。
如果主机支持扩展KVM_CAP_ARM_VM_IPA_SIZE,则可以配置限制。如果支持,请使用
KVM_VM_TYPE_ARM_IPA_SIZE(IPA_Bits)用于设置机器类型标识符的大小,其中IPA_Bits是VM使用的任何物理地址的最大宽度。
IPA_Bits以机器类型标识符的位[7-0]编码。

例如,要将guest虚拟机配置为使用48位物理地址大小:

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

请求的大小(IPA_Bits)必须是:
  0  - 表示默认大小,40位(为了向后兼容)

要么

N  - 表示N位,其中N是正整数,
      32 <= N <= Host_IPA_Limit

Host_IPA_Limit是主机上IPA_Bits的最大可能值,取决于CPU功能和内核配置。
可以在运行时使用KVM_CHECK_EXTENSION ioctl()的KVM_CAP_ARM_VM_IPA_SIZE检索限制。

请注意,配置IPA大小不会影响客户CPU在ID_AA64MMFR0_EL1 [PARange]中公开的功能。
它仅影响stage2级别转换的地址大小(guest虚拟机物理到主机物理地址转换)。

4.5 KVM_GET_VCPU_MMAP_SIZE

能力:基本
架构:全部
输入:system ioctl
参数:无
返回:vcpu mmap区域的大小,以字节为单位

KVM_RUN ioctl(cf.)通过共享与用户空间通信内存区域。 此ioctl返回该区域的大小。 
有关详细信息请参阅KVM_RUN文档。

4.7 KVM_CREATE_VCPU

能力:基本
架构:全部
键入:vm ioctl
参数:vcpu id(x86上的apic id)
返回:成功时vcpu fd,错误时返回-1

此API将vcpu添加到虚拟机。不能超过max_vcpus。
vcpu id是[0,max_vcpu_id]范围内的整数。

可以在运行时使用KVM_CHECK_EXTENSION ioctl()的KVM_CAP_NR_VCPUS检索建议的max_vcpus值。
可以使用运行时KVM_CHECK_EXTENSION ioctl()的KVM_CAP_MAX_VCPUS检索max_vcpus的最大可能值。

如果KVM_CAP_NR_VCPUS不存在,则应假设max_vcpus最大为4 cpus。
如果KVM_CAP_MAX_VCPUS不存在,则应假设max_vcpus与从KVM_CAP_NR_VCPUS返回的值相同。

可以使用运行时KVM_CHECK_EXTENSION ioctl()的KVM_CAP_MAX_VCPU_ID检索max_vcpu_id的最大可能值。

如果KVM_CAP_MAX_VCPU_ID不存在,则应假设max_vcpu_id与从KVM_CAP_MAX_VCPUS返回的值相同。

在使用book3s_hv模式的powerpc上,vcpus映射到一个或多个虚拟CPU核心中的虚拟线程上。 (这是因为
硬件要求CPU核心中的所有硬件线程都在相同的分区。)KVM_CAP_PPC_SMT功能表示每个虚拟核心(vcore)的vcpus数。 
vcore id由。获得将vcpu id除以每个vcore的vcpus数。给定vcore中的vcpus将始终与彼此处于相同的物理核心中
(虽然这可能是不时的不同物理核心)。
用户空间可以通过它控制guest的线程(SMT)模式vcpu id的分配。例如,如果用户空间需要单线程guest虚拟机vcpus,
则应使所有vcpu ID为每个vcore的vcpus数量的倍数。

对于使用S390用户控制的虚拟机创建的虚拟cpu,生成的vcpu fd可以在页面偏移量KVM_S390_SIE_PAGE_OFFSET处进行
内存映射,以获取虚拟cpu的硬件控制块的内存映射。

4.10 KVM_RUN

能力:基本
架构:全部
键入:vcpu ioctl
参数:无
返回:成功时返回0,错误时返回-1
错误:
   EINTR:未屏蔽的信号正在等待处理

此ioctl用于运行guest虚拟CPU。 虽然没有显式参数,但是有一个隐式参数块可以通过mmap()在偏移0处的vcpu fd获得,
其大小由KVM_GET_VCPU_MMAP_SIZE给出。 参数块的格式为'struct kvm_run'(见下文)。

4.11 KVM_GET_REGS

能力:基本
架构:除ARM,arm64之外的所有架构
键入:vcpu ioctl
参数:struct kvm_regs(out)
返回:成功时返回0,错误时返回-1

从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

能力:基本
架构:除ARM,arm64之外的所有架构
键入:vcpu ioctl
参数:struct kvm_regs(in)
返回:成功时返回0,错误时返回-1

将通用寄存器写入vcpu。

有关数据结构,请参阅KVM_GET_REGS。

4.13 KVM_GET_SREGS

能力:基本
架构:x86,ppc
键入:vcpu ioctl
参数:struct kvm_sregs(out)
返回:成功时返回0,错误时返回-1

从vcpu中读取特殊寄存器。

/* x86 */
struct kvm_sregs {
    struct kvm_segment cs, ds, es, fs, gs, ss;
    struct kvm_segment tr, ldt;
    struct kvm_dtable gdt, idt;
    __u64 cr0, cr2, cr3, cr4, cr8;
    __u64 efer;
    __u64 apic_base;
    __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
};

/ * ppc  - 参见arch / powerpc / include / uapi / asm / kvm.h * /

interrupt_bitmap是挂起的外部中断的位图。 最多可以设置一位。 该中断已被APIC确认,但尚未注入cpu核心。

4.14 KVM_SET_SREGS

能力:基本
架构:x86,ppc
键入:vcpu ioctl
参数:struct kvm_sregs(in)
返回:成功时返回0,错误时返回-1

将特殊寄存器写入vcpu。 请参阅KVM_GET_SREGS数据结构。

4.35 KVM_SET_USER_MEMORY_REGION

能力:KVM_CAP_USER_MEM
架构:全部
键入:vm ioctl
参数:struct kvm_userspace_memory_region(in)
返回:成功时返回0,错误时返回-1

struct kvm_userspace_memory_region {
    __u32 slot;
    __u32 flags;
    __u64 guest_phys_addr;
    __u64 memory_size; /* bytes */
    __u64 userspace_addr; /* start of the userspace allocated memory */
};

/* for kvm_memory_region::flags */
#define KVM_MEM_LOG_DIRTY_PAGES    (1UL << 0)
#define KVM_MEM_READONLY    (1UL << 1)

此ioctl允许用户创建,修改或删除客户物理内存插槽。 “slot”的第0-15位指定插槽ID,
该值应小于每个VM支持的最大用户内存插槽数。如果架构支持此功能,则可以使用KVM_CAP_NR_MEMSLOTS
查询允许的最大插槽数。插槽可能在客户物理地址空间中不重叠。

如果KVM_CAP_MULTI_ADDRESS_SPACE可用,则“slot”的第16-31位,指定要修改的地址空间。
它们必须小于KVM_CHECK_EXTENSION为KVM_CAP_MULTI_ADDRESS_SPACE功能返回的值。
不同地址空间中的插槽是不相关的;对重叠槽的限制仅适用于每个地址空间。

删除槽是通过为memory_size传递零来完成的。更改现有插槽时,可以在客户机物理内存空间中移动它,
或者可以修改其标志,但可能不会调整其大小。

该区域的存储器从字段userspace_addr表示的地址开始,该字段必须指向整个存储器插槽大小的用户可寻址存储器。 
任何对象都可以支持此内存,包括匿名内存,普通文件和hugetlbfs。

建议guest_phys_addr和userspace_addr的低21位相同。这允许guest虚拟机中的大页面由主机中的大页面支持。

flags字段支持两个标志:KVM_MEM_LOG_DIRTY_PAGES和KVM_MEM_READONLY。前者可以设置为指示KVM跟踪插槽内存的写入。
请参阅KVM_GET_DIRTY_LOG ioctl以了解如何使用它。如果KVM_CAP_READONLY_MEM功能允许,后者可以设置为只读新插槽。
在这种情况下,当KVM_EXIT_MMIO退出时,对此内存的写入将发布到用户空间。

当KVM_CAP_SYNC_MMU功能可用时,内存区域支持的更改将自动反映到guest虚拟机中。例如,影响该区域的mmap()
将立即可见。另一个例子是madvise(MAD​​V_DROP)。

建议使用此API而不是KVM_SET_MEMORY_REGION ioctl。 KVM_SET_MEMORY_REGION不允许对内存分配进行细粒度控制,
因此不推荐使用。

//******************************************************** FIXME!
4.36

4.68 KVM_SET_ONE_REG

能力:KVM_CAP_ONE_REG
架构:全部
键入:vcpu ioctl
参数:struct kvm_one_reg(in)
返回:成功时为0,失败时为负值

struct kvm_one_reg {
       __u64 id;
       __u64 addr;
};

使用此ioctl,可以将单个vcpu寄存器设置为特定值
由用户空间定义的传入结构kvm_one_reg,其中id指的是如下所述的寄存器标识符,addr是指向具有相应大小的变量的
指针。可以存在体系结构不可知和体系结构特定的寄存器。每个都有自己的操作范围和自己的常量和宽度。
要跟踪已实现的寄存器,请在下面找到一个列表:

Arch  |           Register            | Width (bits)
        | |
  PPC   | KVM_REG_PPC_HIOR              | 64
  PPC   | KVM_REG_PPC_IAC1              | 64
  PPC   | KVM_REG_PPC_IAC2              | 64
  PPC   | KVM_REG_PPC_IAC3              | 64
  PPC   | KVM_REG_PPC_IAC4              | 64
  PPC   | KVM_REG_PPC_DAC1              | 64
  PPC   | KVM_REG_PPC_DAC2              | 64
  PPC   | KVM_REG_PPC_DABR              | 64
  PPC   | KVM_REG_PPC_DSCR              | 64
  PPC   | KVM_REG_PPC_PURR              | 64
  PPC   | KVM_REG_PPC_SPURR             | 64
  PPC   | KVM_REG_PPC_DAR               | 64
  PPC   | KVM_REG_PPC_DSISR             | 32
  PPC   | KVM_REG_PPC_AMR               | 64
  PPC   | KVM_REG_PPC_UAMOR             | 64
  PPC   | KVM_REG_PPC_MMCR0             | 64
  PPC   | KVM_REG_PPC_MMCR1             | 64
  PPC   | KVM_REG_PPC_MMCRA             | 64
  PPC   | KVM_REG_PPC_MMCR2             | 64
  PPC   | KVM_REG_PPC_MMCRS             | 64
  PPC   | KVM_REG_PPC_SIAR              | 64
  PPC   | KVM_REG_PPC_SDAR              | 64
  PPC   | KVM_REG_PPC_SIER              | 64
  PPC   | KVM_REG_PPC_PMC1              | 32
  PPC   | KVM_REG_PPC_PMC2              | 32
  PPC   | KVM_REG_PPC_PMC3              | 32
  PPC   | KVM_REG_PPC_PMC4              | 32
  PPC   | KVM_REG_PPC_PMC5              | 32
  PPC   | KVM_REG_PPC_PMC6              | 32
  PPC   | KVM_REG_PPC_PMC7              | 32
  PPC   | KVM_REG_PPC_PMC8              | 32
  PPC   | KVM_REG_PPC_FPR0              | 64
          ...
  PPC   | KVM_REG_PPC_FPR31             | 64
  PPC   | KVM_REG_PPC_VR0               | 128
          ...
  PPC   | KVM_REG_PPC_VR31              | 128
  PPC   | KVM_REG_PPC_VSR0              | 128
          ...
  PPC   | KVM_REG_PPC_VSR31             | 128
  PPC   | KVM_REG_PPC_FPSCR             | 64
  PPC   | KVM_REG_PPC_VSCR              | 32
  PPC   | KVM_REG_PPC_VPA_ADDR          | 64
  PPC   | KVM_REG_PPC_VPA_SLB           | 128
  PPC   | KVM_REG_PPC_VPA_DTL           | 128
  PPC   | KVM_REG_PPC_EPCR              | 32
  PPC   | KVM_REG_PPC_EPR               | 32
  PPC   | KVM_REG_PPC_TCR               | 32
  PPC   | KVM_REG_PPC_TSR               | 32
  PPC   | KVM_REG_PPC_OR_TSR            | 32
  PPC   | KVM_REG_PPC_CLEAR_TSR         | 32
  PPC   | KVM_REG_PPC_MAS0              | 32
  PPC   | KVM_REG_PPC_MAS1              | 32
  PPC   | KVM_REG_PPC_MAS2              | 64
  PPC   | KVM_REG_PPC_MAS7_3            | 64
  PPC   | KVM_REG_PPC_MAS4              | 32
  PPC   | KVM_REG_PPC_MAS6              | 32
  PPC   | KVM_REG_PPC_MMUCFG            | 32
  PPC   | KVM_REG_PPC_TLB0CFG           | 32
  PPC   | KVM_REG_PPC_TLB1CFG           | 32
  PPC   | KVM_REG_PPC_TLB2CFG           | 32
  PPC   | KVM_REG_PPC_TLB3CFG           | 32
  PPC   | KVM_REG_PPC_TLB0PS            | 32
  PPC   | KVM_REG_PPC_TLB1PS            | 32
  PPC   | KVM_REG_PPC_TLB2PS            | 32
  PPC   | KVM_REG_PPC_TLB3PS            | 32
  PPC   | KVM_REG_PPC_EPTCFG            | 32
  PPC   | KVM_REG_PPC_ICP_STATE         | 64
  PPC   | KVM_REG_PPC_TB_OFFSET         | 64
  PPC   | KVM_REG_PPC_SPMC1             | 32
  PPC   | KVM_REG_PPC_SPMC2             | 32
  PPC   | KVM_REG_PPC_IAMR              | 64
  PPC   | KVM_REG_PPC_TFHAR             | 64
  PPC   | KVM_REG_PPC_TFIAR             | 64
  PPC   | KVM_REG_PPC_TEXASR            | 64
  PPC   | KVM_REG_PPC_FSCR              | 64
  PPC   | KVM_REG_PPC_PSPB              | 32
  PPC   | KVM_REG_PPC_EBBHR             | 64
  PPC   | KVM_REG_PPC_EBBRR             | 64
  PPC   | KVM_REG_PPC_BESCR             | 64
  PPC   | KVM_REG_PPC_TAR               | 64
  PPC   | KVM_REG_PPC_DPDES             | 64
  PPC   | KVM_REG_PPC_DAWR              | 64
  PPC   | KVM_REG_PPC_DAWRX             | 64
  PPC   | KVM_REG_PPC_CIABR             | 64
  PPC   | KVM_REG_PPC_IC                | 64
  PPC   | KVM_REG_PPC_VTB               | 64
  PPC   | KVM_REG_PPC_CSIGR             | 64
  PPC   | KVM_REG_PPC_TACR              | 64
  PPC   | KVM_REG_PPC_TCSCR             | 64
  PPC   | KVM_REG_PPC_PID               | 64
  PPC   | KVM_REG_PPC_ACOP              | 64
  PPC   | KVM_REG_PPC_VRSAVE            | 32
  PPC   | KVM_REG_PPC_LPCR              | 32
  PPC   | KVM_REG_PPC_LPCR_64           | 64
  PPC   | KVM_REG_PPC_PPR               | 64
  PPC   | KVM_REG_PPC_ARCH_COMPAT       | 32
  PPC   | KVM_REG_PPC_DABRX             | 32
  PPC   | KVM_REG_PPC_WORT              | 64
  PPC    | KVM_REG_PPC_SPRG9             | 64
  PPC    | KVM_REG_PPC_DBSR              | 32
  PPC   | KVM_REG_PPC_TM_GPR0           | 64
          ...
  PPC   | KVM_REG_PPC_TM_GPR31          | 64
  PPC   | KVM_REG_PPC_TM_VSR0           | 128
          ...
  PPC   | KVM_REG_PPC_TM_VSR63          | 128
  PPC   | KVM_REG_PPC_TM_CR             | 64
  PPC   | KVM_REG_PPC_TM_LR             | 64
  PPC   | KVM_REG_PPC_TM_CTR            | 64
  PPC   | KVM_REG_PPC_TM_FPSCR          | 64
  PPC   | KVM_REG_PPC_TM_AMR            | 64
  PPC   | KVM_REG_PPC_TM_PPR            | 64
  PPC   | KVM_REG_PPC_TM_VRSAVE         | 64
  PPC   | KVM_REG_PPC_TM_VSCR           | 32
  PPC   | KVM_REG_PPC_TM_DSCR           | 64
  PPC   | KVM_REG_PPC_TM_TAR            | 64
  PPC   | KVM_REG_PPC_TM_XER            | 64
        |                               |
  MIPS  | KVM_REG_MIPS_R0               | 64
          ...
  MIPS  | KVM_REG_MIPS_R31              | 64
  MIPS  | KVM_REG_MIPS_HI               | 64
  MIPS  | KVM_REG_MIPS_LO               | 64
  MIPS  | KVM_REG_MIPS_PC               | 64
  MIPS  | KVM_REG_MIPS_CP0_INDEX        | 32
  MIPS  | KVM_REG_MIPS_CP0_CONTEXT      | 64
  MIPS  | KVM_REG_MIPS_CP0_USERLOCAL    | 64
  MIPS  | KVM_REG_MIPS_CP0_PAGEMASK     | 32
  MIPS  | KVM_REG_MIPS_CP0_WIRED        | 32
  MIPS  | KVM_REG_MIPS_CP0_HWRENA       | 32
  MIPS  | KVM_REG_MIPS_CP0_BADVADDR     | 64
  MIPS  | KVM_REG_MIPS_CP0_COUNT        | 32
  MIPS  | KVM_REG_MIPS_CP0_ENTRYHI      | 64
  MIPS  | KVM_REG_MIPS_CP0_COMPARE      | 32
  MIPS  | KVM_REG_MIPS_CP0_STATUS       | 32
  MIPS  | KVM_REG_MIPS_CP0_CAUSE        | 32
  MIPS  | KVM_REG_MIPS_CP0_EPC          | 64
  MIPS  | KVM_REG_MIPS_CP0_PRID         | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG       | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG1      | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG2      | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG3      | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG4      | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG5      | 32
  MIPS  | KVM_REG_MIPS_CP0_CONFIG7      | 32
  MIPS  | KVM_REG_MIPS_CP0_ERROREPC     | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH1    | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH2    | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH3    | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH4    | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH5    | 64
  MIPS  | KVM_REG_MIPS_CP0_KSCRATCH6    | 64
  MIPS  | KVM_REG_MIPS_COUNT_CTL        | 64
  MIPS  | KVM_REG_MIPS_COUNT_RESUME     | 64
  MIPS  | KVM_REG_MIPS_COUNT_HZ         | 64
  MIPS  | KVM_REG_MIPS_FPR_32(0..31)    | 32
  MIPS  | KVM_REG_MIPS_FPR_64(0..31)    | 64
  MIPS  | KVM_REG_MIPS_VEC_128(0..31)   | 128
  MIPS  | KVM_REG_MIPS_FCR_IR           | 32
  MIPS  | KVM_REG_MIPS_FCR_CSR          | 32
  MIPS  | KVM_REG_MIPS_MSA_IR           | 32
  MIPS  | KVM_REG_MIPS_MSA_CSR          | 32

ARM寄存器使用低32位映射。上面的16个
是寄存器组类型,或协处理器编号:

ARM内核寄存器具有以下id位模式:
  0x4020 0000 0010 <索引到kvm_regs结构:16>

ARM 32位CP15寄存器具有以下id位模式:
  0x4020 0000 000F <零:1> <crn:4> <crm:4> <opc1:4> <opc2:3>

ARM 64位CP15寄存器具有以下id位模式:
  0x4030 0000 000F <零:1> <零:4> <crm:4> <opc1:4> <零:3>

ARM CCSIDR寄存器由CSSELR值解复用:
  0x4020 0000 0011 00 <csselr:8>

ARM 32位VFP控制寄存器具有以下id位模式:
  0x4020 0000 0012 1 <regno:12>

ARM 64位FP寄存器具有以下id位模式:
  0x4030 0000 0012 0 <regno:12>

arm64寄存器使用低32位映射。上面的16
这是寄存器组类型或协处理器号:

arm64内核/ FP-SIMD寄存器具有以下id位模式。请注意,访问的大小是可变的,因为kvm_regs结构包含32到128位的元素。
该索引是kvm_regs结构中的32位值,被视为32位数组。
  0x60x0 0000 0010 <进入kvm_regs结构的索引:16>

arm64 CCSIDR寄存器由CSSELR值解复用:
  0x6020 0000 0011 00 <csselr:8>

arm64系统寄存器具有以下id位模式:
  0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>

MIPS寄存器使用低32位映射。其中的16位是寄存器组类型:

MIPS核心寄存器(见上文)具有以下id位模式:
  0x7030 0000 0000 <reg:16>

MIPS CP0寄存器(参见上面的KVM_REG_MIPS_CP0_ *)具有以下id位模式,具体取决于它们是32位寄存器还是64位寄存器:
  0x7020 0000 0001 00 <reg:5> <sel:3>(32位)
  0x7030 0000 0001 00 <reg:5> <sel:3>(64位)

MIPS KVM控制寄存器(见上文)具有以下id位模式:
  0x7030 0000 0002 <reg:16>

MIPS FPU寄存器(参见上面的KVM_REG_MIPS_FPR_ {32,64}())具有以下id位模式,具体取决于所访问的寄存器的大小。
它们总是根据当前的访客FPU模式(Status.FR和Config5.FRE)访问,即当访客看到它们时,如果访客FPU模式被更改,
它们将变得不可预测。 MIPS SIMD架构(MSA)向量寄存器(参见上面的KVM_REG_MIPS_VEC_128())具有类似的模式
重叠FPU寄存器:
  0x7020 0000 0003 00 <0:3> <reg:5>(32位FPU寄存器)
  0x7030 0000 0003 00 <0:3> <reg:5>(64位FPU寄存器)
  0x7040 0000 0003 00 <0:3> <reg:5>(128位MSA向量寄存器)

MIPS FPU控制寄存器(参见上面的KVM_REG_MIPS_FCR_ {IR,CSR})具有以下id位模式:
  0x7020 0000 0003 01 <0:3> <reg:5>

MIPS MSA控制寄存器(参见上面的KVM_REG_MIPS_MSA_ {IR,CSR})具有以下id位模式:
  0x7020 0000 0003 02 <0:3> <reg:5>

4.69 KVM_GET_ONE_REG

能力:KVM_CAP_ONE_REG
架构:全部
键入:vcpu ioctl
参数:struct kvm_one_reg(in和out)
返回:成功时为0,失败时为负值

该ioctl允许接收实现的单个寄存器的值
在vcpu中。 要读取的寄存器由传入的kvm_one_reg结构的“id”字段指示。成功时,寄存器值可以在“addr”指向的存储器位置找到。

使用此接口可访问的寄存器列表与
在4.68中列出。

4.70 /*************************************************************/FIXME!!!!

4.82 KVM_ARM_VCPU_INIT

能力:基本
架构:arm,arm64
键入:vcpu ioctl
参数:struct kvm_vcpu_init(in)
成功时返回:0; -1错误
错误:
 EINVAL:目标未知,或者功能组合无效。
 ENOENT:指定的功能位未知。

这告诉KVM向guest虚拟机提供什么类型的CPU,以及它应具有哪些可选功能。这将导致cpu寄存器重置为其初始值。
如果未调用此方法,KVM_RUN将返回该vcpu的ENOEXEC。

请注意,由于某些寄存器反映了机器拓扑,因此应在调用此ioctl之前创建所有vcpus。

对于给定的vcpu,用户空间可以多次调用此函数,包括在运行vcpu之后。这会将vcpu重置为其初始状态。
初始调用后对此函数的所有调用必须使用相同的目标和相同的功能标志集,否则将返回EINVAL。

可能的功能:
 -  KVM_ARM_VCPU_POWER_OFF:启动CPU处于断电状态。
取决于KVM_CAP_ARM_PSCI。如果未设置,则在调用KVM_RUN时,CPU将打开电源并执行访客代码。
 -  KVM_ARM_VCPU_EL1_32BIT:以32位模式启动CPU。
取决于KVM_CAP_ARM_EL1_32BIT(仅限arm64)。
 -  KVM_ARM_VCPU_PSCI_0_2:为CPU模拟PSCI v0.2。
取决于KVM_CAP_ARM_PSCI_0_2。
 -  KVM_ARM_VCPU_PMU_V3:模拟CPU的PMUv3。
取决于KVM_CAP_ARM_PMU_V3。

4.83 KVM_ARM_PREFERRED_TARGET

能力:基本
架构:arm,arm64
键入:vm ioctl
参数:struct struct kvm_vcpu_init(out)
成功时返回:0; -1错误
错误:
   ENODEV:没有可用于主机的首选目标

这将查询KVM以获取首选CPU目标类型,该类型可由底层主机上的KVM模拟。

ioctl返回struct kvm_vcpu_init实例,其中包含有关首选CPU目标类型和推荐功能的信息。 
如果首选目标建议设置这些功能,则返回的kvm_vcpu_init-> feature位图将设置功能位,但这是
不是强制性的。

此ioctl返回的信息可用于为KVM_ARM_VCPU_INIT ioctl准备struct kvm_vcpu_init的实例,
这将导致VCPU匹配底层主机。

4.118  //******************************************************** FIXME!

5. kvm_run结构
------------------------

应用程序代码通过mmap()获取vcpu fd来得到获取指向kvm_run结构的指针。 从那时起,应用程序代码可以通过
在调用KVM_RUN ioctl之前更改kvm_run中的字段来控制执行,并通过查找结构成员获取有关KVM_RUN返回原因的信息。

struct kvm_run {
    / * in * /
    __u8 request_interrupt_window;

请求KVM_RUN在可以将外部中断注入guest虚拟机时返回。与KVM_INTERRUPT结合使用。

__u8 immediate_exit;

当KVM_RUN启动时,该字段被轮询一次;如果非零,则KVM_RUN立即退出,返回-EINTR。
在使用信号从KVM_RUN中“踢出”VCPU的常见情况下,此字段可用于避免使用KVM_SET_SIGNAL_MASK,后者具有更差的可伸缩性。
用户空间可以设置一个信号处理程序,将run-> immediate_exit设置为非零值,而不是阻止KVM_RUN外部的信号。
如果KVM_CAP_IMMEDIATE_EXIT不可用,则忽略此字段。

__u8 padding1 [6];

/ * out * /
    __u32 exit_reason;

当KVM_RUN成功返回(返回值0)时,这将通知应用程序代码KVM_RUN返回的原因。该字段的允许值详述如下。

__u8 ready_for_interrupt_injection;

如果已指定request_interrupt_window,则此字段指示
现在可以使用KVM_INTERRUPT注入中断。

__u8 if_flag;

当前中断标志的值。仅在内核中有效
不使用本地APIC。

__u16 flags;

更多特定于体系结构的标志,详细说明可能的VCPU状态
影响设备的行为。唯一当前定义的标志是
KVM_RUN_X86_SMM,在x86机器上有效,如果是,则设置为
VCPU处于系统管理模式。

/ * in(pre_kvm_run),out(post_kvm_run)* /
    __u64 cr8;

cr8寄存器的值。仅在内核本地APIC中有效
不曾用过。输入和输出。

__u64 apic_base;

APIC BASE msr的值。仅在内核本地时有效
不使用API​​C。输入和输出。

union {
        /* KVM_EXIT_UNKNOWN */
        struct {
            __u64 hardware_exit_reason;
        } hw;

如果exit_reason是KVM_EXIT_UNKNOWN,则vcpu由于未知而退出
原因。可以使用其他特定于体系结构的信息
hardware_exit_reason。

/* KVM_EXIT_FAIL_ENTRY */
        struct {
            __u64 hardware_entry_failure_reason;
        } fail_entry;

如果exit_reason是KVM_EXIT_FAIL_ENTRY,则由于未知原因无法运行vcpu。进一步的架构特定信息是
可在hardware_entry_failure_reason中找到。

/* KVM_EXIT_EXCEPTION */
        struct {
            __u32 exception;
            __u32 error_code;
        } ex;

没用过。

/* KVM_EXIT_IO */
        struct {
#define KVM_EXIT_IO_IN  0
#define KVM_EXIT_IO_OUT 1
            __u8 direction;
            __u8 size; /* bytes */
            __u16 port;
            __u32 count;
            __u64 data_offset; /* relative to kvm_run start */
        } io;

如果exit_reason是KVM_EXIT_IO,则vcpu有
执行了kvm无法满足的端口I / O指令。
data_offset描述数据的位置(KVM_EXIT_IO_OUT)或kvm期望应用程序代码为下一个数据放置数据的位置
KVM_RUN调用(KVM_EXIT_IO_IN)。数据格式是打包数组。

/* KVM_EXIT_DEBUG */
        struct {
            struct kvm_debug_exit_arch arch;
        } debug;

如果exit_reason是KVM_EXIT_DEBUG,则vcpu正在处理返回体系结构特定信息的调试事件。

/* KVM_EXIT_MMIO */
        struct {
            __u64 phys_addr;
            __u8  data[8];
            __u32 len;
            __u8  is_write;
        } mmio;

如果exit_reason是KVM_EXIT_MMIO,则vcpu有
执行了kvm无法满足的内存映射I / O指令。如果'is_write'为真,'data'成员包含写入的数据,否则应由应用程序代码填充。

'data'成员在其第一个'len'字节中包含值
如果VCPU直接对字节数组执行适当宽度的加载或存储,则会出现。

注意:对于KVM_EXIT_IO,KVM_EXIT_MMIO,KVM_EXIT_OSI,KVM_EXIT_PAPR和KVM_EXIT_EPR,
只有在用户空间使用KVM_RUN重新进入内核后,相应的操作才会完成(并且访客状态是一致的)。
内核端将首先完成不完整的操作,然后检查待处理的信号。用户空间可以使用未屏蔽的信号重新进入guest虚拟机,
以完成挂起的操作。

/* KVM_EXIT_HYPERCALL */
        struct {
            __u64 nr;
            __u64 args[6];
            __u64 ret;
            __u32 longmode;
            __u32 pad;
        } hypercall;

没用过。这曾经被用于'用户空间的超级呼叫'。要实现此类功能,请使用KVM_EXIT_IO(x86)或KVM_EXIT_MMIO(除s390外)。
注意KVM_EXIT_IO明显快于KVM_EXIT_MMIO。

/* KVM_EXIT_TPR_ACCESS */
        struct {
            __u64 rip;
            __u32 is_write;
            __u32 pad;
        } tpr_access;

记录(KVM_TPR_ACCESS_REPORTING)。

/* KVM_EXIT_S390_SIEIC */
        struct {
            __u8 icptcode;
            __u64 mask; /* psw upper half */
            __u64 addr; /* psw lower half */
            __u16 ipa;
            __u32 ipb;
        } s390_sieic;

s390 specific.

/* KVM_EXIT_S390_RESET */
#define KVM_S390_RESET_POR       1
#define KVM_S390_RESET_CLEAR     2
#define KVM_S390_RESET_SUBSYSTEM 4
#define KVM_S390_RESET_CPU_INIT  8
#define KVM_S390_RESET_IPL       16
        __u64 s390_reset_flags;

s390 specific.

/* KVM_EXIT_S390_UCONTROL */
        struct {
            __u64 trans_exc_code;
            __u32 pgm_code;
        } s390_ucontrol;

s390具体。用户控制的虚拟页面发生了页面错误
机器(KVM_VM_S390_UNCONTROL)在它的主机页面表上,内核无法解析。
放置在cpu低位中的程序代码和转换异常代码在此处由动态地址转换章节中的
z Architecture Principles of Operation Book定义。
(DAT)

/* KVM_EXIT_DCR */
        struct {
            __u32 dcrn;
            __u32 data;
            __u8  is_write;
        } dcr;

不推荐使用 - 用于440 KVM。

/* KVM_EXIT_OSI */
        struct {
            __u64 gprs[32];
        } osi;

MOL使用一个称为“OSI”的特殊超级调用接口。为了启用它,我们捕获超级调用并使用包含所有guest gprs的退出结构退出。

如果exit_reason是KVM_EXIT_OSI,那么vcpu已经触发了这样的超级调用。
用户空间现在可以处理超级调用,并在完成后根据需要修改gprs。在访客入口后,所有来宾GPR将被此结构中的值替换。

/* KVM_EXIT_PAPR_HCALL */
        struct {
            __u64 nr;
            __u64 ret;
            __u64 args[9];
        } papr_hcall;

这在模拟pSeries分区时用于64位PowerPC,
例如在qemu中使用'pseries'机器类型。它出现的时候
guest使用'sc 1'指令进行超级调用。 'nr'字段
包含超级调用号码(来自来宾R3),'args'包含
参数(来自客人R4  -  R12)。用户空间应该放在
返回'ret'中的代码以及args []中的任何额外返回值。
可能的超级调用在www.power.org提供的Power Architecture Platform Requirements(PAPR)文档中定义
(访问它所需的免费开发人员注册)。

/* KVM_EXIT_S390_TSCH */
        struct {
            __u16 subchannel_id;
            __u16 subchannel_nr;
            __u32 io_int_parm;
            __u32 io_int_word;
            __u32 ipb;
            __u8 dequeued;
        } s390_tsch;

s390具体。当KVM_CAP_S390_CSS_SUPPORT被启用并且截获了TEST SUBCHANNEL时,会发生此退出。
如果设置了出队,则目标子信道的待处理I / O中断已经出列,并且subchannel_id,subchannel_nr,io_int_parm
和io_int_word包含该中断的参数。指令参数解码需要ipb。

/* KVM_EXIT_EPR */
        struct {
            __u32 epr;
        } epr;

在FSL BookE PowerPC芯片上,中断控制器具有快速补丁
中断确认核心路径。当核心成功
发送一个中断,它会自动填充EPR寄存器
中断向量编号并确认内部中断
中断控制器。

如果中断控制器位于用户空间中,我们需要通过它执行中断确认循环,以使用此出口获取下一个要传送的中断向量。

只要KVM_CAP_PPC_EPR都被启用并且外部中断刚刚传送到guest虚拟机,它就会被触发。用户空间应将已确认的中断向量放入“epr”字段。

/* KVM_EXIT_SYSTEM_EVENT */
        struct {
#define KVM_SYSTEM_EVENT_SHUTDOWN       1
#define KVM_SYSTEM_EVENT_RESET          2
#define KVM_SYSTEM_EVENT_CRASH          3
            __u32 type;
            __u64 flags;
        } system_event;

如果exit_reason是KVM_EXIT_SYSTEM_EVENT,则vcpu使用某种体系结构特定机制(超级调用或某些特殊指令)触发了
系统级事件。在ARM / ARM64的情况下,这是使用来自vcpu的基于HVC指令的PSCI调用触发的。 'type'字段描述了
系统级事件类型。 'flags'字段描述了系统级事件的体系结构特定标志。

'type'的有效值为:
  KVM_SYSTEM_EVENT_SHUTDOWN  -  guest虚拟机已请求关闭VM。用户空间没有义务遵守这一点,如果它确实遵守,
则不需要同步销毁VM(即它可能在最终关闭之前再次调用KVM_RUN)。
  KVM_SYSTEM_EVENT_RESET  -  guest虚拟机已请求重置VM。
   与SHUTDOWN一样,用户空间可以选择忽略该请求,或者安排将来重置,并可以再次调用KVM_RUN。
  KVM_SYSTEM_EVENT_CRASH  - 发生客户机崩溃,并且客户机已请求崩溃条件维护。用户空间可以选择忽略该请求,
或者收集VM内存核心转储和/或VM的重置/关闭。

/* KVM_EXIT_IOAPIC_EOI */
        struct {
            __u8 vector;
        } eoi;

表示VCPU的内核本地APIC收到a的EOI
电平触发的IOAPIC中断。这个退出只会触发时
IOAPIC在用户空间中实现(即启用KVM_CAP_SPLIT_IRQCHIP);
用户空间IOAPIC应该处理EOI并重新启动中断(如果它仍然被断言)。 Vector是接收EOI的LAPIC中断向量​​。

struct kvm_hyperv_exit {
#define KVM_EXIT_HYPERV_SYNIC          1
#define KVM_EXIT_HYPERV_HCALL          2
            __u32 type;
            union {
                struct {
                    __u32 msr;
                    __u64 control;
                    __u64 evt_page;
                    __u64 msg_page;
                } synic;
                struct {
                    __u64 input;
                    __u64 result;
                    __u64 params[2];
                } hcall;
            } u;
        };
        /* KVM_EXIT_HYPERV */
                struct kvm_hyperv_exit hyperv;
表示VCPU退出到用户空间以处理某些任务
与Hyper-V仿真有关。
'type'的有效值为:
KVM_EXIT_HYPERV_SYNIC  - 同步通知用户空间有关Hyper-V SynIC状态更改的信息。通知用于重新映射SynIC事件/消息页面
以及启用/禁用用户空间中的SynIC消息/事件处理。

/ *修复联合的大小。 * /
        char padding [256];
};

/ *
* kvm和用户空间之间的共享寄存器。
* kvm_valid_regs指定主机设置的寄存器类
* kvm_dirty_regs指定了用户空间弄脏的寄存器类
* struct kvm_sync_regs是特定于体系结构的,以及
* kvm_valid_regs和kvm_dirty_regs的位
* /
    __u64 kvm_valid_regs;
    __u64 kvm_dirty_regs;
    union {
        struct kvm_sync_regs regs;
        char padding[SYNC_REGS_SIZE_BYTES];
    } s;

如果定义了KVM_CAP_SYNC_REGS,则这些字段允许用户空间访问某些访客寄存器,而无需调用SET / GET_ * REGS。
因此,如果用户空间必须处理退出,我们可以避免一些系统调用开销。
用户空间可以通过检查特定位的kvm_valid_regs来查询结构的有效性。这些位是体系结构特定的
并且通常定义一组寄存器的有效性。 (例如,一位用于通用寄存器)

请注意,允许内核使用kvm_run结构作为某些寄存器类型的主存储器。因此,即使没有设置kvm_dirty_regs中的相应位,
内核也可以使用kvm_run中的值。

};

转载于:https://my.oschina.net/u/3231839/blog/3051905

翻译-linux-5.1.2\Documentation\virtual\kvm\api.txt相关推荐

  1. ubuntu linux下解决“no java virtual machine was found after searching the following locations:”的方法

    ubuntu linux下解决"no java virtual machine was found after searching the following locations:" ...

  2. LWN 翻译:DMA-BUF cache handling: Off the DMA API map (part 1)

    声明:本文非原创,只是翻译! 原文:https://lwn.net/Articles/822052/ 作者:John Stultz ( Linaro 成员,kernel timekeeping mai ...

  3. 使用KVM API实现Emulator Demo

    这边文章来描述如何用KVM API来写一个Virtualizer的demo code, 也就是相当与Qemu,用来做设备模拟. 此文是帮助想了解KVM原理已经Qemu原理的人 or Just for ...

  4. Linux 串口编程三 使用termios与API进行串口程序开发

    在 termios 结构体以及内部终端控制标志中,并非所有的参数对于实际的物理串口都是有效的,在使用过程中也不需要对于所有标志的作用都有所理解.事实上,快速掌握一项技术的核心点也是一种学习能力.对于使 ...

  5. linux调用windows接口,想要打通Windows和Linux的任督二脉,少不了API这层功力

    原标题:想要打通Windows和Linux的任督二脉,少不了API这层功力 每每Windows一更新,都伴随着一波又一波的高潮,从界面UI到系统布局,再到各种新功能的加入,每个版本的Windows或多 ...

  6. LWN 翻译:DMA-BUF cache handling: Off the DMA API map (part 2)

    声明:本文非原创,只是翻译! 原文:https://lwn.net/Articles/822521/ 作者:John Stultz ( Linaro 成员,kernel timekeeping mai ...

  7. linux为已有磁盘扩容 kvm,KVM虚拟磁盘扩容

    KVM虚拟磁盘扩容 1.磁盘扩容分为raw和qcow2两种扩容方式,命令相同,区别是后缀名 [root@daixuan ~]# qemu-img info /data/daixuan1.qcow2 / ...

  8. linux禁用及启用pcie设备,KVM 介绍(4):I/O设备直接分配和 SRIOV [KVM PCI/PCIe PassThrough SRIOV]...

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  9. 【Linux学习篇】This virtual machine is configured for 64-bit guest operating systems.……

    在学习Linux的基本操作的时候,安装虚拟环境则提示自己 This virtualmachine is configured for 64-bit guest operatingsystems.--起 ...

最新文章

  1. Win8离线添加Net Framework 3.5功能
  2. 使用Navicat for Oracle新建用户无法登陆(用户名大小写问题)
  3. .net读写 更新 删除(操作)xml文件
  4. 读取缓存行的伪共享问题
  5. Elasticsearch(二)概念及安装、部署
  6. FPGA学习之路—Vivado与Modelsim联合仿真
  7. 让用户研究插上数据的翅膀
  8. 计算机系统应用系统,计算机系统应用.pdf
  9. datatable相同列合并_使用Power Query合并查询
  10. java 485通讯_CAKJ-963U3-KT带485通讯上下限报警智能型仪表
  11. npm ERR! Error: EPERM: operation not permitted问题解决
  12. Java设计模式笔记--------工厂模式------抽象工厂模式
  13. html表格中boder属性与style中boder属性区别
  14. 如何设计游戏中的道具功能(三)
  15. 电脑桌面显示白色图标无法删除
  16. 基本算法4.1堆积木详细题解
  17. GitHub--logparser(日志解析器)
  18. 果然是WIFI引起局域网速度慢
  19. 每周推荐短视频:商用车实现无人驾驶的目的是什么?
  20. 电池管理系统(BMS)-SOC算法

热门文章

  1. 使用Markdown和Latex写数学公式
  2. 基于Web的高校学生成绩管理系统
  3. ABAP Docking Control Container开发实例
  4. Series(一):Series的创建方式和常用属性说明
  5. 命名空间的问题导致No transform from [..._link] to [base_link]
  6. strstr()函数的使用说明(C语言)
  7. Unity 鼠标悬停
  8. matlab 罗德里格斯变换,修正罗德里格斯参数
  9. java带参构造函数_Java 带参数的构造函数
  10. 对弧长和坐标的曲线积分