We need to provide locking around the current_vmcs/VMCS interactions to protect against race conditions.
Signed-off-by: Gregory Haskins <[EMAIL PROTECTED]> --- drivers/kvm/vmx.c | 25 +++++++++++++++++++------ 1 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index d6354ca..78ff917 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -219,6 +219,7 @@ static void __vcpu_clear(void *arg) { struct kvm_vcpu *vcpu = arg; int cpu = raw_smp_processor_id(); + unsigned long flags; if (vcpu->cpu != -1) { /* @@ -238,8 +239,10 @@ static void __vcpu_clear(void *arg) * And finally, if this VMCS *was* currently active on this * CPU, mark the CPU as available again */ + local_irq_save(flags); if (per_cpu(current_vmcs, cpu) == vmx(vcpu)->vmcs) per_cpu(current_vmcs, cpu) = NULL; + local_irq_restore(flags); } else /* * If vcpu->cpu thinks we are not installed anywhere, @@ -464,6 +467,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu) { int cpu; u64 tsc_this, delta; + unsigned long flags; + int reload = 0; cpu = get_cpu(); @@ -477,16 +482,24 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu) * operation above). Either way, we must check to make sure we are * the currently loaded pointer, and correct it if we are not. * - * Note: A race condition exists against current_vmcs between the - * following update, and any IPIs dispatched to clear a different - * VMCS. Currently, this race condition is believed to be benign, - * but tread carefully. + * Note: We disable interrupts to prevent a race condition in + * current_vmcs against IPIs from remote CPUs to clear their own VMCS. + * + * Also note that preemption is currently disabled, so there is no race + * between the current_vmcs and the VMPTRLD operation which happens + * shortly after the current_vmcs update external to the critical + * section. */ + local_irq_save(flags); if (per_cpu(current_vmcs, cpu) != vmx(vcpu)->vmcs) { - /* Re-establish ourselves as the current VMCS */ - vmcs_load(vmx(vcpu)->vmcs); per_cpu(current_vmcs, cpu) = vmx(vcpu)->vmcs; + reload = 1; } + local_irq_restore(flags); + + if (reload) + /* Re-establish ourselves as the current VMCS */ + vmcs_load(vmx(vcpu)->vmcs); if (vcpu->cpu != cpu) { struct descriptor_table dt; ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel