Changeset 623 for trunk/kernel/mm/vmm.c
- Timestamp:
- Mar 6, 2019, 4:37:15 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/vmm.c
r621 r623 59 59 { 60 60 error_t error; 61 vseg_t * vseg_kentry;62 61 vseg_t * vseg_args; 63 62 vseg_t * vseg_envs; … … 91 90 (CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE)) , 92 91 "STACK zone too small\n"); 93 94 // register kentry vseg in VSL95 base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;96 size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;97 98 vseg_kentry = vmm_create_vseg( process,99 VSEG_TYPE_CODE,100 base,101 size,102 0, // file_offset unused103 0, // file_size unused104 XPTR_NULL, // mapper_xp unused105 local_cxy );106 107 if( vseg_kentry == NULL )108 {109 printk("\n[ERROR] in %s : cannot register kentry vseg\n", __FUNCTION__ );110 return -1;111 }112 113 vmm->kent_vpn_base = base;114 92 115 93 // register args vseg in VSL … … 162 140 163 141 if( error ) 164 printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ ); 142 { 143 printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ ); 144 return -1; 145 } 165 146 166 147 // initialize GPT lock 167 148 remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT ); 168 149 169 // architecture specic GPT initialisation 170 // (For TSAR, identity map the kentry_vseg) 171 error = hal_vmm_init( vmm ); 172 173 if( error ) 174 printk("\n[ERROR] in %s : cannot initialize GPT\n", __FUNCTION__ ); 150 // update process VMM with kernel vsegs 151 error = hal_vmm_kernel_update( process ); 152 153 if( error ) 154 { 155 printk("\n[ERROR] in %s : cannot update GPT for kernel vsegs\n", __FUNCTION__ ); 156 return -1; 157 } 175 158 176 159 // initialize STACK allocator … … 326 309 } 327 310 328 // release physical memory allocated for vseg descriptor if no MMAP type 329 if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) ) 311 // release physical memory allocated for vseg if no MMAP and no kernel type 312 if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) && 313 (type != VSEG_TYPE_KCODE) && (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) ) 330 314 { 331 315 vseg_free( vseg ); … … 606 590 child_vmm->vsegs_nr = 0; 607 591 608 // create child GPT592 // create the child GPT 609 593 error = hal_gpt_create( &child_vmm->gpt ); 610 594 … … 639 623 #endif 640 624 641 // all parent vsegs - but STACK - must be copied in child VSL 642 if( type != VSEG_TYPE_STACK ) 625 // all parent vsegs - but STACK and kernel vsegs - must be copied in child VSL 626 if( (type != VSEG_TYPE_STACK) && (type != VSEG_TYPE_KCODE) && 627 (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) ) 643 628 { 644 629 // allocate memory for a new child vseg … … 726 711 remote_rwlock_rd_release( parent_lock_xp ); 727 712 728 // initialize child GPT (architecture specic) 729 // => For TSAR, identity map the kentry_vseg 730 error = hal_vmm_init( child_vmm ); 713 // update child VMM with kernel vsegs 714 error = hal_vmm_kernel_update( child_process ); 731 715 732 716 if( error ) 733 717 { 734 printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );718 printk("\n[ERROR] in %s : cannot update child VMM\n", __FUNCTION__ ); 735 719 return -1; 736 720 } … … 1098 1082 base = vpn_base << CONFIG_PPM_PAGE_SHIFT; 1099 1083 } 1100 else // VSEG_TYPE_DATA or VSEG_TYPE_CODE1084 else // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg 1101 1085 { 1102 1086 uint32_t vpn_min = base >> CONFIG_PPM_PAGE_SHIFT; … … 1178 1162 xptr_t lock_xp; // extended pointer on lock protecting forks counter 1179 1163 uint32_t forks; // actual number of pendinf forks 1164 uint32_t type; // vseg type 1180 1165 1181 1166 #if DEBUG_VMM_DELETE_VSEG … … 1190 1175 process = cluster_get_local_process_from_pid( pid ); 1191 1176 1192 if( process == NULL ) return; 1177 if( process == NULL ) 1178 { 1179 printk("\n[ERRORR] in %s : cannot get local process descriptor\n", 1180 __FUNCTION__ ); 1181 return; 1182 } 1193 1183 1194 1184 // get pointers on local process VMM an GPT … … 1199 1189 vseg = vmm_vseg_from_vaddr( vmm , vaddr ); 1200 1190 1201 if( vseg == NULL ) return; 1202 1203 // loop to invalidate all vseg PTEs in GPT 1191 if( vseg == NULL ) 1192 { 1193 printk("\n[ERRORR] in %s : cannot get vseg descriptor\n", 1194 __FUNCTION__ ); 1195 return; 1196 } 1197 1198 // get relevant vseg infos 1199 type = vseg->type; 1204 1200 vpn_min = vseg->vpn_base; 1205 1201 vpn_max = vpn_min + vseg->vpn_size; 1202 1203 // loop to invalidate all vseg PTEs in GPT 1206 1204 for( vpn = vpn_min ; vpn < vpn_max ; vpn++ ) 1207 1205 { … … 1216 1214 printk("- unmap vpn %x / ppn %x / vseg %s \n" , vpn , ppn, vseg_type_str(vseg->type) ); 1217 1215 #endif 1218 1219 // check small page1220 assert( (attr & GPT_SMALL) , "an user vseg must use small pages" );1221 1222 1216 // unmap GPT entry in local GPT 1223 1217 hal_gpt_reset_pte( gpt , vpn ); 1224 1218 1225 // handle pending forks counter if 1226 // 1) not identity mapped 1227 // 2) reference cluster 1228 if( ((vseg->flags & VSEG_IDENT) == 0) && 1229 (GET_CXY( process->ref_xp ) == local_cxy) ) 1219 // the allocated page is not released to KMEM for kernel vseg 1220 if( (type != VSEG_TYPE_KCODE) && 1221 (type != VSEG_TYPE_KDATA) && 1222 (type != VSEG_TYPE_KDEV ) ) 1230 1223 { 1224 1225 // FIXME This code must be completely re-written, as the actual release must depend on 1226 // - the vseg type 1227 // - the reference cluster 1228 // - the page refcount and/or the forks counter 1229 1231 1230 // get extended pointer on physical page descriptor 1232 1231 page_xp = ppm_ppn2page( ppn ); … … 1238 1237 lock_xp = XPTR( page_cxy , &page_ptr->lock ); 1239 1238 1239 // get the lock protecting the page 1240 1240 remote_busylock_acquire( lock_xp ); 1241 1241 1242 // get pending forks counter 1242 1243 forks = hal_remote_l32( forks_xp ); 1244 1243 1245 if( forks ) // decrement pending forks counter 1244 1246 { … … 1263 1265 #endif 1264 1266 } 1267 1268 // release the lock protecting the page 1265 1269 remote_busylock_release( lock_xp ); 1266 1270 } … … 1311 1315 // return failure 1312 1316 remote_rwlock_rd_release( lock_xp ); 1317 1313 1318 return NULL; 1314 1319 … … 1325 1330 vpn_t vpn_max; 1326 1331 1332 #if DEBUG_VMM_RESIZE_VSEG 1333 uint32_t cycle = (uint32_t)hal_get_cycles(); 1334 thread_t * this = CURRENT_THREAD; 1335 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1336 printk("\n[%s] thread[%x,%x] enter / process %x / base %x / size %d / cycle %d\n", 1337 __FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle ); 1338 #endif 1339 1327 1340 // get pointer on process VMM 1328 1341 vmm_t * vmm = &process->vmm; … … 1334 1347 vseg_t * vseg = vmm_vseg_from_vaddr( vmm , base ); 1335 1348 1336 if( vseg == NULL) return EINVAL;1337 1338 // get extended pointer on VSL lock1339 xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock);1340 1341 // get lock protecting VSL1342 remote_rwlock_wr_acquire( lock_xp ); 1343 1349 if( vseg == NULL) 1350 { 1351 printk("\n[ERROR] in %s : vseg(%x,%d) not found\n", 1352 __FUNCTION__, base , size ); 1353 return -1; 1354 } 1355 1356 // resize depends on unmapped region base and size 1344 1357 if( (vseg->min > addr_min) || (vseg->max < addr_max) ) // not included in vseg 1345 1358 { 1359 printk("\n[ERROR] in %s : unmapped region[%x->%x[ not included in vseg[%x->%x[\n", 1360 __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max ); 1361 1346 1362 error = -1; 1347 1363 } 1348 1364 else if( (vseg->min == addr_min) && (vseg->max == addr_max) ) // vseg must be deleted 1349 1365 { 1366 1367 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1368 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1369 printk("\n[%s] unmapped region[%x->%x[ equal vseg[%x->%x[\n", 1370 __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max ); 1371 #endif 1350 1372 vmm_delete_vseg( process->pid , vseg->min ); 1373 1374 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1375 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1376 printk("\n[%s] thread[%x,%x] deleted vseg\n", 1377 __FUNCTION__, this->process->pid, this->trdid ); 1378 #endif 1351 1379 error = 0; 1352 1380 } 1353 1381 else if( vseg->min == addr_min ) // vseg must be resized 1354 1382 { 1355 // update vseg base address 1383 1384 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1385 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1386 printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n", 1387 __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max ); 1388 #endif 1389 // update vseg min address 1356 1390 vseg->min = addr_max; 1357 1391 … … 1361 1395 vseg->vpn_base = vpn_min; 1362 1396 vseg->vpn_size = vpn_max - vpn_min + 1; 1397 1398 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1399 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1400 printk("\n[%s] thread[%x,%x] changed vseg_min\n", 1401 __FUNCTION__, this->process->pid, this->trdid ); 1402 #endif 1363 1403 error = 0; 1364 1404 } 1365 1405 else if( vseg->max == addr_max ) // vseg must be resized 1366 1406 { 1407 1408 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1409 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1410 printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n", 1411 __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max ); 1412 #endif 1367 1413 // update vseg max address 1368 1414 vseg->max = addr_min; … … 1373 1419 vseg->vpn_base = vpn_min; 1374 1420 vseg->vpn_size = vpn_max - vpn_min + 1; 1421 1422 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1423 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1424 printk("\n[%s] thread[%x,%x] changed vseg_max\n", 1425 __FUNCTION__, this->process->pid, this->trdid ); 1426 #endif 1375 1427 error = 0; 1428 1376 1429 } 1377 1430 else // vseg cut in three regions 1378 1431 { 1432 1433 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1434 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1435 printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n", 1436 __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max ); 1437 #endif 1379 1438 // resize existing vseg 1380 1439 vseg->max = addr_min; … … 1396 1455 vseg->cxy ); 1397 1456 1398 if( new == NULL ) error = EINVAL; 1457 #if( DEBUG_VMM_RESIZE_VSEG & 1 ) 1458 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1459 printk("\n[%s] thread[%x,%x] replaced vseg by two smal vsegs\n", 1460 __FUNCTION__, this->process->pid, this->trdid ); 1461 #endif 1462 1463 if( new == NULL ) error = -1; 1399 1464 else error = 0; 1400 1465 } 1401 1466 1402 // release VMM lock 1403 remote_rwlock_wr_release( lock_xp ); 1467 #if DEBUG_VMM_RESIZE_VSEG 1468 if( DEBUG_VMM_RESIZE_VSEG < cycle ) 1469 printk("\n[%s] thread[%x,%x] exit / process %x / base %x / size %d / cycle %d\n", 1470 __FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle ); 1471 #endif 1404 1472 1405 1473 return error;
Note: See TracChangeset
for help on using the changeset viewer.