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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel