source: trunk/packages/xen-3.1/xen-3.1/xen/include/asm-powerpc/mm.h @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 8.5 KB
Line 
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
15 *
16 * Copyright IBM Corp. 2005, 2006, 2007
17 *
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 *          Jimi Xenidis <jimix@watson.ibm.com>
20 */
21
22#ifndef _ASM_MM_H_
23#define _ASM_MM_H_
24
25#include <public/xen.h>
26#include <xen/list.h>
27#include <xen/types.h>
28#include <xen/mm.h>
29#include <asm/system.h>
30#include <asm/flushtlb.h>
31#include <asm/page.h>
32#include <asm/debugger.h>
33
34#define memguard_guard_range(_p,_l)    ((void)0)
35#define memguard_unguard_range(_p,_l)    ((void)0)
36
37extern unsigned long xenheap_phys_end;
38extern int boot_of_mem_avail(int pos, ulong *start, ulong *end);
39
40/*
41 * Per-page-frame information.
42 *
43 * Every architecture must ensure the following:
44 *  1. 'struct page_info' contains a 'struct list_head list'.
45 *  2. Provide a PFN_ORDER() macro for accessing the order of a free page.
46 */
47#define PFN_ORDER(_pfn) ((_pfn)->u.free.order)
48
49/* XXX copy-and-paste job; re-examine me */
50struct page_info
51{
52    /* Each frame can be threaded onto a doubly-linked list. */
53    struct list_head list;
54
55    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
56    u32 tlbflush_timestamp;
57
58    /* Reference count and various PGC_xxx flags and fields. */
59    unsigned long count_info;
60
61    /* Context-dependent fields follow... */
62    union {
63
64        /* Page is in use: ((count_info & PGC_count_mask) != 0). */
65        struct {
66            /* Owner of this page (NULL if page is anonymous). */
67            u32 _domain;
68            /* Type reference count and various PGT_xxx flags and fields. */
69            unsigned long type_info;
70        } inuse;
71
72        /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */
73        struct {
74            /* Mask of possibly-tainted TLBs. */
75            cpumask_t cpumask;
76            /* Order-size of the free chunk this page is the head of. */
77            u8 order;
78        } free;
79
80    } u;
81
82};
83
84 /* The following page types are MUTUALLY EXCLUSIVE. */
85#define PGT_none            (0UL<<29) /* no special uses of this page */
86#define PGT_RMA             (1UL<<29) /* This page is an RMA page? */
87#define PGT_writable_page   (7UL<<29) /* has writable mappings of this page? */
88#define PGT_type_mask       (7UL<<29) /* Bits 29-31. */
89
90 /* Owning guest has pinned this page to its current type? */
91#define _PGT_pinned         28
92#define PGT_pinned          (1UL<<_PGT_pinned)
93 /* Has this page been validated for use as its current type? */
94#define _PGT_validated      27
95#define PGT_validated       (1UL<<_PGT_validated)
96
97 /* 16-bit count of uses of this frame as its current type. */
98#define PGT_count_mask      ((1UL<<16)-1)
99
100 /* Cleared when the owning guest 'frees' this page. */
101#define _PGC_allocated      31
102#define PGC_allocated       (1UL<<_PGC_allocated)
103 /* Set on a *guest* page to mark it out-of-sync with its shadow */
104#define _PGC_out_of_sync     30
105#define PGC_out_of_sync     (1UL<<_PGC_out_of_sync)
106 /* Set when is using a page as a page table */
107#define _PGC_page_table      29
108#define PGC_page_table      (1UL<<_PGC_page_table)
109/* Set when using page for RMA */
110#define _PGC_page_RMA      28
111#define PGC_page_RMA      (1UL<<_PGC_page_RMA)
112 /* 29-bit count of references to this frame. */
113#define PGC_count_mask      ((1UL<<28)-1)
114
115#define IS_XEN_HEAP_FRAME(_pfn) (page_to_maddr(_pfn) < xenheap_phys_end)
116
117static inline struct domain *unpickle_domptr(u32 _domain)
118{ return ((_domain == 0) || (_domain & 1)) ? NULL : __va(_domain); }
119
120static inline u32 pickle_domptr(struct domain *domain)
121{ return (domain == NULL) ? 0 : (u32)__pa(domain); }
122
123#define PRtype_info "016lx"/* should only be used for printk's */
124
125#define page_get_owner(_p)    (unpickle_domptr((_p)->u.inuse._domain))
126#define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d))
127
128#define XENSHARE_writable 0
129#define XENSHARE_readonly 1
130extern void share_xen_page_with_guest(
131    struct page_info *page, struct domain *d, int readonly);
132extern void share_xen_page_with_privileged_guests(
133    struct page_info *page, int readonly);
134
135extern struct page_info *frame_table;
136extern unsigned long max_page;
137extern unsigned long total_pages;
138void init_frametable(void);
139void init_machine_to_phys_table(void);
140void free_rma_check(struct page_info *page);
141
142static inline void put_page(struct page_info *page)
143{
144    u32 nx, x, y = page->count_info;
145
146    do {
147        x  = y;
148        nx = x - 1;
149    }
150    while ( unlikely((y = cmpxchg(&page->count_info, x, nx)) != x) );
151
152    if ( unlikely((nx & PGC_count_mask) == 0) ) {
153        /* RMA pages can only be released while the domain is dying */
154        free_rma_check(page);
155        free_domheap_page(page);
156    }
157}
158
159static inline int get_page(struct page_info *page,
160                           struct domain *domain)
161{
162    u32 x, nx, y = page->count_info;
163    u32 d, nd = page->u.inuse._domain;
164    u32 _domain = pickle_domptr(domain);
165
166    do {
167        x  = y;
168        nx = x + 1;
169        d  = nd;
170        if ( unlikely((x & PGC_count_mask) == 0) ||  /* Not allocated? */
171             unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
172             unlikely(d != _domain) )                /* Wrong owner? */
173        {
174            return 0;
175        }
176        y = cmpxchg(&page->count_info, x, nx);
177    }
178    while ( unlikely(y != x) );
179
180    return 1;
181}
182
183extern void put_page_type(struct page_info *page);
184extern int  get_page_type(struct page_info *page, unsigned long type);
185
186static inline void put_page_and_type(struct page_info *page)
187{
188    put_page_type(page);
189    put_page(page);
190}
191
192static inline int get_page_and_type(struct page_info *page,
193                                    struct domain *domain,
194                                    unsigned long type)
195{
196    int rc = get_page(page, domain);
197
198    if ( likely(rc) && unlikely(!get_page_type(page, type)) )
199    {
200        put_page(page);
201        rc = 0;
202    }
203
204    return rc;
205}
206
207extern void synchronise_pagetables(unsigned long cpu_mask);
208
209/* XXX don't know what this is for */
210typedef struct {
211    void (*enable)(struct domain *);
212    void (*disable)(struct domain *);
213} vm_assist_info_t;
214extern vm_assist_info_t vm_assist_info[];
215
216extern unsigned long *machine_phys_mapping;
217#define machine_to_phys_mapping  (machine_phys_mapping)
218#define INVALID_M2P_ENTRY        (~0UL)
219
220#define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn))
221#define get_gpfn_from_mfn(mfn)      (machine_to_phys_mapping[(mfn)])
222
223extern unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn);
224
225extern unsigned long paddr_to_maddr(unsigned long paddr);
226
227/* INVALID_MFN can be any value that fails mfn_valid(). */
228#define INVALID_MFN (~0U)
229
230#define PFN_TYPE_NONE 0
231#define PFN_TYPE_LOGICAL 2
232#define PFN_TYPE_IO 3
233#define PFN_TYPE_FOREIGN 4
234#define PFN_TYPE_GNTTAB 5
235
236extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type);
237static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn)
238{
239    int mtype;
240    ulong mfn;
241   
242    mfn = pfn2mfn(d, gmfn, &mtype);
243    if (mfn != INVALID_MFN) {
244        switch (mtype) {
245        case PFN_TYPE_LOGICAL:
246            break;
247        default:
248            WARN();
249            mfn = INVALID_MFN;
250            break;
251        }
252    }
253    return mfn;
254}
255
256extern int update_grant_va_mapping(unsigned long va,
257                                   unsigned long val,
258                                   struct domain *,
259                                   struct vcpu *);
260
261/* Arch-specific portion of memory_op hypercall. */
262long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg);
263
264extern int allocate_rma(struct domain *d, unsigned int order_pages);
265extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages);
266
267extern int steal_page(struct domain *d, struct page_info *page,
268                        unsigned int memflags);
269
270/* XXX these just exist until we can stop #including x86 code */
271#define access_ok(addr,size) 1
272#define array_access_ok(addr,count,size) 1
273
274#define domain_clamp_alloc_bitsize(d, b) (b)
275
276#define domain_get_maximum_gpfn(d) (-ENOSYS)
277
278#endif
Note: See TracBrowser for help on using the repository browser.