[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xen: Allow granting of foreign access to iomem pages, and with
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1195579608 0 # Node ID 2e5d922b7ee3d80b513c641b6e7a50aae7d1a058 # Parent f62e6c697eeb68a7a62f4beb87e85a68b91b3c6a xen: Allow granting of foreign access to iomem pages, and with arbitrary cache attributes. Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxxxxx> --- xen/arch/ia64/xen/mm.c | 12 ++- xen/arch/powerpc/mm.c | 7 +- xen/arch/x86/mm.c | 31 ++++----- xen/common/grant_table.c | 108 ++++++++++++++++++++++------------ xen/include/asm-ia64/grant_table.h | 3 xen/include/asm-powerpc/grant_table.h | 4 - xen/include/asm-x86/grant_table.h | 4 - xen/include/public/grant_table.h | 7 ++ 8 files changed, 111 insertions(+), 65 deletions(-) diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/arch/ia64/xen/mm.c Tue Nov 20 17:26:48 2007 +0000 @@ -2144,16 +2144,18 @@ dom0vp_unexpose_foreign_p2m(struct domai // mfn: frame: machine page frame // flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte int -create_grant_host_mapping(unsigned long gpaddr, - unsigned long mfn, unsigned int flags) +create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, + unsigned int flags, unsigned int cache_flags) { struct domain* d = current->domain; struct page_info* page; int ret; - if (flags & (GNTMAP_device_map | - GNTMAP_application_map | GNTMAP_contains_pte)) { - gdprintk(XENLOG_INFO, "%s: flags 0x%x\n", __func__, flags); + if ((flags & (GNTMAP_device_map | + GNTMAP_application_map | GNTMAP_contains_pte)) || + (cache_flags)) { + gdprintk(XENLOG_INFO, "%s: flags 0x%x cache_flags 0x%x\n", + __func__, flags, cache_flags); return GNTST_general_error; } diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/powerpc/mm.c --- a/xen/arch/powerpc/mm.c Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/arch/powerpc/mm.c Tue Nov 20 17:26:48 2007 +0000 @@ -168,7 +168,7 @@ static int destroy_grant_va_mapping( } int create_grant_host_mapping( - unsigned long addr, unsigned long frame, unsigned int flags) + unsigned long addr, unsigned long frame, unsigned int flags, unsigned int cache_flags) { if (flags & GNTMAP_application_map) { printk("%s: GNTMAP_application_map not supported\n", __func__); @@ -177,6 +177,11 @@ int create_grant_host_mapping( } if (flags & GNTMAP_contains_pte) { printk("%s: GNTMAP_contains_pte not supported\n", __func__); + BUG(); + return GNTST_general_error; + } + if (cache_flags) { + printk("%s: cache_flags not supported\n", __func__); BUG(); return GNTST_general_error; } diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/arch/x86/mm.c Tue Nov 20 17:26:48 2007 +0000 @@ -645,11 +645,7 @@ get_page_from_l1e( return 0; } - /* No reference counting for out-of-range I/O pages. */ - if ( !mfn_valid(mfn) ) - return 1; - - d = dom_io; + return 1; } /* Foreign mappings into guests in shadow external mode don't @@ -667,9 +663,8 @@ get_page_from_l1e( mfn, get_gpfn_from_mfn(mfn), l1e_get_intpte(l1e), d->domain_id); } - else if ( (pte_flags_to_cacheattr(l1f) != - ((page->count_info >> PGC_cacheattr_base) & 7)) && - !is_iomem_page(mfn) ) + else if ( pte_flags_to_cacheattr(l1f) != + ((page->count_info >> PGC_cacheattr_base) & 7) ) { uint32_t x, nx, y = page->count_info; uint32_t cacheattr = pte_flags_to_cacheattr(l1f); @@ -848,13 +843,15 @@ get_page_from_l4e( void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) { - unsigned long pfn = l1e_get_pfn(l1e); - struct page_info *page = mfn_to_page(pfn); - struct domain *e; - struct vcpu *v; - - if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !mfn_valid(pfn) ) + unsigned long pfn = l1e_get_pfn(l1e); + struct page_info *page; + struct domain *e; + struct vcpu *v; + + if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || is_iomem_page(pfn) ) return; + + page = mfn_to_page(pfn); e = page_get_owner(page); @@ -2763,8 +2760,8 @@ static int destroy_grant_va_mapping( return replace_grant_va_mapping(addr, frame, l1e_empty(), v); } -int create_grant_host_mapping( - uint64_t addr, unsigned long frame, unsigned int flags) +int create_grant_host_mapping(uint64_t addr, unsigned long frame, + unsigned int flags, unsigned int cache_flags) { l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS); @@ -2772,6 +2769,8 @@ int create_grant_host_mapping( l1e_add_flags(pte,_PAGE_USER); if ( !(flags & GNTMAP_readonly) ) l1e_add_flags(pte,_PAGE_RW); + + l1e_add_flags(pte, cacheattr_to_pte_flags(cache_flags >> 5)); if ( flags & GNTMAP_contains_pte ) return create_grant_pte_mapping(addr, pte, current); diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/common/grant_table.c --- a/xen/common/grant_table.c Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/common/grant_table.c Tue Nov 20 17:26:48 2007 +0000 @@ -198,6 +198,7 @@ __gnttab_map_grant_ref( int handle; unsigned long frame = 0; int rc = GNTST_okay; + unsigned int cache_flags; struct active_grant_entry *act; struct grant_mapping *mt; grant_entry_t *sha; @@ -326,36 +327,58 @@ __gnttab_map_grant_ref( frame = act->frame; + cache_flags = (sha->flags & (GTF_PAT | GTF_PWT | GTF_PCD) ); + spin_unlock(&rd->grant_table->lock); - if ( unlikely(!mfn_valid(frame)) || - unlikely(!((op->flags & GNTMAP_readonly) ? - get_page(mfn_to_page(frame), rd) : - get_page_and_type(mfn_to_page(frame), rd, - PGT_writable_page))) ) - { - if ( !rd->is_dying ) - gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame); - rc = GNTST_general_error; - goto undo_out; - } + if ( is_iomem_page(frame) ) + { + if ( !iomem_access_permitted(rd, frame, frame) ) + { + gdprintk(XENLOG_WARNING, + "Iomem mapping not permitted %lx (domain %d)\n", + frame, rd->domain_id); + rc = GNTST_general_error; + goto undo_out; + } + + rc = create_grant_host_mapping( + op->host_addr, frame, op->flags, cache_flags); + if ( rc != GNTST_okay ) + goto undo_out; + } + else + { + if ( unlikely(!mfn_valid(frame)) || + unlikely(!((op->flags & GNTMAP_readonly) ? + get_page(mfn_to_page(frame), rd) : + get_page_and_type(mfn_to_page(frame), rd, + PGT_writable_page))) ) + { + if ( !rd->is_dying ) + gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", + frame); + rc = GNTST_general_error; + goto undo_out; + } - if ( op->flags & GNTMAP_host_map ) - { - rc = create_grant_host_mapping(op->host_addr, frame, op->flags); - if ( rc != GNTST_okay ) - { - if ( !(op->flags & GNTMAP_readonly) ) - put_page_type(mfn_to_page(frame)); - put_page(mfn_to_page(frame)); - goto undo_out; - } - - if ( op->flags & GNTMAP_device_map ) - { - (void)get_page(mfn_to_page(frame), rd); - if ( !(op->flags & GNTMAP_readonly) ) - get_page_type(mfn_to_page(frame), PGT_writable_page); + if ( op->flags & GNTMAP_host_map ) + { + rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0); + if ( rc != GNTST_okay ) + { + if ( !(op->flags & GNTMAP_readonly) ) + put_page_type(mfn_to_page(frame)); + put_page(mfn_to_page(frame)); + goto undo_out; + } + + if ( op->flags & GNTMAP_device_map ) + { + (void)get_page(mfn_to_page(frame), rd); + if ( !(op->flags & GNTMAP_readonly) ) + get_page_type(mfn_to_page(frame), PGT_writable_page); + } } } @@ -559,10 +582,13 @@ __gnttab_unmap_common_complete(struct gn if ( op->flags & GNTMAP_device_map ) { - if ( op->flags & GNTMAP_readonly ) - put_page(mfn_to_page(op->frame)); - else - put_page_and_type(mfn_to_page(op->frame)); + if ( !is_iomem_page(act->frame) ) + { + if ( op->flags & GNTMAP_readonly ) + put_page(mfn_to_page(op->frame)); + else + put_page_and_type(mfn_to_page(op->frame)); + } } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -576,10 +602,12 @@ __gnttab_unmap_common_complete(struct gn goto unmap_out; } - if ( op->flags & GNTMAP_readonly ) + if ( !is_iomem_page(op->frame) ) + { + if ( !(op->flags & GNTMAP_readonly) ) + put_page_type(mfn_to_page(op->frame)); put_page(mfn_to_page(op->frame)); - else - put_page_and_type(mfn_to_page(op->frame)); + } } if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 ) @@ -1595,14 +1623,16 @@ gnttab_release_mappings( { BUG_ON(!(act->pin & GNTPIN_devr_mask)); act->pin -= GNTPIN_devr_inc; - put_page(mfn_to_page(act->frame)); + if ( !is_iomem_page(act->frame) ) + put_page(mfn_to_page(act->frame)); } if ( map->flags & GNTMAP_host_map ) { BUG_ON(!(act->pin & GNTPIN_hstr_mask)); act->pin -= GNTPIN_hstr_inc; - gnttab_release_put_page(mfn_to_page(act->frame)); + if ( !is_iomem_page(act->frame) ) + gnttab_release_put_page(mfn_to_page(act->frame)); } } else @@ -1611,14 +1641,16 @@ gnttab_release_mappings( { BUG_ON(!(act->pin & GNTPIN_devw_mask)); act->pin -= GNTPIN_devw_inc; - put_page_and_type(mfn_to_page(act->frame)); + if ( !is_iomem_page(act->frame) ) + put_page_and_type(mfn_to_page(act->frame)); } if ( map->flags & GNTMAP_host_map ) { BUG_ON(!(act->pin & GNTPIN_hstw_mask)); act->pin -= GNTPIN_hstw_inc; - gnttab_release_put_page_and_type(mfn_to_page(act->frame)); + if ( !is_iomem_page(act->frame) ) + gnttab_release_put_page_and_type(mfn_to_page(act->frame)); } if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 ) diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-ia64/grant_table.h --- a/xen/include/asm-ia64/grant_table.h Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/include/asm-ia64/grant_table.h Tue Nov 20 17:26:48 2007 +0000 @@ -8,7 +8,8 @@ #define INITIAL_NR_GRANT_FRAMES 1 // for grant map/unmap -int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags); +int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, + unsigned int flags, unsigned int cache_flags); int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned long new_gpaddr, unsigned int flags); // for grant transfer diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-powerpc/grant_table.h --- a/xen/include/asm-powerpc/grant_table.h Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/include/asm-powerpc/grant_table.h Tue Nov 20 17:26:48 2007 +0000 @@ -33,8 +33,8 @@ extern long pte_remove(ulong flags, ulon 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 create_grant_host_mapping(unsigned long addr, unsigned long frame, + unsigned int flags, unsigned int cache_flags); int replace_grant_host_mapping( unsigned long addr, unsigned long frame, unsigned long new_addr, unsigned int flags); diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/asm-x86/grant_table.h --- a/xen/include/asm-x86/grant_table.h Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/include/asm-x86/grant_table.h Tue Nov 20 17:26:48 2007 +0000 @@ -13,8 +13,8 @@ * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and * must hold a reference to the page. */ -int create_grant_host_mapping( - uint64_t addr, unsigned long frame, unsigned int flags); +int create_grant_host_mapping(uint64_t addr, unsigned long frame, + unsigned int flags, unsigned int cache_flags); int replace_grant_host_mapping( uint64_t addr, unsigned long frame, uint64_t new_addr, unsigned int flags); diff -r f62e6c697eeb -r 2e5d922b7ee3 xen/include/public/grant_table.h --- a/xen/include/public/grant_table.h Tue Nov 20 15:34:25 2007 +0000 +++ b/xen/include/public/grant_table.h Tue Nov 20 17:26:48 2007 +0000 @@ -119,6 +119,7 @@ typedef struct grant_entry grant_entry_t * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] + * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST] */ #define _GTF_readonly (2) #define GTF_readonly (1U<<_GTF_readonly) @@ -126,6 +127,12 @@ typedef struct grant_entry grant_entry_t #define GTF_reading (1U<<_GTF_reading) #define _GTF_writing (4) #define GTF_writing (1U<<_GTF_writing) +#define _GTF_PWT (5) +#define GTF_PWT (1U<<_GTF_PWT) +#define _GTF_PCD (6) +#define GTF_PCD (1U<<_GTF_PCD) +#define _GTF_PAT (7) +#define GTF_PAT (1U<<_GTF_PAT) /* * Subflags for GTF_accept_transfer: _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |