ia64/xen-unstable
changeset 15320:13d5a4ad57d0
[IA64] Implement gnttab replace_and_unmap
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author | Alex Williamson <alex.williamson@hp.com> |
---|---|
date | Tue Jun 12 08:48:02 2007 -0600 (2007-06-12) |
parents | 2d72521fbdfd |
children | ba1f933f2382 |
files | xen/arch/ia64/xen/mm.c xen/include/asm-ia64/grant_table.h |
line diff
1.1 --- a/xen/arch/ia64/xen/mm.c Tue Jun 12 08:39:24 2007 -0600 1.2 +++ b/xen/arch/ia64/xen/mm.c Tue Jun 12 08:48:02 2007 -0600 1.3 @@ -1547,13 +1547,55 @@ replace_grant_host_mapping(unsigned long 1.4 volatile pte_t* pte; 1.5 unsigned long cur_arflags; 1.6 pte_t cur_pte; 1.7 - pte_t new_pte; 1.8 + pte_t new_pte = __pte(0); 1.9 pte_t old_pte; 1.10 struct page_info* page = mfn_to_page(mfn); 1.11 + struct page_info* new_page = NULL; 1.12 + volatile pte_t* new_page_pte = NULL; 1.13 1.14 if (new_gpaddr) { 1.15 - gdprintk(XENLOG_INFO, "%s: new_gpaddr 0x%lx\n", __func__, new_gpaddr); 1.16 - return GNTST_general_error; 1.17 + new_page_pte = lookup_noalloc_domain_pte_none(d, new_gpaddr); 1.18 + if (likely(new_page_pte != NULL)) { 1.19 + new_pte = ptep_get_and_clear(&d->arch.mm, 1.20 + new_gpaddr, new_page_pte); 1.21 + if (likely(pte_present(new_pte))) { 1.22 + unsigned long new_page_mfn; 1.23 + struct domain* page_owner; 1.24 + 1.25 + new_page_mfn = pte_pfn(new_pte); 1.26 + new_page = mfn_to_page(new_page_mfn); 1.27 + page_owner = page_get_owner(new_page); 1.28 + if (unlikely(page_owner == NULL)) { 1.29 + gdprintk(XENLOG_INFO, 1.30 + "%s: page_owner == NULL " 1.31 + "gpaddr 0x%lx mfn 0x%lx " 1.32 + "new_gpaddr 0x%lx mfn 0x%lx\n", 1.33 + __func__, gpaddr, mfn, new_gpaddr, new_page_mfn); 1.34 + new_page = NULL; /* prevent domain_put_page() */ 1.35 + goto out; 1.36 + } 1.37 + 1.38 + /* 1.39 + * domain_put_page(clear_PGC_allcoated = 0) 1.40 + * doesn't decrement refcount of page with 1.41 + * pte_ptc_allocated() = 1. Be carefull. 1.42 + */ 1.43 + if (unlikely(!pte_pgc_allocated(new_pte))) { 1.44 + /* domain_put_page() decrements page refcount. adjust it. */ 1.45 + if (get_page(new_page, page_owner)) { 1.46 + gdprintk(XENLOG_INFO, 1.47 + "%s: get_page() failed. " 1.48 + "gpaddr 0x%lx mfn 0x%lx " 1.49 + "new_gpaddr 0x%lx mfn 0x%lx\n", 1.50 + __func__, gpaddr, mfn, 1.51 + new_gpaddr, new_page_mfn); 1.52 + goto out; 1.53 + } 1.54 + } 1.55 + domain_put_page(d, new_gpaddr, new_page_pte, new_pte, 0); 1.56 + } else 1.57 + new_pte = __pte(0); 1.58 + } 1.59 } 1.60 1.61 if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) { 1.62 @@ -1565,7 +1607,7 @@ replace_grant_host_mapping(unsigned long 1.63 if (pte == NULL) { 1.64 gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx\n", 1.65 __func__, gpaddr, mfn); 1.66 - return GNTST_general_error; 1.67 + goto out; 1.68 } 1.69 1.70 again: 1.71 @@ -1575,16 +1617,15 @@ replace_grant_host_mapping(unsigned long 1.72 (page_get_owner(page) == d && get_gpfn_from_mfn(mfn) == gpfn)) { 1.73 gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx cur_pte 0x%lx\n", 1.74 __func__, gpaddr, mfn, pte_val(cur_pte)); 1.75 - return GNTST_general_error; 1.76 + goto out; 1.77 } 1.78 - new_pte = __pte(0); 1.79 1.80 old_pte = ptep_cmpxchg_rel(&d->arch.mm, gpaddr, pte, cur_pte, new_pte); 1.81 if (unlikely(!pte_present(old_pte))) { 1.82 gdprintk(XENLOG_INFO, "%s: gpaddr 0x%lx mfn 0x%lx" 1.83 " cur_pte 0x%lx old_pte 0x%lx\n", 1.84 __func__, gpaddr, mfn, pte_val(cur_pte), pte_val(old_pte)); 1.85 - return GNTST_general_error; 1.86 + goto out; 1.87 } 1.88 if (unlikely(pte_val(cur_pte) != pte_val(old_pte))) { 1.89 if (pte_pfn(old_pte) == mfn) { 1.90 @@ -1593,7 +1634,7 @@ replace_grant_host_mapping(unsigned long 1.91 gdprintk(XENLOG_INFO, "%s gpaddr 0x%lx mfn 0x%lx cur_pte " 1.92 "0x%lx old_pte 0x%lx\n", 1.93 __func__, gpaddr, mfn, pte_val(cur_pte), pte_val(old_pte)); 1.94 - return GNTST_general_error; 1.95 + goto out; 1.96 } 1.97 BUG_ON(pte_pfn(old_pte) != mfn); 1.98 1.99 @@ -1605,6 +1646,11 @@ replace_grant_host_mapping(unsigned long 1.100 1.101 perfc_incr(replace_grant_host_mapping); 1.102 return GNTST_okay; 1.103 + 1.104 + out: 1.105 + if (new_page) 1.106 + domain_put_page(d, new_gpaddr, new_page_pte, new_pte, 1); 1.107 + return GNTST_general_error; 1.108 } 1.109 1.110 // heavily depends on the struct page layout.
2.1 --- a/xen/include/asm-ia64/grant_table.h Tue Jun 12 08:39:24 2007 -0600 2.2 +++ b/xen/include/asm-ia64/grant_table.h Tue Jun 12 08:48:02 2007 -0600 2.3 @@ -69,7 +69,7 @@ static inline void gnttab_clear_flag(uns 2.4 2.5 static inline int replace_grant_supported(void) 2.6 { 2.7 - return 0; 2.8 + return 1; 2.9 } 2.10 2.11 #endif /* __ASM_GRANT_TABLE_H__ */