direct-io.hg

changeset 12433:3ac52066af81

[IA64] Support Xen/IA64 self-grant-table-page-mapping.

Before the changeset 10677:2937703f0ed0 of xen-unstable.hg,
it is prohibited mapping a page which is granted by self domain.
However it is allowed in order to mount blktap image by dom0.
This patch is necessary to support blktap on Xen/IA64.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Fri Nov 10 11:44:38 2006 -0700 (2006-11-10)
parents 371d2837a1fe
children e28beea6d228
files xen/arch/ia64/xen/mm.c xen/include/asm-ia64/linux-xen/asm/pgtable.h xen/include/public/arch-ia64.h
line diff
     1.1 --- a/xen/arch/ia64/xen/mm.c	Fri Nov 10 11:34:39 2006 -0700
     1.2 +++ b/xen/arch/ia64/xen/mm.c	Fri Nov 10 11:44:38 2006 -0700
     1.3 @@ -765,7 +765,8 @@ static struct page_info *
     1.4      // because set_pte_rel() has release semantics
     1.5      set_pte_rel(pte,
     1.6                  pfn_pte(maddr >> PAGE_SHIFT,
     1.7 -                        __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
     1.8 +                        __pgprot(_PAGE_PGC_ALLOCATED | __DIRTY_BITS |
     1.9 +                                 _PAGE_PL_2 | _PAGE_AR_RWX)));
    1.10  
    1.11      smp_mb();
    1.12      return p;
    1.13 @@ -807,6 +808,7 @@ flags_to_prot (unsigned long flags)
    1.14  #ifdef CONFIG_XEN_IA64_TLB_TRACK
    1.15      res |= flags & ASSIGN_tlb_track ? _PAGE_TLB_TRACKING: 0;
    1.16  #endif
    1.17 +    res |= flags & ASSIGN_pgc_allocated ? _PAGE_PGC_ALLOCATED: 0;
    1.18      
    1.19      return res;
    1.20  }
    1.21 @@ -866,7 +868,8 @@ assign_domain_page(struct domain *d,
    1.22      set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
    1.23      // because __assign_domain_page() uses set_pte_rel() which has
    1.24      // release semantics, smp_mb() isn't needed.
    1.25 -    (void)__assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
    1.26 +    (void)__assign_domain_page(d, mpaddr, physaddr,
    1.27 +                               ASSIGN_writable | ASSIGN_pgc_allocated);
    1.28  }
    1.29  
    1.30  int
    1.31 @@ -1035,6 +1038,7 @@ assign_domain_mach_page(struct domain *d
    1.32                          unsigned long mpaddr, unsigned long size,
    1.33                          unsigned long flags)
    1.34  {
    1.35 +    BUG_ON(flags & ASSIGN_pgc_allocated);
    1.36      assign_domain_same_page(d, mpaddr, size, flags);
    1.37      return mpaddr;
    1.38  }
    1.39 @@ -1046,15 +1050,17 @@ domain_put_page(struct domain* d, unsign
    1.40      unsigned long mfn = pte_pfn(old_pte);
    1.41      struct page_info* page = mfn_to_page(mfn);
    1.42  
    1.43 -    if (page_get_owner(page) == d ||
    1.44 -        page_get_owner(page) == NULL) {
    1.45 -        BUG_ON(get_gpfn_from_mfn(mfn) != (mpaddr >> PAGE_SHIFT));
    1.46 -        set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
    1.47 +    if (pte_pgc_allocated(old_pte)) {
    1.48 +        if (page_get_owner(page) == d || page_get_owner(page) == NULL) {
    1.49 +            BUG_ON(get_gpfn_from_mfn(mfn) != (mpaddr >> PAGE_SHIFT));
    1.50 +	    set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
    1.51 +        } else {
    1.52 +            BUG();
    1.53 +        }
    1.54 +
    1.55 +	if (clear_PGC_allocate)
    1.56 +            try_to_clear_PGC_allocate(d, page);
    1.57      }
    1.58 -
    1.59 -    if (clear_PGC_allocate)
    1.60 -        try_to_clear_PGC_allocate(d, page);
    1.61 -
    1.62      domain_page_flush_and_put(d, mpaddr, ptep, old_pte, page);
    1.63  }
    1.64  
    1.65 @@ -1146,6 +1152,7 @@ assign_domain_page_cmpxchg_rel(struct do
    1.66      }
    1.67  
    1.68      BUG_ON(!pte_mem(old_pte));
    1.69 +    BUG_ON(!pte_pgc_allocated(old_pte));
    1.70      BUG_ON(page_get_owner(old_page) != d);
    1.71      BUG_ON(get_gpfn_from_mfn(old_mfn) != (mpaddr >> PAGE_SHIFT));
    1.72      BUG_ON(old_mfn == new_mfn);
    1.73 @@ -1240,7 +1247,7 @@ dom0vp_add_physmap(struct domain* d, uns
    1.74      struct domain* rd;
    1.75  
    1.76      /* Not allowed by a domain.  */
    1.77 -    if (flags & ASSIGN_nocache)
    1.78 +    if (flags & (ASSIGN_nocache | ASSIGN_pgc_allocated))
    1.79          return -EINVAL;
    1.80  
    1.81      rd = find_domain_by_id(domid);
    1.82 @@ -1424,8 +1431,6 @@ create_grant_host_mapping(unsigned long 
    1.83      page = mfn_to_page(mfn);
    1.84      ret = get_page(page, page_get_owner(page));
    1.85      BUG_ON(ret == 0);
    1.86 -    BUG_ON(page_get_owner(mfn_to_page(mfn)) == d &&
    1.87 -           get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
    1.88      assign_domain_page_replace(d, gpaddr, mfn,
    1.89  #ifdef CONFIG_XEN_IA64_TLB_TRACK
    1.90                                 ASSIGN_tlb_track |
    1.91 @@ -1551,7 +1556,8 @@ steal_page(struct domain *d, struct page
    1.92          // has release semantics.
    1.93  
    1.94          ret = assign_domain_page_cmpxchg_rel(d, gpfn << PAGE_SHIFT, page, new,
    1.95 -                                             ASSIGN_writable);
    1.96 +                                             ASSIGN_writable |
    1.97 +                                             ASSIGN_pgc_allocated);
    1.98          if (ret < 0) {
    1.99              gdprintk(XENLOG_INFO, "assign_domain_page_cmpxchg_rel failed %d\n",
   1.100                      ret);
   1.101 @@ -1648,7 +1654,8 @@ guest_physmap_add_page(struct domain *d,
   1.102      BUG_ON(ret == 0);
   1.103      set_gpfn_from_mfn(mfn, gpfn);
   1.104      smp_mb();
   1.105 -    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, ASSIGN_writable);
   1.106 +    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
   1.107 +                               ASSIGN_writable | ASSIGN_pgc_allocated);
   1.108  
   1.109      //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
   1.110  
     2.1 --- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Fri Nov 10 11:34:39 2006 -0700
     2.2 +++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Fri Nov 10 11:44:38 2006 -0700
     2.3 @@ -89,6 +89,8 @@
     2.4      ((pte_val(pte) & _PAGE_TLB_INSERTED_MANY) != 0)
     2.5  #endif // CONFIG_XEN_IA64_TLB_TRACK
     2.6  
     2.7 +#define _PAGE_PGC_ALLOCATED_BIT	59	/* _PGC_allocated */
     2.8 +#define _PAGE_PGC_ALLOCATED	(__IA64_UL(1) << _PAGE_PGC_ALLOCATED_BIT)
     2.9  /* domVTI */
    2.10  #define GPFN_MEM		(0UL << 60)	/* Guest pfn is normal mem */
    2.11  #define GPFN_FRAME_BUFFER	(1UL << 60)	/* VGA framebuffer */
    2.12 @@ -333,6 +335,7 @@ set_pte_rel(volatile pte_t* ptep, pte_t 
    2.13  #define pte_young(pte)		((pte_val(pte) & _PAGE_A) != 0)
    2.14  #define pte_file(pte)		((pte_val(pte) & _PAGE_FILE) != 0)
    2.15  #ifdef XEN
    2.16 +#define pte_pgc_allocated(pte)	((pte_val(pte) & _PAGE_PGC_ALLOCATED) != 0)
    2.17  #define pte_mem(pte) \
    2.18  	(!(pte_val(pte) & (GPFN_IO_MASK | GPFN_INV_MASK)) && !pte_none(pte))
    2.19  #endif
     3.1 --- a/xen/include/public/arch-ia64.h	Fri Nov 10 11:34:39 2006 -0700
     3.2 +++ b/xen/include/public/arch-ia64.h	Fri Nov 10 11:44:38 2006 -0700
     3.3 @@ -384,6 +384,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
     3.4  // tlb tracking
     3.5  #define _ASSIGN_tlb_track               2
     3.6  #define ASSIGN_tlb_track                (1UL << _ASSIGN_tlb_track)
     3.7 +/* Internal only: associated with PGC_allocated bit */
     3.8 +#define _ASSIGN_pgc_allocated           3
     3.9 +#define ASSIGN_pgc_allocated            (1UL << _ASSIGN_pgc_allocated)
    3.10  
    3.11  /* This structure has the same layout of struct ia64_boot_param, defined in
    3.12     <asm/system.h>.  It is redefined here to ease use.  */