翻譯-linux-5.1.2\Documentation\virtual\kvm\api.txt

google翻譯,部分人工修改css

最終KVM(基於內核的虛擬機)API文檔
===================================================================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:這些查詢和設置屬性,用於控制單個設備的操做。post

   必須從用於建立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中的值。

};

相關文章
相關標籤/搜索