Ignore:
File:
1 edited

Legend:

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

    r57355a40 rc4c2406  
    285285/** Check area conflicts with other areas.
    286286 *
    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 guarded True if the area being tested is protected by guard pages.
    291  * @param avoid   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.
    292291 *
    293292 * @return True if there is no conflict, false otherwise.
     
    295294 */
    296295NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
    297     size_t count, bool guarded, as_area_t *avoid)
     296    size_t count, as_area_t *avoid)
    298297{
    299298        ASSERT((addr % PAGE_SIZE) == 0);
    300299        ASSERT(mutex_locked(&as->lock));
    301 
    302         /*
    303          * If the addition of the supposed area address and size overflows,
    304          * report conflict.
    305          */
    306         if (overflows_into_positive(addr, P2SZ(count)))
    307                 return false;
    308300       
    309301        /*
     
    312304        if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))
    313305                return false;
    314 
     306       
    315307        /*
    316308         * The leaf node is found in O(log n), where n is proportional to
     
    336328                if (area != avoid) {
    337329                        mutex_lock(&area->lock);
    338 
    339                         /*
    340                          * If at least one of the two areas are protected
    341                          * by the AS_AREA_GUARD flag then we must be sure
    342                          * that they are separated by at least one unmapped
    343                          * page.
    344                          */
    345                         int const gp = (guarded ||
    346                             (area->flags & AS_AREA_GUARD)) ? 1 : 0;
    347                        
    348                         /*
    349                          * The area comes from the left neighbour node, which
    350                          * means that there already are some areas in the leaf
    351                          * node, which in turn means that adding gp is safe and
    352                          * will not cause an integer overflow.
    353                          */
     330                       
    354331                        if (overlaps(addr, P2SZ(count), area->base,
    355                             P2SZ(area->pages + gp))) {
    356                                 mutex_unlock(&area->lock);
    357                                 return false;
    358                         }
    359                        
    360                         mutex_unlock(&area->lock);
    361                 }
    362         }
    363        
    364         node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    365         if (node) {
    366                 area = (as_area_t *) node->value[0];
    367                
    368                 if (area != avoid) {
    369                         int gp;
    370 
    371                         mutex_lock(&area->lock);
    372 
    373                         gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
    374                         if (gp && overflows(addr, P2SZ(count))) {
    375                                 /*
    376                                  * Guard page not needed if the supposed area
    377                                  * is adjacent to the end of the address space.
    378                                  * We already know that the following test is
    379                                  * going to fail...
    380                                  */
    381                                 gp--;
    382                         }
    383                        
    384                         if (overlaps(addr, P2SZ(count + gp), area->base,
    385332                            P2SZ(area->pages))) {
    386333                                mutex_unlock(&area->lock);
     
    392339        }
    393340       
     341        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
     342        if (node) {
     343                area = (as_area_t *) node->value[0];
     344               
     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                       
     354                        mutex_unlock(&area->lock);
     355                }
     356        }
     357       
    394358        /* Second, check the leaf node. */
    395359        btree_key_t i;
    396360        for (i = 0; i < leaf->keys; i++) {
    397361                area = (as_area_t *) leaf->value[i];
    398                 int agp;
    399                 int gp;
    400362               
    401363                if (area == avoid)
     
    403365               
    404366                mutex_lock(&area->lock);
    405 
    406                 gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
    407                 agp = gp;
    408 
    409                 /*
    410                  * Sanitize the two possible unsigned integer overflows.
    411                  */
    412                 if (gp && overflows(addr, P2SZ(count)))
    413                         gp--;
    414                 if (agp && overflows(area->base, P2SZ(area->pages)))
    415                         agp--;
    416 
    417                 if (overlaps(addr, P2SZ(count + gp), area->base,
    418                     P2SZ(area->pages + agp))) {
     367               
     368                if (overlaps(addr, P2SZ(count), area->base,
     369                    P2SZ(area->pages))) {
    419370                        mutex_unlock(&area->lock);
    420371                        return false;
     
    426377        /*
    427378         * So far, the area does not conflict with other areas.
    428          * Check if it is contained in the user address space.
     379         * Check if it doesn't conflict with kernel address space.
    429380         */
    430381        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    431                 return iswithin(USER_ADDRESS_SPACE_START,
    432                     (USER_ADDRESS_SPACE_END - USER_ADDRESS_SPACE_START) + 1,
    433                     addr, P2SZ(count));
     382                return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
     383                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    434384        }
    435385       
     
    442392 * this function.
    443393 *
    444  * @param as      Address space.
    445  * @param bound   Lowest address bound.
    446  * @param size    Requested size of the allocation.
    447  * @param guarded True if the allocation must be protected by guard pages.
     394 * @param as    Address space.
     395 * @param bound Lowest address bound.
     396 * @param size  Requested size of the allocation.
    448397 *
    449398 * @return Address of the beginning of unmapped address space area.
     
    452401 */
    453402NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
    454     size_t size, bool guarded)
     403    size_t size)
    455404{
    456405        ASSERT(mutex_locked(&as->lock));
     
    474423        /* First check the bound address itself */
    475424        uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
    476         if (addr >= bound) {
    477                 if (guarded) {
    478                         /* Leave an unmapped page between the lower
    479                          * bound and the area's start address.
    480                          */
    481                         addr += P2SZ(1);
    482                 }
    483 
    484                 if (check_area_conflicts(as, addr, pages, guarded, NULL))
    485                         return addr;
    486         }
     425        if ((addr >= bound) &&
     426            (check_area_conflicts(as, addr, pages, NULL)))
     427                return addr;
    487428       
    488429        /* Eventually check the addresses behind each area */
     
    498439                        addr =
    499440                            ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
    500 
    501                         if (guarded || area->flags & AS_AREA_GUARD) {
    502                                 /* We must leave an unmapped page
    503                                  * between the two areas.
    504                                  */
    505                                 addr += P2SZ(1);
    506                         }
    507 
    508441                        bool avail =
    509442                            ((addr >= bound) && (addr >= area->base) &&
    510                             (check_area_conflicts(as, addr, pages, guarded, area)));
     443                            (check_area_conflicts(as, addr, pages, area)));
    511444                       
    512445                        mutex_unlock(&area->lock);
     
    548481        if (size == 0)
    549482                return NULL;
    550 
     483       
    551484        size_t pages = SIZE2FRAMES(size);
    552485       
     
    554487        if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
    555488                return NULL;
    556 
    557         bool const guarded = flags & AS_AREA_GUARD;
    558489       
    559490        mutex_lock(&as->lock);
    560491       
    561492        if (*base == (uintptr_t) -1) {
    562                 *base = as_get_unmapped_area(as, bound, size, guarded);
     493                *base = as_get_unmapped_area(as, bound, size);
    563494                if (*base == (uintptr_t) -1) {
    564495                        mutex_unlock(&as->lock);
     
    566497                }
    567498        }
    568 
    569         if (overflows_into_positive(*base, size))
    570                 return NULL;
    571 
    572         if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
     499       
     500        if (!check_area_conflicts(as, *base, pages, NULL)) {
    573501                mutex_unlock(&as->lock);
    574502                return NULL;
     
    697625                return ENOENT;
    698626        }
    699 
    700         if (!area->backend->is_resizable(area)) {
     627       
     628        if (area->backend == &phys_backend) {
    701629                /*
    702                  * The backend does not support resizing for this area.
     630                 * Remapping of address space areas associated
     631                 * with memory mapped devices is not supported.
    703632                 */
    704633                mutex_unlock(&area->lock);
     
    847776                /*
    848777                 * Growing the area.
    849                  */
    850 
    851                 if (overflows_into_positive(address, P2SZ(pages)))
    852                         return EINVAL;
    853 
    854                 /*
    855778                 * Check for overlaps with other address space areas.
    856779                 */
    857                 bool const guarded = area->flags & AS_AREA_GUARD;
    858                 if (!check_area_conflicts(as, address, pages, guarded, area)) {
     780                if (!check_area_conflicts(as, address, pages, area)) {
    859781                        mutex_unlock(&area->lock);
    860782                        mutex_unlock(&as->lock);
     
    1057979        }
    1058980       
    1059         if (!src_area->backend->is_shareable(src_area)) {
     981        if ((!src_area->backend) || (!src_area->backend->share)) {
    1060982                /*
    1061                  * The backend does not permit sharing of this area.
     983                 * There is no backend or the backend does not
     984                 * know how to share the area.
    1062985                 */
    1063986                mutex_unlock(&src_area->lock);
     
    21312054{
    21322055        uintptr_t virt = base;
    2133         as_area_t *area = as_area_create(AS, flags | AS_AREA_CACHEABLE, size,
     2056        as_area_t *area = as_area_create(AS, flags, size,
    21342057            AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
    21352058        if (area == NULL)
Note: See TracChangeset for help on using the changeset viewer.