[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 05 of 11] x86/mm: Use get_page_from_gfn() instead of get_gfn()/put_gfn
# HG changeset patch # User Tim Deegan <tim@xxxxxxx> # Date 1336661656 -3600 # Node ID c68f83ff7bf403637ade5a6002a7749226602c05 # Parent 9da426cdc7e478e426bcbd5391b8deacdc85db1e x86/mm: Use get_page_from_gfn() instead of get_gfn()/put_gfn. Signed-off-by: Tim Deegan <tim@xxxxxxx> Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx> diff -r 9da426cdc7e4 -r c68f83ff7bf4 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Thu May 10 15:54:16 2012 +0100 +++ b/xen/arch/x86/mm.c Thu May 10 15:54:16 2012 +0100 @@ -651,7 +651,8 @@ int map_ldt_shadow_page(unsigned int off { struct vcpu *v = current; struct domain *d = v->domain; - unsigned long gmfn, mfn; + unsigned long gmfn; + struct page_info *page; l1_pgentry_t l1e, nl1e; unsigned long gva = v->arch.pv_vcpu.ldt_base + (off << PAGE_SHIFT); int okay; @@ -663,28 +664,24 @@ int map_ldt_shadow_page(unsigned int off return 0; gmfn = l1e_get_pfn(l1e); - mfn = get_gfn_untyped(d, gmfn); - if ( unlikely(!mfn_valid(mfn)) ) + page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); + if ( unlikely(!page) ) + return 0; + + okay = get_page_type(page, PGT_seg_desc_page); + if ( unlikely(!okay) ) { - put_gfn(d, gmfn); + put_page(page); return 0; } - okay = get_page_and_type(mfn_to_page(mfn), d, PGT_seg_desc_page); - if ( unlikely(!okay) ) - { - put_gfn(d, gmfn); - return 0; - } - - nl1e = l1e_from_pfn(mfn, l1e_get_flags(l1e) | _PAGE_RW); + nl1e = l1e_from_pfn(page_to_mfn(page), l1e_get_flags(l1e) | _PAGE_RW); spin_lock(&v->arch.pv_vcpu.shadow_ldt_lock); l1e_write(&v->arch.perdomain_ptes[off + 16], nl1e); v->arch.pv_vcpu.shadow_ldt_mapcnt++; spin_unlock(&v->arch.pv_vcpu.shadow_ldt_lock); - put_gfn(d, gmfn); return 1; } @@ -1819,7 +1816,6 @@ static int mod_l1_entry(l1_pgentry_t *pl { l1_pgentry_t ol1e; struct domain *pt_dom = pt_vcpu->domain; - p2m_type_t p2mt; int rc = 0; if ( unlikely(__copy_from_user(&ol1e, pl1e, sizeof(ol1e)) != 0) ) @@ -1835,22 +1831,21 @@ static int mod_l1_entry(l1_pgentry_t *pl if ( l1e_get_flags(nl1e) & _PAGE_PRESENT ) { /* Translate foreign guest addresses. */ - unsigned long mfn, gfn; - gfn = l1e_get_pfn(nl1e); - mfn = mfn_x(get_gfn(pg_dom, gfn, &p2mt)); - if ( !p2m_is_ram(p2mt) || unlikely(mfn == INVALID_MFN) ) + struct page_info *page = NULL; + if ( paging_mode_translate(pg_dom) ) { - put_gfn(pg_dom, gfn); - return -EINVAL; + page = get_page_from_gfn(pg_dom, l1e_get_pfn(nl1e), NULL, P2M_ALLOC); + if ( !page ) + return -EINVAL; + nl1e = l1e_from_pfn(page_to_mfn(page), l1e_get_flags(nl1e)); } - ASSERT((mfn & ~(PADDR_MASK >> PAGE_SHIFT)) == 0); - nl1e = l1e_from_pfn(mfn, l1e_get_flags(nl1e)); if ( unlikely(l1e_get_flags(nl1e) & l1_disallow_mask(pt_dom)) ) { MEM_LOG("Bad L1 flags %x", l1e_get_flags(nl1e) & l1_disallow_mask(pt_dom)); - put_gfn(pg_dom, gfn); + if ( page ) + put_page(page); return -EINVAL; } @@ -1860,15 +1855,21 @@ static int mod_l1_entry(l1_pgentry_t *pl adjust_guest_l1e(nl1e, pt_dom); if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, preserve_ad) ) + { + if ( page ) + put_page(page); return 0; - put_gfn(pg_dom, gfn); + } + if ( page ) + put_page(page); return -EBUSY; } switch ( rc = get_page_from_l1e(nl1e, pt_dom, pg_dom) ) { default: - put_gfn(pg_dom, gfn); + if ( page ) + put_page(page); return rc; case 0: break; @@ -1876,7 +1877,9 @@ static int mod_l1_entry(l1_pgentry_t *pl l1e_remove_flags(nl1e, _PAGE_RW); break; } - + if ( page ) + put_page(page); + adjust_guest_l1e(nl1e, pt_dom); if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, preserve_ad)) ) @@ -1884,7 +1887,6 @@ static int mod_l1_entry(l1_pgentry_t *pl ol1e = nl1e; rc = -EBUSY; } - put_gfn(pg_dom, gfn); } else if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, preserve_ad)) ) @@ -3042,7 +3044,6 @@ int do_mmuext_op( type = PGT_l4_page_table; pin_page: { - unsigned long mfn; struct page_info *page; /* Ignore pinning of invalid paging levels. */ @@ -3052,25 +3053,28 @@ int do_mmuext_op( if ( paging_mode_refcounts(pg_owner) ) break; - mfn = get_gfn_untyped(pg_owner, op.arg1.mfn); - rc = get_page_and_type_from_pagenr(mfn, type, pg_owner, 0, 1); + page = get_page_from_gfn(pg_owner, op.arg1.mfn, NULL, P2M_ALLOC); + if ( unlikely(!page) ) + { + rc = -EINVAL; + break; + } + + rc = get_page_type_preemptible(page, type); okay = !rc; if ( unlikely(!okay) ) { if ( rc == -EINTR ) rc = -EAGAIN; else if ( rc != -EAGAIN ) - MEM_LOG("Error while pinning mfn %lx", mfn); - put_gfn(pg_owner, op.arg1.mfn); + MEM_LOG("Error while pinning mfn %lx", page_to_mfn(page)); + put_page(page); break; } - page = mfn_to_page(mfn); - if ( (rc = xsm_memory_pin_page(d, page)) != 0 ) { put_page_and_type(page); - put_gfn(pg_owner, op.arg1.mfn); okay = 0; break; } @@ -3078,16 +3082,15 @@ int do_mmuext_op( if ( unlikely(test_and_set_bit(_PGT_pinned, &page->u.inuse.type_info)) ) { - MEM_LOG("Mfn %lx already pinned", mfn); + MEM_LOG("Mfn %lx already pinned", page_to_mfn(page)); put_page_and_type(page); - put_gfn(pg_owner, op.arg1.mfn); okay = 0; break; } /* A page is dirtied when its pin status is set. */ - paging_mark_dirty(pg_owner, mfn); - + paging_mark_dirty(pg_owner, page_to_mfn(page)); + /* We can race domain destruction (domain_relinquish_resources). */ if ( unlikely(pg_owner != d) ) { @@ -3099,35 +3102,29 @@ int do_mmuext_op( spin_unlock(&pg_owner->page_alloc_lock); if ( drop_ref ) put_page_and_type(page); - put_gfn(pg_owner, op.arg1.mfn); } break; } case MMUEXT_UNPIN_TABLE: { - unsigned long mfn; struct page_info *page; if ( paging_mode_refcounts(pg_owner) ) break; - mfn = get_gfn_untyped(pg_owner, op.arg1.mfn); - if ( unlikely(!(okay = get_page_from_pagenr(mfn, pg_owner))) ) + page = get_page_from_gfn(pg_owner, op.arg1.mfn, NULL, P2M_ALLOC); + if ( unlikely(!page) ) { - put_gfn(pg_owner, op.arg1.mfn); - MEM_LOG("Mfn %lx bad domain", mfn); + MEM_LOG("Mfn %lx bad domain", op.arg1.mfn); break; } - page = mfn_to_page(mfn); - if ( !test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) { okay = 0; put_page(page); - put_gfn(pg_owner, op.arg1.mfn); - MEM_LOG("Mfn %lx not pinned", mfn); + MEM_LOG("Mfn %lx not pinned", op.arg1.mfn); break; } @@ -3135,40 +3132,43 @@ int do_mmuext_op( put_page(page); /* A page is dirtied when its pin status is cleared. */ - paging_mark_dirty(pg_owner, mfn); - - put_gfn(pg_owner, op.arg1.mfn); + paging_mark_dirty(pg_owner, page_to_mfn(page)); + break; } case MMUEXT_NEW_BASEPTR: - okay = new_guest_cr3(get_gfn_untyped(d, op.arg1.mfn)); - put_gfn(d, op.arg1.mfn); + okay = (!paging_mode_translate(d) + && new_guest_cr3(op.arg1.mfn)); break; + #ifdef __x86_64__ case MMUEXT_NEW_USER_BASEPTR: { - unsigned long old_mfn, mfn; - - mfn = get_gfn_untyped(d, op.arg1.mfn); - if ( mfn != 0 ) + unsigned long old_mfn; + + if ( paging_mode_translate(current->domain) ) + { + okay = 0; + break; + } + + if ( op.arg1.mfn != 0 ) { if ( paging_mode_refcounts(d) ) - okay = get_page_from_pagenr(mfn, d); + okay = get_page_from_pagenr(op.arg1.mfn, d); else okay = !get_page_and_type_from_pagenr( - mfn, PGT_root_page_table, d, 0, 0); + op.arg1.mfn, PGT_root_page_table, d, 0, 0); if ( unlikely(!okay) ) { - put_gfn(d, op.arg1.mfn); - MEM_LOG("Error while installing new mfn %lx", mfn); + MEM_LOG("Error while installing new mfn %lx", op.arg1.mfn); break; } } old_mfn = pagetable_get_pfn(curr->arch.guest_table_user); - curr->arch.guest_table_user = pagetable_from_pfn(mfn); - put_gfn(d, op.arg1.mfn); + curr->arch.guest_table_user = pagetable_from_pfn(op.arg1.mfn); if ( old_mfn != 0 ) { @@ -3283,28 +3283,27 @@ int do_mmuext_op( } case MMUEXT_CLEAR_PAGE: { - unsigned long mfn; + struct page_info *page; unsigned char *ptr; - mfn = get_gfn_untyped(d, op.arg1.mfn); - okay = !get_page_and_type_from_pagenr( - mfn, PGT_writable_page, d, 0, 0); - if ( unlikely(!okay) ) + page = get_page_from_gfn(d, op.arg1.mfn, NULL, P2M_ALLOC); + if ( !page || !get_page_type(page, PGT_writable_page) ) { - put_gfn(d, op.arg1.mfn); - MEM_LOG("Error while clearing mfn %lx", mfn); + if ( page ) + put_page(page); + MEM_LOG("Error while clearing mfn %lx", op.arg1.mfn); + okay = 0; break; } /* A page is dirtied when it's being cleared. */ - paging_mark_dirty(d, mfn); - - ptr = fixmap_domain_page(mfn); + paging_mark_dirty(d, page_to_mfn(page)); + + ptr = fixmap_domain_page(page_to_mfn(page)); clear_page(ptr); fixunmap_domain_page(ptr); - put_page_and_type(mfn_to_page(mfn)); - put_gfn(d, op.arg1.mfn); + put_page_and_type(page); break; } @@ -3312,42 +3311,38 @@ int do_mmuext_op( { const unsigned char *src; unsigned char *dst; - unsigned long src_mfn, mfn; - - src_mfn = get_gfn_untyped(d, op.arg2.src_mfn); - okay = get_page_from_pagenr(src_mfn, d); + struct page_info *src_page, *dst_page; + + src_page = get_page_from_gfn(d, op.arg2.src_mfn, NULL, P2M_ALLOC); + if ( unlikely(!src_page) ) + { + okay = 0; + MEM_LOG("Error while copying from mfn %lx", op.arg2.src_mfn); + break; + } + + dst_page = get_page_from_gfn(d, op.arg1.mfn, NULL, P2M_ALLOC); + okay = (dst_page && get_page_type(dst_page, PGT_writable_page)); if ( unlikely(!okay) ) { - put_gfn(d, op.arg2.src_mfn); - MEM_LOG("Error while copying from mfn %lx", src_mfn); + put_page(src_page); + if ( dst_page ) + put_page(dst_page); + MEM_LOG("Error while copying to mfn %lx", op.arg1.mfn); break; } - mfn = get_gfn_untyped(d, op.arg1.mfn); - okay = !get_page_and_type_from_pagenr( - mfn, PGT_writable_page, d, 0, 0); - if ( unlikely(!okay) ) - { - put_gfn(d, op.arg1.mfn); - put_page(mfn_to_page(src_mfn)); - put_gfn(d, op.arg2.src_mfn); - MEM_LOG("Error while copying to mfn %lx", mfn); - break; - } - /* A page is dirtied when it's being copied to. */ - paging_mark_dirty(d, mfn); - - src = map_domain_page(src_mfn); - dst = fixmap_domain_page(mfn); + paging_mark_dirty(d, page_to_mfn(dst_page)); + + src = __map_domain_page(src_page); + dst = fixmap_domain_page(page_to_mfn(dst_page)); copy_page(dst, src); fixunmap_domain_page(dst); unmap_domain_page(src); - put_page_and_type(mfn_to_page(mfn)); - put_gfn(d, op.arg1.mfn); - put_page(mfn_to_page(src_mfn)); - put_gfn(d, op.arg2.src_mfn); + put_page_and_type(dst_page); + put_page(src_page); break; } @@ -3538,29 +3533,26 @@ int do_mmu_update( req.ptr -= cmd; gmfn = req.ptr >> PAGE_SHIFT; - mfn = mfn_x(get_gfn(pt_owner, gmfn, &p2mt)); - if ( !p2m_is_valid(p2mt) ) - mfn = INVALID_MFN; + page = get_page_from_gfn(pt_owner, gmfn, &p2mt, P2M_ALLOC); if ( p2m_is_paged(p2mt) ) { - put_gfn(pt_owner, gmfn); + ASSERT(!page); p2m_mem_paging_populate(pg_owner, gmfn); rc = -ENOENT; break; } - if ( unlikely(!get_page_from_pagenr(mfn, pt_owner)) ) + if ( unlikely(!page) ) { MEM_LOG("Could not get page for normal update"); - put_gfn(pt_owner, gmfn); break; } + mfn = page_to_mfn(page); va = map_domain_page_with_cache(mfn, &mapcache); va = (void *)((unsigned long)va + (unsigned long)(req.ptr & ~PAGE_MASK)); - page = mfn_to_page(mfn); if ( page_lock(page) ) { @@ -3569,22 +3561,23 @@ int do_mmu_update( case PGT_l1_page_table: { l1_pgentry_t l1e = l1e_from_intpte(req.val); - p2m_type_t l1e_p2mt; - unsigned long l1egfn = l1e_get_pfn(l1e), l1emfn; - - l1emfn = mfn_x(get_gfn(pg_owner, l1egfn, &l1e_p2mt)); + p2m_type_t l1e_p2mt = p2m_ram_rw; + struct page_info *target = NULL; + + if ( paging_mode_translate(pg_owner) ) + target = get_page_from_gfn(pg_owner, l1e_get_pfn(l1e), + &l1e_p2mt, P2M_ALLOC); if ( p2m_is_paged(l1e_p2mt) ) { - put_gfn(pg_owner, l1egfn); + if ( target ) + put_page(target); p2m_mem_paging_populate(pg_owner, l1e_get_pfn(l1e)); rc = -ENOENT; break; } - else if ( p2m_ram_paging_in == l1e_p2mt && - !mfn_valid(l1emfn) ) + else if ( p2m_ram_paging_in == l1e_p2mt && !target ) { - put_gfn(pg_owner, l1egfn); rc = -ENOENT; break; } @@ -3601,7 +3594,8 @@ int do_mmu_update( rc = mem_sharing_unshare_page(pg_owner, gfn, 0); if ( rc ) { - put_gfn(pg_owner, l1egfn); + if ( target ) + put_page(target); /* Notify helper, don't care about errors, will not * sleep on wq, since we're a foreign domain. */ (void)mem_sharing_notify_enomem(pg_owner, gfn, 0); @@ -3614,112 +3608,22 @@ int do_mmu_update( rc = mod_l1_entry(va, l1e, mfn, cmd == MMU_PT_UPDATE_PRESERVE_AD, v, pg_owner); - put_gfn(pg_owner, l1egfn); + if ( target ) + put_page(target); } break; case PGT_l2_page_table: - { - l2_pgentry_t l2e = l2e_from_intpte(req.val); - p2m_type_t l2e_p2mt; - unsigned long l2egfn = l2e_get_pfn(l2e), l2emfn; - - l2emfn = mfn_x(get_gfn(pg_owner, l2egfn, &l2e_p2mt)); - - if ( p2m_is_paged(l2e_p2mt) ) - { - put_gfn(pg_owner, l2egfn); - p2m_mem_paging_populate(pg_owner, l2egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_paging_in == l2e_p2mt && - !mfn_valid(l2emfn) ) - { - put_gfn(pg_owner, l2egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_shared == l2e_p2mt ) - { - put_gfn(pg_owner, l2egfn); - MEM_LOG("Unexpected attempt to map shared page.\n"); - break; - } - - - rc = mod_l2_entry(va, l2e, mfn, + rc = mod_l2_entry(va, l2e_from_intpte(req.val), mfn, cmd == MMU_PT_UPDATE_PRESERVE_AD, v); - put_gfn(pg_owner, l2egfn); - } - break; + break; case PGT_l3_page_table: - { - l3_pgentry_t l3e = l3e_from_intpte(req.val); - p2m_type_t l3e_p2mt; - unsigned long l3egfn = l3e_get_pfn(l3e), l3emfn; - - l3emfn = mfn_x(get_gfn(pg_owner, l3egfn, &l3e_p2mt)); - - if ( p2m_is_paged(l3e_p2mt) ) - { - put_gfn(pg_owner, l3egfn); - p2m_mem_paging_populate(pg_owner, l3egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_paging_in == l3e_p2mt && - !mfn_valid(l3emfn) ) - { - put_gfn(pg_owner, l3egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_shared == l3e_p2mt ) - { - put_gfn(pg_owner, l3egfn); - MEM_LOG("Unexpected attempt to map shared page.\n"); - break; - } - - rc = mod_l3_entry(va, l3e, mfn, + rc = mod_l3_entry(va, l3e_from_intpte(req.val), mfn, cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v); - put_gfn(pg_owner, l3egfn); - } - break; + break; #if CONFIG_PAGING_LEVELS >= 4 case PGT_l4_page_table: - { - l4_pgentry_t l4e = l4e_from_intpte(req.val); - p2m_type_t l4e_p2mt; - unsigned long l4egfn = l4e_get_pfn(l4e), l4emfn; - - l4emfn = mfn_x(get_gfn(pg_owner, l4egfn, &l4e_p2mt)); - - if ( p2m_is_paged(l4e_p2mt) ) - { - put_gfn(pg_owner, l4egfn); - p2m_mem_paging_populate(pg_owner, l4egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_paging_in == l4e_p2mt && - !mfn_valid(l4emfn) ) - { - put_gfn(pg_owner, l4egfn); - rc = -ENOENT; - break; - } - else if ( p2m_ram_shared == l4e_p2mt ) - { - put_gfn(pg_owner, l4egfn); - MEM_LOG("Unexpected attempt to map shared page.\n"); - break; - } - - rc = mod_l4_entry(va, l4e, mfn, + rc = mod_l4_entry(va, l4e_from_intpte(req.val), mfn, cmd == MMU_PT_UPDATE_PRESERVE_AD, 1, v); - put_gfn(pg_owner, l4egfn); - } break; #endif case PGT_writable_page: @@ -3742,7 +3646,6 @@ int do_mmu_update( unmap_domain_page_with_cache(va, &mapcache); put_page(page); - put_gfn(pt_owner, gmfn); } break; @@ -3829,18 +3732,17 @@ static int create_grant_pte_mapping( adjust_guest_l1e(nl1e, d); gmfn = pte_addr >> PAGE_SHIFT; - mfn = get_gfn_untyped(d, gmfn); - - if ( unlikely(!get_page_from_pagenr(mfn, current->domain)) ) + page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); + + if ( unlikely(!page) ) { - put_gfn(d, gmfn); MEM_LOG("Could not get page for normal update"); return GNTST_general_error; } + mfn = page_to_mfn(page); va = map_domain_page(mfn); va = (void *)((unsigned long)va + ((unsigned long)pte_addr & ~PAGE_MASK)); - page = mfn_to_page(mfn); if ( !page_lock(page) ) { @@ -3871,7 +3773,6 @@ static int create_grant_pte_mapping( failed: unmap_domain_page(va); put_page(page); - put_gfn(d, gmfn); return rc; } @@ -3886,18 +3787,17 @@ static int destroy_grant_pte_mapping( l1_pgentry_t ol1e; gmfn = addr >> PAGE_SHIFT; - mfn = get_gfn_untyped(d, gmfn); - - if ( unlikely(!get_page_from_pagenr(mfn, current->domain)) ) + page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC); + + if ( unlikely(!page) ) { - put_gfn(d, gmfn); MEM_LOG("Could not get page for normal update"); return GNTST_general_error; } + mfn = page_to_mfn(page); va = map_domain_page(mfn); va = (void *)((unsigned long)va + ((unsigned long)addr & ~PAGE_MASK)); - page = mfn_to_page(mfn); if ( !page_lock(page) ) { @@ -3942,7 +3842,6 @@ static int destroy_grant_pte_mapping( failed: unmap_domain_page(va); put_page(page); - put_gfn(d, gmfn); return rc; } @@ -4465,11 +4364,17 @@ long set_gdt(struct vcpu *v, /* Check the pages in the new GDT. */ for ( i = 0; i < nr_pages; i++ ) { + struct page_info *page; pfns[i] = frames[i]; - mfn = frames[i] = get_gfn_untyped(d, frames[i]); - if ( !mfn_valid(mfn) || - !get_page_and_type(mfn_to_page(mfn), d, PGT_seg_desc_page) ) + page = get_page_from_gfn(d, frames[i], NULL, P2M_ALLOC); + if ( !page ) goto fail; + if ( !get_page_type(page, PGT_seg_desc_page) ) + { + put_page(page); + goto fail; + } + mfn = frames[i] = page_to_mfn(page); } /* Tear down the old GDT. */ @@ -4482,7 +4387,6 @@ long set_gdt(struct vcpu *v, v->arch.pv_vcpu.gdt_frames[i] = frames[i]; l1e_write(&v->arch.perdomain_ptes[i], l1e_from_pfn(frames[i], __PAGE_HYPERVISOR)); - put_gfn(d, pfns[i]); } xfree(pfns); @@ -4492,7 +4396,6 @@ long set_gdt(struct vcpu *v, while ( i-- > 0 ) { put_page_and_type(mfn_to_page(frames[i])); - put_gfn(d, pfns[i]); } xfree(pfns); return -EINVAL; @@ -4538,21 +4441,16 @@ long do_update_descriptor(u64 pa, u64 de *(u64 *)&d = desc; - mfn = get_gfn_untyped(dom, gmfn); + page = get_page_from_gfn(dom, gmfn, NULL, P2M_ALLOC); if ( (((unsigned int)pa % sizeof(struct desc_struct)) != 0) || - !mfn_valid(mfn) || + !page || !check_descriptor(dom, &d) ) { - put_gfn(dom, gmfn); + if ( page ) + put_page(page); return -EINVAL; } - - page = mfn_to_page(mfn); - if ( unlikely(!get_page(page, dom)) ) - { - put_gfn(dom, gmfn); - return -EINVAL; - } + mfn = page_to_mfn(page); /* Check if the given frame is in use in an unsafe context. */ switch ( page->u.inuse.type_info & PGT_type_mask ) @@ -4580,7 +4478,6 @@ long do_update_descriptor(u64 pa, u64 de out: put_page(page); - put_gfn(dom, gmfn); return ret; } diff -r 9da426cdc7e4 -r c68f83ff7bf4 xen/arch/x86/mm/guest_walk.c --- a/xen/arch/x86/mm/guest_walk.c Thu May 10 15:54:16 2012 +0100 +++ b/xen/arch/x86/mm/guest_walk.c Thu May 10 15:54:16 2012 +0100 @@ -94,39 +94,37 @@ static inline void *map_domain_gfn(struc p2m_type_t *p2mt, uint32_t *rc) { - p2m_access_t p2ma; + struct page_info *page; void *map; /* Translate the gfn, unsharing if shared */ - *mfn = get_gfn_type_access(p2m, gfn_x(gfn), p2mt, &p2ma, - P2M_ALLOC | P2M_UNSHARE, NULL); + page = get_page_from_gfn_p2m(p2m->domain, p2m, gfn_x(gfn), p2mt, NULL, + P2M_ALLOC | P2M_UNSHARE); if ( p2m_is_paging(*p2mt) ) { ASSERT(!p2m_is_nestedp2m(p2m)); - __put_gfn(p2m, gfn_x(gfn)); + if ( page ) + put_page(page); p2m_mem_paging_populate(p2m->domain, gfn_x(gfn)); *rc = _PAGE_PAGED; return NULL; } if ( p2m_is_shared(*p2mt) ) { - __put_gfn(p2m, gfn_x(gfn)); + if ( page ) + put_page(page); *rc = _PAGE_SHARED; return NULL; } - if ( !p2m_is_ram(*p2mt) ) + if ( !page ) { - __put_gfn(p2m, gfn_x(gfn)); *rc |= _PAGE_PRESENT; return NULL; } + *mfn = _mfn(page_to_mfn(page)); ASSERT(mfn_valid(mfn_x(*mfn))); - - /* Get an extra ref to the page to ensure liveness of the map. - * Then we can safely put gfn */ - page_get_owner_and_reference(mfn_to_page(mfn_x(*mfn))); + map = map_domain_page(mfn_x(*mfn)); - __put_gfn(p2m, gfn_x(gfn)); return map; } diff -r 9da426cdc7e4 -r c68f83ff7bf4 xen/arch/x86/mm/hap/guest_walk.c --- a/xen/arch/x86/mm/hap/guest_walk.c Thu May 10 15:54:16 2012 +0100 +++ b/xen/arch/x86/mm/hap/guest_walk.c Thu May 10 15:54:16 2012 +0100 @@ -54,34 +54,36 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PA mfn_t top_mfn; void *top_map; p2m_type_t p2mt; - p2m_access_t p2ma; walk_t gw; unsigned long top_gfn; + struct page_info *top_page; /* Get the top-level table's MFN */ top_gfn = cr3 >> PAGE_SHIFT; - top_mfn = get_gfn_type_access(p2m, top_gfn, &p2mt, &p2ma, - P2M_ALLOC | P2M_UNSHARE, NULL); + top_page = get_page_from_gfn_p2m(p2m->domain, p2m, top_gfn, + &p2mt, NULL, P2M_ALLOC | P2M_UNSHARE); if ( p2m_is_paging(p2mt) ) { ASSERT(!p2m_is_nestedp2m(p2m)); pfec[0] = PFEC_page_paged; - __put_gfn(p2m, top_gfn); + if ( top_page ) + put_page(top_page); p2m_mem_paging_populate(p2m->domain, cr3 >> PAGE_SHIFT); return INVALID_GFN; } if ( p2m_is_shared(p2mt) ) { pfec[0] = PFEC_page_shared; - __put_gfn(p2m, top_gfn); + if ( top_page ) + put_page(top_page); return INVALID_GFN; } - if ( !p2m_is_ram(p2mt) ) + if ( !top_page ) { pfec[0] &= ~PFEC_page_present; - __put_gfn(p2m, top_gfn); return INVALID_GFN; } + top_mfn = _mfn(page_to_mfn(top_page)); /* Map the top-level table and call the tree-walker */ ASSERT(mfn_valid(mfn_x(top_mfn))); @@ -91,31 +93,30 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PA #endif missing = guest_walk_tables(v, p2m, ga, &gw, pfec[0], top_mfn, top_map); unmap_domain_page(top_map); - __put_gfn(p2m, top_gfn); + put_page(top_page); /* Interpret the answer */ if ( missing == 0 ) { gfn_t gfn = guest_l1e_get_gfn(gw.l1e); - (void)get_gfn_type_access(p2m, gfn_x(gfn), &p2mt, &p2ma, - P2M_ALLOC | P2M_UNSHARE, NULL); + struct page_info *page; + page = get_page_from_gfn_p2m(p2m->domain, p2m, gfn_x(gfn), &p2mt, + NULL, P2M_ALLOC | P2M_UNSHARE); + if ( page ) + put_page(page); if ( p2m_is_paging(p2mt) ) { ASSERT(!p2m_is_nestedp2m(p2m)); pfec[0] = PFEC_page_paged; - __put_gfn(p2m, gfn_x(gfn)); p2m_mem_paging_populate(p2m->domain, gfn_x(gfn)); return INVALID_GFN; } if ( p2m_is_shared(p2mt) ) { pfec[0] = PFEC_page_shared; - __put_gfn(p2m, gfn_x(gfn)); return INVALID_GFN; } - __put_gfn(p2m, gfn_x(gfn)); - if ( page_order ) *page_order = guest_walk_to_page_order(&gw); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |