struct vcpu_vmx {
        struct kvm_vcpu       vcpu;
+       struct list_head      local_vcpus_link;
        int                   launched;
        u8                    fail;
        u32                   idt_vectoring_info;
 
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
 static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
+static DEFINE_PER_CPU(struct list_head, vcpus_on_cpu);
 
 static struct page *vmx_io_bitmap_a;
 static struct page *vmx_io_bitmap_b;
        if (per_cpu(current_vmcs, cpu) == vmx->vmcs)
                per_cpu(current_vmcs, cpu) = NULL;
        rdtscll(vmx->vcpu.arch.host_tsc);
+       list_del(&vmx->local_vcpus_link);
+       vmx->vcpu.cpu = -1;
+       vmx->launched = 0;
 }
 
 static void vcpu_clear(struct vcpu_vmx *vmx)
        if (vmx->vcpu.cpu == -1)
                return;
        smp_call_function_single(vmx->vcpu.cpu, __vcpu_clear, vmx, 1);
-       vmx->launched = 0;
 }
 
 static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx)
                vcpu_clear(vmx);
                kvm_migrate_timers(vcpu);
                vpid_sync_vcpu_all(vmx);
+               local_irq_disable();
+               list_add(&vmx->local_vcpus_link,
+                        &per_cpu(vcpus_on_cpu, cpu));
+               local_irq_enable();
        }
 
        if (per_cpu(current_vmcs, cpu) != vmx->vmcs) {
        u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
        u64 old;
 
+       INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu));
        rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
        if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED |
                    MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
                      : "memory", "cc");
 }
 
+static void vmclear_local_vcpus(void)
+{
+       int cpu = raw_smp_processor_id();
+       struct vcpu_vmx *vmx, *n;
+
+       list_for_each_entry_safe(vmx, n, &per_cpu(vcpus_on_cpu, cpu),
+                                local_vcpus_link)
+               __vcpu_clear(vmx);
+}
+
 static void hardware_disable(void *garbage)
 {
+       vmclear_local_vcpus();
        asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc");
        write_cr4(read_cr4() & ~X86_CR4_VMXE);
 }
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
        if (vmx->vmcs) {
-               on_each_cpu(__vcpu_clear, vmx, 1);
+               vcpu_clear(vmx);
                free_vmcs(vmx->vmcs);
                vmx->vmcs = NULL;
        }
 
  */
 void decache_vcpus_on_cpu(int cpu)
 {
-       struct kvm *vm;
-       struct kvm_vcpu *vcpu;
-       int i;
-
-       spin_lock(&kvm_lock);
-       list_for_each_entry(vm, &vm_list, vm_list)
-               for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-                       vcpu = vm->vcpus[i];
-                       if (!vcpu)
-                               continue;
-                       /*
-                        * If the vcpu is locked, then it is running on some
-                        * other cpu and therefore it is not cached on the
-                        * cpu in question.
-                        *
-                        * If it's not locked, check the last cpu it executed
-                        * on.
-                        */
-                       if (mutex_trylock(&vcpu->mutex)) {
-                               if (vcpu->cpu == cpu) {
-                                       kvm_x86_ops->vcpu_decache(vcpu);
-                                       vcpu->cpu = -1;
-                               }
-                               mutex_unlock(&vcpu->mutex);
-                       }
-               }
-       spin_unlock(&kvm_lock);
 }
 
 int kvm_dev_ioctl_check_extension(long ext)