struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
 {
+       struct page *page;
+
        gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
 
        if (gpa == UNMAPPED_GVA)
                return NULL;
-       return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+
+       down_read(¤t->mm->mmap_sem);
+       page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+       up_read(¤t->mm->mmap_sem);
+
+       return page;
 }
 
 static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 
        struct page *page;
 
+       down_read(&vcpu->kvm->slots_lock);
+
        down_read(¤t->mm->mmap_sem);
        page = gfn_to_page(vcpu->kvm, gfn);
+       up_read(¤t->mm->mmap_sem);
 
        spin_lock(&vcpu->kvm->mmu_lock);
        kvm_mmu_free_some_pages(vcpu);
        r = __nonpaging_map(vcpu, v, write, gfn, page);
        spin_unlock(&vcpu->kvm->mmu_lock);
 
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        return r;
 }
        gfn_t gfn;
        int r;
        u64 gpte = 0;
+       struct page *page;
 
        if (bytes != 4 && bytes != 8)
                return;
        if (!is_present_pte(gpte))
                return;
        gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
+
+       down_read(¤t->mm->mmap_sem);
+       page = gfn_to_page(vcpu->kvm, gfn);
+       up_read(¤t->mm->mmap_sem);
+
        vcpu->arch.update_pte.gfn = gfn;
        vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn);
 }
        gpa_t gpa;
        int r;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        spin_lock(&vcpu->kvm->mmu_lock);
        r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
 
        pt_element_t *table;
        struct page *page;
 
+       down_read(¤t->mm->mmap_sem);
        page = gfn_to_page(kvm, table_gfn);
+       up_read(¤t->mm->mmap_sem);
+
        table = kmap_atomic(page, KM_USER0);
 
        ret = CMPXCHG(&table[index], orig_pte, new_pte);
        if (r)
                return r;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        /*
         * Look up the shadow pte for the faulting address.
         */
                pgprintk("%s: guest page fault\n", __FUNCTION__);
                inject_page_fault(vcpu, addr, walker.error_code);
                vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
-               up_read(¤t->mm->mmap_sem);
+               up_read(&vcpu->kvm->slots_lock);
                return 0;
        }
 
+       down_read(¤t->mm->mmap_sem);
        page = gfn_to_page(vcpu->kvm, walker.gfn);
+       up_read(¤t->mm->mmap_sem);
 
        spin_lock(&vcpu->kvm->mmu_lock);
        kvm_mmu_free_some_pages(vcpu);
         */
        if (shadow_pte && is_io_pte(*shadow_pte)) {
                spin_unlock(&vcpu->kvm->mmu_lock);
-               up_read(¤t->mm->mmap_sem);
+               up_read(&vcpu->kvm->slots_lock);
                return 1;
        }
 
        ++vcpu->stat.pf_fixed;
        kvm_mmu_audit(vcpu, "post page fault (fixed)");
        spin_unlock(&vcpu->kvm->mmu_lock);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        return write_pt;
 }
 
        int ret;
        u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)];
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte,
                                  offset * sizeof(u64), sizeof(pdpte));
        if (ret < 0) {
 
        memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
 out:
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        return ret;
 }
        if (is_long_mode(vcpu) || !is_pae(vcpu))
                return false;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        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:
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        return changed;
 }
                 */
        }
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        /*
         * Does the new cr3 value map to physical memory? (Note, we
         * catch an invalid cr3 even in real-mode, because it would
                vcpu->arch.cr3 = cr3;
                vcpu->arch.mmu.new_cr3(vcpu);
        }
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 }
 EXPORT_SYMBOL_GPL(set_cr3);
 
        if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
                return -EINVAL;
 
-       down_write(¤t->mm->mmap_sem);
+       down_write(&kvm->slots_lock);
 
        kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
        kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
 
-       up_write(¤t->mm->mmap_sem);
+       up_write(&kvm->slots_lock);
        return 0;
 }
 
            < alias->target_phys_addr)
                goto out;
 
-       down_write(¤t->mm->mmap_sem);
+       down_write(&kvm->slots_lock);
 
        p = &kvm->arch.aliases[alias->slot];
        p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
 
        kvm_mmu_zap_all(kvm);
 
-       up_write(¤t->mm->mmap_sem);
+       up_write(&kvm->slots_lock);
 
        return 0;
 
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
-       down_write(¤t->mm->mmap_sem);
+       down_write(&kvm->slots_lock);
 
        r = kvm_get_dirty_log(kvm, log, &is_dirty);
        if (r)
        }
        r = 0;
 out:
-       up_write(¤t->mm->mmap_sem);
+       up_write(&kvm->slots_lock);
        return r;
 }
 
        void *data = val;
        int r = X86EMUL_CONTINUE;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        while (bytes) {
                gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
                unsigned offset = addr & (PAGE_SIZE-1);
                addr += tocopy;
        }
 out:
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
        return r;
 }
 EXPORT_SYMBOL_GPL(emulator_read_std);
                return X86EMUL_CONTINUE;
        }
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        /* For APIC access vmexit */
        if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
 {
        int ret;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
        if (ret < 0) {
-               up_read(¤t->mm->mmap_sem);
+               up_read(&vcpu->kvm->slots_lock);
                return 0;
        }
        kvm_mmu_pte_write(vcpu, gpa, val, bytes);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
        return 1;
 }
 
        struct kvm_io_device *mmio_dev;
        gpa_t                 gpa;
 
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
 
        if (gpa == UNMAPPED_GVA) {
                kvm_inject_page_fault(vcpu, addr, 2);
                char *kaddr;
                u64 val;
 
-               down_read(¤t->mm->mmap_sem);
+               down_read(&vcpu->kvm->slots_lock);
                gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
 
                if (gpa == UNMAPPED_GVA ||
                        goto emul_write;
 
                val = *(u64 *)new;
+
+               down_read(¤t->mm->mmap_sem);
                page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+               up_read(¤t->mm->mmap_sem);
+
                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(¤t->mm->mmap_sem);
+               up_read(&vcpu->kvm->slots_lock);
        }
 #endif
 
                kvm_x86_ops->skip_emulated_instruction(vcpu);
 
        for (i = 0; i < nr_pages; ++i) {
-               down_read(¤t->mm->mmap_sem);
+               down_read(&vcpu->kvm->slots_lock);
                page = gva_to_page(vcpu, address + i * PAGE_SIZE);
                vcpu->arch.pio.guest_pages[i] = page;
-               up_read(¤t->mm->mmap_sem);
+               up_read(&vcpu->kvm->slots_lock);
                if (!page) {
                        kvm_inject_gp(vcpu, 0);
                        free_pio_guest_pages(vcpu);
 
        down_read(¤t->mm->mmap_sem);
        page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
-       vcpu->arch.apic->vapic_page = page;
        up_read(¤t->mm->mmap_sem);
+
+       vcpu->arch.apic->vapic_page = page;
 }
 
 static void vapic_exit(struct kvm_vcpu *vcpu)
        gpa_t gpa;
 
        vcpu_load(vcpu);
-       down_read(¤t->mm->mmap_sem);
+       down_read(&vcpu->kvm->slots_lock);
        gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr);
-       up_read(¤t->mm->mmap_sem);
+       up_read(&vcpu->kvm->slots_lock);
        tr->physical_address = gpa;
        tr->valid = gpa != UNMAPPED_GVA;
        tr->writeable = 1;
         */
        if (!user_alloc) {
                if (npages && !old.rmap) {
+                       down_write(¤t->mm->mmap_sem);
                        memslot->userspace_addr = do_mmap(NULL, 0,
                                                     npages * PAGE_SIZE,
                                                     PROT_READ | PROT_WRITE,
                                                     MAP_SHARED | MAP_ANONYMOUS,
                                                     0);
+                       up_write(¤t->mm->mmap_sem);
 
                        if (IS_ERR((void *)memslot->userspace_addr))
                                return PTR_ERR((void *)memslot->userspace_addr);
                        if (!old.user_alloc && old.rmap) {
                                int ret;
 
+                               down_write(¤t->mm->mmap_sem);
                                ret = do_munmap(current->mm, old.userspace_addr,
                                                old.npages * PAGE_SIZE);
+                               up_write(¤t->mm->mmap_sem);
                                if (ret < 0)
                                        printk(KERN_WARNING
                                       "kvm_vm_ioctl_set_memory_region: "