ia64/xen-unstable

changeset 1709:5b7ee1537994

bitkeeper revision 1.1041.1.20 (40ec2757AMaFbYX_parMzHPjd8NvAw)

Move mm.h to machdep
author djm@kirby.fc.hp.com
date Wed Jul 07 16:39:51 2004 +0000 (2004-07-07)
parents 0641c37d44f8
children b1477b06e393
files .rootkeys xen/include/asm-x86/mm.h xen/include/xen/mm.h
line diff
     1.1 --- a/.rootkeys	Tue Jul 06 23:52:24 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jul 07 16:39:51 2004 +0000
     1.3 @@ -446,6 +446,7 @@ 3ddb79c2TKeScYHQZreTdHqYNLbehQ xen/inclu
     1.4  3ddb79c2L7rTlFzazOLW1XuSZefpFw xen/include/asm-x86/irq.h
     1.5  404f1b93OjLO4bFfBXYNaJdIqlNz-Q xen/include/asm-x86/ldt.h
     1.6  3ddb79c3I98vWcQR8xEo34JMJ4Ahyw xen/include/asm-x86/mc146818rtc.h
     1.7 +40ec25fd7cSvbP7Biw91zaU_g0xsEQ xen/include/asm-x86/mm.h
     1.8  3ddb79c3n_UbPuxlkNxvvLycClIkxA xen/include/asm-x86/mpspec.h
     1.9  3ddb79c2wa0dA_LGigxOelSGbJ284Q xen/include/asm-x86/msr.h
    1.10  3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/include/asm-x86/mm.h	Wed Jul 07 16:39:51 2004 +0000
     2.3 @@ -0,0 +1,326 @@
     2.4 +
     2.5 +#ifndef __ASM_X86_MM_H__
     2.6 +#define __ASM_X86_MM_H__
     2.7 +
     2.8 +#include <xen/config.h>
     2.9 +#ifdef LINUX_2_6
    2.10 +#include <xen/gfp.h>
    2.11 +#endif
    2.12 +#include <xen/list.h>
    2.13 +#include <xen/spinlock.h>
    2.14 +#include <xen/perfc.h>
    2.15 +#include <xen/sched.h>
    2.16 +
    2.17 +#include <asm/processor.h>
    2.18 +#include <asm/atomic.h>
    2.19 +#include <asm/desc.h>
    2.20 +#include <asm/flushtlb.h>
    2.21 +#include <asm/io.h>
    2.22 +
    2.23 +#include <hypervisor-ifs/hypervisor-if.h>
    2.24 +
    2.25 +/*
    2.26 + * The following is for page_alloc.c.
    2.27 + */
    2.28 +
    2.29 +void init_page_allocator(unsigned long min, unsigned long max);
    2.30 +unsigned long __get_free_pages(int order);
    2.31 +void __free_pages(unsigned long p, int order);
    2.32 +#define get_free_page()   (__get_free_pages(0))
    2.33 +#define __get_free_page() (__get_free_pages(0))
    2.34 +#define free_pages(_p,_o) (__free_pages(_p,_o))
    2.35 +#define free_page(_p)     (__free_pages(_p,0))
    2.36 +
    2.37 +
    2.38 +/*
    2.39 + * Per-page-frame information.
    2.40 + */
    2.41 +
    2.42 +struct pfn_info
    2.43 +{
    2.44 +    /* Each frame can be threaded onto a doubly-linked list. */
    2.45 +    struct list_head list;
    2.46 +    /* The following possible uses are context-dependent. */
    2.47 +    union {
    2.48 +        /* Page is in use: we keep a pointer to its owner. */
    2.49 +        struct domain *domain;
    2.50 +        /* Page is not currently allocated: mask of possibly-tainted TLBs. */
    2.51 +        unsigned long cpu_mask;
    2.52 +    } u;
    2.53 +    /* Reference count and various PGC_xxx flags and fields. */
    2.54 +    u32 count_and_flags;
    2.55 +    /* Type reference count and various PGT_xxx flags and fields. */
    2.56 +    u32 type_and_flags;
    2.57 +    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
    2.58 +    u32 tlbflush_timestamp;
    2.59 +};
    2.60 +
    2.61 + /* The following page types are MUTUALLY EXCLUSIVE. */
    2.62 +#define PGT_none            (0<<29) /* no special uses of this page */
    2.63 +#define PGT_l1_page_table   (1<<29) /* using this page as an L1 page table? */
    2.64 +#define PGT_l2_page_table   (2<<29) /* using this page as an L2 page table? */
    2.65 +#define PGT_l3_page_table   (3<<29) /* using this page as an L3 page table? */
    2.66 +#define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
    2.67 +#define PGT_gdt_page        (5<<29) /* using this page in a GDT? */
    2.68 +#define PGT_ldt_page        (6<<29) /* using this page in an LDT? */
    2.69 +#define PGT_writeable_page  (7<<29) /* has writable mappings of this page? */
    2.70 +#define PGT_type_mask       (7<<29) /* Bits 29-31. */
    2.71 + /* Has this page been validated for use as its current type? */
    2.72 +#define _PGT_validated      28
    2.73 +#define PGT_validated       (1<<_PGT_validated)
    2.74 + /* 28-bit count of uses of this frame as its current type. */
    2.75 +#define PGT_count_mask      ((1<<28)-1)
    2.76 +
    2.77 + /* For safety, force a TLB flush when this page's type changes. */
    2.78 +#define _PGC_tlb_flush_on_type_change 31
    2.79 +#define PGC_tlb_flush_on_type_change  (1<<_PGC_tlb_flush_on_type_change)
    2.80 + /* Owning guest has pinned this page to its current type? */
    2.81 +#define _PGC_guest_pinned             30
    2.82 +#define PGC_guest_pinned              (1<<_PGC_guest_pinned)
    2.83 + /* Cleared when the owning guest 'frees' this page. */
    2.84 +#define _PGC_allocated                29
    2.85 +#define PGC_allocated                 (1<<_PGC_allocated)
    2.86 + /* 28-bit count of references to this frame. */
    2.87 +#define PGC_count_mask                ((1<<29)-1)
    2.88 +
    2.89 +
    2.90 +/* We trust the slab allocator in slab.c, and our use of it. */
    2.91 +#define PageSlab(page)		(1)
    2.92 +#define PageSetSlab(page)	((void)0)
    2.93 +#define PageClearSlab(page)	((void)0)
    2.94 +
    2.95 +#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
    2.96 +
    2.97 +#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
    2.98 +    do {                                                                    \
    2.99 +        (_pfn)->u.domain = (_dom);                                          \
   2.100 +        /* The incremented type count is intended to pin to 'writeable'. */ \
   2.101 +        (_pfn)->type_and_flags  = PGT_writeable_page | PGT_validated | 1;   \
   2.102 +        wmb(); /* install valid domain ptr before updating refcnt. */       \
   2.103 +        spin_lock(&(_dom)->page_alloc_lock);                                \
   2.104 +        /* _dom holds an allocation reference */                            \
   2.105 +        (_pfn)->count_and_flags = PGC_allocated | 1;                        \
   2.106 +        if ( unlikely((_dom)->xenheap_pages++ == 0) )                       \
   2.107 +            get_domain(_dom);                                               \
   2.108 +        spin_unlock(&(_dom)->page_alloc_lock);                              \
   2.109 +    } while ( 0 )
   2.110 +
   2.111 +extern struct pfn_info *frame_table;
   2.112 +extern unsigned long frame_table_size;
   2.113 +extern struct list_head free_list;
   2.114 +extern spinlock_t free_list_lock;
   2.115 +extern unsigned int free_pfns;
   2.116 +extern unsigned long max_page;
   2.117 +void init_frametable(void *frametable_vstart, unsigned long nr_pages);
   2.118 +void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
   2.119 +
   2.120 +struct pfn_info *alloc_domain_page(struct domain *p);
   2.121 +void free_domain_page(struct pfn_info *page);
   2.122 +
   2.123 +int alloc_page_type(struct pfn_info *page, unsigned int type);
   2.124 +void free_page_type(struct pfn_info *page, unsigned int type);
   2.125 +
   2.126 +static inline void put_page(struct pfn_info *page)
   2.127 +{
   2.128 +    u32 nx, x, y = page->count_and_flags;
   2.129 +
   2.130 +    do {
   2.131 +        x  = y;
   2.132 +        nx = x - 1;
   2.133 +    }
   2.134 +    while ( unlikely((y = cmpxchg(&page->count_and_flags, x, nx)) != x) );
   2.135 +
   2.136 +    if ( unlikely((nx & PGC_count_mask) == 0) )
   2.137 +        free_domain_page(page);
   2.138 +}
   2.139 +
   2.140 +
   2.141 +static inline int get_page(struct pfn_info *page,
   2.142 +                           struct domain *domain)
   2.143 +{
   2.144 +    u32 x, nx, y = page->count_and_flags;
   2.145 +    struct domain *p, *np = page->u.domain;
   2.146 +
   2.147 +    do {
   2.148 +        x  = y;
   2.149 +        nx = x + 1;
   2.150 +        p  = np;
   2.151 +        if ( unlikely((x & PGC_count_mask) == 0) ||  /* Not allocated? */
   2.152 +             unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
   2.153 +             unlikely(p != domain) )                 /* Wrong owner? */
   2.154 +        {
   2.155 +            DPRINTK("Error pfn %08lx: ed=%p(%u), sd=%p(%u),"
   2.156 +                    " caf=%08x, taf=%08x\n",
   2.157 +                    page_to_pfn(page), domain, domain->domain,
   2.158 +                    p, (p && !((x & PGC_count_mask) == 0))?p->domain:999, 
   2.159 +                    x, page->type_and_flags);
   2.160 +            return 0;
   2.161 +        }
   2.162 +        __asm__ __volatile__(
   2.163 +            LOCK_PREFIX "cmpxchg8b %3"
   2.164 +            : "=a" (np), "=d" (y), "=b" (p),
   2.165 +              "=m" (*(volatile u64 *)(&page->u.domain))
   2.166 +            : "0" (p), "1" (x), "b" (p), "c" (nx) );
   2.167 +    }
   2.168 +    while ( unlikely(np != p) || unlikely(y != x) );
   2.169 +
   2.170 +    return 1;
   2.171 +}
   2.172 +
   2.173 +
   2.174 +static inline void put_page_type(struct pfn_info *page)
   2.175 +{
   2.176 +    u32 nx, x, y = page->type_and_flags;
   2.177 +
   2.178 + again:
   2.179 +    do {
   2.180 +        x  = y;
   2.181 +        nx = x - 1;
   2.182 +        if ( unlikely((nx & PGT_count_mask) == 0) )
   2.183 +        {
   2.184 +            page->tlbflush_timestamp = tlbflush_clock;
   2.185 +            if ( unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) &&
   2.186 +                 likely(nx & PGT_validated) )
   2.187 +            {
   2.188 +                /*
   2.189 +                 * Page-table pages must be unvalidated when count is zero. The
   2.190 +                 * 'free' is safe because the refcnt is non-zero and the
   2.191 +                 * validated bit is clear => other ops will spin or fail.
   2.192 +                 */
   2.193 +                if ( unlikely((y = cmpxchg(&page->type_and_flags, x, 
   2.194 +                                           x & ~PGT_validated)) != x) )
   2.195 +                    goto again;
   2.196 +                /* We cleared the 'valid bit' so we must do the clear up. */
   2.197 +                free_page_type(page, x & PGT_type_mask);
   2.198 +                /* Carry on as we were, but with the 'valid bit' now clear. */
   2.199 +                x  &= ~PGT_validated;
   2.200 +                nx &= ~PGT_validated;
   2.201 +            }
   2.202 +        }
   2.203 +    }
   2.204 +    while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
   2.205 +}
   2.206 +
   2.207 +
   2.208 +static inline int get_page_type(struct pfn_info *page, u32 type)
   2.209 +{
   2.210 +    u32 nx, x, y = page->type_and_flags;
   2.211 + again:
   2.212 +    do {
   2.213 +        x  = y;
   2.214 +        nx = x + 1;
   2.215 +        if ( unlikely((nx & PGT_count_mask) == 0) )
   2.216 +        {
   2.217 +            DPRINTK("Type count overflow on pfn %08lx\n", page_to_pfn(page));
   2.218 +            return 0;
   2.219 +        }
   2.220 +        else if ( unlikely((x & PGT_count_mask) == 0) )
   2.221 +        {
   2.222 +            if ( (x & PGT_type_mask) != type )
   2.223 +            {
   2.224 +                nx &= ~(PGT_type_mask | PGT_validated);
   2.225 +                nx |= type;
   2.226 +                /* No extra validation needed for writeable pages. */
   2.227 +                if ( type == PGT_writeable_page )
   2.228 +                    nx |= PGT_validated;
   2.229 +            }
   2.230 +        }
   2.231 +        else if ( unlikely((x & PGT_type_mask) != type) )
   2.232 +        {
   2.233 +            DPRINTK("Unexpected type (saw %08x != exp %08x) for pfn %08lx\n",
   2.234 +                    x & PGT_type_mask, type, page_to_pfn(page));
   2.235 +            return 0;
   2.236 +        }
   2.237 +        else if ( unlikely(!(x & PGT_validated)) )
   2.238 +        {
   2.239 +            /* Someone else is updating validation of this page. Wait... */
   2.240 +            while ( (y = page->type_and_flags) != x )
   2.241 +            {
   2.242 +                rep_nop();
   2.243 +                barrier();
   2.244 +            }
   2.245 +            goto again;
   2.246 +        }
   2.247 +    }
   2.248 +    while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
   2.249 +
   2.250 +    if ( unlikely(!(nx & PGT_validated)) )
   2.251 +    {
   2.252 +        /* Try to validate page type; drop the new reference on failure. */
   2.253 +        if ( unlikely(!alloc_page_type(page, type)) )
   2.254 +        {
   2.255 +            DPRINTK("Error while validating pfn %08lx for type %08x\n",
   2.256 +                    page_to_pfn(page), type);
   2.257 +            put_page_type(page);
   2.258 +            return 0;
   2.259 +        }
   2.260 +        set_bit(_PGT_validated, &page->type_and_flags);
   2.261 +    }
   2.262 +
   2.263 +    return 1;
   2.264 +}
   2.265 +
   2.266 +
   2.267 +static inline void put_page_and_type(struct pfn_info *page)
   2.268 +{
   2.269 +    put_page_type(page);
   2.270 +    put_page(page);
   2.271 +}
   2.272 +
   2.273 +
   2.274 +static inline int get_page_and_type(struct pfn_info *page,
   2.275 +                                    struct domain *domain,
   2.276 +                                    u32 type)
   2.277 +{
   2.278 +    int rc = get_page(page, domain);
   2.279 +
   2.280 +    if ( likely(rc) && unlikely(!get_page_type(page, type)) )
   2.281 +    {
   2.282 +        put_page(page);
   2.283 +        rc = 0;
   2.284 +    }
   2.285 +
   2.286 +    return rc;
   2.287 +}
   2.288 +
   2.289 +#define ASSERT_PAGE_IS_TYPE(_p, _t)                \
   2.290 +    ASSERT(((_p)->type_and_flags & PGT_type_mask) == (_t));  \
   2.291 +    ASSERT(((_p)->type_and_flags & PGT_count_mask) != 0)
   2.292 +#define ASSERT_PAGE_IS_DOMAIN(_p, _d)              \
   2.293 +    ASSERT(((_p)->count_and_flags & PGC_count_mask) != 0);  \
   2.294 +    ASSERT((_p)->u.domain == (_d))
   2.295 +
   2.296 +int check_descriptor(unsigned long a, unsigned long b);
   2.297 +
   2.298 +/*
   2.299 + * The MPT (machine->physical mapping table) is an array of word-sized
   2.300 + * values, indexed on machine frame number. It is expected that guest OSes
   2.301 + * will use it to store a "physical" frame number to give the appearance of
   2.302 + * contiguous (or near contiguous) physical memory.
   2.303 + */
   2.304 +#undef  machine_to_phys_mapping
   2.305 +#ifdef __x86_64__
   2.306 +extern unsigned long *machine_to_phys_mapping;
   2.307 +#else
   2.308 +#define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
   2.309 +#endif
   2.310 +
   2.311 +/* Part of the domain API. */
   2.312 +int do_mmu_update(mmu_update_t *updates, int count, int *success_count);
   2.313 +
   2.314 +#define DEFAULT_GDT_ENTRIES     ((LAST_RESERVED_GDT_ENTRY*8)+7)
   2.315 +#define DEFAULT_GDT_ADDRESS     ((unsigned long)gdt_table)
   2.316 +
   2.317 +#ifdef MEMORY_GUARD
   2.318 +void *memguard_init(void *heap_start);
   2.319 +void memguard_guard_range(void *p, unsigned long l);
   2.320 +void memguard_unguard_range(void *p, unsigned long l);
   2.321 +int memguard_is_guarded(void *p);
   2.322 +#else
   2.323 +#define memguard_init(_s)              (_s)
   2.324 +#define memguard_guard_range(_p,_l)    ((void)0)
   2.325 +#define memguard_unguard_range(_p,_l)  ((void)0)
   2.326 +#define memguard_is_guarded(_p)        (0)
   2.327 +#endif
   2.328 +
   2.329 +#endif /* __ASM_X86_MM_H__ */
     3.1 --- a/xen/include/xen/mm.h	Tue Jul 06 23:52:24 2004 +0000
     3.2 +++ b/xen/include/xen/mm.h	Wed Jul 07 16:39:51 2004 +0000
     3.3 @@ -2,325 +2,6 @@
     3.4  #ifndef __XEN_MM_H__
     3.5  #define __XEN_MM_H__
     3.6  
     3.7 -#include <xen/config.h>
     3.8 -#ifdef LINUX_2_6
     3.9 -#include <xen/gfp.h>
    3.10 -#endif
    3.11 -#include <xen/list.h>
    3.12 -#include <xen/spinlock.h>
    3.13 -#include <xen/perfc.h>
    3.14 -#include <xen/sched.h>
    3.15 -
    3.16 -#include <asm/processor.h>
    3.17 -#include <asm/atomic.h>
    3.18 -#include <asm/desc.h>
    3.19 -#include <asm/flushtlb.h>
    3.20 -#include <asm/io.h>
    3.21 -
    3.22 -#include <hypervisor-ifs/hypervisor-if.h>
    3.23 -
    3.24 -/*
    3.25 - * The following is for page_alloc.c.
    3.26 - */
    3.27 -
    3.28 -void init_page_allocator(unsigned long min, unsigned long max);
    3.29 -unsigned long __get_free_pages(int order);
    3.30 -void __free_pages(unsigned long p, int order);
    3.31 -#define get_free_page()   (__get_free_pages(0))
    3.32 -#define __get_free_page() (__get_free_pages(0))
    3.33 -#define free_pages(_p,_o) (__free_pages(_p,_o))
    3.34 -#define free_page(_p)     (__free_pages(_p,0))
    3.35 -
    3.36 -
    3.37 -/*
    3.38 - * Per-page-frame information.
    3.39 - */
    3.40 -
    3.41 -struct pfn_info
    3.42 -{
    3.43 -    /* Each frame can be threaded onto a doubly-linked list. */
    3.44 -    struct list_head list;
    3.45 -    /* The following possible uses are context-dependent. */
    3.46 -    union {
    3.47 -        /* Page is in use: we keep a pointer to its owner. */
    3.48 -        struct domain *domain;
    3.49 -        /* Page is not currently allocated: mask of possibly-tainted TLBs. */
    3.50 -        unsigned long cpu_mask;
    3.51 -    } u;
    3.52 -    /* Reference count and various PGC_xxx flags and fields. */
    3.53 -    u32 count_and_flags;
    3.54 -    /* Type reference count and various PGT_xxx flags and fields. */
    3.55 -    u32 type_and_flags;
    3.56 -    /* Timestamp from 'TLB clock', used to reduce need for safety flushes. */
    3.57 -    u32 tlbflush_timestamp;
    3.58 -};
    3.59 -
    3.60 - /* The following page types are MUTUALLY EXCLUSIVE. */
    3.61 -#define PGT_none            (0<<29) /* no special uses of this page */
    3.62 -#define PGT_l1_page_table   (1<<29) /* using this page as an L1 page table? */
    3.63 -#define PGT_l2_page_table   (2<<29) /* using this page as an L2 page table? */
    3.64 -#define PGT_l3_page_table   (3<<29) /* using this page as an L3 page table? */
    3.65 -#define PGT_l4_page_table   (4<<29) /* using this page as an L4 page table? */
    3.66 -#define PGT_gdt_page        (5<<29) /* using this page in a GDT? */
    3.67 -#define PGT_ldt_page        (6<<29) /* using this page in an LDT? */
    3.68 -#define PGT_writeable_page  (7<<29) /* has writable mappings of this page? */
    3.69 -#define PGT_type_mask       (7<<29) /* Bits 29-31. */
    3.70 - /* Has this page been validated for use as its current type? */
    3.71 -#define _PGT_validated      28
    3.72 -#define PGT_validated       (1<<_PGT_validated)
    3.73 - /* 28-bit count of uses of this frame as its current type. */
    3.74 -#define PGT_count_mask      ((1<<28)-1)
    3.75 -
    3.76 - /* For safety, force a TLB flush when this page's type changes. */
    3.77 -#define _PGC_tlb_flush_on_type_change 31
    3.78 -#define PGC_tlb_flush_on_type_change  (1<<_PGC_tlb_flush_on_type_change)
    3.79 - /* Owning guest has pinned this page to its current type? */
    3.80 -#define _PGC_guest_pinned             30
    3.81 -#define PGC_guest_pinned              (1<<_PGC_guest_pinned)
    3.82 - /* Cleared when the owning guest 'frees' this page. */
    3.83 -#define _PGC_allocated                29
    3.84 -#define PGC_allocated                 (1<<_PGC_allocated)
    3.85 - /* 28-bit count of references to this frame. */
    3.86 -#define PGC_count_mask                ((1<<29)-1)
    3.87 -
    3.88 -
    3.89 -/* We trust the slab allocator in slab.c, and our use of it. */
    3.90 -#define PageSlab(page)		(1)
    3.91 -#define PageSetSlab(page)	((void)0)
    3.92 -#define PageClearSlab(page)	((void)0)
    3.93 -
    3.94 -#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
    3.95 -
    3.96 -#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
    3.97 -    do {                                                                    \
    3.98 -        (_pfn)->u.domain = (_dom);                                          \
    3.99 -        /* The incremented type count is intended to pin to 'writeable'. */ \
   3.100 -        (_pfn)->type_and_flags  = PGT_writeable_page | PGT_validated | 1;   \
   3.101 -        wmb(); /* install valid domain ptr before updating refcnt. */       \
   3.102 -        spin_lock(&(_dom)->page_alloc_lock);                                \
   3.103 -        /* _dom holds an allocation reference */                            \
   3.104 -        (_pfn)->count_and_flags = PGC_allocated | 1;                        \
   3.105 -        if ( unlikely((_dom)->xenheap_pages++ == 0) )                       \
   3.106 -            get_domain(_dom);                                               \
   3.107 -        spin_unlock(&(_dom)->page_alloc_lock);                              \
   3.108 -    } while ( 0 )
   3.109 -
   3.110 -extern struct pfn_info *frame_table;
   3.111 -extern unsigned long frame_table_size;
   3.112 -extern struct list_head free_list;
   3.113 -extern spinlock_t free_list_lock;
   3.114 -extern unsigned int free_pfns;
   3.115 -extern unsigned long max_page;
   3.116 -void init_frametable(void *frametable_vstart, unsigned long nr_pages);
   3.117 -void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
   3.118 -
   3.119 -struct pfn_info *alloc_domain_page(struct domain *p);
   3.120 -void free_domain_page(struct pfn_info *page);
   3.121 -
   3.122 -int alloc_page_type(struct pfn_info *page, unsigned int type);
   3.123 -void free_page_type(struct pfn_info *page, unsigned int type);
   3.124 -
   3.125 -static inline void put_page(struct pfn_info *page)
   3.126 -{
   3.127 -    u32 nx, x, y = page->count_and_flags;
   3.128 -
   3.129 -    do {
   3.130 -        x  = y;
   3.131 -        nx = x - 1;
   3.132 -    }
   3.133 -    while ( unlikely((y = cmpxchg(&page->count_and_flags, x, nx)) != x) );
   3.134 -
   3.135 -    if ( unlikely((nx & PGC_count_mask) == 0) )
   3.136 -        free_domain_page(page);
   3.137 -}
   3.138 -
   3.139 -
   3.140 -static inline int get_page(struct pfn_info *page,
   3.141 -                           struct domain *domain)
   3.142 -{
   3.143 -    u32 x, nx, y = page->count_and_flags;
   3.144 -    struct domain *p, *np = page->u.domain;
   3.145 -
   3.146 -    do {
   3.147 -        x  = y;
   3.148 -        nx = x + 1;
   3.149 -        p  = np;
   3.150 -        if ( unlikely((x & PGC_count_mask) == 0) ||  /* Not allocated? */
   3.151 -             unlikely((nx & PGC_count_mask) == 0) || /* Count overflow? */
   3.152 -             unlikely(p != domain) )                 /* Wrong owner? */
   3.153 -        {
   3.154 -            DPRINTK("Error pfn %08lx: ed=%p(%u), sd=%p(%u),"
   3.155 -                    " caf=%08x, taf=%08x\n",
   3.156 -                    page_to_pfn(page), domain, domain->domain,
   3.157 -                    p, (p && !((x & PGC_count_mask) == 0))?p->domain:999, 
   3.158 -                    x, page->type_and_flags);
   3.159 -            return 0;
   3.160 -        }
   3.161 -        __asm__ __volatile__(
   3.162 -            LOCK_PREFIX "cmpxchg8b %3"
   3.163 -            : "=a" (np), "=d" (y), "=b" (p),
   3.164 -              "=m" (*(volatile u64 *)(&page->u.domain))
   3.165 -            : "0" (p), "1" (x), "b" (p), "c" (nx) );
   3.166 -    }
   3.167 -    while ( unlikely(np != p) || unlikely(y != x) );
   3.168 -
   3.169 -    return 1;
   3.170 -}
   3.171 -
   3.172 -
   3.173 -static inline void put_page_type(struct pfn_info *page)
   3.174 -{
   3.175 -    u32 nx, x, y = page->type_and_flags;
   3.176 -
   3.177 - again:
   3.178 -    do {
   3.179 -        x  = y;
   3.180 -        nx = x - 1;
   3.181 -        if ( unlikely((nx & PGT_count_mask) == 0) )
   3.182 -        {
   3.183 -            page->tlbflush_timestamp = tlbflush_clock;
   3.184 -            if ( unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) &&
   3.185 -                 likely(nx & PGT_validated) )
   3.186 -            {
   3.187 -                /*
   3.188 -                 * Page-table pages must be unvalidated when count is zero. The
   3.189 -                 * 'free' is safe because the refcnt is non-zero and the
   3.190 -                 * validated bit is clear => other ops will spin or fail.
   3.191 -                 */
   3.192 -                if ( unlikely((y = cmpxchg(&page->type_and_flags, x, 
   3.193 -                                           x & ~PGT_validated)) != x) )
   3.194 -                    goto again;
   3.195 -                /* We cleared the 'valid bit' so we must do the clear up. */
   3.196 -                free_page_type(page, x & PGT_type_mask);
   3.197 -                /* Carry on as we were, but with the 'valid bit' now clear. */
   3.198 -                x  &= ~PGT_validated;
   3.199 -                nx &= ~PGT_validated;
   3.200 -            }
   3.201 -        }
   3.202 -    }
   3.203 -    while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
   3.204 -}
   3.205 -
   3.206 -
   3.207 -static inline int get_page_type(struct pfn_info *page, u32 type)
   3.208 -{
   3.209 -    u32 nx, x, y = page->type_and_flags;
   3.210 - again:
   3.211 -    do {
   3.212 -        x  = y;
   3.213 -        nx = x + 1;
   3.214 -        if ( unlikely((nx & PGT_count_mask) == 0) )
   3.215 -        {
   3.216 -            DPRINTK("Type count overflow on pfn %08lx\n", page_to_pfn(page));
   3.217 -            return 0;
   3.218 -        }
   3.219 -        else if ( unlikely((x & PGT_count_mask) == 0) )
   3.220 -        {
   3.221 -            if ( (x & PGT_type_mask) != type )
   3.222 -            {
   3.223 -                nx &= ~(PGT_type_mask | PGT_validated);
   3.224 -                nx |= type;
   3.225 -                /* No extra validation needed for writeable pages. */
   3.226 -                if ( type == PGT_writeable_page )
   3.227 -                    nx |= PGT_validated;
   3.228 -            }
   3.229 -        }
   3.230 -        else if ( unlikely((x & PGT_type_mask) != type) )
   3.231 -        {
   3.232 -            DPRINTK("Unexpected type (saw %08x != exp %08x) for pfn %08lx\n",
   3.233 -                    x & PGT_type_mask, type, page_to_pfn(page));
   3.234 -            return 0;
   3.235 -        }
   3.236 -        else if ( unlikely(!(x & PGT_validated)) )
   3.237 -        {
   3.238 -            /* Someone else is updating validation of this page. Wait... */
   3.239 -            while ( (y = page->type_and_flags) != x )
   3.240 -            {
   3.241 -                rep_nop();
   3.242 -                barrier();
   3.243 -            }
   3.244 -            goto again;
   3.245 -        }
   3.246 -    }
   3.247 -    while ( unlikely((y = cmpxchg(&page->type_and_flags, x, nx)) != x) );
   3.248 -
   3.249 -    if ( unlikely(!(nx & PGT_validated)) )
   3.250 -    {
   3.251 -        /* Try to validate page type; drop the new reference on failure. */
   3.252 -        if ( unlikely(!alloc_page_type(page, type)) )
   3.253 -        {
   3.254 -            DPRINTK("Error while validating pfn %08lx for type %08x\n",
   3.255 -                    page_to_pfn(page), type);
   3.256 -            put_page_type(page);
   3.257 -            return 0;
   3.258 -        }
   3.259 -        set_bit(_PGT_validated, &page->type_and_flags);
   3.260 -    }
   3.261 -
   3.262 -    return 1;
   3.263 -}
   3.264 -
   3.265 -
   3.266 -static inline void put_page_and_type(struct pfn_info *page)
   3.267 -{
   3.268 -    put_page_type(page);
   3.269 -    put_page(page);
   3.270 -}
   3.271 -
   3.272 -
   3.273 -static inline int get_page_and_type(struct pfn_info *page,
   3.274 -                                    struct domain *domain,
   3.275 -                                    u32 type)
   3.276 -{
   3.277 -    int rc = get_page(page, domain);
   3.278 -
   3.279 -    if ( likely(rc) && unlikely(!get_page_type(page, type)) )
   3.280 -    {
   3.281 -        put_page(page);
   3.282 -        rc = 0;
   3.283 -    }
   3.284 -
   3.285 -    return rc;
   3.286 -}
   3.287 -
   3.288 -#define ASSERT_PAGE_IS_TYPE(_p, _t)                \
   3.289 -    ASSERT(((_p)->type_and_flags & PGT_type_mask) == (_t));  \
   3.290 -    ASSERT(((_p)->type_and_flags & PGT_count_mask) != 0)
   3.291 -#define ASSERT_PAGE_IS_DOMAIN(_p, _d)              \
   3.292 -    ASSERT(((_p)->count_and_flags & PGC_count_mask) != 0);  \
   3.293 -    ASSERT((_p)->u.domain == (_d))
   3.294 -
   3.295 -int check_descriptor(unsigned long a, unsigned long b);
   3.296 -
   3.297 -/*
   3.298 - * The MPT (machine->physical mapping table) is an array of word-sized
   3.299 - * values, indexed on machine frame number. It is expected that guest OSes
   3.300 - * will use it to store a "physical" frame number to give the appearance of
   3.301 - * contiguous (or near contiguous) physical memory.
   3.302 - */
   3.303 -#undef  machine_to_phys_mapping
   3.304 -#ifdef __x86_64__
   3.305 -extern unsigned long *machine_to_phys_mapping;
   3.306 -#else
   3.307 -#define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
   3.308 -#endif
   3.309 -
   3.310 -/* Part of the domain API. */
   3.311 -int do_mmu_update(mmu_update_t *updates, int count, int *success_count);
   3.312 -
   3.313 -#define DEFAULT_GDT_ENTRIES     ((LAST_RESERVED_GDT_ENTRY*8)+7)
   3.314 -#define DEFAULT_GDT_ADDRESS     ((unsigned long)gdt_table)
   3.315 -
   3.316 -#ifdef MEMORY_GUARD
   3.317 -void *memguard_init(void *heap_start);
   3.318 -void memguard_guard_range(void *p, unsigned long l);
   3.319 -void memguard_unguard_range(void *p, unsigned long l);
   3.320 -int memguard_is_guarded(void *p);
   3.321 -#else
   3.322 -#define memguard_init(_s)              (_s)
   3.323 -#define memguard_guard_range(_p,_l)    ((void)0)
   3.324 -#define memguard_unguard_range(_p,_l)  ((void)0)
   3.325 -#define memguard_is_guarded(_p)        (0)
   3.326 -#endif
   3.327 +#include <asm/mm.h>
   3.328  
   3.329  #endif /* __XEN_MM_H__ */