From 2301f6145b93c7994b4b66e9aeb7775df03dc01f Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Sun, 1 May 2011 14:33:07 +0900 Subject: [PATCH] --- yaml --- r: 248111 b: refs/heads/master c: c8cfbb555eb3632bf3dcbe1a591c1f4d0c28681c h: refs/heads/master i: 248109: 03d1e5650b81db94d4e0dab18fe0419db9862eae 248107: 71e24985ea1fa207eb0e0f7261645161d8a6b07f 248103: ff7ad633917230cdb539cf01bfd22bd78b10100c 248095: 4a2acc9249e8f01242e13499b5bdbffa7762c69c v: v3 --- [refs] | 2 +- trunk/arch/x86/kvm/paging_tmpl.h | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 7929dff47903..598b7679279f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 85722cda308c0ad7390dc910139b2ce58c11b9c4 +refs/heads/master: c8cfbb555eb3632bf3dcbe1a591c1f4d0c28681c diff --git a/trunk/arch/x86/kvm/paging_tmpl.h b/trunk/arch/x86/kvm/paging_tmpl.h index e3f81418797e..6c4dc010c4cb 100644 --- a/trunk/arch/x86/kvm/paging_tmpl.h +++ b/trunk/arch/x86/kvm/paging_tmpl.h @@ -79,21 +79,19 @@ static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) } static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - gfn_t table_gfn, unsigned index, - pt_element_t orig_pte, pt_element_t new_pte) + pt_element_t __user *ptep_user, unsigned index, + pt_element_t orig_pte, pt_element_t new_pte) { + int npages; pt_element_t ret; pt_element_t *table; struct page *page; - gpa_t gpa; - gpa = mmu->translate_gpa(vcpu, table_gfn << PAGE_SHIFT, - PFERR_USER_MASK|PFERR_WRITE_MASK); - if (gpa == UNMAPPED_GVA) + npages = get_user_pages_fast((unsigned long)ptep_user, 1, 1, &page); + /* Check if the user is doing something meaningless. */ + if (unlikely(npages != 1)) return -EFAULT; - page = gfn_to_page(vcpu->kvm, gpa_to_gfn(gpa)); - table = kmap_atomic(page, KM_USER0); ret = CMPXCHG(&table[index], orig_pte, new_pte); kunmap_atomic(table, KM_USER0); @@ -220,9 +218,9 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, int ret; trace_kvm_mmu_set_accessed_bit(table_gfn, index, sizeof(pte)); - ret = FNAME(cmpxchg_gpte)(vcpu, mmu, table_gfn, - index, pte, pte|PT_ACCESSED_MASK); - if (ret < 0) { + ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index, + pte, pte|PT_ACCESSED_MASK); + if (unlikely(ret < 0)) { present = false; break; } else if (ret) @@ -279,9 +277,9 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, int ret; trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); - ret = FNAME(cmpxchg_gpte)(vcpu, mmu, table_gfn, index, pte, - pte|PT_DIRTY_MASK); - if (ret < 0) { + ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index, + pte, pte|PT_DIRTY_MASK); + if (unlikely(ret < 0)) { present = false; goto error; } else if (ret)