aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 4e1a017f3db7..633c2eded08d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -41,6 +41,8 @@
41#include <linux/fs.h> 41#include <linux/fs.h>
42#include <linux/mount.h> 42#include <linux/mount.h>
43#include <linux/sched.h> 43#include <linux/sched.h>
44#include <linux/cpumask.h>
45#include <linux/smp.h>
44 46
45#include "x86_emulate.h" 47#include "x86_emulate.h"
46#include "segment_descriptor.h" 48#include "segment_descriptor.h"
@@ -309,6 +311,48 @@ static void vcpu_put(struct kvm_vcpu *vcpu)
309 mutex_unlock(&vcpu->mutex); 311 mutex_unlock(&vcpu->mutex);
310} 312}
311 313
314static void ack_flush(void *_completed)
315{
316 atomic_t *completed = _completed;
317
318 atomic_inc(completed);
319}
320
321void kvm_flush_remote_tlbs(struct kvm *kvm)
322{
323 int i, cpu, needed;
324 cpumask_t cpus;
325 struct kvm_vcpu *vcpu;
326 atomic_t completed;
327
328 atomic_set(&completed, 0);
329 cpus_clear(cpus);
330 needed = 0;
331 for (i = 0; i < kvm->nvcpus; ++i) {
332 vcpu = &kvm->vcpus[i];
333 if (test_and_set_bit(KVM_TLB_FLUSH, &vcpu->requests))
334 continue;
335 cpu = vcpu->cpu;
336 if (cpu != -1 && cpu != raw_smp_processor_id())
337 if (!cpu_isset(cpu, cpus)) {
338 cpu_set(cpu, cpus);
339 ++needed;
340 }
341 }
342
343 /*
344 * We really want smp_call_function_mask() here. But that's not
345 * available, so ipi all cpus in parallel and wait for them
346 * to complete.
347 */
348 for (cpu = first_cpu(cpus); cpu != NR_CPUS; cpu = next_cpu(cpu, cpus))
349 smp_call_function_single(cpu, ack_flush, &completed, 1, 0);
350 while (atomic_read(&completed) != needed) {
351 cpu_relax();
352 barrier();
353 }
354}
355
312static struct kvm *kvm_create_vm(void) 356static struct kvm *kvm_create_vm(void)
313{ 357{
314 struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); 358 struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);