ia64/xen-unstable

annotate xen/include/xen/mm.h @ 1211:a235ded07b12

bitkeeper revision 1.822 (40600a0a9K2f7dR0Ky2OCGfBDHTTmQ)

Many files:
xeno -> xen renames.
author kaf24@scramble.cl.cam.ac.uk
date Tue Mar 23 09:57:30 2004 +0000 (2004-03-23)
parents 9f85adafc1e1
children 0b18f5295cff 9eb1d25256fa 53a93ee1224d
rev   line source
kaf24@1210 1
kaf24@1211 2 #ifndef __XEN_MM_H__
kaf24@1211 3 #define __XEN_MM_H__
kaf24@1210 4
kaf24@1210 5 #include <xen/config.h>
kaf24@1210 6 #include <xen/list.h>
kaf24@1210 7 #include <xen/spinlock.h>
kaf24@1210 8 #include <xen/perfc.h>
kaf24@1210 9 #include <xen/sched.h>
kaf24@1210 10
kaf24@1210 11 #include <asm/pgalloc.h>
kaf24@1210 12 #include <asm/atomic.h>
kaf24@1210 13 #include <asm/desc.h>
kaf24@1210 14 #include <asm/flushtlb.h>
kaf24@1210 15 #include <asm/io.h>
kaf24@1210 16
kaf24@1210 17 #include <hypervisor-ifs/hypervisor-if.h>
kaf24@1210 18
kaf24@1210 19 /*
kaf24@1210 20 * These are for compatibility with calls to the Linux memory allocators.
kaf24@1210 21 */
kaf24@1210 22
kaf24@1210 23 #define __GFP_DMA 0x01
kaf24@1210 24 #define GFP_DMA __GFP_DMA
kaf24@1210 25 #define __GFP_WAIT 0x10 /* Can wait and reschedule? */
kaf24@1210 26 #define __GFP_HIGH 0x20 /* Should access emergency pools? */
kaf24@1210 27 #define __GFP_IO 0x40 /* Can start low memory physical IO? */
kaf24@1210 28 #define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */
kaf24@1210 29 #define __GFP_FS 0x100 /* Can call down to low-level FS? */
kaf24@1210 30 #define GFP_ATOMIC (__GFP_HIGH)
kaf24@1210 31 #define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | \
kaf24@1210 32 __GFP_HIGHIO | __GFP_FS)
kaf24@1210 33
kaf24@1210 34 /*
kaf24@1210 35 * The following is for page_alloc.c.
kaf24@1210 36 */
kaf24@1210 37
kaf24@1210 38 void init_page_allocator(unsigned long min, unsigned long max);
kaf24@1210 39 unsigned long __get_free_pages(int mask, int order);
kaf24@1210 40 void __free_pages(unsigned long p, int order);
kaf24@1210 41 #define get_free_page(_m) (__get_free_pages((_m),0))
kaf24@1210 42 #define __get_free_page(_m) (__get_free_pages((_m),0))
kaf24@1210 43 #define free_pages(_p,_o) (__free_pages(_p,_o))
kaf24@1210 44 #define free_page(_p) (__free_pages(_p,0))
kaf24@1210 45
kaf24@1210 46
kaf24@1210 47 /*
kaf24@1210 48 * Per-page-frame information.
kaf24@1210 49 */
kaf24@1210 50
kaf24@1210 51 struct pfn_info
kaf24@1210 52 {
kaf24@1210 53 /* Each frame can be threaded onto a doubly-linked list. */
kaf24@1210 54 struct list_head list;
kaf24@1210 55 /* The following possible uses are context-dependent. */
kaf24@1210 56 union {
kaf24@1210 57 /* Page is in use and not a zombie: we keep a pointer to its owner. */
kaf24@1210 58 struct task_struct *domain;
kaf24@1210 59 /* Page is not currently allocated: mask of possibly-tainted TLBs. */
kaf24@1210 60 unsigned long cpu_mask;
kaf24@1210 61 /* Page is a zombie: this word currently has no use. */
kaf24@1210 62 unsigned long _unused;
kaf24@1210 63 } u;
kaf24@1210 64 /* Reference count and various PGC_xxx flags and fields. */
kaf24@1210 65 unsigned long count_and_flags;
kaf24@1210 66 /* Type reference count and various PGT_xxx flags and fields. */
kaf24@1210 67 unsigned long type_and_flags;
kaf24@1210 68 /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
kaf24@1210 69 unsigned long tlbflush_timestamp;
kaf24@1210 70 };
kaf24@1210 71
kaf24@1210 72 /* The following page types are MUTUALLY EXCLUSIVE. */
kaf24@1210 73 #define PGT_none (0<<29) /* no special uses of this page */
kaf24@1210 74 #define PGT_l1_page_table (1<<29) /* using this page as an L1 page table? */
kaf24@1210 75 #define PGT_l2_page_table (2<<29) /* using this page as an L2 page table? */
kaf24@1210 76 #define PGT_l3_page_table (3<<29) /* using this page as an L3 page table? */
kaf24@1210 77 #define PGT_l4_page_table (4<<29) /* using this page as an L4 page table? */
kaf24@1210 78 #define PGT_gdt_page (5<<29) /* using this page in a GDT? */
kaf24@1210 79 #define PGT_ldt_page (6<<29) /* using this page in an LDT? */
kaf24@1210 80 #define PGT_writeable_page (7<<29) /* has writable mappings of this page? */
kaf24@1210 81 #define PGT_type_mask (7<<29) /* Bits 29-31. */
kaf24@1210 82 /* Has this page been validated for use as its current type? */
kaf24@1210 83 #define _PGT_validated 28
kaf24@1210 84 #define PGT_validated (1<<_PGT_validated)
kaf24@1210 85 /* 28-bit count of uses of this frame as its current type. */
kaf24@1210 86 #define PGT_count_mask ((1<<28)-1)
kaf24@1210 87
kaf24@1210 88 /* The owner of this page is dead: 'u.domain' is no longer valid. */
kaf24@1210 89 #define _PGC_zombie 31
kaf24@1210 90 #define PGC_zombie (1<<_PGC_zombie)
kaf24@1210 91 /* For safety, force a TLB flush when this page's type changes. */
kaf24@1210 92 #define _PGC_tlb_flush_on_type_change 30
kaf24@1210 93 #define PGC_tlb_flush_on_type_change (1<<_PGC_tlb_flush_on_type_change)
kaf24@1210 94 /* Owning guest has pinned this page to its current type? */
kaf24@1210 95 #define _PGC_guest_pinned 29
kaf24@1210 96 #define PGC_guest_pinned (1<<_PGC_guest_pinned)
kaf24@1210 97 /* Cleared when the owning guest 'frees' this page. */
kaf24@1210 98 #define _PGC_allocated 28
kaf24@1210 99 #define PGC_allocated (1<<_PGC_allocated)
kaf24@1210 100 /* 28-bit count of references to this frame. */
kaf24@1210 101 #define PGC_count_mask ((1<<28)-1)
kaf24@1210 102
kaf24@1210 103 /* We trust the slab allocator in slab.c, and our use of it. */
kaf24@1210 104 #define PageSlab(page) (1)
kaf24@1210 105 #define PageSetSlab(page) ((void)0)
kaf24@1210 106 #define PageClearSlab(page) ((void)0)
kaf24@1210 107
kaf24@1210 108 #define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < MAX_MONITOR_ADDRESS)
kaf24@1210 109
kaf24@1210 110 #define SHARE_PFN_WITH_DOMAIN(_pfn, _dom) \
kaf24@1210 111 do { \
kaf24@1210 112 (_pfn)->u.domain = (_dom); \
kaf24@1210 113 wmb(); /* install valid domain ptr before updating refcnt. */ \
kaf24@1210 114 (_pfn)->count_and_flags = 1; /* Xen holds a writeable reference */ \
kaf24@1210 115 (_pfn)->type_and_flags = PGT_writeable_page | PGT_validated | 1; \
kaf24@1210 116 } while ( 0 )
kaf24@1210 117
kaf24@1210 118 #define UNSHARE_PFN(_pfn) put_page_and_type(_pfn)
kaf24@1210 119
kaf24@1210 120 extern struct pfn_info *frame_table;
kaf24@1210 121 extern unsigned long frame_table_size;
kaf24@1210 122 extern struct list_head free_list;
kaf24@1210 123 extern spinlock_t free_list_lock;
kaf24@1210 124 extern unsigned int free_pfns;
kaf24@1210 125 extern unsigned long max_page;
kaf24@1210 126 void init_frametable(unsigned long nr_pages);
kaf24@1210 127
kaf24@1210 128 struct pfn_info *alloc_domain_page(struct task_struct *p);
kaf24@1210 129 void free_domain_page(struct pfn_info *page);
kaf24@1210 130
kaf24@1210 131 int alloc_page_type(struct pfn_info *page, unsigned int type);
kaf24@1210 132 void free_page_type(struct pfn_info *page, unsigned int type);
kaf24@1210 133
kaf24@1210 134 static inline void put_page(struct pfn_info *page)
kaf24@1210 135 {
kaf24@1210 136 unsigned long nx, x, y = page->count_and_flags;
kaf24@1210 137
kaf24@1210 138 do {
kaf24@1210 139 x = y;
kaf24@1210 140 nx = x - 1;
kaf24@1210 141 }
kaf24@1210 142 while ( unlikely((y = cmpxchg(&page->count_and_flags, x, nx)) != x) );
kaf24@1210 143
kaf24@1210 144 if ( unlikely((nx & PGC_count_mask) == 0) )
kaf24@1210 145 free_domain_page(page);
kaf24@1210 146 }
kaf24@1210 147
kaf24@1210 148
kaf24@1210 149 static inline int get_page(struct pfn_info *page,
kaf24@1210 150 struct task_struct *domain)
kaf24@1210 151 {
kaf24@1210 152 unsigned long x, nx, y = page->count_and_flags;
kaf24@1210 153 struct task_struct *p, *np = page->u.domain;
kaf24@1210 154
kaf24@1210 155 do {
kaf24@1210 156 x = y;
kaf24@1210 157 nx = x + 1;
kaf24@1210 158 p = np;
kaf24@1210 159 if ( unlikely((x & PGC_count_mask) == 0) || /* Not allocated? */
kaf24@1210 160 unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
kaf24@1210 161 unlikely(x & PGC_zombie) || /* Zombie? */
kaf24@1210 162 unlikely(p != domain) ) /* Wrong owner? */
kaf24@1210 163 {
kaf24@1210 164 DPRINTK("Error pfn %08lx: ed=%p,sd=%p,caf=%08lx\n",
kaf24@1210 165 page_to_pfn(page), domain, p, x);
kaf24@1210 166 return 0;
kaf24@1210 167 }
kaf24@1210 168 __asm__ __volatile__(
kaf24@1210 169 LOCK_PREFIX "cmpxchg8b %3"
kaf24@1210 170 : "=a" (np), "=d" (y), "=b" (p),
kaf24@1210 171 "=m" (*(volatile unsigned long long *)(&page->u.domain))
kaf24@1210 172 : "0" (p), "1" (x), "b" (p), "c" (nx) );
kaf24@1210 173 }
kaf24@1210 174 while ( unlikely(np != p) || unlikely(y != x) );
kaf24@1210 175
kaf24@1210 176 return 1;
kaf24@1210 177 }
kaf24@1210 178
kaf24@1210 179
kaf24@1210 180 static inline void put_page_type(struct pfn_info *page)
kaf24@1210 181 {
kaf24@1210 182 unsigned long nx, x, y = page->type_and_flags;
kaf24@1210 183
kaf24@1210 184 again:
kaf24@1210 185 do {
kaf24@1210 186 x = y;
kaf24@1210 187 nx = x - 1;
kaf24@1210 188 if ( unlikely((nx & PGT_count_mask) == 0) )
kaf24@1210 189 {
kaf24@1210 190 page->tlbflush_timestamp = tlbflush_clock;
kaf24@1210 191 if ( unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) &&
kaf24@1210 192 likely(nx & PGT_validated) )
kaf24@1210 193 {
kaf24@1210 194 /*
kaf24@1210 195 * Page-table pages must be unvalidated when count is zero. The
kaf24@1210 196 * 'free' is safe because the refcnt is non-zero and the
kaf24@1210 197 * validated bit is clear => other ops will spin or fail.
kaf24@1210 198 */
kaf24@1210 199 if ( unlikely((y = cmpxchg(&page->type_and_flags, x,
kaf24@1210 200 x & ~PGT_validated)) != x) )
kaf24@1210 201 goto again;
kaf24@1210 202 /* We cleared the 'valid bit' so we must do the clear up. */
kaf24@1210 203 free_page_type(page, x & PGT_type_mask);
kaf24@1210 204 /* Carry on as we were, but with the 'valid bit' now clear. */
kaf24@1210 205 x &= ~PGT_validated;
kaf24@1210 206 nx &= ~PGT_validated;
kaf24@1210 207 }
kaf24@1210 208 }
kaf24@1210 209 }
kaf24@1210 210 while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
kaf24@1210 211 }
kaf24@1210 212
kaf24@1210 213
kaf24@1210 214 static inline int get_page_type(struct pfn_info *page, unsigned long type)
kaf24@1210 215 {
kaf24@1210 216 unsigned long nx, x, y = page->type_and_flags;
kaf24@1210 217 again:
kaf24@1210 218 do {
kaf24@1210 219 x = y;
kaf24@1210 220 nx = x + 1;
kaf24@1210 221 if ( unlikely((nx & PGT_count_mask) == 0) )
kaf24@1210 222 {
kaf24@1210 223 DPRINTK("Type count overflow on pfn %08lx\n", page_to_pfn(page));
kaf24@1210 224 return 0;
kaf24@1210 225 }
kaf24@1210 226 else if ( unlikely((x & PGT_count_mask) == 0) )
kaf24@1210 227 {
kaf24@1210 228 if ( (x & PGT_type_mask) != type )
kaf24@1210 229 {
kaf24@1210 230 nx &= ~(PGT_type_mask | PGT_validated);
kaf24@1210 231 nx |= type;
kaf24@1210 232 /* No extra validation needed for writeable pages. */
kaf24@1210 233 if ( type == PGT_writeable_page )
kaf24@1210 234 nx |= PGT_validated;
kaf24@1210 235 }
kaf24@1210 236 }
kaf24@1210 237 else if ( unlikely((x & PGT_type_mask) != type) )
kaf24@1210 238 {
kaf24@1210 239 DPRINTK("Unexpected type (saw %08lx != exp %08lx) for pfn %08lx\n",
kaf24@1210 240 x & PGT_type_mask, type, page_to_pfn(page));
kaf24@1210 241 return 0;
kaf24@1210 242 }
kaf24@1210 243 else if ( unlikely(!(x & PGT_validated)) )
kaf24@1210 244 {
kaf24@1210 245 /* Someone else is updating validation of this page. Wait... */
kaf24@1210 246 while ( (y = page->type_and_flags) != x )
kaf24@1210 247 {
kaf24@1210 248 rep_nop();
kaf24@1210 249 barrier();
kaf24@1210 250 }
kaf24@1210 251 goto again;
kaf24@1210 252 }
kaf24@1210 253 }
kaf24@1210 254 while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
kaf24@1210 255
kaf24@1210 256 if ( unlikely(!(nx & PGT_validated)) )
kaf24@1210 257 {
kaf24@1210 258 /* Try to validate page type; drop the new reference on failure. */
kaf24@1210 259 if ( unlikely(!alloc_page_type(page, type)) )
kaf24@1210 260 {
kaf24@1210 261 DPRINTK("Error while validating pfn %08lx for type %08lx\n",
kaf24@1210 262 page_to_pfn(page), type);
kaf24@1210 263 put_page_type(page);
kaf24@1210 264 return 0;
kaf24@1210 265 }
kaf24@1210 266 set_bit(_PGT_validated, &page->type_and_flags);
kaf24@1210 267 }
kaf24@1210 268
kaf24@1210 269 return 1;
kaf24@1210 270 }
kaf24@1210 271
kaf24@1210 272
kaf24@1210 273 static inline void put_page_and_type(struct pfn_info *page)
kaf24@1210 274 {
kaf24@1210 275 put_page_type(page);
kaf24@1210 276 put_page(page);
kaf24@1210 277 }
kaf24@1210 278
kaf24@1210 279
kaf24@1210 280 static inline int get_page_and_type(struct pfn_info *page,
kaf24@1210 281 struct task_struct *domain,
kaf24@1210 282 unsigned int type)
kaf24@1210 283 {
kaf24@1210 284 int rc = get_page(page, domain);
kaf24@1210 285
kaf24@1210 286 if ( likely(rc) && unlikely(!get_page_type(page, type)) )
kaf24@1210 287 {
kaf24@1210 288 put_page(page);
kaf24@1210 289 rc = 0;
kaf24@1210 290 }
kaf24@1210 291
kaf24@1210 292 return rc;
kaf24@1210 293 }
kaf24@1210 294
kaf24@1210 295 #define ASSERT_PAGE_IS_TYPE(_p, _t) \
kaf24@1210 296 ASSERT(((_p)->type_and_flags & PGT_type_mask) == (_t)); \
kaf24@1210 297 ASSERT(((_p)->type_and_flags & PGT_count_mask) != 0)
kaf24@1210 298 #define ASSERT_PAGE_IS_DOMAIN(_p, _d) \
kaf24@1210 299 ASSERT(((_p)->count_and_flags & PGC_count_mask) != 0); \
kaf24@1210 300 ASSERT((_p)->u.domain == (_d))
kaf24@1210 301
kaf24@1210 302 int check_descriptor(unsigned long a, unsigned long b);
kaf24@1210 303
kaf24@1210 304 /*
kaf24@1210 305 * The MPT (machine->physical mapping table) is an array of word-sized
kaf24@1210 306 * values, indexed on machine frame number. It is expected that guest OSes
kaf24@1210 307 * will use it to store a "physical" frame number to give the appearance of
kaf24@1210 308 * contiguous (or near contiguous) physical memory.
kaf24@1210 309 */
kaf24@1210 310 #undef machine_to_phys_mapping
kaf24@1210 311 #define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
kaf24@1210 312
kaf24@1210 313 /* Part of the domain API. */
kaf24@1210 314 int do_mmu_update(mmu_update_t *updates, int count);
kaf24@1210 315
kaf24@1210 316 #define DEFAULT_GDT_ENTRIES ((LAST_RESERVED_GDT_ENTRY*8)+7)
kaf24@1210 317 #define DEFAULT_GDT_ADDRESS ((unsigned long)gdt_table)
kaf24@1210 318
kaf24@1210 319 #ifdef MEMORY_GUARD
kaf24@1210 320 void *memguard_init(void *heap_start);
kaf24@1210 321 void memguard_guard_range(void *p, unsigned long l);
kaf24@1210 322 void memguard_unguard_range(void *p, unsigned long l);
kaf24@1210 323 int memguard_is_guarded(void *p);
kaf24@1210 324 #else
kaf24@1210 325 #define memguard_init(_s) (_s)
kaf24@1210 326 #define memguard_guard_range(_p,_l) ((void)0)
kaf24@1210 327 #define memguard_unguard_range(_p,_l) ((void)0)
kaf24@1210 328 #define memguard_is_guarded(_p) (0)
kaf24@1210 329 #endif
kaf24@1210 330
kaf24@1211 331 #endif /* __XEN_MM_H__ */