direct-io.hg
changeset 4100:bd0c28f54450
bitkeeper revision 1.1236.26.1 (4231b4a20dnya9Kf1nGoYAKIhIcGJw)
Grant tables map operation working.
Grant tables map operation working.
author | cwc22@centipede.cl.cam.ac.uk |
---|---|
date | Fri Mar 11 15:09:22 2005 +0000 (2005-03-11) |
parents | afa2f6b47e70 |
children | 00c3e9ce38eb |
files | xen/arch/x86/domain.c xen/arch/x86/mm.c xen/common/grant_table.c xen/include/asm-x86/mm.h xen/include/xen/grant_table.h |
line diff
1.1 --- a/xen/arch/x86/domain.c Thu Mar 10 16:10:02 2005 +0000 1.2 +++ b/xen/arch/x86/domain.c Fri Mar 11 15:09:22 2005 +0000 1.3 @@ -970,6 +970,10 @@ void domain_relinquish_memory(struct dom 1.4 /* Ensure that noone is running over the dead domain's page tables. */ 1.5 synchronise_pagetables(~0UL); 1.6 1.7 + /* Release device mappings of other domains */ 1.8 + gnttab_release_dev_mappings( d->grant_table ); 1.9 + 1.10 + 1.11 /* Exit shadow mode before deconstructing final guest page table. */ 1.12 shadow_mode_disable(d); 1.13
2.1 --- a/xen/arch/x86/mm.c Thu Mar 10 16:10:02 2005 +0000 2.2 +++ b/xen/arch/x86/mm.c Fri Mar 11 15:09:22 2005 +0000 2.3 @@ -1976,13 +1976,6 @@ int update_grant_va_mapping(unsigned lon 2.4 * . check PTE being installed isn't DISALLOWED 2.5 */ 2.6 2.7 - /* Return value: 2.8 - * -ve : error 2.9 - * 0 : done 2.10 - * GNTUPDVA_prev_ro : done & prior mapping was ro to same frame 2.11 - * GNTUPDVA_prev_rw : done & prior mapping was rw to same frame 2.12 - */ 2.13 - 2.14 int rc = 0; 2.15 l1_pgentry_t *pl1e; 2.16 unsigned long _ol1e; 2.17 @@ -1998,18 +1991,7 @@ int update_grant_va_mapping(unsigned lon 2.18 l1_pgentry_t ol1e = mk_l1_pgentry(_ol1e); 2.19 2.20 if ( update_l1e(pl1e, ol1e, mk_l1_pgentry(_nl1e)) ) 2.21 - { 2.22 - /* overwrote different mfn? */ 2.23 - if (((_ol1e ^ _nl1e) & (PADDR_MASK & PAGE_MASK)) != 0) 2.24 - put_page_from_l1e(ol1e, d); 2.25 - 2.26 - else if (_ol1e & _PAGE_PRESENT) 2.27 - rc = ((_ol1e & _PAGE_RW) ? GNTUPDVA_prev_rw 2.28 - : GNTUPDVA_prev_ro ); 2.29 - /* use return code to avoid nasty grant table 2.30 - * slow path in put_page_from_l1e -- caller 2.31 - * must handle grant ref count instead. */ 2.32 - } 2.33 + put_page_from_l1e(ol1e, d); 2.34 else 2.35 rc = -EINVAL; 2.36 }
3.1 --- a/xen/common/grant_table.c Thu Mar 10 16:10:02 2005 +0000 3.2 +++ b/xen/common/grant_table.c Fri Mar 11 15:09:22 2005 +0000 3.3 @@ -227,6 +227,8 @@ static int 3.4 if ( (act->pin & 0x80808080U) != 0 ) 3.5 PIN_FAIL(ENOSPC, "Risk of counter overflow %08x\n", act->pin); 3.6 3.7 + frame = act->frame; 3.8 + 3.9 if ( !(flags & GNTMAP_readonly) && 3.10 !((sflags = sha->flags) & GTF_writing) ) 3.11 { 3.12 @@ -256,8 +258,6 @@ static int 3.13 sflags = prev_sflags; 3.14 } 3.15 3.16 - frame = act->frame; 3.17 - 3.18 if ( unlikely(!get_page_type(&frame_table[frame], 3.19 PGT_writable_page)) ) 3.20 { 3.21 @@ -275,14 +275,9 @@ static int 3.22 GNTPIN_hstr_inc : GNTPIN_hstw_inc; 3.23 } 3.24 3.25 - ld->grant_table->maptrack[handle].domid = dom; 3.26 - ld->grant_table->maptrack[handle].ref_and_flags = 3.27 - (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK); 3.28 - 3.29 /* At this point: 3.30 * act->pin updated to reflect mapping 3.31 * sha->flags updated to indicate to granting domain mapping done 3.32 - * maptrack points to correct remote domain data 3.33 * frame contains the mfn 3.34 */ 3.35 3.36 @@ -290,12 +285,22 @@ static int 3.37 { 3.38 /* Write update into the pagetable 3.39 */ 3.40 - if ( 0 > (rc = update_grant_va_mapping( host_virt_addr, 3.41 + 3.42 + /* cwc22: TODO: check locking... */ 3.43 + 3.44 + spin_unlock(&rd->grant_table->lock); 3.45 + 3.46 + rc = update_grant_va_mapping( host_virt_addr, 3.47 (frame << PAGE_SHIFT) | _PAGE_PRESENT | 3.48 _PAGE_ACCESSED | 3.49 _PAGE_DIRTY | 3.50 ((flags & GNTMAP_readonly) ? 0 : _PAGE_RW), 3.51 - ld, led )) ) 3.52 + ld, led ); 3.53 + DPRINTK("update_grant_va_mapping : rc %d\n", rc); 3.54 + 3.55 + spin_lock(&rd->grant_table->lock); 3.56 + 3.57 + if ( 0 > rc ) 3.58 { 3.59 /* Abort. */ 3.60 act->pin -= (flags & GNTMAP_readonly) ? 3.61 @@ -306,37 +311,20 @@ static int 3.62 else 3.63 { 3.64 act->pin -= GNTPIN_hstw_inc; 3.65 - if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 ) 3.66 + if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) 3.67 { 3.68 put_page_type(&frame_table[frame]); 3.69 clear_bit(_GTF_writing, &sha->flags); 3.70 } 3.71 - 3.72 - if ( act->pin == 0 ) 3.73 - { 3.74 - put_page(&frame_table[frame]); 3.75 - clear_bit(_GTF_reading, &sha->flags); 3.76 - } 3.77 + } 3.78 + if ( act->pin == 0 ) 3.79 + { 3.80 + put_page(&frame_table[frame]); 3.81 + clear_bit(_GTF_reading, &sha->flags); 3.82 } 3.83 goto fail; 3.84 } 3.85 3.86 - /* Check to see if update overwrote a mapping of the same mfn 3.87 - * - if so, must handle ref count here 3.88 - */ 3.89 - if ( rc == GNTUPDVA_prev_ro ) 3.90 - act->pin -= GNTPIN_hstr_inc; 3.91 - 3.92 - if ( rc == GNTUPDVA_prev_rw ) 3.93 - { 3.94 - act->pin -= GNTPIN_hstw_inc; 3.95 - 3.96 - if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_devw_mask)) == 0 ) 3.97 - { 3.98 - put_page_type(&frame_table[frame]); 3.99 - clear_bit(_GTF_writing, &sha->flags); 3.100 - } 3.101 - } 3.102 rc = 0; 3.103 *va = host_virt_addr; 3.104 3.105 @@ -345,6 +333,12 @@ static int 3.106 */ 3.107 } 3.108 3.109 + /* Only make the maptrack live _after_ writing the pte, in case 3.110 + * we overwrite the same frame number, causing a maptrack walk to find it */ 3.111 + ld->grant_table->maptrack[handle].domid = dom; 3.112 + ld->grant_table->maptrack[handle].ref_and_flags = 3.113 + (ref << MAPTRACK_REF_SHIFT) | (flags & MAPTRACK_GNTMAP_MASK); 3.114 + 3.115 /* Unchecked and unconditional writes to user uop. */ 3.116 if ( flags & GNTMAP_device_map ) 3.117 (void)__put_user(frame, &uop->dev_bus_addr); 3.118 @@ -437,6 +431,8 @@ static int 3.119 act = &rd->grant_table->active[ref]; 3.120 sha = &rd->grant_table->shared[ref]; 3.121 3.122 + // cwc22: TODO: put_maptrack_handle 3.123 + 3.124 spin_lock(&rd->grant_table->lock); 3.125 3.126 if ( frame != 0 ) 3.127 @@ -643,9 +639,9 @@ gnttab_dump_table(gnttab_dump_table_t *u 3.128 if ( act->pin || act->domid || act->frame || 3.129 sha_copy.flags || sha_copy.domid || sha_copy.frame ) 3.130 { 3.131 - DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%u)\n", 3.132 + DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%lx)\n", 3.133 op.dom, i, act->pin, act->domid, act->frame); 3.134 - DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%u)\n", 3.135 + DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n", 3.136 op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame); 3.137 3.138 } 3.139 @@ -729,6 +725,11 @@ gnttab_check_unmap( 3.140 * also traverse this. 3.141 */ 3.142 3.143 + /* Note: if the same frame is mapped multiple times, and then one of 3.144 + * the ptes is overwritten, which maptrack handle gets invalidated? 3.145 + * Advice: don't do it. 3.146 + */ 3.147 + 3.148 unsigned int handle, ref, refcount; 3.149 grant_table_t *lgt, *rgt; 3.150 active_grant_entry_t *act; 3.151 @@ -741,8 +742,6 @@ gnttab_check_unmap( 3.152 if ( lgt->map_count == 0 ) 3.153 return 0; 3.154 3.155 - rgt = rd->grant_table; 3.156 - 3.157 #ifdef GRANT_DEBUG 3.158 if ( ld->id != 0 ) { 3.159 DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n", 3.160 @@ -750,6 +749,14 @@ gnttab_check_unmap( 3.161 } 3.162 #endif 3.163 3.164 + if ( get_domain(rd) == 0 ) 3.165 + { 3.166 + DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->id); 3.167 + return 0; 3.168 + } 3.169 + 3.170 + rgt = rd->grant_table; 3.171 + 3.172 for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ ) 3.173 { 3.174 map = &lgt->maptrack[handle]; 3.175 @@ -792,7 +799,7 @@ gnttab_check_unmap( 3.176 act->pin -= GNTPIN_hstw_inc; 3.177 3.178 /* any more granted writable mappings? */ 3.179 - if ( (act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) == 0 ) 3.180 + if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) 3.181 { 3.182 put_page_type(&frame_table[frame]); 3.183 clear_bit(_GTF_writing, &rgt->shared[ref].flags); 3.184 @@ -815,6 +822,7 @@ gnttab_check_unmap( 3.185 break; 3.186 } 3.187 } 3.188 + put_domain(rd); 3.189 3.190 return found; 3.191 } 3.192 @@ -957,6 +965,79 @@ grant_table_create( 3.193 } 3.194 3.195 void 3.196 +gnttab_release_dev_mappings(grant_table_t *gt) 3.197 +{ 3.198 + grant_mapping_t *map; 3.199 + domid_t dom; 3.200 + grant_ref_t ref; 3.201 + u16 handle; 3.202 + struct domain *ld, *rd; 3.203 + unsigned long frame; 3.204 + active_grant_entry_t *act; 3.205 + grant_entry_t *sha; 3.206 + 3.207 + ld = current->domain; 3.208 + 3.209 + for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ ) 3.210 + { 3.211 + map = >->maptrack[handle]; 3.212 + 3.213 + if ( map->ref_and_flags & GNTMAP_device_map ) 3.214 + { 3.215 + dom = map->domid; 3.216 + ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT; 3.217 + 3.218 + DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n", 3.219 + handle, ref, 3.220 + map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom); 3.221 + 3.222 + if ( unlikely((rd = find_domain_by_id(dom)) == NULL) || 3.223 + unlikely(ld == rd) ) 3.224 + { 3.225 + if ( rd != NULL ) 3.226 + put_domain(rd); 3.227 + 3.228 + printk(KERN_WARNING "Grant release: Could not find domain %d\n", dom); 3.229 + continue; 3.230 + } 3.231 + 3.232 + act = &rd->grant_table->active[ref]; 3.233 + sha = &rd->grant_table->shared[ref]; 3.234 + 3.235 + spin_lock(&rd->grant_table->lock); 3.236 + 3.237 + if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) ) 3.238 + { 3.239 + frame = act->frame; 3.240 + 3.241 + if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) && 3.242 + ( (act->pin & GNTPIN_devw_mask) > 0 ) ) 3.243 + { 3.244 + clear_bit(_GTF_writing, &sha->flags); 3.245 + put_page_type(&frame_table[frame]); 3.246 + } 3.247 + 3.248 + act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask); 3.249 + 3.250 + if ( act->pin == 0 ) 3.251 + { 3.252 + clear_bit(_GTF_reading, &sha->flags); 3.253 + map->ref_and_flags = 0; 3.254 + put_page(&frame_table[frame]); 3.255 + } 3.256 + else 3.257 + map->ref_and_flags &= ~GNTMAP_device_map; 3.258 + } 3.259 + 3.260 + spin_unlock(&rd->grant_table->lock); 3.261 + 3.262 + put_domain(rd); 3.263 + } 3.264 + } 3.265 +} 3.266 + 3.267 + 3.268 +void 3.269 grant_table_destroy( 3.270 struct domain *d) 3.271 {
4.1 --- a/xen/include/asm-x86/mm.h Thu Mar 10 16:10:02 2005 +0000 4.2 +++ b/xen/include/asm-x86/mm.h Fri Mar 11 15:09:22 2005 +0000 4.3 @@ -343,7 +343,4 @@ int update_grant_va_mapping(unsigned lon 4.4 unsigned long val, 4.5 struct domain *d, 4.6 struct exec_domain *ed); 4.7 -#define GNTUPDVA_prev_ro 1 4.8 -#define GNTUPDVA_prev_rw 2 4.9 - 4.10 #endif /* __ASM_X86_MM_H__ */
5.1 --- a/xen/include/xen/grant_table.h Thu Mar 10 16:10:02 2005 +0000 5.2 +++ b/xen/include/xen/grant_table.h Fri Mar 11 15:09:22 2005 +0000 5.3 @@ -106,4 +106,8 @@ void 5.4 gnttab_notify_transfer( 5.5 struct domain *rd, grant_ref_t ref, unsigned long frame); 5.6 5.7 +/* Pre-domain destruction release of granted device mappings of other domains.*/ 5.8 +void 5.9 +gnttab_release_dev_mappings(grant_table_t *gt); 5.10 + 5.11 #endif /* __XEN_GRANT_H__ */