ia64/xen-unstable

changeset 5452:a8d6aae1c5ac

bitkeeper revision 1.1709.1.4 (42af14e3nI6x4CAkSIQRQMV4Bahpcg)

adds get_page/put_page to XEN/IA64

Signed-off-by Kevin Tian <Kevin.tian@intel.com>
author djm@kirby.fc.hp.com
date Tue Jun 14 17:33:23 2005 +0000 (2005-06-14)
parents dce7deb4c508
children a514af3f6017
files xen/include/asm-ia64/mm.h
line diff
     1.1 --- a/xen/include/asm-ia64/mm.h	Mon Jun 13 22:03:21 2005 +0000
     1.2 +++ b/xen/include/asm-ia64/mm.h	Tue Jun 14 17:33:23 2005 +0000
     1.3 @@ -27,43 +27,12 @@ typedef unsigned long page_flags_t;
     1.4  
     1.5  /*
     1.6   * Per-page-frame information.
     1.7 + * 
     1.8 + * Every architecture must ensure the following:
     1.9 + *  1. 'struct pfn_info' contains a 'struct list_head list'.
    1.10 + *  2. Provide a PFN_ORDER() macro for accessing the order of a free page.
    1.11   */
    1.12 -
    1.13 -//FIXME: This can go away when common/dom0_ops.c is fully arch-independent
    1.14 -#if 0
    1.15 -struct pfn_info
    1.16 -{
    1.17 -    /* Each frame can be threaded onto a doubly-linked list. */
    1.18 -    struct list_head list;
    1.19 -    /* Context-dependent fields follow... */
    1.20 -    union {
    1.21 -
    1.22 -        /* Page is in use by a domain. */
    1.23 -        struct {
    1.24 -            /* Owner of this page. */
    1.25 -            struct domain *domain;
    1.26 -            /* Reference count and various PGC_xxx flags and fields. */
    1.27 -            u32 count_info;
    1.28 -            /* Type reference count and various PGT_xxx flags and fields. */
    1.29 -            u32 type_info;
    1.30 -        } inuse;
    1.31 -
    1.32 -        /* Page is on a free list. */
    1.33 -        struct {
    1.34 -            /* Mask of possibly-tainted TLBs. */
    1.35 -            unsigned long cpu_mask;
    1.36 -            /* Must be at same offset as 'u.inuse.count_flags'. */
    1.37 -            u32 __unavailable;
    1.38 -            /* Order-size of the free chunk this page is the head of. */
    1.39 -            u8 order;
    1.40 -        } free;
    1.41 -
    1.42 -    } u;
    1.43 -
    1.44 -    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
    1.45 -    u32 tlbflush_timestamp;
    1.46 -};
    1.47 -#endif
    1.48 +#define PFN_ORDER(_pfn)	((_pfn)->u.free.order)
    1.49  
    1.50  struct page
    1.51  {
    1.52 @@ -82,7 +51,7 @@ struct page
    1.53          /* Page is in use by a domain. */
    1.54          struct {
    1.55              /* Owner of this page. */
    1.56 -            u64	_domain;
    1.57 +            u32	_domain;
    1.58              /* Type reference count and various PGT_xxx flags and fields. */
    1.59              u32 type_info;
    1.60          } inuse;
    1.61 @@ -104,37 +73,49 @@ struct page
    1.62  
    1.63  #define set_page_count(p,v) 	atomic_set(&(p)->_count, v - 1)
    1.64  
    1.65 -//FIXME: These can go away when common/dom0_ops.c is fully arch-independent
    1.66 - /* The following page types are MUTUALLY EXCLUSIVE. */
    1.67 +/* Still small set of flags defined by far on IA-64 */
    1.68 +/* The following page types are MUTUALLY EXCLUSIVE. */
    1.69  #define PGT_none            (0<<29) /* no special uses of this page */
    1.70  #define PGT_l1_page_table   (1<<29) /* using this page as an L1 page table? */
    1.71  #define PGT_l2_page_table   (2<<29) /* using this page as an L2 page table? */
    1.72  #define PGT_l3_page_table   (3<<29) /* using this page as an L3 page table? */
    1.73  #define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
    1.74 -#define PGT_gdt_page        (5<<29) /* using this page in a GDT? */
    1.75 -#define PGT_ldt_page        (6<<29) /* using this page in an LDT? */
    1.76 -#define PGT_writeable_page  (7<<29) /* has writable mappings of this page? */
    1.77 -#define PGT_type_mask       (7<<29) /* Bits 29-31. */
    1.78 +#define PGT_writeable_page  (5<<29) /* has writable mappings of this page? */
    1.79 +#define PGT_type_mask       (5<<29) /* Bits 29-31. */
    1.80 +
    1.81   /* Has this page been validated for use as its current type? */
    1.82  #define _PGT_validated      28
    1.83  #define PGT_validated       (1<<_PGT_validated)
    1.84 - /* 28-bit count of uses of this frame as its current type. */
    1.85 -#define PGT_count_mask      ((1<<28)-1)
    1.86 +/* Owning guest has pinned this page to its current type? */
    1.87 +#define _PGT_pinned         27
    1.88 +#define PGT_pinned          (1U<<_PGT_pinned)
    1.89 +
    1.90 +/* 27-bit count of uses of this frame as its current type. */
    1.91 +#define PGT_count_mask      ((1U<<27)-1)
    1.92  
    1.93  /* Cleared when the owning guest 'frees' this page. */
    1.94  #define _PGC_allocated      31
    1.95  #define PGC_allocated       (1U<<_PGC_allocated)
    1.96 -#define PFN_ORDER(_pfn)	((_pfn)->u.free.order)
    1.97 +/* Set when the page is used as a page table */
    1.98 +#define _PGC_page_table     30
    1.99 +#define PGC_page_table      (1U<<_PGC_page_table)
   1.100 +/* 30-bit count of references to this frame. */
   1.101 +#define PGC_count_mask      ((1U<<30)-1)
   1.102  
   1.103  #define IS_XEN_HEAP_FRAME(_pfn) ((page_to_phys(_pfn) < xenheap_phys_end) \
   1.104  				 && (page_to_phys(_pfn) >= xen_pstart))
   1.105  
   1.106 -#define pickle_domptr(_d)	((u64)(_d))
   1.107 -#define unpickle_domptr(_d)	((struct domain*)(_d))
   1.108 +static inline struct domain *unpickle_domptr(u32 _d)
   1.109 +{ return (_d == 0) ? NULL : __va(_d); }
   1.110 +static inline u32 pickle_domptr(struct domain *_d)
   1.111 +{ return (_d == NULL) ? 0 : (u32)__pa(_d); }
   1.112  
   1.113  #define page_get_owner(_p)	(unpickle_domptr((_p)->u.inuse._domain))
   1.114  #define page_set_owner(_p, _d)	((_p)->u.inuse._domain = pickle_domptr(_d))
   1.115  
   1.116 +/* Dummy now */
   1.117 +#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom) do { } while (0)
   1.118 +
   1.119  extern struct pfn_info *frame_table;
   1.120  extern unsigned long frame_table_size;
   1.121  extern struct list_head free_list;
   1.122 @@ -151,16 +132,46 @@ void add_to_domain_alloc_list(unsigned l
   1.123  
   1.124  static inline void put_page(struct pfn_info *page)
   1.125  {
   1.126 -	dummy();
   1.127 +    u32 nx, x, y = page->count_info;
   1.128 +
   1.129 +    do {
   1.130 +	x = y;
   1.131 +	nx = x - 1;
   1.132 +    }
   1.133 +    while (unlikely((y = cmpxchg(&page->count_info, x, nx)) != x));
   1.134 +
   1.135 +    if (unlikely((nx & PGC_count_mask) == 0))
   1.136 +	free_domheap_page(page);
   1.137  }
   1.138  
   1.139 -
   1.140 +/* count_info and ownership are checked atomically. */
   1.141  static inline int get_page(struct pfn_info *page,
   1.142                             struct domain *domain)
   1.143  {
   1.144 -	dummy();
   1.145 +    u64 x, nx, y = *((u64*)&page->count_info);
   1.146 +    u32 _domain = pickle_domptr(domain);
   1.147 +
   1.148 +    do {
   1.149 +	x = y;
   1.150 +	nx = x + 1;
   1.151 +	if (unlikely((x & PGC_count_mask) == 0) ||	/* Not allocated? */
   1.152 +	    unlikely((nx & PGC_count_mask) == 0) ||	/* Count overflow? */
   1.153 +	    unlikely((x >> 32) != _domain)) {		/* Wrong owner? */
   1.154 +	    DPRINTK("Error pfn %lx: rd=%p, od=%p, caf=%08x, taf=%08x\n",
   1.155 +		page_to_pfn(page), domain, unpickle_domptr(d),
   1.156 +		x, page->u.inuse.typeinfo);
   1.157 +	    return 0;
   1.158 +	}
   1.159 +    }
   1.160 +    while(unlikely(y = cmpxchg(&page->count_info, x, nx)) != x);
   1.161 +
   1.162 +    return 1;
   1.163  }
   1.164  
   1.165 +/* No type info now */
   1.166 +#define put_page_and_type(page) put_page((page))
   1.167 +#define get_page_and_type(page, domain, type) get_page((page))
   1.168 +
   1.169  #define	set_machinetophys(_mfn, _pfn) do { } while(0);
   1.170  
   1.171  #ifdef MEMORY_GUARD