Ignore:
File:
1 edited

Legend:

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

    r1624aae r8f80c77  
    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 *
    8889 */
    8990as_operations_t *as_operations = NULL;
     
    9192/**
    9293 * Slab for as_t objects.
     94 *
    9395 */
    9496static slab_cache_t *as_slab;
     
    100102 * - as->asid for each as of the as_t type
    101103 * - asids_allocated counter
     104 *
    102105 */
    103106SPINLOCK_INITIALIZE(asidlock);
     
    106109 * This list contains address spaces that are not active on any
    107110 * processor and that have valid ASID.
     111 *
    108112 */
    109113LIST_INITIALIZE(inactive_as_with_asid_head);
     
    112116as_t *AS_KERNEL = NULL;
    113117
    114 static int area_flags_to_page_flags(int);
     118static unsigned int area_flags_to_page_flags(unsigned int);
    115119static as_area_t *find_area_and_lock(as_t *, uintptr_t);
    116120static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
    117121static void sh_info_remove_reference(share_info_t *);
    118122
    119 static int as_constructor(void *obj, int flags)
     123static int as_constructor(void *obj, unsigned int flags)
    120124{
    121125        as_t *as = (as_t *) obj;
    122         int rc;
    123 
     126       
    124127        link_initialize(&as->inactive_as_with_asid_link);
    125128        mutex_initialize(&as->lock, MUTEX_PASSIVE);
    126129       
    127         rc = as_constructor_arch(as, flags);
     130        int rc = as_constructor_arch(as, flags);
    128131       
    129132        return rc;
    130133}
    131134
    132 static int as_destructor(void *obj)
     135static size_t as_destructor(void *obj)
    133136{
    134137        as_t *as = (as_t *) obj;
    135 
    136138        return as_destructor_arch(as);
    137139}
     
    141143{
    142144        as_arch_init();
    143 
     145       
    144146        as_slab = slab_cache_create("as_slab", sizeof(as_t), 0,
    145147            as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
     
    157159/** Create address space.
    158160 *
    159  * @param flags         Flags that influence the way in wich the address space
    160  *                      is created.
    161  */
    162 as_t *as_create(int flags)
    163 {
    164         as_t *as;
    165 
    166         as = (as_t *) slab_alloc(as_slab, 0);
     161 * @param flags Flags that influence the way in wich the address
     162 *              space is created.
     163 *
     164 */
     165as_t *as_create(unsigned int flags)
     166{
     167        as_t *as = (as_t *) slab_alloc(as_slab, 0);
    167168        (void) as_create_arch(as, 0);
    168169       
     
    176177        atomic_set(&as->refcount, 0);
    177178        as->cpu_refcount = 0;
     179       
    178180#ifdef AS_PAGE_TABLE
    179181        as->genarch.page_table = page_table_create(flags);
     
    192194 * We know that we don't hold any spinlock.
    193195 *
    194  * @param as            Address space to be destroyed.
     196 * @param as Address space to be destroyed.
     197 *
    195198 */
    196199void as_destroy(as_t *as)
    197200{
    198         ipl_t ipl;
    199         bool cond;
    200201        DEADLOCK_PROBE_INIT(p_asidlock);
    201202
     
    214215         * disabled to prevent nested context switches. We also depend on the
    215216         * fact that so far no spinlocks are held.
     217         *
    216218         */
    217219        preemption_disable();
    218         ipl = interrupts_read();
     220        ipl_t ipl = interrupts_read();
     221       
    219222retry:
    220223        interrupts_disable();
     
    224227                goto retry;
    225228        }
    226         preemption_enable();    /* Interrupts disabled, enable preemption */
    227         if (as->asid != ASID_INVALID && as != AS_KERNEL) {
     229       
     230        /* Interrupts disabled, enable preemption */
     231        preemption_enable();
     232       
     233        if ((as->asid != ASID_INVALID) && (as != AS_KERNEL)) {
    228234                if (as->cpu_refcount == 0)
    229235                        list_remove(&as->inactive_as_with_asid_link);
     236               
    230237                asid_put(as->asid);
    231238        }
     239       
    232240        spinlock_unlock(&asidlock);
    233 
     241       
    234242        /*
    235243         * Destroy address space areas of the address space.
    236244         * The B+tree must be walked carefully because it is
    237245         * also being destroyed.
    238          */     
    239         for (cond = true; cond; ) {
    240                 btree_node_t *node;
    241 
     246         *
     247         */
     248        bool cond = true;
     249        while (cond) {
    242250                ASSERT(!list_empty(&as->as_area_btree.leaf_head));
    243                 node = list_get_instance(as->as_area_btree.leaf_head.next,
     251               
     252                btree_node_t *node =
     253                    list_get_instance(as->as_area_btree.leaf_head.next,
    244254                    btree_node_t, leaf_link);
    245 
    246                 if ((cond = node->keys)) {
     255               
     256                if ((cond = node->keys))
    247257                        as_area_destroy(as, node->key[0]);
    248                 }
    249         }
    250 
     258        }
     259       
    251260        btree_destroy(&as->as_area_btree);
     261       
    252262#ifdef AS_PAGE_TABLE
    253263        page_table_destroy(as->genarch.page_table);
     
    255265        page_table_destroy(NULL);
    256266#endif
    257 
     267       
    258268        interrupts_restore(ipl);
    259 
     269       
    260270        slab_free(as_slab, as);
    261271}
     
    266276 * space.
    267277 *
    268  * @param a             Address space to be held.
     278 * @param as Address space to be held.
     279 *
    269280 */
    270281void as_hold(as_t *as)
     
    278289 * space.
    279290 *
    280  * @param a             Address space to be released.
     291 * @param asAddress space to be released.
     292 *
    281293 */
    282294void as_release(as_t *as)
     
    290302 * The created address space area is added to the target address space.
    291303 *
    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  */
    302 as_area_t *
    303 as_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        
     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 */
     315as_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{
    309319        if (base % PAGE_SIZE)
    310320                return NULL;
    311 
     321       
    312322        if (!size)
    313323                return NULL;
    314 
     324       
    315325        /* Writeable executable areas are not supported. */
    316326        if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
    317327                return NULL;
    318328       
    319         ipl = interrupts_disable();
     329        ipl_t ipl = interrupts_disable();
    320330        mutex_lock(&as->lock);
    321331       
     
    326336        }
    327337       
    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;
     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       
    339350        if (backend_data)
    340                 a->backend_data = *backend_data;
     351                area->backend_data = *backend_data;
    341352        else
    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 
     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       
    348358        mutex_unlock(&as->lock);
    349359        interrupts_restore(ipl);
    350 
    351         return a;
     360       
     361        return area;
    352362}
    353363
    354364/** Find address space area and change it.
    355365 *
    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  */
    365 int 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();
     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 */
     376int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
     377{
     378        ipl_t ipl = interrupts_disable();
    372379        mutex_lock(&as->lock);
    373380       
    374381        /*
    375382         * Locate the area.
    376          */
    377         area = find_area_and_lock(as, address);
     383         *
     384         */
     385        as_area_t *area = find_area_and_lock(as, address);
    378386        if (!area) {
    379387                mutex_unlock(&as->lock);
     
    381389                return ENOENT;
    382390        }
    383 
     391       
    384392        if (area->backend == &phys_backend) {
    385393                /*
    386394                 * Remapping of address space areas associated
    387395                 * with memory mapped devices is not supported.
     396                 *
    388397                 */
    389398                mutex_unlock(&area->lock);
     
    392401                return ENOTSUP;
    393402        }
     403       
    394404        if (area->sh_info) {
    395405                /*
    396                  * Remapping of shared address space areas 
     406                 * Remapping of shared address space areas
    397407                 * is not supported.
     408                 *
    398409                 */
    399410                mutex_unlock(&area->lock);
     
    402413                return ENOTSUP;
    403414        }
    404 
    405         pages = SIZE2FRAMES((address - area->base) + size);
     415       
     416        size_t pages = SIZE2FRAMES((address - area->base) + size);
    406417        if (!pages) {
    407418                /*
    408419                 * Zero size address space areas are not allowed.
     420                 *
    409421                 */
    410422                mutex_unlock(&area->lock);
     
    415427       
    416428        if (pages < area->pages) {
    417                 bool cond;
    418429                uintptr_t start_free = area->base + pages * PAGE_SIZE;
    419 
     430               
    420431                /*
    421432                 * Shrinking the area.
    422433                 * No need to check for overlaps.
    423                  */
    424 
     434                 *
     435                 */
     436               
     437                page_table_lock(as, false);
     438               
    425439                /*
    426440                 * Start TLB shootdown sequence.
     441                 *
    427442                 */
    428443                tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
    429444                    pages * PAGE_SIZE, area->pages - pages);
    430 
     445               
    431446                /*
    432447                 * Remove frames belonging to used space starting from
     
    435450                 * is also the right way to remove part of the used_space
    436451                 * B+tree leaf list.
    437                  */             
    438                 for (cond = true; cond;) {
    439                         btree_node_t *node;
    440                
     452                 *
     453                 */
     454                bool cond = true;
     455                while (cond) {
    441456                        ASSERT(!list_empty(&area->used_space.leaf_head));
    442                         node =
     457                       
     458                        btree_node_t *node =
    443459                            list_get_instance(area->used_space.leaf_head.prev,
    444460                            btree_node_t, leaf_link);
     461                       
    445462                        if ((cond = (bool) node->keys)) {
    446                                 uintptr_t b = node->key[node->keys - 1];
    447                                 size_t c =
     463                                uintptr_t ptr = node->key[node->keys - 1];
     464                                size_t size =
    448465                                    (size_t) node->value[node->keys - 1];
    449                                 unsigned int i = 0;
    450                        
    451                                 if (overlaps(b, c * PAGE_SIZE, area->base,
     466                                size_t i = 0;
     467                               
     468                                if (overlaps(ptr, size * PAGE_SIZE, area->base,
    452469                                    pages * PAGE_SIZE)) {
    453470                                       
    454                                         if (b + c * PAGE_SIZE <= start_free) {
     471                                        if (ptr + size * PAGE_SIZE <= start_free) {
    455472                                                /*
    456473                                                 * The whole interval fits
    457474                                                 * completely in the resized
    458475                                                 * address space area.
     476                                                 *
    459477                                                 */
    460478                                                break;
    461479                                        }
    462                
     480                                       
    463481                                        /*
    464482                                         * Part of the interval corresponding
    465483                                         * to b and c overlaps with the resized
    466484                                         * address space area.
     485                                         *
    467486                                         */
    468                
    469                                         cond = false;   /* we are almost done */
    470                                         i = (start_free - b) >> PAGE_WIDTH;
     487                                       
     488                                        /* We are almost done */
     489                                        cond = false;
     490                                        i = (start_free - ptr) >> PAGE_WIDTH;
    471491                                        if (!used_space_remove(area, start_free,
    472                                             c - i))
    473                                                 panic("Cannot remove used "
    474                                                     "space.");
     492                                            size - i))
     493                                                panic("Cannot remove used space.");
    475494                                } else {
    476495                                        /*
     
    478497                                         * completely removed.
    479498                                         */
    480                                         if (!used_space_remove(area, b, c))
    481                                                 panic("Cannot remove used "
    482                                                     "space.");
     499                                        if (!used_space_remove(area, ptr, size))
     500                                                panic("Cannot remove used space.");
    483501                                }
    484                        
    485                                 for (; i < c; i++) {
    486                                         pte_t *pte;
    487                        
    488                                         page_table_lock(as, false);
    489                                         pte = page_mapping_find(as, b +
     502                               
     503                                for (; i < size; i++) {
     504                                        pte_t *pte = page_mapping_find(as, ptr +
    490505                                            i * PAGE_SIZE);
    491                                         ASSERT(pte && PTE_VALID(pte) &&
    492                                             PTE_PRESENT(pte));
    493                                         if (area->backend &&
    494                                             area->backend->frame_free) {
     506                                       
     507                                        ASSERT(pte);
     508                                        ASSERT(PTE_VALID(pte));
     509                                        ASSERT(PTE_PRESENT(pte));
     510                                       
     511                                        if ((area->backend) &&
     512                                            (area->backend->frame_free)) {
    495513                                                area->backend->frame_free(area,
    496                                                     b + i * PAGE_SIZE,
     514                                                    ptr + i * PAGE_SIZE,
    497515                                                    PTE_GET_FRAME(pte));
    498516                                        }
    499                                         page_mapping_remove(as, b +
     517                                       
     518                                        page_mapping_remove(as, ptr +
    500519                                            i * PAGE_SIZE);
    501                                         page_table_unlock(as, false);
    502520                                }
    503521                        }
    504522                }
    505 
     523               
    506524                /*
    507525                 * Finish TLB shootdown sequence.
    508                  */
    509 
     526                 *
     527                 */
     528               
    510529                tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
    511530                    area->pages - pages);
     531               
    512532                /*
    513533                 * Invalidate software translation caches (e.g. TSB on sparc64).
     534                 *
    514535                 */
    515536                as_invalidate_translation_cache(as, area->base +
     
    517538                tlb_shootdown_finalize();
    518539               
     540                page_table_unlock(as, false);
    519541        } else {
    520542                /*
    521543                 * Growing the area.
    522544                 * Check for overlaps with other address space areas.
     545                 *
    523546                 */
    524547                if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
    525548                    area)) {
    526549                        mutex_unlock(&area->lock);
    527                         mutex_unlock(&as->lock);               
     550                        mutex_unlock(&as->lock);
    528551                        interrupts_restore(ipl);
    529552                        return EADDRNOTAVAIL;
    530553                }
    531         } 
    532 
     554        }
     555       
    533556        area->pages = pages;
    534557       
     
    536559        mutex_unlock(&as->lock);
    537560        interrupts_restore(ipl);
    538 
     561       
    539562        return 0;
    540563}
     
    542565/** Destroy address space area.
    543566 *
    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.
     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 *
    548572 */
    549573int as_area_destroy(as_t *as, uintptr_t address)
    550574{
    551         as_area_t *area;
    552         uintptr_t base;
    553         link_t *cur;
    554         ipl_t ipl;
    555 
    556         ipl = interrupts_disable();
     575        ipl_t ipl = interrupts_disable();
    557576        mutex_lock(&as->lock);
    558 
    559         area = find_area_and_lock(as, address);
     577       
     578        as_area_t *area = find_area_and_lock(as, address);
    560579        if (!area) {
    561580                mutex_unlock(&as->lock);
     
    563582                return ENOENT;
    564583        }
    565 
    566         base = area->base;
    567 
     584       
     585        uintptr_t base = area->base;
     586       
     587        page_table_lock(as, false);
     588       
    568589        /*
    569590         * Start TLB shootdown sequence.
    570591         */
    571592        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    572 
     593       
    573594        /*
    574595         * Visit only the pages mapped by used_space B+tree.
    575596         */
     597        link_t *cur;
    576598        for (cur = area->used_space.leaf_head.next;
    577599            cur != &area->used_space.leaf_head; cur = cur->next) {
    578600                btree_node_t *node;
    579                 unsigned int i;
     601                btree_key_t i;
    580602               
    581603                node = list_get_instance(cur, btree_node_t, leaf_link);
    582604                for (i = 0; i < node->keys; i++) {
    583                         uintptr_t b = node->key[i];
    584                         size_t j;
    585                         pte_t *pte;
     605                        uintptr_t ptr = node->key[i];
     606                        size_t size;
    586607                       
    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));
     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));
    596619                                }
    597                                 page_mapping_remove(as, b + j * PAGE_SIZE);                             
    598                                 page_table_unlock(as, false);
     620                               
     621                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
    599622                        }
    600623                }
    601624        }
    602 
     625       
    603626        /*
    604627         * Finish TLB shootdown sequence.
    605          */
    606 
     628         *
     629         */
     630       
    607631        tlb_invalidate_pages(as->asid, area->base, area->pages);
     632       
    608633        /*
    609634         * Invalidate potential software translation caches (e.g. TSB on
    610635         * sparc64).
     636         *
    611637         */
    612638        as_invalidate_translation_cache(as, area->base, area->pages);
    613639        tlb_shootdown_finalize();
    614640       
     641        page_table_unlock(as, false);
     642       
    615643        btree_destroy(&area->used_space);
    616 
     644       
    617645        area->attributes |= AS_AREA_ATTR_PARTIAL;
    618646       
    619647        if (area->sh_info)
    620648                sh_info_remove_reference(area->sh_info);
    621                
     649       
    622650        mutex_unlock(&area->lock);
    623 
     651       
    624652        /*
    625653         * Remove the empty area from address space.
     654         *
    626655         */
    627656        btree_remove(&as->as_area_btree, base, NULL);
     
    641670 * sh_info of the source area. The process of duplicating the
    642671 * mapping is done through the backend share function.
    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.
     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.
    649678 * @param dst_flags_mask Destination address space area flags mask.
    650679 *
    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.
     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 *
    657688 */
    658689int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
    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();
     690    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
     691{
     692        ipl_t ipl = interrupts_disable();
    670693        mutex_lock(&src_as->lock);
    671         src_area = find_area_and_lock(src_as, src_base);
     694        as_area_t *src_area = find_area_and_lock(src_as, src_base);
    672695        if (!src_area) {
    673696                /*
    674697                 * Could not find the source address space area.
     698                 *
    675699                 */
    676700                mutex_unlock(&src_as->lock);
     
    678702                return ENOENT;
    679703        }
    680 
    681         if (!src_area->backend || !src_area->backend->share) {
     704       
     705        if ((!src_area->backend) || (!src_area->backend->share)) {
    682706                /*
    683707                 * There is no backend or the backend does not
    684708                 * know how to share the area.
     709                 *
    685710                 */
    686711                mutex_unlock(&src_area->lock);
     
    690715        }
    691716       
    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 
     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       
    697722        /* Share the cacheable flag from the original mapping */
    698723        if (src_flags & AS_AREA_CACHEABLE)
    699724                dst_flags_mask |= AS_AREA_CACHEABLE;
    700 
    701         if (src_size != acc_size ||
    702             (src_flags & dst_flags_mask) != dst_flags_mask) {
     725       
     726        if ((src_size != acc_size) ||
     727            ((src_flags & dst_flags_mask) != dst_flags_mask)) {
    703728                mutex_unlock(&src_area->lock);
    704729                mutex_unlock(&src_as->lock);
     
    706731                return EPERM;
    707732        }
    708 
     733       
    709734        /*
    710735         * Now we are committed to sharing the area.
    711736         * First, prepare the area for sharing.
    712737         * Then it will be safe to unlock it.
    713          */
    714         sh_info = src_area->sh_info;
     738         *
     739         */
     740        share_info_t *sh_info = src_area->sh_info;
    715741        if (!sh_info) {
    716742                sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
     
    719745                btree_create(&sh_info->pagemap);
    720746                src_area->sh_info = sh_info;
     747               
    721748                /*
    722749                 * Call the backend to setup sharing.
     750                 *
    723751                 */
    724752                src_area->backend->share(src_area);
     
    728756                mutex_unlock(&sh_info->lock);
    729757        }
    730 
     758       
    731759        mutex_unlock(&src_area->lock);
    732760        mutex_unlock(&src_as->lock);
    733 
     761       
    734762        /*
    735763         * Create copy of the source address space area.
     
    739767         * The flags of the source area are masked against dst_flags_mask
    740768         * to support sharing in less privileged mode.
    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);
     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);
    744773        if (!dst_area) {
    745774                /*
     
    751780                return ENOMEM;
    752781        }
    753 
     782       
    754783        /*
    755784         * Now the destination address space area has been
    756785         * fully initialized. Clear the AS_AREA_ATTR_PARTIAL
    757786         * attribute and set the sh_info.
    758          */     
    759         mutex_lock(&dst_as->lock);     
     787         *
     788         */
     789        mutex_lock(&dst_as->lock);
    760790        mutex_lock(&dst_area->lock);
    761791        dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
    762792        dst_area->sh_info = sh_info;
    763793        mutex_unlock(&dst_area->lock);
    764         mutex_unlock(&dst_as->lock);   
    765 
     794        mutex_unlock(&dst_as->lock);
     795       
    766796        interrupts_restore(ipl);
    767797       
     
    771801/** Check access mode for address space area.
    772802 *
    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.
     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 *
    780809 */
    781810bool as_area_check_access(as_area_t *area, pf_access_t access)
     
    787816        };
    788817
     818        ASSERT(interrupts_disabled());
     819        ASSERT(mutex_locked(&area->lock));
     820       
    789821        if (!(area->flags & flagmap[access]))
    790822                return false;
     
    807839 *
    808840 */
    809 int 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        
     841int as_area_change_flags(as_t *as, unsigned int flags, uintptr_t address)
     842{
    819843        /* Flags for the new memory mapping */
    820         page_flags = area_flags_to_page_flags(flags);
    821 
    822         ipl = interrupts_disable();
     844        unsigned int page_flags = area_flags_to_page_flags(flags);
     845       
     846        ipl_t ipl = interrupts_disable();
    823847        mutex_lock(&as->lock);
    824 
    825         area = find_area_and_lock(as, address);
     848       
     849        as_area_t *area = find_area_and_lock(as, address);
    826850        if (!area) {
    827851                mutex_unlock(&as->lock);
     
    829853                return ENOENT;
    830854        }
    831 
     855       
    832856        if ((area->sh_info) || (area->backend != &anon_backend)) {
    833857                /* Copying shared areas not supported yet */
     
    838862                return ENOTSUP;
    839863        }
    840 
     864       
    841865        /*
    842866         * Compute total number of used pages in the used_space B+tree
    843          */
    844         used_pages = 0;
    845 
     867         *
     868         */
     869        size_t used_pages = 0;
     870        link_t *cur;
     871       
    846872        for (cur = area->used_space.leaf_head.next;
    847873            cur != &area->used_space.leaf_head; cur = cur->next) {
    848                 btree_node_t *node;
    849                 unsigned int i;
    850                
    851                 node = list_get_instance(cur, btree_node_t, leaf_link);
    852                 for (i = 0; i < node->keys; i++) {
     874                btree_node_t *node
     875                    = list_get_instance(cur, btree_node_t, leaf_link);
     876                btree_key_t i;
     877               
     878                for (i = 0; i < node->keys; i++)
    853879                        used_pages += (size_t) node->value[i];
    854                 }
    855         }
    856 
     880        }
     881       
    857882        /* An array for storing frame numbers */
    858         old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
    859 
     883        uintptr_t *old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
     884       
     885        page_table_lock(as, false);
     886       
    860887        /*
    861888         * Start TLB shootdown sequence.
     889         *
    862890         */
    863891        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
    864 
     892       
    865893        /*
    866894         * Remove used pages from page tables and remember their frame
    867895         * numbers.
    868          */
    869         frame_idx = 0;
    870 
     896         *
     897         */
     898        size_t frame_idx = 0;
     899       
    871900        for (cur = area->used_space.leaf_head.next;
    872901            cur != &area->used_space.leaf_head; cur = cur->next) {
    873                 btree_node_t *node;
    874                 unsigned int i;
    875                
    876                 node = list_get_instance(cur, btree_node_t, leaf_link);
     902                btree_node_t *node
     903                    = list_get_instance(cur, btree_node_t, leaf_link);
     904                btree_key_t i;
     905               
    877906                for (i = 0; i < node->keys; i++) {
    878                         uintptr_t b = node->key[i];
    879                         size_t j;
    880                         pte_t *pte;
     907                        uintptr_t ptr = node->key[i];
     908                        size_t size;
    881909                       
    882                         for (j = 0; j < (size_t) node->value[i]; j++) {
     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                               
     917                                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
     918                               
     919                                /* Remove old mapping */
     920                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
     921                        }
     922                }
     923        }
     924       
     925        /*
     926         * Finish TLB shootdown sequence.
     927         *
     928         */
     929       
     930        tlb_invalidate_pages(as->asid, area->base, area->pages);
     931       
     932        /*
     933         * Invalidate potential software translation caches (e.g. TSB on
     934         * sparc64).
     935         *
     936         */
     937        as_invalidate_translation_cache(as, area->base, area->pages);
     938        tlb_shootdown_finalize();
     939       
     940        page_table_unlock(as, false);
     941       
     942        /*
     943         * Set the new flags.
     944         */
     945        area->flags = flags;
     946       
     947        /*
     948         * Map pages back in with new flags. This step is kept separate
     949         * so that the memory area could not be accesed with both the old and
     950         * the new flags at once.
     951         */
     952        frame_idx = 0;
     953       
     954        for (cur = area->used_space.leaf_head.next;
     955            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;
     959               
     960                for (i = 0; i < node->keys; i++) {
     961                        uintptr_t ptr = node->key[i];
     962                        size_t size;
     963                       
     964                        for (size = 0; size < (size_t) node->value[i]; size++) {
    883965                                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));
    887                                 old_frame[frame_idx++] = PTE_GET_FRAME(pte);
    888 
    889                                 /* Remove old mapping */
    890                                 page_mapping_remove(as, b + j * PAGE_SIZE);
     966                               
     967                                /* Insert the new mapping */
     968                                page_mapping_insert(as, ptr + size * PAGE_SIZE,
     969                                    old_frame[frame_idx++], page_flags);
     970                               
    891971                                page_table_unlock(as, false);
    892972                        }
    893973                }
    894974        }
    895 
    896         /*
    897          * Finish TLB shootdown sequence.
    898          */
    899 
    900         tlb_invalidate_pages(as->asid, area->base, area->pages);
    901        
    902         /*
    903          * Invalidate potential software translation caches (e.g. TSB on
    904          * sparc64).
    905          */
    906         as_invalidate_translation_cache(as, area->base, area->pages);
    907         tlb_shootdown_finalize();
    908 
    909         /*
    910          * Set the new flags.
    911          */
    912         area->flags = flags;
    913 
    914         /*
    915          * Map pages back in with new flags. This step is kept separate
    916          * so that the memory area could not be accesed with both the old and
    917          * the new flags at once.
    918          */
    919         frame_idx = 0;
    920 
    921         for (cur = area->used_space.leaf_head.next;
    922             cur != &area->used_space.leaf_head; cur = cur->next) {
    923                 btree_node_t *node;
    924                 unsigned int i;
    925                
    926                 node = list_get_instance(cur, btree_node_t, leaf_link);
    927                 for (i = 0; i < node->keys; i++) {
    928                         uintptr_t b = node->key[i];
    929                         size_t j;
    930                        
    931                         for (j = 0; j < (size_t) node->value[i]; j++) {
    932                                 page_table_lock(as, false);
    933 
    934                                 /* Insert the new mapping */
    935                                 page_mapping_insert(as, b + j * PAGE_SIZE,
    936                                     old_frame[frame_idx++], page_flags);
    937 
    938                                 page_table_unlock(as, false);
    939                         }
    940                 }
    941         }
    942 
     975       
    943976        free(old_frame);
    944 
     977       
    945978        mutex_unlock(&area->lock);
    946979        mutex_unlock(&as->lock);
    947980        interrupts_restore(ipl);
    948 
     981       
    949982        return 0;
    950983}
    951 
    952984
    953985/** Handle page fault within the current address space.
     
    959991 * Interrupts are assumed disabled.
    960992 *
    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().
     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 *
    9691003 */
    9701004int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
    9711005{
    972         pte_t *pte;
    973         as_area_t *area;
    974        
    9751006        if (!THREAD)
    9761007                return AS_PF_FAULT;
     
    9801011       
    9811012        mutex_lock(&AS->lock);
    982         area = find_area_and_lock(AS, page);
     1013        as_area_t *area = find_area_and_lock(AS, page);
    9831014        if (!area) {
    9841015                /*
    9851016                 * No area contained mapping for 'page'.
    9861017                 * Signal page fault to low-level handler.
     1018                 *
    9871019                 */
    9881020                mutex_unlock(&AS->lock);
    9891021                goto page_fault;
    9901022        }
    991 
     1023       
    9921024        if (area->attributes & AS_AREA_ATTR_PARTIAL) {
    9931025                /*
     
    9971029                mutex_unlock(&area->lock);
    9981030                mutex_unlock(&AS->lock);
    999                 goto page_fault;               
    1000         }
    1001 
    1002         if (!area->backend || !area->backend->page_fault) {
     1031                goto page_fault;
     1032        }
     1033       
     1034        if ((!area->backend) || (!area->backend->page_fault)) {
    10031035                /*
    10041036                 * The address space area is not backed by any backend
    10051037                 * or the backend cannot handle page faults.
     1038                 *
    10061039                 */
    10071040                mutex_unlock(&area->lock);
    10081041                mutex_unlock(&AS->lock);
    1009                 goto page_fault;               
    1010         }
    1011 
     1042                goto page_fault;
     1043        }
     1044       
    10121045        page_table_lock(AS, false);
    10131046       
     
    10151048         * To avoid race condition between two page faults on the same address,
    10161049         * we need to make sure the mapping has not been already inserted.
    1017          */
     1050         *
     1051         */
     1052        pte_t *pte;
    10181053        if ((pte = page_mapping_find(AS, page))) {
    10191054                if (PTE_PRESENT(pte)) {
     
    10311066        /*
    10321067         * Resort to the backend page fault handler.
     1068         *
    10331069         */
    10341070        if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
     
    10431079        mutex_unlock(&AS->lock);
    10441080        return AS_PF_OK;
    1045 
     1081       
    10461082page_fault:
    10471083        if (THREAD->in_copy_from_uspace) {
     
    10561092                return AS_PF_FAULT;
    10571093        }
    1058 
     1094       
    10591095        return AS_PF_DEFER;
    10601096}
     
    10681104 * When this function is enetered, no spinlocks may be held.
    10691105 *
    1070  * @param old           Old address space or NULL.
    1071  * @param new           New address space.
     1106 * @param old Old address space or NULL.
     1107 * @param new New address space.
     1108 *
    10721109 */
    10731110void as_switch(as_t *old_as, as_t *new_as)
     
    10751112        DEADLOCK_PROBE_INIT(p_asidlock);
    10761113        preemption_disable();
     1114       
    10771115retry:
    10781116        (void) interrupts_disable();
    10791117        if (!spinlock_trylock(&asidlock)) {
    1080                 /* 
     1118                /*
    10811119                 * Avoid deadlock with TLB shootdown.
    10821120                 * We can enable interrupts here because
    10831121                 * preemption is disabled. We should not be
    10841122                 * holding any other lock.
     1123                 *
    10851124                 */
    10861125                (void) interrupts_enable();
     
    10891128        }
    10901129        preemption_enable();
    1091 
     1130       
    10921131        /*
    10931132         * First, take care of the old address space.
    1094          */     
     1133         */
    10951134        if (old_as) {
    10961135                ASSERT(old_as->cpu_refcount);
    1097                 if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
     1136               
     1137                if ((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
    10981138                        /*
    10991139                         * The old address space is no longer active on
     
    11011141                         * list of inactive address spaces with assigned
    11021142                         * ASID.
     1143                         *
    11031144                         */
    11041145                        ASSERT(old_as->asid != ASID_INVALID);
     1146                       
    11051147                        list_append(&old_as->inactive_as_with_asid_link,
    11061148                            &inactive_as_with_asid_head);
    11071149                }
    1108 
     1150               
    11091151                /*
    11101152                 * Perform architecture-specific tasks when the address space
    11111153                 * is being removed from the CPU.
     1154                 *
    11121155                 */
    11131156                as_deinstall_arch(old_as);
    11141157        }
    1115 
     1158       
    11161159        /*
    11171160         * Second, prepare the new address space.
     1161         *
    11181162         */
    11191163        if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
     
    11231167                        new_as->asid = asid_get();
    11241168        }
     1169       
    11251170#ifdef AS_PAGE_TABLE
    11261171        SET_PTL0_ADDRESS(new_as->genarch.page_table);
     
    11301175         * Perform architecture-specific steps.
    11311176         * (e.g. write ASID to hardware register etc.)
     1177         *
    11321178         */
    11331179        as_install_arch(new_as);
    1134 
     1180       
    11351181        spinlock_unlock(&asidlock);
    11361182       
     
    11401186/** Convert address space area flags to page flags.
    11411187 *
    1142  * @param aflags        Flags of some address space area.
    1143  *
    1144  * @return              Flags to be passed to page_mapping_insert().
    1145  */
    1146 int area_flags_to_page_flags(int aflags)
    1147 {
    1148         int flags;
    1149 
    1150         flags = PAGE_USER | PAGE_PRESENT;
     1188 * @param aflags Flags of some address space area.
     1189 *
     1190 * @return Flags to be passed to page_mapping_insert().
     1191 *
     1192 */
     1193unsigned int area_flags_to_page_flags(unsigned int aflags)
     1194{
     1195        unsigned int flags = PAGE_USER | PAGE_PRESENT;
    11511196       
    11521197        if (aflags & AS_AREA_READ)
     
    11611206        if (aflags & AS_AREA_CACHEABLE)
    11621207                flags |= PAGE_CACHEABLE;
    1163                
     1208       
    11641209        return flags;
    11651210}
     
    11671212/** Compute flags for virtual address translation subsytem.
    11681213 *
    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  */
    1176 int as_area_get_flags(as_area_t *a)
    1177 {
    1178         return area_flags_to_page_flags(a->flags);
     1214 * @param area Address space area.
     1215 *
     1216 * @return Flags to be used in page_mapping_insert().
     1217 *
     1218 */
     1219unsigned 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);
    11791225}
    11801226
     
    11841230 * table.
    11851231 *
    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  */
    1191 pte_t *page_table_create(int flags)
     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 */
     1238pte_t *page_table_create(unsigned int flags)
    11921239{
    11931240        ASSERT(as_operations);
     
    12011248 * Destroy page table in architecture specific way.
    12021249 *
    1203  * @param page_table    Physical address of PTL0.
     1250 * @param page_table Physical address of PTL0.
     1251 *
    12041252 */
    12051253void page_table_destroy(pte_t *page_table)
     
    12151263 * This function should be called before any page_mapping_insert(),
    12161264 * page_mapping_remove() and page_mapping_find().
    1217  * 
     1265 *
    12181266 * Locking order is such that address space areas must be locked
    12191267 * prior to this call. Address space can be locked prior to this
    12201268 * call in which case the lock argument is false.
    12211269 *
    1222  * @param as            Address space.
    1223  * @param lock          If false, do not attempt to lock as->lock.
     1270 * @param as   Address space.
     1271 * @param lock If false, do not attempt to lock as->lock.
     1272 *
    12241273 */
    12251274void page_table_lock(as_t *as, bool lock)
     
    12331282/** Unlock page table.
    12341283 *
    1235  * @param as            Address space.
    1236  * @param unlock        If false, do not attempt to unlock as->lock.
     1284 * @param as     Address space.
     1285 * @param unlock If false, do not attempt to unlock as->lock.
     1286 *
    12371287 */
    12381288void page_table_unlock(as_t *as, bool unlock)
     
    12441294}
    12451295
     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 */
     1303bool 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
    12461311
    12471312/** Find address space area and lock it.
    12481313 *
    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.
     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 *
    12561320 */
    12571321as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
    12581322{
    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) {
     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) {
    12651329                /* va is the base address of an address space area */
    1266                 mutex_lock(&a->lock);
    1267                 return a;
     1330                mutex_lock(&area->lock);
     1331                return area;
    12681332        }
    12691333       
     
    12721336         * to find out whether this is a miss or va belongs to an address
    12731337         * space area found there.
     1338         *
    12741339         */
    12751340       
    12761341        /* First, search the leaf node itself. */
     1342        btree_key_t i;
     1343       
    12771344        for (i = 0; i < leaf->keys; i++) {
    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 
     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       
    12861355        /*
    12871356         * Second, locate the left neighbour and test its last record.
    12881357         * Because of its position in the B+tree, it must have base < va.
    1289          */
    1290         lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     1358         *
     1359         */
     1360        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    12911361        if (lnode) {
    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 
     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       
    13001372        return NULL;
    13011373}
     
    13031375/** Check area conflicts with other areas.
    13041376 *
    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  */
    1314 bool
    1315 check_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        
     1377 * @param as         Address space.
     1378 * @param va         Starting virtual address of the area being tested.
     1379 * @param size       Size of the area being tested.
     1380 * @param avoid_area Do not touch this area.
     1381 *
     1382 * @return True if there is no conflict, false otherwise.
     1383 *
     1384 */
     1385bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
     1386    as_area_t *avoid_area)
     1387{
     1388        ASSERT(interrupts_disabled());
     1389        ASSERT(mutex_locked(&as->lock));
     1390
    13211391        /*
    13221392         * We don't want any area to have conflicts with NULL page.
     1393         *
    13231394         */
    13241395        if (overlaps(va, size, NULL, PAGE_SIZE))
     
    13311402         * record in the left neighbour, the leftmost record in the right
    13321403         * neighbour and all records in the leaf node itself.
    1333          */
    1334        
    1335         if ((a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf))) {
    1336                 if (a != avoid_area)
     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)
    13371411                        return false;
    13381412        }
    13391413       
    13401414        /* First, check the two border cases. */
    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);
     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);
    13461424                        return false;
    13471425                }
    1348                 mutex_unlock(&a->lock);
    1349         }
     1426               
     1427                mutex_unlock(&area->lock);
     1428        }
     1429       
    13501430        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    13511431        if (node) {
    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);
     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);
    13561438                        return false;
    13571439                }
    1358                 mutex_unlock(&a->lock);
     1440               
     1441                mutex_unlock(&area->lock);
    13591442        }
    13601443       
    13611444        /* Second, check the leaf node. */
     1445        btree_key_t i;
    13621446        for (i = 0; i < leaf->keys; i++) {
    1363                 a = (as_area_t *) leaf->value[i];
    1364        
    1365                 if (a == avoid_area)
     1447                area = (as_area_t *) leaf->value[i];
     1448               
     1449                if (area == avoid_area)
    13661450                        continue;
    1367        
    1368                 mutex_lock(&a->lock);
    1369                 if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
    1370                         mutex_unlock(&a->lock);
     1451               
     1452                mutex_lock(&area->lock);
     1453               
     1454                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     1455                        mutex_unlock(&area->lock);
    13711456                        return false;
    13721457                }
    1373                 mutex_unlock(&a->lock);
    1374         }
    1375 
     1458               
     1459                mutex_unlock(&area->lock);
     1460        }
     1461       
    13761462        /*
    13771463         * So far, the area does not conflict with other areas.
    13781464         * Check if it doesn't conflict with kernel address space.
    1379          */     
     1465         *
     1466         */
    13801467        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    1381                 return !overlaps(va, size, 
     1468                return !overlaps(va, size,
    13821469                    KERNEL_ADDRESS_SPACE_START,
    13831470                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    13841471        }
    1385 
     1472       
    13861473        return true;
    13871474}
     
    13891476/** Return size of the address space area with given base.
    13901477 *
    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.
     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 *
    13951483 */
    13961484size_t as_area_get_size(uintptr_t base)
    13971485{
    1398         ipl_t ipl;
    1399         as_area_t *src_area;
    14001486        size_t size;
    1401 
    1402         ipl = interrupts_disable();
    1403         src_area = find_area_and_lock(AS, base);
     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       
    14041492        if (src_area) {
    14051493                size = src_area->pages * PAGE_SIZE;
    14061494                mutex_unlock(&src_area->lock);
    1407         } else {
     1495        } else
    14081496                size = 0;
    1409         }
     1497       
     1498        page_table_unlock(AS, true);
    14101499        interrupts_restore(ipl);
    14111500        return size;
     
    14161505 * The address space area must be already locked.
    14171506 *
    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  */
    1424 int 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 
     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 */
     1514int used_space_insert(as_area_t *area, uintptr_t page, size_t count)
     1515{
     1516        ASSERT(mutex_locked(&area->lock));
    14301517        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    14311518        ASSERT(count);
    1432 
    1433         pages = (size_t) btree_search(&a->used_space, page, &leaf);
     1519       
     1520        btree_node_t *leaf;
     1521        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
    14341522        if (pages) {
    14351523                /*
    14361524                 * We hit the beginning of some used space.
     1525                 *
    14371526                 */
    14381527                return 0;
    14391528        }
    1440 
     1529       
    14411530        if (!leaf->keys) {
    1442                 btree_insert(&a->used_space, page, (void *) count, leaf);
     1531                btree_insert(&area->used_space, page, (void *) count, leaf);
    14431532                return 1;
    14441533        }
    1445 
    1446         node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
     1534       
     1535        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
    14471536        if (node) {
    14481537                uintptr_t left_pg = node->key[node->keys - 1];
     
    14551544                 * somewhere between the rightmost interval of
    14561545                 * the left neigbour and the first interval of the leaf.
    1457                  */
    1458                  
     1546                 *
     1547                 */
     1548               
    14591549                if (page >= right_pg) {
    14601550                        /* Do nothing. */
     
    14661556                    right_cnt * PAGE_SIZE)) {
    14671557                        /* The interval intersects with the right interval. */
    1468                         return 0;                       
     1558                        return 0;
    14691559                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    14701560                    (page + count * PAGE_SIZE == right_pg)) {
     
    14721562                         * The interval can be added by merging the two already
    14731563                         * present intervals.
     1564                         *
    14741565                         */
    14751566                        node->value[node->keys - 1] += count + right_cnt;
    1476                         btree_remove(&a->used_space, right_pg, leaf);
    1477                         return 1; 
     1567                        btree_remove(&area->used_space, right_pg, leaf);
     1568                        return 1;
    14781569                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    1479                         /* 
     1570                        /*
    14801571                         * The interval can be added by simply growing the left
    14811572                         * interval.
     1573                         *
    14821574                         */
    14831575                        node->value[node->keys - 1] += count;
     
    14881580                         * the right interval down and increasing its size
    14891581                         * accordingly.
     1582                         *
    14901583                         */
    14911584                        leaf->value[0] += count;
     
    14961589                         * The interval is between both neigbouring intervals,
    14971590                         * but cannot be merged with any of them.
     1591                         *
    14981592                         */
    1499                         btree_insert(&a->used_space, page, (void *) count,
     1593                        btree_insert(&area->used_space, page, (void *) count,
    15001594                            leaf);
    15011595                        return 1;
     
    15041598                uintptr_t right_pg = leaf->key[0];
    15051599                size_t right_cnt = (size_t) leaf->value[0];
    1506        
     1600               
    15071601                /*
    15081602                 * Investigate the border case in which the left neighbour does
    15091603                 * not exist but the interval fits from the left.
    1510                  */
    1511                  
     1604                 *
     1605                 */
     1606               
    15121607                if (overlaps(page, count * PAGE_SIZE, right_pg,
    15131608                    right_cnt * PAGE_SIZE)) {
     
    15191614                         * right interval down and increasing its size
    15201615                         * accordingly.
     1616                         *
    15211617                         */
    15221618                        leaf->key[0] = page;
     
    15271623                         * The interval doesn't adjoin with the right interval.
    15281624                         * It must be added individually.
     1625                         *
    15291626                         */
    1530                         btree_insert(&a->used_space, page, (void *) count,
     1627                        btree_insert(&area->used_space, page, (void *) count,
    15311628                            leaf);
    15321629                        return 1;
    15331630                }
    15341631        }
    1535 
    1536         node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
     1632       
     1633        node = btree_leaf_node_right_neighbour(&area->used_space, leaf);
    15371634        if (node) {
    15381635                uintptr_t left_pg = leaf->key[leaf->keys - 1];
     
    15451642                 * somewhere between the leftmost interval of
    15461643                 * the right neigbour and the last interval of the leaf.
    1547                  */
    1548 
     1644                 *
     1645                 */
     1646               
    15491647                if (page < left_pg) {
    15501648                        /* Do nothing. */
     
    15561654                    right_cnt * PAGE_SIZE)) {
    15571655                        /* The interval intersects with the right interval. */
    1558                         return 0;                       
     1656                        return 0;
    15591657                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    15601658                    (page + count * PAGE_SIZE == right_pg)) {
     
    15621660                         * The interval can be added by merging the two already
    15631661                         * present intervals.
    1564                          * */
     1662                         *
     1663                         */
    15651664                        leaf->value[leaf->keys - 1] += count + right_cnt;
    1566                         btree_remove(&a->used_space, right_pg, node);
    1567                         return 1; 
     1665                        btree_remove(&area->used_space, right_pg, node);
     1666                        return 1;
    15681667                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    15691668                        /*
    15701669                         * The interval can be added by simply growing the left
    15711670                         * interval.
    1572                          * */
     1671                         *
     1672                         */
    15731673                        leaf->value[leaf->keys - 1] +=  count;
    15741674                        return 1;
     
    15781678                         * the right interval down and increasing its size
    15791679                         * accordingly.
     1680                         *
    15801681                         */
    15811682                        node->value[0] += count;
     
    15861687                         * The interval is between both neigbouring intervals,
    15871688                         * but cannot be merged with any of them.
     1689                         *
    15881690                         */
    1589                         btree_insert(&a->used_space, page, (void *) count,
     1691                        btree_insert(&area->used_space, page, (void *) count,
    15901692                            leaf);
    15911693                        return 1;
     
    15941696                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    15951697                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    1596        
     1698               
    15971699                /*
    15981700                 * Investigate the border case in which the right neighbour
    15991701                 * does not exist but the interval fits from the right.
    1600                  */
    1601                  
     1702                 *
     1703                 */
     1704               
    16021705                if (overlaps(page, count * PAGE_SIZE, left_pg,
    16031706                    left_cnt * PAGE_SIZE)) {
     
    16081711                         * The interval can be added by growing the left
    16091712                         * interval.
     1713                         *
    16101714                         */
    16111715                        leaf->value[leaf->keys - 1] += count;
     
    16151719                         * The interval doesn't adjoin with the left interval.
    16161720                         * It must be added individually.
     1721                         *
    16171722                         */
    1618                         btree_insert(&a->used_space, page, (void *) count,
     1723                        btree_insert(&area->used_space, page, (void *) count,
    16191724                            leaf);
    16201725                        return 1;
     
    16261731         * only between two other intervals of the leaf. The two border cases
    16271732         * were already resolved.
    1628          */
     1733         *
     1734         */
     1735        btree_key_t i;
    16291736        for (i = 1; i < leaf->keys; i++) {
    16301737                if (page < leaf->key[i]) {
     
    16331740                        size_t left_cnt = (size_t) leaf->value[i - 1];
    16341741                        size_t right_cnt = (size_t) leaf->value[i];
    1635 
     1742                       
    16361743                        /*
    16371744                         * The interval fits between left_pg and right_pg.
     1745                         *
    16381746                         */
    1639 
     1747                       
    16401748                        if (overlaps(page, count * PAGE_SIZE, left_pg,
    16411749                            left_cnt * PAGE_SIZE)) {
     
    16431751                                 * The interval intersects with the left
    16441752                                 * interval.
     1753                                 *
    16451754                                 */
    16461755                                return 0;
     
    16501759                                 * The interval intersects with the right
    16511760                                 * interval.
     1761                                 *
    16521762                                 */
    1653                                 return 0;                       
     1763                                return 0;
    16541764                        } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    16551765                            (page + count * PAGE_SIZE == right_pg)) {
     
    16571767                                 * The interval can be added by merging the two
    16581768                                 * already present intervals.
     1769                                 *
    16591770                                 */
    16601771                                leaf->value[i - 1] += count + right_cnt;
    1661                                 btree_remove(&a->used_space, right_pg, leaf);
    1662                                 return 1; 
     1772                                btree_remove(&area->used_space, right_pg, leaf);
     1773                                return 1;
    16631774                        } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    16641775                                /*
    16651776                                 * The interval can be added by simply growing
    16661777                                 * the left interval.
     1778                                 *
    16671779                                 */
    16681780                                leaf->value[i - 1] += count;
     
    16701782                        } else if (page + count * PAGE_SIZE == right_pg) {
    16711783                                /*
    1672                                 * The interval can be addded by simply moving
     1784                                * The interval can be addded by simply moving
    16731785                                 * base of the right interval down and
    16741786                                 * increasing its size accordingly.
    1675                                  */
     1787                                 *
     1788                                 */
    16761789                                leaf->value[i] += count;
    16771790                                leaf->key[i] = page;
     
    16821795                                 * intervals, but cannot be merged with any of
    16831796                                 * them.
     1797                                 *
    16841798                                 */
    1685                                 btree_insert(&a->used_space, page,
     1799                                btree_insert(&area->used_space, page,
    16861800                                    (void *) count, leaf);
    16871801                                return 1;
     
    16891803                }
    16901804        }
    1691 
     1805       
    16921806        panic("Inconsistency detected while adding %" PRIs " pages of used "
    16931807            "space at %p.", count, page);
     
    16981812 * The address space area must be already locked.
    16991813 *
    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  */
    1706 int 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 
     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 */
     1821int used_space_remove(as_area_t *area, uintptr_t page, size_t count)
     1822{
     1823        ASSERT(mutex_locked(&area->lock));
    17121824        ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
    17131825        ASSERT(count);
    1714 
    1715         pages = (size_t) btree_search(&a->used_space, page, &leaf);
     1826       
     1827        btree_node_t *leaf;
     1828        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
    17161829        if (pages) {
    17171830                /*
    17181831                 * We are lucky, page is the beginning of some interval.
     1832                 *
    17191833                 */
    17201834                if (count > pages) {
    17211835                        return 0;
    17221836                } else if (count == pages) {
    1723                         btree_remove(&a->used_space, page, leaf);
     1837                        btree_remove(&area->used_space, page, leaf);
    17241838                        return 1;
    17251839                } else {
     
    17271841                         * Find the respective interval.
    17281842                         * Decrease its size and relocate its start address.
     1843                         *
    17291844                         */
     1845                        btree_key_t i;
    17301846                        for (i = 0; i < leaf->keys; i++) {
    17311847                                if (leaf->key[i] == page) {
     
    17381854                }
    17391855        }
    1740 
    1741         node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
    1742         if (node && page < leaf->key[0]) {
     1856       
     1857        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     1858        if ((node) && (page < leaf->key[0])) {
    17431859                uintptr_t left_pg = node->key[node->keys - 1];
    17441860                size_t left_cnt = (size_t) node->value[node->keys - 1];
    1745 
     1861               
    17461862                if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    17471863                    count * PAGE_SIZE)) {
     
    17531869                                 * removed by updating the size of the bigger
    17541870                                 * interval.
     1871                                 *
    17551872                                 */
    17561873                                node->value[node->keys - 1] -= count;
     
    17581875                        } else if (page + count * PAGE_SIZE <
    17591876                            left_pg + left_cnt*PAGE_SIZE) {
    1760                                 size_t new_cnt;
    1761                                
    17621877                                /*
    17631878                                 * The interval is contained in the rightmost
     
    17661881                                 * the original interval and also inserting a
    17671882                                 * new interval.
     1883                                 *
    17681884                                 */
    1769                                 new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1885                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    17701886                                    (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
    17711887                                node->value[node->keys - 1] -= count + new_cnt;
    1772                                 btree_insert(&a->used_space, page +
     1888                                btree_insert(&area->used_space, page +
    17731889                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    17741890                                return 1;
     
    17761892                }
    17771893                return 0;
    1778         } else if (page < leaf->key[0]) {
     1894        } else if (page < leaf->key[0])
    17791895                return 0;
    1780         }
    17811896       
    17821897        if (page > leaf->key[leaf->keys - 1]) {
    17831898                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    17841899                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    1785 
     1900               
    17861901                if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    17871902                    count * PAGE_SIZE)) {
    1788                         if (page + count * PAGE_SIZE == 
     1903                        if (page + count * PAGE_SIZE ==
    17891904                            left_pg + left_cnt * PAGE_SIZE) {
    17901905                                /*
     
    17921907                                 * interval of the leaf and can be removed by
    17931908                                 * updating the size of the bigger interval.
     1909                                 *
    17941910                                 */
    17951911                                leaf->value[leaf->keys - 1] -= count;
     
    17971913                        } else if (page + count * PAGE_SIZE < left_pg +
    17981914                            left_cnt * PAGE_SIZE) {
    1799                                 size_t new_cnt;
    1800                                
    18011915                                /*
    18021916                                 * The interval is contained in the rightmost
     
    18051919                                 * original interval and also inserting a new
    18061920                                 * interval.
     1921                                 *
    18071922                                 */
    1808                                 new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1923                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    18091924                                    (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
    18101925                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    1811                                 btree_insert(&a->used_space, page +
     1926                                btree_insert(&area->used_space, page +
    18121927                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18131928                                return 1;
     
    18151930                }
    18161931                return 0;
    1817         }       
     1932        }
    18181933       
    18191934        /*
     
    18211936         * Now the interval can be only between intervals of the leaf.
    18221937         */
     1938        btree_key_t i;
    18231939        for (i = 1; i < leaf->keys - 1; i++) {
    18241940                if (page < leaf->key[i]) {
    18251941                        uintptr_t left_pg = leaf->key[i - 1];
    18261942                        size_t left_cnt = (size_t) leaf->value[i - 1];
    1827 
     1943                       
    18281944                        /*
    18291945                         * Now the interval is between intervals corresponding
     
    18391955                                         * be removed by updating the size of
    18401956                                         * the bigger interval.
     1957                                         *
    18411958                                         */
    18421959                                        leaf->value[i - 1] -= count;
     
    18441961                                } else if (page + count * PAGE_SIZE <
    18451962                                    left_pg + left_cnt * PAGE_SIZE) {
    1846                                         size_t new_cnt;
    1847                                
    18481963                                        /*
    18491964                                         * The interval is contained in the
     
    18531968                                         * also inserting a new interval.
    18541969                                         */
    1855                                         new_cnt = ((left_pg +
     1970                                        size_t new_cnt = ((left_pg +
    18561971                                            left_cnt * PAGE_SIZE) -
    18571972                                            (page + count * PAGE_SIZE)) >>
    18581973                                            PAGE_WIDTH;
    18591974                                        leaf->value[i - 1] -= count + new_cnt;
    1860                                         btree_insert(&a->used_space, page +
     1975                                        btree_insert(&area->used_space, page +
    18611976                                            count * PAGE_SIZE, (void *) new_cnt,
    18621977                                            leaf);
     
    18671982                }
    18681983        }
    1869 
     1984       
    18701985error:
    18711986        panic("Inconsistency detected while removing %" PRIs " pages of used "
     
    18771992 * If the reference count drops to 0, the sh_info is deallocated.
    18781993 *
    1879  * @param sh_info       Pointer to address space area share info.
     1994 * @param sh_info Pointer to address space area share info.
     1995 *
    18801996 */
    18811997void sh_info_remove_reference(share_info_t *sh_info)
    18821998{
    18831999        bool dealloc = false;
    1884 
     2000       
    18852001        mutex_lock(&sh_info->lock);
    18862002        ASSERT(sh_info->refcount);
     2003       
    18872004        if (--sh_info->refcount == 0) {
    18882005                dealloc = true;
     
    18952012                for (cur = sh_info->pagemap.leaf_head.next;
    18962013                    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
    1897                         btree_node_t *node;
    1898                         unsigned int i;
     2014                        btree_node_t *node
     2015                            = list_get_instance(cur, btree_node_t, leaf_link);
     2016                        btree_key_t i;
    18992017                       
    1900                         node = list_get_instance(cur, btree_node_t, leaf_link);
    1901                         for (i = 0; i < node->keys; i++)
     2018                        for (i = 0; i < node->keys; i++)
    19022019                                frame_free((uintptr_t) node->value[i]);
    19032020                }
     
    19172034
    19182035/** Wrapper for as_area_create(). */
    1919 unative_t sys_as_area_create(uintptr_t address, size_t size, int flags)
     2036unative_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
    19202037{
    19212038        if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
     
    19272044
    19282045/** Wrapper for as_area_resize(). */
    1929 unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
     2046unative_t sys_as_area_resize(uintptr_t address, size_t size, unsigned int flags)
    19302047{
    19312048        return (unative_t) as_area_resize(AS, address, size, 0);
     
    19332050
    19342051/** Wrapper for as_area_change_flags(). */
    1935 unative_t sys_as_area_change_flags(uintptr_t address, int flags)
     2052unative_t sys_as_area_change_flags(uintptr_t address, unsigned int flags)
    19362053{
    19372054        return (unative_t) as_area_change_flags(AS, flags, address);
     
    19462063/** Get list of adress space areas.
    19472064 *
    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.
     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 *
    19512069 */
    19522070void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
    19532071{
    1954         ipl_t ipl;
    1955         size_t area_cnt, area_idx, i;
     2072        ipl_t ipl = interrupts_disable();
     2073        mutex_lock(&as->lock);
     2074       
     2075        /* First pass, count number of areas. */
     2076       
     2077        size_t area_cnt = 0;
    19562078        link_t *cur;
    1957 
    1958         as_area_info_t *info;
    1959         size_t isize;
    1960 
    1961         ipl = interrupts_disable();
    1962         mutex_lock(&as->lock);
    1963 
    1964         /* First pass, count number of areas. */
    1965 
    1966         area_cnt = 0;
    1967 
     2079       
    19682080        for (cur = as->as_area_btree.leaf_head.next;
    19692081            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    1970                 btree_node_t *node;
    1971 
    1972                 node = list_get_instance(cur, btree_node_t, leaf_link);
     2082                btree_node_t *node =
     2083                    list_get_instance(cur, btree_node_t, leaf_link);
    19732084                area_cnt += node->keys;
    19742085        }
    1975 
    1976         isize = area_cnt * sizeof(as_area_info_t);
    1977         info = malloc(isize, 0);
    1978 
     2086       
     2087        size_t isize = area_cnt * sizeof(as_area_info_t);
     2088        as_area_info_t *info = malloc(isize, 0);
     2089       
    19792090        /* Second pass, record data. */
    1980 
    1981         area_idx = 0;
    1982 
     2091       
     2092        size_t area_idx = 0;
     2093       
    19832094        for (cur = as->as_area_btree.leaf_head.next;
    19842095            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    1985                 btree_node_t *node;
    1986 
    1987                 node = list_get_instance(cur, btree_node_t, leaf_link);
    1988 
     2096                btree_node_t *node =
     2097                    list_get_instance(cur, btree_node_t, leaf_link);
     2098                btree_key_t i;
     2099               
    19892100                for (i = 0; i < node->keys; i++) {
    19902101                        as_area_t *area = node->value[i];
    1991 
     2102                       
    19922103                        ASSERT(area_idx < area_cnt);
    19932104                        mutex_lock(&area->lock);
    1994 
     2105                       
    19952106                        info[area_idx].start_addr = area->base;
    19962107                        info[area_idx].size = FRAMES2SIZE(area->pages);
    19972108                        info[area_idx].flags = area->flags;
    19982109                        ++area_idx;
    1999 
     2110                       
    20002111                        mutex_unlock(&area->lock);
    20012112                }
    20022113        }
    2003 
     2114       
    20042115        mutex_unlock(&as->lock);
    20052116        interrupts_restore(ipl);
    2006 
     2117       
    20072118        *obuf = info;
    20082119        *osize = isize;
    20092120}
    20102121
    2011 
    20122122/** Print out information about address space.
    20132123 *
    2014  * @param as            Address space.
     2124 * @param as Address space.
     2125 *
    20152126 */
    20162127void as_print(as_t *as)
    20172128{
    2018         ipl_t ipl;
    2019        
    2020         ipl = interrupts_disable();
     2129        ipl_t ipl = interrupts_disable();
    20212130        mutex_lock(&as->lock);
    20222131       
     
    20252134        for (cur = as->as_area_btree.leaf_head.next;
    20262135            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
    2027                 btree_node_t *node;
    2028                
    2029                 node = list_get_instance(cur, btree_node_t, leaf_link);
    2030                
    2031                 unsigned int i;
     2136                btree_node_t *node
     2137                    = list_get_instance(cur, btree_node_t, leaf_link);
     2138                btree_key_t i;
     2139               
    20322140                for (i = 0; i < node->keys; i++) {
    20332141                        as_area_t *area = node->value[i];
    2034                
     2142                       
    20352143                        mutex_lock(&area->lock);
    20362144                        printf("as_area: %p, base=%p, pages=%" PRIs
Note: See TracChangeset for help on using the changeset viewer.