Ignore:
File:
1 edited

Legend:

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

    rc964521 r336db295  
    11/*
    2  * Copyright (c) 2010 Jakub Jermar
     2 * Copyright (c) 2001-2006 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    7575#include <config.h>
    7676#include <align.h>
    77 #include <typedefs.h>
     77#include <arch/types.h>
    7878#include <syscall/copy.h>
    7979#include <arch/interrupt.h>
     
    152152         * reference count never drops to zero.
    153153         */
    154         as_hold(AS_KERNEL);
     154        atomic_set(&AS_KERNEL->refcount, 1);
    155155}
    156156
     
    200200        DEADLOCK_PROBE_INIT(p_asidlock);
    201201
    202         ASSERT(as != AS);
    203202        ASSERT(atomic_get(&as->refcount) == 0);
    204203       
    205204        /*
    206          * Since there is no reference to this address space, it is safe not to
    207          * lock its mutex.
     205         * Since there is no reference to this area,
     206         * it is safe not to lock its mutex.
    208207         */
    209208
     
    226225        preemption_enable();    /* Interrupts disabled, enable preemption */
    227226        if (as->asid != ASID_INVALID && as != AS_KERNEL) {
    228                 if (as->cpu_refcount == 0)
     227                if (as != AS && as->cpu_refcount == 0)
    229228                        list_remove(&as->inactive_as_with_asid_link);
    230229                asid_put(as->asid);
     
    259258
    260259        slab_free(as_slab, as);
    261 }
    262 
    263 /** Hold a reference to an address space.
    264  *
    265  * Holding a reference to an address space prevents destruction of that address
    266  * space.
    267  *
    268  * @param a             Address space to be held.
    269  */
    270 void as_hold(as_t *as)
    271 {
    272         atomic_inc(&as->refcount);
    273 }
    274 
    275 /** Release a reference to an address space.
    276  *
    277  * The last one to release a reference to an address space destroys the address
    278  * space.
    279  *
    280  * @param a             Address space to be released.
    281  */
    282 void as_release(as_t *as)
    283 {
    284         if (atomic_predec(&as->refcount) == 0)
    285                 as_destroy(as);
    286260}
    287261
     
    422396                 * No need to check for overlaps.
    423397                 */
    424 
    425                 page_table_lock(as, false);
    426398
    427399                /*
     
    488460                                        pte_t *pte;
    489461                       
     462                                        page_table_lock(as, false);
    490463                                        pte = page_mapping_find(as, b +
    491464                                            i * PAGE_SIZE);
     
    500473                                        page_mapping_remove(as, b +
    501474                                            i * PAGE_SIZE);
     475                                        page_table_unlock(as, false);
    502476                                }
    503477                        }
     
    510484                tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
    511485                    area->pages - pages);
    512 
    513486                /*
    514487                 * Invalidate software translation caches (e.g. TSB on sparc64).
     
    517490                    pages * PAGE_SIZE, area->pages - pages);
    518491                tlb_shootdown_finalize();
    519 
    520                 page_table_unlock(as, false);
    521492               
    522493        } else {
     
    568539
    569540        base = area->base;
    570 
    571         page_table_lock(as, false);
    572541
    573542        /*
     
    591560                       
    592561                        for (j = 0; j < (size_t) node->value[i]; j++) {
     562                                page_table_lock(as, false);
    593563                                pte = page_mapping_find(as, b + j * PAGE_SIZE);
    594564                                ASSERT(pte && PTE_VALID(pte) &&
     
    600570                                }
    601571                                page_mapping_remove(as, b + j * PAGE_SIZE);                             
     572                                page_table_unlock(as, false);
    602573                        }
    603574                }
     
    609580
    610581        tlb_invalidate_pages(as->asid, area->base, area->pages);
    611 
    612582        /*
    613583         * Invalidate potential software translation caches (e.g. TSB on
     
    616586        as_invalidate_translation_cache(as, area->base, area->pages);
    617587        tlb_shootdown_finalize();
    618 
    619         page_table_unlock(as, false);
    620588       
    621589        btree_destroy(&area->used_space);
     
    816784{
    817785        as_area_t *area;
     786        uintptr_t base;
    818787        link_t *cur;
    819788        ipl_t ipl;
     
    844813                return ENOTSUP;
    845814        }
     815
     816        base = area->base;
    846817
    847818        /*
     
    863834        /* An array for storing frame numbers */
    864835        old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
    865 
    866         page_table_lock(as, false);
    867836
    868837        /*
     
    889858                       
    890859                        for (j = 0; j < (size_t) node->value[i]; j++) {
     860                                page_table_lock(as, false);
    891861                                pte = page_mapping_find(as, b + j * PAGE_SIZE);
    892862                                ASSERT(pte && PTE_VALID(pte) &&
     
    896866                                /* Remove old mapping */
    897867                                page_mapping_remove(as, b + j * PAGE_SIZE);
     868                                page_table_unlock(as, false);
    898869                        }
    899870                }
     
    912883        as_invalidate_translation_cache(as, area->base, area->pages);
    913884        tlb_shootdown_finalize();
    914 
    915         page_table_unlock(as, false);
    916885
    917886        /*
     
    983952        if (!THREAD)
    984953                return AS_PF_FAULT;
    985        
    986         if (!AS)
    987                 return AS_PF_FAULT;
    988        
     954               
     955        ASSERT(AS);
     956
    989957        mutex_lock(&AS->lock);
    990         area = find_area_and_lock(AS, page);
     958        area = find_area_and_lock(AS, page);   
    991959        if (!area) {
    992960                /*
Note: See TracChangeset for help on using the changeset viewer.