Ignore:
File:
1 edited

Legend:

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

    re394b736 rfc47885  
    7171#include <memstr.h>
    7272#include <macros.h>
    73 #include <bitops.h>
    7473#include <arch.h>
    7574#include <errno.h>
     
    8079#include <arch/interrupt.h>
    8180
     81#ifdef CONFIG_VIRT_IDX_DCACHE
     82#include <arch/mm/cache.h>
     83#endif /* CONFIG_VIRT_IDX_DCACHE */
     84
    8285/**
    8386 * Each architecture decides what functions will be used to carry out
     
    285288/** Check area conflicts with other areas.
    286289 *
    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.
     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.
    291294 *
    292295 * @return True if there is no conflict, false otherwise.
    293296 *
    294297 */
    295 NO_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);
     298NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
     299    as_area_t *avoid_area)
     300{
    299301        ASSERT(mutex_locked(&as->lock));
    300302       
     
    302304         * We don't want any area to have conflicts with NULL page.
    303305         */
    304         if (overlaps(addr, count << PAGE_WIDTH, (uintptr_t) NULL, PAGE_SIZE))
     306        if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE))
    305307                return false;
    306308       
     
    314316        btree_node_t *leaf;
    315317        as_area_t *area =
    316             (as_area_t *) btree_search(&as->as_area_btree, addr, &leaf);
     318            (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    317319        if (area) {
    318                 if (area != avoid)
     320                if (area != avoid_area)
    319321                        return false;
    320322        }
     
    326328                area = (as_area_t *) node->value[node->keys - 1];
    327329               
    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                        
     330                mutex_lock(&area->lock);
     331               
     332                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    337333                        mutex_unlock(&area->lock);
    338                 }
     334                        return false;
     335                }
     336               
     337                mutex_unlock(&area->lock);
    339338        }
    340339       
     
    343342                area = (as_area_t *) node->value[0];
    344343               
    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                        
     344                mutex_lock(&area->lock);
     345               
     346                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    354347                        mutex_unlock(&area->lock);
    355                 }
     348                        return false;
     349                }
     350               
     351                mutex_unlock(&area->lock);
    356352        }
    357353       
     
    361357                area = (as_area_t *) leaf->value[i];
    362358               
    363                 if (area == avoid)
     359                if (area == avoid_area)
    364360                        continue;
    365361               
    366362                mutex_lock(&area->lock);
    367363               
    368                 if (overlaps(addr, count << PAGE_WIDTH,
    369                     area->base, area->pages << PAGE_WIDTH)) {
     364                if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
    370365                        mutex_unlock(&area->lock);
    371366                        return false;
     
    380375         */
    381376        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    382                 return !overlaps(addr, count << PAGE_WIDTH,
     377                return !overlaps(va, size,
    383378                    KERNEL_ADDRESS_SPACE_START,
    384379                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     
    407402    mem_backend_data_t *backend_data)
    408403{
    409         if ((base % PAGE_SIZE) != 0)
     404        if (base % PAGE_SIZE)
    410405                return NULL;
    411406       
    412         if (size == 0)
     407        if (!size)
    413408                return NULL;
    414        
    415         size_t pages = SIZE2FRAMES(size);
    416409       
    417410        /* Writeable executable areas are not supported. */
     
    421414        mutex_lock(&as->lock);
    422415       
    423         if (!check_area_conflicts(as, base, pages, NULL)) {
     416        if (!check_area_conflicts(as, base, size, NULL)) {
    424417                mutex_unlock(&as->lock);
    425418                return NULL;
     
    433426        area->flags = flags;
    434427        area->attributes = attrs;
    435         area->pages = pages;
     428        area->pages = SIZE2FRAMES(size);
    436429        area->resident = 0;
    437430        area->base = base;
     
    443436        else
    444437                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         }
    453438       
    454439        btree_create(&area->used_space);
     
    495480                mutex_lock(&area->lock);
    496481               
    497                 if ((area->base <= va) &&
    498                     (va < area->base + (area->pages << PAGE_WIDTH)))
     482                if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
    499483                        return area;
    500484               
     
    512496                mutex_lock(&area->lock);
    513497               
    514                 if (va < area->base + (area->pages << PAGE_WIDTH))
     498                if (va < area->base + area->pages * PAGE_SIZE)
    515499                        return area;
    516500               
     
    577561       
    578562        if (pages < area->pages) {
    579                 uintptr_t start_free = area->base + (pages << PAGE_WIDTH);
     563                uintptr_t start_free = area->base + pages * PAGE_SIZE;
    580564               
    581565                /*
     
    590574                 */
    591575                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    592                     area->base + (pages << PAGE_WIDTH), area->pages - pages);
     576                    area->base + pages * PAGE_SIZE, area->pages - pages);
    593577               
    594578                /*
     
    613597                                size_t i = 0;
    614598                               
    615                                 if (overlaps(ptr, size << PAGE_WIDTH, area->base,
    616                                     pages << PAGE_WIDTH)) {
     599                                if (overlaps(ptr, size * PAGE_SIZE, area->base,
     600                                    pages * PAGE_SIZE)) {
    617601                                       
    618                                         if (ptr + (size << PAGE_WIDTH) <= start_free) {
     602                                        if (ptr + size * PAGE_SIZE <= start_free) {
    619603                                                /*
    620604                                                 * The whole interval fits
     
    648632                                for (; i < size; i++) {
    649633                                        pte_t *pte = page_mapping_find(as, ptr +
    650                                             (i << PAGE_WIDTH));
     634                                            i * PAGE_SIZE);
    651635                                       
    652636                                        ASSERT(pte);
     
    657641                                            (area->backend->frame_free)) {
    658642                                                area->backend->frame_free(area,
    659                                                     ptr + (i << PAGE_WIDTH),
     643                                                    ptr + i * PAGE_SIZE,
    660644                                                    PTE_GET_FRAME(pte));
    661645                                        }
    662646                                       
    663647                                        page_mapping_remove(as, ptr +
    664                                             (i << PAGE_WIDTH));
     648                                            i * PAGE_SIZE);
    665649                                }
    666650                        }
     
    671655                 */
    672656               
    673                 tlb_invalidate_pages(as->asid, area->base + (pages << PAGE_WIDTH),
     657                tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
    674658                    area->pages - pages);
    675659               
     
    678662                 */
    679663                as_invalidate_translation_cache(as, area->base +
    680                     (pages << PAGE_WIDTH), area->pages - pages);
     664                    pages * PAGE_SIZE, area->pages - pages);
    681665                tlb_shootdown_finalize(ipl);
    682666               
     
    687671                 * Check for overlaps with other address space areas.
    688672                 */
    689                 if (!check_area_conflicts(as, address, pages, area)) {
     673                if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
     674                    area)) {
    690675                        mutex_unlock(&area->lock);
    691676                        mutex_unlock(&as->lock);
    692677                        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;
    701678                }
    702679        }
     
    768745                return ENOENT;
    769746        }
    770 
    771         if (area->backend && area->backend->destroy)
    772                 area->backend->destroy(area);
    773747       
    774748        uintptr_t base = area->base;
     
    797771                       
    798772                        for (size = 0; size < (size_t) node->value[i]; size++) {
    799                                 pte_t *pte =
    800                                     page_mapping_find(as, ptr + (size << PAGE_WIDTH));
     773                                pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    801774                               
    802775                                ASSERT(pte);
     
    807780                                    (area->backend->frame_free)) {
    808781                                        area->backend->frame_free(area,
    809                                             ptr + (size << PAGE_WIDTH), PTE_GET_FRAME(pte));
     782                                            ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
    810783                                }
    811784                               
    812                                 page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
     785                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
    813786                        }
    814787                }
     
    897870        }
    898871       
    899         size_t src_size = src_area->pages << PAGE_WIDTH;
     872        size_t src_size = src_area->pages * PAGE_SIZE;
    900873        unsigned int src_flags = src_area->flags;
    901874        mem_backend_t *src_backend = src_area->backend;
     
    11031076                       
    11041077                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1105                                 pte_t *pte =
    1106                                     page_mapping_find(as, ptr + (size << PAGE_WIDTH));
     1078                                pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    11071079                               
    11081080                                ASSERT(pte);
     
    11131085                               
    11141086                                /* Remove old mapping */
    1115                                 page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
     1087                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
    11161088                        }
    11171089                }
     
    11591131                               
    11601132                                /* Insert the new mapping */
    1161                                 page_mapping_insert(as, ptr + (size << PAGE_WIDTH),
     1133                                page_mapping_insert(as, ptr + size * PAGE_SIZE,
    11621134                                    old_frame[frame_idx++], page_flags);
    11631135                               
     
    14811453       
    14821454        if (src_area) {
    1483                 size = src_area->pages << PAGE_WIDTH;
     1455                size = src_area->pages * PAGE_SIZE;
    14841456                mutex_unlock(&src_area->lock);
    14851457        } else
     
    15361508                if (page >= right_pg) {
    15371509                        /* Do nothing. */
    1538                 } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1539                     left_cnt << PAGE_WIDTH)) {
     1510                } else if (overlaps(page, count * PAGE_SIZE, left_pg,
     1511                    left_cnt * PAGE_SIZE)) {
    15401512                        /* The interval intersects with the left interval. */
    15411513                        return false;
    1542                 } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1543                     right_cnt << PAGE_WIDTH)) {
     1514                } else if (overlaps(page, count * PAGE_SIZE, right_pg,
     1515                    right_cnt * PAGE_SIZE)) {
    15441516                        /* The interval intersects with the right interval. */
    15451517                        return false;
    1546                 } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1547                     (page + (count << PAGE_WIDTH) == right_pg)) {
     1518                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
     1519                    (page + count * PAGE_SIZE == right_pg)) {
    15481520                        /*
    15491521                         * The interval can be added by merging the two already
     
    15531525                        btree_remove(&area->used_space, right_pg, leaf);
    15541526                        goto success;
    1555                 } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1527                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    15561528                        /*
    15571529                         * The interval can be added by simply growing the left
     
    15601532                        node->value[node->keys - 1] += count;
    15611533                        goto success;
    1562                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1534                } else if (page + count * PAGE_SIZE == right_pg) {
    15631535                        /*
    15641536                         * The interval can be addded by simply moving base of
     
    15871559                 */
    15881560               
    1589                 if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1590                     right_cnt << PAGE_WIDTH)) {
     1561                if (overlaps(page, count * PAGE_SIZE, right_pg,
     1562                    right_cnt * PAGE_SIZE)) {
    15911563                        /* The interval intersects with the right interval. */
    15921564                        return false;
    1593                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1565                } else if (page + count * PAGE_SIZE == right_pg) {
    15941566                        /*
    15951567                         * The interval can be added by moving the base of the
     
    16261598                if (page < left_pg) {
    16271599                        /* Do nothing. */
    1628                 } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1629                     left_cnt << PAGE_WIDTH)) {
     1600                } else if (overlaps(page, count * PAGE_SIZE, left_pg,
     1601                    left_cnt * PAGE_SIZE)) {
    16301602                        /* The interval intersects with the left interval. */
    16311603                        return false;
    1632                 } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1633                     right_cnt << PAGE_WIDTH)) {
     1604                } else if (overlaps(page, count * PAGE_SIZE, right_pg,
     1605                    right_cnt * PAGE_SIZE)) {
    16341606                        /* The interval intersects with the right interval. */
    16351607                        return false;
    1636                 } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1637                     (page + (count << PAGE_WIDTH) == right_pg)) {
     1608                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
     1609                    (page + count * PAGE_SIZE == right_pg)) {
    16381610                        /*
    16391611                         * The interval can be added by merging the two already
     
    16431615                        btree_remove(&area->used_space, right_pg, node);
    16441616                        goto success;
    1645                 } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1617                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    16461618                        /*
    16471619                         * The interval can be added by simply growing the left
     
    16501622                        leaf->value[leaf->keys - 1] += count;
    16511623                        goto success;
    1652                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1624                } else if (page + count * PAGE_SIZE == right_pg) {
    16531625                        /*
    16541626                         * The interval can be addded by simply moving base of
     
    16771649                 */
    16781650               
    1679                 if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1680                     left_cnt << PAGE_WIDTH)) {
     1651                if (overlaps(page, count * PAGE_SIZE, left_pg,
     1652                    left_cnt * PAGE_SIZE)) {
    16811653                        /* The interval intersects with the left interval. */
    16821654                        return false;
    1683                 } else if (left_pg + (left_cnt << PAGE_WIDTH) == page) {
     1655                } else if (left_pg + left_cnt * PAGE_SIZE == page) {
    16841656                        /*
    16851657                         * The interval can be added by growing the left
     
    17161688                         */
    17171689                       
    1718                         if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1719                             left_cnt << PAGE_WIDTH)) {
     1690                        if (overlaps(page, count * PAGE_SIZE, left_pg,
     1691                            left_cnt * PAGE_SIZE)) {
    17201692                                /*
    17211693                                 * The interval intersects with the left
     
    17231695                                 */
    17241696                                return false;
    1725                         } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1726                             right_cnt << PAGE_WIDTH)) {
     1697                        } else if (overlaps(page, count * PAGE_SIZE, right_pg,
     1698                            right_cnt * PAGE_SIZE)) {
    17271699                                /*
    17281700                                 * The interval intersects with the right
     
    17301702                                 */
    17311703                                return false;
    1732                         } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1733                             (page + (count << PAGE_WIDTH) == right_pg)) {
     1704                        } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
     1705                            (page + count * PAGE_SIZE == right_pg)) {
    17341706                                /*
    17351707                                 * The interval can be added by merging the two
     
    17391711                                btree_remove(&area->used_space, right_pg, leaf);
    17401712                                goto success;
    1741                         } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1713                        } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    17421714                                /*
    17431715                                 * The interval can be added by simply growing
     
    17461718                                leaf->value[i - 1] += count;
    17471719                                goto success;
    1748                         } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1720                        } else if (page + count * PAGE_SIZE == right_pg) {
    17491721                                /*
    17501722                                 * The interval can be addded by simply moving
     
    18121784                        for (i = 0; i < leaf->keys; i++) {
    18131785                                if (leaf->key[i] == page) {
    1814                                         leaf->key[i] += count << PAGE_WIDTH;
     1786                                        leaf->key[i] += count * PAGE_SIZE;
    18151787                                        leaf->value[i] -= count;
    18161788                                        goto success;
     
    18271799                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18281800               
    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)) {
     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) {
    18331805                                /*
    18341806                                 * The interval is contained in the rightmost
     
    18391811                                node->value[node->keys - 1] -= count;
    18401812                                goto success;
    1841                         } else if (page + (count << PAGE_WIDTH) <
    1842                             left_pg + (left_cnt << PAGE_WIDTH)) {
     1813                        } else if (page + count * PAGE_SIZE <
     1814                            left_pg + left_cnt*PAGE_SIZE) {
    18431815                                /*
    18441816                                 * The interval is contained in the rightmost
     
    18481820                                 * new interval.
    18491821                                 */
    1850                                 size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
    1851                                     (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
     1822                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1823                                    (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
    18521824                                node->value[node->keys - 1] -= count + new_cnt;
    18531825                                btree_insert(&area->used_space, page +
    1854                                     (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1826                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18551827                                goto success;
    18561828                        }
     
    18651837                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18661838               
    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)) {
     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) {
    18711843                                /*
    18721844                                 * The interval is contained in the rightmost
     
    18761848                                leaf->value[leaf->keys - 1] -= count;
    18771849                                goto success;
    1878                         } else if (page + (count << PAGE_WIDTH) < left_pg +
    1879                             (left_cnt << PAGE_WIDTH)) {
     1850                        } else if (page + count * PAGE_SIZE < left_pg +
     1851                            left_cnt * PAGE_SIZE) {
    18801852                                /*
    18811853                                 * The interval is contained in the rightmost
     
    18851857                                 * interval.
    18861858                                 */
    1887                                 size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
    1888                                     (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
     1859                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1860                                    (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
    18891861                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18901862                                btree_insert(&area->used_space, page +
    1891                                     (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1863                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18921864                                goto success;
    18931865                        }
     
    19111883                         * to (i - 1) and i.
    19121884                         */
    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)) {
     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) {
    19171889                                        /*
    19181890                                         * The interval is contained in the
     
    19231895                                        leaf->value[i - 1] -= count;
    19241896                                        goto success;
    1925                                 } else if (page + (count << PAGE_WIDTH) <
    1926                                     left_pg + (left_cnt << PAGE_WIDTH)) {
     1897                                } else if (page + count * PAGE_SIZE <
     1898                                    left_pg + left_cnt * PAGE_SIZE) {
    19271899                                        /*
    19281900                                         * The interval is contained in the
     
    19331905                                         */
    19341906                                        size_t new_cnt = ((left_pg +
    1935                                             (left_cnt << PAGE_WIDTH)) -
    1936                                             (page + (count << PAGE_WIDTH))) >>
     1907                                            left_cnt * PAGE_SIZE) -
     1908                                            (page + count * PAGE_SIZE)) >>
    19371909                                            PAGE_WIDTH;
    19381910                                        leaf->value[i - 1] -= count + new_cnt;
    19391911                                        btree_insert(&area->used_space, page +
    1940                                             (count << PAGE_WIDTH), (void *) new_cnt,
     1912                                            count * PAGE_SIZE, (void *) new_cnt,
    19411913                                            leaf);
    19421914                                        goto success;
     
    19871959{
    19881960        return (sysarg_t) as_area_destroy(AS, address);
    1989 }
    1990 
    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  */
    1999 sysarg_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;
    20551961}
    20561962
     
    21212027        mutex_lock(&as->lock);
    21222028       
    2123         /* Print out info about address space areas */
     2029        /* print out info about address space areas */
    21242030        link_t *cur;
    21252031        for (cur = as->as_area_btree.leaf_head.next;
Note: See TracChangeset for help on using the changeset viewer.