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

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

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();
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值