Changeset 2c2d54a in mainline for kernel


Ignore:
Timestamp:
2016-09-02T17:58:05Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4c3602c4
Parents:
4bf0926e (diff), 3233adb (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/pager

Location:
kernel
Files:
2 added
30 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r4bf0926e r2c2d54a  
    237237        generic/src/mm/backend_elf.c \
    238238        generic/src/mm/backend_phys.c \
     239        generic/src/mm/backend_user.c \
    239240        generic/src/mm/slab.c \
    240241        generic/src/lib/func.c \
     
    278279        generic/src/ipc/ops/datawrite.c \
    279280        generic/src/ipc/ops/debug.c \
     281        generic/src/ipc/ops/pagein.c \
    280282        generic/src/ipc/ops/sharein.c \
    281283        generic/src/ipc/ops/shareout.c \
  • kernel/arch/abs32le/include/arch/mm/page.h

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    151151/* Macros for querying the last-level PTE entries. */
    152152#define PTE_VALID_ARCH(p) \
    153         (*((uint64_t *) (p)) != 0)
     153        ((p)->soft_valid != 0)
    154154#define PTE_PRESENT_ARCH(p) \
    155155        ((p)->present != 0)
  • kernel/arch/arm32/include/arch/mm/page_armv4.h

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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/ipc/ipc.h

    r4bf0926e r2c2d54a  
    147147        struct task *sender;
    148148       
     149        /*
     150         * Answerbox that will receive the answer.
     151         * This will most of the times be the sender's answerbox,
     152         * but we allow for useful exceptions.
     153         */
     154        answerbox_t *callerbox;
     155
    149156        /** Phone which was used to send the call. */
    150157        phone_t *caller_phone;
     
    172179extern void ipc_call_release(call_t *);
    173180
     181extern int ipc_call_sync(phone_t *, call_t *);
    174182extern int ipc_call(phone_t *, call_t *);
    175183extern call_t *ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
  • kernel/generic/include/ipc/sysipc.h

    r4bf0926e r2c2d54a  
    4040#include <typedefs.h>
    4141
     42extern int ipc_req_internal(int, ipc_data_t *);
     43
    4244extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t,
    4345    sysarg_t, sysarg_t, sysarg_t);
  • kernel/generic/include/mm/as.h

    r4bf0926e r2c2d54a  
    169169/** Backend data stored in address space area. */
    170170typedef union mem_backend_data {
     171        /* anon_backend members */
     172        struct {
     173        };
     174
    171175        /** elf_backend members */
    172176        struct {
     
    181185                bool anonymous;
    182186        };
     187
     188        /** user_backend members */
     189        struct {
     190                as_area_pager_info_t pager_info;
     191        };
     192
    183193} mem_backend_data_t;
    184194
     
    296306extern mem_backend_t elf_backend;
    297307extern mem_backend_t phys_backend;
     308extern mem_backend_t user_backend;
    298309
    299310/* Address space area related syscalls. */
    300 extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t);
     311extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t,
     312    as_area_pager_info_t *);
    301313extern sysarg_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
    302314extern sysarg_t sys_as_area_change_flags(uintptr_t, unsigned int);
  • kernel/generic/include/mm/page.h

    r4bf0926e r2c2d54a  
    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/ipc.c

    r4bf0926e r2c2d54a  
    7777        call->forget = false;
    7878        call->sender = NULL;
     79        call->callerbox = &TASK->answerbox;
    7980        call->buffer = NULL;
    8081}
     
    185186        phone->state = IPC_PHONE_FREE;
    186187        atomic_set(&phone->active_calls, 0);
     188}
     189
     190/** Helper function to facilitate synchronous calls.
     191 *
     192 * @param phone   Destination kernel phone structure.
     193 * @param request Call structure with request.
     194 *
     195 * @return EOK on success or a negative error code.
     196 *
     197 */
     198int ipc_call_sync(phone_t *phone, call_t *request)
     199{
     200        answerbox_t *mybox = slab_alloc(ipc_answerbox_slab, 0);
     201        ipc_answerbox_init(mybox, TASK);
     202       
     203        /* We will receive data in a special box. */
     204        request->callerbox = mybox;
     205       
     206        int rc = ipc_call(phone, request);
     207        if (rc != EOK) {
     208                slab_free(ipc_answerbox_slab, mybox);
     209                return rc;
     210        }
     211        // TODO: forget the call if interrupted
     212        (void) ipc_wait_for_call(mybox, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
     213       
     214        slab_free(ipc_answerbox_slab, mybox);
     215        return EOK;
    187216}
    188217
     
    220249        spinlock_unlock(&call->forget_lock);
    221250
    222         answerbox_t *callerbox = &call->sender->answerbox;
     251        answerbox_t *callerbox = call->callerbox;
    223252        bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox));
    224253       
     
    755784        ipc_cleanup_call_list(&TASK->answerbox,
    756785            &TASK->answerbox.dispatched_calls);
    757 
     786       
    758787        ipc_forget_all_active_calls();
    759788        ipc_wait_for_all_answered_calls();
  • kernel/generic/src/ipc/sysipc.c

    r4bf0926e r2c2d54a  
    106106{
    107107        switch (imethod) {
     108        case IPC_M_PAGE_IN:
    108109        case IPC_M_SHARE_OUT:
    109110        case IPC_M_SHARE_IN:
     
    137138        case IPC_M_CONNECT_TO_ME:
    138139        case IPC_M_CONNECT_ME_TO:
     140        case IPC_M_PAGE_IN:
    139141        case IPC_M_SHARE_OUT:
    140142        case IPC_M_SHARE_IN:
     
    257259{
    258260        return SYSIPC_OP(request_process, call, box);
     261}
     262
     263/** Make a call over IPC and wait for reply.
     264 *
     265 * @param phoneid     Phone handle for the call.
     266 * @param data[inout] Structure with request/reply data.
     267 *
     268 * @return EOK on success.
     269 * @return ENOENT if there is no such phone handle.
     270 *
     271 */
     272int ipc_req_internal(int phoneid, ipc_data_t *data)
     273{
     274        phone_t *phone;
     275        if (phone_get(phoneid, &phone) != EOK)
     276                return ENOENT;
     277       
     278        call_t *call = ipc_call_alloc(0);
     279        memcpy(call->data.args, data->args, sizeof(data->args));
     280       
     281        int rc = request_preprocess(call, phone);
     282        if (!rc) {
     283#ifdef CONFIG_UDEBUG
     284                udebug_stoppable_begin();
     285#endif
     286
     287                rc = ipc_call_sync(phone, call);
     288
     289#ifdef CONFIG_UDEBUG
     290                udebug_stoppable_end();
     291#endif
     292
     293                if (rc != EOK)
     294                        return EINTR;
     295
     296                process_answer(call);
     297        } else
     298                IPC_SET_RETVAL(call->data, rc);
     299       
     300        memcpy(data->args, call->data.args, sizeof(data->args));
     301        ipc_call_free(call);
     302       
     303        return EOK;
    259304}
    260305
  • kernel/generic/src/ipc/sysipc_ops.c

    r4bf0926e r2c2d54a  
    4242sysipc_ops_t ipc_m_connect_to_me_ops;
    4343sysipc_ops_t ipc_m_connect_me_to_ops;
     44sysipc_ops_t ipc_m_page_in_ops;
    4445sysipc_ops_t ipc_m_share_out_ops;
    4546sysipc_ops_t ipc_m_share_in_ops;
     
    5455        [IPC_M_CONNECT_TO_ME] = &ipc_m_connect_to_me_ops,
    5556        [IPC_M_CONNECT_ME_TO] = &ipc_m_connect_me_to_ops,
     57        [IPC_M_PAGE_IN] = &ipc_m_page_in_ops,
    5658        [IPC_M_SHARE_OUT] = &ipc_m_share_out_ops,
    5759        [IPC_M_SHARE_IN] = &ipc_m_share_in_ops,
  • kernel/generic/src/mm/as.c

    r4bf0926e r2c2d54a  
    574574 * @param backend_data NULL or a pointer to custom backend data.
    575575 * @param base         Starting virtual address of the area.
    576  *                     If set to -1, a suitable mappable area is found.
    577  * @param bound        Lowest address bound if base is set to -1.
     576 *                     If set to AS_AREA_ANY, a suitable mappable area is
     577 *                     found.
     578 * @param bound        Lowest address bound if base is set to AS_AREA_ANY.
    578579 *                     Otherwise ignored.
    579580 *
     
    585586    mem_backend_data_t *backend_data, uintptr_t *base, uintptr_t bound)
    586587{
    587         if ((*base != (uintptr_t) -1) && !IS_ALIGNED(*base, PAGE_SIZE))
     588        if ((*base != (uintptr_t) AS_AREA_ANY) && !IS_ALIGNED(*base, PAGE_SIZE))
    588589                return NULL;
    589590       
     
    601602        mutex_lock(&as->lock);
    602603       
    603         if (*base == (uintptr_t) -1) {
     604        if (*base == (uintptr_t) AS_AREA_ANY) {
    604605                *base = as_get_unmapped_area(as, bound, size, guarded);
    605606                if (*base == (uintptr_t) -1) {
     
    888889               
    889890                                for (; i < node_size; i++) {
    890                                         pte_t *pte = page_mapping_find(as,
    891                                             ptr + P2SZ(i), false);
     891                                        pte_t pte;
     892                                        bool found = page_mapping_find(as,
     893                                            ptr + P2SZ(i), false, &pte);
    892894                                       
    893                                         ASSERT(pte);
    894                                         ASSERT(PTE_VALID(pte));
    895                                         ASSERT(PTE_PRESENT(pte));
     895                                        ASSERT(found);
     896                                        ASSERT(PTE_VALID(&pte));
     897                                        ASSERT(PTE_PRESENT(&pte));
    896898                                       
    897899                                        if ((area->backend) &&
     
    899901                                                area->backend->frame_free(area,
    900902                                                    ptr + P2SZ(i),
    901                                                     PTE_GET_FRAME(pte));
     903                                                    PTE_GET_FRAME(&pte));
    902904                                        }
    903905                                       
     
    10021004                       
    10031005                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1004                                 pte_t *pte = page_mapping_find(as,
    1005                                      ptr + P2SZ(size), false);
     1006                                pte_t pte;
     1007                                bool found = page_mapping_find(as,
     1008                                     ptr + P2SZ(size), false, &pte);
    10061009                               
    1007                                 ASSERT(pte);
    1008                                 ASSERT(PTE_VALID(pte));
    1009                                 ASSERT(PTE_PRESENT(pte));
     1010                                ASSERT(found);
     1011                                ASSERT(PTE_VALID(&pte));
     1012                                ASSERT(PTE_PRESENT(&pte));
    10101013                               
    10111014                                if ((area->backend) &&
     
    10131016                                        area->backend->frame_free(area,
    10141017                                            ptr + P2SZ(size),
    1015                                             PTE_GET_FRAME(pte));
     1018                                            PTE_GET_FRAME(&pte));
    10161019                                }
    10171020                               
     
    13141317                       
    13151318                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1316                                 pte_t *pte = page_mapping_find(as,
    1317                                     ptr + P2SZ(size), false);
     1319                                pte_t pte;
     1320                                bool found = page_mapping_find(as,
     1321                                    ptr + P2SZ(size), false, &pte);
    13181322                               
    1319                                 ASSERT(pte);
    1320                                 ASSERT(PTE_VALID(pte));
    1321                                 ASSERT(PTE_PRESENT(pte));
     1323                                ASSERT(found);
     1324                                ASSERT(PTE_VALID(&pte));
     1325                                ASSERT(PTE_PRESENT(&pte));
    13221326                               
    1323                                 old_frame[frame_idx++] = PTE_GET_FRAME(pte);
     1327                                old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
    13241328                               
    13251329                                /* Remove old mapping */
     
    14511455         * we need to make sure the mapping has not been already inserted.
    14521456         */
    1453         pte_t *pte;
    1454         if ((pte = page_mapping_find(AS, page, false))) {
    1455                 if (PTE_PRESENT(pte)) {
    1456                         if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
    1457                             (access == PF_ACCESS_WRITE && PTE_WRITABLE(pte)) ||
    1458                             (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))) {
    14591464                                page_table_unlock(AS, false);
    14601465                                mutex_unlock(&area->lock);
     
    21822187
    21832188sysarg_t sys_as_area_create(uintptr_t base, size_t size, unsigned int flags,
    2184     uintptr_t bound)
     2189    uintptr_t bound, as_area_pager_info_t *pager_info)
    21852190{
    21862191        uintptr_t virt = base;
     2192        mem_backend_t *backend;
     2193        mem_backend_data_t backend_data;
     2194
     2195        if (pager_info == AS_AREA_UNPAGED)
     2196                backend = &anon_backend;
     2197        else {
     2198                backend = &user_backend;
     2199                if (copy_from_uspace(&backend_data.pager_info, pager_info,
     2200                        sizeof(as_area_pager_info_t)) != EOK) {
     2201                        return (sysarg_t) AS_MAP_FAILED;
     2202                }
     2203        }
    21872204        as_area_t *area = as_area_create(AS, flags, size,
    2188             AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, bound);
     2205            AS_AREA_ATTR_NONE, backend, &backend_data, &virt, bound);
    21892206        if (area == NULL)
    2190                 return (sysarg_t) -1;
     2207                return (sysarg_t) AS_MAP_FAILED;
    21912208       
    21922209        return (sysarg_t) virt;
  • kernel/generic/src/mm/backend_anon.c

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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

    r4bf0926e r2c2d54a  
    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.