Ignore:
File:
1 edited

Legend:

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

    rfc47885 reef1b031  
    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
     
    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                /*
     
    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);
    677693                        return EADDRNOTAVAIL;
     694                }
     695        }
     696       
     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;
    678702                }
    679703        }
     
    745769                return ENOENT;
    746770        }
     771
     772        if (area->backend && area->backend->destroy)
     773                area->backend->destroy(area);
    747774       
    748775        uintptr_t base = area->base;
     
    771798                       
    772799                        for (size = 0; size < (size_t) node->value[i]; size++) {
    773                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     800                                pte_t *pte = page_mapping_find(as,
     801                                     ptr + P2SZ(size), false);
    774802                               
    775803                                ASSERT(pte);
     
    780808                                    (area->backend->frame_free)) {
    781809                                        area->backend->frame_free(area,
    782                                             ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
     810                                            ptr + P2SZ(size),
     811                                            PTE_GET_FRAME(pte));
    783812                                }
    784813                               
    785                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     814                                page_mapping_remove(as, ptr + P2SZ(size));
    786815                        }
    787816                }
     
    795824       
    796825        /*
    797          * Invalidate potential software translation caches (e.g. TSB on
    798          * sparc64).
     826         * Invalidate potential software translation caches
     827         * (e.g. TSB on sparc64, PHT on ppc32).
    799828         */
    800829        as_invalidate_translation_cache(as, area->base, area->pages);
     
    870899        }
    871900       
    872         size_t src_size = src_area->pages * PAGE_SIZE;
     901        size_t src_size = P2SZ(src_area->pages);
    873902        unsigned int src_flags = src_area->flags;
    874903        mem_backend_t *src_backend = src_area->backend;
     
    10671096        for (cur = area->used_space.leaf_head.next;
    10681097            cur != &area->used_space.leaf_head; cur = cur->next) {
    1069                 btree_node_t *node
    1070                     = list_get_instance(cur, btree_node_t, leaf_link);
     1098                btree_node_t *node = list_get_instance(cur, btree_node_t,
     1099                    leaf_link);
    10711100                btree_key_t i;
    10721101               
     
    10761105                       
    10771106                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1078                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     1107                                pte_t *pte = page_mapping_find(as,
     1108                                    ptr + P2SZ(size), false);
    10791109                               
    10801110                                ASSERT(pte);
     
    10851115                               
    10861116                                /* Remove old mapping */
    1087                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     1117                                page_mapping_remove(as, ptr + P2SZ(size));
    10881118                        }
    10891119                }
     
    10971127       
    10981128        /*
    1099          * Invalidate potential software translation caches (e.g. TSB on
    1100          * sparc64).
     1129         * Invalidate potential software translation caches
     1130         * (e.g. TSB on sparc64, PHT on ppc32).
    11011131         */
    11021132        as_invalidate_translation_cache(as, area->base, area->pages);
     
    11311161                               
    11321162                                /* Insert the new mapping */
    1133                                 page_mapping_insert(as, ptr + size * PAGE_SIZE,
     1163                                page_mapping_insert(as, ptr + P2SZ(size),
    11341164                                    old_frame[frame_idx++], page_flags);
    11351165                               
     
    12121242         */
    12131243        pte_t *pte;
    1214         if ((pte = page_mapping_find(AS, page))) {
     1244        if ((pte = page_mapping_find(AS, page, false))) {
    12151245                if (PTE_PRESENT(pte)) {
    12161246                        if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
     
    14531483       
    14541484        if (src_area) {
    1455                 size = src_area->pages * PAGE_SIZE;
     1485                size = P2SZ(src_area->pages);
    14561486                mutex_unlock(&src_area->lock);
    14571487        } else
     
    15081538                if (page >= right_pg) {
    15091539                        /* Do nothing. */
    1510                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1511                     left_cnt * PAGE_SIZE)) {
     1540                } else if (overlaps(page, P2SZ(count), left_pg,
     1541                    P2SZ(left_cnt))) {
    15121542                        /* The interval intersects with the left interval. */
    15131543                        return false;
    1514                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1515                     right_cnt * PAGE_SIZE)) {
     1544                } else if (overlaps(page, P2SZ(count), right_pg,
     1545                    P2SZ(right_cnt))) {
    15161546                        /* The interval intersects with the right interval. */
    15171547                        return false;
    1518                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1519                     (page + count * PAGE_SIZE == right_pg)) {
     1548                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1549                    (page + P2SZ(count) == right_pg)) {
    15201550                        /*
    15211551                         * The interval can be added by merging the two already
     
    15251555                        btree_remove(&area->used_space, right_pg, leaf);
    15261556                        goto success;
    1527                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1557                } else if (page == left_pg + P2SZ(left_cnt)) {
    15281558                        /*
    15291559                         * The interval can be added by simply growing the left
     
    15321562                        node->value[node->keys - 1] += count;
    15331563                        goto success;
    1534                 } else if (page + count * PAGE_SIZE == right_pg) {
     1564                } else if (page + P2SZ(count) == right_pg) {
    15351565                        /*
    15361566                         * The interval can be addded by simply moving base of
     
    15591589                 */
    15601590               
    1561                 if (overlaps(page, count * PAGE_SIZE, right_pg,
    1562                     right_cnt * PAGE_SIZE)) {
     1591                if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
    15631592                        /* The interval intersects with the right interval. */
    15641593                        return false;
    1565                 } else if (page + count * PAGE_SIZE == right_pg) {
     1594                } else if (page + P2SZ(count) == right_pg) {
    15661595                        /*
    15671596                         * The interval can be added by moving the base of the
     
    15981627                if (page < left_pg) {
    15991628                        /* Do nothing. */
    1600                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1601                     left_cnt * PAGE_SIZE)) {
     1629                } else if (overlaps(page, P2SZ(count), left_pg,
     1630                    P2SZ(left_cnt))) {
    16021631                        /* The interval intersects with the left interval. */
    16031632                        return false;
    1604                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1605                     right_cnt * PAGE_SIZE)) {
     1633                } else if (overlaps(page, P2SZ(count), right_pg,
     1634                    P2SZ(right_cnt))) {
    16061635                        /* The interval intersects with the right interval. */
    16071636                        return false;
    1608                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1609                     (page + count * PAGE_SIZE == right_pg)) {
     1637                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1638                    (page + P2SZ(count) == right_pg)) {
    16101639                        /*
    16111640                         * The interval can be added by merging the two already
     
    16151644                        btree_remove(&area->used_space, right_pg, node);
    16161645                        goto success;
    1617                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1646                } else if (page == left_pg + P2SZ(left_cnt)) {
    16181647                        /*
    16191648                         * The interval can be added by simply growing the left
     
    16221651                        leaf->value[leaf->keys - 1] += count;
    16231652                        goto success;
    1624                 } else if (page + count * PAGE_SIZE == right_pg) {
     1653                } else if (page + P2SZ(count) == right_pg) {
    16251654                        /*
    16261655                         * The interval can be addded by simply moving base of
     
    16491678                 */
    16501679               
    1651                 if (overlaps(page, count * PAGE_SIZE, left_pg,
    1652                     left_cnt * PAGE_SIZE)) {
     1680                if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
    16531681                        /* The interval intersects with the left interval. */
    16541682                        return false;
    1655                 } else if (left_pg + left_cnt * PAGE_SIZE == page) {
     1683                } else if (left_pg + P2SZ(left_cnt) == page) {
    16561684                        /*
    16571685                         * The interval can be added by growing the left
     
    16881716                         */
    16891717                       
    1690                         if (overlaps(page, count * PAGE_SIZE, left_pg,
    1691                             left_cnt * PAGE_SIZE)) {
     1718                        if (overlaps(page, P2SZ(count), left_pg,
     1719                            P2SZ(left_cnt))) {
    16921720                                /*
    16931721                                 * The interval intersects with the left
     
    16951723                                 */
    16961724                                return false;
    1697                         } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1698                             right_cnt * PAGE_SIZE)) {
     1725                        } else if (overlaps(page, P2SZ(count), right_pg,
     1726                            P2SZ(right_cnt))) {
    16991727                                /*
    17001728                                 * The interval intersects with the right
     
    17021730                                 */
    17031731                                return false;
    1704                         } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1705                             (page + count * PAGE_SIZE == right_pg)) {
     1732                        } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1733                            (page + P2SZ(count) == right_pg)) {
    17061734                                /*
    17071735                                 * The interval can be added by merging the two
     
    17111739                                btree_remove(&area->used_space, right_pg, leaf);
    17121740                                goto success;
    1713                         } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1741                        } else if (page == left_pg + P2SZ(left_cnt)) {
    17141742                                /*
    17151743                                 * The interval can be added by simply growing
     
    17181746                                leaf->value[i - 1] += count;
    17191747                                goto success;
    1720                         } else if (page + count * PAGE_SIZE == right_pg) {
     1748                        } else if (page + P2SZ(count) == right_pg) {
    17211749                                /*
    17221750                                 * The interval can be addded by simply moving
     
    17841812                        for (i = 0; i < leaf->keys; i++) {
    17851813                                if (leaf->key[i] == page) {
    1786                                         leaf->key[i] += count * PAGE_SIZE;
     1814                                        leaf->key[i] += P2SZ(count);
    17871815                                        leaf->value[i] -= count;
    17881816                                        goto success;
     
    17941822        }
    17951823       
    1796         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     1824        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
     1825            leaf);
    17971826        if ((node) && (page < leaf->key[0])) {
    17981827                uintptr_t left_pg = node->key[node->keys - 1];
    17991828                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18001829               
    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) {
     1830                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1831                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18051832                                /*
    18061833                                 * The interval is contained in the rightmost
     
    18111838                                node->value[node->keys - 1] -= count;
    18121839                                goto success;
    1813                         } else if (page + count * PAGE_SIZE <
    1814                             left_pg + left_cnt*PAGE_SIZE) {
     1840                        } else if (page + P2SZ(count) <
     1841                            left_pg + P2SZ(left_cnt)) {
     1842                                size_t new_cnt;
     1843
    18151844                                /*
    18161845                                 * The interval is contained in the rightmost
     
    18201849                                 * new interval.
    18211850                                 */
    1822                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1823                                     (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
     1851                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1852                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18241853                                node->value[node->keys - 1] -= count + new_cnt;
    18251854                                btree_insert(&area->used_space, page +
    1826                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1855                                    P2SZ(count), (void *) new_cnt, leaf);
    18271856                                goto success;
    18281857                        }
     
    18371866                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18381867               
    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) {
     1868                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1869                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18431870                                /*
    18441871                                 * The interval is contained in the rightmost
     
    18481875                                leaf->value[leaf->keys - 1] -= count;
    18491876                                goto success;
    1850                         } else if (page + count * PAGE_SIZE < left_pg +
    1851                             left_cnt * PAGE_SIZE) {
     1877                        } else if (page + P2SZ(count) < left_pg +
     1878                            P2SZ(left_cnt)) {
     1879                                size_t new_cnt;
     1880
    18521881                                /*
    18531882                                 * The interval is contained in the rightmost
     
    18571886                                 * interval.
    18581887                                 */
    1859                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1860                                     (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
     1888                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1889                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18611890                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18621891                                btree_insert(&area->used_space, page +
    1863                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1892                                    P2SZ(count), (void *) new_cnt, leaf);
    18641893                                goto success;
    18651894                        }
     
    18831912                         * to (i - 1) and i.
    18841913                         */
    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) {
     1914                        if (overlaps(left_pg, P2SZ(left_cnt), page,
     1915                            P2SZ(count))) {
     1916                                if (page + P2SZ(count) ==
     1917                                    left_pg + P2SZ(left_cnt)) {
    18891918                                        /*
    18901919                                         * The interval is contained in the
     
    18951924                                        leaf->value[i - 1] -= count;
    18961925                                        goto success;
    1897                                 } else if (page + count * PAGE_SIZE <
    1898                                     left_pg + left_cnt * PAGE_SIZE) {
     1926                                } else if (page + P2SZ(count) <
     1927                                    left_pg + P2SZ(left_cnt)) {
     1928                                        size_t new_cnt;
     1929
    18991930                                        /*
    19001931                                         * The interval is contained in the
     
    19041935                                         * also inserting a new interval.
    19051936                                         */
    1906                                         size_t new_cnt = ((left_pg +
    1907                                             left_cnt * PAGE_SIZE) -
    1908                                             (page + count * PAGE_SIZE)) >>
     1937                                        new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1938                                            (page + P2SZ(count))) >>
    19091939                                            PAGE_WIDTH;
    19101940                                        leaf->value[i - 1] -= count + new_cnt;
    19111941                                        btree_insert(&area->used_space, page +
    1912                                             count * PAGE_SIZE, (void *) new_cnt,
     1942                                            P2SZ(count), (void *) new_cnt,
    19131943                                            leaf);
    19141944                                        goto success;
     
    19611991}
    19621992
     1993/** Return pointer to unmapped address space area
     1994 *
     1995 * @param base Lowest address bound.
     1996 * @param size Requested size of the allocation.
     1997 *
     1998 * @return Pointer to the beginning of unmapped address space area.
     1999 *
     2000 */
     2001sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
     2002{
     2003        if (size == 0)
     2004                return 0;
     2005       
     2006        /*
     2007         * Make sure we allocate from page-aligned
     2008         * address. Check for possible overflow in
     2009         * each step.
     2010         */
     2011       
     2012        size_t pages = SIZE2FRAMES(size);
     2013        uintptr_t ret = 0;
     2014       
     2015        /*
     2016         * Find the lowest unmapped address aligned on the sz
     2017         * boundary, not smaller than base and of the required size.
     2018         */
     2019       
     2020        mutex_lock(&AS->lock);
     2021       
     2022        /* First check the base address itself */
     2023        uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
     2024        if ((addr >= base) &&
     2025            (check_area_conflicts(AS, addr, pages, NULL)))
     2026                ret = addr;
     2027       
     2028        /* Eventually check the addresses behind each area */
     2029        link_t *cur;
     2030        for (cur = AS->as_area_btree.leaf_head.next;
     2031            (ret == 0) && (cur != &AS->as_area_btree.leaf_head);
     2032            cur = cur->next) {
     2033                btree_node_t *node =
     2034                    list_get_instance(cur, btree_node_t, leaf_link);
     2035               
     2036                btree_key_t i;
     2037                for (i = 0; (ret == 0) && (i < node->keys); i++) {
     2038                        uintptr_t addr;
     2039
     2040                        as_area_t *area = (as_area_t *) node->value[i];
     2041                       
     2042                        mutex_lock(&area->lock);
     2043                       
     2044                        addr = ALIGN_UP(area->base + P2SZ(area->pages),
     2045                            PAGE_SIZE);
     2046                       
     2047                        if ((addr >= base) && (addr >= area->base) &&
     2048                            (check_area_conflicts(AS, addr, pages, area)))
     2049                                ret = addr;
     2050                       
     2051                        mutex_unlock(&area->lock);
     2052                }
     2053        }
     2054       
     2055        mutex_unlock(&AS->lock);
     2056       
     2057        return (sysarg_t) ret;
     2058}
     2059
    19632060/** Get list of adress space areas.
    19642061 *
     
    20042101                       
    20052102                        info[area_idx].start_addr = area->base;
    2006                         info[area_idx].size = FRAMES2SIZE(area->pages);
     2103                        info[area_idx].size = P2SZ(area->pages);
    20072104                        info[area_idx].flags = area->flags;
    20082105                        ++area_idx;
     
    20272124        mutex_lock(&as->lock);
    20282125       
    2029         /* print out info about address space areas */
     2126        /* Print out info about address space areas */
    20302127        link_t *cur;
    20312128        for (cur = as->as_area_btree.leaf_head.next;
     
    20422139                            " (%p - %p)\n", area, (void *) area->base,
    20432140                            area->pages, (void *) area->base,
    2044                             (void *) (area->base + FRAMES2SIZE(area->pages)));
     2141                            (void *) (area->base + P2SZ(area->pages)));
    20452142                        mutex_unlock(&area->lock);
    20462143                }
Note: See TracChangeset for help on using the changeset viewer.