Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/mm/page_pt.c

    rde73242 r346b12a2  
    5353static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    5454static void pt_mapping_remove(as_t *, uintptr_t);
    55 static pte_t *pt_mapping_find(as_t *, uintptr_t, bool);
     55static bool pt_mapping_find(as_t *, uintptr_t, bool, pte_t *pte);
     56static void pt_mapping_update(as_t *, uintptr_t, bool, pte_t *pte);
    5657static void pt_mapping_make_global(uintptr_t, size_t);
    5758
     
    6061        .mapping_remove = pt_mapping_remove,
    6162        .mapping_find = pt_mapping_find,
     63        .mapping_update = pt_mapping_update,
    6264        .mapping_make_global = pt_mapping_make_global
    6365};
     
    8284       
    8385        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    84                 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE,
    85                     FRAME_LOWMEM | FRAME_KA);
    86                 memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
     86                pte_t *newpt = (pte_t *)
     87                    PA2KA(frame_alloc(PTL1_FRAMES, FRAME_LOWMEM, PTL1_SIZE - 1));
     88                memsetb(newpt, PTL1_SIZE, 0);
    8789                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
    8890                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page),
     
    101103       
    102104        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    103                 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE,
    104                     FRAME_LOWMEM | FRAME_KA);
    105                 memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
     105                pte_t *newpt = (pte_t *)
     106                    PA2KA(frame_alloc(PTL2_FRAMES, FRAME_LOWMEM, PTL2_SIZE - 1));
     107                memsetb(newpt, PTL2_SIZE, 0);
    106108                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
    107109                SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page),
     
    112114                 */
    113115                write_barrier();
    114                 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));       
     116                SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));
    115117        }
    116118       
     
    118120       
    119121        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    120                 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE,
    121                     FRAME_LOWMEM | FRAME_KA);
    122                 memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
     122                pte_t *newpt = (pte_t *)
     123                    PA2KA(frame_alloc(PTL3_FRAMES, FRAME_LOWMEM, PTL2_SIZE - 1));
     124                memsetb(newpt, PTL2_SIZE, 0);
    123125                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
    124126                SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page),
     
    180182         * Destroy the mapping.
    181183         * Setting to PAGE_NOT_PRESENT is not sufficient.
    182          */
     184         * But we need SET_FRAME for possible PT coherence maintenance.
     185         * At least on ARM.
     186         */
     187        //TODO: Fix this inconsistency
     188        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), PAGE_NOT_PRESENT);
    183189        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    184190       
     
    215221                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    216222#endif
    217                 frame_free(KA2PA((uintptr_t) ptl3));
     223                frame_free(KA2PA((uintptr_t) ptl3), PTL3_FRAMES);
    218224        } else {
    219225                /*
     
    249255                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    250256#endif
    251                 frame_free(KA2PA((uintptr_t) ptl2));
     257                frame_free(KA2PA((uintptr_t) ptl2), PTL2_FRAMES);
    252258        } else {
    253259                /*
     
    280286
    281287                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    282                 frame_free(KA2PA((uintptr_t) ptl1));
     288                frame_free(KA2PA((uintptr_t) ptl1), PTL1_FRAMES);
    283289        }
    284290#endif /* PTL1_ENTRIES != 0 */
    285291}
    286292
    287 /** Find mapping for virtual page in hierarchical page tables.
    288  *
    289  * @param as     Address space to which page belongs.
    290  * @param page   Virtual page.
    291  * @param nolock True if the page tables need not be locked.
    292  *
    293  * @return NULL if there is no such mapping; entry from PTL3 describing
    294  *         the mapping otherwise.
    295  *
    296  */
    297 pte_t *pt_mapping_find(as_t *as, uintptr_t page, bool nolock)
     293static pte_t *pt_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
    298294{
    299295        ASSERT(nolock || page_table_locked(as));
     
    330326       
    331327        return &ptl3[PTL3_INDEX(page)];
     328}
     329
     330/** Find mapping for virtual page in hierarchical page tables.
     331 *
     332 * @param as       Address space to which page belongs.
     333 * @param page     Virtual page.
     334 * @param nolock   True if the page tables need not be locked.
     335 * @param[out] pte Structure that will receive a copy of the found PTE.
     336 *
     337 * @return True if the mapping was found, false otherwise.
     338 */
     339bool pt_mapping_find(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
     340{
     341        pte_t *t = pt_mapping_find_internal(as, page, nolock);
     342        if (t)
     343                *pte = *t;
     344        return t != NULL;
     345}
     346
     347/** Update mapping for virtual page in hierarchical page tables.
     348 *
     349 * @param as       Address space to which page belongs.
     350 * @param page     Virtual page.
     351 * @param nolock   True if the page tables need not be locked.
     352 * @param[in] pte  New PTE.
     353 */
     354void pt_mapping_update(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
     355{
     356        pte_t *t = pt_mapping_find_internal(as, page, nolock);
     357        if (!t)
     358                panic("Updating non-existent PTE");     
     359
     360        ASSERT(PTE_VALID(t) == PTE_VALID(pte));
     361        ASSERT(PTE_PRESENT(t) == PTE_PRESENT(pte));
     362        ASSERT(PTE_GET_FRAME(t) == PTE_GET_FRAME(pte));
     363        ASSERT(PTE_WRITABLE(t) == PTE_WRITABLE(pte));
     364        ASSERT(PTE_EXECUTABLE(t) == PTE_EXECUTABLE(pte));
     365
     366        *t = *pte;
    332367}
    333368
     
    359394 * @param size Size in bytes defining the range of PTL0 entries that will be
    360395 *             altered by this function.
     396 *
    361397 */
    362398void pt_mapping_make_global(uintptr_t base, size_t size)
    363399{
     400        ASSERT(size > 0);
     401       
    364402        uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
    365403        uintptr_t ptl0_step = ptl0_step_get();
    366         size_t order;
    367         uintptr_t addr;
    368 
     404        size_t frames;
     405       
    369406#if (PTL1_ENTRIES != 0)
    370         order = PTL1_SIZE;
     407        frames = PTL1_FRAMES;
    371408#elif (PTL2_ENTRIES != 0)
    372         order = PTL2_SIZE;
     409        frames = PTL2_FRAMES;
    373410#else
    374         order = PTL3_SIZE;
     411        frames = PTL3_FRAMES;
    375412#endif
    376 
    377         ASSERT(size > 0);
    378 
    379         for (addr = ALIGN_DOWN(base, ptl0_step); addr - 1 < base + size - 1;
     413       
     414        for (uintptr_t addr = ALIGN_DOWN(base, ptl0_step);
     415            addr - 1 < base + size - 1;
    380416            addr += ptl0_step) {
    381                 uintptr_t l1;
    382 
    383                 l1 = (uintptr_t) frame_alloc(order, FRAME_KA | FRAME_LOWMEM);
    384                 memsetb((void *) l1, FRAME_SIZE << order, 0);
     417                if (GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr))) {
     418                        ASSERT(overlaps(addr, ptl0_step,
     419                            config.identity_base, config.identity_size));
     420
     421                        /*
     422                         * This PTL0 entry also maps the kernel identity region,
     423                         * so it is already global and initialized.
     424                         */
     425                        continue;
     426                }
     427
     428                uintptr_t l1 = PA2KA(frame_alloc(frames, FRAME_LOWMEM, 0));
     429                memsetb((void *) l1, FRAMES2SIZE(frames), 0);
    385430                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1));
    386431                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr),
Note: See TracChangeset for help on using the changeset viewer.