]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kvm/x86.c
Merge branches 'release' and 'ppc-workaround' into release
[linux-2.6-omap-h63xx.git] / arch / x86 / kvm / x86.c
index 5902c5cbc1bbd721fdfa805ff27341e62c4e271f..cf530814868957a9de8058849538405ca493dcc5 100644 (file)
@@ -73,6 +73,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
        { "mmu_flooded", VM_STAT(mmu_flooded) },
        { "mmu_recycled", VM_STAT(mmu_recycled) },
+       { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
        { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
        { NULL }
 };
@@ -180,7 +181,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
        int ret;
        u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
 
-       mutex_lock(&vcpu->kvm->lock);
+       down_read(&current->mm->mmap_sem);
        ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
                                  offset * sizeof(u64), sizeof(pdpte));
        if (ret < 0) {
@@ -197,7 +198,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 
        memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
 out:
-       mutex_unlock(&vcpu->kvm->lock);
+       up_read(&current->mm->mmap_sem);
 
        return ret;
 }
@@ -211,13 +212,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
        if (is_long_mode(vcpu) || !is_pae(vcpu))
                return false;
 
-       mutex_lock(&vcpu->kvm->lock);
+       down_read(&current->mm->mmap_sem);
        r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
        if (r < 0)
                goto out;
        changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0;
 out:
-       mutex_unlock(&vcpu->kvm->lock);
+       up_read(&current->mm->mmap_sem);
 
        return changed;
 }
@@ -277,9 +278,7 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        kvm_x86_ops->set_cr0(vcpu, cr0);
        vcpu->arch.cr0 = cr0;
 
-       mutex_lock(&vcpu->kvm->lock);
        kvm_mmu_reset_context(vcpu);
-       mutex_unlock(&vcpu->kvm->lock);
        return;
 }
 EXPORT_SYMBOL_GPL(set_cr0);
@@ -319,9 +318,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
        }
        kvm_x86_ops->set_cr4(vcpu, cr4);
        vcpu->arch.cr4 = cr4;
-       mutex_lock(&vcpu->kvm->lock);
        kvm_mmu_reset_context(vcpu);
-       mutex_unlock(&vcpu->kvm->lock);
 }
 EXPORT_SYMBOL_GPL(set_cr4);
 
@@ -359,7 +356,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
                 */
        }
 
-       mutex_lock(&vcpu->kvm->lock);
+       down_read(&current->mm->mmap_sem);
        /*
         * Does the new cr3 value map to physical memory? (Note, we
         * catch an invalid cr3 even in real-mode, because it would
@@ -375,7 +372,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
                vcpu->arch.cr3 = cr3;
                vcpu->arch.mmu.new_cr3(vcpu);
        }
-       mutex_unlock(&vcpu->kvm->lock);
+       up_read(&current->mm->mmap_sem);
 }
 EXPORT_SYMBOL_GPL(set_cr3);
 
@@ -498,7 +495,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                vcpu->arch.ia32_misc_enable_msr = data;
                break;
        default:
-               pr_unimpl(vcpu, "unhandled wrmsr: 0x%x\n", msr);
+               pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data);
                return 1;
        }
        return 0;
@@ -685,6 +682,9 @@ int kvm_dev_ioctl_check_extension(long ext)
        case KVM_CAP_EXT_CPUID:
                r = 1;
                break;
+       case KVM_CAP_VAPIC:
+               r = !kvm_x86_ops->cpu_has_accelerated_tpr();
+               break;
        default:
                r = 0;
                break;
@@ -1054,6 +1054,15 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
        return 0;
 }
 
+static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu,
+                                          struct kvm_tpr_access_ctl *tac)
+{
+       if (tac->flags)
+               return -EINVAL;
+       vcpu->arch.tpr_access_reporting = !!tac->enabled;
+       return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
                         unsigned int ioctl, unsigned long arg)
 {
@@ -1147,6 +1156,34 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        case KVM_SET_MSRS:
                r = msr_io(vcpu, argp, do_set_msr, 0);
                break;
+       case KVM_TPR_ACCESS_REPORTING: {
+               struct kvm_tpr_access_ctl tac;
+
+               r = -EFAULT;
+               if (copy_from_user(&tac, argp, sizeof tac))
+                       goto out;
+               r = vcpu_ioctl_tpr_access_reporting(vcpu, &tac);
+               if (r)
+                       goto out;
+               r = -EFAULT;
+               if (copy_to_user(argp, &tac, sizeof tac))
+                       goto out;
+               r = 0;
+               break;
+       };
+       case KVM_SET_VAPIC_ADDR: {
+               struct kvm_vapic_addr va;
+
+               r = -EINVAL;
+               if (!irqchip_in_kernel(vcpu->kvm))
+                       goto out;
+               r = -EFAULT;
+               if (copy_from_user(&va, argp, sizeof va))
+                       goto out;
+               r = 0;
+               kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
+               break;
+       }
        default:
                r = -EINVAL;
        }
@@ -1170,12 +1207,12 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
        if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
                return -EINVAL;
 
-       mutex_lock(&kvm->lock);
+       down_write(&current->mm->mmap_sem);
 
        kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
        kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
 
-       mutex_unlock(&kvm->lock);
+       up_write(&current->mm->mmap_sem);
        return 0;
 }
 
@@ -1224,7 +1261,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
            < alias->target_phys_addr)
                goto out;
 
-       mutex_lock(&kvm->lock);
+       down_write(&current->mm->mmap_sem);
 
        p = &kvm->arch.aliases[alias->slot];
        p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
@@ -1238,7 +1275,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
 
        kvm_mmu_zap_all(kvm);
 
-       mutex_unlock(&kvm->lock);
+       up_write(&current->mm->mmap_sem);
 
        return 0;
 
@@ -1314,7 +1351,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
-       mutex_lock(&kvm->lock);
+       down_write(&current->mm->mmap_sem);
 
        r = kvm_get_dirty_log(kvm, log, &is_dirty);
        if (r)
@@ -1330,7 +1367,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        }
        r = 0;
 out:
-       mutex_unlock(&kvm->lock);
+       up_write(&current->mm->mmap_sem);
        return r;
 }
 
@@ -1524,25 +1561,32 @@ int emulator_read_std(unsigned long addr,
                             struct kvm_vcpu *vcpu)
 {
        void *data = val;
+       int r = X86EMUL_CONTINUE;
 
+       down_read(&current->mm->mmap_sem);
        while (bytes) {
                gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
                unsigned offset = addr & (PAGE_SIZE-1);
                unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
                int ret;
 
-               if (gpa == UNMAPPED_GVA)
-                       return X86EMUL_PROPAGATE_FAULT;
+               if (gpa == UNMAPPED_GVA) {
+                       r = X86EMUL_PROPAGATE_FAULT;
+                       goto out;
+               }
                ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
-               if (ret < 0)
-                       return X86EMUL_UNHANDLEABLE;
+               if (ret < 0) {
+                       r = X86EMUL_UNHANDLEABLE;
+                       goto out;
+               }
 
                bytes -= tocopy;
                data += tocopy;
                addr += tocopy;
        }
-
-       return X86EMUL_CONTINUE;
+out:
+       up_read(&current->mm->mmap_sem);
+       return r;
 }
 EXPORT_SYMBOL_GPL(emulator_read_std);
 
@@ -1560,7 +1604,9 @@ static int emulator_read_emulated(unsigned long addr,
                return X86EMUL_CONTINUE;
        }
 
+       down_read(&current->mm->mmap_sem);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+       up_read(&current->mm->mmap_sem);
 
        /* For APIC access vmexit */
        if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
@@ -1576,11 +1622,14 @@ mmio:
        /*
         * Is this MMIO handled locally?
         */
+       mutex_lock(&vcpu->kvm->lock);
        mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
        if (mmio_dev) {
                kvm_iodevice_read(mmio_dev, gpa, bytes, val);
+               mutex_unlock(&vcpu->kvm->lock);
                return X86EMUL_CONTINUE;
        }
+       mutex_unlock(&vcpu->kvm->lock);
 
        vcpu->mmio_needed = 1;
        vcpu->mmio_phys_addr = gpa;
@@ -1595,10 +1644,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
 {
        int ret;
 
+       down_read(&current->mm->mmap_sem);
        ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
-       if (ret < 0)
+       if (ret < 0) {
+               up_read(&current->mm->mmap_sem);
                return 0;
+       }
        kvm_mmu_pte_write(vcpu, gpa, val, bytes);
+       up_read(&current->mm->mmap_sem);
        return 1;
 }
 
@@ -1608,7 +1661,11 @@ static int emulator_write_emulated_onepage(unsigned long addr,
                                           struct kvm_vcpu *vcpu)
 {
        struct kvm_io_device *mmio_dev;
-       gpa_t                 gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+       gpa_t                 gpa;
+
+       down_read(&current->mm->mmap_sem);
+       gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+       up_read(&current->mm->mmap_sem);
 
        if (gpa == UNMAPPED_GVA) {
                kvm_inject_page_fault(vcpu, addr, 2);
@@ -1626,11 +1683,14 @@ mmio:
        /*
         * Is this MMIO handled locally?
         */
+       mutex_lock(&vcpu->kvm->lock);
        mmio_dev = vcpu_find_mmio_dev(vcpu, gpa);
        if (mmio_dev) {
                kvm_iodevice_write(mmio_dev, gpa, bytes, val);
+               mutex_unlock(&vcpu->kvm->lock);
                return X86EMUL_CONTINUE;
        }
+       mutex_unlock(&vcpu->kvm->lock);
 
        vcpu->mmio_needed = 1;
        vcpu->mmio_phys_addr = gpa;
@@ -1677,11 +1737,14 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
 #ifndef CONFIG_X86_64
        /* guests cmpxchg8b have to be emulated atomically */
        if (bytes == 8) {
-               gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+               gpa_t gpa;
                struct page *page;
-               char *addr;
+               char *kaddr;
                u64 val;
 
+               down_read(&current->mm->mmap_sem);
+               gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+
                if (gpa == UNMAPPED_GVA ||
                   (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
                        goto emul_write;
@@ -1691,12 +1754,13 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
 
                val = *(u64 *)new;
                page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
-               addr = kmap_atomic(page, KM_USER0);
-               set_64bit((u64 *)(addr + offset_in_page(gpa)), val);
-               kunmap_atomic(addr, KM_USER0);
+               kaddr = kmap_atomic(page, KM_USER0);
+               set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val);
+               kunmap_atomic(kaddr, KM_USER0);
                kvm_release_page_dirty(page);
+       emul_write:
+               up_read(&current->mm->mmap_sem);
        }
-emul_write:
 #endif
 
        return emulator_write_emulated(addr, new, bytes, vcpu);
@@ -1776,9 +1840,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
                        struct kvm_run *run,
                        unsigned long cr2,
                        u16 error_code,
-                       int no_decode)
+                       int emulation_type)
 {
        int r;
+       struct decode_cache *c;
 
        vcpu->arch.mmio_fault_cr2 = cr2;
        kvm_x86_ops->cache_regs(vcpu);
@@ -1786,7 +1851,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
        vcpu->mmio_is_write = 0;
        vcpu->arch.pio.string = 0;
 
-       if (!no_decode) {
+       if (!(emulation_type & EMULTYPE_NO_DECODE)) {
                int cs_db, cs_l;
                kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 
@@ -1820,6 +1885,16 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
                                        get_segment_base(vcpu, VCPU_SREG_FS);
 
                r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
+
+               /* Reject the instructions other than VMCALL/VMMCALL when
+                * try to emulate invalid opcode */
+               c = &vcpu->arch.emulate_ctxt.decode;
+               if ((emulation_type & EMULTYPE_TRAP_UD) &&
+                   (!(c->twobyte && c->b == 0x01 &&
+                     (c->modrm_reg == 0 || c->modrm_reg == 3) &&
+                      c->modrm_mod == 3 && c->modrm_rm == 1)))
+                       return EMULATE_FAIL;
+
                ++vcpu->stat.insn_emulation;
                if (r)  {
                        ++vcpu->stat.insn_emulation_fail;
@@ -2077,10 +2152,10 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
                kvm_x86_ops->skip_emulated_instruction(vcpu);
 
        for (i = 0; i < nr_pages; ++i) {
-               mutex_lock(&vcpu->kvm->lock);
+               down_read(&current->mm->mmap_sem);
                page = gva_to_page(vcpu, address + i * PAGE_SIZE);
                vcpu->arch.pio.guest_pages[i] = page;
-               mutex_unlock(&vcpu->kvm->lock);
+               up_read(&current->mm->mmap_sem);
                if (!page) {
                        kvm_inject_gp(vcpu, 0);
                        free_pio_guest_pages(vcpu);
@@ -2112,12 +2187,6 @@ int kvm_arch_init(void *opaque)
        int r;
        struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
 
-       r = kvm_mmu_module_init();
-       if (r)
-               goto out_fail;
-
-       kvm_init_msr_list();
-
        if (kvm_x86_ops) {
                printk(KERN_ERR "kvm: already loaded the other module\n");
                r = -EEXIST;
@@ -2135,13 +2204,17 @@ int kvm_arch_init(void *opaque)
                goto out;
        }
 
+       r = kvm_mmu_module_init();
+       if (r)
+               goto out;
+
+       kvm_init_msr_list();
+
        kvm_x86_ops = ops;
        kvm_mmu_set_nonpresent_ptes(0ull, 0ull);
        return 0;
 
 out:
-       kvm_mmu_module_exit();
-out_fail:
        return r;
 }
 
@@ -2188,6 +2261,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
        }
 
        switch (nr) {
+       case KVM_HC_VAPIC_POLL_IRQ:
+               ret = 0;
+               break;
        default:
                ret = -KVM_ENOSYS;
                break;
@@ -2203,7 +2279,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
        char instruction[3];
        int ret = 0;
 
-       mutex_lock(&vcpu->kvm->lock);
 
        /*
         * Blow out the MMU to ensure that no other VCPU has an active mapping
@@ -2218,8 +2293,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
            != X86EMUL_CONTINUE)
                ret = -EFAULT;
 
-       mutex_unlock(&vcpu->kvm->lock);
-
        return ret;
 }
 
@@ -2395,6 +2468,31 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu,
                                         vcpu->arch.irq_summary == 0);
 }
 
+static void vapic_enter(struct kvm_vcpu *vcpu)
+{
+       struct kvm_lapic *apic = vcpu->arch.apic;
+       struct page *page;
+
+       if (!apic || !apic->vapic_addr)
+               return;
+
+       down_read(&current->mm->mmap_sem);
+       page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
+       vcpu->arch.apic->vapic_page = page;
+       up_read(&current->mm->mmap_sem);
+}
+
+static void vapic_exit(struct kvm_vcpu *vcpu)
+{
+       struct kvm_lapic *apic = vcpu->arch.apic;
+
+       if (!apic || !apic->vapic_addr)
+               return;
+
+       kvm_release_page_dirty(apic->vapic_page);
+       mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
+}
+
 static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
        int r;
@@ -2409,6 +2507,8 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                vcpu->arch.mp_state = VCPU_MP_STATE_RUNNABLE;
        }
 
+       vapic_enter(vcpu);
+
 preempted:
        if (vcpu->guest_debug.enabled)
                kvm_x86_ops->guest_debug_pre(vcpu);
@@ -2418,6 +2518,17 @@ again:
        if (unlikely(r))
                goto out;
 
+       if (vcpu->requests) {
+               if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
+                       __kvm_migrate_apic_timer(vcpu);
+               if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
+                                      &vcpu->requests)) {
+                       kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
+                       r = 0;
+                       goto out;
+               }
+       }
+
        kvm_inject_pending_timer_irqs(vcpu);
 
        preempt_disable();
@@ -2427,6 +2538,13 @@ again:
 
        local_irq_disable();
 
+       if (need_resched()) {
+               local_irq_enable();
+               preempt_enable();
+               r = 1;
+               goto out;
+       }
+
        if (signal_pending(current)) {
                local_irq_enable();
                preempt_enable();
@@ -2443,6 +2561,8 @@ again:
        else
                kvm_x86_ops->inject_pending_vectors(vcpu, kvm_run);
 
+       kvm_lapic_sync_to_vapic(vcpu);
+
        vcpu->guest_mode = 1;
        kvm_guest_enter();
 
@@ -2480,6 +2600,8 @@ again:
        if (vcpu->arch.exception.pending && kvm_x86_ops->exception_injected(vcpu))
                vcpu->arch.exception.pending = false;
 
+       kvm_lapic_sync_from_vapic(vcpu);
+
        r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
 
        if (r > 0) {
@@ -2501,6 +2623,8 @@ out:
 
        post_kvm_run_save(vcpu, kvm_run);
 
+       vapic_exit(vcpu);
+
        return r;
 }
 
@@ -2535,7 +2659,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                vcpu->mmio_read_completed = 1;
                vcpu->mmio_needed = 0;
                r = emulate_instruction(vcpu, kvm_run,
-                                       vcpu->arch.mmio_fault_cr2, 0, 1);
+                                       vcpu->arch.mmio_fault_cr2, 0,
+                                       EMULTYPE_NO_DECODE);
                if (r == EMULATE_DO_MMIO) {
                        /*
                         * Read-modify-write.  Back to userspace.
@@ -2827,13 +2952,13 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
        gpa_t gpa;
 
        vcpu_load(vcpu);
-       mutex_lock(&vcpu->kvm->lock);
+       down_read(&current->mm->mmap_sem);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
+       up_read(&current->mm->mmap_sem);
        tr->physical_address = gpa;
        tr->valid = gpa != UNMAPPED_GVA;
        tr->writeable = 1;
        tr->usermode = 0;
-       mutex_unlock(&vcpu->kvm->lock);
        vcpu_put(vcpu);
 
        return 0;
@@ -3102,13 +3227,11 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
         */
        if (!user_alloc) {
                if (npages && !old.rmap) {
-                       down_write(&current->mm->mmap_sem);
                        memslot->userspace_addr = do_mmap(NULL, 0,
                                                     npages * PAGE_SIZE,
                                                     PROT_READ | PROT_WRITE,
                                                     MAP_SHARED | MAP_ANONYMOUS,
                                                     0);
-                       up_write(&current->mm->mmap_sem);
 
                        if (IS_ERR((void *)memslot->userspace_addr))
                                return PTR_ERR((void *)memslot->userspace_addr);
@@ -3116,10 +3239,8 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
                        if (!old.user_alloc && old.rmap) {
                                int ret;
 
-                               down_write(&current->mm->mmap_sem);
                                ret = do_munmap(current->mm, old.userspace_addr,
                                                old.npages * PAGE_SIZE);
-                               up_write(&current->mm->mmap_sem);
                                if (ret < 0)
                                        printk(KERN_WARNING
                                       "kvm_vm_ioctl_set_memory_region: "
@@ -3144,3 +3265,23 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
        return vcpu->arch.mp_state == VCPU_MP_STATE_RUNNABLE
               || vcpu->arch.mp_state == VCPU_MP_STATE_SIPI_RECEIVED;
 }
+
+static void vcpu_kick_intr(void *info)
+{
+#ifdef DEBUG
+       struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
+       printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
+#endif
+}
+
+void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
+{
+       int ipi_pcpu = vcpu->cpu;
+
+       if (waitqueue_active(&vcpu->wq)) {
+               wake_up_interruptible(&vcpu->wq);
+               ++vcpu->stat.halt_wakeup;
+       }
+       if (vcpu->guest_mode)
+               smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
+}