kvm中的vCPU


转载请注明出处:

http://www.openext.org/2014/04/kvmvcpu/

http://blog.csdn.net/muge0913/article/details/24660731

qemu/kvm为客户机提供了完整的硬件环境,在客户机看来其所拥有的CPU为vCPU,在KVM看来每个客户机都是一个标准的linux进程qemu进程。在宿主机上vCPU是qemu进程派生出来的普通线程。

在linux中进程有两种模式:用户模式,内核模式。而kvm增加了第三种模式:客户模式。用户模式主要是一些IO的模拟管理。内核模式主要执行一些安全性高性能的指令。客户模式执行大部分的代码。

 

下面讲下vcpu的创建。创建vCPU就是创建vCPU描述符,在KVM中,vCPU对应的数据结构体为kvm_vcpu。kvm_vcpu中描述符包含的内容,包含各个平台通用的内容和平台相关的内容。

主要过程:分配VCPU标识,设置cpu_id属于哪个KVM虚拟机,并且分配对该VCPU的唯一标识符。

初始化虚拟寄存器组。

初始化kvm_vcpu的状态信息,设置kvm_vcpu在被调度前需要配置的必要标志。

初始化额外的信息,并且配置apic等虚拟化组件。

最终目的就是将kvm_vcpu的各个数据结构体设置成为可用的状态

创建vcpu函数kvm_vm_ioctl_create_vcpu其代码如下。

static int kvm_vm_ioctl_create_vcpu(struct kvm*kvm, u32 id) 
 { 
     int r; 
     struct kvm_vcpu *vcpu, *v; 
   // 创建kvm_vcpu结构体
     vcpu = kvm_arch_vcpu_create(kvm, id); 
     if (IS_ERR(vcpu)) 
          return PTR_ERR(vcpu); 
   
     preempt_notifier_init(&vcpu->preempt_notifier,&kvm_preempt_ops); 
   //设置结构体内容
     r = kvm_arch_vcpu_setup(vcpu); 
     if (r) 
         return r; 
   //加锁,以便vcpu_fd正确加载
     mutex_lock(&kvm->lock); 
     if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) { 
         r = -EINVAL; 
         goto vcpu_destroy; 
     } 
   //检查创建出来的vcpu是否存在
     kvm_for_each_vcpu(r, v, kvm) 
         if (v->vcpu_id == id) { 
              r = -EEXIST; 
              goto vcpu_destroy; 
         } 
   
    BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]); 
   
     /* Now it's all set up, let userspace reach it */ 
     kvm_get_kvm(kvm); 
     //创建vcp_fd
     r = create_vcpu_fd(vcpu); 
     if (r < 0) { 
         kvm_put_kvm(kvm); 
         goto vcpu_destroy; 
     } 
   
     kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu; 
     smp_wmb(); 
     atomic_inc(&kvm->online_vcpus); 
   
 #ifdef CONFIG_KVM_APIC_ARCHITECTURE 
     if (kvm->bsp_vcpu_id == id) 
         kvm->bsp_vcpu = vcpu; 
 #endif 
       //解锁
     mutex_unlock(&kvm->lock); 
     return r; 
   
 vcpu_destroy: 
     mutex_unlock(&kvm->lock); 
     kvm_arch_vcpu_destroy(vcpu); 
     return r; 
 }  

相关内容