ia64/xen-unstable

changeset 10422:7e26d6ffdde7

[IA64] add INVALID_MFN check to dom0vp_zap_physmap()

guest_physmap_remove_page() should check mfn.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Mon Jun 19 12:54:34 2006 -0600 (2006-06-19)
parents f02d59f9b11f
children d60da6514d65
files xen/arch/ia64/xen/mm.c
line diff
     1.1 --- a/xen/arch/ia64/xen/mm.c	Mon Jun 19 12:52:38 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/mm.c	Mon Jun 19 12:54:34 2006 -0600
     1.3 @@ -891,12 +891,11 @@ assign_domain_page_cmpxchg_rel(struct do
     1.4  }
     1.5  
     1.6  static void
     1.7 -zap_domain_page_one(struct domain *d, unsigned long mpaddr)
     1.8 +zap_domain_page_one(struct domain *d, unsigned long mpaddr, unsigned long mfn)
     1.9  {
    1.10      struct mm_struct *mm = &d->arch.mm;
    1.11      volatile pte_t *pte;
    1.12      pte_t old_pte;
    1.13 -    unsigned long mfn;
    1.14      struct page_info *page;
    1.15  
    1.16      pte = lookup_noalloc_domain_pte_none(d, mpaddr);
    1.17 @@ -905,9 +904,38 @@ zap_domain_page_one(struct domain *d, un
    1.18      if (pte_none(*pte))
    1.19          return;
    1.20  
    1.21 -    // update pte
    1.22 -    old_pte = ptep_get_and_clear(mm, mpaddr, pte);
    1.23 -    mfn = pte_pfn(old_pte);
    1.24 +    if (mfn == INVALID_MFN) {
    1.25 +        // clear pte
    1.26 +        old_pte = ptep_get_and_clear(mm, mpaddr, pte);
    1.27 +        mfn = pte_pfn(old_pte);
    1.28 +    } else {
    1.29 +        unsigned long old_arflags;
    1.30 +        pte_t new_pte;
    1.31 +        pte_t ret_pte;
    1.32 +
    1.33 +    again:
    1.34 +        BUG_ON(page_get_owner(mfn_to_page(mfn)) != d);
    1.35 +        old_arflags = pte_val(*pte) & ~_PAGE_PPN_MASK;
    1.36 +        old_pte = pfn_pte(mfn, __pgprot(old_arflags));
    1.37 +        new_pte = __pte(0);
    1.38 +        
    1.39 +        // update pte
    1.40 +        ret_pte = ptep_cmpxchg_rel(mm, mpaddr, pte, old_pte, new_pte);
    1.41 +        if (unlikely(pte_val(old_pte) != pte_val(ret_pte))) {
    1.42 +            if (pte_pfn(old_pte) == pte_pfn(ret_pte)) {
    1.43 +                goto again;
    1.44 +            }
    1.45 +
    1.46 +            DPRINTK("%s: old_pte 0x%lx old_arflags 0x%lx mfn 0x%lx "
    1.47 +                    "ret_pte 0x%lx ret_mfn 0x%lx\n",
    1.48 +                    __func__,
    1.49 +                    pte_val(old_pte), old_arflags, mfn,
    1.50 +                    pte_val(ret_pte), pte_pfn(ret_pte));
    1.51 +            return;
    1.52 +        }
    1.53 +        BUG_ON(mfn != pte_pfn(ret_pte));
    1.54 +    }
    1.55 +
    1.56      page = mfn_to_page(mfn);
    1.57      BUG_ON((page->count_info & PGC_count_mask) == 0);
    1.58  
    1.59 @@ -931,7 +959,7 @@ dom0vp_zap_physmap(struct domain *d, uns
    1.60          return -ENOSYS;
    1.61      }
    1.62  
    1.63 -    zap_domain_page_one(d, gpfn << PAGE_SHIFT);
    1.64 +    zap_domain_page_one(d, gpfn << PAGE_SHIFT, INVALID_MFN);
    1.65      return 0;
    1.66  }
    1.67  
    1.68 @@ -1193,7 +1221,7 @@ guest_physmap_remove_page(struct domain 
    1.69                            unsigned long mfn)
    1.70  {
    1.71      BUG_ON(mfn == 0);//XXX
    1.72 -    zap_domain_page_one(d, gpfn << PAGE_SHIFT);
    1.73 +    zap_domain_page_one(d, gpfn << PAGE_SHIFT, mfn);
    1.74  }
    1.75  
    1.76  //XXX sledgehammer.