Ignore:
File:
1 edited

Legend:

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

    rfc47885 r7250d2c  
    7171#include <memstr.h>
    7272#include <macros.h>
     73#include <bitops.h>
    7374#include <arch.h>
    7475#include <errno.h>
     
    7980#include <arch/interrupt.h>
    8081
    81 #ifdef CONFIG_VIRT_IDX_DCACHE
    82 #include <arch/mm/cache.h>
    83 #endif /* CONFIG_VIRT_IDX_DCACHE */
    84 
    8582/**
    8683 * Each architecture decides what functions will be used to carry out
     
    9794 *
    9895 * This lock protects:
    99  * - inactive_as_with_asid_head list
     96 * - inactive_as_with_asid_list
    10097 * - as->asid for each as of the as_t type
    10198 * - asids_allocated counter
     
    108105 * that have valid ASID.
    109106 */
    110 LIST_INITIALIZE(inactive_as_with_asid_head);
     107LIST_INITIALIZE(inactive_as_with_asid_list);
    111108
    112109/** Kernel address space. */
     
    238235        bool cond = true;
    239236        while (cond) {
    240                 ASSERT(!list_empty(&as->as_area_btree.leaf_head));
     237                ASSERT(!list_empty(&as->as_area_btree.leaf_list));
    241238               
    242239                btree_node_t *node =
    243                     list_get_instance(as->as_area_btree.leaf_head.next,
     240                    list_get_instance(list_first(&as->as_area_btree.leaf_list),
    244241                    btree_node_t, leaf_link);
    245242               
     
    288285/** Check area conflicts with other areas.
    289286 *
    290  * @param as         Address space.
    291  * @param va         Starting virtual address of the area being tested.
    292  * @param size       Size of the area being tested.
    293  * @param avoid_area Do not touch this area.
     287 * @param as    Address space.
     288 * @param addr  Starting virtual address of the area being tested.
     289 * @param count Number of pages in the area being tested.
     290 * @param avoid Do not touch this area.
    294291 *
    295292 * @return True if there is no conflict, false otherwise.
    296293 *
    297294 */
    298 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
    299     as_area_t *avoid_area)
    300 {
     295NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
     296    size_t count, as_area_t *avoid)
     297{
     298        ASSERT((addr % PAGE_SIZE) == 0);
    301299        ASSERT(mutex_locked(&as->lock));
    302300       
     
    304302         * We don't want any area to have conflicts with NULL page.
    305303         */
    306         if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE))
     304        if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))
    307305                return false;
    308306       
     
    316314        btree_node_t *leaf;
    317315        as_area_t *area =
    318             (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     316            (as_area_t *) btree_search(&as->as_area_btree, addr, &leaf);
    319317        if (area) {
    320                 if (area != avoid_area)
     318                if (area != avoid)
    321319                        return false;
    322320        }
     
    328326                area = (as_area_t *) node->value[node->keys - 1];
    329327               
    330                 mutex_lock(&area->lock);
    331                
    332                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     328                if (area != avoid) {
     329                        mutex_lock(&area->lock);
     330                       
     331                        if (overlaps(addr, P2SZ(count), area->base,
     332                            P2SZ(area->pages))) {
     333                                mutex_unlock(&area->lock);
     334                                return false;
     335                        }
     336                       
    333337                        mutex_unlock(&area->lock);
    334                         return false;
    335                 }
    336                
    337                 mutex_unlock(&area->lock);
     338                }
    338339        }
    339340       
     
    342343                area = (as_area_t *) node->value[0];
    343344               
    344                 mutex_lock(&area->lock);
    345                
    346                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     345                if (area != avoid) {
     346                        mutex_lock(&area->lock);
     347                       
     348                        if (overlaps(addr, P2SZ(count), area->base,
     349                            P2SZ(area->pages))) {
     350                                mutex_unlock(&area->lock);
     351                                return false;
     352                        }
     353                       
    347354                        mutex_unlock(&area->lock);
    348                         return false;
    349                 }
    350                
    351                 mutex_unlock(&area->lock);
     355                }
    352356        }
    353357       
     
    357361                area = (as_area_t *) leaf->value[i];
    358362               
    359                 if (area == avoid_area)
     363                if (area == avoid)
    360364                        continue;
    361365               
    362366                mutex_lock(&area->lock);
    363367               
    364                 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
     368                if (overlaps(addr, P2SZ(count), area->base,
     369                    P2SZ(area->pages))) {
    365370                        mutex_unlock(&area->lock);
    366371                        return false;
     
    375380         */
    376381        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    377                 return !overlaps(va, size,
    378                     KERNEL_ADDRESS_SPACE_START,
     382                return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
    379383                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    380384        }
     
    402406    mem_backend_data_t *backend_data)
    403407{
    404         if (base % PAGE_SIZE)
     408        if ((base % PAGE_SIZE) != 0)
    405409                return NULL;
    406410       
    407         if (!size)
     411        if (size == 0)
    408412                return NULL;
     413       
     414        size_t pages = SIZE2FRAMES(size);
    409415       
    410416        /* Writeable executable areas are not supported. */
     
    414420        mutex_lock(&as->lock);
    415421       
    416         if (!check_area_conflicts(as, base, size, NULL)) {
     422        if (!check_area_conflicts(as, base, pages, NULL)) {
    417423                mutex_unlock(&as->lock);
    418424                return NULL;
     
    426432        area->flags = flags;
    427433        area->attributes = attrs;
    428         area->pages = SIZE2FRAMES(size);
     434        area->pages = pages;
    429435        area->resident = 0;
    430436        area->base = base;
     
    437443                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    438444       
     445        if (area->backend && area->backend->create) {
     446                if (!area->backend->create(area)) {
     447                        free(area);
     448                        mutex_unlock(&as->lock);
     449                        return NULL;
     450                }
     451        }
     452       
    439453        btree_create(&area->used_space);
    440454        btree_insert(&as->as_area_btree, base, (void *) area, NULL);
     
    459473       
    460474        btree_node_t *leaf;
    461         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     475        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va,
     476            &leaf);
    462477        if (area) {
    463478                /* va is the base address of an address space area */
     
    467482       
    468483        /*
    469          * Search the leaf node and the righmost record of its left neighbour
     484         * Search the leaf node and the rightmost record of its left neighbour
    470485         * to find out whether this is a miss or va belongs to an address
    471486         * space area found there.
     
    479494               
    480495                mutex_lock(&area->lock);
    481                
    482                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     496
     497                if ((area->base <= va) &&
     498                    (va <= area->base + (P2SZ(area->pages) - 1)))
    483499                        return area;
    484500               
     
    490506         * Because of its position in the B+tree, it must have base < va.
    491507         */
    492         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     508        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree,
     509            leaf);
    493510        if (lnode) {
    494511                area = (as_area_t *) lnode->value[lnode->keys - 1];
     
    496513                mutex_lock(&area->lock);
    497514               
    498                 if (va < area->base + area->pages * PAGE_SIZE)
     515                if (va <= area->base + (P2SZ(area->pages) - 1))
    499516                        return area;
    500517               
     
    561578       
    562579        if (pages < area->pages) {
    563                 uintptr_t start_free = area->base + pages * PAGE_SIZE;
     580                uintptr_t start_free = area->base + P2SZ(pages);
    564581               
    565582                /*
     
    574591                 */
    575592                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    576                     area->base + pages * PAGE_SIZE, area->pages - pages);
     593                    area->base + P2SZ(pages), area->pages - pages);
    577594               
    578595                /*
     
    585602                bool cond = true;
    586603                while (cond) {
    587                         ASSERT(!list_empty(&area->used_space.leaf_head));
     604                        ASSERT(!list_empty(&area->used_space.leaf_list));
    588605                       
    589606                        btree_node_t *node =
    590                             list_get_instance(area->used_space.leaf_head.prev,
     607                            list_get_instance(list_last(&area->used_space.leaf_list),
    591608                            btree_node_t, leaf_link);
    592609                       
     
    597614                                size_t i = 0;
    598615                               
    599                                 if (overlaps(ptr, size * PAGE_SIZE, area->base,
    600                                     pages * PAGE_SIZE)) {
     616                                if (overlaps(ptr, P2SZ(size), area->base,
     617                                    P2SZ(pages))) {
    601618                                       
    602                                         if (ptr + size * PAGE_SIZE <= start_free) {
     619                                        if (ptr + P2SZ(size) <= start_free) {
    603620                                                /*
    604621                                                 * The whole interval fits
     
    631648                               
    632649                                for (; i < size; i++) {
    633                                         pte_t *pte = page_mapping_find(as, ptr +
    634                                             i * PAGE_SIZE);
     650                                        pte_t *pte = page_mapping_find(as,
     651                                            ptr + P2SZ(i), false);
    635652                                       
    636653                                        ASSERT(pte);
     
    641658                                            (area->backend->frame_free)) {
    642659                                                area->backend->frame_free(area,
    643                                                     ptr + i * PAGE_SIZE,
     660                                                    ptr + P2SZ(i),
    644661                                                    PTE_GET_FRAME(pte));
    645662                                        }
    646663                                       
    647                                         page_mapping_remove(as, ptr +
    648                                             i * PAGE_SIZE);
     664                                        page_mapping_remove(as, ptr + P2SZ(i));
    649665                                }
    650666                        }
     
    655671                 */
    656672               
    657                 tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
     673                tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
    658674                    area->pages - pages);
    659675               
    660676                /*
    661                  * Invalidate software translation caches (e.g. TSB on sparc64).
    662                  */
    663                 as_invalidate_translation_cache(as, area->base +
    664                     pages * PAGE_SIZE, area->pages - pages);
     677                 * Invalidate software translation caches
     678                 * (e.g. TSB on sparc64, PHT on ppc32).
     679                 */
     680                as_invalidate_translation_cache(as, area->base + P2SZ(pages),
     681                    area->pages - pages);
    665682                tlb_shootdown_finalize(ipl);
    666683               
     
    671688                 * Check for overlaps with other address space areas.
    672689                 */
    673                 if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
    674                     area)) {
     690                if (!check_area_conflicts(as, address, pages, area)) {
    675691                        mutex_unlock(&area->lock);
    676692                        mutex_unlock(&as->lock);
     
    679695        }
    680696       
     697        if (area->backend && area->backend->resize) {
     698                if (!area->backend->resize(area, pages)) {
     699                        mutex_unlock(&area->lock);
     700                        mutex_unlock(&as->lock);
     701                        return ENOMEM;
     702                }
     703        }
     704       
    681705        area->pages = pages;
    682706       
     
    703727        if (--sh_info->refcount == 0) {
    704728                dealloc = true;
    705                 link_t *cur;
    706729               
    707730                /*
     
    709732                 * reference from all frames found there.
    710733                 */
    711                 for (cur = sh_info->pagemap.leaf_head.next;
    712                     cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
     734                list_foreach(sh_info->pagemap.leaf_list, cur) {
    713735                        btree_node_t *node
    714736                            = list_get_instance(cur, btree_node_t, leaf_link);
     
    745767                return ENOENT;
    746768        }
     769
     770        if (area->backend && area->backend->destroy)
     771                area->backend->destroy(area);
    747772       
    748773        uintptr_t base = area->base;
     
    759784         * Visit only the pages mapped by used_space B+tree.
    760785         */
    761         link_t *cur;
    762         for (cur = area->used_space.leaf_head.next;
    763             cur != &area->used_space.leaf_head; cur = cur->next) {
     786        list_foreach(area->used_space.leaf_list, cur) {
    764787                btree_node_t *node;
    765788                btree_key_t i;
     
    771794                       
    772795                        for (size = 0; size < (size_t) node->value[i]; size++) {
    773                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     796                                pte_t *pte = page_mapping_find(as,
     797                                     ptr + P2SZ(size), false);
    774798                               
    775799                                ASSERT(pte);
     
    780804                                    (area->backend->frame_free)) {
    781805                                        area->backend->frame_free(area,
    782                                             ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
     806                                            ptr + P2SZ(size),
     807                                            PTE_GET_FRAME(pte));
    783808                                }
    784809                               
    785                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     810                                page_mapping_remove(as, ptr + P2SZ(size));
    786811                        }
    787812                }
     
    795820       
    796821        /*
    797          * Invalidate potential software translation caches (e.g. TSB on
    798          * sparc64).
     822         * Invalidate potential software translation caches
     823         * (e.g. TSB on sparc64, PHT on ppc32).
    799824         */
    800825        as_invalidate_translation_cache(as, area->base, area->pages);
     
    870895        }
    871896       
    872         size_t src_size = src_area->pages * PAGE_SIZE;
     897        size_t src_size = P2SZ(src_area->pages);
    873898        unsigned int src_flags = src_area->flags;
    874899        mem_backend_t *src_backend = src_area->backend;
     
    10361061         */
    10371062        size_t used_pages = 0;
    1038         link_t *cur;
    1039        
    1040         for (cur = area->used_space.leaf_head.next;
    1041             cur != &area->used_space.leaf_head; cur = cur->next) {
     1063       
     1064        list_foreach(area->used_space.leaf_list, cur) {
    10421065                btree_node_t *node
    10431066                    = list_get_instance(cur, btree_node_t, leaf_link);
     
    10651088        size_t frame_idx = 0;
    10661089       
    1067         for (cur = area->used_space.leaf_head.next;
    1068             cur != &area->used_space.leaf_head; cur = cur->next) {
    1069                 btree_node_t *node
    1070                     = list_get_instance(cur, btree_node_t, leaf_link);
     1090        list_foreach(area->used_space.leaf_list, cur) {
     1091                btree_node_t *node = list_get_instance(cur, btree_node_t,
     1092                    leaf_link);
    10711093                btree_key_t i;
    10721094               
     
    10761098                       
    10771099                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1078                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     1100                                pte_t *pte = page_mapping_find(as,
     1101                                    ptr + P2SZ(size), false);
    10791102                               
    10801103                                ASSERT(pte);
     
    10851108                               
    10861109                                /* Remove old mapping */
    1087                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     1110                                page_mapping_remove(as, ptr + P2SZ(size));
    10881111                        }
    10891112                }
     
    10971120       
    10981121        /*
    1099          * Invalidate potential software translation caches (e.g. TSB on
    1100          * sparc64).
     1122         * Invalidate potential software translation caches
     1123         * (e.g. TSB on sparc64, PHT on ppc32).
    11011124         */
    11021125        as_invalidate_translation_cache(as, area->base, area->pages);
     
    11171140        frame_idx = 0;
    11181141       
    1119         for (cur = area->used_space.leaf_head.next;
    1120             cur != &area->used_space.leaf_head; cur = cur->next) {
     1142        list_foreach(area->used_space.leaf_list, cur) {
    11211143                btree_node_t *node
    11221144                    = list_get_instance(cur, btree_node_t, leaf_link);
     
    11311153                               
    11321154                                /* Insert the new mapping */
    1133                                 page_mapping_insert(as, ptr + size * PAGE_SIZE,
     1155                                page_mapping_insert(as, ptr + P2SZ(size),
    11341156                                    old_frame[frame_idx++], page_flags);
    11351157                               
     
    12121234         */
    12131235        pte_t *pte;
    1214         if ((pte = page_mapping_find(AS, page))) {
     1236        if ((pte = page_mapping_find(AS, page, false))) {
    12151237                if (PTE_PRESENT(pte)) {
    12161238                        if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
     
    12621284 * thing which is forbidden in this context is locking the address space.
    12631285 *
    1264  * When this function is enetered, no spinlocks may be held.
     1286 * When this function is entered, no spinlocks may be held.
    12651287 *
    12661288 * @param old Old address space or NULL.
     
    13041326                       
    13051327                        list_append(&old_as->inactive_as_with_asid_link,
    1306                             &inactive_as_with_asid_head);
     1328                            &inactive_as_with_asid_list);
    13071329                }
    13081330               
     
    14531475       
    14541476        if (src_area) {
    1455                 size = src_area->pages * PAGE_SIZE;
     1477                size = P2SZ(src_area->pages);
    14561478                mutex_unlock(&src_area->lock);
    14571479        } else
     
    15081530                if (page >= right_pg) {
    15091531                        /* Do nothing. */
    1510                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1511                     left_cnt * PAGE_SIZE)) {
     1532                } else if (overlaps(page, P2SZ(count), left_pg,
     1533                    P2SZ(left_cnt))) {
    15121534                        /* The interval intersects with the left interval. */
    15131535                        return false;
    1514                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1515                     right_cnt * PAGE_SIZE)) {
     1536                } else if (overlaps(page, P2SZ(count), right_pg,
     1537                    P2SZ(right_cnt))) {
    15161538                        /* The interval intersects with the right interval. */
    15171539                        return false;
    1518                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1519                     (page + count * PAGE_SIZE == right_pg)) {
     1540                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1541                    (page + P2SZ(count) == right_pg)) {
    15201542                        /*
    15211543                         * The interval can be added by merging the two already
     
    15251547                        btree_remove(&area->used_space, right_pg, leaf);
    15261548                        goto success;
    1527                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1549                } else if (page == left_pg + P2SZ(left_cnt)) {
    15281550                        /*
    15291551                         * The interval can be added by simply growing the left
     
    15321554                        node->value[node->keys - 1] += count;
    15331555                        goto success;
    1534                 } else if (page + count * PAGE_SIZE == right_pg) {
     1556                } else if (page + P2SZ(count) == right_pg) {
    15351557                        /*
    15361558                         * The interval can be addded by simply moving base of
     
    15591581                 */
    15601582               
    1561                 if (overlaps(page, count * PAGE_SIZE, right_pg,
    1562                     right_cnt * PAGE_SIZE)) {
     1583                if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
    15631584                        /* The interval intersects with the right interval. */
    15641585                        return false;
    1565                 } else if (page + count * PAGE_SIZE == right_pg) {
     1586                } else if (page + P2SZ(count) == right_pg) {
    15661587                        /*
    15671588                         * The interval can be added by moving the base of the
     
    15981619                if (page < left_pg) {
    15991620                        /* Do nothing. */
    1600                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1601                     left_cnt * PAGE_SIZE)) {
     1621                } else if (overlaps(page, P2SZ(count), left_pg,
     1622                    P2SZ(left_cnt))) {
    16021623                        /* The interval intersects with the left interval. */
    16031624                        return false;
    1604                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1605                     right_cnt * PAGE_SIZE)) {
     1625                } else if (overlaps(page, P2SZ(count), right_pg,
     1626                    P2SZ(right_cnt))) {
    16061627                        /* The interval intersects with the right interval. */
    16071628                        return false;
    1608                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1609                     (page + count * PAGE_SIZE == right_pg)) {
     1629                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1630                    (page + P2SZ(count) == right_pg)) {
    16101631                        /*
    16111632                         * The interval can be added by merging the two already
     
    16151636                        btree_remove(&area->used_space, right_pg, node);
    16161637                        goto success;
    1617                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1638                } else if (page == left_pg + P2SZ(left_cnt)) {
    16181639                        /*
    16191640                         * The interval can be added by simply growing the left
     
    16221643                        leaf->value[leaf->keys - 1] += count;
    16231644                        goto success;
    1624                 } else if (page + count * PAGE_SIZE == right_pg) {
     1645                } else if (page + P2SZ(count) == right_pg) {
    16251646                        /*
    16261647                         * The interval can be addded by simply moving base of
     
    16491670                 */
    16501671               
    1651                 if (overlaps(page, count * PAGE_SIZE, left_pg,
    1652                     left_cnt * PAGE_SIZE)) {
     1672                if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
    16531673                        /* The interval intersects with the left interval. */
    16541674                        return false;
    1655                 } else if (left_pg + left_cnt * PAGE_SIZE == page) {
     1675                } else if (left_pg + P2SZ(left_cnt) == page) {
    16561676                        /*
    16571677                         * The interval can be added by growing the left
     
    16881708                         */
    16891709                       
    1690                         if (overlaps(page, count * PAGE_SIZE, left_pg,
    1691                             left_cnt * PAGE_SIZE)) {
     1710                        if (overlaps(page, P2SZ(count), left_pg,
     1711                            P2SZ(left_cnt))) {
    16921712                                /*
    16931713                                 * The interval intersects with the left
     
    16951715                                 */
    16961716                                return false;
    1697                         } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1698                             right_cnt * PAGE_SIZE)) {
     1717                        } else if (overlaps(page, P2SZ(count), right_pg,
     1718                            P2SZ(right_cnt))) {
    16991719                                /*
    17001720                                 * The interval intersects with the right
     
    17021722                                 */
    17031723                                return false;
    1704                         } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1705                             (page + count * PAGE_SIZE == right_pg)) {
     1724                        } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1725                            (page + P2SZ(count) == right_pg)) {
    17061726                                /*
    17071727                                 * The interval can be added by merging the two
     
    17111731                                btree_remove(&area->used_space, right_pg, leaf);
    17121732                                goto success;
    1713                         } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1733                        } else if (page == left_pg + P2SZ(left_cnt)) {
    17141734                                /*
    17151735                                 * The interval can be added by simply growing
     
    17181738                                leaf->value[i - 1] += count;
    17191739                                goto success;
    1720                         } else if (page + count * PAGE_SIZE == right_pg) {
     1740                        } else if (page + P2SZ(count) == right_pg) {
    17211741                                /*
    17221742                                 * The interval can be addded by simply moving
     
    17841804                        for (i = 0; i < leaf->keys; i++) {
    17851805                                if (leaf->key[i] == page) {
    1786                                         leaf->key[i] += count * PAGE_SIZE;
     1806                                        leaf->key[i] += P2SZ(count);
    17871807                                        leaf->value[i] -= count;
    17881808                                        goto success;
     
    17941814        }
    17951815       
    1796         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     1816        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
     1817            leaf);
    17971818        if ((node) && (page < leaf->key[0])) {
    17981819                uintptr_t left_pg = node->key[node->keys - 1];
    17991820                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18001821               
    1801                 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1802                     count * PAGE_SIZE)) {
    1803                         if (page + count * PAGE_SIZE ==
    1804                             left_pg + left_cnt * PAGE_SIZE) {
     1822                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1823                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18051824                                /*
    18061825                                 * The interval is contained in the rightmost
     
    18111830                                node->value[node->keys - 1] -= count;
    18121831                                goto success;
    1813                         } else if (page + count * PAGE_SIZE <
    1814                             left_pg + left_cnt*PAGE_SIZE) {
     1832                        } else if (page + P2SZ(count) <
     1833                            left_pg + P2SZ(left_cnt)) {
     1834                                size_t new_cnt;
     1835
    18151836                                /*
    18161837                                 * The interval is contained in the rightmost
     
    18201841                                 * new interval.
    18211842                                 */
    1822                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1823                                     (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
     1843                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1844                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18241845                                node->value[node->keys - 1] -= count + new_cnt;
    18251846                                btree_insert(&area->used_space, page +
    1826                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1847                                    P2SZ(count), (void *) new_cnt, leaf);
    18271848                                goto success;
    18281849                        }
     
    18371858                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18381859               
    1839                 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1840                     count * PAGE_SIZE)) {
    1841                         if (page + count * PAGE_SIZE ==
    1842                             left_pg + left_cnt * PAGE_SIZE) {
     1860                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1861                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18431862                                /*
    18441863                                 * The interval is contained in the rightmost
     
    18481867                                leaf->value[leaf->keys - 1] -= count;
    18491868                                goto success;
    1850                         } else if (page + count * PAGE_SIZE < left_pg +
    1851                             left_cnt * PAGE_SIZE) {
     1869                        } else if (page + P2SZ(count) < left_pg +
     1870                            P2SZ(left_cnt)) {
     1871                                size_t new_cnt;
     1872
    18521873                                /*
    18531874                                 * The interval is contained in the rightmost
     
    18571878                                 * interval.
    18581879                                 */
    1859                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1860                                     (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
     1880                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1881                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18611882                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18621883                                btree_insert(&area->used_space, page +
    1863                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1884                                    P2SZ(count), (void *) new_cnt, leaf);
    18641885                                goto success;
    18651886                        }
     
    18831904                         * to (i - 1) and i.
    18841905                         */
    1885                         if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
    1886                             count * PAGE_SIZE)) {
    1887                                 if (page + count * PAGE_SIZE ==
    1888                                     left_pg + left_cnt*PAGE_SIZE) {
     1906                        if (overlaps(left_pg, P2SZ(left_cnt), page,
     1907                            P2SZ(count))) {
     1908                                if (page + P2SZ(count) ==
     1909                                    left_pg + P2SZ(left_cnt)) {
    18891910                                        /*
    18901911                                         * The interval is contained in the
     
    18951916                                        leaf->value[i - 1] -= count;
    18961917                                        goto success;
    1897                                 } else if (page + count * PAGE_SIZE <
    1898                                     left_pg + left_cnt * PAGE_SIZE) {
     1918                                } else if (page + P2SZ(count) <
     1919                                    left_pg + P2SZ(left_cnt)) {
     1920                                        size_t new_cnt;
     1921
    18991922                                        /*
    19001923                                         * The interval is contained in the
     
    19041927                                         * also inserting a new interval.
    19051928                                         */
    1906                                         size_t new_cnt = ((left_pg +
    1907                                             left_cnt * PAGE_SIZE) -
    1908                                             (page + count * PAGE_SIZE)) >>
     1929                                        new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1930                                            (page + P2SZ(count))) >>
    19091931                                            PAGE_WIDTH;
    19101932                                        leaf->value[i - 1] -= count + new_cnt;
    19111933                                        btree_insert(&area->used_space, page +
    1912                                             count * PAGE_SIZE, (void *) new_cnt,
     1934                                            P2SZ(count), (void *) new_cnt,
    19131935                                            leaf);
    19141936                                        goto success;
     
    19611983}
    19621984
     1985/** Return pointer to unmapped address space area
     1986 *
     1987 * @param base Lowest address bound.
     1988 * @param size Requested size of the allocation.
     1989 *
     1990 * @return Pointer to the beginning of unmapped address space area.
     1991 *
     1992 */
     1993sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
     1994{
     1995        if (size == 0)
     1996                return 0;
     1997       
     1998        /*
     1999         * Make sure we allocate from page-aligned
     2000         * address. Check for possible overflow in
     2001         * each step.
     2002         */
     2003       
     2004        size_t pages = SIZE2FRAMES(size);
     2005        uintptr_t ret = 0;
     2006       
     2007        /*
     2008         * Find the lowest unmapped address aligned on the sz
     2009         * boundary, not smaller than base and of the required size.
     2010         */
     2011       
     2012        mutex_lock(&AS->lock);
     2013       
     2014        /* First check the base address itself */
     2015        uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
     2016        if ((addr >= base) &&
     2017            (check_area_conflicts(AS, addr, pages, NULL)))
     2018                ret = addr;
     2019       
     2020        /* Eventually check the addresses behind each area */
     2021        list_foreach(AS->as_area_btree.leaf_list, cur) {
     2022                if (ret != 0)
     2023                        break;
     2024
     2025                btree_node_t *node =
     2026                    list_get_instance(cur, btree_node_t, leaf_link);
     2027               
     2028                btree_key_t i;
     2029                for (i = 0; (ret == 0) && (i < node->keys); i++) {
     2030                        uintptr_t addr;
     2031
     2032                        as_area_t *area = (as_area_t *) node->value[i];
     2033                       
     2034                        mutex_lock(&area->lock);
     2035                       
     2036                        addr = ALIGN_UP(area->base + P2SZ(area->pages),
     2037                            PAGE_SIZE);
     2038                       
     2039                        if ((addr >= base) && (addr >= area->base) &&
     2040                            (check_area_conflicts(AS, addr, pages, area)))
     2041                                ret = addr;
     2042                       
     2043                        mutex_unlock(&area->lock);
     2044                }
     2045        }
     2046       
     2047        mutex_unlock(&AS->lock);
     2048       
     2049        return (sysarg_t) ret;
     2050}
     2051
    19632052/** Get list of adress space areas.
    19642053 *
     
    19752064       
    19762065        size_t area_cnt = 0;
    1977         link_t *cur;
    1978        
    1979         for (cur = as->as_area_btree.leaf_head.next;
    1980             cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     2066       
     2067        list_foreach(as->as_area_btree.leaf_list, cur) {
    19812068                btree_node_t *node =
    19822069                    list_get_instance(cur, btree_node_t, leaf_link);
     
    19912078        size_t area_idx = 0;
    19922079       
    1993         for (cur = as->as_area_btree.leaf_head.next;
    1994             cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     2080        list_foreach(as->as_area_btree.leaf_list, cur) {
    19952081                btree_node_t *node =
    19962082                    list_get_instance(cur, btree_node_t, leaf_link);
     
    20042090                       
    20052091                        info[area_idx].start_addr = area->base;
    2006                         info[area_idx].size = FRAMES2SIZE(area->pages);
     2092                        info[area_idx].size = P2SZ(area->pages);
    20072093                        info[area_idx].flags = area->flags;
    20082094                        ++area_idx;
     
    20272113        mutex_lock(&as->lock);
    20282114       
    2029         /* print out info about address space areas */
    2030         link_t *cur;
    2031         for (cur = as->as_area_btree.leaf_head.next;
    2032             cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     2115        /* Print out info about address space areas */
     2116        list_foreach(as->as_area_btree.leaf_list, cur) {
    20332117                btree_node_t *node
    20342118                    = list_get_instance(cur, btree_node_t, leaf_link);
     
    20422126                            " (%p - %p)\n", area, (void *) area->base,
    20432127                            area->pages, (void *) area->base,
    2044                             (void *) (area->base + FRAMES2SIZE(area->pages)));
     2128                            (void *) (area->base + P2SZ(area->pages)));
    20452129                        mutex_unlock(&area->lock);
    20462130                }
Note: See TracChangeset for help on using the changeset viewer.