[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][POWERPC] Create a Domain Foreign Map space
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID 79bb96e0ba73754aecbbdd37d1d69342af2730ee # Parent 067bf06057cc311f5c0141798cb3629828f908c1 [XEN][POWERPC] Create a Domain Foreign Map space The following patch creates a Domain Foreign Map space that is uses to map granted memory into the Linear Map of the domain. The Linear Map of Linux is the is the Kernel Virtual address space where VA = PA + PAGE_OFFSET. Also: - lots of grant_* interfaces work now - mm.[ch] cleanups - first pass at extracting Page Table operations from PAPR interfaces - get_page_type() fix logic bug - recognize a grant table mapping by placing its gmfn at the end of real memory. - grant table usually mapped like an IO page, so force WIMG bits I=0 - mfn_to_gmfn and pfn2mfn get WAY to complex, need get a simpler model in. - communicate the Domain Foreign Map to domains using /xen/foreign-map - make sure all bit definitions are UL where possible - now that we actually assign Xen heap pages to domains they must be relinquished Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/arch/powerpc/domain.c | 2 xen/arch/powerpc/mm.c | 164 +++++++++++++++++++++++++++++----- xen/arch/powerpc/ofd_fixup.c | 5 + xen/arch/powerpc/papr/xlate.c | 130 +++++++++++++++----------- xen/include/asm-powerpc/grant_table.h | 16 ++- xen/include/asm-powerpc/mm.h | 120 +++++++++++++++++------- 6 files changed, 320 insertions(+), 117 deletions(-) diff -r 067bf06057cc -r 79bb96e0ba73 xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/arch/powerpc/domain.c Sun Oct 08 11:34:24 2006 -0400 @@ -94,6 +94,7 @@ void arch_domain_destroy(struct domain * void arch_domain_destroy(struct domain *d) { shadow_teardown(d); + /* shared_info is part of the RMA so no need to release it */ } static void machine_fail(const char *s) @@ -290,6 +291,7 @@ static void relinquish_memory(struct dom void domain_relinquish_resources(struct domain *d) { + relinquish_memory(d, &d->xenpage_list); relinquish_memory(d, &d->page_list); free_extents(d); return; diff -r 067bf06057cc -r 79bb96e0ba73 xen/arch/powerpc/mm.c --- a/xen/arch/powerpc/mm.c Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/arch/powerpc/mm.c Sun Oct 08 11:34:24 2006 -0400 @@ -41,18 +41,107 @@ unsigned long max_page; unsigned long max_page; unsigned long total_pages; +void __init init_frametable(void) +{ + unsigned long p; + unsigned long nr_pages; + int i; + + nr_pages = PFN_UP(max_page * sizeof(struct page_info)); + + p = alloc_boot_pages(nr_pages, 1); + if (p == 0) + panic("Not enough memory for frame table\n"); + + frame_table = (struct page_info *)(p << PAGE_SHIFT); + for (i = 0; i < nr_pages; i += 1) + clear_page((void *)((p + i) << PAGE_SHIFT)); +} + +void share_xen_page_with_guest( + struct page_info *page, struct domain *d, int readonly) +{ + if ( page_get_owner(page) == d ) + return; + + /* this causes us to leak pages in the Domain and reuslts in + * Zombie domains, I think we are missing a piece, until we find + * it we disable the following code */ + set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY); + + spin_lock(&d->page_alloc_lock); + + /* The incremented type count pins as writable or read-only. */ + page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page); + page->u.inuse.type_info |= PGT_validated | 1; + + page_set_owner(page, d); + wmb(); /* install valid domain ptr before updating refcnt. */ + ASSERT(page->count_info == 0); + page->count_info |= PGC_allocated | 1; + + if ( unlikely(d->xenheap_pages++ == 0) ) + get_knownalive_domain(d); + list_add_tail(&page->list, &d->xenpage_list); + + spin_unlock(&d->page_alloc_lock); +} + +void share_xen_page_with_privileged_guests( + struct page_info *page, int readonly) +{ + unimplemented(); +} + +static int create_grant_va_mapping( + unsigned long va, unsigned long frame, struct vcpu *v) +{ + if (v->domain->domain_id != 0) { + printk("only Dom0 can map a grant entry\n"); + BUG(); + return GNTST_permission_denied; + } + return GNTST_okay; +} + +static int destroy_grant_va_mapping( + unsigned long addr, unsigned long frame, struct domain *d) +{ + if (d->domain_id != 0) { + printk("only Dom0 can map a grant entry\n"); + BUG(); + return GNTST_permission_denied; + } + return GNTST_okay; +} + int create_grant_host_mapping( unsigned long addr, unsigned long frame, unsigned int flags) { - panic("%s called\n", __func__); - return 1; + if (flags & GNTMAP_application_map) { + printk("%s: GNTMAP_application_map not supported\n", __func__); + BUG(); + return GNTST_general_error; + } + if (flags & GNTMAP_contains_pte) { + printk("%s: GNTMAP_contains_pte not supported\n", __func__); + BUG(); + return GNTST_general_error; + } + return create_grant_va_mapping(addr, frame, current); } int destroy_grant_host_mapping( unsigned long addr, unsigned long frame, unsigned int flags) { - panic("%s called\n", __func__); - return 1; + if (flags & GNTMAP_contains_pte) { + printk("%s: GNTMAP_contains_pte not supported\n", __func__); + BUG(); + return GNTST_general_error; + } + + /* may have force the remove here */ + return destroy_grant_va_mapping(addr, frame, current->domain); } int steal_page(struct domain *d, struct page_info *page, unsigned int memflags) @@ -138,7 +227,7 @@ int get_page_type(struct page_info *page { return 0; } - if ( unlikely(!(x & PGT_validated)) ) + else if ( unlikely(!(x & PGT_validated)) ) { /* Someone else is updating validation of this page. Wait... */ while ( (y = page->u.inuse.type_info) == x ) @@ -155,23 +244,6 @@ int get_page_type(struct page_info *page } return 1; -} - -void __init init_frametable(void) -{ - unsigned long p; - unsigned long nr_pages; - int i; - - nr_pages = PFN_UP(max_page * sizeof(struct page_info)); - - p = alloc_boot_pages(nr_pages, 1); - if (p == 0) - panic("Not enough memory for frame table\n"); - - frame_table = (struct page_info *)(p << PAGE_SHIFT); - for (i = 0; i < nr_pages; i += 1) - clear_page((void *)((p + i) << PAGE_SHIFT)); } long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) @@ -311,9 +383,18 @@ ulong pfn2mfn(struct domain *d, ulong pf struct page_extents *pe; ulong mfn = INVALID_MFN; int t = PFN_TYPE_NONE; + ulong foreign_map_pfn = 1UL << cpu_foreign_map_order(); /* quick tests first */ - if (d->is_privileged && cpu_io_mfn(pfn)) { + if (pfn & foreign_map_pfn) { + t = PFN_TYPE_FOREIGN; + mfn = pfn & ~(foreign_map_pfn); + } else if (pfn >= max_page && pfn < (max_page + NR_GRANT_FRAMES)) { + /* Its a grant table access */ + t = PFN_TYPE_GNTTAB; + mfn = gnttab_shared_mfn(d, d->grant_table, (pfn - max_page)); + } else if (test_bit(_DOMF_privileged, &d->domain_flags) && + cpu_io_mfn(pfn)) { t = PFN_TYPE_IO; mfn = pfn; } else { @@ -365,6 +446,43 @@ ulong pfn2mfn(struct domain *d, ulong pf return mfn; } +unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn) +{ + struct page_extents *pe; + ulong cur_pfn; + ulong gnttab_mfn; + ulong rma_mfn; + + /* grant? */ + gnttab_mfn = gnttab_shared_mfn(d, d->grant_table, 0); + if (mfn >= gnttab_mfn && mfn < (gnttab_mfn + NR_GRANT_FRAMES)) + return max_page + (mfn - gnttab_mfn); + + /* IO? */ + if (test_bit(_DOMF_privileged, &d->domain_flags) && + cpu_io_mfn(mfn)) + return mfn; + + rma_mfn = page_to_mfn(d->arch.rma_page); + if (mfn >= rma_mfn && + mfn < (rma_mfn + (1 << d->arch.rma_order))) + return mfn - rma_mfn; + + /* Extent? */ + cur_pfn = 1UL << d->arch.rma_order; + list_for_each_entry (pe, &d->arch.extent_list, pe_list) { + uint pe_pages = 1UL << pe->order; + uint b_mfn = page_to_mfn(pe->pg); + uint e_mfn = b_mfn + pe_pages; + + if (mfn >= b_mfn && mfn < e_mfn) { + return cur_pfn + (mfn - b_mfn); + } + cur_pfn += pe_pages; + } + return INVALID_M2P_ENTRY; +} + void guest_physmap_add_page( struct domain *d, unsigned long gpfn, unsigned long mfn) { diff -r 067bf06057cc -r 79bb96e0ba73 xen/arch/powerpc/ofd_fixup.c --- a/xen/arch/powerpc/ofd_fixup.c Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/arch/powerpc/ofd_fixup.c Sun Oct 08 11:34:24 2006 -0400 @@ -352,6 +352,11 @@ static ofdn_t ofd_xen_props(void *m, str if (!rtas_entry) ofd_prop_add(m, n, "power-control", NULL, 0); + /* tell dom0 where ranted pages go in the linear map */ + val[0] = cpu_foreign_map_order(); + val[1] = max_page; + ofd_prop_add(m, n, "foreign-map", val, sizeof (val)); + n = ofd_node_add(m, n, console, sizeof (console)); if (n > 0) { val[0] = 0; diff -r 067bf06057cc -r 79bb96e0ba73 xen/arch/powerpc/papr/xlate.c --- a/xen/arch/powerpc/papr/xlate.c Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/arch/powerpc/papr/xlate.c Sun Oct 08 11:34:24 2006 -0400 @@ -117,11 +117,8 @@ static void pte_tlbie(union pte volatile } -static void h_enter(struct cpu_user_regs *regs) -{ - ulong flags = regs->gprs[4]; - ulong ptex = regs->gprs[5]; - +long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn) +{ union pte pte; union pte volatile *ppte; struct domain_htab *htab; @@ -141,13 +138,12 @@ static void h_enter(struct cpu_user_regs htab = &d->arch.htab; if (ptex > (1UL << htab->log_num_ptes)) { DBG("%s: bad ptex: 0x%lx\n", __func__, ptex); - regs->gprs[3] = H_Parameter; - return; + return H_Parameter; } /* use local HPTE to avoid manual shifting & masking */ - pte.words.vsid = regs->gprs[6]; - pte.words.rpn = regs->gprs[7]; + pte.words.vsid = vsid; + pte.words.rpn = rpn; if ( pte.bits.l ) { /* large page? */ /* figure out the page size for the selected large page */ @@ -163,8 +159,7 @@ static void h_enter(struct cpu_user_regs if ( lp_size >= d->arch.large_page_sizes ) { DBG("%s: attempt to use unsupported lp_size %d\n", __func__, lp_size); - regs->gprs[3] = H_Parameter; - return; + return H_Parameter; } /* get correct pgshift value */ @@ -180,19 +175,16 @@ static void h_enter(struct cpu_user_regs mfn = pfn2mfn(d, pfn, &mtype); if (mfn == INVALID_MFN) { DBG("%s: Bad PFN: 0x%lx\n", __func__, pfn); - regs->gprs[3] = H_Parameter; - return; - } - + return H_Parameter; + } + + if (mtype == PFN_TYPE_IO &&!test_bit(_DOMF_privileged, &d->domain_flags)) { + /* only a privilaged dom can access outside IO space */ + DBG("%s: unprivileged access to physical page: 0x%lx\n", + __func__, pfn); + return H_Privilege; + } if (mtype == PFN_TYPE_IO) { - /* only a privilaged dom can access outside IO space */ - if ( !d->is_privileged ) { - DBG("%s: unprivileged access to physical page: 0x%lx\n", - __func__, pfn); - regs->gprs[3] = H_Privilege; - return; - } - if ( !((pte.bits.w == 0) && (pte.bits.i == 1) && (pte.bits.g == 1)) ) { @@ -200,9 +192,13 @@ static void h_enter(struct cpu_user_regs "w=%x i=%d m=%d, g=%d\n word 0x%lx\n", __func__, pte.bits.w, pte.bits.i, pte.bits.m, pte.bits.g, pte.words.rpn); - regs->gprs[3] = H_Parameter; - return; - } + return H_Parameter; + } + } + if (mtype == PFN_TYPE_GNTTAB) { + DBG("%s: Dom[%d] mapping grant table: 0x%lx\n", + __func__, d->domain_id, pfn << PAGE_SHIFT); + pte.bits.i = 0; } /* fixup the RPN field of our local PTE copy */ pte.bits.rpn = mfn | lp_bits; @@ -224,14 +220,12 @@ static void h_enter(struct cpu_user_regs if (unlikely(!get_domain(f))) { DBG("%s: Rescinded, no domain: 0x%lx\n", __func__, pfn); - regs->gprs[3] = H_Rescinded; - return; + return H_Rescinded; } if (unlikely(!get_page(pg, f))) { put_domain(f); DBG("%s: Rescinded, no page: 0x%lx\n", __func__, pfn); - regs->gprs[3] = H_Rescinded; - return; + return H_Rescinded; } } @@ -288,10 +282,7 @@ static void h_enter(struct cpu_user_regs : "b" (ppte), "r" (pte.words.rpn), "r" (pte.words.vsid) : "memory"); - regs->gprs[3] = H_Success; - regs->gprs[4] = idx; - - return; + return idx; } } @@ -304,7 +295,24 @@ static void h_enter(struct cpu_user_regs if (f != NULL) put_domain(f); - regs->gprs[3] = H_PTEG_Full; + return H_PTEG_Full; +} + +static void h_enter(struct cpu_user_regs *regs) +{ + ulong flags = regs->gprs[4]; + ulong ptex = regs->gprs[5]; + ulong vsid = regs->gprs[6]; + ulong rpn = regs->gprs[7]; + long ret; + + ret = pte_enter(flags, ptex, vsid, rpn); + + if (ret >= 0) { + regs->gprs[3] = H_Success; + regs->gprs[4] = ret; + } else + regs->gprs[3] = ret; } static void h_protect(struct cpu_user_regs *regs) @@ -332,7 +340,7 @@ static void h_protect(struct cpu_user_re /* the AVPN param occupies the bit-space of the word */ if ( (flags & H_AVPN) && lpte.bits.avpn != avpn >> 7 ) { - DBG("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__, + DBG_LOW("%s: %p: AVPN check failed: 0x%lx, 0x%lx\n", __func__, ppte, lpte.words.vsid, lpte.words.rpn); regs->gprs[3] = H_Not_Found; return; @@ -469,11 +477,8 @@ static void h_clear_mod(struct cpu_user_ } } -static void h_remove(struct cpu_user_regs *regs) -{ - ulong flags = regs->gprs[4]; - ulong ptex = regs->gprs[5]; - ulong avpn = regs->gprs[6]; +long pte_remove(ulong flags, ulong ptex, ulong avpn, ulong *hi, ulong *lo) +{ struct vcpu *v = get_current(); struct domain *d = v->domain; struct domain_htab *htab = &d->arch.htab; @@ -485,29 +490,25 @@ static void h_remove(struct cpu_user_reg if ( ptex > (1UL << htab->log_num_ptes) ) { DBG("%s: bad ptex: 0x%lx\n", __func__, ptex); - regs->gprs[3] = H_Parameter; - return; + return H_Parameter; } pte = &htab->map[ptex]; lpte.words.vsid = pte->words.vsid; lpte.words.rpn = pte->words.rpn; if ((flags & H_AVPN) && lpte.bits.avpn != (avpn >> 7)) { - DBG("%s: avpn doesn not match\n", __func__); - regs->gprs[3] = H_Not_Found; - return; + DBG_LOW("%s: AVPN does not match\n", __func__); + return H_Not_Found; } if ((flags & H_ANDCOND) && ((avpn & pte->words.vsid) != 0)) { DBG("%s: andcond does not match\n", __func__); - regs->gprs[3] = H_Not_Found; - return; - } - - regs->gprs[3] = H_Success; + return H_Not_Found; + } + /* return old PTE in regs 4 and 5 */ - regs->gprs[4] = lpte.words.vsid; - regs->gprs[5] = lpte.words.rpn; + *hi = lpte.words.vsid; + *lo = lpte.words.rpn; #ifdef DEBUG_LOW /* XXX - I'm very skeptical of doing ANYTHING if not bits.v */ @@ -522,7 +523,7 @@ static void h_remove(struct cpu_user_reg if (!cpu_io_mfn(mfn)) { struct page_info *pg = mfn_to_page(mfn); struct domain *f = page_get_owner(pg); - + if (f != d) { put_domain(f); put_page(pg); @@ -536,6 +537,27 @@ static void h_remove(struct cpu_user_reg : "memory"); pte_tlbie(&lpte, ptex); + + return H_Success; +} + +static void h_remove(struct cpu_user_regs *regs) +{ + ulong flags = regs->gprs[4]; + ulong ptex = regs->gprs[5]; + ulong avpn = regs->gprs[6]; + ulong hi, lo; + long ret; + + ret = pte_remove(flags, ptex, avpn, &hi, &lo); + + regs->gprs[3] = ret; + + if (ret == H_Success) { + regs->gprs[4] = hi; + regs->gprs[5] = lo; + } + return; } static void h_read(struct cpu_user_regs *regs) diff -r 067bf06057cc -r 79bb96e0ba73 xen/include/asm-powerpc/grant_table.h --- a/xen/include/asm-powerpc/grant_table.h Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/include/asm-powerpc/grant_table.h Sun Oct 08 11:34:24 2006 -0400 @@ -29,6 +29,10 @@ * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and * must hold a reference to the page. */ +extern long pte_enter(ulong flags, ulong ptex, ulong vsid, ulong rpn); +extern long pte_remove(ulong flags, ulong ptex, ulong avpn, + ulong *hi, ulong *lo); + int create_grant_host_mapping( unsigned long addr, unsigned long frame, unsigned int flags); int destroy_grant_host_mapping( @@ -41,8 +45,7 @@ int destroy_grant_host_mapping( (d), XENSHARE_writable); \ } while ( 0 ) -#define gnttab_shared_mfn(d, t, i) \ - ((virt_to_maddr((t)->shared) >> PAGE_SHIFT) + (i)) +#define gnttab_shared_mfn(d, t, i) (((ulong)((t)->shared) >> PAGE_SHIFT) + (i)) #define gnttab_shared_gmfn(d, t, i) \ (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i))) @@ -61,4 +64,13 @@ static inline void gnttab_clear_flag(uns clear_bit(lnr, laddr); } +static inline uint cpu_foreign_map_order(void) +{ + /* 16 GiB */ + return 34 - PAGE_SHIFT; +} + +#define GNTTAB_DEV_BUS(f) \ + ((f) | (1UL << (cpu_foreign_map_order() + PAGE_SHIFT))) + #endif /* __ASM_PPC_GRANT_TABLE_H__ */ diff -r 067bf06057cc -r 79bb96e0ba73 xen/include/asm-powerpc/mm.h --- a/xen/include/asm-powerpc/mm.h Sat Oct 07 16:25:46 2006 -0400 +++ b/xen/include/asm-powerpc/mm.h Sun Oct 08 11:34:24 2006 -0400 @@ -13,9 +13,10 @@ * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Copyright (C) IBM Corp. 2005 + * Copyright (C) IBM Corp. 2005, 2006 * * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> + * Jimi Xenidis <jimix@xxxxxxxxxxxxxx> */ #ifndef _ASM_MM_H_ @@ -90,35 +91,35 @@ struct page_extents { }; /* The following page types are MUTUALLY EXCLUSIVE. */ -#define PGT_none (0<<29) /* no special uses of this page */ -#define PGT_RMA (1<<29) /* This page is an RMA page? */ -#define PGT_writable_page (7<<29) /* has writable mappings of this page? */ -#define PGT_type_mask (7<<29) /* Bits 29-31. */ +#define PGT_none (0UL<<29) /* no special uses of this page */ +#define PGT_RMA (1UL<<29) /* This page is an RMA page? */ +#define PGT_writable_page (7UL<<29) /* has writable mappings of this page? */ +#define PGT_type_mask (7UL<<29) /* Bits 29-31. */ /* Owning guest has pinned this page to its current type? */ #define _PGT_pinned 28 -#define PGT_pinned (1U<<_PGT_pinned) +#define PGT_pinned (1UL<<_PGT_pinned) /* Has this page been validated for use as its current type? */ #define _PGT_validated 27 -#define PGT_validated (1U<<_PGT_validated) +#define PGT_validated (1UL<<_PGT_validated) /* 16-bit count of uses of this frame as its current type. */ -#define PGT_count_mask ((1U<<16)-1) +#define PGT_count_mask ((1UL<<16)-1) /* Cleared when the owning guest 'frees' this page. */ #define _PGC_allocated 31 -#define PGC_allocated (1U<<_PGC_allocated) +#define PGC_allocated (1UL<<_PGC_allocated) /* Set on a *guest* page to mark it out-of-sync with its shadow */ #define _PGC_out_of_sync 30 -#define PGC_out_of_sync (1U<<_PGC_out_of_sync) +#define PGC_out_of_sync (1UL<<_PGC_out_of_sync) /* Set when is using a page as a page table */ #define _PGC_page_table 29 -#define PGC_page_table (1U<<_PGC_page_table) +#define PGC_page_table (1UL<<_PGC_page_table) /* Set when using page for RMA */ #define _PGC_page_RMA 28 -#define PGC_page_RMA (1U<<_PGC_page_RMA) +#define PGC_page_RMA (1UL<<_PGC_page_RMA) /* 29-bit count of references to this frame. */ -#define PGC_count_mask ((1U<<28)-1) +#define PGC_count_mask ((1UL<<28)-1) #define IS_XEN_HEAP_FRAME(_pfn) (page_to_maddr(_pfn) < xenheap_phys_end) @@ -132,6 +133,13 @@ static inline u32 pickle_domptr(struct d #define page_get_owner(_p) (unpickle_domptr((_p)->u.inuse._domain)) #define page_set_owner(_p,_d) ((_p)->u.inuse._domain = pickle_domptr(_d)) + +#define XENSHARE_writable 0 +#define XENSHARE_readonly 1 +extern void share_xen_page_with_guest( + struct page_info *page, struct domain *d, int readonly); +extern void share_xen_page_with_privileged_guests( + struct page_info *page, int readonly); extern struct page_info *frame_table; extern unsigned long max_page; @@ -218,16 +226,18 @@ typedef struct { } vm_assist_info_t; extern vm_assist_info_t vm_assist_info[]; -#define share_xen_page_with_guest(p, d, r) do { } while (0) -#define share_xen_page_with_privileged_guests(p, r) do { } while (0) /* hope that accesses to this will fail spectacularly */ -#define machine_to_phys_mapping ((u32 *)-1UL) - -extern int update_grant_va_mapping(unsigned long va, - unsigned long val, - struct domain *, - struct vcpu *); +#undef machine_to_phys_mapping +#define INVALID_M2P_ENTRY (~0UL) + +/* do nothing, its all calculated */ +#define set_gpfn_from_mfn(mfn, pfn) do { } while (0) +#define get_gpfn_from_mfn(mfn) (mfn) + +extern unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn); + +extern unsigned long paddr_to_maddr(unsigned long paddr); #define INVALID_MFN (~0UL) #define PFN_TYPE_NONE 0 @@ -235,17 +245,9 @@ extern int update_grant_va_mapping(unsig #define PFN_TYPE_LOGICAL 2 #define PFN_TYPE_IO 3 #define PFN_TYPE_FOREIGN 4 +#define PFN_TYPE_GNTTAB 5 extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type); - -/* Arch-specific portion of memory_op hypercall. */ -long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); - -/* XXX implement me? */ -#define set_gpfn_from_mfn(mfn, pfn) do { } while (0) -/* XXX only used for debug print right now... */ -#define get_gpfn_from_mfn(mfn) (mfn) - static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn) { int mtype; @@ -266,14 +268,27 @@ static inline unsigned long gmfn_to_mfn( return mfn; } -#define mfn_to_gmfn(_d, mfn) (mfn) - -extern int allocate_rma(struct domain *d, unsigned int order_pages); -extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages); -extern void free_extents(struct domain *d); - -extern int steal_page(struct domain *d, struct page_info *page, - unsigned int memflags); +extern int update_grant_va_mapping(unsigned long va, + unsigned long val, + struct domain *, + struct vcpu *); + +#define INVALID_MFN (~0UL) +#define PFN_TYPE_NONE 0 +#define PFN_TYPE_RMA 1 +#define PFN_TYPE_LOGICAL 2 +#define PFN_TYPE_IO 3 +#define PFN_TYPE_FOREIGN 4 + +extern ulong pfn2mfn(struct domain *d, ulong pfn, int *type); + +/* Arch-specific portion of memory_op hypercall. */ +long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); + +/* XXX implement me? */ +#define set_gpfn_from_mfn(mfn, pfn) do { } while (0) +/* XXX only used for debug print right now... */ +#define get_gpfn_from_mfn(mfn) (mfn) static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn) { @@ -297,4 +312,33 @@ static inline unsigned long gmfn_to_mfn( #define mfn_to_gmfn(_d, mfn) (mfn) +extern int allocate_rma(struct domain *d, unsigned int order_pages); +extern uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages); +extern void free_extents(struct domain *d); + +extern int steal_page(struct domain *d, struct page_info *page, + unsigned int memflags); + +static inline unsigned long gmfn_to_mfn(struct domain *d, unsigned long gmfn) +{ + int mtype; + ulong mfn; + + mfn = pfn2mfn(d, gmfn, &mtype); + if (mfn != INVALID_MFN) { + switch (mtype) { + case PFN_TYPE_RMA: + case PFN_TYPE_LOGICAL: + break; + default: + WARN(); + mfn = INVALID_MFN; + break; + } + } + return mfn; +} + +#define mfn_to_gmfn(_d, mfn) (mfn) + #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |