~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to xen/include/xen/mm.h

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * include/xen/mm.h
 
3
 * 
 
4
 * Definitions for memory pages, frame numbers, addresses, allocations, etc.
 
5
 * 
 
6
 * Note that Xen must handle several different physical 'address spaces' and
 
7
 * there is a consistent terminology for these:
 
8
 * 
 
9
 * 1. gpfn/gpaddr: A guest-specific pseudo-physical frame number or address.
 
10
 * 2. gmfn/gmaddr: A machine address from the p.o.v. of a particular guest.
 
11
 * 3. mfn/maddr:   A real machine frame number or address.
 
12
 * 4. pfn/paddr:   Used in 'polymorphic' functions that work across all
 
13
 *                 address spaces, depending on context. See the pagetable
 
14
 *                 conversion macros in asm-x86/page.h for examples.
 
15
 *                 Also 'paddr_t' is big enough to store any physical address.
 
16
 * 
 
17
 * This scheme provides consistent function and variable names even when
 
18
 * different guests are running in different memory-management modes.
 
19
 * 1. A guest running in auto-translated mode (e.g., shadow_mode_translate())
 
20
 *    will have gpfn == gmfn and gmfn != mfn.
 
21
 * 2. A paravirtualised x86 guest will have gpfn != gmfn and gmfn == mfn.
 
22
 * 3. A paravirtualised guest with no pseudophysical overlay will have
 
23
 *    gpfn == gpmfn == mfn.
 
24
 * 
 
25
 * Copyright (c) 2002-2006, K A Fraser <keir@xensource.com>
 
26
 */
 
27
 
 
28
#ifndef __XEN_MM_H__
 
29
#define __XEN_MM_H__
 
30
 
 
31
#include <xen/config.h>
 
32
#include <xen/types.h>
 
33
#include <xen/list.h>
 
34
#include <xen/spinlock.h>
 
35
 
 
36
struct domain;
 
37
struct page_info;
 
38
 
 
39
/* Boot-time allocator. Turns into generic allocator after bootstrap. */
 
40
void init_boot_pages(paddr_t ps, paddr_t pe);
 
41
unsigned long alloc_boot_pages(
 
42
    unsigned long nr_pfns, unsigned long pfn_align);
 
43
void end_boot_allocator(void);
 
44
 
 
45
/* Xen suballocator. These functions are interrupt-safe. */
 
46
void init_xenheap_pages(paddr_t ps, paddr_t pe);
 
47
void *alloc_xenheap_pages(unsigned int order, unsigned int memflags);
 
48
void free_xenheap_pages(void *v, unsigned int order);
 
49
#define alloc_xenheap_page() (alloc_xenheap_pages(0,0))
 
50
#define free_xenheap_page(v) (free_xenheap_pages(v,0))
 
51
 
 
52
/* Domain suballocator. These functions are *not* interrupt-safe.*/
 
53
void init_domheap_pages(paddr_t ps, paddr_t pe);
 
54
struct page_info *alloc_domheap_pages(
 
55
    struct domain *d, unsigned int order, unsigned int memflags);
 
56
void free_domheap_pages(struct page_info *pg, unsigned int order);
 
57
unsigned long avail_domheap_pages_region(
 
58
    unsigned int node, unsigned int min_width, unsigned int max_width);
 
59
unsigned long avail_domheap_pages(void);
 
60
#define alloc_domheap_page(d,f) (alloc_domheap_pages(d,0,f))
 
61
#define free_domheap_page(p)  (free_domheap_pages(p,0))
 
62
unsigned int online_page(unsigned long mfn, uint32_t *status);
 
63
int offline_page(unsigned long mfn, int broken, uint32_t *status);
 
64
int query_page_offline(unsigned long mfn, uint32_t *status);
 
65
unsigned long total_free_pages(void);
 
66
 
 
67
void scrub_heap_pages(void);
 
68
 
 
69
int assign_pages(
 
70
    struct domain *d,
 
71
    struct page_info *pg,
 
72
    unsigned int order,
 
73
    unsigned int memflags);
 
74
 
 
75
/* memflags: */
 
76
#define _MEMF_no_refcount 0
 
77
#define  MEMF_no_refcount (1U<<_MEMF_no_refcount)
 
78
#define _MEMF_populate_on_demand 1
 
79
#define  MEMF_populate_on_demand (1U<<_MEMF_populate_on_demand)
 
80
#define _MEMF_tmem        2
 
81
#define  MEMF_tmem        (1U<<_MEMF_tmem)
 
82
#define _MEMF_node        8
 
83
#define  MEMF_node(n)     ((((n)+1)&0xff)<<_MEMF_node)
 
84
#define _MEMF_bits        24
 
85
#define  MEMF_bits(n)     ((n)<<_MEMF_bits)
 
86
 
 
87
#ifdef CONFIG_PAGEALLOC_MAX_ORDER
 
88
#define MAX_ORDER CONFIG_PAGEALLOC_MAX_ORDER
 
89
#else
 
90
#define MAX_ORDER 20 /* 2^20 contiguous pages */
 
91
#endif
 
92
 
 
93
#define page_list_entry list_head
 
94
 
 
95
#include <asm/mm.h>
 
96
 
 
97
#ifndef page_list_entry
 
98
struct page_list_head
 
99
{
 
100
    struct page_info *next, *tail;
 
101
};
 
102
/* These must only have instances in struct page_info. */
 
103
# define page_list_entry
 
104
 
 
105
#define PAGE_LIST_NULL (~0)
 
106
 
 
107
# if !defined(pdx_to_page) && !defined(page_to_pdx)
 
108
#  if defined(__page_to_mfn) || defined(__mfn_to_page)
 
109
#   define page_to_pdx __page_to_mfn
 
110
#   define pdx_to_page __mfn_to_page
 
111
#  else
 
112
#   define page_to_pdx page_to_mfn
 
113
#   define pdx_to_page mfn_to_page
 
114
#  endif
 
115
# endif
 
116
 
 
117
# define PAGE_LIST_HEAD_INIT(name) { NULL, NULL }
 
118
# define PAGE_LIST_HEAD(name) \
 
119
    struct page_list_head name = PAGE_LIST_HEAD_INIT(name)
 
120
# define INIT_PAGE_LIST_HEAD(head) ((head)->tail = (head)->next = NULL)
 
121
# define INIT_PAGE_LIST_ENTRY(ent) ((ent)->prev = (ent)->next = PAGE_LIST_NULL)
 
122
 
 
123
static inline int
 
124
page_list_empty(const struct page_list_head *head)
 
125
{
 
126
    return !head->next;
 
127
}
 
128
static inline struct page_info *
 
129
page_list_first(const struct page_list_head *head)
 
130
{
 
131
    return head->next;
 
132
}
 
133
static inline struct page_info *
 
134
page_list_next(const struct page_info *page,
 
135
               const struct page_list_head *head)
 
136
{
 
137
    return page != head->tail ? pdx_to_page(page->list.next) : NULL;
 
138
}
 
139
static inline struct page_info *
 
140
page_list_prev(const struct page_info *page,
 
141
               const struct page_list_head *head)
 
142
{
 
143
    return page != head->next ? pdx_to_page(page->list.prev) : NULL;
 
144
}
 
145
static inline void
 
146
page_list_add(struct page_info *page, struct page_list_head *head)
 
147
{
 
148
    if ( head->next )
 
149
    {
 
150
        page->list.next = page_to_pdx(head->next);
 
151
        head->next->list.prev = page_to_pdx(page);
 
152
    }
 
153
    else
 
154
    {
 
155
        head->tail = page;
 
156
        page->list.next = PAGE_LIST_NULL;
 
157
    }
 
158
    page->list.prev = PAGE_LIST_NULL;
 
159
    head->next = page;
 
160
}
 
161
static inline void
 
162
page_list_add_tail(struct page_info *page, struct page_list_head *head)
 
163
{
 
164
    page->list.next = PAGE_LIST_NULL;
 
165
    if ( head->next )
 
166
    {
 
167
        page->list.prev = page_to_pdx(head->tail);
 
168
        head->tail->list.next = page_to_pdx(page);
 
169
    }
 
170
    else
 
171
    {
 
172
        page->list.prev = PAGE_LIST_NULL;
 
173
        head->next = page;
 
174
    }
 
175
    head->tail = page;
 
176
}
 
177
static inline bool_t
 
178
__page_list_del_head(struct page_info *page, struct page_list_head *head,
 
179
                     struct page_info *next, struct page_info *prev)
 
180
{
 
181
    if ( head->next == page )
 
182
    {
 
183
        if ( head->tail != page )
 
184
        {
 
185
            next->list.prev = PAGE_LIST_NULL;
 
186
            head->next = next;
 
187
        }
 
188
        else
 
189
            head->tail = head->next = NULL;
 
190
        return 1;
 
191
    }
 
192
 
 
193
    if ( head->tail == page )
 
194
    {
 
195
        prev->list.next = PAGE_LIST_NULL;
 
196
        head->tail = prev;
 
197
        return 1;
 
198
    }
 
199
 
 
200
    return 0;
 
201
}
 
202
static inline void
 
203
page_list_del(struct page_info *page, struct page_list_head *head)
 
204
{
 
205
    struct page_info *next = pdx_to_page(page->list.next);
 
206
    struct page_info *prev = pdx_to_page(page->list.prev);
 
207
 
 
208
    if ( !__page_list_del_head(page, head, next, prev) )
 
209
    {
 
210
        next->list.prev = page->list.prev;
 
211
        prev->list.next = page->list.next;
 
212
    }
 
213
}
 
214
static inline void
 
215
page_list_del2(struct page_info *page, struct page_list_head *head1,
 
216
               struct page_list_head *head2)
 
217
{
 
218
    struct page_info *next = pdx_to_page(page->list.next);
 
219
    struct page_info *prev = pdx_to_page(page->list.prev);
 
220
 
 
221
    if ( !__page_list_del_head(page, head1, next, prev) &&
 
222
         !__page_list_del_head(page, head2, next, prev) )
 
223
    {
 
224
        next->list.prev = page->list.prev;
 
225
        prev->list.next = page->list.next;
 
226
    }
 
227
}
 
228
static inline struct page_info *
 
229
page_list_remove_head(struct page_list_head *head)
 
230
{
 
231
    struct page_info *page = head->next;
 
232
 
 
233
    if ( page )
 
234
        page_list_del(page, head);
 
235
 
 
236
    return page;
 
237
}
 
238
static inline void
 
239
page_list_move(struct page_list_head *dst, struct page_list_head *src)
 
240
{
 
241
    if ( !page_list_empty(src) )
 
242
    {
 
243
        *dst = *src;
 
244
        INIT_PAGE_LIST_HEAD(src);
 
245
    }
 
246
}
 
247
static inline void
 
248
page_list_splice(struct page_list_head *list, struct page_list_head *head)
 
249
{
 
250
    struct page_info *first, *last, *at;
 
251
 
 
252
    if ( page_list_empty(list) )
 
253
        return;
 
254
 
 
255
    if ( page_list_empty(head) )
 
256
    {
 
257
        head->next = list->next;
 
258
        head->tail = list->tail;
 
259
        return;
 
260
    }
 
261
 
 
262
    first = list->next;
 
263
    last = list->tail;
 
264
    at = head->next;
 
265
 
 
266
    first->list.prev = page_to_pdx(head->next);
 
267
    head->next = first;
 
268
 
 
269
    last->list.next = page_to_pdx(at);
 
270
    at->list.prev = page_to_pdx(last);
 
271
}
 
272
 
 
273
#define page_list_for_each(pos, head) \
 
274
    for ( pos = (head)->next; pos; pos = page_list_next(pos, head) )
 
275
#define page_list_for_each_safe(pos, tmp, head) \
 
276
    for ( pos = (head)->next; \
 
277
          pos ? (tmp = page_list_next(pos, head), 1) : 0; \
 
278
          pos = tmp )
 
279
#define page_list_for_each_safe_reverse(pos, tmp, head) \
 
280
    for ( pos = (head)->tail; \
 
281
          pos ? (tmp = page_list_prev(pos, head), 1) : 0; \
 
282
          pos = tmp )
 
283
#else
 
284
# define page_list_head                  list_head
 
285
# define PAGE_LIST_HEAD_INIT             LIST_HEAD_INIT
 
286
# define PAGE_LIST_HEAD                  LIST_HEAD
 
287
# define INIT_PAGE_LIST_HEAD             INIT_LIST_HEAD
 
288
# define INIT_PAGE_LIST_ENTRY            INIT_LIST_HEAD
 
289
# define page_list_empty                 list_empty
 
290
# define page_list_first(hd)             list_entry((hd)->next, \
 
291
                                                    struct page_info, list)
 
292
# define page_list_next(pg, hd)          list_entry((pg)->list.next, \
 
293
                                                    struct page_info, list)
 
294
# define page_list_add(pg, hd)           list_add(&(pg)->list, hd)
 
295
# define page_list_add_tail(pg, hd)      list_add_tail(&(pg)->list, hd)
 
296
# define page_list_del(pg, hd)           list_del(&(pg)->list)
 
297
# define page_list_del2(pg, hd1, hd2)    list_del(&(pg)->list)
 
298
# define page_list_remove_head(hd)       (!page_list_empty(hd) ? \
 
299
    ({ \
 
300
        struct page_info *__pg = page_list_first(hd); \
 
301
        list_del(&__pg->list); \
 
302
        __pg; \
 
303
    }) : NULL)
 
304
# define page_list_move(dst, src)        (!list_empty(src) ? \
 
305
    list_replace_init(src, dst) : (void)0)
 
306
# define page_list_for_each(pos, head)   list_for_each_entry(pos, head, list)
 
307
# define page_list_for_each_safe(pos, tmp, head) \
 
308
    list_for_each_entry_safe(pos, tmp, head, list)
 
309
# define page_list_for_each_safe_reverse(pos, tmp, head) \
 
310
    list_for_each_entry_safe_reverse(pos, tmp, head, list)
 
311
# define page_list_splice(list, hd)        list_splice(list, hd)
 
312
#endif
 
313
 
 
314
void scrub_one_page(struct page_info *);
 
315
 
 
316
int guest_remove_page(struct domain *d, unsigned long gmfn);
 
317
 
 
318
#define RAM_TYPE_CONVENTIONAL 0x00000001
 
319
#define RAM_TYPE_RESERVED     0x00000002
 
320
#define RAM_TYPE_UNUSABLE     0x00000004
 
321
#define RAM_TYPE_ACPI         0x00000008
 
322
/* TRUE if the whole page at @mfn is of the requested RAM type(s) above. */
 
323
int page_is_ram_type(unsigned long mfn, unsigned long mem_type);
 
324
 
 
325
#endif /* __XEN_MM_H__ */