我正在通过Linux KVM学习Intel VMX。
我也不能清楚地理解KVM (Linux)如何调度多个VM在同一主机上同时运行。
例如,主机中有1个物理vCPU,有2个KVM VM,每个都配置有1个CPU。
一旦它们启动,KVM/QEMU会为每个vCPU配置一个VMCSes,因此KVM中有2个VMCS。因为只有1个pCPU,所以KVM/Linux必须以1为单位调度每个vCPU。
我的理解是,当vCPUa运行时,KVM的VMCS,并运行VM的代码。然后,调度vCPUb,KVM将vCPUa的VMCS VMPTRST到某处,VMPTRLD vCPUb的VMCS从某处。
通过阅读KVM的代码,我没有找到vCPU调度的VMPTRLD/VMPTRST发生在哪里,以及什么是“某处”。
发布于 2018-06-10 04:51:54
vmptrld位于arch/x86/kvm/vmx.c中的vmx_vcpu_load中
vmresume在vmx_vcpu_run中
发布于 2018-06-11 08:46:46
首先,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);
}
就是这样。
https://stackoverflow.com/questions/50774234
复制相似问题