Changeset 346b12a2 in mainline for kernel/genarch/src


Ignore:
Timestamp:
2016-08-31T17:51:04Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb63c06
Parents:
38dc82d
Message:

Add page_mapping_update()

page_mapping_update() can be used to safely update the accessed and dirty
bits of a PTE in the actual page tables.

Location:
kernel/genarch/src/mm
Files:
2 edited

Legend:

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

    r38dc82d r346b12a2  
    6060static void ht_mapping_remove(as_t *, uintptr_t);
    6161static bool ht_mapping_find(as_t *, uintptr_t, bool, pte_t *);
     62static void ht_mapping_update(as_t *, uintptr_t, bool, pte_t *);
    6263static void ht_mapping_make_global(uintptr_t, size_t);
    6364
     
    9192        .mapping_remove = ht_mapping_remove,
    9293        .mapping_find = ht_mapping_find,
     94        .mapping_update = ht_mapping_update,
    9395        .mapping_make_global = ht_mapping_make_global
    9496};
     
    245247}
    246248
     249static pte_t *ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
     250{
     251        sysarg_t key[2] = {
     252                (uintptr_t) as,
     253                page = ALIGN_DOWN(page, PAGE_SIZE)
     254        };
     255
     256        ASSERT(nolock || page_table_locked(as));
     257       
     258        link_t *cur = hash_table_find(&page_ht, key);
     259        if (cur)
     260                return hash_table_get_instance(cur, pte_t, link);
     261       
     262        return NULL;
     263}
    247264
    248265/** Find mapping for virtual page in page hash table.
     
    257274bool ht_mapping_find(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
    258275{
    259         sysarg_t key[2] = {
    260                 (uintptr_t) as,
    261                 page = ALIGN_DOWN(page, PAGE_SIZE)
    262         };
    263 
    264         ASSERT(nolock || page_table_locked(as));
    265        
    266         link_t *cur = hash_table_find(&page_ht, key);
    267         if (cur)
    268                 *pte = *hash_table_get_instance(cur, pte_t, link);
    269        
    270         return cur != NULL;
     276        pte_t *t = ht_mapping_find_internal(as, page, nolock);
     277        if (t)
     278                *pte = *t;
     279       
     280        return t != NULL;
     281}
     282
     283/** Update mapping for virtual page in page hash table.
     284 *
     285 * @param as       Address space to which page belongs.
     286 * @param page     Virtual page.
     287 * @param nolock   True if the page tables need not be locked.
     288 * @param pte      New PTE.
     289 */
     290void ht_mapping_update(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
     291{
     292        pte_t *t = ht_mapping_find_internal(as, page, nolock);
     293        if (!t)
     294                panic("Updating non-existent PTE");
     295       
     296        ASSERT(pte->as == t->as);
     297        ASSERT(pte->page == t->page);
     298        ASSERT(pte->frame == t->frame);
     299        ASSERT(pte->g == t->g);
     300        ASSERT(pte->x == t->x);
     301        ASSERT(pte->w == t->w);
     302        ASSERT(pte->k == t->k);
     303        ASSERT(pte->c == t->c);
     304        ASSERT(pte->p == t->p);
     305
     306        t->a = pte->a;
     307        t->d = pte->d;
    271308}
    272309
  • kernel/genarch/src/mm/page_pt.c

    r38dc82d r346b12a2  
    5454static void pt_mapping_remove(as_t *, uintptr_t);
    5555static 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};
     
    289291}
    290292
     293static pte_t *pt_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
     294{
     295        ASSERT(nolock || page_table_locked(as));
     296
     297        pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
     298        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
     299                return NULL;
     300
     301        read_barrier();
     302       
     303        pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
     304        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
     305                return NULL;
     306
     307#if (PTL1_ENTRIES != 0)
     308        /*
     309         * Always read ptl2 only after we are sure it is present.
     310         */
     311        read_barrier();
     312#endif
     313       
     314        pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
     315        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
     316                return NULL;
     317
     318#if (PTL2_ENTRIES != 0)
     319        /*
     320         * Always read ptl3 only after we are sure it is present.
     321         */
     322        read_barrier();
     323#endif
     324       
     325        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     326       
     327        return &ptl3[PTL3_INDEX(page)];
     328}
     329
    291330/** Find mapping for virtual page in hierarchical page tables.
    292331 *
     
    300339bool pt_mapping_find(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
    301340{
    302         ASSERT(nolock || page_table_locked(as));
    303 
    304         pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    305         if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
    306                 return false;
    307 
    308         read_barrier();
    309        
    310         pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    311         if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
    312                 return false;
    313 
    314 #if (PTL1_ENTRIES != 0)
    315         /*
    316          * Always read ptl2 only after we are sure it is present.
    317          */
    318         read_barrier();
    319 #endif
    320        
    321         pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    322         if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
    323                 return false;
    324 
    325 #if (PTL2_ENTRIES != 0)
    326         /*
    327          * Always read ptl3 only after we are sure it is present.
    328          */
    329         read_barrier();
    330 #endif
    331        
    332         pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    333        
    334         *pte = ptl3[PTL3_INDEX(page)];
    335         return true;
     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;
    336367}
    337368
Note: See TracChangeset for help on using the changeset viewer.