Ignore:
File:
1 edited

Legend:

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

    ra35b458 r1b20da0  
    114114{
    115115        as_t *as = (as_t *) obj;
    116 
     116       
    117117        link_initialize(&as->inactive_as_with_asid_link);
    118118        mutex_initialize(&as->lock, MUTEX_PASSIVE);
    119 
     119       
    120120        return as_constructor_arch(as, flags);
    121121}
     
    130130{
    131131        as_arch_init();
    132 
     132       
    133133        as_cache = slab_cache_create("as_t", sizeof(as_t), 0,
    134134            as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
    135 
     135       
    136136        AS_KERNEL = as_create(FLAG_AS_KERNEL);
    137137        if (!AS_KERNEL)
    138138                panic("Cannot create kernel address space.");
    139 
     139       
    140140        /*
    141141         * Make sure the kernel address space
     
    155155        as_t *as = (as_t *) slab_alloc(as_cache, 0);
    156156        (void) as_create_arch(as, 0);
    157 
     157       
    158158        btree_create(&as->as_area_btree);
    159 
     159       
    160160        if (flags & FLAG_AS_KERNEL)
    161161                as->asid = ASID_KERNEL;
    162162        else
    163163                as->asid = ASID_INVALID;
    164 
     164       
    165165        atomic_set(&as->refcount, 0);
    166166        as->cpu_refcount = 0;
    167 
     167       
    168168#ifdef AS_PAGE_TABLE
    169169        as->genarch.page_table = page_table_create(flags);
     
    171171        page_table_create(flags);
    172172#endif
    173 
     173       
    174174        return as;
    175175}
     
    188188{
    189189        DEADLOCK_PROBE_INIT(p_asidlock);
    190 
     190       
    191191        assert(as != AS);
    192192        assert(atomic_get(&as->refcount) == 0);
    193 
     193       
    194194        /*
    195195         * Since there is no reference to this address space, it is safe not to
    196196         * lock its mutex.
    197197         */
    198 
     198       
    199199        /*
    200200         * We need to avoid deadlock between TLB shootdown and asidlock.
     
    206206        preemption_disable();
    207207        ipl_t ipl = interrupts_read();
    208 
     208       
    209209retry:
    210210        interrupts_disable();
     
    214214                goto retry;
    215215        }
    216 
     216       
    217217        /* Interrupts disabled, enable preemption */
    218218        preemption_enable();
    219 
     219       
    220220        if ((as->asid != ASID_INVALID) && (as != AS_KERNEL)) {
    221221                if (as->cpu_refcount == 0)
    222222                        list_remove(&as->inactive_as_with_asid_link);
    223 
     223               
    224224                asid_put(as->asid);
    225225        }
    226 
     226       
    227227        spinlock_unlock(&asidlock);
    228228        interrupts_restore(ipl);
    229 
    230 
     229       
     230       
    231231        /*
    232232         * Destroy address space areas of the address space.
     
    237237        while (cond) {
    238238                assert(!list_empty(&as->as_area_btree.leaf_list));
    239 
     239               
    240240                btree_node_t *node =
    241241                    list_get_instance(list_first(&as->as_area_btree.leaf_list),
    242242                    btree_node_t, leaf_link);
    243 
     243               
    244244                if ((cond = node->keys))
    245245                        as_area_destroy(as, node->key[0]);
    246246        }
    247 
     247       
    248248        btree_destroy(&as->as_area_btree);
    249 
     249       
    250250#ifdef AS_PAGE_TABLE
    251251        page_table_destroy(as->genarch.page_table);
     
    253253        page_table_destroy(NULL);
    254254#endif
    255 
     255       
    256256        slab_free(as_cache, as);
    257257}
     
    307307        if (overflows_into_positive(addr, P2SZ(count)))
    308308                return false;
    309 
     309       
    310310        /*
    311311         * We don't want any area to have conflicts with NULL page.
     
    328328                        return false;
    329329        }
    330 
     330       
    331331        /* First, check the two border cases. */
    332332        btree_node_t *node =
     
    334334        if (node) {
    335335                area = (as_area_t *) node->value[node->keys - 1];
    336 
     336               
    337337                if (area != avoid) {
    338338                        mutex_lock(&area->lock);
     
    346346                        int const gp = (guarded ||
    347347                            (area->flags & AS_AREA_GUARD)) ? 1 : 0;
    348 
     348                       
    349349                        /*
    350350                         * The area comes from the left neighbour node, which
     
    358358                                return false;
    359359                        }
    360 
     360                       
    361361                        mutex_unlock(&area->lock);
    362362                }
    363363        }
    364 
     364       
    365365        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    366366        if (node) {
    367367                area = (as_area_t *) node->value[0];
    368 
     368               
    369369                if (area != avoid) {
    370370                        int gp;
     
    382382                                gp--;
    383383                        }
    384 
     384                       
    385385                        if (overlaps(addr, P2SZ(count + gp), area->base,
    386386                            P2SZ(area->pages))) {
     
    388388                                return false;
    389389                        }
    390 
     390                       
    391391                        mutex_unlock(&area->lock);
    392392                }
    393393        }
    394 
     394       
    395395        /* Second, check the leaf node. */
    396396        btree_key_t i;
     
    399399                int agp;
    400400                int gp;
    401 
     401               
    402402                if (area == avoid)
    403403                        continue;
    404 
     404               
    405405                mutex_lock(&area->lock);
    406406
     
    421421                        return false;
    422422                }
    423 
     423               
    424424                mutex_unlock(&area->lock);
    425425        }
    426 
     426       
    427427        /*
    428428         * So far, the area does not conflict with other areas.
     
    434434                    addr, P2SZ(count));
    435435        }
    436 
     436       
    437437        return true;
    438438}
     
    456456{
    457457        assert(mutex_locked(&as->lock));
    458 
     458       
    459459        if (size == 0)
    460460                return (uintptr_t) -1;
    461 
     461       
    462462        /*
    463463         * Make sure we allocate from page-aligned
     
    465465         * each step.
    466466         */
    467 
     467       
    468468        size_t pages = SIZE2FRAMES(size);
    469 
     469       
    470470        /*
    471471         * Find the lowest unmapped address aligned on the size
    472472         * boundary, not smaller than bound and of the required size.
    473473         */
    474 
     474       
    475475        /* First check the bound address itself */
    476476        uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
     
    486486                        return addr;
    487487        }
    488 
     488       
    489489        /* Eventually check the addresses behind each area */
    490490        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
    491 
     491               
    492492                for (btree_key_t i = 0; i < node->keys; i++) {
    493493                        as_area_t *area = (as_area_t *) node->value[i];
    494 
     494                       
    495495                        mutex_lock(&area->lock);
    496 
     496                       
    497497                        addr =
    498498                            ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
     
    508508                            ((addr >= bound) && (addr >= area->base) &&
    509509                            (check_area_conflicts(as, addr, pages, guarded, area)));
    510 
     510                       
    511511                        mutex_unlock(&area->lock);
    512 
     512                       
    513513                        if (avail)
    514514                                return addr;
    515515                }
    516516        }
    517 
     517       
    518518        /* No suitable address space area found */
    519519        return (uintptr_t) -1;
     
    530530{
    531531        bool dealloc = false;
    532 
     532       
    533533        mutex_lock(&sh_info->lock);
    534534        assert(sh_info->refcount);
    535 
     535       
    536536        if (--sh_info->refcount == 0) {
    537537                dealloc = true;
    538 
     538               
    539539                /*
    540540                 * Now walk carefully the pagemap B+tree and free/remove
     
    544544                    btree_node_t, node) {
    545545                        btree_key_t i;
    546 
     546                       
    547547                        for (i = 0; i < node->keys; i++)
    548548                                frame_free((uintptr_t) node->value[i], 1);
    549549                }
    550 
     550               
    551551        }
    552552        mutex_unlock(&sh_info->lock);
    553 
     553       
    554554        if (dealloc) {
    555555                if (sh_info->backend && sh_info->backend->destroy_shared_data) {
     
    588588        if ((*base != (uintptr_t) AS_AREA_ANY) && !IS_ALIGNED(*base, PAGE_SIZE))
    589589                return NULL;
    590 
     590       
    591591        if (size == 0)
    592592                return NULL;
    593593
    594594        size_t pages = SIZE2FRAMES(size);
    595 
     595       
    596596        /* Writeable executable areas are not supported. */
    597597        if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
     
    599599
    600600        bool const guarded = flags & AS_AREA_GUARD;
    601 
     601       
    602602        mutex_lock(&as->lock);
    603 
     603       
    604604        if (*base == (uintptr_t) AS_AREA_ANY) {
    605605                *base = as_get_unmapped_area(as, bound, size, guarded);
     
    619619                return NULL;
    620620        }
    621 
     621       
    622622        as_area_t *area = (as_area_t *) malloc(sizeof(as_area_t), 0);
    623 
     623       
    624624        mutex_initialize(&area->lock, MUTEX_PASSIVE);
    625 
     625       
    626626        area->as = as;
    627627        area->flags = flags;
     
    632632        area->backend = backend;
    633633        area->sh_info = NULL;
    634 
     634       
    635635        if (backend_data)
    636636                area->backend_data = *backend_data;
     
    655655
    656656                area->sh_info = si;
    657 
     657       
    658658                if (area->backend && area->backend->create_shared_data) {
    659659                        if (!area->backend->create_shared_data(area)) {
     
    679679        btree_insert(&as->as_area_btree, *base, (void *) area,
    680680            NULL);
    681 
     681       
    682682        mutex_unlock(&as->lock);
    683 
     683       
    684684        return area;
    685685}
     
    697697{
    698698        assert(mutex_locked(&as->lock));
    699 
     699       
    700700        btree_node_t *leaf;
    701701        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va,
     
    706706                return area;
    707707        }
    708 
     708       
    709709        /*
    710710         * Search the leaf node and the rightmost record of its left neighbour
     
    712712         * space area found there.
    713713         */
    714 
     714       
    715715        /* First, search the leaf node itself. */
    716716        btree_key_t i;
    717 
     717       
    718718        for (i = 0; i < leaf->keys; i++) {
    719719                area = (as_area_t *) leaf->value[i];
    720 
     720               
    721721                mutex_lock(&area->lock);
    722722
     
    724724                    (va <= area->base + (P2SZ(area->pages) - 1)))
    725725                        return area;
    726 
     726               
    727727                mutex_unlock(&area->lock);
    728728        }
    729 
     729       
    730730        /*
    731731         * Second, locate the left neighbour and test its last record.
     
    736736        if (lnode) {
    737737                area = (as_area_t *) lnode->value[lnode->keys - 1];
    738 
     738               
    739739                mutex_lock(&area->lock);
    740 
     740               
    741741                if (va <= area->base + (P2SZ(area->pages) - 1))
    742742                        return area;
    743 
     743               
    744744                mutex_unlock(&area->lock);
    745745        }
    746 
     746       
    747747        return NULL;
    748748}
     
    766766
    767767        mutex_lock(&as->lock);
    768 
     768       
    769769        /*
    770770         * Locate the area.
     
    784784                return ENOTSUP;
    785785        }
    786 
     786       
    787787        mutex_lock(&area->sh_info->lock);
    788788        if (area->sh_info->shared) {
     
    797797        }
    798798        mutex_unlock(&area->sh_info->lock);
    799 
     799       
    800800        size_t pages = SIZE2FRAMES((address - area->base) + size);
    801801        if (!pages) {
     
    807807                return EPERM;
    808808        }
    809 
     809       
    810810        if (pages < area->pages) {
    811811                uintptr_t start_free = area->base + P2SZ(pages);
    812 
     812               
    813813                /*
    814814                 * Shrinking the area.
    815815                 * No need to check for overlaps.
    816816                 */
    817 
     817               
    818818                page_table_lock(as, false);
    819 
     819               
    820820                /*
    821821                 * Remove frames belonging to used space starting from
     
    828828                while (cond) {
    829829                        assert(!list_empty(&area->used_space.leaf_list));
    830 
     830                       
    831831                        btree_node_t *node =
    832832                            list_get_instance(list_last(&area->used_space.leaf_list),
    833833                            btree_node_t, leaf_link);
    834 
     834                       
    835835                        if ((cond = (node->keys != 0))) {
    836836                                uintptr_t ptr = node->key[node->keys - 1];
     
    838838                                    (size_t) node->value[node->keys - 1];
    839839                                size_t i = 0;
    840 
     840                               
    841841                                if (overlaps(ptr, P2SZ(node_size), area->base,
    842842                                    P2SZ(pages))) {
    843 
     843                                       
    844844                                        if (ptr + P2SZ(node_size) <= start_free) {
    845845                                                /*
     
    850850                                                break;
    851851                                        }
    852 
     852                                       
    853853                                        /*
    854854                                         * Part of the interval corresponding
     
    856856                                         * address space area.
    857857                                         */
    858 
     858                                       
    859859                                        /* We are almost done */
    860860                                        cond = false;
     
    871871                                                panic("Cannot remove used space.");
    872872                                }
    873 
     873                               
    874874                                /*
    875875                                 * Start TLB shootdown sequence.
     
    887887                                    as->asid, area->base + P2SZ(pages),
    888888                                    area->pages - pages);
    889 
     889               
    890890                                for (; i < node_size; i++) {
    891891                                        pte_t pte;
    892892                                        bool found = page_mapping_find(as,
    893893                                            ptr + P2SZ(i), false, &pte);
    894 
     894                                       
    895895                                        assert(found);
    896896                                        assert(PTE_VALID(&pte));
    897897                                        assert(PTE_PRESENT(&pte));
    898 
     898                                       
    899899                                        if ((area->backend) &&
    900900                                            (area->backend->frame_free)) {
     
    903903                                                    PTE_GET_FRAME(&pte));
    904904                                        }
    905 
     905                                       
    906906                                        page_mapping_remove(as, ptr + P2SZ(i));
    907907                                }
    908 
     908               
    909909                                /*
    910910                                 * Finish TLB shootdown sequence.
    911911                                 */
    912 
     912               
    913913                                tlb_invalidate_pages(as->asid,
    914914                                    area->base + P2SZ(pages),
    915915                                    area->pages - pages);
    916 
     916               
    917917                                /*
    918918                                 * Invalidate software translation caches
     
    944944                }
    945945        }
    946 
     946       
    947947        if (area->backend && area->backend->resize) {
    948948                if (!area->backend->resize(area, pages)) {
     
    952952                }
    953953        }
    954 
     954       
    955955        area->pages = pages;
    956 
     956       
    957957        mutex_unlock(&area->lock);
    958958        mutex_unlock(&as->lock);
    959 
     959       
    960960        return 0;
    961961}
     
    972972{
    973973        mutex_lock(&as->lock);
    974 
     974       
    975975        as_area_t *area = find_area_and_lock(as, address);
    976976        if (!area) {
     
    981981        if (area->backend && area->backend->destroy)
    982982                area->backend->destroy(area);
    983 
     983       
    984984        uintptr_t base = area->base;
    985 
     985       
    986986        page_table_lock(as, false);
    987 
     987       
    988988        /*
    989989         * Start TLB shootdown sequence.
     
    991991        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
    992992            area->pages);
    993 
     993       
    994994        /*
    995995         * Visit only the pages mapped by used_space B+tree.
     
    998998            node) {
    999999                btree_key_t i;
    1000 
     1000               
    10011001                for (i = 0; i < node->keys; i++) {
    10021002                        uintptr_t ptr = node->key[i];
    10031003                        size_t size;
    1004 
     1004                       
    10051005                        for (size = 0; size < (size_t) node->value[i]; size++) {
    10061006                                pte_t pte;
    10071007                                bool found = page_mapping_find(as,
    10081008                                     ptr + P2SZ(size), false, &pte);
    1009 
     1009                               
    10101010                                assert(found);
    10111011                                assert(PTE_VALID(&pte));
    10121012                                assert(PTE_PRESENT(&pte));
    1013 
     1013                               
    10141014                                if ((area->backend) &&
    10151015                                    (area->backend->frame_free)) {
     
    10181018                                            PTE_GET_FRAME(&pte));
    10191019                                }
    1020 
     1020                               
    10211021                                page_mapping_remove(as, ptr + P2SZ(size));
    10221022                        }
    10231023                }
    10241024        }
    1025 
     1025       
    10261026        /*
    10271027         * Finish TLB shootdown sequence.
    10281028         */
    1029 
     1029       
    10301030        tlb_invalidate_pages(as->asid, area->base, area->pages);
    1031 
     1031       
    10321032        /*
    10331033         * Invalidate potential software translation caches
     
    10361036        as_invalidate_translation_cache(as, area->base, area->pages);
    10371037        tlb_shootdown_finalize(ipl);
    1038 
     1038       
    10391039        page_table_unlock(as, false);
    1040 
     1040       
    10411041        btree_destroy(&area->used_space);
    1042 
     1042       
    10431043        area->attributes |= AS_AREA_ATTR_PARTIAL;
    1044 
     1044       
    10451045        sh_info_remove_reference(area->sh_info);
    1046 
     1046       
    10471047        mutex_unlock(&area->lock);
    1048 
     1048       
    10491049        /*
    10501050         * Remove the empty area from address space.
    10511051         */
    10521052        btree_remove(&as->as_area_btree, base, NULL);
    1053 
     1053       
    10541054        free(area);
    1055 
     1055       
    10561056        mutex_unlock(&as->lock);
    10571057        return 0;
     
    10981098                return ENOENT;
    10991099        }
    1100 
     1100       
    11011101        if (!src_area->backend->is_shareable(src_area)) {
    11021102                /*
     
    11071107                return ENOTSUP;
    11081108        }
    1109 
     1109       
    11101110        size_t src_size = P2SZ(src_area->pages);
    11111111        unsigned int src_flags = src_area->flags;
    11121112        mem_backend_t *src_backend = src_area->backend;
    11131113        mem_backend_data_t src_backend_data = src_area->backend_data;
    1114 
     1114       
    11151115        /* Share the cacheable flag from the original mapping */
    11161116        if (src_flags & AS_AREA_CACHEABLE)
    11171117                dst_flags_mask |= AS_AREA_CACHEABLE;
    1118 
     1118       
    11191119        if ((src_size != acc_size) ||
    11201120            ((src_flags & dst_flags_mask) != dst_flags_mask)) {
     
    11231123                return EPERM;
    11241124        }
    1125 
     1125       
    11261126        /*
    11271127         * Now we are committed to sharing the area.
     
    11301130         */
    11311131        share_info_t *sh_info = src_area->sh_info;
    1132 
     1132       
    11331133        mutex_lock(&sh_info->lock);
    11341134        sh_info->refcount++;
     
    11441144                src_area->backend->share(src_area);
    11451145        }
    1146 
     1146       
    11471147        mutex_unlock(&src_area->lock);
    11481148        mutex_unlock(&src_as->lock);
    1149 
     1149       
    11501150        /*
    11511151         * Create copy of the source address space area.
     
    11641164                 */
    11651165                sh_info_remove_reference(sh_info);
    1166 
     1166               
    11671167                return ENOMEM;
    11681168        }
    1169 
     1169       
    11701170        /*
    11711171         * Now the destination address space area has been
     
    11791179        mutex_unlock(&dst_area->lock);
    11801180        mutex_unlock(&dst_as->lock);
    1181 
     1181       
    11821182        return 0;
    11831183}
     
    11951195{
    11961196        assert(mutex_locked(&area->lock));
    1197 
     1197       
    11981198        int flagmap[] = {
    11991199                [PF_ACCESS_READ] = AS_AREA_READ,
     
    12011201                [PF_ACCESS_EXEC] = AS_AREA_EXEC
    12021202        };
    1203 
     1203       
    12041204        if (!(area->flags & flagmap[access]))
    12051205                return false;
    1206 
     1206       
    12071207        return true;
    12081208}
     
    12181218{
    12191219        unsigned int flags = PAGE_USER | PAGE_PRESENT;
    1220 
     1220       
    12211221        if (aflags & AS_AREA_READ)
    12221222                flags |= PAGE_READ;
    1223 
     1223               
    12241224        if (aflags & AS_AREA_WRITE)
    12251225                flags |= PAGE_WRITE;
    1226 
     1226       
    12271227        if (aflags & AS_AREA_EXEC)
    12281228                flags |= PAGE_EXEC;
    1229 
     1229       
    12301230        if (aflags & AS_AREA_CACHEABLE)
    12311231                flags |= PAGE_CACHEABLE;
    1232 
     1232       
    12331233        return flags;
    12341234}
     
    12521252        /* Flags for the new memory mapping */
    12531253        unsigned int page_flags = area_flags_to_page_flags(flags);
    1254 
     1254       
    12551255        mutex_lock(&as->lock);
    1256 
     1256       
    12571257        as_area_t *area = find_area_and_lock(as, address);
    12581258        if (!area) {
     
    12601260                return ENOENT;
    12611261        }
    1262 
     1262       
    12631263        if (area->backend != &anon_backend) {
    12641264                /* Copying non-anonymous memory not supported yet */
     
    12771277        }
    12781278        mutex_unlock(&area->sh_info->lock);
    1279 
     1279       
    12801280        /*
    12811281         * Compute total number of used pages in the used_space B+tree
    12821282         */
    12831283        size_t used_pages = 0;
    1284 
     1284       
    12851285        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    12861286            node) {
    12871287                btree_key_t i;
    1288 
     1288               
    12891289                for (i = 0; i < node->keys; i++)
    12901290                        used_pages += (size_t) node->value[i];
    12911291        }
    1292 
     1292       
    12931293        /* An array for storing frame numbers */
    12941294        uintptr_t *old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
    1295 
     1295       
    12961296        page_table_lock(as, false);
    1297 
     1297       
    12981298        /*
    12991299         * Start TLB shootdown sequence.
     
    13011301        ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
    13021302            area->pages);
    1303 
     1303       
    13041304        /*
    13051305         * Remove used pages from page tables and remember their frame
     
    13071307         */
    13081308        size_t frame_idx = 0;
    1309 
     1309       
    13101310        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    13111311            node) {
    13121312                btree_key_t i;
    1313 
     1313               
    13141314                for (i = 0; i < node->keys; i++) {
    13151315                        uintptr_t ptr = node->key[i];
    13161316                        size_t size;
    1317 
     1317                       
    13181318                        for (size = 0; size < (size_t) node->value[i]; size++) {
    13191319                                pte_t pte;
    13201320                                bool found = page_mapping_find(as,
    13211321                                    ptr + P2SZ(size), false, &pte);
    1322 
     1322                               
    13231323                                assert(found);
    13241324                                assert(PTE_VALID(&pte));
    13251325                                assert(PTE_PRESENT(&pte));
    1326 
     1326                               
    13271327                                old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
    1328 
     1328                               
    13291329                                /* Remove old mapping */
    13301330                                page_mapping_remove(as, ptr + P2SZ(size));
     
    13321332                }
    13331333        }
    1334 
     1334       
    13351335        /*
    13361336         * Finish TLB shootdown sequence.
    13371337         */
    1338 
     1338       
    13391339        tlb_invalidate_pages(as->asid, area->base, area->pages);
    1340 
     1340       
    13411341        /*
    13421342         * Invalidate potential software translation caches
     
    13451345        as_invalidate_translation_cache(as, area->base, area->pages);
    13461346        tlb_shootdown_finalize(ipl);
    1347 
     1347       
    13481348        page_table_unlock(as, false);
    1349 
     1349       
    13501350        /*
    13511351         * Set the new flags.
    13521352         */
    13531353        area->flags = flags;
    1354 
     1354       
    13551355        /*
    13561356         * Map pages back in with new flags. This step is kept separate
     
    13591359         */
    13601360        frame_idx = 0;
    1361 
     1361       
    13621362        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
    13631363            node) {
    13641364                btree_key_t i;
    1365 
     1365               
    13661366                for (i = 0; i < node->keys; i++) {
    13671367                        uintptr_t ptr = node->key[i];
    13681368                        size_t size;
    1369 
     1369                       
    13701370                        for (size = 0; size < (size_t) node->value[i]; size++) {
    13711371                                page_table_lock(as, false);
    1372 
     1372                               
    13731373                                /* Insert the new mapping */
    13741374                                page_mapping_insert(as, ptr + P2SZ(size),
    13751375                                    old_frame[frame_idx++], page_flags);
    1376 
     1376                               
    13771377                                page_table_unlock(as, false);
    13781378                        }
    13791379                }
    13801380        }
    1381 
     1381       
    13821382        free(old_frame);
    1383 
     1383       
    13841384        mutex_unlock(&area->lock);
    13851385        mutex_unlock(&as->lock);
    1386 
     1386       
    13871387        return 0;
    13881388}
     
    14141414        if (!THREAD)
    14151415                goto page_fault;
    1416 
     1416       
    14171417        if (!AS)
    14181418                goto page_fault;
    1419 
     1419       
    14201420        mutex_lock(&AS->lock);
    14211421        as_area_t *area = find_area_and_lock(AS, page);
     
    14281428                goto page_fault;
    14291429        }
    1430 
     1430       
    14311431        if (area->attributes & AS_AREA_ATTR_PARTIAL) {
    14321432                /*
     
    14381438                goto page_fault;
    14391439        }
    1440 
     1440       
    14411441        if ((!area->backend) || (!area->backend->page_fault)) {
    14421442                /*
     
    14481448                goto page_fault;
    14491449        }
    1450 
     1450       
    14511451        page_table_lock(AS, false);
    1452 
     1452       
    14531453        /*
    14541454         * To avoid race condition between two page faults on the same address,
     
    14671467                }
    14681468        }
    1469 
     1469       
    14701470        /*
    14711471         * Resort to the backend page fault handler.
     
    14781478                goto page_fault;
    14791479        }
    1480 
     1480       
    14811481        page_table_unlock(AS, false);
    14821482        mutex_unlock(&area->lock);
    14831483        mutex_unlock(&AS->lock);
    14841484        return AS_PF_OK;
    1485 
     1485       
    14861486page_fault:
    14871487        if (THREAD->in_copy_from_uspace) {
     
    15011501                panic_memtrap(istate, access, address, NULL);
    15021502        }
    1503 
     1503       
    15041504        return AS_PF_DEFER;
    15051505}
     
    15211521        DEADLOCK_PROBE_INIT(p_asidlock);
    15221522        preemption_disable();
    1523 
     1523       
    15241524retry:
    15251525        (void) interrupts_disable();
     
    15361536        }
    15371537        preemption_enable();
    1538 
     1538       
    15391539        /*
    15401540         * First, take care of the old address space.
     
    15421542        if (old_as) {
    15431543                assert(old_as->cpu_refcount);
    1544 
     1544               
    15451545                if ((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
    15461546                        /*
     
    15511551                         */
    15521552                        assert(old_as->asid != ASID_INVALID);
    1553 
     1553                       
    15541554                        list_append(&old_as->inactive_as_with_asid_link,
    15551555                            &inactive_as_with_asid_list);
    15561556                }
    1557 
     1557               
    15581558                /*
    15591559                 * Perform architecture-specific tasks when the address space
     
    15621562                as_deinstall_arch(old_as);
    15631563        }
    1564 
     1564       
    15651565        /*
    15661566         * Second, prepare the new address space.
     
    15721572                        new_as->asid = asid_get();
    15731573        }
    1574 
     1574       
    15751575#ifdef AS_PAGE_TABLE
    15761576        SET_PTL0_ADDRESS(new_as->genarch.page_table);
    15771577#endif
    1578 
     1578       
    15791579        /*
    15801580         * Perform architecture-specific steps.
     
    15821582         */
    15831583        as_install_arch(new_as);
    1584 
     1584       
    15851585        spinlock_unlock(&asidlock);
    1586 
     1586       
    15871587        AS = new_as;
    15881588}
     
    15981598{
    15991599        assert(mutex_locked(&area->lock));
    1600 
     1600       
    16011601        return area_flags_to_page_flags(area->flags);
    16021602}
     
    16171617        assert(as_operations);
    16181618        assert(as_operations->page_table_create);
    1619 
     1619       
    16201620        return as_operations->page_table_create(flags);
    16211621}
     
    16321632        assert(as_operations);
    16331633        assert(as_operations->page_table_destroy);
    1634 
     1634       
    16351635        as_operations->page_table_destroy(page_table);
    16361636}
     
    16531653        assert(as_operations);
    16541654        assert(as_operations->page_table_lock);
    1655 
     1655       
    16561656        as_operations->page_table_lock(as, lock);
    16571657}
     
    16671667        assert(as_operations);
    16681668        assert(as_operations->page_table_unlock);
    1669 
     1669       
    16701670        as_operations->page_table_unlock(as, unlock);
    16711671}
     
    16971697{
    16981698        size_t size;
    1699 
     1699       
    17001700        page_table_lock(AS, true);
    17011701        as_area_t *src_area = find_area_and_lock(AS, base);
    1702 
     1702       
    17031703        if (src_area) {
    17041704                size = P2SZ(src_area->pages);
     
    17061706        } else
    17071707                size = 0;
    1708 
     1708       
    17091709        page_table_unlock(AS, true);
    17101710        return size;
     
    17271727        assert(IS_ALIGNED(page, PAGE_SIZE));
    17281728        assert(count);
    1729 
     1729       
    17301730        btree_node_t *leaf = NULL;
    17311731        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
     
    17381738
    17391739        assert(leaf != NULL);
    1740 
     1740       
    17411741        if (!leaf->keys) {
    17421742                btree_insert(&area->used_space, page, (void *) count, leaf);
    17431743                goto success;
    17441744        }
    1745 
     1745       
    17461746        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
    17471747        if (node) {
     
    17501750                size_t left_cnt = (size_t) node->value[node->keys - 1];
    17511751                size_t right_cnt = (size_t) leaf->value[0];
    1752 
     1752               
    17531753                /*
    17541754                 * Examine the possibility that the interval fits
     
    17561756                 * the left neigbour and the first interval of the leaf.
    17571757                 */
    1758 
     1758               
    17591759                if (page >= right_pg) {
    17601760                        /* Do nothing. */
     
    18041804                uintptr_t right_pg = leaf->key[0];
    18051805                size_t right_cnt = (size_t) leaf->value[0];
    1806 
     1806               
    18071807                /*
    18081808                 * Investigate the border case in which the left neighbour does
    18091809                 * not exist but the interval fits from the left.
    18101810                 */
    1811 
     1811               
    18121812                if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
    18131813                        /* The interval intersects with the right interval. */
     
    18321832                }
    18331833        }
    1834 
     1834       
    18351835        node = btree_leaf_node_right_neighbour(&area->used_space, leaf);
    18361836        if (node) {
     
    18391839                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18401840                size_t right_cnt = (size_t) node->value[0];
    1841 
     1841               
    18421842                /*
    18431843                 * Examine the possibility that the interval fits
     
    18451845                 * the right neigbour and the last interval of the leaf.
    18461846                 */
    1847 
     1847               
    18481848                if (page < left_pg) {
    18491849                        /* Do nothing. */
     
    18931893                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    18941894                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    1895 
     1895               
    18961896                /*
    18971897                 * Investigate the border case in which the right neighbour
    18981898                 * does not exist but the interval fits from the right.
    18991899                 */
    1900 
     1900               
    19011901                if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
    19021902                        /* The interval intersects with the left interval. */
     
    19191919                }
    19201920        }
    1921 
     1921       
    19221922        /*
    19231923         * Note that if the algorithm made it thus far, the interval can fit
     
    19321932                        size_t left_cnt = (size_t) leaf->value[i - 1];
    19331933                        size_t right_cnt = (size_t) leaf->value[i];
    1934 
     1934                       
    19351935                        /*
    19361936                         * The interval fits between left_pg and right_pg.
    19371937                         */
    1938 
     1938                       
    19391939                        if (overlaps(page, P2SZ(count), left_pg,
    19401940                            P2SZ(left_cnt))) {
     
    19881988                }
    19891989        }
    1990 
     1990       
    19911991        panic("Inconsistency detected while adding %zu pages of used "
    19921992            "space at %p.", count, (void *) page);
    1993 
     1993       
    19941994success:
    19951995        area->resident += count;
     
    20132013        assert(IS_ALIGNED(page, PAGE_SIZE));
    20142014        assert(count);
    2015 
     2015       
    20162016        btree_node_t *leaf;
    20172017        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
     
    20382038                                }
    20392039                        }
    2040 
     2040                       
    20412041                        goto error;
    20422042                }
    20432043        }
    2044 
     2044       
    20452045        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
    20462046            leaf);
     
    20482048                uintptr_t left_pg = node->key[node->keys - 1];
    20492049                size_t left_cnt = (size_t) node->value[node->keys - 1];
    2050 
     2050               
    20512051                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
    20522052                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
     
    20782078                        }
    20792079                }
    2080 
     2080               
    20812081                return false;
    20822082        } else if (page < leaf->key[0])
    20832083                return false;
    2084 
     2084       
    20852085        if (page > leaf->key[leaf->keys - 1]) {
    20862086                uintptr_t left_pg = leaf->key[leaf->keys - 1];
    20872087                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    2088 
     2088               
    20892089                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
    20902090                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
     
    21152115                        }
    21162116                }
    2117 
     2117               
    21182118                return false;
    21192119        }
    2120 
     2120       
    21212121        /*
    21222122         * The border cases have been already resolved.
     
    21282128                        uintptr_t left_pg = leaf->key[i - 1];
    21292129                        size_t left_cnt = (size_t) leaf->value[i - 1];
    2130 
     2130                       
    21312131                        /*
    21322132                         * Now the interval is between intervals corresponding
     
    21662166                                }
    21672167                        }
    2168 
     2168                       
    21692169                        return false;
    21702170                }
    21712171        }
    2172 
     2172       
    21732173error:
    21742174        panic("Inconsistency detected while removing %zu pages of used "
    21752175            "space from %p.", count, (void *) page);
    2176 
     2176       
    21772177success:
    21782178        area->resident -= count;
     
    22042204        if (area == NULL)
    22052205                return (sysarg_t) AS_MAP_FAILED;
    2206 
     2206       
    22072207        return (sysarg_t) virt;
    22082208}
     
    22332233{
    22342234        mutex_lock(&as->lock);
    2235 
     2235       
    22362236        /* First pass, count number of areas. */
    2237 
     2237       
    22382238        size_t area_cnt = 0;
    2239 
     2239       
    22402240        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    22412241            node) {
    22422242                area_cnt += node->keys;
    22432243        }
    2244 
     2244       
    22452245        size_t isize = area_cnt * sizeof(as_area_info_t);
    22462246        as_area_info_t *info = malloc(isize, 0);
    2247 
     2247       
    22482248        /* Second pass, record data. */
    2249 
     2249       
    22502250        size_t area_idx = 0;
    2251 
     2251       
    22522252        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    22532253            node) {
    22542254                btree_key_t i;
    2255 
     2255               
    22562256                for (i = 0; i < node->keys; i++) {
    22572257                        as_area_t *area = node->value[i];
    2258 
     2258                       
    22592259                        assert(area_idx < area_cnt);
    22602260                        mutex_lock(&area->lock);
    2261 
     2261                       
    22622262                        info[area_idx].start_addr = area->base;
    22632263                        info[area_idx].size = P2SZ(area->pages);
    22642264                        info[area_idx].flags = area->flags;
    22652265                        ++area_idx;
    2266 
     2266                       
    22672267                        mutex_unlock(&area->lock);
    22682268                }
    22692269        }
    2270 
     2270       
    22712271        mutex_unlock(&as->lock);
    2272 
     2272       
    22732273        *obuf = info;
    22742274        *osize = isize;
     
    22832283{
    22842284        mutex_lock(&as->lock);
    2285 
     2285       
    22862286        /* Print out info about address space areas */
    22872287        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
    22882288            node) {
    22892289                btree_key_t i;
    2290 
     2290               
    22912291                for (i = 0; i < node->keys; i++) {
    22922292                        as_area_t *area = node->value[i];
    2293 
     2293                       
    22942294                        mutex_lock(&area->lock);
    22952295                        printf("as_area: %p, base=%p, pages=%zu"
     
    23002300                }
    23012301        }
    2302 
     2302       
    23032303        mutex_unlock(&as->lock);
    23042304}
Note: See TracChangeset for help on using the changeset viewer.