Changeset 567807b1 in mainline for generic/src/mm/as.c


Ignore:
Timestamp:
2006-05-24T17:03:29Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d6bc2d5
Parents:
82da5f5
Message:

Modify the hierarchy of page fault handlers to pass access mode that caused the fault.
Architectures are required to pass either PF_ACCESS_READ, PF_ACCESS_WRITE or PF_ACCESS_EXEC
to as_page_fault(), depending on the cause of the fault.

File:
1 edited

Legend:

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

    r82da5f5 r567807b1  
    376376        __address base;
    377377        ipl_t ipl;
     378        bool cond;
    378379
    379380        ipl = interrupts_disable();
     
    388389
    389390        base = area->base;
    390         if (!(area->flags & AS_AREA_DEVICE)) {
    391                 bool cond;     
    392        
    393                 /*
    394                  * Releasing physical memory.
    395                  * Areas mapping memory-mapped devices are treated differently than
    396                  * areas backing frame_alloc()'ed memory.
    397                  */
    398 
    399                 /*
    400                  * Visit only the pages mapped by used_space B+tree.
    401                  * Note that we must be very careful when walking the tree
    402                  * leaf list and removing used space as the leaf list changes
    403                  * unpredictibly after each remove. The solution is to actually
    404                  * not walk the tree at all, but to remove items from the head
    405                  * of the leaf list until there are some keys left.
    406                  */
    407                 for (cond = true; cond;) {
    408                         btree_node_t *node;
     391
     392        /*
     393         * Visit only the pages mapped by used_space B+tree.
     394         * Note that we must be very careful when walking the tree
     395         * leaf list and removing used space as the leaf list changes
     396         * unpredictibly after each remove. The solution is to actually
     397         * not walk the tree at all, but to remove items from the head
     398         * of the leaf list until there are some keys left.
     399         */
     400        for (cond = true; cond;) {
     401                btree_node_t *node;
    409402               
    410                         ASSERT(!list_empty(&area->used_space.leaf_head));
    411                         node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link);
    412                         if ((cond = (bool) node->keys)) {
    413                                 __address b = node->key[0];
    414                                 count_t i;
    415                                 pte_t *pte;
     403                ASSERT(!list_empty(&area->used_space.leaf_head));
     404                node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link);
     405                if ((cond = (bool) node->keys)) {
     406                        __address b = node->key[0];
     407                        count_t i;
     408                        pte_t *pte;
    416409                       
    417                                 for (i = 0; i < (count_t) node->value[0]; i++) {
    418                                         page_table_lock(as, false);
    419                                         pte = page_mapping_find(as, b + i*PAGE_SIZE);
    420                                         ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
    421                                         if (area->backend && area->backend->backend_frame_free) {
    422                                                 area->backend->backend_frame_free(area,
    423                                                         b + i*PAGE_SIZE, PTE_GET_FRAME(pte));
    424                                         }
    425                                         page_mapping_remove(as, b + i*PAGE_SIZE);
    426                                         page_table_unlock(as, false);
     410                        for (i = 0; i < (count_t) node->value[0]; i++) {
     411                                page_table_lock(as, false);
     412                                pte = page_mapping_find(as, b + i*PAGE_SIZE);
     413                                ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
     414                                if (area->backend && area->backend->backend_frame_free) {
     415                                        area->backend->backend_frame_free(area,
     416                                                b + i*PAGE_SIZE, PTE_GET_FRAME(pte));
    427417                                }
    428                                 if (!used_space_remove(area, b, i))
    429                                         panic("Could not remove used space.\n");
     418                                page_mapping_remove(as, b + i*PAGE_SIZE);
     419                                page_table_unlock(as, false);
    430420                        }
     421                        if (!used_space_remove(area, b, i))
     422                                panic("Could not remove used space.\n");
    431423                }
    432424        }
     
    624616 *
    625617 * @param page Faulting page.
     618 * @param access Access mode that caused the fault (i.e. read/write/exec).
    626619 * @param istate Pointer to interrupted state.
    627620 *
     
    629622 *         fault was caused by copy_to_uspace() or copy_from_uspace().
    630623 */
    631 int as_page_fault(__address page, istate_t *istate)
     624int as_page_fault(__address page, pf_access_t access, istate_t *istate)
    632625{
    633626        pte_t *pte;
     
    689682         * Resort to the backend page fault handler.
    690683         */
    691         if (area->backend->backend_page_fault(area, page) != AS_PF_OK) {
     684        if (area->backend->backend_page_fault(area, page, access) != AS_PF_OK) {
    692685                page_table_unlock(AS, false);
    693686                mutex_unlock(&area->lock);
     
    14511444}
    14521445
    1453 static int anon_page_fault(as_area_t *area, __address addr);
     1446static int anon_page_fault(as_area_t *area, __address addr, pf_access_t access);
    14541447static void anon_frame_free(as_area_t *area, __address page, __address frame);
    14551448
     
    14681461 * @param area Pointer to the address space area.
    14691462 * @param addr Faulting virtual address.
     1463 * @param access Access mode that caused the fault (i.e. read/write/exec).
    14701464 *
    14711465 * @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced).
    14721466 */
    1473 int anon_page_fault(as_area_t *area, __address addr)
     1467int anon_page_fault(as_area_t *area, __address addr, pf_access_t access)
    14741468{
    14751469        __address frame;
Note: See TracChangeset for help on using the changeset viewer.