Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    r97bdb4a r8f80c77  
    116116as_t *AS_KERNEL = NULL;
    117117
    118 NO_TRACE static int as_constructor(void *obj, unsigned int flags)
     118static unsigned int area_flags_to_page_flags(unsigned int);
     119static as_area_t *find_area_and_lock(as_t *, uintptr_t);
     120static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
     121static void sh_info_remove_reference(share_info_t *);
     122
     123static int as_constructor(void *obj, unsigned int flags)
    119124{
    120125        as_t *as = (as_t *) obj;
     
    128133}
    129134
    130 NO_TRACE static size_t as_destructor(void *obj)
     135static size_t as_destructor(void *obj)
    131136{
    132137        as_t *as = (as_t *) obj;
     
    234239       
    235240        spinlock_unlock(&asidlock);
    236         interrupts_restore(ipl);
    237 
    238241       
    239242        /*
     
    263266#endif
    264267       
     268        interrupts_restore(ipl);
     269       
    265270        slab_free(as_slab, as);
    266271}
     
    274279 *
    275280 */
    276 NO_TRACE void as_hold(as_t *as)
     281void as_hold(as_t *as)
    277282{
    278283        atomic_inc(&as->refcount);
     
    287292 *
    288293 */
    289 NO_TRACE void as_release(as_t *as)
     294void as_release(as_t *as)
    290295{
    291296        if (atomic_predec(&as->refcount) == 0)
    292297                as_destroy(as);
    293 }
    294 
    295 /** Check area conflicts with other areas.
    296  *
    297  * @param as         Address space.
    298  * @param va         Starting virtual address of the area being tested.
    299  * @param size       Size of the area being tested.
    300  * @param avoid_area Do not touch this area.
    301  *
    302  * @return True if there is no conflict, false otherwise.
    303  *
    304  */
    305 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
    306     as_area_t *avoid_area)
    307 {
    308         ASSERT(mutex_locked(&as->lock));
    309        
    310         /*
    311          * We don't want any area to have conflicts with NULL page.
    312          *
    313          */
    314         if (overlaps(va, size, NULL, PAGE_SIZE))
    315                 return false;
    316        
    317         /*
    318          * The leaf node is found in O(log n), where n is proportional to
    319          * the number of address space areas belonging to as.
    320          * The check for conflicts is then attempted on the rightmost
    321          * record in the left neighbour, the leftmost record in the right
    322          * neighbour and all records in the leaf node itself.
    323          *
    324          */
    325         btree_node_t *leaf;
    326         as_area_t *area =
    327             (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    328         if (area) {
    329                 if (area != avoid_area)
    330                         return false;
    331         }
    332        
    333         /* First, check the two border cases. */
    334         btree_node_t *node =
    335             btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    336         if (node) {
    337                 area = (as_area_t *) node->value[node->keys - 1];
    338                
    339                 mutex_lock(&area->lock);
    340                
    341                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    342                         mutex_unlock(&area->lock);
    343                         return false;
    344                 }
    345                
    346                 mutex_unlock(&area->lock);
    347         }
    348        
    349         node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    350         if (node) {
    351                 area = (as_area_t *) node->value[0];
    352                
    353                 mutex_lock(&area->lock);
    354                
    355                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    356                         mutex_unlock(&area->lock);
    357                         return false;
    358                 }
    359                
    360                 mutex_unlock(&area->lock);
    361         }
    362        
    363         /* Second, check the leaf node. */
    364         btree_key_t i;
    365         for (i = 0; i < leaf->keys; i++) {
    366                 area = (as_area_t *) leaf->value[i];
    367                
    368                 if (area == avoid_area)
    369                         continue;
    370                
    371                 mutex_lock(&area->lock);
    372                
    373                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    374                         mutex_unlock(&area->lock);
    375                         return false;
    376                 }
    377                
    378                 mutex_unlock(&area->lock);
    379         }
    380        
    381         /*
    382          * So far, the area does not conflict with other areas.
    383          * Check if it doesn't conflict with kernel address space.
    384          *
    385          */
    386         if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    387                 return !overlaps(va, size,
    388                     KERNEL_ADDRESS_SPACE_START,
    389                     KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    390         }
    391        
    392         return true;
    393298}
    394299
     
    422327                return NULL;
    423328       
     329        ipl_t ipl = interrupts_disable();
    424330        mutex_lock(&as->lock);
    425331       
    426332        if (!check_area_conflicts(as, base, size, NULL)) {
    427333                mutex_unlock(&as->lock);
     334                interrupts_restore(ipl);
    428335                return NULL;
    429336        }
     
    450357       
    451358        mutex_unlock(&as->lock);
     359        interrupts_restore(ipl);
    452360       
    453361        return area;
    454 }
    455 
    456 /** Find address space area and lock it.
    457  *
    458  * @param as Address space.
    459  * @param va Virtual address.
    460  *
    461  * @return Locked address space area containing va on success or
    462  *         NULL on failure.
    463  *
    464  */
    465 NO_TRACE static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
    466 {
    467         ASSERT(mutex_locked(&as->lock));
    468        
    469         btree_node_t *leaf;
    470         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    471         if (area) {
    472                 /* va is the base address of an address space area */
    473                 mutex_lock(&area->lock);
    474                 return area;
    475         }
    476        
    477         /*
    478          * Search the leaf node and the righmost record of its left neighbour
    479          * to find out whether this is a miss or va belongs to an address
    480          * space area found there.
    481          *
    482          */
    483        
    484         /* First, search the leaf node itself. */
    485         btree_key_t i;
    486        
    487         for (i = 0; i < leaf->keys; i++) {
    488                 area = (as_area_t *) leaf->value[i];
    489                
    490                 mutex_lock(&area->lock);
    491                
    492                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
    493                         return area;
    494                
    495                 mutex_unlock(&area->lock);
    496         }
    497        
    498         /*
    499          * Second, locate the left neighbour and test its last record.
    500          * Because of its position in the B+tree, it must have base < va.
    501          *
    502          */
    503         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    504         if (lnode) {
    505                 area = (as_area_t *) lnode->value[lnode->keys - 1];
    506                
    507                 mutex_lock(&area->lock);
    508                
    509                 if (va < area->base + area->pages * PAGE_SIZE)
    510                         return area;
    511                
    512                 mutex_unlock(&area->lock);
    513         }
    514        
    515         return NULL;
    516362}
    517363
     
    530376int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
    531377{
     378        ipl_t ipl = interrupts_disable();
    532379        mutex_lock(&as->lock);
    533380       
     
    539386        if (!area) {
    540387                mutex_unlock(&as->lock);
     388                interrupts_restore(ipl);
    541389                return ENOENT;
    542390        }
     
    550398                mutex_unlock(&area->lock);
    551399                mutex_unlock(&as->lock);
     400                interrupts_restore(ipl);
    552401                return ENOTSUP;
    553402        }
     
    561410                mutex_unlock(&area->lock);
    562411                mutex_unlock(&as->lock);
     412                interrupts_restore(ipl);
    563413                return ENOTSUP;
    564414        }
     
    572422                mutex_unlock(&area->lock);
    573423                mutex_unlock(&as->lock);
     424                interrupts_restore(ipl);
    574425                return EPERM;
    575426        }
     
    590441                 *
    591442                 */
    592                 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    593                     area->base + pages * PAGE_SIZE, area->pages - pages);
     443                tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
     444                    pages * PAGE_SIZE, area->pages - pages);
    594445               
    595446                /*
     
    685536                as_invalidate_translation_cache(as, area->base +
    686537                    pages * PAGE_SIZE, area->pages - pages);
    687                 tlb_shootdown_finalize(ipl);
     538                tlb_shootdown_finalize();
    688539               
    689540                page_table_unlock(as, false);
     
    698549                        mutex_unlock(&area->lock);
    699550                        mutex_unlock(&as->lock);
     551                        interrupts_restore(ipl);
    700552                        return EADDRNOTAVAIL;
    701553                }
     
    706558        mutex_unlock(&area->lock);
    707559        mutex_unlock(&as->lock);
     560        interrupts_restore(ipl);
    708561       
    709562        return 0;
    710 }
    711 
    712 /** Remove reference to address space area share info.
    713  *
    714  * If the reference count drops to 0, the sh_info is deallocated.
    715  *
    716  * @param sh_info Pointer to address space area share info.
    717  *
    718  */
    719 NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
    720 {
    721         bool dealloc = false;
    722        
    723         mutex_lock(&sh_info->lock);
    724         ASSERT(sh_info->refcount);
    725        
    726         if (--sh_info->refcount == 0) {
    727                 dealloc = true;
    728                 link_t *cur;
    729                
    730                 /*
    731                  * Now walk carefully the pagemap B+tree and free/remove
    732                  * reference from all frames found there.
    733                  */
    734                 for (cur = sh_info->pagemap.leaf_head.next;
    735                     cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
    736                         btree_node_t *node
    737                             = list_get_instance(cur, btree_node_t, leaf_link);
    738                         btree_key_t i;
    739                        
    740                         for (i = 0; i < node->keys; i++)
    741                                 frame_free((uintptr_t) node->value[i]);
    742                 }
    743                
    744         }
    745         mutex_unlock(&sh_info->lock);
    746        
    747         if (dealloc) {
    748                 btree_destroy(&sh_info->pagemap);
    749                 free(sh_info);
    750         }
    751563}
    752564
     
    761573int as_area_destroy(as_t *as, uintptr_t address)
    762574{
     575        ipl_t ipl = interrupts_disable();
    763576        mutex_lock(&as->lock);
    764577       
     
    766579        if (!area) {
    767580                mutex_unlock(&as->lock);
     581                interrupts_restore(ipl);
    768582                return ENOENT;
    769583        }
     
    776590         * Start TLB shootdown sequence.
    777591         */
    778         ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
    779             area->pages);
     592        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    780593       
    781594        /*
     
    824637         */
    825638        as_invalidate_translation_cache(as, area->base, area->pages);
    826         tlb_shootdown_finalize(ipl);
     639        tlb_shootdown_finalize();
    827640       
    828641        page_table_unlock(as, false);
     
    846659       
    847660        mutex_unlock(&as->lock);
     661        interrupts_restore(ipl);
    848662        return 0;
    849663}
     
    876690    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
    877691{
     692        ipl_t ipl = interrupts_disable();
    878693        mutex_lock(&src_as->lock);
    879694        as_area_t *src_area = find_area_and_lock(src_as, src_base);
     
    884699                 */
    885700                mutex_unlock(&src_as->lock);
     701                interrupts_restore(ipl);
    886702                return ENOENT;
    887703        }
     
    895711                mutex_unlock(&src_area->lock);
    896712                mutex_unlock(&src_as->lock);
     713                interrupts_restore(ipl);
    897714                return ENOTSUP;
    898715        }
     
    911728                mutex_unlock(&src_area->lock);
    912729                mutex_unlock(&src_as->lock);
     730                interrupts_restore(ipl);
    913731                return EPERM;
    914732        }
     
    959777                sh_info_remove_reference(sh_info);
    960778               
     779                interrupts_restore(ipl);
    961780                return ENOMEM;
    962781        }
     
    975794        mutex_unlock(&dst_as->lock);
    976795       
     796        interrupts_restore(ipl);
     797       
    977798        return 0;
    978799}
     
    987808 *
    988809 */
    989 NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
     810bool as_area_check_access(as_area_t *area, pf_access_t access)
    990811{
    991812        int flagmap[] = {
     
    995816        };
    996817
     818        ASSERT(interrupts_disabled());
    997819        ASSERT(mutex_locked(&area->lock));
    998820       
     
    1001823       
    1002824        return true;
    1003 }
    1004 
    1005 /** Convert address space area flags to page flags.
    1006  *
    1007  * @param aflags Flags of some address space area.
    1008  *
    1009  * @return Flags to be passed to page_mapping_insert().
    1010  *
    1011  */
    1012 NO_TRACE static unsigned int area_flags_to_page_flags(unsigned int aflags)
    1013 {
    1014         unsigned int flags = PAGE_USER | PAGE_PRESENT;
    1015        
    1016         if (aflags & AS_AREA_READ)
    1017                 flags |= PAGE_READ;
    1018                
    1019         if (aflags & AS_AREA_WRITE)
    1020                 flags |= PAGE_WRITE;
    1021        
    1022         if (aflags & AS_AREA_EXEC)
    1023                 flags |= PAGE_EXEC;
    1024        
    1025         if (aflags & AS_AREA_CACHEABLE)
    1026                 flags |= PAGE_CACHEABLE;
    1027        
    1028         return flags;
    1029825}
    1030826
     
    1048844        unsigned int page_flags = area_flags_to_page_flags(flags);
    1049845       
     846        ipl_t ipl = interrupts_disable();
    1050847        mutex_lock(&as->lock);
    1051848       
     
    1053850        if (!area) {
    1054851                mutex_unlock(&as->lock);
     852                interrupts_restore(ipl);
    1055853                return ENOENT;
    1056854        }
     
    1061859                mutex_unlock(&area->lock);
    1062860                mutex_unlock(&as->lock);
     861                interrupts_restore(ipl);
    1063862                return ENOTSUP;
    1064863        }
     
    1090889         *
    1091890         */
    1092         ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
    1093             area->pages);
     891        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    1094892       
    1095893        /*
     
    1138936         */
    1139937        as_invalidate_translation_cache(as, area->base, area->pages);
    1140         tlb_shootdown_finalize(ipl);
     938        tlb_shootdown_finalize();
    1141939       
    1142940        page_table_unlock(as, false);
     
    1180978        mutex_unlock(&area->lock);
    1181979        mutex_unlock(&as->lock);
     980        interrupts_restore(ipl);
    1182981       
    1183982        return 0;
     
    13851184}
    13861185
     1186/** Convert address space area flags to page flags.
     1187 *
     1188 * @param aflags Flags of some address space area.
     1189 *
     1190 * @return Flags to be passed to page_mapping_insert().
     1191 *
     1192 */
     1193unsigned int area_flags_to_page_flags(unsigned int aflags)
     1194{
     1195        unsigned int flags = PAGE_USER | PAGE_PRESENT;
     1196       
     1197        if (aflags & AS_AREA_READ)
     1198                flags |= PAGE_READ;
     1199               
     1200        if (aflags & AS_AREA_WRITE)
     1201                flags |= PAGE_WRITE;
     1202       
     1203        if (aflags & AS_AREA_EXEC)
     1204                flags |= PAGE_EXEC;
     1205       
     1206        if (aflags & AS_AREA_CACHEABLE)
     1207                flags |= PAGE_CACHEABLE;
     1208       
     1209        return flags;
     1210}
     1211
    13871212/** Compute flags for virtual address translation subsytem.
    13881213 *
     
    13921217 *
    13931218 */
    1394 NO_TRACE unsigned int as_area_get_flags(as_area_t *area)
    1395 {
     1219unsigned int as_area_get_flags(as_area_t *area)
     1220{
     1221        ASSERT(interrupts_disabled());
    13961222        ASSERT(mutex_locked(&area->lock));
    13971223
     
    14101236 *
    14111237 */
    1412 NO_TRACE pte_t *page_table_create(unsigned int flags)
     1238pte_t *page_table_create(unsigned int flags)
    14131239{
    14141240        ASSERT(as_operations);
     
    14251251 *
    14261252 */
    1427 NO_TRACE void page_table_destroy(pte_t *page_table)
     1253void page_table_destroy(pte_t *page_table)
    14281254{
    14291255        ASSERT(as_operations);
     
    14461272 *
    14471273 */
    1448 NO_TRACE void page_table_lock(as_t *as, bool lock)
     1274void page_table_lock(as_t *as, bool lock)
    14491275{
    14501276        ASSERT(as_operations);
     
    14601286 *
    14611287 */
    1462 NO_TRACE void page_table_unlock(as_t *as, bool unlock)
     1288void page_table_unlock(as_t *as, bool unlock)
    14631289{
    14641290        ASSERT(as_operations);
     
    14701296/** Test whether page tables are locked.
    14711297 *
    1472  * @param as Address space where the page tables belong.
    1473  *
    1474  * @return True if the page tables belonging to the address soace
    1475  *         are locked, otherwise false.
    1476  */
    1477 NO_TRACE bool page_table_locked(as_t *as)
     1298 * @param as            Address space where the page tables belong.
     1299 *
     1300 * @return              True if the page tables belonging to the address soace
     1301 *                      are locked, otherwise false.
     1302 */
     1303bool page_table_locked(as_t *as)
    14781304{
    14791305        ASSERT(as_operations);
     
    14831309}
    14841310
     1311
     1312/** Find address space area and lock it.
     1313 *
     1314 * @param as Address space.
     1315 * @param va Virtual address.
     1316 *
     1317 * @return Locked address space area containing va on success or
     1318 *         NULL on failure.
     1319 *
     1320 */
     1321as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
     1322{
     1323        ASSERT(interrupts_disabled());
     1324        ASSERT(mutex_locked(&as->lock));
     1325
     1326        btree_node_t *leaf;
     1327        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     1328        if (area) {
     1329                /* va is the base address of an address space area */
     1330                mutex_lock(&area->lock);
     1331                return area;
     1332        }
     1333       
     1334        /*
     1335         * Search the leaf node and the righmost record of its left neighbour
     1336         * to find out whether this is a miss or va belongs to an address
     1337         * space area found there.
     1338         *
     1339         */
     1340       
     1341        /* First, search the leaf node itself. */
     1342        btree_key_t i;
     1343       
     1344        for (i = 0; i < leaf->keys; i++) {
     1345                area = (as_area_t *) leaf->value[i];
     1346               
     1347                mutex_lock(&area->lock);
     1348               
     1349                if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     1350                        return area;
     1351               
     1352                mutex_unlock(&area->lock);
     1353        }
     1354       
     1355        /*
     1356         * Second, locate the left neighbour and test its last record.
     1357         * Because of its position in the B+tree, it must have base < va.
     1358         *
     1359         */
     1360        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     1361        if (lnode) {
     1362                area = (as_area_t *) lnode->value[lnode->keys - 1];
     1363               
     1364                mutex_lock(&area->lock);
     1365               
     1366                if (va < area->base + area->pages * PAGE_SIZE)
     1367                        return area;
     1368               
     1369                mutex_unlock(&area->lock);
     1370        }
     1371       
     1372        return NULL;
     1373}
     1374
     1375/** Check area conflicts with other areas.
     1376 *
     1377 * @param as         Address space.
     1378 * @param va         Starting virtual address of the area being tested.
     1379 * @param size       Size of the area being tested.
     1380 * @param avoid_area Do not touch this area.
     1381 *
     1382 * @return True if there is no conflict, false otherwise.
     1383 *
     1384 */
     1385bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
     1386    as_area_t *avoid_area)
     1387{
     1388        ASSERT(interrupts_disabled());
     1389        ASSERT(mutex_locked(&as->lock));
     1390
     1391        /*
     1392         * We don't want any area to have conflicts with NULL page.
     1393         *
     1394         */
     1395        if (overlaps(va, size, NULL, PAGE_SIZE))
     1396                return false;
     1397       
     1398        /*
     1399         * The leaf node is found in O(log n), where n is proportional to
     1400         * the number of address space areas belonging to as.
     1401         * The check for conflicts is then attempted on the rightmost
     1402         * record in the left neighbour, the leftmost record in the right
     1403         * neighbour and all records in the leaf node itself.
     1404         *
     1405         */
     1406        btree_node_t *leaf;
     1407        as_area_t *area =
     1408            (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     1409        if (area) {
     1410                if (area != avoid_area)
     1411                        return false;
     1412        }
     1413       
     1414        /* First, check the two border cases. */
     1415        btree_node_t *node =
     1416            btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     1417        if (node) {
     1418                area = (as_area_t *) node->value[node->keys - 1];
     1419               
     1420                mutex_lock(&area->lock);
     1421               
     1422                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1423                        mutex_unlock(&area->lock);
     1424                        return false;
     1425                }
     1426               
     1427                mutex_unlock(&area->lock);
     1428        }
     1429       
     1430        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
     1431        if (node) {
     1432                area = (as_area_t *) node->value[0];
     1433               
     1434                mutex_lock(&area->lock);
     1435               
     1436                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1437                        mutex_unlock(&area->lock);
     1438                        return false;
     1439                }
     1440               
     1441                mutex_unlock(&area->lock);
     1442        }
     1443       
     1444        /* Second, check the leaf node. */
     1445        btree_key_t i;
     1446        for (i = 0; i < leaf->keys; i++) {
     1447                area = (as_area_t *) leaf->value[i];
     1448               
     1449                if (area == avoid_area)
     1450                        continue;
     1451               
     1452                mutex_lock(&area->lock);
     1453               
     1454                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1455                        mutex_unlock(&area->lock);
     1456                        return false;
     1457                }
     1458               
     1459                mutex_unlock(&area->lock);
     1460        }
     1461       
     1462        /*
     1463         * So far, the area does not conflict with other areas.
     1464         * Check if it doesn't conflict with kernel address space.
     1465         *
     1466         */
     1467        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
     1468                return !overlaps(va, size,
     1469                    KERNEL_ADDRESS_SPACE_START,
     1470                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     1471        }
     1472       
     1473        return true;
     1474}
     1475
    14851476/** Return size of the address space area with given base.
    14861477 *
     
    14951486        size_t size;
    14961487       
     1488        ipl_t ipl = interrupts_disable();
    14971489        page_table_lock(AS, true);
    14981490        as_area_t *src_area = find_area_and_lock(AS, base);
     
    15051497       
    15061498        page_table_unlock(AS, true);
     1499        interrupts_restore(ipl);
    15071500        return size;
    15081501}
     
    19951988}
    19961989
     1990/** Remove reference to address space area share info.
     1991 *
     1992 * If the reference count drops to 0, the sh_info is deallocated.
     1993 *
     1994 * @param sh_info Pointer to address space area share info.
     1995 *
     1996 */
     1997void sh_info_remove_reference(share_info_t *sh_info)
     1998{
     1999        bool dealloc = false;
     2000       
     2001        mutex_lock(&sh_info->lock);
     2002        ASSERT(sh_info->refcount);
     2003       
     2004        if (--sh_info->refcount == 0) {
     2005                dealloc = true;
     2006                link_t *cur;
     2007               
     2008                /*
     2009                 * Now walk carefully the pagemap B+tree and free/remove
     2010                 * reference from all frames found there.
     2011                 */
     2012                for (cur = sh_info->pagemap.leaf_head.next;
     2013                    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
     2014                        btree_node_t *node
     2015                            = list_get_instance(cur, btree_node_t, leaf_link);
     2016                        btree_key_t i;
     2017                       
     2018                        for (i = 0; i < node->keys; i++)
     2019                                frame_free((uintptr_t) node->value[i]);
     2020                }
     2021               
     2022        }
     2023        mutex_unlock(&sh_info->lock);
     2024       
     2025        if (dealloc) {
     2026                btree_destroy(&sh_info->pagemap);
     2027                free(sh_info);
     2028        }
     2029}
     2030
    19972031/*
    19982032 * Address space related syscalls.
     
    20362070void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
    20372071{
     2072        ipl_t ipl = interrupts_disable();
    20382073        mutex_lock(&as->lock);
    20392074       
     
    20792114       
    20802115        mutex_unlock(&as->lock);
     2116        interrupts_restore(ipl);
    20812117       
    20822118        *obuf = info;
     
    20912127void as_print(as_t *as)
    20922128{
     2129        ipl_t ipl = interrupts_disable();
    20932130        mutex_lock(&as->lock);
    20942131       
     
    21132150       
    21142151        mutex_unlock(&as->lock);
     2152        interrupts_restore(ipl);
    21152153}
    21162154
Note: See TracChangeset for help on using the changeset viewer.