转载请注明出处:
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; }
原文地址:http://blog.csdn.net/muge0913/article/details/24660731