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

Reply via email to