Ignore:
File:
1 edited

Legend:

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

    r2fc3b2d rd91488d  
    153153{
    154154        elf_segment_header_t *entry = area->backend_data.segment;
    155         used_space_ival_t *start;
    156         used_space_ival_t *cur;
     155        link_t *cur;
     156        btree_node_t *leaf, *node;
    157157        uintptr_t start_anon = entry->p_vaddr + entry->p_filesz;
    158158
     
    164164         */
    165165        if (area->flags & AS_AREA_WRITE) {
    166                 start = used_space_first(&area->used_space);
     166                node = list_get_instance(list_first(&area->used_space.leaf_list),
     167                    btree_node_t, leaf_link);
    167168        } else {
    168                 /* Find first interval containing addresses >= start_anon */
    169                 start = used_space_find_gteq(&area->used_space, start_anon);
     169                (void) btree_search(&area->used_space, start_anon, &leaf);
     170                node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     171                if (!node)
     172                        node = leaf;
    170173        }
    171174
     
    174177         */
    175178        mutex_lock(&area->sh_info->lock);
    176         cur = start;
    177         while (cur != NULL) {
    178                 uintptr_t base = cur->page;
    179                 size_t count = cur->count;
     179        for (cur = &node->leaf_link; cur != &area->used_space.leaf_list.head;
     180            cur = cur->next) {
    180181                unsigned int i;
    181182
    182                 /*
    183                  * Skip read-only areas of used space that are backed
    184                  * by the ELF image.
    185                  */
    186                 if (!(area->flags & AS_AREA_WRITE))
    187                         if (base >= entry->p_vaddr &&
    188                             base + P2SZ(count) <= start_anon)
    189                                 continue;
    190 
    191                 for (i = 0; i < count; i++) {
    192                         pte_t pte;
    193                         bool found;
     183                node = list_get_instance(cur, btree_node_t, leaf_link);
     184
     185                for (i = 0; i < node->keys; i++) {
     186                        uintptr_t base = node->key[i];
     187                        size_t count = (size_t) node->value[i];
     188                        unsigned int j;
    194189
    195190                        /*
    196                          * Skip read-only pages that are backed by the
    197                          * ELF image.
     191                         * Skip read-only areas of used space that are backed
     192                         * by the ELF image.
    198193                         */
    199194                        if (!(area->flags & AS_AREA_WRITE))
    200195                                if (base >= entry->p_vaddr &&
    201                                     base + P2SZ(i + 1) <= start_anon)
     196                                    base + P2SZ(count) <= start_anon)
    202197                                        continue;
    203198
    204                         page_table_lock(area->as, false);
    205                         found = page_mapping_find(area->as,
    206                             base + P2SZ(i), false, &pte);
    207 
    208                         (void) found;
    209                         assert(found);
    210                         assert(PTE_VALID(&pte));
    211                         assert(PTE_PRESENT(&pte));
    212 
    213                         as_pagemap_insert(&area->sh_info->pagemap,
    214                             (base + P2SZ(i)) - area->base,
    215                             PTE_GET_FRAME(&pte));
    216                         page_table_unlock(area->as, false);
    217 
    218                         pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
    219                         frame_reference_add(pfn);
    220                 }
    221 
    222                 cur = used_space_next(cur);
    223         }
    224 
     199                        for (j = 0; j < count; j++) {
     200                                pte_t pte;
     201                                bool found;
     202
     203                                /*
     204                                 * Skip read-only pages that are backed by the
     205                                 * ELF image.
     206                                 */
     207                                if (!(area->flags & AS_AREA_WRITE))
     208                                        if (base >= entry->p_vaddr &&
     209                                            base + P2SZ(j + 1) <= start_anon)
     210                                                continue;
     211
     212                                page_table_lock(area->as, false);
     213                                found = page_mapping_find(area->as,
     214                                    base + P2SZ(j), false, &pte);
     215
     216                                (void) found;
     217                                assert(found);
     218                                assert(PTE_VALID(&pte));
     219                                assert(PTE_PRESENT(&pte));
     220
     221                                btree_insert(&area->sh_info->pagemap,
     222                                    (base + P2SZ(j)) - area->base,
     223                                    (void *) PTE_GET_FRAME(&pte), NULL);
     224                                page_table_unlock(area->as, false);
     225
     226                                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
     227                                frame_reference_add(pfn);
     228                        }
     229
     230                }
     231        }
    225232        mutex_unlock(&area->sh_info->lock);
    226233}
     
    260267        elf_header_t *elf = area->backend_data.elf;
    261268        elf_segment_header_t *entry = area->backend_data.segment;
     269        btree_node_t *leaf;
    262270        uintptr_t base;
    263271        uintptr_t frame;
     
    293301        mutex_lock(&area->sh_info->lock);
    294302        if (area->sh_info->shared) {
     303                bool found = false;
     304
    295305                /*
    296306                 * The address space area is shared.
    297307                 */
    298308
    299                 errno_t rc = as_pagemap_find(&area->sh_info->pagemap,
    300                     upage - area->base, &frame);
    301                 if (rc == EOK) {
     309                frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
     310                    upage - area->base, &leaf);
     311                if (!frame) {
     312                        unsigned int i;
     313
     314                        /*
     315                         * Workaround for valid NULL address.
     316                         */
     317
     318                        for (i = 0; i < leaf->keys; i++) {
     319                                if (leaf->key[i] == upage - area->base) {
     320                                        found = true;
     321                                        break;
     322                                }
     323                        }
     324                }
     325                if (frame || found) {
    302326                        frame_reference_add(ADDR2PFN(frame));
    303327                        page_mapping_insert(AS, upage, frame,
    304328                            as_area_get_flags(area));
    305                         if (!used_space_insert(&area->used_space, upage, 1))
     329                        if (!used_space_insert(area, upage, 1))
    306330                                panic("Cannot insert used space.");
    307331                        mutex_unlock(&area->sh_info->lock);
     
    391415        if (dirty && area->sh_info->shared) {
    392416                frame_reference_add(ADDR2PFN(frame));
    393                 as_pagemap_insert(&area->sh_info->pagemap, upage - area->base,
    394                     frame);
     417                btree_insert(&area->sh_info->pagemap, upage - area->base,
     418                    (void *) frame, leaf);
    395419        }
    396420
     
    398422
    399423        page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
    400         if (!used_space_insert(&area->used_space, upage, 1))
     424        if (!used_space_insert(area, upage, 1))
    401425                panic("Cannot insert used space.");
    402426
Note: See TracChangeset for help on using the changeset viewer.