kvm代码中vcpu_vmx、vcpu、vmcs、cpu的关系

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/leoufung/article/details/52485114

先来看一下相关结构体的相关部分

struct vcpu_vmx {
	struct kvm_vcpu       vcpu;
	/*
	 * loaded_vmcs points to the VMCS currently used in this vcpu. For a
	 * non-nested (L1) guest, it always points to vmcs01. For a nested
	 * guest (L2), it points to a different VMCS.
	 */
	struct loaded_vmcs    vmcs01;
	struct loaded_vmcs   *loaded_vmcs;
}

struct kvm_vcpu {

	int cpu;    /*运行当前VCPU的物理CPU编号*/

}


struct loaded_vmcs {
	struct vmcs *vmcs;  /*本VCPU对应的VMCS*/
	int cpu;            /*上一次运行的CPU编号*/
	int launched;
	struct list_head loaded_vmcss_on_cpu_link;
};

VMX其实是VCPU的一个运行环境,理解为environment。集中通过loaded_vmcs和vcpu成员将vmcs和CPU及VMCS关联起来。

一个VCPU当然可以运行在不同的物理CPU之上,只要更换loaded_vmcs中cpu编号即可;

但是为什么会一个VCPU对应多个不同的VMCS呢?其实是因为层叠虚拟化的原因,当L2虚拟机的VMCS加载后,VCPU所使用的VMCS不是L1层的VMCS;而是L2层的VMCS;其实就是把L1的VCPU在L2中当做了物理CPU用,物理CPU当然可以有多个VMCS了。




一般L1中,loaded_vmcs就执行vmcs01,当VCPU运行的物理CPU发生切换的时候,修改loaded_vmcs中的cpu成员即可

static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
{

    /*vmcs的分配*/
	vmx->loaded_vmcs = &vmx->vmcs01;
	vmx->loaded_vmcs->vmcs = alloc_vmcs();

}


在L2中,loaded_vmcs会在L1 VMCS和各个L2 VMCS之间切换,那么就需要修改loaded_vmcs指针的指向

static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
{
	cpu = get_cpu();
	vmx->loaded_vmcs = vmcs02;
	vmx_vcpu_put(vcpu);
	vmx_vcpu_load(vcpu, cpu);
	vcpu->cpu = cpu;
	put_cpu();
}





展开阅读全文

没有更多推荐了,返回首页