KVM虚拟机创建功能详细讲解

 

__u16 ipa;

__u32 ipb;

} s390_sieic;

/* 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;

/* KVM_EXIT_DCR */

struct {

__u32dcrn;

__u32data;

__u8  is_write;

} dcr;

/* Fix the size of the union. */

char padding[256];

2. 函数kvm_create():该函数主要用于创建一个虚拟机内核环境。该函数原型为:

int kvm_create(kvm_context_t kvm,unsignedlong phys_mem_bytes, void **phys_mem);

参数:kvm_context_t 表示传递的用户态虚拟机上下文环境,phys_mem_bytes表示需要创建的物理内存的大小,phys_mem表示创建虚拟机的首地址。这个函数首先调用kvm_create_vm()分配IRQ并且初始化为0,设置vcpu[0]的值为-1,即不允许调度虚拟机执行。然后调用ioctl系统调用ioctl(fd,KVM_CREATE_VM,0)来创建虚拟机内核数据结构struct kvm。

3. 系统调用函数ioctl(fd,KVM_CREATE_VM,0),用于在内核中创建和虚拟机相关的数据结构。该函数原型为:

Static long kvm_dev_ioctl(struct file *filp,unsigned intioctl, unsignedlong arg);其中ioctl表示命令。这个函数调用kvm_dev_ioctl_create_vm()创建虚拟机实例内核相关数据结构。该函数首先通过内核中kvm_create_vm()函数创建内核中kvm上下文struct kvm,然后通过函数

Anno_inode_getfd(“kvm_vm”,&kvm_vm_fops,kvm,0)返回该虚拟机的文件描述符,返回给用户调用函数,由2中描述的函数赋值给用户态虚拟机上下文变量中的虚拟机描述符kvm_vm_fd。

4. 内核创建虚拟机kvm对象后,接着调用kvm_arch_create函数用于创建一些体系结构相关的信息,主要包括kvm_init_tss、kvm_create_pit以及kvm_init_coalsced_mmio等信息。然后调用kvm_create_phys_mem创建物理内存,函数kvm_create_irqchip用于创建内核irq信息,通过系统调用ioctl(kvm->vm_fd,KVM_CREATE_IRQCHIP)。

5,函数kvm_create_vcpu():用于创建虚拟处理器。该函数原型为:

int kvm_create_vcpu(kvm_context_t kvm, intslot);

参数:kvm表示对应用户态虚拟机上下文,slot表示需要创建的虚拟处理器的个数。

该函数通过ioctl系统调用ioctl(kvm->vm_fd,KVM_CREATE_VCPU,slot)创建属于该虚拟机的虚拟处理器。该系统调用函数:

Static init kvm_vm_ioctl_create_vcpu(struct*kvm, n) 参数kvm为内核虚拟机实例数据结构,n为创建的虚拟CPU的数目。

6,函数kvm_create_phys_mem()用于创建虚拟机内存空间,该函数原型:

Void * kvm_create_phys_mem(kvm_context_tkvm,unsigned long phys_start,unsigned len,int log,int writable);

参数:kvm 表示用户态虚拟机上下文信息,phys_start为分配给该虚拟机的物理起始地址,len表示内存大小,log表示是否记录脏页面,writable表示该段内存对应的页表是否可写。

该函数首先申请一个结构体kvm_userspace_memory_region 然后通过系统调用KVM_SET_USER_MEMORY_REGION来设置内核中对应的内存的属性。该系统调用函数原型:

Ioctl(int kvm->vm_fd,KVM_SET_USER_MEMORY_REGION,&memory);

参数:第一个参数vm_fd为指向内核虚拟机实例对象的文件描述符,第二个参数KVM_SET_USER_MEMORY_REGION为系统调用命令参数,表示该系统调用为创建内核客户机映射,即影子页表。第三个参数memory表示指向该虚拟机的内存空间地址。系统调用首先通过参数memory通过函数copy_from_user从用户空间复制struct_user_momory_region 变量,然后通过kvm_vm_ioctl_set_memory_region函数设置内核中对应的内存域。该函数原型:

Int kvm_vm_ioctl_set_memory_region(struct*kvm,struct kvm_usersapce_memory_region *mem,int user_alloc);该函数再调用函数kvm_set_memory_resgion()设置影子页表。当这一切都准备完毕后,调用kvm_run()函数即可调度执行虚拟处理器。

7,函数kvm_run():用于调度运行虚拟处理器。该函数原型为:

Int kvm_run(kvm_context_t kvm,int vcpu,void *env) 该函数首先得到vcpu的描述符,然后调用系统调用ioctl(fd,kvm_run,0)调度运行虚拟处理器。Kvm_run函数在正常运行情况下并不返回,除非发生以下事件之一:一是发生了I/O事件,I/O事件由用户态的QEMU处理;一个是发生了客户机和KVM都无法处理的异常事件。KVM_RUN()中返回截获的事件,主要是I/O以及停机等事件。

标签: 无
返回文章列表 文章二维码
本页链接的二维码
打赏二维码