KVM: protect concurrent make_all_cpus_request
make_all_cpus_request contains a race condition which can trigger false request completed status, as follows:
CPU0 CPU1
if (test_and_set_bit(req,&vcpu->requests))
.... if (test_and_set_bit(req,&vcpu->requests))
.. return
proceed to smp_call_function_many(wait=1)
Use a spinlock to serialize concurrent CPUs.
include/linux/kvm_host.h +1 -0
@@ -124,6 +124,7 @@ struct kvm_kernel_irq_routing_entry {struct kvm {spinlock_t mmu_lock; +spinlock_t requests_lock;struct rw_semaphore slots_lock;struct mm_struct *mm;/* userspace tied to this vm */ int nmemslots;
virt/kvm/kvm_main.c +3 -0
@@ -739,6 +739,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)cpumask_clear (cpus); me =get_cpu (); +spin_lock (&kvm->requests_lock);kvm_for_each_vcpu (i, vcpu, kvm) {if (test_and_set_bit (req, &vcpu->requests))continue ;
@@ -752,6 +753,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)smp_call_function_many (cpus, ack_flush,NULL ,1 ); else called = false; +spin_unlock (&kvm->requests_lock);put_cpu ();free_cpumask_var (cpus);return called;
@@ -972,6 +974,7 @@ static struct kvm *kvm_create_vm(void) kvm->mm = current->mm;atomic_inc (&kvm->mm->mm_count);spin_lock_init (&kvm->mmu_lock); +spin_lock_init (&kvm->requests_lock);kvm_io_bus_init (&kvm->pio_bus);kvm_irqfd_init (kvm);mutex_init (&kvm->lock);
Quoted 5 lines · Marcelo Tosatti
make_all_cpus_requestcontains a race condition which can trigger false request completed status, as follows:
Quoted 8 lines
CPU0 CPU1
if (
test_and_set_bit(req,&vcpu->requests))
.... if (test_and_set_bit(req,&vcpu->requests))
.. return
proceed tosmp_call_function_many(wait=1)Use a spinlock to serialize concurrent CPUs.
Agreed, this is the safest...
Avi Kivity
AppliedQuoted 13 lines · Marcelo Tosatti
make_all_cpus_requestcontains a race condition which can trigger false request completed status, as follows:CPU0 CPU1
if (
test_and_set_bit(req,&vcpu->requests)).... if (test_and_set_bit(req,&vcpu->requests)) .. returnproceed to
smp_call_function_many(wait=1)Use a spinlock to serialize concurrent CPUs.
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function