Ignore:
File:
1 edited

Legend:

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

    r8f80c77 r1624aae  
    3333/**
    3434 * @file
    35  * @brief Address space related functions.
     35 * @brief       Address space related functions.
    3636 *
    3737 * This file contains address space manipulation functions.
     
    8686 * Each architecture decides what functions will be used to carry out
    8787 * address space operations such as creating or locking page tables.
    88  *
    8988 */
    9089as_operations_t *as_operations = NULL;
     
    9291/**
    9392 * Slab for as_t objects.
    94  *
    9593 */
    9694static slab_cache_t *as_slab;
     
    102100 * - as->asid for each as of the as_t type
    103101 * - asids_allocated counter
    104  *
    105102 */
    106103SPINLOCK_INITIALIZE(asidlock);
     
    109106 * This list contains address spaces that are not active on any
    110107 * processor and that have valid ASID.
    111  *
    112108 */
    113109LIST_INITIALIZE(inactive_as_with_asid_head);
     
    116112as_t *AS_KERNEL = NULL;
    117113
    118 static unsigned int area_flags_to_page_flags(unsigned int);
     114static int area_flags_to_page_flags(int);
    119115static as_area_t *find_area_and_lock(as_t *, uintptr_t);
    120116static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
    121117static void sh_info_remove_reference(share_info_t *);
    122118
    123 static int as_constructor(void *obj, unsigned int flags)
     119static int as_constructor(void *obj, int flags)
    124120{
    125121        as_t *as = (as_t *) obj;
    126        
     122        int rc;
     123
    127124        link_initialize(&as->inactive_as_with_asid_link);
    128125        mutex_initialize(&as->lock, MUTEX_PASSIVE);
    129126       
    130         int rc = as_constructor_arch(as, flags);
     127        rc = as_constructor_arch(as, flags);
    131128       
    132129        return rc;
    133130}
    134131
    135 static size_t as_destructor(void *obj)
     132static int as_destructor(void *obj)
    136133{
    137134        as_t *as = (as_t *) obj;
     135
    138136        return as_destructor_arch(as);
    139137}
     
    143141{
    144142        as_arch_init();
    145        
     143
    146144        as_slab = slab_cache_create("as_slab", sizeof(as_t), 0,
    147145            as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
     
    159157/** Create address space.
    160158 *
    161  * @param flags Flags that influence the way in wich the address
    162  *              space is created.
    163  *
    164  */
    165 as_t *as_create(unsigned int flags)
    166 {
    167         as_t *as = (as_t *) slab_alloc(as_slab, 0);
     159 * @param flags         Flags that influence the way in wich the address space
     160 *                      is created.
     161 */
     162as_t *as_create(int flags)
     163{
     164        as_t *as;
     165
     166        as = (as_t *) slab_alloc(as_slab, 0);
    168167        (void) as_create_arch(as, 0);
    169168       
     
    177176        atomic_set(&as->refcount, 0);
    178177        as->cpu_refcount = 0;
    179        
    180178#ifdef AS_PAGE_TABLE
    181179        as->genarch.page_table = page_table_create(flags);
     
    194192 * We know that we don't hold any spinlock.
    195193 *
    196  * @param as Address space to be destroyed.
    197  *
     194 * @param as            Address space to be destroyed.
    198195 */
    199196void as_destroy(as_t *as)
    200197{
     198        ipl_t ipl;
     199        bool cond;
    201200        DEADLOCK_PROBE_INIT(p_asidlock);
    202201
     
    215214         * disabled to prevent nested context switches. We also depend on the
    216215         * fact that so far no spinlocks are held.
    217          *
    218216         */
    219217        preemption_disable();
    220         ipl_t ipl = interrupts_read();
    221        
     218        ipl = interrupts_read();
    222219retry:
    223220        interrupts_disable();
     
    227224                goto retry;
    228225        }
    229        
    230         /* Interrupts disabled, enable preemption */
    231         preemption_enable();
    232        
    233         if ((as->asid != ASID_INVALID) && (as != AS_KERNEL)) {
     226        preemption_enable();    /* Interrupts disabled, enable preemption */
     227        if (as->asid != ASID_INVALID && as != AS_KERNEL) {
    234228                if (as->cpu_refcount == 0)
    235229                        list_remove(&as->inactive_as_with_asid_link);
    236                
    237230                asid_put(as->asid);
    238231        }
    239        
    240232        spinlock_unlock(&asidlock);
    241        
     233
    242234        /*
    243235         * Destroy address space areas of the address space.
    244236         * The B+tree must be walked carefully because it is
    245237         * also being destroyed.
    246          *
    247          */
    248         bool cond = true;
    249         while (cond) {
     238         */     
     239        for (cond = true; cond; ) {
     240                btree_node_t *node;
     241
    250242                ASSERT(!list_empty(&as->as_area_btree.leaf_head));
    251                
    252                 btree_node_t *node =
    253                     list_get_instance(as->as_area_btree.leaf_head.next,
     243                node = list_get_instance(as->as_area_btree.leaf_head.next,
    254244                    btree_node_t, leaf_link);
    255                
    256                 if ((cond = node->keys))
     245
     246                if ((cond = node->keys)) {
    257247                        as_area_destroy(as, node->key[0]);
    258         }
    259        
     248                }
     249        }
     250
    260251        btree_destroy(&as->as_area_btree);
    261        
    262252#ifdef AS_PAGE_TABLE
    263253        page_table_destroy(as->genarch.page_table);
     
    265255        page_table_destroy(NULL);
    266256#endif
    267        
     257
    268258        interrupts_restore(ipl);
    269        
     259
    270260        slab_free(as_slab, as);
    271261}
     
    276266 * space.
    277267 *
    278  * @param as Address space to be held.
    279  *
     268 * @param a             Address space to be held.
    280269 */
    281270void as_hold(as_t *as)
     
    289278 * space.
    290279 *
    291  * @param asAddress space to be released.
    292  *
     280 * @param a             Address space to be released.
    293281 */
    294282void as_release(as_t *as)
     
    302290 * The created address space area is added to the target address space.
    303291 *
    304  * @param as           Target address space.
    305  * @param flags        Flags of the area memory.
    306  * @param size         Size of area.
    307  * @param base         Base address of area.
    308  * @param attrs        Attributes of the area.
    309  * @param backend      Address space area backend. NULL if no backend is used.
    310  * @param backend_data NULL or a pointer to an array holding two void *.
    311  *
    312  * @return Address space area on success or NULL on failure.
    313  *
    314  */
    315 as_area_t *as_area_create(as_t *as, unsigned int flags, size_t size,
    316     uintptr_t base, unsigned int attrs, mem_backend_t *backend,
    317     mem_backend_data_t *backend_data)
    318 {
     292 * @param as            Target address space.
     293 * @param flags         Flags of the area memory.
     294 * @param size          Size of area.
     295 * @param base          Base address of area.
     296 * @param attrs         Attributes of the area.
     297 * @param backend       Address space area backend. NULL if no backend is used.
     298 * @param backend_data  NULL or a pointer to an array holding two void *.
     299 *
     300 * @return              Address space area on success or NULL on failure.
     301 */
     302as_area_t *
     303as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs,
     304    mem_backend_t *backend, mem_backend_data_t *backend_data)
     305{
     306        ipl_t ipl;
     307        as_area_t *a;
     308       
    319309        if (base % PAGE_SIZE)
    320310                return NULL;
    321        
     311
    322312        if (!size)
    323313                return NULL;
    324        
     314
    325315        /* Writeable executable areas are not supported. */
    326316        if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
    327317                return NULL;
    328318       
    329         ipl_t ipl = interrupts_disable();
     319        ipl = interrupts_disable();
    330320        mutex_lock(&as->lock);
    331321       
     
    336326        }
    337327       
    338         as_area_t *area = (as_area_t *) malloc(sizeof(as_area_t), 0);
    339        
    340         mutex_initialize(&area->lock, MUTEX_PASSIVE);
    341        
    342         area->as = as;
    343         area->flags = flags;
    344         area->attributes = attrs;
    345         area->pages = SIZE2FRAMES(size);
    346         area->base = base;
    347         area->sh_info = NULL;
    348         area->backend = backend;
    349        
     328        a = (as_area_t *) malloc(sizeof(as_area_t), 0);
     329
     330        mutex_initialize(&a->lock, MUTEX_PASSIVE);
     331       
     332        a->as = as;
     333        a->flags = flags;
     334        a->attributes = attrs;
     335        a->pages = SIZE2FRAMES(size);
     336        a->base = base;
     337        a->sh_info = NULL;
     338        a->backend = backend;
    350339        if (backend_data)
    351                 area->backend_data = *backend_data;
     340                a->backend_data = *backend_data;
    352341        else
    353                 memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    354        
    355         btree_create(&area->used_space);
    356         btree_insert(&as->as_area_btree, base, (void *) area, NULL);
    357        
     342                memsetb(&a->backend_data, sizeof(a->backend_data), 0);
     343
     344        btree_create(&a->used_space);
     345       
     346        btree_insert(&as->as_area_btree, base, (void *) a, NULL);
     347
    358348        mutex_unlock(&as->lock);
    359349        interrupts_restore(ipl);
    360        
    361         return area;
     350
     351        return a;
    362352}
    363353
    364354/** Find address space area and change it.
    365355 *
    366  * @param as      Address space.
    367  * @param address Virtual address belonging to the area to be changed.
    368  *                Must be page-aligned.
    369  * @param size    New size of the virtual memory block starting at
    370  *                address.
    371  * @param flags   Flags influencing the remap operation. Currently unused.
    372  *
    373  * @return Zero on success or a value from @ref errno.h otherwise.
    374  *
    375  */
    376 int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
    377 {
    378         ipl_t ipl = interrupts_disable();
     356 * @param as            Address space.
     357 * @param address       Virtual address belonging to the area to be changed.
     358 *                      Must be page-aligned.
     359 * @param size          New size of the virtual memory block starting at
     360 *                      address.
     361 * @param flags         Flags influencing the remap operation. Currently unused.
     362 *
     363 * @return              Zero on success or a value from @ref errno.h otherwise.
     364 */
     365int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags)
     366{
     367        as_area_t *area;
     368        ipl_t ipl;
     369        size_t pages;
     370       
     371        ipl = interrupts_disable();
    379372        mutex_lock(&as->lock);
    380373       
    381374        /*
    382375         * Locate the area.
    383          *
    384          */
    385         as_area_t *area = find_area_and_lock(as, address);
     376         */
     377        area = find_area_and_lock(as, address);
    386378        if (!area) {
    387379                mutex_unlock(&as->lock);
     
    389381                return ENOENT;
    390382        }
    391        
     383
    392384        if (area->backend == &phys_backend) {
    393385                /*
    394386                 * Remapping of address space areas associated
    395387                 * with memory mapped devices is not supported.
    396                  *
    397388                 */
    398389                mutex_unlock(&area->lock);
     
    401392                return ENOTSUP;
    402393        }
    403        
    404394        if (area->sh_info) {
    405395                /*
    406                  * Remapping of shared address space areas
     396                 * Remapping of shared address space areas 
    407397                 * is not supported.
    408                  *
    409398                 */
    410399                mutex_unlock(&area->lock);
     
    413402                return ENOTSUP;
    414403        }
    415        
    416         size_t pages = SIZE2FRAMES((address - area->base) + size);
     404
     405        pages = SIZE2FRAMES((address - area->base) + size);
    417406        if (!pages) {
    418407                /*
    419408                 * Zero size address space areas are not allowed.
    420                  *
    421409                 */
    422410                mutex_unlock(&area->lock);
     
    427415       
    428416        if (pages < area->pages) {
     417                bool cond;
    429418                uintptr_t start_free = area->base + pages * PAGE_SIZE;
    430                
     419
    431420                /*
    432421                 * Shrinking the area.
    433422                 * No need to check for overlaps.
    434                  *
    435                  */
    436                
    437                 page_table_lock(as, false);
    438                
     423                 */
     424
    439425                /*
    440426                 * Start TLB shootdown sequence.
    441                  *
    442427                 */
    443428                tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
    444429                    pages * PAGE_SIZE, area->pages - pages);
    445                
     430
    446431                /*
    447432                 * Remove frames belonging to used space starting from
     
    450435                 * is also the right way to remove part of the used_space
    451436                 * B+tree leaf list.
    452                  *
    453                  */
    454                 bool cond = true;
    455                 while (cond) {
     437                 */             
     438                for (cond = true; cond;) {
     439                        btree_node_t *node;
     440               
    456441                        ASSERT(!list_empty(&area->used_space.leaf_head));
    457                        
    458                         btree_node_t *node =
     442                        node =
    459443                            list_get_instance(area->used_space.leaf_head.prev,
    460444                            btree_node_t, leaf_link);
     445                        if ((cond = (bool) node->keys)) {
     446                                uintptr_t b = node->key[node->keys - 1];
     447                                size_t c =
     448                                    (size_t) node->value[node->keys - 1];
     449                                unsigned int i = 0;
    461450                       
    462                         if ((cond = (bool) node->keys)) {
    463                                 uintptr_t ptr = node->key[node->keys - 1];
    464                                 size_t size =
    465                                     (size_t) node->value[node->keys - 1];
    466                                 size_t i = 0;
    467                                
    468                                 if (overlaps(ptr, size * PAGE_SIZE, area->base,
     451                                if (overlaps(b, c * PAGE_SIZE, area->base,
    469452                                    pages * PAGE_SIZE)) {
    470453                                       
    471                                         if (ptr + size * PAGE_SIZE <= start_free) {
     454                                        if (b + c * PAGE_SIZE <= start_free) {
    472455                                                /*
    473456                                                 * The whole interval fits
    474457                                                 * completely in the resized
    475458                                                 * address space area.
    476                                                  *
    477459                                                 */
    478460                                                break;
    479461                                        }
    480                                        
     462               
    481463                                        /*
    482464                                         * Part of the interval corresponding
    483465                                         * to b and c overlaps with the resized
    484466                                         * address space area.
    485                                          *
    486467                                         */
    487                                        
    488                                         /* We are almost done */
    489                                         cond = false;
    490                                         i = (start_free - ptr) >> PAGE_WIDTH;
     468               
     469                                        cond = false;   /* we are almost done */
     470                                        i = (start_free - b) >> PAGE_WIDTH;
    491471                                        if (!used_space_remove(area, start_free,
    492                                             size - i))
    493                                                 panic("Cannot remove used space.");
     472                                            c - i))
     473                                                panic("Cannot remove used "
     474                                                    "space.");
    494475                                } else {
    495476                                        /*
     
    497478                                         * completely removed.
    498479                                         */
    499                                         if (!used_space_remove(area, ptr, size))
    500                                                 panic("Cannot remove used space.");
     480                                        if (!used_space_remove(area, b, c))
     481                                                panic("Cannot remove used "
     482                                                    "space.");
    501483                                }
    502                                
    503                                 for (; i < size; i++) {
    504                                         pte_t *pte = page_mapping_find(as, ptr +
     484                       
     485                                for (; i < c; i++) {
     486                                        pte_t *pte;
     487                       
     488                                        page_table_lock(as, false);
     489                                        pte = page_mapping_find(as, b +
    505490                                            i * PAGE_SIZE);
    506                                        
    507                                         ASSERT(pte);
    508                                         ASSERT(PTE_VALID(pte));
    509                                         ASSERT(PTE_PRESENT(pte));
    510                                        
    511                                         if ((area->backend) &&
    512                                             (area->backend->frame_free)) {
     491                                        ASSERT(pte && PTE_VALID(pte) &&
     492                                            PTE_PRESENT(pte));
     493                                        if (area->backend &&
     494                                            area->backend->frame_free) {
    513495                                                area->backend->frame_free(area,
    514                                                     ptr + i * PAGE_SIZE,
     496                                                    b + i * PAGE_SIZE,
    515497                                                    PTE_GET_FRAME(pte));
    516498                                        }
    517                                        
    518                                         page_mapping_remove(as, ptr +
     499                                        page_mapping_remove(as, b +
    519500                                            i * PAGE_SIZE);
     501                                        page_table_unlock(as, false);
    520502                                }
    521503                        }
    522504                }
    523                
     505
    524506                /*
    525507                 * Finish TLB shootdown sequence.
    526                  *
    527                  */
    528                
     508                 */
     509
    529510                tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
    530511                    area->pages - pages);
    531                
    532512                /*
    533513                 * Invalidate software translation caches (e.g. TSB on sparc64).
    534                  *
    535514                 */
    536515                as_invalidate_translation_cache(as, area->base +
     
    538517                tlb_shootdown_finalize();
    539518               
    540                 page_table_unlock(as, false);
    541519        } else {
    542520                /*
    543521                 * Growing the area.
    544522                 * Check for overlaps with other address space areas.
    545                  *
    546523                 */
    547524                if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
    548525                    area)) {
    549526                        mutex_unlock(&area->lock);
    550                         mutex_unlock(&as->lock);
     527                        mutex_unlock(&as->lock);               
    551528                        interrupts_restore(ipl);
    552529                        return EADDRNOTAVAIL;
    553530                }
    554         }
    555        
     531        } 
     532
    556533        area->pages = pages;
    557534       
     
    559536        mutex_unlock(&as->lock);
    560537        interrupts_restore(ipl);
    561        
     538
    562539        return 0;
    563540}
     
    565542/** Destroy address space area.
    566543 *
    567  * @param as      Address space.
    568  * @param address Address within the area to be deleted.
    569  *
    570  * @return Zero on success or a value from @ref errno.h on failure.
    571  *
     544 * @param as            Address space.
     545 * @param address       Address within the area to be deleted.
     546 *
     547 * @return              Zero on success or a value from @ref errno.h on failure.
    572548 */
    573549int as_area_destroy(as_t *as, uintptr_t address)
    574550{
    575         ipl_t ipl = interrupts_disable();
     551        as_area_t *area;
     552        uintptr_t base;
     553        link_t *cur;
     554        ipl_t ipl;
     555
     556        ipl = interrupts_disable();
    576557        mutex_lock(&as->lock);
    577        
    578         as_area_t *area = find_area_and_lock(as, address);
     558
     559        area = find_area_and_lock(as, address);
    579560        if (!area) {
    580561                mutex_unlock(&as->lock);
     
    582563                return ENOENT;
    583564        }
    584        
    585         uintptr_t base = area->base;
    586        
    587         page_table_lock(as, false);
    588        
     565
     566        base = area->base;
     567
    589568        /*
    590569         * Start TLB shootdown sequence.
    591570         */
    592571        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    593        
     572
    594573        /*
    595574         * Visit only the pages mapped by used_space B+tree.
    596575         */
    597         link_t *cur;
    598576        for (cur = area->used_space.leaf_head.next;
    599577            cur != &area->used_space.leaf_head; cur = cur->next) {
    600578                btree_node_t *node;
    601                 btree_key_t i;
     579                unsigned int i;
    602580               
    603581                node = list_get_instance(cur, btree_node_t, leaf_link);
    604582                for (i = 0; i < node->keys; i++) {
    605                         uintptr_t ptr = node->key[i];
    606                         size_t size;
     583                        uintptr_t b = node->key[i];
     584                        size_t j;
     585                        pte_t *pte;
    607586                       
    608                         for (size = 0; size < (size_t) node->value[i]; size++) {
    609                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    610                                
    611                                 ASSERT(pte);
    612                                 ASSERT(PTE_VALID(pte));
    613                                 ASSERT(PTE_PRESENT(pte));
    614                                
    615                                 if ((area->backend) &&
    616                                     (area->backend->frame_free)) {
    617                                         area->backend->frame_free(area,
    618                                             ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
     587                        for (j = 0; j < (size_t) node->value[i]; j++) {
     588                                page_table_lock(as, false);
     589                                pte = page_mapping_find(as, b + j * PAGE_SIZE);
     590                                ASSERT(pte && PTE_VALID(pte) &&
     591                                    PTE_PRESENT(pte));
     592                                if (area->backend &&
     593                                    area->backend->frame_free) {
     594                                        area->backend->frame_free(area, b +
     595                                            j * PAGE_SIZE, PTE_GET_FRAME(pte));
    619596                                }
    620                                
    621                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     597                                page_mapping_remove(as, b + j * PAGE_SIZE);                             
     598                                page_table_unlock(as, false);
    622599                        }
    623600                }
    624601        }
    625        
     602
    626603        /*
    627604         * Finish TLB shootdown sequence.
    628          *
    629          */
    630        
     605         */
     606
    631607        tlb_invalidate_pages(as->asid, area->base, area->pages);
    632        
    633608        /*
    634609         * Invalidate potential software translation caches (e.g. TSB on
    635610         * sparc64).
    636          *
    637611         */
    638612        as_invalidate_translation_cache(as, area->base, area->pages);
    639613        tlb_shootdown_finalize();
    640614       
    641         page_table_unlock(as, false);
    642        
    643615        btree_destroy(&area->used_space);
    644        
     616
    645617        area->attributes |= AS_AREA_ATTR_PARTIAL;
    646618       
    647619        if (area->sh_info)
    648620                sh_info_remove_reference(area->sh_info);
    649        
     621               
    650622        mutex_unlock(&area->lock);
    651        
     623
    652624        /*
    653625         * Remove the empty area from address space.
    654          *
    655626         */
    656627        btree_remove(&as->as_area_btree, base, NULL);
     
    670641 * sh_info of the source area. The process of duplicating the
    671642 * mapping is done through the backend share function.
    672  *
    673  * @param src_as         Pointer to source address space.
    674  * @param src_base       Base address of the source address space area.
    675  * @param acc_size       Expected size of the source area.
    676  * @param dst_as         Pointer to destination address space.
    677  * @param dst_base       Target base address.
     643 * 
     644 * @param src_as        Pointer to source address space.
     645 * @param src_base      Base address of the source address space area.
     646 * @param acc_size      Expected size of the source area.
     647 * @param dst_as        Pointer to destination address space.
     648 * @param dst_base      Target base address.
    678649 * @param dst_flags_mask Destination address space area flags mask.
    679650 *
    680  * @return Zero on success.
    681  * @return ENOENT if there is no such task or such address space.
    682  * @return EPERM if there was a problem in accepting the area.
    683  * @return ENOMEM if there was a problem in allocating destination
    684  *         address space area.
    685  * @return ENOTSUP if the address space area backend does not support
    686  *         sharing.
    687  *
     651 * @return              Zero on success or ENOENT if there is no such task or if
     652 *                      there is no such address space area, EPERM if there was
     653 *                      a problem in accepting the area or ENOMEM if there was a
     654 *                      problem in allocating destination address space area.
     655 *                      ENOTSUP is returned if the address space area backend
     656 *                      does not support sharing.
    688657 */
    689658int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
    690     as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
    691 {
    692         ipl_t ipl = interrupts_disable();
     659    as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
     660{
     661        ipl_t ipl;
     662        int src_flags;
     663        size_t src_size;
     664        as_area_t *src_area, *dst_area;
     665        share_info_t *sh_info;
     666        mem_backend_t *src_backend;
     667        mem_backend_data_t src_backend_data;
     668       
     669        ipl = interrupts_disable();
    693670        mutex_lock(&src_as->lock);
    694         as_area_t *src_area = find_area_and_lock(src_as, src_base);
     671        src_area = find_area_and_lock(src_as, src_base);
    695672        if (!src_area) {
    696673                /*
    697674                 * Could not find the source address space area.
    698                  *
    699675                 */
    700676                mutex_unlock(&src_as->lock);
     
    702678                return ENOENT;
    703679        }
    704        
    705         if ((!src_area->backend) || (!src_area->backend->share)) {
     680
     681        if (!src_area->backend || !src_area->backend->share) {
    706682                /*
    707683                 * There is no backend or the backend does not
    708684                 * know how to share the area.
    709                  *
    710685                 */
    711686                mutex_unlock(&src_area->lock);
     
    715690        }
    716691       
    717         size_t src_size = src_area->pages * PAGE_SIZE;
    718         unsigned int src_flags = src_area->flags;
    719         mem_backend_t *src_backend = src_area->backend;
    720         mem_backend_data_t src_backend_data = src_area->backend_data;
    721        
     692        src_size = src_area->pages * PAGE_SIZE;
     693        src_flags = src_area->flags;
     694        src_backend = src_area->backend;
     695        src_backend_data = src_area->backend_data;
     696
    722697        /* Share the cacheable flag from the original mapping */
    723698        if (src_flags & AS_AREA_CACHEABLE)
    724699                dst_flags_mask |= AS_AREA_CACHEABLE;
    725        
    726         if ((src_size != acc_size) ||
    727             ((src_flags & dst_flags_mask) != dst_flags_mask)) {
     700
     701        if (src_size != acc_size ||
     702            (src_flags & dst_flags_mask) != dst_flags_mask) {
    728703                mutex_unlock(&src_area->lock);
    729704                mutex_unlock(&src_as->lock);
     
    731706                return EPERM;
    732707        }
    733        
     708
    734709        /*
    735710         * Now we are committed to sharing the area.
    736711         * First, prepare the area for sharing.
    737712         * Then it will be safe to unlock it.
    738          *
    739          */
    740         share_info_t *sh_info = src_area->sh_info;
     713         */
     714        sh_info = src_area->sh_info;
    741715        if (!sh_info) {
    742716                sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
     
    745719                btree_create(&sh_info->pagemap);
    746720                src_area->sh_info = sh_info;
    747                
    748721                /*
    749722                 * Call the backend to setup sharing.
    750                  *
    751723                 */
    752724                src_area->backend->share(src_area);
     
    756728                mutex_unlock(&sh_info->lock);
    757729        }
    758        
     730
    759731        mutex_unlock(&src_area->lock);
    760732        mutex_unlock(&src_as->lock);
    761        
     733
    762734        /*
    763735         * Create copy of the source address space area.
     
    767739         * The flags of the source area are masked against dst_flags_mask
    768740         * to support sharing in less privileged mode.
    769          *
    770          */
    771         as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size,
    772             dst_base, AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
     741         */
     742        dst_area = as_area_create(dst_as, dst_flags_mask, src_size, dst_base,
     743            AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
    773744        if (!dst_area) {
    774745                /*
     
    780751                return ENOMEM;
    781752        }
    782        
     753
    783754        /*
    784755         * Now the destination address space area has been
    785756         * fully initialized. Clear the AS_AREA_ATTR_PARTIAL
    786757         * attribute and set the sh_info.
    787          *
    788          */
    789         mutex_lock(&dst_as->lock);
     758         */     
     759        mutex_lock(&dst_as->lock);     
    790760        mutex_lock(&dst_area->lock);
    791761        dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
    792762        dst_area->sh_info = sh_info;
    793763        mutex_unlock(&dst_area->lock);
    794         mutex_unlock(&dst_as->lock);
    795        
     764        mutex_unlock(&dst_as->lock);   
     765
    796766        interrupts_restore(ipl);
    797767       
     
    801771/** Check access mode for address space area.
    802772 *
    803  * @param area   Address space area.
    804  * @param access Access mode.
    805  *
    806  * @return False if access violates area's permissions, true
    807  *         otherwise.
    808  *
     773 * The address space area must be locked prior to this call.
     774 *
     775 * @param area          Address space area.
     776 * @param access        Access mode.
     777 *
     778 * @return              False if access violates area's permissions, true
     779 *                      otherwise.
    809780 */
    810781bool as_area_check_access(as_area_t *area, pf_access_t access)
     
    816787        };
    817788
    818         ASSERT(interrupts_disabled());
    819         ASSERT(mutex_locked(&area->lock));
    820        
    821789        if (!(area->flags & flagmap[access]))
    822790                return false;
     
    839807 *
    840808 */
    841 int as_area_change_flags(as_t *as, unsigned int flags, uintptr_t address)
    842 {
     809int as_area_change_flags(as_t *as, int flags, uintptr_t address)
     810{
     811        as_area_t *area;
     812        link_t *cur;
     813        ipl_t ipl;
     814        int page_flags;
     815        uintptr_t *old_frame;
     816        size_t frame_idx;
     817        size_t used_pages;
     818       
    843819        /* Flags for the new memory mapping */
    844         unsigned int page_flags = area_flags_to_page_flags(flags);
    845        
    846         ipl_t ipl = interrupts_disable();
     820        page_flags = area_flags_to_page_flags(flags);
     821
     822        ipl = interrupts_disable();
    847823        mutex_lock(&as->lock);
    848        
    849         as_area_t *area = find_area_and_lock(as, address);
     824
     825        area = find_area_and_lock(as, address);
    850826        if (!area) {
    851827                mutex_unlock(&as->lock);
     
    853829                return ENOENT;
    854830        }
    855        
     831
    856832        if ((area->sh_info) || (area->backend != &anon_backend)) {
    857833                /* Copying shared areas not supported yet */
     
    862838                return ENOTSUP;
    863839        }
    864        
     840
    865841        /*
    866842         * Compute total number of used pages in the used_space B+tree
    867          *
    868          */
    869         size_t used_pages = 0;
    870         link_t *cur;
    871        
     843         */
     844        used_pages = 0;
     845
    872846        for (cur = area->used_space.leaf_head.next;
    873847            cur != &area->used_space.leaf_head; cur = cur->next) {
    874                 btree_node_t *node
    875                     = list_get_instance(cur, btree_node_t, leaf_link);
    876                 btree_key_t i;
     848                btree_node_t *node;
     849                unsigned int i;
    877850               
    878                 for (i = 0; i < node->keys; i++)
     851                node = list_get_instance(cur, btree_node_t, leaf_link);
     852                for (i = 0; i < node->keys; i++) {
    879853                        used_pages += (size_t) node->value[i];
    880         }
    881        
     854                }
     855        }
     856
    882857        /* An array for storing frame numbers */
    883         uintptr_t *old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
    884        
    885         page_table_lock(as, false);
    886        
     858        old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
     859
    887860        /*
    888861         * Start TLB shootdown sequence.
    889          *
    890862         */
    891863        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    892        
     864
    893865        /*
    894866         * Remove used pages from page tables and remember their frame
    895867         * numbers.
    896          *
    897          */
    898         size_t frame_idx = 0;
    899        
     868         */
     869        frame_idx = 0;
     870
    900871        for (cur = area->used_space.leaf_head.next;
    901872            cur != &area->used_space.leaf_head; cur = cur->next) {
    902                 btree_node_t *node
    903                     = list_get_instance(cur, btree_node_t, leaf_link);
    904                 btree_key_t i;
     873                btree_node_t *node;
     874                unsigned int i;
    905875               
     876                node = list_get_instance(cur, btree_node_t, leaf_link);
    906877                for (i = 0; i < node->keys; i++) {
    907                         uintptr_t ptr = node->key[i];
    908                         size_t size;
     878                        uintptr_t b = node->key[i];
     879                        size_t j;
     880                        pte_t *pte;
    909881                       
    910                         for (size = 0; size < (size_t) node->value[i]; size++) {
    911                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    912                                
    913                                 ASSERT(pte);
    914                                 ASSERT(PTE_VALID(pte));
    915                                 ASSERT(PTE_PRESENT(pte));
    916                                
     882                        for (j = 0; j < (size_t) node->value[i]; j++) {
     883                                page_table_lock(as, false);
     884                                pte = page_mapping_find(as, b + j * PAGE_SIZE);
     885                                ASSERT(pte && PTE_VALID(pte) &&
     886                                    PTE_PRESENT(pte));
    917887                                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
    918                                
     888
    919889                                /* Remove old mapping */
    920                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     890                                page_mapping_remove(as, b + j * PAGE_SIZE);
     891                                page_table_unlock(as, false);
    921892                        }
    922893                }
    923894        }
    924        
     895
    925896        /*
    926897         * Finish TLB shootdown sequence.
    927          *
    928          */
    929        
     898         */
     899
    930900        tlb_invalidate_pages(as->asid, area->base, area->pages);
    931901       
     
    933903         * Invalidate potential software translation caches (e.g. TSB on
    934904         * sparc64).
    935          *
    936905         */
    937906        as_invalidate_translation_cache(as, area->base, area->pages);
    938907        tlb_shootdown_finalize();
    939        
    940         page_table_unlock(as, false);
    941        
     908
    942909        /*
    943910         * Set the new flags.
    944911         */
    945912        area->flags = flags;
    946        
     913
    947914        /*
    948915         * Map pages back in with new flags. This step is kept separate
     
    951918         */
    952919        frame_idx = 0;
    953        
     920
    954921        for (cur = area->used_space.leaf_head.next;
    955922            cur != &area->used_space.leaf_head; cur = cur->next) {
    956                 btree_node_t *node
    957                     = list_get_instance(cur, btree_node_t, leaf_link);
    958                 btree_key_t i;
     923                btree_node_t *node;
     924                unsigned int i;
    959925               
     926                node = list_get_instance(cur, btree_node_t, leaf_link);
    960927                for (i = 0; i < node->keys; i++) {
    961                         uintptr_t ptr = node->key[i];
    962                         size_t size;
     928                        uintptr_t b = node->key[i];
     929                        size_t j;
    963930                       
    964                         for (size = 0; size < (size_t) node->value[i]; size++) {
     931                        for (j = 0; j < (size_t) node->value[i]; j++) {
    965932                                page_table_lock(as, false);
    966                                
     933
    967934                                /* Insert the new mapping */
    968                                 page_mapping_insert(as, ptr + size * PAGE_SIZE,
     935                                page_mapping_insert(as, b + j * PAGE_SIZE,
    969936                                    old_frame[frame_idx++], page_flags);
    970                                
     937
    971938                                page_table_unlock(as, false);
    972939                        }
    973940                }
    974941        }
    975        
     942
    976943        free(old_frame);
    977        
     944
    978945        mutex_unlock(&area->lock);
    979946        mutex_unlock(&as->lock);
    980947        interrupts_restore(ipl);
    981        
     948
    982949        return 0;
    983950}
     951
    984952
    985953/** Handle page fault within the current address space.
     
    991959 * Interrupts are assumed disabled.
    992960 *
    993  * @param page   Faulting page.
    994  * @param access Access mode that caused the page fault (i.e.
    995  *               read/write/exec).
    996  * @param istate Pointer to the interrupted state.
    997  *
    998  * @return AS_PF_FAULT on page fault.
    999  * @return AS_PF_OK on success.
    1000  * @return AS_PF_DEFER if the fault was caused by copy_to_uspace()
    1001  *         or copy_from_uspace().
    1002  *
     961 * @param page          Faulting page.
     962 * @param access        Access mode that caused the page fault (i.e.
     963 *                      read/write/exec).
     964 * @param istate        Pointer to the interrupted state.
     965 *
     966 * @return              AS_PF_FAULT on page fault, AS_PF_OK on success or
     967 *                      AS_PF_DEFER if the fault was caused by copy_to_uspace()
     968 *                      or copy_from_uspace().
    1003969 */
    1004970int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
    1005971{
     972        pte_t *pte;
     973        as_area_t *area;
     974       
    1006975        if (!THREAD)
    1007976                return AS_PF_FAULT;
     
    1011980       
    1012981        mutex_lock(&AS->lock);
    1013         as_area_t *area = find_area_and_lock(AS, page);
     982        area = find_area_and_lock(AS, page);
    1014983        if (!area) {
    1015984                /*
    1016985                 * No area contained mapping for 'page'.
    1017986                 * Signal page fault to low-level handler.
    1018                  *
    1019987                 */
    1020988                mutex_unlock(&AS->lock);
    1021989                goto page_fault;
    1022990        }
    1023        
     991
    1024992        if (area->attributes & AS_AREA_ATTR_PARTIAL) {
    1025993                /*
     
    1029997                mutex_unlock(&area->lock);
    1030998                mutex_unlock(&AS->lock);
    1031                 goto page_fault;
    1032         }
    1033        
    1034         if ((!area->backend) || (!area->backend->page_fault)) {
     999                goto page_fault;               
     1000        }
     1001
     1002        if (!area->backend || !area->backend->page_fault) {
    10351003                /*
    10361004                 * The address space area is not backed by any backend
    10371005                 * or the backend cannot handle page faults.
    1038                  *
    10391006                 */
    10401007                mutex_unlock(&area->lock);
    10411008                mutex_unlock(&AS->lock);
    1042                 goto page_fault;
    1043         }
    1044        
     1009                goto page_fault;               
     1010        }
     1011
    10451012        page_table_lock(AS, false);
    10461013       
     
    10481015         * To avoid race condition between two page faults on the same address,
    10491016         * we need to make sure the mapping has not been already inserted.
    1050          *
    1051          */
    1052         pte_t *pte;
     1017         */
    10531018        if ((pte = page_mapping_find(AS, page))) {
    10541019                if (PTE_PRESENT(pte)) {
     
    10661031        /*
    10671032         * Resort to the backend page fault handler.
    1068          *
    10691033         */
    10701034        if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
     
    10791043        mutex_unlock(&AS->lock);
    10801044        return AS_PF_OK;
    1081        
     1045
    10821046page_fault:
    10831047        if (THREAD->in_copy_from_uspace) {
     
    10921056                return AS_PF_FAULT;
    10931057        }
    1094        
     1058
    10951059        return AS_PF_DEFER;
    10961060}
     
    11041068 * When this function is enetered, no spinlocks may be held.
    11051069 *
    1106  * @param old Old address space or NULL.
    1107  * @param new New address space.
    1108  *
     1070 * @param old           Old address space or NULL.
     1071 * @param new           New address space.
    11091072 */
    11101073void as_switch(as_t *old_as, as_t *new_as)
     
    11121075        DEADLOCK_PROBE_INIT(p_asidlock);
    11131076        preemption_disable();
    1114        
    11151077retry:
    11161078        (void) interrupts_disable();
    11171079        if (!spinlock_trylock(&asidlock)) {
    1118                 /*
     1080                /* 
    11191081                 * Avoid deadlock with TLB shootdown.
    11201082                 * We can enable interrupts here because
    11211083                 * preemption is disabled. We should not be
    11221084                 * holding any other lock.
    1123                  *
    11241085                 */
    11251086                (void) interrupts_enable();
     
    11281089        }
    11291090        preemption_enable();
    1130        
     1091
    11311092        /*
    11321093         * First, take care of the old address space.
    1133          */
     1094         */     
    11341095        if (old_as) {
    11351096                ASSERT(old_as->cpu_refcount);
    1136                
    1137                 if ((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
     1097                if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
    11381098                        /*
    11391099                         * The old address space is no longer active on
     
    11411101                         * list of inactive address spaces with assigned
    11421102                         * ASID.
    1143                          *
    11441103                         */
    11451104                        ASSERT(old_as->asid != ASID_INVALID);
    1146                        
    11471105                        list_append(&old_as->inactive_as_with_asid_link,
    11481106                            &inactive_as_with_asid_head);
    11491107                }
    1150                
     1108
    11511109                /*
    11521110                 * Perform architecture-specific tasks when the address space
    11531111                 * is being removed from the CPU.
    1154                  *
    11551112                 */
    11561113                as_deinstall_arch(old_as);
    11571114        }
    1158        
     1115
    11591116        /*
    11601117         * Second, prepare the new address space.
    1161          *
    11621118         */
    11631119        if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
     
    11671123                        new_as->asid = asid_get();
    11681124        }
    1169        
    11701125#ifdef AS_PAGE_TABLE
    11711126        SET_PTL0_ADDRESS(new_as->genarch.page_table);
     
    11751130         * Perform architecture-specific steps.
    11761131         * (e.g. write ASID to hardware register etc.)
    1177          *
    11781132         */
    11791133        as_install_arch(new_as);
    1180        
     1134
    11811135        spinlock_unlock(&asidlock);
    11821136       
     
    11861140/** Convert address space area flags to page flags.
    11871141 *
    1188  * @param aflags Flags of some address space area.
    1189  *
    1190  * @return Flags to be passed to page_mapping_insert().
    1191  *
    1192  */
    1193 unsigned int area_flags_to_page_flags(unsigned int aflags)
    1194 {
    1195         unsigned int flags = PAGE_USER | PAGE_PRESENT;
     1142 * @param aflags        Flags of some address space area.
     1143 *
     1144 * @return              Flags to be passed to page_mapping_insert().
     1145 */
     1146int area_flags_to_page_flags(int aflags)
     1147{
     1148        int flags;
     1149
     1150        flags = PAGE_USER | PAGE_PRESENT;
    11961151       
    11971152        if (aflags & AS_AREA_READ)
     
    12061161        if (aflags & AS_AREA_CACHEABLE)
    12071162                flags |= PAGE_CACHEABLE;
    1208        
     1163               
    12091164        return flags;
    12101165}
     
    12121167/** Compute flags for virtual address translation subsytem.
    12131168 *
    1214  * @param area Address space area.
    1215  *
    1216  * @return Flags to be used in page_mapping_insert().
    1217  *
    1218  */
    1219 unsigned int as_area_get_flags(as_area_t *area)
    1220 {
    1221         ASSERT(interrupts_disabled());
    1222         ASSERT(mutex_locked(&area->lock));
    1223 
    1224         return area_flags_to_page_flags(area->flags);
     1169 * The address space area must be locked.
     1170 * Interrupts must be disabled.
     1171 *
     1172 * @param a             Address space area.
     1173 *
     1174 * @return              Flags to be used in page_mapping_insert().
     1175 */
     1176int as_area_get_flags(as_area_t *a)
     1177{
     1178        return area_flags_to_page_flags(a->flags);
    12251179}
    12261180
     
    12301184 * table.
    12311185 *
    1232  * @param flags Flags saying whether the page table is for the kernel
    1233  *              address space.
    1234  *
    1235  * @return First entry of the page table.
    1236  *
    1237  */
    1238 pte_t *page_table_create(unsigned int flags)
     1186 * @param flags         Flags saying whether the page table is for the kernel
     1187 *                      address space.
     1188 *
     1189 * @return              First entry of the page table.
     1190 */
     1191pte_t *page_table_create(int flags)
    12391192{
    12401193        ASSERT(as_operations);
     
    12481201 * Destroy page table in architecture specific way.
    12491202 *
    1250  * @param page_table Physical address of PTL0.
    1251  *
     1203 * @param page_table    Physical address of PTL0.
    12521204 */
    12531205void page_table_destroy(pte_t *page_table)
     
    12631215 * This function should be called before any page_mapping_insert(),
    12641216 * page_mapping_remove() and page_mapping_find().
    1265  *
     1217 * 
    12661218 * Locking order is such that address space areas must be locked
    12671219 * prior to this call. Address space can be locked prior to this
    12681220 * call in which case the lock argument is false.
    12691221 *
    1270  * @param as   Address space.
    1271  * @param lock If false, do not attempt to lock as->lock.
    1272  *
     1222 * @param as            Address space.
     1223 * @param lock          If false, do not attempt to lock as->lock.
    12731224 */
    12741225void page_table_lock(as_t *as, bool lock)
     
    12821233/** Unlock page table.
    12831234 *
    1284  * @param as     Address space.
    1285  * @param unlock If false, do not attempt to unlock as->lock.
    1286  *
     1235 * @param as            Address space.
     1236 * @param unlock        If false, do not attempt to unlock as->lock.
    12871237 */
    12881238void page_table_unlock(as_t *as, bool unlock)
     
    12941244}
    12951245
    1296 /** Test whether page tables are locked.
    1297  *
    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  */
    1303 bool page_table_locked(as_t *as)
    1304 {
    1305         ASSERT(as_operations);
    1306         ASSERT(as_operations->page_table_locked);
    1307 
    1308         return as_operations->page_table_locked(as);
    1309 }
    1310 
    13111246
    13121247/** Find address space area and lock it.
    13131248 *
    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  *
     1249 * The address space must be locked and interrupts must be disabled.
     1250 *
     1251 * @param as            Address space.
     1252 * @param va            Virtual address.
     1253 *
     1254 * @return              Locked address space area containing va on success or
     1255 *                      NULL on failure.
    13201256 */
    13211257as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
    13221258{
    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) {
     1259        as_area_t *a;
     1260        btree_node_t *leaf, *lnode;
     1261        unsigned int i;
     1262       
     1263        a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     1264        if (a) {
    13291265                /* va is the base address of an address space area */
    1330                 mutex_lock(&area->lock);
    1331                 return area;
     1266                mutex_lock(&a->lock);
     1267                return a;
    13321268        }
    13331269       
     
    13361272         * to find out whether this is a miss or va belongs to an address
    13371273         * space area found there.
    1338          *
    13391274         */
    13401275       
    13411276        /* First, search the leaf node itself. */
    1342         btree_key_t i;
    1343        
    13441277        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        
     1278                a = (as_area_t *) leaf->value[i];
     1279                mutex_lock(&a->lock);
     1280                if ((a->base <= va) && (va < a->base + a->pages * PAGE_SIZE)) {
     1281                        return a;
     1282                }
     1283                mutex_unlock(&a->lock);
     1284        }
     1285
    13551286        /*
    13561287         * Second, locate the left neighbour and test its last record.
    13571288         * 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);
     1289         */
     1290        lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    13611291        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        
     1292                a = (as_area_t *) lnode->value[lnode->keys - 1];
     1293                mutex_lock(&a->lock);
     1294                if (va < a->base + a->pages * PAGE_SIZE) {
     1295                        return a;
     1296                }
     1297                mutex_unlock(&a->lock);
     1298        }
     1299
    13721300        return NULL;
    13731301}
     
    13751303/** Check area conflicts with other areas.
    13761304 *
    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  */
    1385 bool 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 
     1305 * The address space must be locked and interrupts must be disabled.
     1306 *
     1307 * @param as            Address space.
     1308 * @param va            Starting virtual address of the area being tested.
     1309 * @param size          Size of the area being tested.
     1310 * @param avoid_area    Do not touch this area.
     1311 *
     1312 * @return              True if there is no conflict, false otherwise.
     1313 */
     1314bool
     1315check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area)
     1316{
     1317        as_area_t *a;
     1318        btree_node_t *leaf, *node;
     1319        unsigned int i;
     1320       
    13911321        /*
    13921322         * We don't want any area to have conflicts with NULL page.
    1393          *
    13941323         */
    13951324        if (overlaps(va, size, NULL, PAGE_SIZE))
     
    14021331         * record in the left neighbour, the leftmost record in the right
    14031332         * 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)
     1333         */
     1334       
     1335        if ((a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf))) {
     1336                if (a != avoid_area)
    14111337                        return false;
    14121338        }
    14131339       
    14141340        /* 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);
     1341        if ((node = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
     1342                a = (as_area_t *) node->value[node->keys - 1];
     1343                mutex_lock(&a->lock);
     1344                if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
     1345                        mutex_unlock(&a->lock);
    14241346                        return false;
    14251347                }
    1426                
    1427                 mutex_unlock(&area->lock);
    1428         }
    1429        
     1348                mutex_unlock(&a->lock);
     1349        }
    14301350        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    14311351        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);
     1352                a = (as_area_t *) node->value[0];
     1353                mutex_lock(&a->lock);
     1354                if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
     1355                        mutex_unlock(&a->lock);
    14381356                        return false;
    14391357                }
    1440                
    1441                 mutex_unlock(&area->lock);
     1358                mutex_unlock(&a->lock);
    14421359        }
    14431360       
    14441361        /* Second, check the leaf node. */
    1445         btree_key_t i;
    14461362        for (i = 0; i < leaf->keys; i++) {
    1447                 area = (as_area_t *) leaf->value[i];
    1448                
    1449                 if (area == avoid_area)
     1363                a = (as_area_t *) leaf->value[i];
     1364       
     1365                if (a == avoid_area)
    14501366                        continue;
    1451                
    1452                 mutex_lock(&area->lock);
    1453                
    1454                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    1455                         mutex_unlock(&area->lock);
     1367       
     1368                mutex_lock(&a->lock);
     1369                if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
     1370                        mutex_unlock(&a->lock);
    14561371                        return false;
    14571372                }
    1458                
    1459                 mutex_unlock(&area->lock);
    1460         }
    1461        
     1373                mutex_unlock(&a->lock);
     1374        }
     1375
    14621376        /*
    14631377         * So far, the area does not conflict with other areas.
    14641378         * Check if it doesn't conflict with kernel address space.
    1465          *
    1466          */
     1379         */     
    14671380        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    1468                 return !overlaps(va, size,
     1381                return !overlaps(va, size, 
    14691382                    KERNEL_ADDRESS_SPACE_START,
    14701383                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    14711384        }
    1472        
     1385
    14731386        return true;
    14741387}
     
    14761389/** Return size of the address space area with given base.
    14771390 *
    1478  * @param base Arbitrary address inside the address space area.
    1479  *
    1480  * @return Size of the address space area in bytes or zero if it
    1481  *         does not exist.
    1482  *
     1391 * @param base          Arbitrary address insede the address space area.
     1392 *
     1393 * @return              Size of the address space area in bytes or zero if it
     1394 *                      does not exist.
    14831395 */
    14841396size_t as_area_get_size(uintptr_t base)
    14851397{
     1398        ipl_t ipl;
     1399        as_area_t *src_area;
    14861400        size_t size;
    1487        
    1488         ipl_t ipl = interrupts_disable();
    1489         page_table_lock(AS, true);
    1490         as_area_t *src_area = find_area_and_lock(AS, base);
    1491        
     1401
     1402        ipl = interrupts_disable();
     1403        src_area = find_area_and_lock(AS, base);
    14921404        if (src_area) {
    14931405                size = src_area->pages * PAGE_SIZE;
    14941406                mutex_unlock(&src_area->lock);
    1495         } else
     1407        } else {
    14961408                size = 0;
    1497        
    1498         page_table_unlock(AS, true);
     1409        }
    14991410        interrupts_restore(ipl);
    15001411        return size;
     
    15051416 * The address space area must be already locked.
    15061417 *
    1507  * @param area  Address space area.
    1508  * @param page  First page to be marked.
    1509  * @param count Number of page to be marked.
    1510  *
    1511  * @return Zero on failure and non-zero on success.
    1512  *
    1513  */
    1514 int used_space_insert(as_area_t *area, uintptr_t page, size_t count)
    1515 {
    1516         ASSERT(mutex_locked(&area->lock));
     1418 * @param a             Address space area.
     1419 * @param page          First page to be marked.
     1420 * @param count         Number of page to be marked.
     1421 *
     1422 * @return              Zero on failure and non-zero on success.
     1423 */
     1424int used_space_insert(as_area_t *a, uintptr_t page, size_t count)
     1425{
     1426        btree_node_t *leaf, *node;
     1427        size_t pages;
     1428        unsigned int i;
     1429
    15171430        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    15181431        ASSERT(count);
    1519        
    1520         btree_node_t *leaf;
    1521         size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
     1432
     1433        pages = (size_t) btree_search(&a->used_space, page, &leaf);
    15221434        if (pages) {
    15231435                /*
    15241436                 * We hit the beginning of some used space.
    1525                  *
    15261437                 */
    15271438                return 0;
    15281439        }
    1529        
     1440
    15301441        if (!leaf->keys) {
    1531                 btree_insert(&area->used_space, page, (void *) count, leaf);
     1442                btree_insert(&a->used_space, page, (void *) count, leaf);
    15321443                return 1;
    15331444        }
    1534        
    1535         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     1445
     1446        node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
    15361447        if (node) {
    15371448                uintptr_t left_pg = node->key[node->keys - 1];
     
    15441455                 * somewhere between the rightmost interval of
    15451456                 * the left neigbour and the first interval of the leaf.
    1546                  *
    1547                  */
    1548                
     1457                 */
     1458                 
    15491459                if (page >= right_pg) {
    15501460                        /* Do nothing. */
     
    15561466                    right_cnt * PAGE_SIZE)) {
    15571467                        /* The interval intersects with the right interval. */
    1558                         return 0;
     1468                        return 0;                       
    15591469                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    15601470                    (page + count * PAGE_SIZE == right_pg)) {
     
    15621472                         * The interval can be added by merging the two already
    15631473                         * present intervals.
    1564                          *
    15651474                         */
    15661475                        node->value[node->keys - 1] += count + right_cnt;
    1567                         btree_remove(&area->used_space, right_pg, leaf);
    1568                         return 1;
     1476                        btree_remove(&a->used_space, right_pg, leaf);
     1477                        return 1; 
    15691478                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    1570                         /*
     1479                        /* 
    15711480                         * The interval can be added by simply growing the left
    15721481                         * interval.
    1573                          *
    15741482                         */
    15751483                        node->value[node->keys - 1] += count;
     
    15801488                         * the right interval down and increasing its size
    15811489                         * accordingly.
    1582                          *
    15831490                         */
    15841491                        leaf->value[0] += count;
     
    15891496                         * The interval is between both neigbouring intervals,
    15901497                         * but cannot be merged with any of them.
    1591                          *
    15921498                         */
    1593                         btree_insert(&area->used_space, page, (void *) count,
     1499                        btree_insert(&a->used_space, page, (void *) count,
    15941500                            leaf);
    15951501                        return 1;
     
    15981504                uintptr_t right_pg = leaf->key[0];
    15991505                size_t right_cnt = (size_t) leaf->value[0];
    1600                
     1506       
    16011507                /*
    16021508                 * Investigate the border case in which the left neighbour does
    16031509                 * not exist but the interval fits from the left.
    1604                  *
    1605                  */
    1606                
     1510                 */
     1511                 
    16071512                if (overlaps(page, count * PAGE_SIZE, right_pg,
    16081513                    right_cnt * PAGE_SIZE)) {
     
    16141519                         * right interval down and increasing its size
    16151520                         * accordingly.
    1616                          *
    16171521                         */
    16181522                        leaf->key[0] = page;
     
    16231527                         * The interval doesn't adjoin with the right interval.
    16241528                         * It must be added individually.
    1625                          *
    16261529                         */
    1627                         btree_insert(&area->used_space, page, (void *) count,
     1530                        btree_insert(&a->used_space, page, (void *) count,
    16281531                            leaf);
    16291532                        return 1;
    16301533                }
    16311534        }
    1632        
    1633         node = btree_leaf_node_right_neighbour(&area->used_space, leaf);
     1535
     1536        node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
    16341537        if (node) {
    16351538                uintptr_t left_pg = leaf->key[leaf->keys - 1];
     
    16421545                 * somewhere between the leftmost interval of
    16431546                 * the right neigbour and the last interval of the leaf.
    1644                  *
    1645                  */
    1646                
     1547                 */
     1548
    16471549                if (page < left_pg) {
    16481550                        /* Do nothing. */
     
    16541556                    right_cnt * PAGE_SIZE)) {
    16551557                        /* The interval intersects with the right interval. */
    1656                         return 0;
     1558                        return 0;                       
    16571559                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    16581560                    (page + count * PAGE_SIZE == right_pg)) {
     
    16601562                         * The interval can be added by merging the two already
    16611563                         * present intervals.
    1662                          *
    1663                          */
     1564                         * */
    16641565                        leaf->value[leaf->keys - 1] += count + right_cnt;
    1665                         btree_remove(&area->used_space, right_pg, node);
    1666                         return 1;
     1566                        btree_remove(&a->used_space, right_pg, node);
     1567                        return 1; 
    16671568                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    16681569                        /*
    16691570                         * The interval can be added by simply growing the left
    16701571                         * interval.
    1671                          *
    1672                          */
     1572                         * */
    16731573                        leaf->value[leaf->keys - 1] +=  count;
    16741574                        return 1;
     
    16781578                         * the right interval down and increasing its size
    16791579                         * accordingly.
    1680                          *
    16811580                         */
    16821581                        node->value[0] += count;
     
    16871586                         * The interval is between both neigbouring intervals,
    16881587                         * but cannot be merged with any of them.
    1689                          *
    16901588                         */
    1691                         btree_insert(&area->used_space, page, (void *) count,
     1589                        btree_insert(&a->used_space, page, (void *) count,
    16921590                            leaf);
    16931591                        return 1;
     
    16961594                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    16971595                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    1698                
     1596       
    16991597                /*
    17001598                 * Investigate the border case in which the right neighbour
    17011599                 * does not exist but the interval fits from the right.
    1702                  *
    1703                  */
    1704                
     1600                 */
     1601                 
    17051602                if (overlaps(page, count * PAGE_SIZE, left_pg,
    17061603                    left_cnt * PAGE_SIZE)) {
     
    17111608                         * The interval can be added by growing the left
    17121609                         * interval.
    1713                          *
    17141610                         */
    17151611                        leaf->value[leaf->keys - 1] += count;
     
    17191615                         * The interval doesn't adjoin with the left interval.
    17201616                         * It must be added individually.
    1721                          *
    17221617                         */
    1723                         btree_insert(&area->used_space, page, (void *) count,
     1618                        btree_insert(&a->used_space, page, (void *) count,
    17241619                            leaf);
    17251620                        return 1;
     
    17311626         * only between two other intervals of the leaf. The two border cases
    17321627         * were already resolved.
    1733          *
    1734          */
    1735         btree_key_t i;
     1628         */
    17361629        for (i = 1; i < leaf->keys; i++) {
    17371630                if (page < leaf->key[i]) {
     
    17401633                        size_t left_cnt = (size_t) leaf->value[i - 1];
    17411634                        size_t right_cnt = (size_t) leaf->value[i];
    1742                        
     1635
    17431636                        /*
    17441637                         * The interval fits between left_pg and right_pg.
    1745                          *
    17461638                         */
    1747                        
     1639
    17481640                        if (overlaps(page, count * PAGE_SIZE, left_pg,
    17491641                            left_cnt * PAGE_SIZE)) {
     
    17511643                                 * The interval intersects with the left
    17521644                                 * interval.
    1753                                  *
    17541645                                 */
    17551646                                return 0;
     
    17591650                                 * The interval intersects with the right
    17601651                                 * interval.
    1761                                  *
    17621652                                 */
    1763                                 return 0;
     1653                                return 0;                       
    17641654                        } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    17651655                            (page + count * PAGE_SIZE == right_pg)) {
     
    17671657                                 * The interval can be added by merging the two
    17681658                                 * already present intervals.
    1769                                  *
    17701659                                 */
    17711660                                leaf->value[i - 1] += count + right_cnt;
    1772                                 btree_remove(&area->used_space, right_pg, leaf);
    1773                                 return 1;
     1661                                btree_remove(&a->used_space, right_pg, leaf);
     1662                                return 1; 
    17741663                        } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    17751664                                /*
    17761665                                 * The interval can be added by simply growing
    17771666                                 * the left interval.
    1778                                  *
    17791667                                 */
    17801668                                leaf->value[i - 1] += count;
     
    17821670                        } else if (page + count * PAGE_SIZE == right_pg) {
    17831671                                /*
    1784                                 * The interval can be addded by simply moving
     1672                                * The interval can be addded by simply moving
    17851673                                 * base of the right interval down and
    17861674                                 * increasing its size accordingly.
    1787                                  *
    1788                                  */
     1675                                 */
    17891676                                leaf->value[i] += count;
    17901677                                leaf->key[i] = page;
     
    17951682                                 * intervals, but cannot be merged with any of
    17961683                                 * them.
    1797                                  *
    17981684                                 */
    1799                                 btree_insert(&area->used_space, page,
     1685                                btree_insert(&a->used_space, page,
    18001686                                    (void *) count, leaf);
    18011687                                return 1;
     
    18031689                }
    18041690        }
    1805        
     1691
    18061692        panic("Inconsistency detected while adding %" PRIs " pages of used "
    18071693            "space at %p.", count, page);
     
    18121698 * The address space area must be already locked.
    18131699 *
    1814  * @param area  Address space area.
    1815  * @param page  First page to be marked.
    1816  * @param count Number of page to be marked.
    1817  *
    1818  * @return Zero on failure and non-zero on success.
    1819  *
    1820  */
    1821 int used_space_remove(as_area_t *area, uintptr_t page, size_t count)
    1822 {
    1823         ASSERT(mutex_locked(&area->lock));
     1700 * @param a             Address space area.
     1701 * @param page          First page to be marked.
     1702 * @param count         Number of page to be marked.
     1703 *
     1704 * @return              Zero on failure and non-zero on success.
     1705 */
     1706int used_space_remove(as_area_t *a, uintptr_t page, size_t count)
     1707{
     1708        btree_node_t *leaf, *node;
     1709        size_t pages;
     1710        unsigned int i;
     1711
    18241712        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    18251713        ASSERT(count);
    1826        
    1827         btree_node_t *leaf;
    1828         size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
     1714
     1715        pages = (size_t) btree_search(&a->used_space, page, &leaf);
    18291716        if (pages) {
    18301717                /*
    18311718                 * We are lucky, page is the beginning of some interval.
    1832                  *
    18331719                 */
    18341720                if (count > pages) {
    18351721                        return 0;
    18361722                } else if (count == pages) {
    1837                         btree_remove(&area->used_space, page, leaf);
     1723                        btree_remove(&a->used_space, page, leaf);
    18381724                        return 1;
    18391725                } else {
     
    18411727                         * Find the respective interval.
    18421728                         * Decrease its size and relocate its start address.
    1843                          *
    18441729                         */
    1845                         btree_key_t i;
    18461730                        for (i = 0; i < leaf->keys; i++) {
    18471731                                if (leaf->key[i] == page) {
     
    18541738                }
    18551739        }
    1856        
    1857         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
    1858         if ((node) && (page < leaf->key[0])) {
     1740
     1741        node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
     1742        if (node && page < leaf->key[0]) {
    18591743                uintptr_t left_pg = node->key[node->keys - 1];
    18601744                size_t left_cnt = (size_t) node->value[node->keys - 1];
    1861                
     1745
    18621746                if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    18631747                    count * PAGE_SIZE)) {
     
    18691753                                 * removed by updating the size of the bigger
    18701754                                 * interval.
    1871                                  *
    18721755                                 */
    18731756                                node->value[node->keys - 1] -= count;
     
    18751758                        } else if (page + count * PAGE_SIZE <
    18761759                            left_pg + left_cnt*PAGE_SIZE) {
     1760                                size_t new_cnt;
     1761                               
    18771762                                /*
    18781763                                 * The interval is contained in the rightmost
     
    18811766                                 * the original interval and also inserting a
    18821767                                 * new interval.
    1883                                  *
    18841768                                 */
    1885                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1769                                new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    18861770                                    (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
    18871771                                node->value[node->keys - 1] -= count + new_cnt;
    1888                                 btree_insert(&area->used_space, page +
     1772                                btree_insert(&a->used_space, page +
    18891773                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18901774                                return 1;
     
    18921776                }
    18931777                return 0;
    1894         } else if (page < leaf->key[0])
     1778        } else if (page < leaf->key[0]) {
    18951779                return 0;
     1780        }
    18961781       
    18971782        if (page > leaf->key[leaf->keys - 1]) {
    18981783                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    18991784                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    1900                
     1785
    19011786                if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    19021787                    count * PAGE_SIZE)) {
    1903                         if (page + count * PAGE_SIZE ==
     1788                        if (page + count * PAGE_SIZE == 
    19041789                            left_pg + left_cnt * PAGE_SIZE) {
    19051790                                /*
     
    19071792                                 * interval of the leaf and can be removed by
    19081793                                 * updating the size of the bigger interval.
    1909                                  *
    19101794                                 */
    19111795                                leaf->value[leaf->keys - 1] -= count;
     
    19131797                        } else if (page + count * PAGE_SIZE < left_pg +
    19141798                            left_cnt * PAGE_SIZE) {
     1799                                size_t new_cnt;
     1800                               
    19151801                                /*
    19161802                                 * The interval is contained in the rightmost
     
    19191805                                 * original interval and also inserting a new
    19201806                                 * interval.
    1921                                  *
    19221807                                 */
    1923                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1808                                new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    19241809                                    (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
    19251810                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    1926                                 btree_insert(&area->used_space, page +
     1811                                btree_insert(&a->used_space, page +
    19271812                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    19281813                                return 1;
     
    19301815                }
    19311816                return 0;
    1932         }
     1817        }       
    19331818       
    19341819        /*
     
    19361821         * Now the interval can be only between intervals of the leaf.
    19371822         */
    1938         btree_key_t i;
    19391823        for (i = 1; i < leaf->keys - 1; i++) {
    19401824                if (page < leaf->key[i]) {
    19411825                        uintptr_t left_pg = leaf->key[i - 1];
    19421826                        size_t left_cnt = (size_t) leaf->value[i - 1];
    1943                        
     1827
    19441828                        /*
    19451829                         * Now the interval is between intervals corresponding
     
    19551839                                         * be removed by updating the size of
    19561840                                         * the bigger interval.
    1957                                          *
    19581841                                         */
    19591842                                        leaf->value[i - 1] -= count;
     
    19611844                                } else if (page + count * PAGE_SIZE <
    19621845                                    left_pg + left_cnt * PAGE_SIZE) {
     1846                                        size_t new_cnt;
     1847                               
    19631848                                        /*
    19641849                                         * The interval is contained in the
     
    19681853                                         * also inserting a new interval.
    19691854                                         */
    1970                                         size_t new_cnt = ((left_pg +
     1855                                        new_cnt = ((left_pg +
    19711856                                            left_cnt * PAGE_SIZE) -
    19721857                                            (page + count * PAGE_SIZE)) >>
    19731858                                            PAGE_WIDTH;
    19741859                                        leaf->value[i - 1] -= count + new_cnt;
    1975                                         btree_insert(&area->used_space, page +
     1860                                        btree_insert(&a->used_space, page +
    19761861                                            count * PAGE_SIZE, (void *) new_cnt,
    19771862                                            leaf);
     
    19821867                }
    19831868        }
    1984        
     1869
    19851870error:
    19861871        panic("Inconsistency detected while removing %" PRIs " pages of used "
     
    19921877 * If the reference count drops to 0, the sh_info is deallocated.
    19931878 *
    1994  * @param sh_info Pointer to address space area share info.
    1995  *
     1879 * @param sh_info       Pointer to address space area share info.
    19961880 */
    19971881void sh_info_remove_reference(share_info_t *sh_info)
    19981882{
    19991883        bool dealloc = false;
    2000        
     1884
    20011885        mutex_lock(&sh_info->lock);
    20021886        ASSERT(sh_info->refcount);
    2003        
    20041887        if (--sh_info->refcount == 0) {
    20051888                dealloc = true;
     
    20121895                for (cur = sh_info->pagemap.leaf_head.next;
    20131896                    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;
     1897                        btree_node_t *node;
     1898                        unsigned int i;
    20171899                       
    2018                         for (i = 0; i < node->keys; i++)
     1900                        node = list_get_instance(cur, btree_node_t, leaf_link);
     1901                        for (i = 0; i < node->keys; i++)
    20191902                                frame_free((uintptr_t) node->value[i]);
    20201903                }
     
    20341917
    20351918/** Wrapper for as_area_create(). */
    2036 unative_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
     1919unative_t sys_as_area_create(uintptr_t address, size_t size, int flags)
    20371920{
    20381921        if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
     
    20441927
    20451928/** Wrapper for as_area_resize(). */
    2046 unative_t sys_as_area_resize(uintptr_t address, size_t size, unsigned int flags)
     1929unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
    20471930{
    20481931        return (unative_t) as_area_resize(AS, address, size, 0);
     
    20501933
    20511934/** Wrapper for as_area_change_flags(). */
    2052 unative_t sys_as_area_change_flags(uintptr_t address, unsigned int flags)
     1935unative_t sys_as_area_change_flags(uintptr_t address, int flags)
    20531936{
    20541937        return (unative_t) as_area_change_flags(AS, flags, address);
     
    20631946/** Get list of adress space areas.
    20641947 *
    2065  * @param as    Address space.
    2066  * @param obuf  Place to save pointer to returned buffer.
    2067  * @param osize Place to save size of returned buffer.
    2068  *
     1948 * @param as            Address space.
     1949 * @param obuf          Place to save pointer to returned buffer.
     1950 * @param osize         Place to save size of returned buffer.
    20691951 */
    20701952void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
    20711953{
    2072         ipl_t ipl = interrupts_disable();
     1954        ipl_t ipl;
     1955        size_t area_cnt, area_idx, i;
     1956        link_t *cur;
     1957
     1958        as_area_info_t *info;
     1959        size_t isize;
     1960
     1961        ipl = interrupts_disable();
    20731962        mutex_lock(&as->lock);
    2074        
     1963
    20751964        /* First pass, count number of areas. */
    2076        
    2077         size_t area_cnt = 0;
    2078         link_t *cur;
    2079        
     1965
     1966        area_cnt = 0;
     1967
    20801968        for (cur = as->as_area_btree.leaf_head.next;
    20811969            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    2082                 btree_node_t *node =
    2083                     list_get_instance(cur, btree_node_t, leaf_link);
     1970                btree_node_t *node;
     1971
     1972                node = list_get_instance(cur, btree_node_t, leaf_link);
    20841973                area_cnt += node->keys;
    20851974        }
    2086        
    2087         size_t isize = area_cnt * sizeof(as_area_info_t);
    2088         as_area_info_t *info = malloc(isize, 0);
    2089        
     1975
     1976        isize = area_cnt * sizeof(as_area_info_t);
     1977        info = malloc(isize, 0);
     1978
    20901979        /* Second pass, record data. */
    2091        
    2092         size_t area_idx = 0;
    2093        
     1980
     1981        area_idx = 0;
     1982
    20941983        for (cur = as->as_area_btree.leaf_head.next;
    20951984            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    2096                 btree_node_t *node =
    2097                     list_get_instance(cur, btree_node_t, leaf_link);
    2098                 btree_key_t i;
    2099                
     1985                btree_node_t *node;
     1986
     1987                node = list_get_instance(cur, btree_node_t, leaf_link);
     1988
    21001989                for (i = 0; i < node->keys; i++) {
    21011990                        as_area_t *area = node->value[i];
    2102                        
     1991
    21031992                        ASSERT(area_idx < area_cnt);
    21041993                        mutex_lock(&area->lock);
    2105                        
     1994
    21061995                        info[area_idx].start_addr = area->base;
    21071996                        info[area_idx].size = FRAMES2SIZE(area->pages);
    21081997                        info[area_idx].flags = area->flags;
    21091998                        ++area_idx;
    2110                        
     1999
    21112000                        mutex_unlock(&area->lock);
    21122001                }
    21132002        }
    2114        
     2003
    21152004        mutex_unlock(&as->lock);
    21162005        interrupts_restore(ipl);
    2117        
     2006
    21182007        *obuf = info;
    21192008        *osize = isize;
    21202009}
    21212010
     2011
    21222012/** Print out information about address space.
    21232013 *
    2124  * @param as Address space.
    2125  *
     2014 * @param as            Address space.
    21262015 */
    21272016void as_print(as_t *as)
    21282017{
    2129         ipl_t ipl = interrupts_disable();
     2018        ipl_t ipl;
     2019       
     2020        ipl = interrupts_disable();
    21302021        mutex_lock(&as->lock);
    21312022       
     
    21342025        for (cur = as->as_area_btree.leaf_head.next;
    21352026            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    2136                 btree_node_t *node
    2137                     = list_get_instance(cur, btree_node_t, leaf_link);
    2138                 btree_key_t i;
     2027                btree_node_t *node;
    21392028               
     2029                node = list_get_instance(cur, btree_node_t, leaf_link);
     2030               
     2031                unsigned int i;
    21402032                for (i = 0; i < node->keys; i++) {
    21412033                        as_area_t *area = node->value[i];
    2142                        
     2034               
    21432035                        mutex_lock(&area->lock);
    21442036                        printf("as_area: %p, base=%p, pages=%" PRIs
Note: See TracChangeset for help on using the changeset viewer.