[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Implement gnttab replace_and_unmap
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1181659682 21600 # Node ID 13d5a4ad57d00d063126fd009f28354f45ac1be5 # Parent 2d72521fbdfddbfc53bcd9cb4b293a762ddd2905 [IA64] Implement gnttab replace_and_unmap Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> --- xen/arch/ia64/xen/mm.c | 64 +++++++++++++++++++++++++++++++------ xen/include/asm-ia64/grant_table.h | 2 - 2 files changed, 56 insertions(+), 10 deletions(-) diff -r 2d72521fbdfd -r 13d5a4ad57d0 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Tue Jun 12 08:39:24 2007 -0600 +++ b/xen/arch/ia64/xen/mm.c Tue Jun 12 08:48:02 2007 -0600 @@ -1547,13 +1547,55 @@ replace_grant_host_mapping(unsigned long volatile pte_t* pte; unsigned long cur_arflags; pte_t cur_pte; - pte_t new_pte; + pte_t new_pte = __pte(0); pte_t old_pte; struct page_info* page = mfn_to_page(mfn); + struct page_info* new_page = NULL; + volatile pte_t* new_page_pte = NULL; if (new_gpaddr) { - gdprintk(XENLOG_INFO, "%s: new_gpaddr 0x%lx\n", __func__, new_gpaddr); - return GNTST_general_error; + new_page_pte = lookup_noalloc_domain_pte_none(d, new_gpaddr); + if (likely(new_page_pte != NULL)) { + new_pte = ptep_get_and_clear(&d->arch.mm, + new_gpaddr, new_page_pte); + if (likely(pte_present(new_pte))) { + unsigned long new_page_mfn; + struct domain* page_owner; + + new_page_mfn = pte_pfn(new_pte); + new_page = mfn_to_page(new_page_mfn); + page_owner = page_get_owner(new_page); + if (unlikely(page_owner == NULL)) { + gdprintk(XENLOG_INFO, + "%s: page_owner == NULL " + "gpaddr 0x%lx mfn 0x%lx " + "new_gpaddr 0x%lx mfn 0x%lx\n", + __func__, gpaddr, mfn, new_gpaddr, new_page_mfn); + new_page = NULL; /* prevent domain_put_page() */ + goto out; + } + + /* + * domain_put_page(clear_PGC_allcoated = 0) + * doesn't decrement refcount of page with + * pte_ptc_allocated() = 1. Be carefull. + */ + if (unlikely(!pte_pgc_allocated(new_pte))) { + /* domain_put_page() decrements page refcount. adjust it. */ + if (get_page(new_page, page_owner)) { + gdprintk(XENLOG_INFO, + "%s: get_page() failed. " + "gpaddr 0x%lx mfn 0x%lx " + "new_gpaddr 0x%lx mfn 0x%lx\n", + __func__, gpaddr, mfn, + new_gpaddr, new_page_mfn); + goto out; + } + } + domain_put_page(d, new_gpaddr, new_page_pte, new_pte, 0); + } else + new_pte = __pte(0); + } } if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) { @@ -1565,7 +1607,7 @@ replace_grant_host_mapping(unsigned long if (pte == NULL) { gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx\n", __func__, gpaddr, mfn); - return GNTST_general_error; + goto out; } again: @@ -1575,16 +1617,15 @@ replace_grant_host_mapping(unsigned long (page_get_owner(page) == d && get_gpfn_from_mfn(mfn) == gpfn)) { gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx cur_pte 0x%lx\n", __func__, gpaddr, mfn, pte_val(cur_pte)); - return GNTST_general_error; - } - new_pte = __pte(0); + goto out; + } old_pte = ptep_cmpxchg_rel(&d->arch.mm, gpaddr, pte, cur_pte, new_pte); if (unlikely(!pte_present(old_pte))) { gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx" " cur_pte 0x%lx old_pte 0x%lx\n", __func__, gpaddr, mfn, pte_val(cur_pte), pte_val(old_pte)); - return GNTST_general_error; + goto out; } if (unlikely(pte_val(cur_pte) != pte_val(old_pte))) { if (pte_pfn(old_pte) == mfn) { @@ -1593,7 +1634,7 @@ replace_grant_host_mapping(unsigned long gdprintk(XENLOG_INFO, "%s gpaddr 0x%lx mfn 0x%lx cur_pte " "0x%lx old_pte 0x%lx\n", __func__, gpaddr, mfn, pte_val(cur_pte), pte_val(old_pte)); - return GNTST_general_error; + goto out; } BUG_ON(pte_pfn(old_pte) != mfn); @@ -1605,6 +1646,11 @@ replace_grant_host_mapping(unsigned long perfc_incr(replace_grant_host_mapping); return GNTST_okay; + + out: + if (new_page) + domain_put_page(d, new_gpaddr, new_page_pte, new_pte, 1); + return GNTST_general_error; } // heavily depends on the struct page layout. diff -r 2d72521fbdfd -r 13d5a4ad57d0 xen/include/asm-ia64/grant_table.h --- a/xen/include/asm-ia64/grant_table.h Tue Jun 12 08:39:24 2007 -0600 +++ b/xen/include/asm-ia64/grant_table.h Tue Jun 12 08:48:02 2007 -0600 @@ -69,7 +69,7 @@ static inline void gnttab_clear_flag(uns static inline int replace_grant_supported(void) { - return 0; + return 1; } #endif /* __ASM_GRANT_TABLE_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |