Changeset a35b458 in mainline for kernel/generic/src/mm/as.c


Ignore:
Timestamp:
2018-03-02T20:10:49Z (7 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f1380b7
Parents:
3061bc1
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
Message:

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

File:
1 edited

Legend:

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

    r3061bc1 ra35b458  
    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.