我正在通过Linux KVM学习英特尔VMX 我无法清楚地了解KVM(Linux)如何安排在同一主机上并行运行的多个VM 例如,主机中有1个物理CPU,并且有2个KVM VM,每个VM配置1个vCPU。 启动后,KVM / QEMU为每个vCPU配置VMCS,因此KVM中有2个VMCS。由于只有1个pCPU,因此KVM / Linux必须将每个vCPU 1安排为1 我的理解是vCPUa运行时,vCPUa的KVM VMPTRLD VMCS,并运行VM的代码。然后,将调度vCPUb,KVM将VCPTRST的VCPTRST到某个地方的VMCS,以及来自某处的vCPUb的VMPTRLD VMCS。 通过阅读KVM的代码,我找不到vMPTRLD / VMPTRST在vCPU调度中发生的位置,以及“某处”的内容。
答案 0 :(得分:2)
vmptrld位于arch / x86 / kvm / vmx.c中的vmx_vcpu_load中 vmresume位于vmx_vcpu_run
答案 1 :(得分:1)
首先,KVM将为vCPU进出登记注册两个标注,如下所示
kvm_preempt_ops.sched_in = kvm_sched_in;
kvm_preempt_ops.sched_out = kvm_sched_out;
所以,每当调度发生时(没有深入研究),就会调用它们。以kvm_sched_in()
为例,它会调用,
static void kvm_sched_in(struct preempt_notifier *pn, int cpu)
{
struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
if (vcpu->preempted)
vcpu->preempted = false;
kvm_arch_sched_in(vcpu, cpu);
kvm_arch_vcpu_load(vcpu, cpu);
}
kvm_arch_vcpu_load()
将与VMCS一起使用,如下所示。
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
/* Address WBINVD may be executed by guest */
if (need_emulate_wbinvd(vcpu)) {
if (kvm_x86_ops->has_wbinvd_exit())
cpumask_set_cpu(cpu, vcpu->arch.wbinvd_dirty_mask);
else if (vcpu->cpu != -1 && vcpu->cpu != cpu)
smp_call_function_single(vcpu->cpu,
wbinvd_ipi, NULL, 1);
}
kvm_x86_ops->vcpu_load(vcpu, cpu); <<======
自.vcpu_load = vmx_vcpu_load,
/*
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
* vcpu mutex is already taken.
*/
static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
if (!vmm_exclusive)
kvm_cpu_vmxon(phys_addr);
else if (vmx->loaded_vmcs->cpu != cpu)
loaded_vmcs_clear(vmx->loaded_vmcs);
if (per_cpu(current_vmcs, cpu) != vmx->loaded_vmcs->vmcs) {
per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs;
vmcs_load(vmx->loaded_vmcs->vmcs);
}
就是这样。