ia64/xen-unstable

changeset 15320:13d5a4ad57d0

[IA64] Implement gnttab replace_and_unmap

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__ */