ia64/xen-unstable
changeset 16407:2e5d922b7ee3
xen: Allow granting of foreign access to iomem pages, and with
arbitrary cache attributes.
Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
Signed-off-by: Keir Fraser <keir.fraser@eu.citrix.com>
arbitrary cache attributes.
Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
Signed-off-by: Keir Fraser <keir.fraser@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Nov 20 17:26:48 2007 +0000 (2007-11-20) |
parents | f62e6c697eeb |
children | 9a9ddc04eea2 00fec8212ae6 |
files | xen/arch/ia64/xen/mm.c xen/arch/powerpc/mm.c xen/arch/x86/mm.c xen/common/grant_table.c xen/include/asm-ia64/grant_table.h xen/include/asm-powerpc/grant_table.h xen/include/asm-x86/grant_table.h xen/include/public/grant_table.h |
line diff
1.1 --- a/xen/arch/ia64/xen/mm.c Tue Nov 20 15:34:25 2007 +0000 1.2 +++ b/xen/arch/ia64/xen/mm.c Tue Nov 20 17:26:48 2007 +0000 1.3 @@ -2144,16 +2144,18 @@ dom0vp_unexpose_foreign_p2m(struct domai 1.4 // mfn: frame: machine page frame 1.5 // flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte 1.6 int 1.7 -create_grant_host_mapping(unsigned long gpaddr, 1.8 - unsigned long mfn, unsigned int flags) 1.9 +create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 1.10 + unsigned int flags, unsigned int cache_flags) 1.11 { 1.12 struct domain* d = current->domain; 1.13 struct page_info* page; 1.14 int ret; 1.15 1.16 - if (flags & (GNTMAP_device_map | 1.17 - GNTMAP_application_map | GNTMAP_contains_pte)) { 1.18 - gdprintk(XENLOG_INFO, "%s: flags 0x%x\n", __func__, flags); 1.19 + if ((flags & (GNTMAP_device_map | 1.20 + GNTMAP_application_map | GNTMAP_contains_pte)) || 1.21 + (cache_flags)) { 1.22 + gdprintk(XENLOG_INFO, "%s: flags 0x%x cache_flags 0x%x\n", 1.23 + __func__, flags, cache_flags); 1.24 return GNTST_general_error; 1.25 } 1.26
2.1 --- a/xen/arch/powerpc/mm.c Tue Nov 20 15:34:25 2007 +0000 2.2 +++ b/xen/arch/powerpc/mm.c Tue Nov 20 17:26:48 2007 +0000 2.3 @@ -168,7 +168,7 @@ static int destroy_grant_va_mapping( 2.4 } 2.5 2.6 int create_grant_host_mapping( 2.7 - unsigned long addr, unsigned long frame, unsigned int flags) 2.8 + unsigned long addr, unsigned long frame, unsigned int flags, unsigned int cache_flags) 2.9 { 2.10 if (flags & GNTMAP_application_map) { 2.11 printk("%s: GNTMAP_application_map not supported\n", __func__); 2.12 @@ -180,6 +180,11 @@ int create_grant_host_mapping( 2.13 BUG(); 2.14 return GNTST_general_error; 2.15 } 2.16 + if (cache_flags) { 2.17 + printk("%s: cache_flags not supported\n", __func__); 2.18 + BUG(); 2.19 + return GNTST_general_error; 2.20 + } 2.21 return create_grant_va_mapping(addr, frame, current); 2.22 } 2.23
3.1 --- a/xen/arch/x86/mm.c Tue Nov 20 15:34:25 2007 +0000 3.2 +++ b/xen/arch/x86/mm.c Tue Nov 20 17:26:48 2007 +0000 3.3 @@ -645,11 +645,7 @@ get_page_from_l1e( 3.4 return 0; 3.5 } 3.6 3.7 - /* No reference counting for out-of-range I/O pages. */ 3.8 - if ( !mfn_valid(mfn) ) 3.9 - return 1; 3.10 - 3.11 - d = dom_io; 3.12 + return 1; 3.13 } 3.14 3.15 /* Foreign mappings into guests in shadow external mode don't 3.16 @@ -667,9 +663,8 @@ get_page_from_l1e( 3.17 mfn, get_gpfn_from_mfn(mfn), 3.18 l1e_get_intpte(l1e), d->domain_id); 3.19 } 3.20 - else if ( (pte_flags_to_cacheattr(l1f) != 3.21 - ((page->count_info >> PGC_cacheattr_base) & 7)) && 3.22 - !is_iomem_page(mfn) ) 3.23 + else if ( pte_flags_to_cacheattr(l1f) != 3.24 + ((page->count_info >> PGC_cacheattr_base) & 7) ) 3.25 { 3.26 uint32_t x, nx, y = page->count_info; 3.27 uint32_t cacheattr = pte_flags_to_cacheattr(l1f); 3.28 @@ -848,14 +843,16 @@ get_page_from_l4e( 3.29 3.30 void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) 3.31 { 3.32 - unsigned long pfn = l1e_get_pfn(l1e); 3.33 - struct page_info *page = mfn_to_page(pfn); 3.34 - struct domain *e; 3.35 - struct vcpu *v; 3.36 - 3.37 - if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !mfn_valid(pfn) ) 3.38 + unsigned long pfn = l1e_get_pfn(l1e); 3.39 + struct page_info *page; 3.40 + struct domain *e; 3.41 + struct vcpu *v; 3.42 + 3.43 + if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || is_iomem_page(pfn) ) 3.44 return; 3.45 3.46 + page = mfn_to_page(pfn); 3.47 + 3.48 e = page_get_owner(page); 3.49 3.50 /* 3.51 @@ -2763,8 +2760,8 @@ static int destroy_grant_va_mapping( 3.52 return replace_grant_va_mapping(addr, frame, l1e_empty(), v); 3.53 } 3.54 3.55 -int create_grant_host_mapping( 3.56 - uint64_t addr, unsigned long frame, unsigned int flags) 3.57 +int create_grant_host_mapping(uint64_t addr, unsigned long frame, 3.58 + unsigned int flags, unsigned int cache_flags) 3.59 { 3.60 l1_pgentry_t pte = l1e_from_pfn(frame, GRANT_PTE_FLAGS); 3.61 3.62 @@ -2773,6 +2770,8 @@ int create_grant_host_mapping( 3.63 if ( !(flags & GNTMAP_readonly) ) 3.64 l1e_add_flags(pte,_PAGE_RW); 3.65 3.66 + l1e_add_flags(pte, cacheattr_to_pte_flags(cache_flags >> 5)); 3.67 + 3.68 if ( flags & GNTMAP_contains_pte ) 3.69 return create_grant_pte_mapping(addr, pte, current); 3.70 return create_grant_va_mapping(addr, pte, current);
4.1 --- a/xen/common/grant_table.c Tue Nov 20 15:34:25 2007 +0000 4.2 +++ b/xen/common/grant_table.c Tue Nov 20 17:26:48 2007 +0000 4.3 @@ -198,6 +198,7 @@ static void 4.4 int handle; 4.5 unsigned long frame = 0; 4.6 int rc = GNTST_okay; 4.7 + unsigned int cache_flags; 4.8 struct active_grant_entry *act; 4.9 struct grant_mapping *mt; 4.10 grant_entry_t *sha; 4.11 @@ -326,36 +327,58 @@ static void 4.12 4.13 frame = act->frame; 4.14 4.15 + cache_flags = (sha->flags & (GTF_PAT | GTF_PWT | GTF_PCD) ); 4.16 + 4.17 spin_unlock(&rd->grant_table->lock); 4.18 4.19 - if ( unlikely(!mfn_valid(frame)) || 4.20 - unlikely(!((op->flags & GNTMAP_readonly) ? 4.21 - get_page(mfn_to_page(frame), rd) : 4.22 - get_page_and_type(mfn_to_page(frame), rd, 4.23 - PGT_writable_page))) ) 4.24 + if ( is_iomem_page(frame) ) 4.25 { 4.26 - if ( !rd->is_dying ) 4.27 - gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame); 4.28 - rc = GNTST_general_error; 4.29 - goto undo_out; 4.30 - } 4.31 - 4.32 - if ( op->flags & GNTMAP_host_map ) 4.33 - { 4.34 - rc = create_grant_host_mapping(op->host_addr, frame, op->flags); 4.35 - if ( rc != GNTST_okay ) 4.36 + if ( !iomem_access_permitted(rd, frame, frame) ) 4.37 { 4.38 - if ( !(op->flags & GNTMAP_readonly) ) 4.39 - put_page_type(mfn_to_page(frame)); 4.40 - put_page(mfn_to_page(frame)); 4.41 + gdprintk(XENLOG_WARNING, 4.42 + "Iomem mapping not permitted %lx (domain %d)\n", 4.43 + frame, rd->domain_id); 4.44 + rc = GNTST_general_error; 4.45 goto undo_out; 4.46 } 4.47 4.48 - if ( op->flags & GNTMAP_device_map ) 4.49 + rc = create_grant_host_mapping( 4.50 + op->host_addr, frame, op->flags, cache_flags); 4.51 + if ( rc != GNTST_okay ) 4.52 + goto undo_out; 4.53 + } 4.54 + else 4.55 + { 4.56 + if ( unlikely(!mfn_valid(frame)) || 4.57 + unlikely(!((op->flags & GNTMAP_readonly) ? 4.58 + get_page(mfn_to_page(frame), rd) : 4.59 + get_page_and_type(mfn_to_page(frame), rd, 4.60 + PGT_writable_page))) ) 4.61 { 4.62 - (void)get_page(mfn_to_page(frame), rd); 4.63 - if ( !(op->flags & GNTMAP_readonly) ) 4.64 - get_page_type(mfn_to_page(frame), PGT_writable_page); 4.65 + if ( !rd->is_dying ) 4.66 + gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", 4.67 + frame); 4.68 + rc = GNTST_general_error; 4.69 + goto undo_out; 4.70 + } 4.71 + 4.72 + if ( op->flags & GNTMAP_host_map ) 4.73 + { 4.74 + rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0); 4.75 + if ( rc != GNTST_okay ) 4.76 + { 4.77 + if ( !(op->flags & GNTMAP_readonly) ) 4.78 + put_page_type(mfn_to_page(frame)); 4.79 + put_page(mfn_to_page(frame)); 4.80 + goto undo_out; 4.81 + } 4.82 + 4.83 + if ( op->flags & GNTMAP_device_map ) 4.84 + { 4.85 + (void)get_page(mfn_to_page(frame), rd); 4.86 + if ( !(op->flags & GNTMAP_readonly) ) 4.87 + get_page_type(mfn_to_page(frame), PGT_writable_page); 4.88 + } 4.89 } 4.90 } 4.91 4.92 @@ -559,10 +582,13 @@ static void 4.93 4.94 if ( op->flags & GNTMAP_device_map ) 4.95 { 4.96 - if ( op->flags & GNTMAP_readonly ) 4.97 - put_page(mfn_to_page(op->frame)); 4.98 - else 4.99 - put_page_and_type(mfn_to_page(op->frame)); 4.100 + if ( !is_iomem_page(act->frame) ) 4.101 + { 4.102 + if ( op->flags & GNTMAP_readonly ) 4.103 + put_page(mfn_to_page(op->frame)); 4.104 + else 4.105 + put_page_and_type(mfn_to_page(op->frame)); 4.106 + } 4.107 } 4.108 4.109 if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) 4.110 @@ -576,10 +602,12 @@ static void 4.111 goto unmap_out; 4.112 } 4.113 4.114 - if ( op->flags & GNTMAP_readonly ) 4.115 + if ( !is_iomem_page(op->frame) ) 4.116 + { 4.117 + if ( !(op->flags & GNTMAP_readonly) ) 4.118 + put_page_type(mfn_to_page(op->frame)); 4.119 put_page(mfn_to_page(op->frame)); 4.120 - else 4.121 - put_page_and_type(mfn_to_page(op->frame)); 4.122 + } 4.123 } 4.124 4.125 if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 ) 4.126 @@ -1595,14 +1623,16 @@ gnttab_release_mappings( 4.127 { 4.128 BUG_ON(!(act->pin & GNTPIN_devr_mask)); 4.129 act->pin -= GNTPIN_devr_inc; 4.130 - put_page(mfn_to_page(act->frame)); 4.131 + if ( !is_iomem_page(act->frame) ) 4.132 + put_page(mfn_to_page(act->frame)); 4.133 } 4.134 4.135 if ( map->flags & GNTMAP_host_map ) 4.136 { 4.137 BUG_ON(!(act->pin & GNTPIN_hstr_mask)); 4.138 act->pin -= GNTPIN_hstr_inc; 4.139 - gnttab_release_put_page(mfn_to_page(act->frame)); 4.140 + if ( !is_iomem_page(act->frame) ) 4.141 + gnttab_release_put_page(mfn_to_page(act->frame)); 4.142 } 4.143 } 4.144 else 4.145 @@ -1611,14 +1641,16 @@ gnttab_release_mappings( 4.146 { 4.147 BUG_ON(!(act->pin & GNTPIN_devw_mask)); 4.148 act->pin -= GNTPIN_devw_inc; 4.149 - put_page_and_type(mfn_to_page(act->frame)); 4.150 + if ( !is_iomem_page(act->frame) ) 4.151 + put_page_and_type(mfn_to_page(act->frame)); 4.152 } 4.153 4.154 if ( map->flags & GNTMAP_host_map ) 4.155 { 4.156 BUG_ON(!(act->pin & GNTPIN_hstw_mask)); 4.157 act->pin -= GNTPIN_hstw_inc; 4.158 - gnttab_release_put_page_and_type(mfn_to_page(act->frame)); 4.159 + if ( !is_iomem_page(act->frame) ) 4.160 + gnttab_release_put_page_and_type(mfn_to_page(act->frame)); 4.161 } 4.162 4.163 if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
5.1 --- a/xen/include/asm-ia64/grant_table.h Tue Nov 20 15:34:25 2007 +0000 5.2 +++ b/xen/include/asm-ia64/grant_table.h Tue Nov 20 17:26:48 2007 +0000 5.3 @@ -8,7 +8,8 @@ 5.4 #define INITIAL_NR_GRANT_FRAMES 1 5.5 5.6 // for grant map/unmap 5.7 -int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags); 5.8 +int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, 5.9 + unsigned int flags, unsigned int cache_flags); 5.10 int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned long new_gpaddr, unsigned int flags); 5.11 5.12 // for grant transfer
6.1 --- a/xen/include/asm-powerpc/grant_table.h Tue Nov 20 15:34:25 2007 +0000 6.2 +++ b/xen/include/asm-powerpc/grant_table.h Tue Nov 20 17:26:48 2007 +0000 6.3 @@ -33,8 +33,8 @@ extern long pte_enter(ulong flags, ulong 6.4 extern long pte_remove(ulong flags, ulong ptex, ulong avpn, 6.5 ulong *hi, ulong *lo); 6.6 6.7 -int create_grant_host_mapping( 6.8 - unsigned long addr, unsigned long frame, unsigned int flags); 6.9 +int create_grant_host_mapping(unsigned long addr, unsigned long frame, 6.10 + unsigned int flags, unsigned int cache_flags); 6.11 int replace_grant_host_mapping( 6.12 unsigned long addr, unsigned long frame, unsigned long new_addr, 6.13 unsigned int flags);
7.1 --- a/xen/include/asm-x86/grant_table.h Tue Nov 20 15:34:25 2007 +0000 7.2 +++ b/xen/include/asm-x86/grant_table.h Tue Nov 20 17:26:48 2007 +0000 7.3 @@ -13,8 +13,8 @@ 7.4 * Caller must own caller's BIGLOCK, is responsible for flushing the TLB, and 7.5 * must hold a reference to the page. 7.6 */ 7.7 -int create_grant_host_mapping( 7.8 - uint64_t addr, unsigned long frame, unsigned int flags); 7.9 +int create_grant_host_mapping(uint64_t addr, unsigned long frame, 7.10 + unsigned int flags, unsigned int cache_flags); 7.11 int replace_grant_host_mapping( 7.12 uint64_t addr, unsigned long frame, uint64_t new_addr, unsigned int flags); 7.13
8.1 --- a/xen/include/public/grant_table.h Tue Nov 20 15:34:25 2007 +0000 8.2 +++ b/xen/include/public/grant_table.h Tue Nov 20 17:26:48 2007 +0000 8.3 @@ -119,6 +119,7 @@ typedef struct grant_entry grant_entry_t 8.4 * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] 8.5 * GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN] 8.6 * GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN] 8.7 + * GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST] 8.8 */ 8.9 #define _GTF_readonly (2) 8.10 #define GTF_readonly (1U<<_GTF_readonly) 8.11 @@ -126,6 +127,12 @@ typedef struct grant_entry grant_entry_t 8.12 #define GTF_reading (1U<<_GTF_reading) 8.13 #define _GTF_writing (4) 8.14 #define GTF_writing (1U<<_GTF_writing) 8.15 +#define _GTF_PWT (5) 8.16 +#define GTF_PWT (1U<<_GTF_PWT) 8.17 +#define _GTF_PCD (6) 8.18 +#define GTF_PCD (1U<<_GTF_PCD) 8.19 +#define _GTF_PAT (7) 8.20 +#define GTF_PAT (1U<<_GTF_PAT) 8.21 8.22 /* 8.23 * Subflags for GTF_accept_transfer: