ia64/xen-unstable

view xen/include/asm-ia64/mm.h @ 19164:de853e901b5c

Remove cpumask for page_info struct.

This makes TLB flushing on page allocation more conservative, but the
flush clock should still save us most of the time (page freeing and
alloc'ing tends to happen in batches, and not necesasrily close
together). We could add some optimisations to the flush filter if this
does turn out to be a significant overhead for some (useful)
workloads.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 04 15:29:51 2009 +0000 (2009-02-04)
parents d68178692b7c
children 416197f0292b
line source
1 /*
2 * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
3 * VA Linux Systems Japan K.K.
4 * dom0 vp model support
5 */
6 #ifndef __ASM_IA64_MM_H__
7 #define __ASM_IA64_MM_H__
9 #include <xen/config.h>
10 #ifdef LINUX_2_6
11 #include <linux/gfp.h>
12 #endif
13 #include <xen/list.h>
14 #include <xen/spinlock.h>
15 #include <xen/perfc.h>
17 #include <asm/processor.h>
18 #include <asm/atomic.h>
19 #include <asm/tlbflush.h>
20 #include <asm/flushtlb.h>
21 #include <asm/io.h>
23 #include <public/xen.h>
25 /*
26 * The following is for page_alloc.c.
27 */
29 typedef unsigned long page_flags_t;
31 /*
32 * Per-page-frame information.
33 *
34 * Every architecture must ensure the following:
35 * 1. 'struct page_info' contains a 'struct list_head list'.
36 * 2. Provide a PFN_ORDER() macro for accessing the order of a free page.
37 */
38 #define PFN_ORDER(_pfn) ((_pfn)->u.free.order)
40 #define PRtype_info "016lx"
42 struct page_info
43 {
44 /* Each frame can be threaded onto a doubly-linked list. */
45 struct list_head list;
47 /* Reference count and various PGC_xxx flags and fields. */
48 unsigned long count_info;
50 /* Context-dependent fields follow... */
51 union {
53 /* Page is in use: ((count_info & PGC_count_mask) != 0). */
54 struct {
55 /* Owner of this page (NULL if page is anonymous). */
56 unsigned long _domain; /* pickled format */
57 /* Type reference count and various PGT_xxx flags and fields. */
58 unsigned long type_info;
59 } inuse;
61 /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
62 struct {
63 /* Order-size of the free chunk this page is the head of. */
64 u32 order;
65 } free;
67 } u;
69 /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
70 u32 tlbflush_timestamp;
71 };
73 #define set_page_count(p,v) atomic_set(&(p)->_count, v - 1)
75 /*
76 * Still small set of flags defined by far on IA-64.
77 * IA-64 should make it a definition same as x86_64.
78 */
79 #define PG_shift(idx) (BITS_PER_LONG - (idx))
80 #define PG_mask(x, idx) (x ## UL << PG_shift(idx))
82 /* The following page types are MUTUALLY EXCLUSIVE. */
83 #define PGT_none PG_mask(0, 3) /* no special uses of this page */
84 #define PGT_l1_page_table PG_mask(1, 3) /* using as an L1 page table? */
85 #define PGT_l2_page_table PG_mask(2, 3) /* using as an L2 page table? */
86 #define PGT_l3_page_table PG_mask(3, 3) /* using as an L3 page table? */
87 #define PGT_l4_page_table PG_mask(4, 3) /* using as an L4 page table? */
88 /* Value 5 reserved. See asm-x86/mm.h */
89 /* Value 6 reserved. See asm-x86/mm.h */
90 #define PGT_writable_page PG_mask(7, 3) /* has writable mappings? */
91 #define PGT_type_mask PG_mask(7, 3) /* Bits 29-31. */
93 /* Owning guest has pinned this page to its current type? */
94 #define _PGT_pinned PG_shift(4)
95 #define PGT_pinned PG_mask(1, 4)
96 /* Has this page been validated for use as its current type? */
97 #define _PGT_validated PG_shift(5)
98 #define PGT_validated PG_mask(1, 5)
100 /* Count of uses of this frame as its current type. */
101 #define PGT_count_width PG_shift(7)
102 #define PGT_count_mask ((1UL<<PGT_count_width)-1)
104 /* Cleared when the owning guest 'frees' this page. */
105 #define _PGC_allocated PG_shift(1)
106 #define PGC_allocated PG_mask(1, 1)
107 /* Page is Xen heap? */
108 # define _PGC_xen_heap PG_shift(2)
109 # define PGC_xen_heap PG_mask(1, 2)
110 /* bit PG_shift(3) reserved. See asm-x86/mm.h */
111 /* PG_mask(7, 6) reserved. See asm-x86/mm.h*/
112 /* Count of references to this frame. */
113 #define PGC_count_width PG_shift(6)
114 #define PGC_count_mask ((1UL<<PGC_count_width)-1)
116 #define is_xen_heap_page(page) ((page)->count_info & PGC_xen_heap)
117 #define is_xen_heap_mfn(mfn) (mfn_valid(mfn) && \
118 is_xen_heap_page(mfn_to_page(mfn)))
120 #define page_get_owner(_p) ((struct domain *)(_p)->u.inuse._domain)
121 #define page_set_owner(_p, _d) ((_p)->u.inuse._domain = (unsigned long)(_d))
123 #define XENSHARE_writable 0
124 #define XENSHARE_readonly 1
125 void share_xen_page_with_guest(struct page_info *page,
126 struct domain *d, int readonly);
127 void share_xen_page_with_privileged_guests(struct page_info *page,
128 int readonly);
130 extern unsigned long frametable_pg_dir[];
131 extern struct page_info *frame_table;
132 extern unsigned long frame_table_size;
133 extern struct list_head free_list;
134 extern spinlock_t free_list_lock;
135 extern unsigned int free_pfns;
136 extern unsigned long max_page;
138 extern void __init init_frametable(void);
139 void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
141 static inline void put_page(struct page_info *page)
142 {
143 unsigned long nx, x, y = page->count_info;
145 do {
146 x = y;
147 nx = x - 1;
148 }
149 while (unlikely((y = cmpxchg_rel(&page->count_info, x, nx)) != x));
151 if (unlikely((nx & PGC_count_mask) == 0))
152 free_domheap_page(page);
153 }
155 /* count_info and ownership are checked atomically. */
156 static inline int get_page(struct page_info *page,
157 struct domain *domain)
158 {
159 unsigned long x, y = page->count_info;
161 do {
162 x = y;
163 if (unlikely((x & PGC_count_mask) == 0) || /* Not allocated? */
164 unlikely(((x + 1) & PGC_count_mask) == 0) ) {/* Count overflow? */
165 goto fail;
166 }
167 y = cmpxchg_acq(&page->count_info, x, x + 1);
168 } while (unlikely(y != x));
170 if (likely(page_get_owner(page) == domain))
171 return 1;
173 put_page(page);
174 fail:
175 /* if (!domain->is_dying) */ /* XXX: header inclusion hell */
176 gdprintk(XENLOG_INFO,
177 "Error pfn %lx: rd=%p, od=%p, caf=%016lx, taf=%" PRtype_info "\n",
178 page_to_mfn(page), domain,
179 page_get_owner(page), y, page->u.inuse.type_info);
180 return 0;
181 }
183 int is_iomem_page(unsigned long mfn);
185 extern void put_page_type(struct page_info *page);
186 extern int get_page_type(struct page_info *page, unsigned long type);
188 static inline void put_page_and_type(struct page_info *page)
189 {
190 put_page_type(page);
191 put_page(page);
192 }
195 static inline int get_page_and_type(struct page_info *page,
196 struct domain *domain,
197 unsigned long type)
198 {
199 int rc = get_page(page, domain);
201 if ( likely(rc) && unlikely(!get_page_type(page, type)) )
202 {
203 put_page(page);
204 rc = 0;
205 }
207 return rc;
208 }
210 #define set_machinetophys(_mfn, _pfn) do { } while(0);
212 #ifdef MEMORY_GUARD
213 void *memguard_init(void *heap_start);
214 void memguard_guard_stack(void *p);
215 void memguard_guard_range(void *p, unsigned long l);
216 void memguard_unguard_range(void *p, unsigned long l);
217 #else
218 #define memguard_init(_s) (_s)
219 #define memguard_guard_stack(_p) ((void)0)
220 #define memguard_guard_range(_p,_l) ((void)0)
221 #define memguard_unguard_range(_p,_l) ((void)0)
222 #endif
224 // prototype of misc memory stuff
225 //unsigned long __get_free_pages(unsigned int mask, unsigned int order);
226 //void __free_pages(struct page_info *page, unsigned int order);
227 void *pgtable_quicklist_alloc(void);
228 void pgtable_quicklist_free(void *pgtable_entry);
230 // FOLLOWING FROM linux-2.6.7/include/mm.h
232 /*
233 * This struct defines a memory VMM memory area. There is one of these
234 * per VM-area/task. A VM area is any part of the process virtual memory
235 * space that has a special rule for the page-fault handlers (ie a shared
236 * library, the executable area etc).
237 */
238 struct vm_area_struct {
239 struct mm_struct * vm_mm; /* The address space we belong to. */
240 unsigned long vm_start; /* Our start address within vm_mm. */
241 unsigned long vm_end; /* The first byte after our end address
242 within vm_mm. */
244 /* linked list of VM areas per task, sorted by address */
245 struct vm_area_struct *vm_next;
247 pgprot_t vm_page_prot; /* Access permissions of this VMA. */
248 unsigned long vm_flags; /* Flags, listed below. */
250 #ifndef XEN
251 struct rb_node vm_rb;
253 // XEN doesn't need all the backing store stuff
254 /*
255 * For areas with an address space and backing store,
256 * linkage into the address_space->i_mmap prio tree, or
257 * linkage to the list of like vmas hanging off its node, or
258 * linkage of vma in the address_space->i_mmap_nonlinear list.
259 */
260 union {
261 struct {
262 struct list_head list;
263 void *parent; /* aligns with prio_tree_node parent */
264 struct vm_area_struct *head;
265 } vm_set;
267 struct prio_tree_node prio_tree_node;
268 } shared;
270 /*
271 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
272 * list, after a COW of one of the file pages. A MAP_SHARED vma
273 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
274 * or brk vma (with NULL file) can only be in an anon_vma list.
275 */
276 struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
277 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
279 /* Function pointers to deal with this struct. */
280 struct vm_operations_struct * vm_ops;
282 /* Information about our backing store: */
283 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
284 units, *not* PAGE_CACHE_SIZE */
285 struct file * vm_file; /* File we map to (can be NULL). */
286 void * vm_private_data; /* was vm_pte (shared mem) */
288 #ifdef CONFIG_NUMA
289 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
290 #endif
291 #endif
292 };
293 /*
294 * vm_flags..
295 */
296 #define VM_READ 0x00000001 /* currently active flags */
297 #define VM_WRITE 0x00000002
298 #define VM_EXEC 0x00000004
299 #define VM_SHARED 0x00000008
301 #define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */
302 #define VM_MAYWRITE 0x00000020
303 #define VM_MAYEXEC 0x00000040
304 #define VM_MAYSHARE 0x00000080
306 #define VM_GROWSDOWN 0x00000100 /* general info on the segment */
307 #define VM_GROWSUP 0x00000200
308 #define VM_SHM 0x00000400 /* shared memory area, don't swap out */
309 #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */
311 #define VM_EXECUTABLE 0x00001000
312 #define VM_LOCKED 0x00002000
313 #define VM_IO 0x00004000 /* Memory mapped I/O or similar */
315 /* Used by sys_madvise() */
316 #define VM_SEQ_READ 0x00008000 /* App will access data sequentially */
317 #define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */
319 #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
320 #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
321 #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
322 #define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
323 #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
324 #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
326 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
327 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
328 #endif
330 #ifdef CONFIG_STACK_GROWSUP
331 #define VM_STACK_FLAGS (VM_GROWSUP | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
332 #else
333 #define VM_STACK_FLAGS (VM_GROWSDOWN | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
334 #endif
336 #if 0 /* removed when rebasing to 2.6.13 */
337 /*
338 * The zone field is never updated after free_area_init_core()
339 * sets it, so none of the operations on it need to be atomic.
340 * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total,
341 * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits.
342 */
343 #define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT)
344 #define NODEZONE(node, zone) ((node << ZONES_SHIFT) | zone)
346 static inline unsigned long page_zonenum(struct page_info *page)
347 {
348 return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT));
349 }
350 static inline unsigned long page_to_nid(struct page_info *page)
351 {
352 return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT));
353 }
355 struct zone;
356 extern struct zone *zone_table[];
358 static inline struct zone *page_zone(struct page_info *page)
359 {
360 return zone_table[page->flags >> NODEZONE_SHIFT];
361 }
363 static inline void set_page_zone(struct page_info *page, unsigned long nodezone_num)
364 {
365 page->flags &= ~(~0UL << NODEZONE_SHIFT);
366 page->flags |= nodezone_num << NODEZONE_SHIFT;
367 }
368 #endif
370 #ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */
371 extern unsigned long max_mapnr;
372 #endif
374 static inline void *lowmem_page_address(struct page_info *page)
375 {
376 return __va(page_to_mfn(page) << PAGE_SHIFT);
377 }
379 #if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL)
380 #define HASHED_PAGE_VIRTUAL
381 #endif
383 #if defined(WANT_PAGE_VIRTUAL)
384 #define page_address(page) ((page)->virtual)
385 #define set_page_address(page, address) \
386 do { \
387 (page)->virtual = (address); \
388 } while(0)
389 #define page_address_init() do { } while(0)
390 #endif
392 #if defined(HASHED_PAGE_VIRTUAL)
393 void *page_address(struct page_info *page);
394 void set_page_address(struct page_info *page, void *virtual);
395 void page_address_init(void);
396 #endif
398 #if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL)
399 #define page_address(page) lowmem_page_address(page)
400 #define set_page_address(page, address) do { } while(0)
401 #define page_address_init() do { } while(0)
402 #endif
405 #ifndef CONFIG_DEBUG_PAGEALLOC
406 static inline void
407 kernel_map_pages(struct page_info *page, int numpages, int enable)
408 {
409 }
410 #endif
412 extern unsigned long num_physpages;
413 extern unsigned long totalram_pages;
414 extern int nr_swap_pages;
416 extern void alloc_dom_xen_and_dom_io(void);
417 extern int mm_teardown(struct domain* d);
418 extern void mm_final_teardown(struct domain* d);
419 extern struct page_info * assign_new_domain_page(struct domain *d, unsigned long mpaddr);
420 extern void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);
421 extern int __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr, unsigned long flags);
422 extern void assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr);
423 extern void assign_domain_io_page(struct domain *d, unsigned long mpaddr, unsigned long flags);
424 extern int deassign_domain_mmio_page(struct domain *d, unsigned long mpaddr,
425 unsigned long phys_addr, unsigned long size);
426 struct p2m_entry;
427 extern unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr, struct p2m_entry* entry);
428 extern void *domain_mpa_to_imva(struct domain *d, unsigned long mpaddr);
429 extern volatile pte_t *lookup_noalloc_domain_pte(struct domain* d, unsigned long mpaddr);
430 extern unsigned long assign_domain_mmio_page(struct domain *d, unsigned long mpaddr, unsigned long phys_addr, unsigned long size, unsigned long flags);
431 extern unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size, unsigned long flags);
432 int domain_page_mapped(struct domain *d, unsigned long mpaddr);
433 int efi_mmio(unsigned long physaddr, unsigned long size);
434 extern unsigned long ____lookup_domain_mpa(struct domain *d, unsigned long mpaddr);
435 extern unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);
436 extern unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order);
437 extern unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned long flags, domid_t domid);
438 extern unsigned long dom0vp_add_physmap_with_gmfn(struct domain* d, unsigned long gpfn, unsigned long gmfn, unsigned long flags, domid_t domid);
439 #ifdef CONFIG_XEN_IA64_EXPOSE_P2M
440 extern void expose_p2m_init(void);
441 extern unsigned long dom0vp_expose_p2m(struct domain* d, unsigned long conv_start_gpfn, unsigned long assign_start_gpfn, unsigned long expose_size, unsigned long granule_pfn);
442 extern void foreign_p2m_init(struct domain* d);
443 extern void foreign_p2m_destroy(struct domain* d);
444 extern unsigned long dom0vp_expose_foreign_p2m(struct domain* dest_dom, unsigned long dest_gpfn, domid_t domid, XEN_GUEST_HANDLE(char) buffer, unsigned long flags);
445 extern unsigned long dom0vp_unexpose_foreign_p2m(struct domain* dest_dom, unsigned long dest_gpfn, domid_t domid);
446 extern unsigned long dom0vp_get_memmap(domid_t domid, XEN_GUEST_HANDLE(char) buffer);
447 #else
448 #define expose_p2m_init() do { } while (0)
449 #define dom0vp_expose_p2m(d, conv_start_gpfn, assign_start_gpfn, expose_size, granule_pfn) (-ENOSYS)
450 #define foreign_p2m_init(d) do { } while (0)
451 #define foreign_p2m_destroy(d) do { } while (0)
452 #define dom0vp_expose_foreign_p2m(dest_dom, dest_gpfn, domid, buffer, flags) (-ENOSYS)
453 #define dom0vp_unexpose_foreign_p2m(dest_dom, dest_gpfn, domid) (-ENOSYS)
454 #define __dom0vp_add_memdesc(d, memmap_info, memdesc) (-ENOSYS)
455 #define dom0vp_get_memmap(domid, buffer) (-ENOSYS)
456 #endif
458 int
459 p2m_pod_decrease_reservation(struct domain *d,
460 xen_pfn_t gpfn, unsigned int order);
461 int guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
462 unsigned int order);
464 extern volatile unsigned long *mpt_table;
465 extern unsigned long gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
466 extern u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__,
467 u64* itir, struct p2m_entry* entry);
468 #define machine_to_phys_mapping mpt_table
470 #define INVALID_M2P_ENTRY (~0UL)
471 #define VALID_M2P(_e) (!((_e) & (1UL<<63)))
473 #define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn))
474 #define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)])
476 /* If pmt table is provided by control pannel later, we need __get_user
477 * here. However if it's allocated by HV, we should access it directly
478 */
480 #define mfn_to_gmfn(_d, mfn) \
481 get_gpfn_from_mfn(mfn)
483 #define gmfn_to_mfn(_d, gpfn) \
484 gmfn_to_mfn_foreign((_d), (gpfn))
486 #define __gpfn_invalid(_d, gpfn) \
487 (lookup_domain_mpa((_d), ((gpfn)<<PAGE_SHIFT), NULL) == INVALID_MFN)
489 #define __gmfn_valid(_d, gpfn) !__gpfn_invalid(_d, gpfn)
491 #define __gpa_to_mpa(_d, gpa) \
492 ((gmfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK))
494 #define __mpa_to_gpa(madr) \
495 ((get_gpfn_from_mfn((madr) >> PAGE_SHIFT) << PAGE_SHIFT) | \
496 ((madr) & ~PAGE_MASK))
498 /* Internal use only: returns 0 in case of bad address. */
499 extern unsigned long paddr_to_maddr(unsigned long paddr);
501 /* Arch-specific portion of memory_op hypercall. */
502 long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
504 int steal_page(
505 struct domain *d, struct page_info *page, unsigned int memflags);
507 #define domain_clamp_alloc_bitsize(d, b) (b)
509 unsigned long domain_get_maximum_gpfn(struct domain *d);
511 extern struct domain *dom_xen, *dom_io; /* for vmcoreinfo */
513 #endif /* __ASM_IA64_MM_H__ */