Ignore:
File:
1 edited

Legend:

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

    rc142860 r59fb782  
    5959static void anon_destroy(as_area_t *);
    6060
     61static bool anon_is_resizable(as_area_t *);
     62static bool anon_is_shareable(as_area_t *);
     63
    6164static int anon_page_fault(as_area_t *, uintptr_t, pf_access_t);
    6265static void anon_frame_free(as_area_t *, uintptr_t, uintptr_t);
     
    6871        .destroy = anon_destroy,
    6972
     73        .is_resizable = anon_is_resizable,
     74        .is_shareable = anon_is_shareable,
     75
    7076        .page_fault = anon_page_fault,
    7177        .frame_free = anon_frame_free,
     
    7480bool anon_create(as_area_t *area)
    7581{
     82        if (area->flags & AS_AREA_LATE_RESERVE)
     83                return true;
     84
    7685        return reserve_try_alloc(area->pages);
    7786}
     
    7988bool anon_resize(as_area_t *area, size_t new_pages)
    8089{
     90        if (area->flags & AS_AREA_LATE_RESERVE)
     91                return true;
     92
    8193        if (new_pages > area->pages)
    8294                return reserve_try_alloc(new_pages - area->pages);
     
    100112        ASSERT(mutex_locked(&area->as->lock));
    101113        ASSERT(mutex_locked(&area->lock));
     114        ASSERT(!(area->flags & AS_AREA_LATE_RESERVE));
    102115
    103116        /*
     
    139152void anon_destroy(as_area_t *area)
    140153{
     154        if (area->flags & AS_AREA_LATE_RESERVE)
     155                return;
     156
    141157        reserve_free(area->pages);
    142158}
    143159
     160bool anon_is_resizable(as_area_t *area)
     161{
     162        return true;
     163}
     164
     165bool anon_is_shareable(as_area_t *area)
     166{
     167        return !(area->flags & AS_AREA_LATE_RESERVE);
     168}
    144169
    145170/** Service a page fault in the anonymous memory address space area.
     
    148173 *
    149174 * @param area Pointer to the address space area.
    150  * @param addr Faulting virtual address.
     175 * @param upage Faulting virtual page.
    151176 * @param access Access mode that caused the fault (i.e. read/write/exec).
    152177 *
     
    154179 *     serviced).
    155180 */
    156 int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
    157 {
    158         uintptr_t upage = ALIGN_DOWN(addr, PAGE_SIZE);
     181int anon_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access)
     182{
    159183        uintptr_t kpage;
    160184        uintptr_t frame;
     
    162186        ASSERT(page_table_locked(AS));
    163187        ASSERT(mutex_locked(&area->lock));
     188        ASSERT(IS_ALIGNED(upage, PAGE_SIZE));
    164189
    165190        if (!as_area_check_access(area, access))
     
    225250                 *   the different causes
    226251                 */
     252
     253                if (area->flags & AS_AREA_LATE_RESERVE) {
     254                        /*
     255                         * Reserve the memory for this page now.
     256                         */
     257                        if (!reserve_try_alloc(1))
     258                                return AS_PF_SILENT;
     259                }
     260
    227261                kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE);
    228262                memsetb((void *) kpage, PAGE_SIZE, 0);
     
    255289        ASSERT(mutex_locked(&area->lock));
    256290
    257         frame_free_noreserve(frame);
     291        if (area->flags & AS_AREA_LATE_RESERVE) {
     292                /*
     293                 * In case of the late reserve areas, physical memory will not
     294                 * be unreserved when the area is destroyed so we need to use
     295                 * the normal unreserving frame_free().
     296                 */
     297                frame_free(frame);
     298        } else {
     299                /*
     300                 * The reserve will be given back when the area is destroyed or
     301                 * resized, so use the frame_free_noreserve() which does not
     302                 * manipulate the reserve or it would be given back twice.
     303                 */
     304                frame_free_noreserve(frame);
     305        }
    258306}
    259307
Note: See TracChangeset for help on using the changeset viewer.