Ignore:
File:
1 edited

Legend:

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

    reef1b031 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, P2SZ(count), (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, P2SZ(count), area->base,
    332                             P2SZ(area->pages))) {
    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, P2SZ(count), area->base,
    349                             P2SZ(area->pages))) {
    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, P2SZ(count), area->base,
    369                     P2SZ(area->pages))) {
     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, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
     377                return !overlaps(va, size,
     378                    KERNEL_ADDRESS_SPACE_START,
    383379                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    384380        }
     
    406402    mem_backend_data_t *backend_data)
    407403{
    408         if ((base % PAGE_SIZE) != 0)
     404        if (base % PAGE_SIZE)
    409405                return NULL;
    410406       
    411         if (size == 0)
     407        if (!size)
    412408                return NULL;
    413        
    414         size_t pages = SIZE2FRAMES(size);
    415409       
    416410        /* Writeable executable areas are not supported. */
     
    420414        mutex_lock(&as->lock);
    421415       
    422         if (!check_area_conflicts(as, base, pages, NULL)) {
     416        if (!check_area_conflicts(as, base, size, NULL)) {
    423417                mutex_unlock(&as->lock);
    424418                return NULL;
     
    432426        area->flags = flags;
    433427        area->attributes = attrs;
    434         area->pages = pages;
     428        area->pages = SIZE2FRAMES(size);
    435429        area->resident = 0;
    436430        area->base = base;
     
    443437                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    444438       
    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        
    453439        btree_create(&area->used_space);
    454440        btree_insert(&as->as_area_btree, base, (void *) area, NULL);
     
    473459       
    474460        btree_node_t *leaf;
    475         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va,
    476             &leaf);
     461        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
    477462        if (area) {
    478463                /* va is the base address of an address space area */
     
    482467       
    483468        /*
    484          * Search the leaf node and the rightmost record of its left neighbour
     469         * Search the leaf node and the righmost record of its left neighbour
    485470         * to find out whether this is a miss or va belongs to an address
    486471         * space area found there.
     
    494479               
    495480                mutex_lock(&area->lock);
    496 
    497                 if ((area->base <= va) &&
    498                     (va <= area->base + (P2SZ(area->pages) - 1)))
     481               
     482                if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
    499483                        return area;
    500484               
     
    506490         * Because of its position in the B+tree, it must have base < va.
    507491         */
    508         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree,
    509             leaf);
     492        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
    510493        if (lnode) {
    511494                area = (as_area_t *) lnode->value[lnode->keys - 1];
     
    513496                mutex_lock(&area->lock);
    514497               
    515                 if (va <= area->base + (P2SZ(area->pages) - 1))
     498                if (va < area->base + area->pages * PAGE_SIZE)
    516499                        return area;
    517500               
     
    578561       
    579562        if (pages < area->pages) {
    580                 uintptr_t start_free = area->base + P2SZ(pages);
     563                uintptr_t start_free = area->base + pages * PAGE_SIZE;
    581564               
    582565                /*
     
    591574                 */
    592575                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    593                     area->base + P2SZ(pages), area->pages - pages);
     576                    area->base + pages * PAGE_SIZE, area->pages - pages);
    594577               
    595578                /*
     
    614597                                size_t i = 0;
    615598                               
    616                                 if (overlaps(ptr, P2SZ(size), area->base,
    617                                     P2SZ(pages))) {
     599                                if (overlaps(ptr, size * PAGE_SIZE, area->base,
     600                                    pages * PAGE_SIZE)) {
    618601                                       
    619                                         if (ptr + P2SZ(size) <= start_free) {
     602                                        if (ptr + size * PAGE_SIZE <= start_free) {
    620603                                                /*
    621604                                                 * The whole interval fits
     
    648631                               
    649632                                for (; i < size; i++) {
    650                                         pte_t *pte = page_mapping_find(as,
    651                                             ptr + P2SZ(i), false);
     633                                        pte_t *pte = page_mapping_find(as, ptr +
     634                                            i * PAGE_SIZE);
    652635                                       
    653636                                        ASSERT(pte);
     
    658641                                            (area->backend->frame_free)) {
    659642                                                area->backend->frame_free(area,
    660                                                     ptr + P2SZ(i),
     643                                                    ptr + i * PAGE_SIZE,
    661644                                                    PTE_GET_FRAME(pte));
    662645                                        }
    663646                                       
    664                                         page_mapping_remove(as, ptr + P2SZ(i));
     647                                        page_mapping_remove(as, ptr +
     648                                            i * PAGE_SIZE);
    665649                                }
    666650                        }
     
    671655                 */
    672656               
    673                 tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
     657                tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
    674658                    area->pages - pages);
    675659               
    676660                /*
    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);
     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);
    682665                tlb_shootdown_finalize(ipl);
    683666               
     
    688671                 * Check for overlaps with other address space areas.
    689672                 */
    690                 if (!check_area_conflicts(as, address, pages, area)) {
     673                if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
     674                    area)) {
    691675                        mutex_unlock(&area->lock);
    692676                        mutex_unlock(&as->lock);
    693677                        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;
    702678                }
    703679        }
     
    769745                return ENOENT;
    770746        }
    771 
    772         if (area->backend && area->backend->destroy)
    773                 area->backend->destroy(area);
    774747       
    775748        uintptr_t base = area->base;
     
    798771                       
    799772                        for (size = 0; size < (size_t) node->value[i]; size++) {
    800                                 pte_t *pte = page_mapping_find(as,
    801                                      ptr + P2SZ(size), false);
     773                                pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    802774                               
    803775                                ASSERT(pte);
     
    808780                                    (area->backend->frame_free)) {
    809781                                        area->backend->frame_free(area,
    810                                             ptr + P2SZ(size),
    811                                             PTE_GET_FRAME(pte));
     782                                            ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
    812783                                }
    813784                               
    814                                 page_mapping_remove(as, ptr + P2SZ(size));
     785                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
    815786                        }
    816787                }
     
    824795       
    825796        /*
    826          * Invalidate potential software translation caches
    827          * (e.g. TSB on sparc64, PHT on ppc32).
     797         * Invalidate potential software translation caches (e.g. TSB on
     798         * sparc64).
    828799         */
    829800        as_invalidate_translation_cache(as, area->base, area->pages);
     
    899870        }
    900871       
    901         size_t src_size = P2SZ(src_area->pages);
     872        size_t src_size = src_area->pages * PAGE_SIZE;
    902873        unsigned int src_flags = src_area->flags;
    903874        mem_backend_t *src_backend = src_area->backend;
     
    10961067        for (cur = area->used_space.leaf_head.next;
    10971068            cur != &area->used_space.leaf_head; cur = cur->next) {
    1098                 btree_node_t *node = list_get_instance(cur, btree_node_t,
    1099                     leaf_link);
     1069                btree_node_t *node
     1070                    = list_get_instance(cur, btree_node_t, leaf_link);
    11001071                btree_key_t i;
    11011072               
     
    11051076                       
    11061077                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1107                                 pte_t *pte = page_mapping_find(as,
    1108                                     ptr + P2SZ(size), false);
     1078                                pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
    11091079                               
    11101080                                ASSERT(pte);
     
    11151085                               
    11161086                                /* Remove old mapping */
    1117                                 page_mapping_remove(as, ptr + P2SZ(size));
     1087                                page_mapping_remove(as, ptr + size * PAGE_SIZE);
    11181088                        }
    11191089                }
     
    11271097       
    11281098        /*
    1129          * Invalidate potential software translation caches
    1130          * (e.g. TSB on sparc64, PHT on ppc32).
     1099         * Invalidate potential software translation caches (e.g. TSB on
     1100         * sparc64).
    11311101         */
    11321102        as_invalidate_translation_cache(as, area->base, area->pages);
     
    11611131                               
    11621132                                /* Insert the new mapping */
    1163                                 page_mapping_insert(as, ptr + P2SZ(size),
     1133                                page_mapping_insert(as, ptr + size * PAGE_SIZE,
    11641134                                    old_frame[frame_idx++], page_flags);
    11651135                               
     
    12421212         */
    12431213        pte_t *pte;
    1244         if ((pte = page_mapping_find(AS, page, false))) {
     1214        if ((pte = page_mapping_find(AS, page))) {
    12451215                if (PTE_PRESENT(pte)) {
    12461216                        if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
     
    14831453       
    14841454        if (src_area) {
    1485                 size = P2SZ(src_area->pages);
     1455                size = src_area->pages * PAGE_SIZE;
    14861456                mutex_unlock(&src_area->lock);
    14871457        } else
     
    15381508                if (page >= right_pg) {
    15391509                        /* Do nothing. */
    1540                 } else if (overlaps(page, P2SZ(count), left_pg,
    1541                     P2SZ(left_cnt))) {
     1510                } else if (overlaps(page, count * PAGE_SIZE, left_pg,
     1511                    left_cnt * PAGE_SIZE)) {
    15421512                        /* The interval intersects with the left interval. */
    15431513                        return false;
    1544                 } else if (overlaps(page, P2SZ(count), right_pg,
    1545                     P2SZ(right_cnt))) {
     1514                } else if (overlaps(page, count * PAGE_SIZE, right_pg,
     1515                    right_cnt * PAGE_SIZE)) {
    15461516                        /* The interval intersects with the right interval. */
    15471517                        return false;
    1548                 } else if ((page == left_pg + P2SZ(left_cnt)) &&
    1549                     (page + P2SZ(count) == right_pg)) {
     1518                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
     1519                    (page + count * PAGE_SIZE == right_pg)) {
    15501520                        /*
    15511521                         * The interval can be added by merging the two already
     
    15551525                        btree_remove(&area->used_space, right_pg, leaf);
    15561526                        goto success;
    1557                 } else if (page == left_pg + P2SZ(left_cnt)) {
     1527                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    15581528                        /*
    15591529                         * The interval can be added by simply growing the left
     
    15621532                        node->value[node->keys - 1] += count;
    15631533                        goto success;
    1564                 } else if (page + P2SZ(count) == right_pg) {
     1534                } else if (page + count * PAGE_SIZE == right_pg) {
    15651535                        /*
    15661536                         * The interval can be addded by simply moving base of
     
    15891559                 */
    15901560               
    1591                 if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
     1561                if (overlaps(page, count * PAGE_SIZE, right_pg,
     1562                    right_cnt * PAGE_SIZE)) {
    15921563                        /* The interval intersects with the right interval. */
    15931564                        return false;
    1594                 } else if (page + P2SZ(count) == right_pg) {
     1565                } else if (page + count * PAGE_SIZE == right_pg) {
    15951566                        /*
    15961567                         * The interval can be added by moving the base of the
     
    16271598                if (page < left_pg) {
    16281599                        /* Do nothing. */
    1629                 } else if (overlaps(page, P2SZ(count), left_pg,
    1630                     P2SZ(left_cnt))) {
     1600                } else if (overlaps(page, count * PAGE_SIZE, left_pg,
     1601                    left_cnt * PAGE_SIZE)) {
    16311602                        /* The interval intersects with the left interval. */
    16321603                        return false;
    1633                 } else if (overlaps(page, P2SZ(count), right_pg,
    1634                     P2SZ(right_cnt))) {
     1604                } else if (overlaps(page, count * PAGE_SIZE, right_pg,
     1605                    right_cnt * PAGE_SIZE)) {
    16351606                        /* The interval intersects with the right interval. */
    16361607                        return false;
    1637                 } else if ((page == left_pg + P2SZ(left_cnt)) &&
    1638                     (page + P2SZ(count) == right_pg)) {
     1608                } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
     1609                    (page + count * PAGE_SIZE == right_pg)) {
    16391610                        /*
    16401611                         * The interval can be added by merging the two already
     
    16441615                        btree_remove(&area->used_space, right_pg, node);
    16451616                        goto success;
    1646                 } else if (page == left_pg + P2SZ(left_cnt)) {
     1617                } else if (page == left_pg + left_cnt * PAGE_SIZE) {
    16471618                        /*
    16481619                         * The interval can be added by simply growing the left
     
    16511622                        leaf->value[leaf->keys - 1] += count;
    16521623                        goto success;
    1653                 } else if (page + P2SZ(count) == right_pg) {
     1624                } else if (page + count * PAGE_SIZE == right_pg) {
    16541625                        /*
    16551626                         * The interval can be addded by simply moving base of
     
    16781649                 */
    16791650               
    1680                 if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
     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 + P2SZ(left_cnt) == 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, P2SZ(count), left_pg,
    1719                             P2SZ(left_cnt))) {
     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, P2SZ(count), right_pg,
    1726                             P2SZ(right_cnt))) {
     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 + P2SZ(left_cnt)) &&
    1733                             (page + P2SZ(count) == 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 + P2SZ(left_cnt)) {
     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 + P2SZ(count) == 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] += P2SZ(count);
     1786                                        leaf->key[i] += count * PAGE_SIZE;
    18151787                                        leaf->value[i] -= count;
    18161788                                        goto success;
     
    18221794        }
    18231795       
    1824         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
    1825             leaf);
     1796        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
    18261797        if ((node) && (page < leaf->key[0])) {
    18271798                uintptr_t left_pg = node->key[node->keys - 1];
    18281799                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18291800               
    1830                 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
    1831                         if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
     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) {
    18321805                                /*
    18331806                                 * The interval is contained in the rightmost
     
    18381811                                node->value[node->keys - 1] -= count;
    18391812                                goto success;
    1840                         } else if (page + P2SZ(count) <
    1841                             left_pg + P2SZ(left_cnt)) {
    1842                                 size_t new_cnt;
    1843 
     1813                        } else if (page + count * PAGE_SIZE <
     1814                            left_pg + left_cnt*PAGE_SIZE) {
    18441815                                /*
    18451816                                 * The interval is contained in the rightmost
     
    18491820                                 * new interval.
    18501821                                 */
    1851                                 new_cnt = ((left_pg + P2SZ(left_cnt)) -
    1852                                     (page + P2SZ(count))) >> PAGE_WIDTH;
     1822                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1823                                    (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
    18531824                                node->value[node->keys - 1] -= count + new_cnt;
    18541825                                btree_insert(&area->used_space, page +
    1855                                     P2SZ(count), (void *) new_cnt, leaf);
     1826                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18561827                                goto success;
    18571828                        }
     
    18661837                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18671838               
    1868                 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
    1869                         if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
     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) {
    18701843                                /*
    18711844                                 * The interval is contained in the rightmost
     
    18751848                                leaf->value[leaf->keys - 1] -= count;
    18761849                                goto success;
    1877                         } else if (page + P2SZ(count) < left_pg +
    1878                             P2SZ(left_cnt)) {
    1879                                 size_t new_cnt;
    1880 
     1850                        } else if (page + count * PAGE_SIZE < left_pg +
     1851                            left_cnt * PAGE_SIZE) {
    18811852                                /*
    18821853                                 * The interval is contained in the rightmost
     
    18861857                                 * interval.
    18871858                                 */
    1888                                 new_cnt = ((left_pg + P2SZ(left_cnt)) -
    1889                                     (page + P2SZ(count))) >> PAGE_WIDTH;
     1859                                size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
     1860                                    (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
    18901861                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18911862                                btree_insert(&area->used_space, page +
    1892                                     P2SZ(count), (void *) new_cnt, leaf);
     1863                                    count * PAGE_SIZE, (void *) new_cnt, leaf);
    18931864                                goto success;
    18941865                        }
     
    19121883                         * to (i - 1) and i.
    19131884                         */
    1914                         if (overlaps(left_pg, P2SZ(left_cnt), page,
    1915                             P2SZ(count))) {
    1916                                 if (page + P2SZ(count) ==
    1917                                     left_pg + P2SZ(left_cnt)) {
     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) {
    19181889                                        /*
    19191890                                         * The interval is contained in the
     
    19241895                                        leaf->value[i - 1] -= count;
    19251896                                        goto success;
    1926                                 } else if (page + P2SZ(count) <
    1927                                     left_pg + P2SZ(left_cnt)) {
    1928                                         size_t new_cnt;
    1929 
     1897                                } else if (page + count * PAGE_SIZE <
     1898                                    left_pg + left_cnt * PAGE_SIZE) {
    19301899                                        /*
    19311900                                         * The interval is contained in the
     
    19351904                                         * also inserting a new interval.
    19361905                                         */
    1937                                         new_cnt = ((left_pg + P2SZ(left_cnt)) -
    1938                                             (page + P2SZ(count))) >>
     1906                                        size_t new_cnt = ((left_pg +
     1907                                            left_cnt * PAGE_SIZE) -
     1908                                            (page + count * PAGE_SIZE)) >>
    19391909                                            PAGE_WIDTH;
    19401910                                        leaf->value[i - 1] -= count + new_cnt;
    19411911                                        btree_insert(&area->used_space, page +
    1942                                             P2SZ(count), (void *) new_cnt,
     1912                                            count * PAGE_SIZE, (void *) new_cnt,
    19431913                                            leaf);
    19441914                                        goto success;
     
    19891959{
    19901960        return (sysarg_t) as_area_destroy(AS, address);
    1991 }
    1992 
    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  */
    2001 sysarg_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;
    20581961}
    20591962
     
    21012004                       
    21022005                        info[area_idx].start_addr = area->base;
    2103                         info[area_idx].size = P2SZ(area->pages);
     2006                        info[area_idx].size = FRAMES2SIZE(area->pages);
    21042007                        info[area_idx].flags = area->flags;
    21052008                        ++area_idx;
     
    21242027        mutex_lock(&as->lock);
    21252028       
    2126         /* Print out info about address space areas */
     2029        /* print out info about address space areas */
    21272030        link_t *cur;
    21282031        for (cur = as->as_area_btree.leaf_head.next;
     
    21392042                            " (%p - %p)\n", area, (void *) area->base,
    21402043                            area->pages, (void *) area->base,
    2141                             (void *) (area->base + P2SZ(area->pages)));
     2044                            (void *) (area->base + FRAMES2SIZE(area->pages)));
    21422045                        mutex_unlock(&area->lock);
    21432046                }
Note: See TracChangeset for help on using the changeset viewer.