Changeset 2a2fbc8 in mainline


Ignore:
Timestamp:
2016-09-01T17:05:13Z (8 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
42d08592
Parents:
f126c87 (diff), fb63c06 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/pt

Location:
kernel
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/abs32le/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    115115/* Macros for querying the last level entries. */
    116116#define PTE_VALID_ARCH(p) \
    117         (*((uint32_t *) (p)) != 0)
     117        ((p)->soft_valid != 0)
    118118#define PTE_PRESENT_ARCH(p) \
    119119        ((p)->present != 0)
  • kernel/arch/amd64/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    131131/* Macros for querying the last-level PTE entries. */
    132132#define PTE_VALID_ARCH(p) \
    133         (*((uint64_t *) (p)) != 0)
     133        ((p)->soft_valid != 0)
    134134#define PTE_PRESENT_ARCH(p) \
    135135        ((p)->present != 0)
  • kernel/arch/arm32/include/arch/mm/page_armv4.h

    rf126c87 r2a2fbc8  
    4444/* Macros for querying the last-level PTE entries. */
    4545#define PTE_VALID_ARCH(pte) \
    46         (*((uint32_t *) (pte)) != 0)
     46        (((pte_t *) (pte))->l0.should_be_zero != 0 || PTE_PRESENT_ARCH(pte))
    4747#define PTE_PRESENT_ARCH(pte) \
    4848        (((pte_t *) (pte))->l0.descriptor_type != 0)
  • kernel/arch/arm32/include/arch/mm/page_armv6.h

    rf126c87 r2a2fbc8  
    4444/* Macros for querying the last-level PTE entries. */
    4545#define PTE_VALID_ARCH(pte) \
    46         (*((uint32_t *) (pte)) != 0)
     46        (((pte_t *) (pte))->l0.should_be_zero_0 != 0 || PTE_PRESENT_ARCH(pte))
    4747#define PTE_PRESENT_ARCH(pte) \
    4848        (((pte_t *) (pte))->l0.descriptor_type != 0)
  • kernel/arch/ia32/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    132132/* Macros for querying the last level entries. */
    133133#define PTE_VALID_ARCH(p) \
    134         (*((uint32_t *) (p)) != 0)
     134        ((p)->soft_valid != 0)
    135135#define PTE_PRESENT_ARCH(p) \
    136136        ((p)->present != 0)
  • kernel/arch/ia64/src/mm/tlb.c

    rf126c87 r2a2fbc8  
    484484{
    485485        uintptr_t va;
    486         pte_t *t;
     486        pte_t t;
    487487       
    488488        va = istate->cr_ifa; /* faulting address */
     
    490490        ASSERT(!is_kernel_fault(va));
    491491
    492         t = page_mapping_find(AS, va, true);
    493         if (t) {
     492        bool found = page_mapping_find(AS, va, true, &t);
     493        if (found) {
    494494                /*
    495495                 * The mapping was found in software page hash table.
    496496                 * Insert it into data translation cache.
    497497                 */
    498                 itc_pte_copy(t);
     498                itc_pte_copy(&t);
    499499        } else {
    500500                /*
     
    600600       
    601601       
    602         pte_t *entry = page_mapping_find(as, va, true);
    603         if (entry) {
     602        pte_t t;
     603        bool found = page_mapping_find(as, va, true, &t);
     604        if (found) {
    604605                /*
    605606                 * The mapping was found in the software page hash table.
    606607                 * Insert it into data translation cache.
    607608                 */
    608                 dtc_pte_copy(entry);
     609                dtc_pte_copy(&t);
    609610        } else {
    610611                if (try_memmap_io_insertion(va, istate))
     
    641642{
    642643        uintptr_t va;
    643         pte_t *t;
     644        pte_t t;
    644645        as_t *as = AS;
    645646       
     
    649650                as = AS_KERNEL;
    650651
    651         t = page_mapping_find(as, va, true);
    652         ASSERT((t) && (t->p));
    653         if ((t) && (t->p) && (t->w)) {
     652        bool found = page_mapping_find(as, va, true, &t);
     653
     654        ASSERT(found);
     655        ASSERT(t.p);
     656
     657        if (found && t.p && t.w) {
    654658                /*
    655659                 * Update the Dirty bit in page tables and reinsert
    656660                 * the mapping into DTC.
    657661                 */
    658                 t->d = true;
    659                 dtc_pte_copy(t);
     662                t.d = true;
     663                dtc_pte_copy(&t);
     664                page_mapping_update(as, va, true, &t);
    660665        } else {
    661666                as_page_fault(va, PF_ACCESS_WRITE, istate);
     
    672677{
    673678        uintptr_t va;
    674         pte_t *t;
     679        pte_t t;
    675680       
    676681        va = istate->cr_ifa;  /* faulting address */
     
    678683        ASSERT(!is_kernel_fault(va));
    679684       
    680         t = page_mapping_find(AS, va, true);
    681         ASSERT((t) && (t->p));
    682         if ((t) && (t->p) && (t->x)) {
     685        bool found = page_mapping_find(AS, va, true, &t);
     686
     687        ASSERT(found);
     688        ASSERT(t.p);
     689
     690        if (found && t.p && t.x) {
    683691                /*
    684692                 * Update the Accessed bit in page tables and reinsert
    685693                 * the mapping into ITC.
    686694                 */
    687                 t->a = true;
    688                 itc_pte_copy(t);
     695                t.a = true;
     696                itc_pte_copy(&t);
     697                page_mapping_update(AS, va, true, &t);
    689698        } else {
    690699                as_page_fault(va, PF_ACCESS_EXEC, istate);
     
    701710{
    702711        uintptr_t va;
    703         pte_t *t;
     712        pte_t t;
    704713        as_t *as = AS;
    705714       
     
    709718                as = AS_KERNEL;
    710719
    711         t = page_mapping_find(as, va, true);
    712         ASSERT((t) && (t->p));
    713         if ((t) && (t->p)) {
     720        bool found = page_mapping_find(as, va, true, &t);
     721
     722        ASSERT(found);
     723        ASSERT(t.p);
     724
     725        if (found && t.p) {
    714726                /*
    715727                 * Update the Accessed bit in page tables and reinsert
    716728                 * the mapping into DTC.
    717729                 */
    718                 t->a = true;
    719                 dtc_pte_copy(t);
     730                t.a = true;
     731                dtc_pte_copy(&t);
     732                page_mapping_update(as, va, true, &t);
    720733        } else {
    721734                if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
     
    736749{
    737750        uintptr_t va;
    738         pte_t *t;
     751        pte_t t;
    739752       
    740753        va = istate->cr_ifa;  /* faulting address */
     
    745758         * Assume a write to a read-only page.
    746759         */
    747         t = page_mapping_find(AS, va, true);
    748         ASSERT((t) && (t->p));
    749         ASSERT(!t->w);
     760        bool found = page_mapping_find(AS, va, true, &t);
     761
     762        ASSERT(found);
     763        ASSERT(t.p);
     764        ASSERT(!t.w);
     765
    750766        as_page_fault(va, PF_ACCESS_WRITE, istate);
    751767}
     
    760776{
    761777        uintptr_t va;
    762         pte_t *t;
     778        pte_t t;
    763779       
    764780        va = istate->cr_ifa;  /* faulting address */
     
    766782        ASSERT(!is_kernel_fault(va));
    767783
    768         t = page_mapping_find(AS, va, true);
    769         ASSERT(t);
    770        
    771         if (t->p) {
     784        bool found = page_mapping_find(AS, va, true, &t);
     785
     786        ASSERT(found);
     787       
     788        if (t.p) {
    772789                /*
    773790                 * If the Present bit is set in page hash table, just copy it
    774791                 * and update ITC/DTC.
    775792                 */
    776                 if (t->x)
    777                         itc_pte_copy(t);
     793                if (t.x)
     794                        itc_pte_copy(&t);
    778795                else
    779                         dtc_pte_copy(t);
     796                        dtc_pte_copy(&t);
    780797        } else {
    781798                as_page_fault(va, PF_ACCESS_READ, istate);
  • kernel/arch/mips32/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    137137
    138138/* Last-level info macros. */
    139 #define PTE_VALID_ARCH(pte)                     (*((uint32_t *) (pte)) != 0)
    140 #define PTE_PRESENT_ARCH(pte)                   ((pte)->p != 0)
    141 #define PTE_GET_FRAME_ARCH(pte)                 ((pte)->pfn << 12)
    142 #define PTE_WRITABLE_ARCH(pte)                  ((pte)->w != 0)
    143 #define PTE_EXECUTABLE_ARCH(pte)                1
     139#define PTE_VALID_ARCH(pte)             ((pte)->soft_valid != 0)
     140#define PTE_PRESENT_ARCH(pte)           ((pte)->p != 0)
     141#define PTE_GET_FRAME_ARCH(pte)         ((pte)->pfn << 12)
     142#define PTE_WRITABLE_ARCH(pte)          ((pte)->w != 0)
     143#define PTE_EXECUTABLE_ARCH(pte)        1
    144144
    145145#ifndef __ASM__
  • kernel/arch/mips32/src/mm/tlb.c

    rf126c87 r2a2fbc8  
    9797        entry_lo_t lo;
    9898        uintptr_t badvaddr;
    99         pte_t *pte;
     99        pte_t pte;
    100100       
    101101        badvaddr = cp0_badvaddr_read();
    102102
    103         pte = page_mapping_find(AS, badvaddr, true);
    104         if (pte && pte->p) {
     103        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     104        if (found && pte.p) {
    105105                /*
    106106                 * Record access to PTE.
    107107                 */
    108                 pte->a = 1;
    109 
    110                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
    111                     pte->cacheable, pte->pfn);
     108                pte.a = 1;
     109
     110                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.d,
     111                    pte.cacheable, pte.pfn);
     112
     113                page_mapping_update(AS, badvaddr, true, &pte);
    112114
    113115                /*
     
    138140        tlb_index_t index;
    139141        uintptr_t badvaddr;
    140         pte_t *pte;
     142        pte_t pte;
    141143
    142144        /*
     
    162164        badvaddr = cp0_badvaddr_read();
    163165
    164         pte = page_mapping_find(AS, badvaddr, true);
    165         if (pte && pte->p) {
     166        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     167        if (found && pte.p) {
    166168                /*
    167169                 * Read the faulting TLB entry.
     
    172174                 * Record access to PTE.
    173175                 */
    174                 pte->a = 1;
    175 
    176                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
    177                     pte->cacheable, pte->pfn);
     176                pte.a = 1;
     177
     178                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.d,
     179                    pte.cacheable, pte.pfn);
     180
     181                page_mapping_update(AS, badvaddr, true, &pte);
    178182
    179183                /*
     
    200204        tlb_index_t index;
    201205        uintptr_t badvaddr;
    202         pte_t *pte;
     206        pte_t pte;
    203207
    204208        badvaddr = cp0_badvaddr_read();
     
    224228        }
    225229
    226         pte = page_mapping_find(AS, badvaddr, true);
    227         if (pte && pte->p && pte->w) {
     230        bool found = page_mapping_find(AS, badvaddr, true, &pte);
     231        if (found && pte.p && pte.w) {
    228232                /*
    229233                 * Read the faulting TLB entry.
     
    234238                 * Record access and write to PTE.
    235239                 */
    236                 pte->a = 1;
    237                 pte->d = 1;
    238 
    239                 tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w,
    240                     pte->cacheable, pte->pfn);
     240                pte.a = 1;
     241                pte.d = 1;
     242
     243                tlb_prepare_entry_lo(&lo, pte.g, pte.p, pte.w,
     244                    pte.cacheable, pte.pfn);
     245
     246                page_mapping_update(AS, badvaddr, true, &pte);
    241247
    242248                /*
  • kernel/arch/ppc32/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    140140
    141141/* Macros for querying the last-level PTEs. */
    142 #define PTE_VALID_ARCH(pte)       (*((uint32_t *) (pte)) != 0)
     142#define PTE_VALID_ARCH(pte)       ((pte)->valid != 0)
    143143#define PTE_PRESENT_ARCH(pte)     ((pte)->present != 0)
    144144#define PTE_GET_FRAME_ARCH(pte)   ((pte)->pfn << 12)
  • kernel/arch/ppc32/src/mm/pht.c

    rf126c87 r2a2fbc8  
    4949 * @param access   Access mode that caused the fault.
    5050 * @param istate   Pointer to interrupted state.
    51  *
    52  * @return PTE on success, NULL otherwise.
    53  *
    54  */
    55 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    56     istate_t *istate)
     51 * @param[out] pte Structure that will receive a copy of the found PTE.
     52 *
     53 * @return True if the mapping was found, false otherwise.
     54 *
     55 */
     56static bool find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
     57    istate_t *istate, pte_t *pte)
    5758{
    5859        /*
    5960         * Check if the mapping exists in page tables.
    6061         */
    61         pte_t *pte = page_mapping_find(as, badvaddr, true);
    62         if ((pte) && (pte->present)) {
     62        bool found = page_mapping_find(as, badvaddr, true, pte);
     63        if (found && pte->present) {
    6364                /*
    6465                 * Mapping found in page tables.
    6566                 * Immediately succeed.
    6667                 */
    67                 return pte;
     68                return true;
    6869        }
    6970        /*
     
    7677                 * The mapping ought to be in place.
    7778                 */
    78                 pte = page_mapping_find(as, badvaddr, true);
    79                 ASSERT((pte) && (pte->present));
    80                 return pte;
    81         }
    82 
    83         return NULL;
     79                found = page_mapping_find(as, badvaddr, true, pte);
     80
     81                ASSERT(found);
     82                ASSERT(pte->present);
     83
     84                return found;
     85        }
     86
     87        return false;
    8488}
    8589
     
    182186                badvaddr = istate->pc;
    183187       
    184         pte_t *pte = find_mapping_and_check(AS, badvaddr,
    185             PF_ACCESS_READ /* FIXME */, istate);
    186        
    187         if (pte) {
     188        pte_t pte;
     189        bool found = find_mapping_and_check(AS, badvaddr,
     190            PF_ACCESS_READ /* FIXME */, istate, &pte);
     191       
     192        if (found) {
    188193                /* Record access to PTE */
    189                 pte->accessed = 1;
    190                 pht_insert(badvaddr, pte);
     194                pte.accessed = 1;
     195                pht_insert(badvaddr, &pte);
    191196        }
    192197}
  • kernel/arch/sparc32/include/arch/mm/page.h

    rf126c87 r2a2fbc8  
    129129/* Macros for querying the last level entries. */
    130130#define PTE_VALID_ARCH(p) \
    131         (*((uint32_t *) (p)) != 0)
     131        ((p)->et != PTE_ET_INVALID)
    132132#define PTE_PRESENT_ARCH(p) \
    133133        ((p)->et != 0)
  • kernel/arch/sparc64/src/mm/sun4u/tlb.c

    rf126c87 r2a2fbc8  
    197197{
    198198        size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
    199         pte_t *t;
    200 
    201         t = page_mapping_find(AS, istate->tpc, true);
    202         if (t && PTE_EXECUTABLE(t)) {
     199        pte_t t;
     200
     201        bool found = page_mapping_find(AS, istate->tpc, true, &t);
     202        if (found && PTE_EXECUTABLE(&t)) {
    203203                /*
    204204                 * The mapping was found in the software page hash table.
    205205                 * Insert it into ITLB.
    206206                 */
    207                 t->a = true;
    208                 itlb_pte_copy(t, index);
     207                t.a = true;
     208                itlb_pte_copy(&t, index);
    209209#ifdef CONFIG_TSB
    210                 itsb_pte_copy(t, index);
    211 #endif
     210                itsb_pte_copy(&t, index);
     211#endif
     212                page_mapping_update(AS, istate->tpc, true, &t);
    212213        } else {
    213214                /*
     
    233234        uintptr_t page_16k;
    234235        size_t index;
    235         pte_t *t;
     236        pte_t t;
    236237        as_t *as = AS;
    237238
     
    253254        }
    254255
    255         t = page_mapping_find(as, page_16k, true);
    256         if (t) {
     256        bool found = page_mapping_find(as, page_16k, true, &t);
     257        if (found) {
    257258                /*
    258259                 * The mapping was found in the software page hash table.
    259260                 * Insert it into DTLB.
    260261                 */
    261                 t->a = true;
    262                 dtlb_pte_copy(t, index, true);
     262                t.a = true;
     263                dtlb_pte_copy(&t, index, true);
    263264#ifdef CONFIG_TSB
    264                 dtsb_pte_copy(t, index, true);
    265 #endif
     265                dtsb_pte_copy(&t, index, true);
     266#endif
     267                page_mapping_update(as, page_16k, true, &t);
    266268        } else {
    267269                /*
     
    283285        uintptr_t page_16k;
    284286        size_t index;
    285         pte_t *t;
     287        pte_t t;
    286288        as_t *as = AS;
    287289
     
    293295                as = AS_KERNEL;
    294296
    295         t = page_mapping_find(as, page_16k, true);
    296         if (t && PTE_WRITABLE(t)) {
     297        bool found = page_mapping_find(as, page_16k, true, &t);
     298        if (found && PTE_WRITABLE(&t)) {
    297299                /*
    298300                 * The mapping was found in the software page hash table and is
     
    300302                 * into DTLB.
    301303                 */
    302                 t->a = true;
    303                 t->d = true;
     304                t.a = true;
     305                t.d = true;
    304306                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
    305307                    page_16k + index * MMU_PAGE_SIZE);
    306                 dtlb_pte_copy(t, index, false);
     308                dtlb_pte_copy(&t, index, false);
    307309#ifdef CONFIG_TSB
    308                 dtsb_pte_copy(t, index, false);
    309 #endif
     310                dtsb_pte_copy(&t, index, false);
     311#endif
     312                page_mapping_update(as, page_16k, true, &t);
    310313        } else {
    311314                /*
  • kernel/arch/sparc64/src/mm/sun4v/tlb.c

    rf126c87 r2a2fbc8  
    211211{
    212212        uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
    213         pte_t *t;
    214 
    215         t = page_mapping_find(AS, va, true);
    216 
    217         if (t && PTE_EXECUTABLE(t)) {
     213        pte_t t;
     214
     215        bool found = page_mapping_find(AS, va, true, &t);
     216        if (found && PTE_EXECUTABLE(&t)) {
    218217                /*
    219218                 * The mapping was found in the software page hash table.
    220219                 * Insert it into ITLB.
    221220                 */
    222                 t->a = true;
    223                 itlb_pte_copy(t);
     221                t.a = true;
     222                itlb_pte_copy(&t);
    224223#ifdef CONFIG_TSB
    225                 itsb_pte_copy(t);
    226 #endif
     224                itsb_pte_copy(&t);
     225#endif
     226                page_mapping_update(AS, va, true, &t);
    227227        } else {
    228228                /*
     
    244244void fast_data_access_mmu_miss(unsigned int tt, istate_t *istate)
    245245{
    246         pte_t *t;
     246        pte_t t;
    247247        uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
    248248        uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
     
    261261        }
    262262
    263         t = page_mapping_find(as, va, true);
    264         if (t) {
     263        bool found = page_mapping_find(as, va, true, &t);
     264        if (found) {
    265265                /*
    266266                 * The mapping was found in the software page hash table.
    267267                 * Insert it into DTLB.
    268268                 */
    269                 t->a = true;
    270                 dtlb_pte_copy(t, true);
     269                t.a = true;
     270                dtlb_pte_copy(&t, true);
    271271#ifdef CONFIG_TSB
    272                 dtsb_pte_copy(t, true);
    273 #endif
     272                dtsb_pte_copy(&t, true);
     273#endif
     274                page_mapping_update(as, va, true, &t);
    274275        } else {
    275276                /*
     
    288289void fast_data_access_protection(unsigned int tt, istate_t *istate)
    289290{
    290         pte_t *t;
     291        pte_t t;
    291292        uintptr_t va = DMISS_ADDRESS(istate->tlb_tag_access);
    292293        uint16_t ctx = DMISS_CONTEXT(istate->tlb_tag_access);
     
    296297                as = AS_KERNEL;
    297298
    298         t = page_mapping_find(as, va, true);
    299         if (t && PTE_WRITABLE(t)) {
     299        bool found = page_mapping_find(as, va, true, &t);
     300        if (found && PTE_WRITABLE(&t)) {
    300301                /*
    301302                 * The mapping was found in the software page hash table and is
     
    303304                 * into DTLB.
    304305                 */
    305                 t->a = true;
    306                 t->d = true;
     306                t.a = true;
     307                t.d = true;
    307308                mmu_demap_page(va, ctx, MMU_FLAG_DTLB);
    308                 dtlb_pte_copy(t, false);
     309                dtlb_pte_copy(&t, false);
    309310#ifdef CONFIG_TSB
    310                 dtsb_pte_copy(t, false);
    311 #endif
     311                dtsb_pte_copy(&t, false);
     312#endif
     313                page_mapping_update(as, va, true, &t);
    312314        } else {
    313315                /*
  • kernel/genarch/include/genarch/mm/page_ht.h

    rf126c87 r2a2fbc8  
    4444#include <mm/page.h>
    4545#include <mm/slab.h>
    46 #include <synch/mutex.h>
    4746#include <adt/hash_table.h>
    4847
     
    5554
    5655/* Macros for querying page hash table PTEs. */
    57 #define PTE_VALID(pte)       ((pte) != NULL)
     56#define PTE_VALID(pte)       ((void *) (pte) != NULL)
    5857#define PTE_PRESENT(pte)     ((pte)->p != 0)
    5958#define PTE_GET_FRAME(pte)   ((pte)->frame)
     
    6665
    6766extern slab_cache_t *pte_cache;
    68 extern mutex_t page_ht_lock;
    6967extern hash_table_t page_ht;
    7068extern hash_table_operations_t ht_operations;
  • kernel/genarch/src/mm/as_ht.c

    rf126c87 r2a2fbc8  
    7777        if (flags & FLAG_AS_KERNEL) {
    7878                hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations);
    79                 mutex_initialize(&page_ht_lock, MUTEX_PASSIVE);
    8079                pte_cache = slab_cache_create("pte_t", sizeof(pte_t), 0,
    8180                    NULL, NULL, SLAB_CACHE_MAGDEFERRED);
     
    9998/** Lock page table.
    10099 *
    101  * Lock address space and page hash table.
     100 * Lock address space.
    102101 * Interrupts must be disabled.
    103102 *
     
    110109        if (lock)
    111110                mutex_lock(&as->lock);
    112        
    113         mutex_lock(&page_ht_lock);
    114111}
    115112
    116113/** Unlock page table.
    117114 *
    118  * Unlock address space and page hash table.
     115 * Unlock address space.
    119116 * Interrupts must be disabled.
    120117 *
     
    125122void ht_unlock(as_t *as, bool unlock)
    126123{
    127         mutex_unlock(&page_ht_lock);
    128        
    129124        if (unlock)
    130125                mutex_unlock(&as->lock);
     
    140135bool ht_locked(as_t *as)
    141136{
    142         return (mutex_locked(&page_ht_lock) && mutex_locked(&as->lock));
     137        return mutex_locked(&as->lock);
    143138}
    144139
  • kernel/genarch/src/mm/page_ht.c

    rf126c87 r2a2fbc8  
    5959static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    6060static void ht_mapping_remove(as_t *, uintptr_t);
    61 static pte_t *ht_mapping_find(as_t *, uintptr_t, bool);
     61static 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
     
    7071 *
    7172 */
    72 mutex_t page_ht_lock;
     73IRQ_SPINLOCK_STATIC_INITIALIZE(page_ht_lock);
    7374
    7475/** Page hash table.
     
    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};
     
    191193
    192194        ASSERT(page_table_locked(as));
     195
     196        irq_spinlock_lock(&page_ht_lock, true);
    193197       
    194198        if (!hash_table_find(&page_ht, key)) {
     
    217221                hash_table_insert(&page_ht, key, &pte->link);
    218222        }
     223
     224        irq_spinlock_unlock(&page_ht_lock, true);
    219225}
    220226
     
    238244        ASSERT(page_table_locked(as));
    239245       
     246        irq_spinlock_lock(&page_ht_lock, true);
     247
    240248        /*
    241249         * Note that removed PTE's will be freed
     
    243251         */
    244252        hash_table_remove(&page_ht, key, 2);
    245 }
    246 
    247 
    248 /** Find mapping for virtual page in page hash table.
    249  *
    250  * @param as     Address space to which page belongs.
    251  * @param page   Virtual page.
    252  * @param nolock True if the page tables need not be locked.
    253  *
    254  * @return NULL if there is no such mapping; requested mapping otherwise.
    255  *
    256  */
    257 pte_t *ht_mapping_find(as_t *as, uintptr_t page, bool nolock)
     253
     254        irq_spinlock_unlock(&page_ht_lock, true);
     255}
     256
     257static pte_t *ht_mapping_find_internal(as_t *as, uintptr_t page, bool nolock)
    258258{
    259259        sysarg_t key[2] = {
     
    263263
    264264        ASSERT(nolock || page_table_locked(as));
    265        
     265
    266266        link_t *cur = hash_table_find(&page_ht, key);
    267267        if (cur)
     
    271271}
    272272
     273/** Find mapping for virtual page in page hash table.
     274 *
     275 * @param as       Address space to which page belongs.
     276 * @param page     Virtual page.
     277 * @param nolock   True if the page tables need not be locked.
     278 * @param[out] pte Structure that will receive a copy of the found PTE.
     279 *
     280 * @return True if the mapping was found, false otherwise.
     281 */
     282bool ht_mapping_find(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
     283{
     284        irq_spinlock_lock(&page_ht_lock, true);
     285
     286        pte_t *t = ht_mapping_find_internal(as, page, nolock);
     287        if (t)
     288                *pte = *t;
     289
     290        irq_spinlock_unlock(&page_ht_lock, true);
     291       
     292        return t != NULL;
     293}
     294
     295/** Update mapping for virtual page in page hash table.
     296 *
     297 * @param as       Address space to which page belongs.
     298 * @param page     Virtual page.
     299 * @param nolock   True if the page tables need not be locked.
     300 * @param pte      New PTE.
     301 */
     302void ht_mapping_update(as_t *as, uintptr_t page, bool nolock, pte_t *pte)
     303{
     304        irq_spinlock_lock(&page_ht_lock, true);
     305
     306        pte_t *t = ht_mapping_find_internal(as, page, nolock);
     307        if (!t)
     308                panic("Updating non-existent PTE");
     309       
     310        ASSERT(pte->as == t->as);
     311        ASSERT(pte->page == t->page);
     312        ASSERT(pte->frame == t->frame);
     313        ASSERT(pte->g == t->g);
     314        ASSERT(pte->x == t->x);
     315        ASSERT(pte->w == t->w);
     316        ASSERT(pte->k == t->k);
     317        ASSERT(pte->c == t->c);
     318        ASSERT(pte->p == t->p);
     319
     320        t->a = pte->a;
     321        t->d = pte->d;
     322
     323        irq_spinlock_unlock(&page_ht_lock, true);
     324}
     325
    273326void ht_mapping_make_global(uintptr_t base, size_t size)
    274327{
  • kernel/genarch/src/mm/page_pt.c

    rf126c87 r2a2fbc8  
    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};
     
    289291}
    290292
    291 /** Find mapping for virtual page in hierarchical page tables.
    292  *
    293  * @param as     Address space to which page belongs.
    294  * @param page   Virtual page.
    295  * @param nolock True if the page tables need not be locked.
    296  *
    297  * @return NULL if there is no such mapping; entry from PTL3 describing
    298  *         the mapping otherwise.
    299  *
    300  */
    301 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)
    302294{
    303295        ASSERT(nolock || page_table_locked(as));
     
    334326       
    335327        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;
    336367}
    337368
  • kernel/generic/include/mm/page.h

    rf126c87 r2a2fbc8  
    4848        void (* mapping_insert)(as_t *, uintptr_t, uintptr_t, unsigned int);
    4949        void (* mapping_remove)(as_t *, uintptr_t);
    50         pte_t *(* mapping_find)(as_t *, uintptr_t, bool);
     50        bool (* mapping_find)(as_t *, uintptr_t, bool, pte_t *);
     51        void (* mapping_update)(as_t *, uintptr_t, bool, pte_t *);
    5152        void (* mapping_make_global)(uintptr_t, size_t);
    5253} page_mapping_operations_t;
     
    6061extern void page_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    6162extern void page_mapping_remove(as_t *, uintptr_t);
    62 extern pte_t *page_mapping_find(as_t *, uintptr_t, bool);
     63extern bool page_mapping_find(as_t *, uintptr_t, bool, pte_t *);
     64extern void page_mapping_update(as_t *, uintptr_t, bool, pte_t *);
    6365extern void page_mapping_make_global(uintptr_t, size_t);
    6466extern pte_t *page_table_create(unsigned int);
  • kernel/generic/src/ipc/ops/pagein.c

    rf126c87 r2a2fbc8  
    4747{
    4848        if (!IPC_GET_RETVAL(answer->data)) {
    49                 pte_t *pte;
     49                pte_t pte;
    5050                uintptr_t frame;
    5151
    5252                page_table_lock(AS, true);
    53                 pte = page_mapping_find(AS, IPC_GET_ARG1(answer->data), false);
    54                 if (pte) {
    55                         frame = PTE_GET_FRAME(pte);
     53                bool found = page_mapping_find(AS, IPC_GET_ARG1(answer->data),
     54                    false, &pte);
     55                if (found) {
     56                        frame = PTE_GET_FRAME(&pte);
    5657                        pfn_t pfn = ADDR2PFN(frame);
    5758                        if (find_zone(pfn, 1, 0) != (size_t) -1) {
  • kernel/generic/src/mm/as.c

    rf126c87 r2a2fbc8  
    889889               
    890890                                for (; i < node_size; i++) {
    891                                         pte_t *pte = page_mapping_find(as,
    892                                             ptr + P2SZ(i), false);
     891                                        pte_t pte;
     892                                        bool found = page_mapping_find(as,
     893                                            ptr + P2SZ(i), false, &pte);
    893894                                       
    894                                         ASSERT(pte);
    895                                         ASSERT(PTE_VALID(pte));
    896                                         ASSERT(PTE_PRESENT(pte));
     895                                        ASSERT(found);
     896                                        ASSERT(PTE_VALID(&pte));
     897                                        ASSERT(PTE_PRESENT(&pte));
    897898                                       
    898899                                        if ((area->backend) &&
     
    900901                                                area->backend->frame_free(area,
    901902                                                    ptr + P2SZ(i),
    902                                                     PTE_GET_FRAME(pte));
     903                                                    PTE_GET_FRAME(&pte));
    903904                                        }
    904905                                       
     
    10031004                       
    10041005                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1005                                 pte_t *pte = page_mapping_find(as,
    1006                                      ptr + P2SZ(size), false);
     1006                                pte_t pte;
     1007                                bool found = page_mapping_find(as,
     1008                                     ptr + P2SZ(size), false, &pte);
    10071009                               
    1008                                 ASSERT(pte);
    1009                                 ASSERT(PTE_VALID(pte));
    1010                                 ASSERT(PTE_PRESENT(pte));
     1010                                ASSERT(found);
     1011                                ASSERT(PTE_VALID(&pte));
     1012                                ASSERT(PTE_PRESENT(&pte));
    10111013                               
    10121014                                if ((area->backend) &&
     
    10141016                                        area->backend->frame_free(area,
    10151017                                            ptr + P2SZ(size),
    1016                                             PTE_GET_FRAME(pte));
     1018                                            PTE_GET_FRAME(&pte));
    10171019                                }
    10181020                               
     
    13151317                       
    13161318                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1317                                 pte_t *pte = page_mapping_find(as,
    1318                                     ptr + P2SZ(size), false);
     1319                                pte_t pte;
     1320                                bool found = page_mapping_find(as,
     1321                                    ptr + P2SZ(size), false, &pte);
    13191322                               
    1320                                 ASSERT(pte);
    1321                                 ASSERT(PTE_VALID(pte));
    1322                                 ASSERT(PTE_PRESENT(pte));
     1323                                ASSERT(found);
     1324                                ASSERT(PTE_VALID(&pte));
     1325                                ASSERT(PTE_PRESENT(&pte));
    13231326                               
    1324                                 old_frame[frame_idx++] = PTE_GET_FRAME(pte);
     1327                                old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
    13251328                               
    13261329                                /* Remove old mapping */
     
    14521455         * we need to make sure the mapping has not been already inserted.
    14531456         */
    1454         pte_t *pte;
    1455         if ((pte = page_mapping_find(AS, page, false))) {
    1456                 if (PTE_PRESENT(pte)) {
    1457                         if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
    1458                             (access == PF_ACCESS_WRITE && PTE_WRITABLE(pte)) ||
    1459                             (access == PF_ACCESS_EXEC && PTE_EXECUTABLE(pte))) {
     1457        pte_t pte;
     1458        bool found = page_mapping_find(AS, page, false, &pte);
     1459        if (found) {
     1460                if (PTE_PRESENT(&pte)) {
     1461                        if (((access == PF_ACCESS_READ) && PTE_READABLE(&pte)) ||
     1462                            (access == PF_ACCESS_WRITE && PTE_WRITABLE(&pte)) ||
     1463                            (access == PF_ACCESS_EXEC && PTE_EXECUTABLE(&pte))) {
    14601464                                page_table_unlock(AS, false);
    14611465                                mutex_unlock(&area->lock);
  • kernel/generic/src/mm/backend_anon.c

    rf126c87 r2a2fbc8  
    131131                       
    132132                        for (j = 0; j < count; j++) {
    133                                 pte_t *pte;
     133                                pte_t pte;
     134                                bool found;
    134135                       
    135136                                page_table_lock(area->as, false);
    136                                 pte = page_mapping_find(area->as,
    137                                     base + P2SZ(j), false);
    138                                 ASSERT(pte && PTE_VALID(pte) &&
    139                                     PTE_PRESENT(pte));
     137                                found = page_mapping_find(area->as,
     138                                    base + P2SZ(j), false, &pte);
     139
     140                                ASSERT(found);
     141                                ASSERT(PTE_VALID(&pte));
     142                                ASSERT(PTE_PRESENT(&pte));
     143
    140144                                btree_insert(&area->sh_info->pagemap,
    141145                                    (base + P2SZ(j)) - area->base,
    142                                     (void *) PTE_GET_FRAME(pte), NULL);
     146                                    (void *) PTE_GET_FRAME(&pte), NULL);
    143147                                page_table_unlock(area->as, false);
    144148
    145                                 pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
     149                                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
    146150                                frame_reference_add(pfn);
    147151                        }
  • kernel/generic/src/mm/backend_elf.c

    rf126c87 r2a2fbc8  
    184184                       
    185185                        for (j = 0; j < count; j++) {
    186                                 pte_t *pte;
     186                                pte_t pte;
     187                                bool found;
    187188                       
    188189                                /*
     
    196197                               
    197198                                page_table_lock(area->as, false);
    198                                 pte = page_mapping_find(area->as,
    199                                     base + P2SZ(j), false);
    200                                 ASSERT(pte && PTE_VALID(pte) &&
    201                                     PTE_PRESENT(pte));
     199                                found = page_mapping_find(area->as,
     200                                    base + P2SZ(j), false, &pte);
     201
     202                                ASSERT(found);
     203                                ASSERT(PTE_VALID(&pte));
     204                                ASSERT(PTE_PRESENT(&pte));
     205
    202206                                btree_insert(&area->sh_info->pagemap,
    203207                                    (base + P2SZ(j)) - area->base,
    204                                     (void *) PTE_GET_FRAME(pte), NULL);
     208                                    (void *) PTE_GET_FRAME(&pte), NULL);
    205209                                page_table_unlock(area->as, false);
    206210
    207                                 pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
     211                                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
    208212                                frame_reference_add(pfn);
    209213                        }
     
    335339                        dirty = true;
    336340                } else {
    337                         pte_t *pte = page_mapping_find(AS_KERNEL,
    338                             base + i * FRAME_SIZE, true);
    339 
    340                         ASSERT(pte);
    341                         ASSERT(PTE_PRESENT(pte));
    342 
    343                         frame = PTE_GET_FRAME(pte);
     341                        pte_t pte;
     342                        bool found;
     343
     344                        found = page_mapping_find(AS_KERNEL,
     345                            base + i * FRAME_SIZE, true, &pte);
     346
     347                        ASSERT(found);
     348                        ASSERT(PTE_PRESENT(&pte));
     349
     350                        frame = PTE_GET_FRAME(&pte);
    344351                }       
    345352        } else if (upage >= start_anon) {
  • kernel/generic/src/mm/page.c

    rf126c87 r2a2fbc8  
    137137/** Find mapping for virtual page.
    138138 *
    139  * @param as     Address space to which page belongs.
    140  * @param page   Virtual page.
    141  * @param nolock True if the page tables need not be locked.
    142  *
    143  * @return NULL if there is no such mapping; requested mapping
    144  *         otherwise.
    145  *
    146  */
    147 NO_TRACE pte_t *page_mapping_find(as_t *as, uintptr_t page, bool nolock)
     139 * @param as       Address space to which page belongs.
     140 * @param page     Virtual page.
     141 * @param nolock   True if the page tables need not be locked.
     142 * @param[out] pte Structure that will receive a copy of the found PTE.
     143 *
     144 * @return True if the mapping was found, false otherwise.
     145 */
     146NO_TRACE bool page_mapping_find(as_t *as, uintptr_t page, bool nolock,
     147    pte_t *pte)
    148148{
    149149        ASSERT(nolock || page_table_locked(as));
     
    153153       
    154154        return page_mapping_operations->mapping_find(as,
    155             ALIGN_DOWN(page, PAGE_SIZE), nolock);
     155            ALIGN_DOWN(page, PAGE_SIZE), nolock, pte);
     156}
     157
     158/** Update mapping for virtual page.
     159 *
     160 * Use only to update accessed and modified/dirty bits.
     161 *
     162 * @param as       Address space to which page belongs.
     163 * @param page     Virtual page.
     164 * @param nolock   True if the page tables need not be locked.
     165 * @param pte      New PTE.
     166 */
     167NO_TRACE void page_mapping_update(as_t *as, uintptr_t page, bool nolock,
     168    pte_t *pte)
     169{
     170        ASSERT(nolock || page_table_locked(as));
     171       
     172        ASSERT(page_mapping_operations);
     173        ASSERT(page_mapping_operations->mapping_find);
     174       
     175        page_mapping_operations->mapping_update(as,
     176            ALIGN_DOWN(page, PAGE_SIZE), nolock, pte);
    156177}
    157178
     
    173194        page_table_lock(AS, true);
    174195       
    175         pte_t *pte = page_mapping_find(AS, virt, false);
    176         if ((!PTE_VALID(pte)) || (!PTE_PRESENT(pte))) {
     196        pte_t pte;
     197        bool found = page_mapping_find(AS, virt, false, &pte);
     198        if (!found || !PTE_VALID(&pte) || !PTE_PRESENT(&pte)) {
    177199                page_table_unlock(AS, true);
    178200                return ENOENT;
    179201        }
    180202       
    181         *phys = PTE_GET_FRAME(pte) +
     203        *phys = PTE_GET_FRAME(&pte) +
    182204            (virt - ALIGN_DOWN(virt, PAGE_SIZE));
    183205       
  • kernel/generic/src/synch/futex.c

    rf126c87 r2a2fbc8  
    291291        spinlock_lock(&futex_ht_lock);
    292292
    293         bool found = false;
    294         pte_t *t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), true);
    295        
    296         if (t && PTE_VALID(t) && PTE_PRESENT(t)) {
    297                 found = true;
    298                 *paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
     293        bool success = false;
     294
     295        pte_t t;
     296        bool found;
     297
     298        found = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), true, &t);
     299        if (found && PTE_VALID(&t) && PTE_PRESENT(&t)) {
     300                success = true;
     301                *paddr = PTE_GET_FRAME(&t) +
     302                    (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
    299303        }
    300304       
     
    302306        page_table_unlock(AS, false);
    303307       
    304         return found;
     308        return success;
    305309}
    306310
Note: See TracChangeset for help on using the changeset viewer.