@@ -662,6 +662,7 @@ again:
goto vcpu_run_fail;
srcu_read_unlock(&vcpu->kvm->srcu, idx);
+ atomic_set(&vcpu->guest_mode, 1);
kvm_guest_enter();
/*
@@ -683,6 +684,7 @@ again:
*/
barrier();
kvm_guest_exit();
+ atomic_set(&vcpu->guest_mode, 0);
preempt_enable();
idx = srcu_read_lock(&vcpu->kvm->srcu);
@@ -5214,7 +5214,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
kvm_load_guest_xcr0(vcpu);
atomic_set(&vcpu->guest_mode, 1);
- smp_wmb();
+
+ /* We should set ->guest_mode before check ->requests,
+ * see the comment in make_all_cpus_request.
+ */
+ smp_mb();
local_irq_disable();
@@ -103,14 +103,15 @@ struct kvm_vcpu {
#ifdef CONFIG_PREEMPT_NOTIFIERS
struct preempt_notifier preempt_notifier;
#endif
+ int cpu;
int vcpu_id;
- struct mutex mutex;
- int cpu;
+ int srcu_idx;
atomic_t guest_mode;
- struct kvm_run *run;
unsigned long requests;
unsigned long guest_debug;
- int srcu_idx;
+
+ struct mutex mutex;
+ struct kvm_run *run;
int fpu_active;
int guest_fpu_loaded, guest_xcr0_loaded;
@@ -153,7 +153,12 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
if (kvm_make_check_request(req, vcpu))
continue;
cpu = vcpu->cpu;
- if (cpus != NULL && cpu != -1 && cpu != me)
+
+ /* Set ->requests bit before we read ->guest_mode */
+ smp_mb();
+
+ if (cpus != NULL && cpu != -1 && cpu != me &&
+ atomic_read(&vcpu->guest_mode))
cpumask_set_cpu(cpu, cpus);
}
if (unlikely(cpus == NULL))