Ignore:
File:
1 edited

Legend:

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

    rfc47885 re394b736  
    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, count << PAGE_WIDTH, (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, count << PAGE_WIDTH,
     332                            area->base, area->pages << PAGE_WIDTH)) {
     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, count << PAGE_WIDTH,
     349                            area->base, area->pages << PAGE_WIDTH)) {
     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, count << PAGE_WIDTH,
     369                    area->base, area->pages << PAGE_WIDTH)) {
    365370                        mutex_unlock(&area->lock);
    366371                        return false;
     
    375380         */
    376381        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    377                 return !overlaps(va, size,
     382                return !overlaps(addr, count << PAGE_WIDTH,
    378383                    KERNEL_ADDRESS_SPACE_START,
    379384                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     
    402407    mem_backend_data_t *backend_data)
    403408{
    404         if (base % PAGE_SIZE)
     409        if ((base % PAGE_SIZE) != 0)
    405410                return NULL;
    406411       
    407         if (!size)
     412        if (size == 0)
    408413                return NULL;
     414       
     415        size_t pages = SIZE2FRAMES(size);
    409416       
    410417        /* Writeable executable areas are not supported. */
     
    414421        mutex_lock(&as->lock);
    415422       
    416         if (!check_area_conflicts(as, base, size, NULL)) {
     423        if (!check_area_conflicts(as, base, pages, NULL)) {
    417424                mutex_unlock(&as->lock);
    418425                return NULL;
     
    426433        area->flags = flags;
    427434        area->attributes = attrs;
    428         area->pages = SIZE2FRAMES(size);
     435        area->pages = pages;
    429436        area->resident = 0;
    430437        area->base = base;
     
    436443        else
    437444                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
     445       
     446        if (area->backend && area->backend->create) {
     447                if (!area->backend->create(area)) {
     448                        free(area);
     449                        mutex_unlock(&as->lock);
     450                        return NULL;
     451                }
     452        }
    438453       
    439454        btree_create(&area->used_space);
     
    480495                mutex_lock(&area->lock);
    481496               
    482                 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
     497                if ((area->base <= va) &&
     498                    (va < area->base + (area->pages << PAGE_WIDTH)))
    483499                        return area;
    484500               
     
    496512                mutex_lock(&area->lock);
    497513               
    498                 if (va < area->base + area->pages * PAGE_SIZE)
     514                if (va < area->base + (area->pages << PAGE_WIDTH))
    499515                        return area;
    500516               
     
    561577       
    562578        if (pages < area->pages) {
    563                 uintptr_t start_free = area->base + pages * PAGE_SIZE;
     579                uintptr_t start_free = area->base + (pages << PAGE_WIDTH);
    564580               
    565581                /*
     
    574590                 */
    575591                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    576                     area->base + pages * PAGE_SIZE, area->pages - pages);
     592                    area->base + (pages << PAGE_WIDTH), area->pages - pages);
    577593               
    578594                /*
     
    597613                                size_t i = 0;
    598614                               
    599                                 if (overlaps(ptr, size * PAGE_SIZE, area->base,
    600                                     pages * PAGE_SIZE)) {
     615                                if (overlaps(ptr, size << PAGE_WIDTH, area->base,
     616                                    pages << PAGE_WIDTH)) {
    601617                                       
    602                                         if (ptr + size * PAGE_SIZE <= start_free) {
     618                                        if (ptr + (size << PAGE_WIDTH) <= start_free) {
    603619                                                /*
    604620                                                 * The whole interval fits
     
    632648                                for (; i < size; i++) {
    633649                                        pte_t *pte = page_mapping_find(as, ptr +
    634                                             i * PAGE_SIZE);
     650                                            (i << PAGE_WIDTH));
    635651                                       
    636652                                        ASSERT(pte);
     
    641657                                            (area->backend->frame_free)) {
    642658                                                area->backend->frame_free(area,
    643                                                     ptr + i * PAGE_SIZE,
     659                                                    ptr + (i << PAGE_WIDTH),
    644660                                                    PTE_GET_FRAME(pte));
    645661                                        }
    646662                                       
    647663                                        page_mapping_remove(as, ptr +
    648                                             i * PAGE_SIZE);
     664                                            (i << PAGE_WIDTH));
    649665                                }
    650666                        }
     
    655671                 */
    656672               
    657                 tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
     673                tlb_invalidate_pages(as->asid, area->base + (pages << PAGE_WIDTH),
    658674                    area->pages - pages);
    659675               
     
    662678                 */
    663679                as_invalidate_translation_cache(as, area->base +
    664                     pages * PAGE_SIZE, area->pages - pages);
     680                    (pages << PAGE_WIDTH), area->pages - pages);
    665681                tlb_shootdown_finalize(ipl);
    666682               
     
    671687                 * Check for overlaps with other address space areas.
    672688                 */
    673                 if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
    674                     area)) {
     689                if (!check_area_conflicts(as, address, pages, area)) {
    675690                        mutex_unlock(&area->lock);
    676691                        mutex_unlock(&as->lock);
    677692                        return EADDRNOTAVAIL;
     693                }
     694        }
     695       
     696        if (area->backend && area->backend->resize) {
     697                if (!area->backend->resize(area, pages)) {
     698                        mutex_unlock(&area->lock);
     699                        mutex_unlock(&as->lock);
     700                        return ENOMEM;
    678701                }
    679702        }
     
    745768                return ENOENT;
    746769        }
     770
     771        if (area->backend && area->backend->destroy)
     772                area->backend->destroy(area);
    747773       
    748774        uintptr_t base = area->base;
     
    771797                       
    772798                        for (size = 0; size < (size_t) node->value[i]; size++) {
    773                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     799                                pte_t *pte =
     800                                    page_mapping_find(as, ptr + (size << PAGE_WIDTH));
    774801                               
    775802                                ASSERT(pte);
     
    780807                                    (area->backend->frame_free)) {
    781808                                        area->backend->frame_free(area,
    782                                             ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
     809                                            ptr + (size << PAGE_WIDTH), PTE_GET_FRAME(pte));
    783810                                }
    784811                               
    785                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     812                                page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
    786813                        }
    787814                }
     
    870897        }
    871898       
    872         size_t src_size = src_area->pages * PAGE_SIZE;
     899        size_t src_size = src_area->pages << PAGE_WIDTH;
    873900        unsigned int src_flags = src_area->flags;
    874901        mem_backend_t *src_backend = src_area->backend;
     
    10761103                       
    10771104                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1078                                 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
     1105                                pte_t *pte =
     1106                                    page_mapping_find(as, ptr + (size << PAGE_WIDTH));
    10791107                               
    10801108                                ASSERT(pte);
     
    10851113                               
    10861114                                /* Remove old mapping */
    1087                                 page_mapping_remove(as, ptr + size * PAGE_SIZE);
     1115                                page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
    10881116                        }
    10891117                }
     
    11311159                               
    11321160                                /* Insert the new mapping */
    1133                                 page_mapping_insert(as, ptr + size * PAGE_SIZE,
     1161                                page_mapping_insert(as, ptr + (size << PAGE_WIDTH),
    11341162                                    old_frame[frame_idx++], page_flags);
    11351163                               
     
    14531481       
    14541482        if (src_area) {
    1455                 size = src_area->pages * PAGE_SIZE;
     1483                size = src_area->pages << PAGE_WIDTH;
    14561484                mutex_unlock(&src_area->lock);
    14571485        } else
     
    15081536                if (page >= right_pg) {
    15091537                        /* Do nothing. */
    1510                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1511                     left_cnt * PAGE_SIZE)) {
     1538                } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1539                    left_cnt << PAGE_WIDTH)) {
    15121540                        /* The interval intersects with the left interval. */
    15131541                        return false;
    1514                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1515                     right_cnt * PAGE_SIZE)) {
     1542                } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1543                    right_cnt << PAGE_WIDTH)) {
    15161544                        /* The interval intersects with the right interval. */
    15171545                        return false;
    1518                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1519                     (page + count * PAGE_SIZE == right_pg)) {
     1546                } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
     1547                    (page + (count << PAGE_WIDTH) == right_pg)) {
    15201548                        /*
    15211549                         * The interval can be added by merging the two already
     
    15251553                        btree_remove(&area->used_space, right_pg, leaf);
    15261554                        goto success;
    1527                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1555                } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
    15281556                        /*
    15291557                         * The interval can be added by simply growing the left
     
    15321560                        node->value[node->keys - 1] += count;
    15331561                        goto success;
    1534                 } else if (page + count * PAGE_SIZE == right_pg) {
     1562                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    15351563                        /*
    15361564                         * The interval can be addded by simply moving base of
     
    15591587                 */
    15601588               
    1561                 if (overlaps(page, count * PAGE_SIZE, right_pg,
    1562                     right_cnt * PAGE_SIZE)) {
     1589                if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1590                    right_cnt << PAGE_WIDTH)) {
    15631591                        /* The interval intersects with the right interval. */
    15641592                        return false;
    1565                 } else if (page + count * PAGE_SIZE == right_pg) {
     1593                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    15661594                        /*
    15671595                         * The interval can be added by moving the base of the
     
    15981626                if (page < left_pg) {
    15991627                        /* Do nothing. */
    1600                 } else if (overlaps(page, count * PAGE_SIZE, left_pg,
    1601                     left_cnt * PAGE_SIZE)) {
     1628                } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1629                    left_cnt << PAGE_WIDTH)) {
    16021630                        /* The interval intersects with the left interval. */
    16031631                        return false;
    1604                 } else if (overlaps(page, count * PAGE_SIZE, right_pg,
    1605                     right_cnt * PAGE_SIZE)) {
     1632                } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
     1633                    right_cnt << PAGE_WIDTH)) {
    16061634                        /* The interval intersects with the right interval. */
    16071635                        return false;
    1608                 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
    1609                     (page + count * PAGE_SIZE == right_pg)) {
     1636                } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
     1637                    (page + (count << PAGE_WIDTH) == right_pg)) {
    16101638                        /*
    16111639                         * The interval can be added by merging the two already
     
    16151643                        btree_remove(&area->used_space, right_pg, node);
    16161644                        goto success;
    1617                 } else if (page == left_pg + left_cnt * PAGE_SIZE) {
     1645                } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
    16181646                        /*
    16191647                         * The interval can be added by simply growing the left
     
    16221650                        leaf->value[leaf->keys - 1] += count;
    16231651                        goto success;
    1624                 } else if (page + count * PAGE_SIZE == right_pg) {
     1652                } else if (page + (count << PAGE_WIDTH) == right_pg) {
    16251653                        /*
    16261654                         * The interval can be addded by simply moving base of
     
    16491677                 */
    16501678               
    1651                 if (overlaps(page, count * PAGE_SIZE, left_pg,
    1652                     left_cnt * PAGE_SIZE)) {
     1679                if (overlaps(page, count << PAGE_WIDTH, left_pg,
     1680                    left_cnt << PAGE_WIDTH)) {
    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 + (left_cnt << PAGE_WIDTH) == 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, count << PAGE_WIDTH, left_pg,
     1719                            left_cnt << PAGE_WIDTH)) {
    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, count << PAGE_WIDTH, right_pg,
     1726                            right_cnt << PAGE_WIDTH)) {
    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 + (left_cnt << PAGE_WIDTH)) &&
     1733                            (page + (count << PAGE_WIDTH) == 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 + (left_cnt << PAGE_WIDTH)) {
    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 + (count << PAGE_WIDTH) == 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] += count << PAGE_WIDTH;
    17871815                                        leaf->value[i] -= count;
    17881816                                        goto success;
     
    17991827                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18001828               
    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) {
     1829                if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1830                    count << PAGE_WIDTH)) {
     1831                        if (page + (count << PAGE_WIDTH) ==
     1832                            left_pg + (left_cnt << PAGE_WIDTH)) {
    18051833                                /*
    18061834                                 * The interval is contained in the rightmost
     
    18111839                                node->value[node->keys - 1] -= count;
    18121840                                goto success;
    1813                         } else if (page + count * PAGE_SIZE <
    1814                             left_pg + left_cnt*PAGE_SIZE) {
     1841                        } else if (page + (count << PAGE_WIDTH) <
     1842                            left_pg + (left_cnt << PAGE_WIDTH)) {
    18151843                                /*
    18161844                                 * The interval is contained in the rightmost
     
    18201848                                 * new interval.
    18211849                                 */
    1822                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1823                                     (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
     1850                                size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
     1851                                    (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
    18241852                                node->value[node->keys - 1] -= count + new_cnt;
    18251853                                btree_insert(&area->used_space, page +
    1826                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1854                                    (count << PAGE_WIDTH), (void *) new_cnt, leaf);
    18271855                                goto success;
    18281856                        }
     
    18371865                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18381866               
    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) {
     1867                if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1868                    count << PAGE_WIDTH)) {
     1869                        if (page + (count << PAGE_WIDTH) ==
     1870                            left_pg + (left_cnt << PAGE_WIDTH)) {
    18431871                                /*
    18441872                                 * The interval is contained in the rightmost
     
    18481876                                leaf->value[leaf->keys - 1] -= count;
    18491877                                goto success;
    1850                         } else if (page + count * PAGE_SIZE < left_pg +
    1851                             left_cnt * PAGE_SIZE) {
     1878                        } else if (page + (count << PAGE_WIDTH) < left_pg +
     1879                            (left_cnt << PAGE_WIDTH)) {
    18521880                                /*
    18531881                                 * The interval is contained in the rightmost
     
    18571885                                 * interval.
    18581886                                 */
    1859                                 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
    1860                                     (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
     1887                                size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
     1888                                    (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
    18611889                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18621890                                btree_insert(&area->used_space, page +
    1863                                     count * PAGE_SIZE, (void *) new_cnt, leaf);
     1891                                    (count << PAGE_WIDTH), (void *) new_cnt, leaf);
    18641892                                goto success;
    18651893                        }
     
    18831911                         * to (i - 1) and i.
    18841912                         */
    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) {
     1913                        if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
     1914                            count << PAGE_WIDTH)) {
     1915                                if (page + (count << PAGE_WIDTH) ==
     1916                                    left_pg + (left_cnt << PAGE_WIDTH)) {
    18891917                                        /*
    18901918                                         * The interval is contained in the
     
    18951923                                        leaf->value[i - 1] -= count;
    18961924                                        goto success;
    1897                                 } else if (page + count * PAGE_SIZE <
    1898                                     left_pg + left_cnt * PAGE_SIZE) {
     1925                                } else if (page + (count << PAGE_WIDTH) <
     1926                                    left_pg + (left_cnt << PAGE_WIDTH)) {
    18991927                                        /*
    19001928                                         * The interval is contained in the
     
    19051933                                         */
    19061934                                        size_t new_cnt = ((left_pg +
    1907                                             left_cnt * PAGE_SIZE) -
    1908                                             (page + count * PAGE_SIZE)) >>
     1935                                            (left_cnt << PAGE_WIDTH)) -
     1936                                            (page + (count << PAGE_WIDTH))) >>
    19091937                                            PAGE_WIDTH;
    19101938                                        leaf->value[i - 1] -= count + new_cnt;
    19111939                                        btree_insert(&area->used_space, page +
    1912                                             count * PAGE_SIZE, (void *) new_cnt,
     1940                                            (count << PAGE_WIDTH), (void *) new_cnt,
    19131941                                            leaf);
    19141942                                        goto success;
     
    19611989}
    19621990
     1991/** Return pointer to unmapped address space area
     1992 *
     1993 * @param base Lowest address bound.
     1994 * @param size Requested size of the allocation.
     1995 *
     1996 * @return Pointer to the beginning of unmapped address space area.
     1997 *
     1998 */
     1999sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size)
     2000{
     2001        if (size == 0)
     2002                return 0;
     2003       
     2004        /*
     2005         * Make sure we allocate from page-aligned
     2006         * address. Check for possible overflow in
     2007         * each step.
     2008         */
     2009       
     2010        size_t pages = SIZE2FRAMES(size);
     2011        uintptr_t ret = 0;
     2012       
     2013        /*
     2014         * Find the lowest unmapped address aligned on the sz
     2015         * boundary, not smaller than base and of the required size.
     2016         */
     2017       
     2018        mutex_lock(&AS->lock);
     2019       
     2020        /* First check the base address itself */
     2021        uintptr_t addr = ALIGN_UP(base, PAGE_SIZE);
     2022        if ((addr >= base) &&
     2023            (check_area_conflicts(AS, addr, pages, NULL)))
     2024                ret = addr;
     2025       
     2026        /* Eventually check the addresses behind each area */
     2027        link_t *cur;
     2028        for (cur = AS->as_area_btree.leaf_head.next;
     2029            (ret == 0) && (cur != &AS->as_area_btree.leaf_head);
     2030            cur = cur->next) {
     2031                btree_node_t *node =
     2032                    list_get_instance(cur, btree_node_t, leaf_link);
     2033               
     2034                btree_key_t i;
     2035                for (i = 0; (ret == 0) && (i < node->keys); i++) {
     2036                        as_area_t *area = (as_area_t *) node->value[i];
     2037                       
     2038                        mutex_lock(&area->lock);
     2039                       
     2040                        uintptr_t addr =
     2041                            ALIGN_UP(area->base + (area->pages << PAGE_WIDTH),
     2042                            PAGE_SIZE);
     2043                       
     2044                        if ((addr >= base) && (addr >= area->base) &&
     2045                            (check_area_conflicts(AS, addr, pages, area)))
     2046                                ret = addr;
     2047                       
     2048                        mutex_unlock(&area->lock);
     2049                }
     2050        }
     2051       
     2052        mutex_unlock(&AS->lock);
     2053       
     2054        return (sysarg_t) ret;
     2055}
     2056
    19632057/** Get list of adress space areas.
    19642058 *
     
    20272121        mutex_lock(&as->lock);
    20282122       
    2029         /* print out info about address space areas */
     2123        /* Print out info about address space areas */
    20302124        link_t *cur;
    20312125        for (cur = as->as_area_btree.leaf_head.next;
Note: See TracChangeset for help on using the changeset viewer.