Changeset 8f88beb7 in mainline for kernel


Ignore:
Timestamp:
2012-11-25T21:34:07Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e1a27be
Parents:
150a2718 (diff), 7462674 (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 mainline changes

Location:
kernel
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/Makefile.inc

    r150a2718 r8f88beb7  
    3333
    3434FPU_NO_CFLAGS = -mno-sse -mno-sse2
    35 
    36 #
    37 # FIXME:
    38 #
    39 # The -fno-optimize-sibling-calls should be removed as soon as a bug
    40 # in GCC concerning the "large" memory model and tail call optimization
    41 # is fixed.
    42 #
    43 # When GCC generates a code for tail call, instead of generating ..
    44 #
    45 #   jmp *fnc
    46 #
    47 # it generates an assembly code with an illegal immediate prefix:
    48 #
    49 #   jmp *$fnc
    50 #
    51 # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48385 for reference.
    52 #
    53 
    54 CMN1 = -m64 -mcmodel=large -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer -fno-optimize-sibling-calls
     35CMN1 = -m64 -mcmodel=large -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
    5536GCC_CFLAGS += $(CMN1)
    5637ICC_CFLAGS += $(CMN1)
  • kernel/arch/amd64/src/mm/page.c

    r150a2718 r8f88beb7  
    9292                access = PF_ACCESS_READ;
    9393       
    94         if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
    95                 fault_if_from_uspace(istate, "Page fault: %p.", (void *) page);
    96                 panic_memtrap(istate, access, page, NULL);
    97         }
     94        as_page_fault(page, access, istate);
    9895}
    9996
  • kernel/arch/arm32/src/mm/page_fault.c

    r150a2718 r8f88beb7  
    289289#error "Unsupported architecture"
    290290#endif
    291         const int ret = as_page_fault(badvaddr, access, istate);
    292 
    293         if (ret == AS_PF_FAULT) {
    294                 fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
    295                 panic_memtrap(istate, access, badvaddr, NULL);
    296         }
     291        as_page_fault(badvaddr, access, istate);
    297292}
    298293
     
    305300void prefetch_abort(unsigned int exc_no, istate_t *istate)
    306301{
    307         /* NOTE: We should use IFAR and IFSR here. */
    308         int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    309 
    310         if (ret == AS_PF_FAULT) {
    311                 fault_if_from_uspace(istate,
    312                     "Page fault - prefetch_abort: %#x.", istate->pc);
    313                 panic_memtrap(istate, PF_ACCESS_EXEC, istate->pc, NULL);
    314         }
     302        as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
    315303}
    316304
  • kernel/arch/ia64/include/mm/as.h

    r150a2718 r8f88beb7  
    4343#define USER_ADDRESS_SPACE_END_ARCH      UINT64_C(0xdfffffffffffffff)
    4444
    45 #define USTACK_ADDRESS_ARCH  UINT64_C(0x0000000ff0000000)
    46 
    4745typedef struct {
    4846} as_arch_t;
  • kernel/arch/ia64/src/mm/tlb.c

    r150a2718 r8f88beb7  
    113113        va = page;
    114114       
    115         rr.word = rr_read(VA2VRN(va));
    116         if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
     115        rr.word = rr_read(VA2VRN(page));
     116        if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(page))))) {
    117117                /*
    118118                 * The selected region register does not contain required RID.
     
    122122               
    123123                rr0 = rr;
    124                 rr0.map.rid = ASID2RID(asid, VA2VRN(va));
    125                 rr_write(VA2VRN(va), rr0.word);
     124                rr0.map.rid = ASID2RID(asid, VA2VRN(page));
     125                rr_write(VA2VRN(page), rr0.word);
    126126                srlz_d();
    127127                srlz_i();
     
    139139        case 1: /* cnt 4 - 15 */
    140140                ps = PAGE_WIDTH + 2;
    141                 va &= ~((1 << ps) - 1);
     141                va &= ~((1UL << ps) - 1);
    142142                break;
    143143        case 2: /* cnt 16 - 63 */
    144144                ps = PAGE_WIDTH + 4;
    145                 va &= ~((1 << ps) - 1);
     145                va &= ~((1UL << ps) - 1);
    146146                break;
    147147        case 3: /* cnt 64 - 255 */
    148148                ps = PAGE_WIDTH + 6;
    149                 va &= ~((1 << ps) - 1);
     149                va &= ~((1UL << ps) - 1);
    150150                break;
    151151        case 4: /* cnt 256 - 1023 */
    152152                ps = PAGE_WIDTH + 8;
    153                 va &= ~((1 << ps) - 1);
     153                va &= ~((1UL << ps) - 1);
    154154                break;
    155155        case 5: /* cnt 1024 - 4095 */
    156156                ps = PAGE_WIDTH + 10;
    157                 va &= ~((1 << ps) - 1);
     157                va &= ~((1UL << ps) - 1);
    158158                break;
    159159        case 6: /* cnt 4096 - 16383 */
    160160                ps = PAGE_WIDTH + 12;
    161                 va &= ~((1 << ps) - 1);
     161                va &= ~((1UL << ps) - 1);
    162162                break;
    163163        case 7: /* cnt 16384 - 65535 */
    164164        case 8: /* cnt 65536 - (256K - 1) */
    165165                ps = PAGE_WIDTH + 14;
    166                 va &= ~((1 << ps) - 1);
     166                va &= ~((1UL << ps) - 1);
    167167                break;
    168168        default:
    169169                ps = PAGE_WIDTH + 18;
    170                 va &= ~((1 << ps) - 1);
    171                 break;
    172         }
    173        
    174         for (; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
     170                va &= ~((1UL << ps) - 1);
     171                break;
     172        }
     173       
     174        for (; va < (page + cnt * PAGE_SIZE); va += (1UL << ps))
    175175                asm volatile (
    176176                        "ptc.l %[va], %[ps] ;;"
     
    183183       
    184184        if (restore_rr) {
    185                 rr_write(VA2VRN(va), rr.word);
     185                rr_write(VA2VRN(page), rr.word);
    186186                srlz_d();
    187187                srlz_i();
     
    501501                 * Forward the page fault to address space page fault handler.
    502502                 */
    503                 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
    504                         fault_if_from_uspace(istate, "Page fault at %p.",
    505                             (void *) va);
    506                         panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
    507                 }
     503                as_page_fault(va, PF_ACCESS_EXEC, istate);
    508504        }
    509505}
     
    619615                 * handler.
    620616                 */
    621                 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
    622                         fault_if_from_uspace(istate, "Page fault at %p.",
    623                             (void *) va);
    624                         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
    625                 }
     617                as_page_fault(va, PF_ACCESS_READ, istate);
    626618        }
    627619}
     
    667659                dtc_pte_copy(t);
    668660        } else {
    669                 if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
    670                         fault_if_from_uspace(istate, "Page fault at %p.",
    671                             (void *) va);
    672                         panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
    673                 }
     661                as_page_fault(va, PF_ACCESS_WRITE, istate);
    674662        }
    675663}
     
    700688                itc_pte_copy(t);
    701689        } else {
    702                 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
    703                         fault_if_from_uspace(istate, "Page fault at %p.",
    704                             (void *) va);
    705                         panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
    706                 }
     690                as_page_fault(va, PF_ACCESS_EXEC, istate);
    707691        }
    708692}
     
    764748        ASSERT((t) && (t->p));
    765749        ASSERT(!t->w);
    766         if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
    767                 fault_if_from_uspace(istate, "Page fault at %p.",
    768                     (void *) va);
    769                 panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
    770         }
     750        as_page_fault(va, PF_ACCESS_WRITE, istate);
    771751}
    772752
     
    799779                        dtc_pte_copy(t);
    800780        } else {
    801                 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
    802                         fault_if_from_uspace(istate, "Page fault at %p.",
    803                             (void *) va);
    804                         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
    805                 }
     781                as_page_fault(va, PF_ACCESS_READ, istate);
    806782        }
    807783}
  • kernel/arch/mips32/src/mm/tlb.c

    r150a2718 r8f88beb7  
    4848#include <symtab.h>
    4949
    50 static void tlb_refill_fail(istate_t *);
    51 static void tlb_invalid_fail(istate_t *);
    52 static void tlb_modified_fail(istate_t *);
    53 
    54 static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *);
     50static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *);
    5551
    5652/** Initialize TLB.
     
    9288        uintptr_t badvaddr;
    9389        pte_t *pte;
    94         int pfrc;
    9590       
    9691        badvaddr = cp0_badvaddr_read();
    9792        asid = AS->asid;
    9893       
    99         pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
    100         if (!pte) {
    101                 switch (pfrc) {
    102                 case AS_PF_FAULT:
    103                         goto fail;
    104                         break;
    105                 case AS_PF_DEFER:
    106                         /*
    107                          * The page fault came during copy_from_uspace()
    108                          * or copy_to_uspace().
    109                          */
    110                         return;
    111                 default:
    112                         panic("Unexpected pfrc (%d).", pfrc);
     94        pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate);
     95        if (pte) {
     96                /*
     97                 * Record access to PTE.
     98                 */
     99                pte->a = 1;
     100
     101                tlb_prepare_entry_hi(&hi, asid, badvaddr);
     102                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
     103                    pte->cacheable, pte->pfn);
     104
     105                /*
     106                 * New entry is to be inserted into TLB
     107                 */
     108                cp0_entry_hi_write(hi.value);
     109                if ((badvaddr / PAGE_SIZE) % 2 == 0) {
     110                        cp0_entry_lo0_write(lo.value);
     111                        cp0_entry_lo1_write(0);
     112                } else {
     113                        cp0_entry_lo0_write(0);
     114                        cp0_entry_lo1_write(lo.value);
    113115                }
    114         }
    115 
    116         /*
    117          * Record access to PTE.
    118          */
    119         pte->a = 1;
    120 
    121         tlb_prepare_entry_hi(&hi, asid, badvaddr);
    122         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable,
    123             pte->pfn);
    124 
    125         /*
    126          * New entry is to be inserted into TLB
    127          */
    128         cp0_entry_hi_write(hi.value);
    129         if ((badvaddr / PAGE_SIZE) % 2 == 0) {
    130                 cp0_entry_lo0_write(lo.value);
    131                 cp0_entry_lo1_write(0);
    132         }
    133         else {
    134                 cp0_entry_lo0_write(0);
    135                 cp0_entry_lo1_write(lo.value);
    136         }
    137         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    138         tlbwr();
    139 
    140         return;
    141        
    142 fail:
    143         tlb_refill_fail(istate);
     116                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     117                tlbwr();
     118        }
    144119}
    145120
     
    155130        entry_hi_t hi;
    156131        pte_t *pte;
    157         int pfrc;
    158132
    159133        badvaddr = cp0_badvaddr_read();
     
    168142        index.value = cp0_index_read();
    169143
    170         /*
    171          * Fail if the entry is not in TLB.
    172          */
    173         if (index.p) {
    174                 printf("TLB entry not found.\n");
    175                 goto fail;
    176         }
    177 
    178         pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
    179         if (!pte) {
    180                 switch (pfrc) {
    181                 case AS_PF_FAULT:
    182                         goto fail;
    183                         break;
    184                 case AS_PF_DEFER:
    185                         /*
    186                          * The page fault came during copy_from_uspace()
    187                          * or copy_to_uspace().
    188                          */
    189                         return;
    190                 default:
    191                         panic("Unexpected pfrc (%d).", pfrc);
    192                 }
    193         }
    194 
    195         /*
    196          * Read the faulting TLB entry.
    197          */
    198         tlbr();
    199 
    200         /*
    201          * Record access to PTE.
    202          */
    203         pte->a = 1;
    204 
    205         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable,
    206             pte->pfn);
    207 
    208         /*
    209          * The entry is to be updated in TLB.
    210          */
    211         if ((badvaddr / PAGE_SIZE) % 2 == 0)
    212                 cp0_entry_lo0_write(lo.value);
    213         else
    214                 cp0_entry_lo1_write(lo.value);
    215         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    216         tlbwi();
    217 
    218         return;
    219        
    220 fail:
    221         tlb_invalid_fail(istate);
     144        ASSERT(!index.p);
     145
     146        pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate);
     147        if (pte) {
     148                /*
     149                 * Read the faulting TLB entry.
     150                 */
     151                tlbr();
     152
     153                /*
     154                 * Record access to PTE.
     155                 */
     156                pte->a = 1;
     157
     158                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d,
     159                    pte->cacheable, pte->pfn);
     160
     161                /*
     162                 * The entry is to be updated in TLB.
     163                 */
     164                if ((badvaddr / PAGE_SIZE) % 2 == 0)
     165                        cp0_entry_lo0_write(lo.value);
     166                else
     167                        cp0_entry_lo1_write(lo.value);
     168                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     169                tlbwi();
     170        }
    222171}
    223172
     
    233182        entry_hi_t hi;
    234183        pte_t *pte;
    235         int pfrc;
    236184
    237185        badvaddr = cp0_badvaddr_read();
     
    249197         * Fail if the entry is not in TLB.
    250198         */
    251         if (index.p) {
    252                 printf("TLB entry not found.\n");
    253                 goto fail;
    254         }
    255 
    256         pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate, &pfrc);
    257         if (!pte) {
    258                 switch (pfrc) {
    259                 case AS_PF_FAULT:
    260                         goto fail;
    261                         break;
    262                 case AS_PF_DEFER:
    263                         /*
    264                          * The page fault came during copy_from_uspace()
    265                          * or copy_to_uspace().
    266                          */
    267                         return;
    268                 default:
    269                         panic("Unexpected pfrc (%d).", pfrc);
    270                 }
    271         }
    272 
    273         /*
    274          * Read the faulting TLB entry.
    275          */
    276         tlbr();
    277 
    278         /*
    279          * Record access and write to PTE.
    280          */
    281         pte->a = 1;
    282         pte->d = 1;
    283 
    284         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable,
    285             pte->pfn);
    286 
    287         /*
    288          * The entry is to be updated in TLB.
    289          */
    290         if ((badvaddr / PAGE_SIZE) % 2 == 0)
    291                 cp0_entry_lo0_write(lo.value);
    292         else
    293                 cp0_entry_lo1_write(lo.value);
    294         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    295         tlbwi();
    296 
    297         return;
    298        
    299 fail:
    300         tlb_modified_fail(istate);
    301 }
    302 
    303 void tlb_refill_fail(istate_t *istate)
    304 {
    305         uintptr_t va = cp0_badvaddr_read();
    306        
    307         fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
    308             (void *) va);
    309         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Refill Exception.");
    310 }
    311 
    312 
    313 void tlb_invalid_fail(istate_t *istate)
    314 {
    315         uintptr_t va = cp0_badvaddr_read();
    316        
    317         fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
    318             (void *) va);
    319         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Invalid Exception.");
    320 }
    321 
    322 void tlb_modified_fail(istate_t *istate)
    323 {
    324         uintptr_t va = cp0_badvaddr_read();
    325        
    326         fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
    327             (void *) va);
    328         panic_memtrap(istate, PF_ACCESS_WRITE, va, "TLB Modified Exception.");
     199        ASSERT(!index.p);
     200
     201        pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate);
     202        if (pte) {
     203                /*
     204                 * Read the faulting TLB entry.
     205                 */
     206                tlbr();
     207
     208                /*
     209                 * Record access and write to PTE.
     210                 */
     211                pte->a = 1;
     212                pte->d = 1;
     213
     214                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w,
     215                    pte->cacheable, pte->pfn);
     216
     217                /*
     218                 * The entry is to be updated in TLB.
     219                 */
     220                if ((badvaddr / PAGE_SIZE) % 2 == 0)
     221                        cp0_entry_lo0_write(lo.value);
     222                else
     223                        cp0_entry_lo1_write(lo.value);
     224                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     225                tlbwi();
     226        }
    329227}
    330228
     
    334232 * @param access        Access mode that caused the fault.
    335233 * @param istate        Pointer to interrupted state.
    336  * @param pfrc          Pointer to variable where as_page_fault() return code
    337  *                      will be stored.
    338234 *
    339235 * @return              PTE on success, NULL otherwise.
    340236 */
    341 pte_t *
    342 find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate,
    343     int *pfrc)
     237pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate)
    344238{
    345239        entry_hi_t hi;
     
    348242        hi.value = cp0_entry_hi_read();
    349243
    350         /*
    351          * Handler cannot succeed if the ASIDs don't match.
    352          */
    353         if (hi.asid != AS->asid) {
    354                 printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
    355                 return NULL;
    356         }
     244        ASSERT(hi.asid == AS->asid);
    357245
    358246        /*
     
    366254                 */
    367255                return pte;
    368         } else {
    369                 int rc;
    370                
    371                 /*
    372                  * Mapping not found in page tables.
    373                  * Resort to higher-level page fault handler.
    374                  */
    375                 switch (rc = as_page_fault(badvaddr, access, istate)) {
    376                 case AS_PF_OK:
    377                         /*
    378                          * The higher-level page fault handler succeeded,
    379                          * The mapping ought to be in place.
    380                          */
    381                         pte = page_mapping_find(AS, badvaddr, true);
    382                         ASSERT(pte && pte->p);
    383                         ASSERT(pte->w || access != PF_ACCESS_WRITE);
    384                         return pte;
    385                 case AS_PF_DEFER:
    386                         *pfrc = AS_PF_DEFER;
    387                         return NULL;
    388                 case AS_PF_FAULT:
    389                         *pfrc = AS_PF_FAULT;
    390                         return NULL;
    391                 default:
    392                         panic("Unexpected rc (%d).", rc);
    393                 }
    394                
    395         }
     256        }
     257
     258        /*
     259         * Mapping not found in page tables.
     260         * Resort to higher-level page fault handler.
     261         */
     262        if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) {
     263                pte = page_mapping_find(AS, badvaddr, true);
     264                ASSERT(pte && pte->p);
     265                ASSERT(pte->w || access != PF_ACCESS_WRITE);
     266                return pte;
     267        }
     268
     269        return NULL;
    396270}
    397271
  • kernel/arch/mips64/src/mm/tlb.c

    r150a2718 r8f88beb7  
    7979 * @param access   Access mode that caused the fault.
    8080 * @param istate   Pointer to interrupted state.
    81  * @param pfrc     Pointer to variable where as_page_fault()
    82  *                 return code will be stored.
    8381 *
    8482 * @return PTE on success, NULL otherwise.
     
    8684 */
    8785static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access,
    88     istate_t *istate, int *pfrc)
     86    istate_t *istate)
    8987{
    9088        entry_hi_t hi;
    9189        hi.value = cp0_entry_hi_read();
    9290       
    93         /*
    94          * Handler cannot succeed if the ASIDs don't match.
    95          */
    96         if (hi.asid != AS->asid) {
    97                 printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
    98                 return NULL;
    99         }
     91        ASSERT(hi.asid == AS->asid);
    10092       
    10193        /*
     
    109101                 */
    110102                return pte;
    111         } else {
    112                 int rc;
    113                
    114                 /*
    115                  * Mapping not found in page tables.
    116                  * Resort to higher-level page fault handler.
    117                  */
    118                 switch (rc = as_page_fault(badvaddr, access, istate)) {
    119                 case AS_PF_OK:
    120                         /*
    121                          * The higher-level page fault handler succeeded,
    122                          * The mapping ought to be in place.
    123                          */
    124                         pte = page_mapping_find(AS, badvaddr, true);
    125                         ASSERT(pte);
    126                         ASSERT(pte->p);
    127                         ASSERT((pte->w) || (access != PF_ACCESS_WRITE));
    128                         return pte;
    129                 case AS_PF_DEFER:
    130                         *pfrc = AS_PF_DEFER;
    131                         return NULL;
    132                 case AS_PF_FAULT:
    133                         *pfrc = AS_PF_FAULT;
    134                         return NULL;
    135                 default:
    136                         panic("Unexpected return code (%d).", rc);
    137                 }
    138         }
     103        }
     104
     105        /*
     106         * Mapping not found in page tables.
     107         * Resort to higher-level page fault handler.
     108         */
     109        if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) {
     110                /*
     111                 * The higher-level page fault handler succeeded,
     112                 * The mapping ought to be in place.
     113                 */
     114                pte = page_mapping_find(AS, badvaddr, true);
     115                ASSERT(pte);
     116                ASSERT(pte->p);
     117                ASSERT((pte->w) || (access != PF_ACCESS_WRITE));
     118                return pte;
     119        }
     120
     121        return NULL;
    139122}
    140123
     
    156139}
    157140
    158 static void tlb_refill_fail(istate_t *istate)
    159 {
    160         uintptr_t va = cp0_badvaddr_read();
    161        
    162         fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
    163             (void *) va);
    164         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Refill Exception.");
    165 }
    166 
    167 static void tlb_invalid_fail(istate_t *istate)
    168 {
    169         uintptr_t va = cp0_badvaddr_read();
    170        
    171         fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
    172             (void *) va);
    173         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Invalid Exception.");
    174 }
    175 
    176 static void tlb_modified_fail(istate_t *istate)
    177 {
    178         uintptr_t va = cp0_badvaddr_read();
    179        
    180         fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
    181             (void *) va);
    182         panic_memtrap(istate, PF_ACCESS_WRITE, va, "TLB Modified Exception.");
    183 }
    184 
    185141/** Process TLB Refill Exception.
    186142 *
     
    196152        mutex_unlock(&AS->lock);
    197153       
    198         int pfrc;
    199         pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ,
    200             istate, &pfrc);
    201         if (!pte) {
    202                 switch (pfrc) {
    203                 case AS_PF_FAULT:
    204                         goto fail;
    205                         break;
    206                 case AS_PF_DEFER:
    207                         /*
    208                          * The page fault came during copy_from_uspace()
    209                          * or copy_to_uspace().
    210                          */
    211                         return;
    212                 default:
    213                         panic("Unexpected pfrc (%d).", pfrc);
     154        pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate);
     155        if (pte) {
     156                /*
     157                 * Record access to PTE.
     158                 */
     159                pte->a = 1;
     160       
     161                entry_lo_t lo;
     162                entry_hi_t hi;
     163       
     164                tlb_prepare_entry_hi(&hi, asid, badvaddr);
     165                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
     166                    pte->frame);
     167       
     168                /*
     169                 * New entry is to be inserted into TLB
     170                 */
     171                cp0_entry_hi_write(hi.value);
     172       
     173                if ((badvaddr / PAGE_SIZE) % 2 == 0) {
     174                        cp0_entry_lo0_write(lo.value);
     175                        cp0_entry_lo1_write(0);
     176                } else {
     177                        cp0_entry_lo0_write(0);
     178                        cp0_entry_lo1_write(lo.value);
    214179                }
    215         }
    216        
    217         /*
    218          * Record access to PTE.
    219          */
    220         pte->a = 1;
    221        
    222         entry_lo_t lo;
    223         entry_hi_t hi;
    224        
    225         tlb_prepare_entry_hi(&hi, asid, badvaddr);
    226         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
    227             pte->frame);
    228        
    229         /*
    230          * New entry is to be inserted into TLB
    231          */
    232         cp0_entry_hi_write(hi.value);
    233        
    234         if ((badvaddr / PAGE_SIZE) % 2 == 0) {
    235                 cp0_entry_lo0_write(lo.value);
    236                 cp0_entry_lo1_write(0);
    237         } else {
    238                 cp0_entry_lo0_write(0);
    239                 cp0_entry_lo1_write(lo.value);
    240         }
    241        
    242         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    243         tlbwr();
    244        
    245         return;
    246        
    247 fail:
    248         tlb_refill_fail(istate);
     180       
     181                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     182                tlbwr();
     183        }
    249184}
    250185
     
    271206        index.value = cp0_index_read();
    272207       
    273         /*
    274          * Fail if the entry is not in TLB.
    275          */
    276         if (index.p) {
    277                 printf("TLB entry not found.\n");
    278                 goto fail;
    279         }
    280        
    281         int pfrc;
    282         pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ,
    283             istate, &pfrc);
    284         if (!pte) {
    285                 switch (pfrc) {
    286                 case AS_PF_FAULT:
    287                         goto fail;
    288                         break;
    289                 case AS_PF_DEFER:
    290                         /*
    291                          * The page fault came during copy_from_uspace()
    292                          * or copy_to_uspace().
    293                          */
    294                         return;
    295                 default:
    296                         panic("Unexpected pfrc (%d).", pfrc);
    297                 }
    298         }
    299        
    300         /*
    301          * Read the faulting TLB entry.
    302          */
    303         tlbr();
    304        
    305         /*
    306          * Record access to PTE.
    307          */
    308         pte->a = 1;
    309        
    310         entry_lo_t lo;
    311         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
    312             pte->frame);
    313        
    314         /*
    315          * The entry is to be updated in TLB.
    316          */
    317         if ((badvaddr / PAGE_SIZE) % 2 == 0)
    318                 cp0_entry_lo0_write(lo.value);
    319         else
    320                 cp0_entry_lo1_write(lo.value);
    321        
    322         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    323         tlbwi();
    324        
    325         return;
    326        
    327 fail:
    328         tlb_invalid_fail(istate);
     208        ASSERT(!index.p);
     209       
     210        pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate);
     211        if (pte) {
     212                /*
     213                 * Read the faulting TLB entry.
     214                 */
     215                tlbr();
     216       
     217                /*
     218                 * Record access to PTE.
     219                 */
     220                pte->a = 1;
     221
     222                entry_lo_t lo;
     223                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
     224                    pte->frame);
     225       
     226                /*
     227                 * The entry is to be updated in TLB.
     228                 */
     229                if ((badvaddr / PAGE_SIZE) % 2 == 0)
     230                        cp0_entry_lo0_write(lo.value);
     231                else
     232                        cp0_entry_lo1_write(lo.value);
     233       
     234                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     235                tlbwi();
     236        }
     237       
    329238}
    330239
     
    351260        index.value = cp0_index_read();
    352261       
    353         /*
    354          * Fail if the entry is not in TLB.
    355          */
    356         if (index.p) {
    357                 printf("TLB entry not found.\n");
    358                 goto fail;
    359         }
    360        
    361         int pfrc;
    362         pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE,
    363             istate, &pfrc);
    364         if (!pte) {
    365                 switch (pfrc) {
    366                 case AS_PF_FAULT:
    367                         goto fail;
    368                         break;
    369                 case AS_PF_DEFER:
    370                         /*
    371                          * The page fault came during copy_from_uspace()
    372                          * or copy_to_uspace().
    373                          */
    374                         return;
    375                 default:
    376                         panic("Unexpected pfrc (%d).", pfrc);
    377                 }
    378         }
    379        
    380         /*
    381          * Read the faulting TLB entry.
    382          */
    383         tlbr();
    384        
    385         /*
    386          * Record access and write to PTE.
    387          */
    388         pte->a = 1;
    389         pte->d = 1;
    390        
    391         entry_lo_t lo;
    392         tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->c,
    393             pte->frame);
    394        
    395         /*
    396          * The entry is to be updated in TLB.
    397          */
    398         if ((badvaddr / PAGE_SIZE) % 2 == 0)
    399                 cp0_entry_lo0_write(lo.value);
    400         else
    401                 cp0_entry_lo1_write(lo.value);
    402        
    403         cp0_pagemask_write(TLB_PAGE_MASK_16K);
    404         tlbwi();
    405        
    406         return;
    407        
    408 fail:
    409         tlb_modified_fail(istate);
     262        ASSERT(!index.p);
     263       
     264        pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate);
     265        if (pte) {
     266                /*
     267                 * Read the faulting TLB entry.
     268                 */
     269                tlbr();
     270       
     271                /*
     272                 * Record access and write to PTE.
     273                 */
     274                pte->a = 1;
     275                pte->d = 1;
     276       
     277                entry_lo_t lo;
     278                tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->c,
     279                    pte->frame);
     280       
     281                /*
     282                 * The entry is to be updated in TLB.
     283                 */
     284                if ((badvaddr / PAGE_SIZE) % 2 == 0)
     285                        cp0_entry_lo0_write(lo.value);
     286                else
     287                        cp0_entry_lo1_write(lo.value);
     288       
     289                cp0_pagemask_write(TLB_PAGE_MASK_16K);
     290                tlbwi();
     291        }
    410292}
    411293
  • kernel/arch/ppc32/src/mm/pht.c

    r150a2718 r8f88beb7  
    4949 * @param access   Access mode that caused the fault.
    5050 * @param istate   Pointer to interrupted state.
    51  * @param pfrc     Pointer to variable where as_page_fault() return code
    52  *                 will be stored.
    5351 *
    5452 * @return PTE on success, NULL otherwise.
     
    5654 */
    5755static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    58     istate_t *istate, int *pfrc)
     56    istate_t *istate)
    5957{
    6058        /*
     
    6866                 */
    6967                return pte;
    70         } else {
     68        }
     69        /*
     70         * Mapping not found in page tables.
     71         * Resort to higher-level page fault handler.
     72         */
     73        if (as_page_fault(badvaddr, access, istate) == AS_PF_OK) {
    7174                /*
    72                  * Mapping not found in page tables.
    73                  * Resort to higher-level page fault handler.
     75                 * The higher-level page fault handler succeeded,
     76                 * The mapping ought to be in place.
    7477                 */
    75                 int rc = as_page_fault(badvaddr, access, istate);
    76                 switch (rc) {
    77                 case AS_PF_OK:
    78                         /*
    79                          * The higher-level page fault handler succeeded,
    80                          * The mapping ought to be in place.
    81                          */
    82                         pte = page_mapping_find(as, badvaddr, true);
    83                         ASSERT((pte) && (pte->present));
    84                         *pfrc = 0;
    85                         return pte;
    86                 case AS_PF_DEFER:
    87                         *pfrc = rc;
    88                         return NULL;
    89                 case AS_PF_FAULT:
    90                         *pfrc = rc;
    91                         return NULL;
    92                 default:
    93                         panic("Unexpected rc (%d).", rc);
    94                 }
    95         }
    96 }
    97 
    98 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
    99 {
    100         fault_if_from_uspace(istate, "PHT Refill Exception on %p.",
    101             (void *) badvaddr);
    102         panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
    103             "PHT Refill Exception.");
     78                pte = page_mapping_find(as, badvaddr, true);
     79                ASSERT((pte) && (pte->present));
     80                return pte;
     81        }
     82
     83        return NULL;
    10484}
    10585
     
    202182                badvaddr = istate->pc;
    203183       
    204         int pfrc;
    205184        pte_t *pte = find_mapping_and_check(AS, badvaddr,
    206             PF_ACCESS_READ /* FIXME */, istate, &pfrc);
    207        
    208         if (!pte) {
    209                 switch (pfrc) {
    210                 case AS_PF_FAULT:
    211                         pht_refill_fail(badvaddr, istate);
    212                         return;
    213                 case AS_PF_DEFER:
    214                         /*
    215                          * The page fault came during copy_from_uspace()
    216                          * or copy_to_uspace().
    217                          */
    218                         return;
    219                 default:
    220                         panic("Unexpected pfrc (%d).", pfrc);
    221                 }
    222         }
    223        
    224         /* Record access to PTE */
    225         pte->accessed = 1;
    226         pht_insert(badvaddr, pte);
     185            PF_ACCESS_READ /* FIXME */, istate);
     186       
     187        if (pte) {
     188                /* Record access to PTE */
     189                pte->accessed = 1;
     190                pht_insert(badvaddr, pte);
     191        }
    227192}
    228193
  • kernel/arch/ppc32/src/ppc32.c

    r150a2718 r8f88beb7  
    103103}
    104104
     105#ifdef CONFIG_FB
    105106static bool display_register(ofw_tree_node_t *node, void *arg)
    106107{
     
    169170        return true;
    170171}
     172#endif
    171173
    172174void arch_post_mm_init(void)
  • kernel/arch/sparc64/src/mm/sun4u/tlb.c

    r150a2718 r8f88beb7  
    5858static void dtlb_pte_copy(pte_t *, size_t, bool);
    5959static void itlb_pte_copy(pte_t *, size_t);
    60 static void do_fast_instruction_access_mmu_miss_fault(istate_t *, uintptr_t,
    61     const char *);
    62 static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
    63     const char *);
    64 static void do_fast_data_access_protection_fault(istate_t *,
    65     tlb_tag_access_reg_t, const char *);
    6660
    6761const char *context_encoding[] = {
     
    222216                 * handler.
    223217                 */
    224                 if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
    225                     AS_PF_FAULT) {
    226                         do_fast_instruction_access_mmu_miss_fault(istate,
    227                             istate->tpc, __func__);
    228                 }
     218                as_page_fault(page_16k, PF_ACCESS_EXEC, istate);
    229219        }
    230220}
     
    256246                if (!tag.vpn) {
    257247                        /* NULL access in kernel */
    258                         do_fast_data_access_mmu_miss_fault(istate, tag,
    259                             "Dereferencing NULL pointer.");
     248                        panic("NULL pointer dereference.");
    260249                } else if (page_8k >= end_of_identity) {
    261250                        /* Kernel non-identity. */
    262251                        as = AS_KERNEL;
    263252                } else {
    264                         do_fast_data_access_mmu_miss_fault(istate, tag,
    265                     "Unexpected kernel page fault.");
     253                        panic("Unexpected kernel page fault.");
    266254                }
    267255        }
     
    283271                 * handler.
    284272                 */
    285                 if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
    286                     AS_PF_FAULT) {
    287                         do_fast_data_access_mmu_miss_fault(istate, tag,
    288                             __func__);
    289                 }
     273                as_page_fault(page_16k, PF_ACCESS_READ, istate);
    290274        }
    291275}
     
    332316                 * handler.
    333317                 */             
    334                 if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
    335                     AS_PF_FAULT) {
    336                         do_fast_data_access_protection_fault(istate, tag,
    337                             __func__);
    338                 }
     318                as_page_fault(page_16k, PF_ACCESS_WRITE, istate);
    339319        }
    340320}
     
    428408
    429409#endif
    430 
    431 void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
    432     uintptr_t va, const char *str)
    433 {
    434         fault_if_from_uspace(istate, "%s, address=%p.", str, (void *) va);
    435         panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
    436 }
    437 
    438 void do_fast_data_access_mmu_miss_fault(istate_t *istate,
    439     tlb_tag_access_reg_t tag, const char *str)
    440 {
    441         uintptr_t va;
    442 
    443         va = tag.vpn << MMU_PAGE_WIDTH;
    444         fault_if_from_uspace(istate, "%s, page=%p (asid=%u).", str,
    445             (void *) va, tag.context);
    446         panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, str);
    447 }
    448 
    449 void do_fast_data_access_protection_fault(istate_t *istate,
    450     tlb_tag_access_reg_t tag, const char *str)
    451 {
    452         uintptr_t va;
    453 
    454         va = tag.vpn << MMU_PAGE_WIDTH;
    455         fault_if_from_uspace(istate, "%s, page=%p (asid=%u).", str,
    456             (void *) va, tag.context);
    457         panic_memtrap(istate, PF_ACCESS_WRITE, va, str);
    458 }
    459410
    460411void describe_dmmu_fault(void)
  • kernel/arch/sparc64/src/mm/sun4v/tlb.c

    r150a2718 r8f88beb7  
    6262static void itlb_pte_copy(pte_t *);
    6363static void dtlb_pte_copy(pte_t *, bool);
    64 static void do_fast_instruction_access_mmu_miss_fault(istate_t *, uintptr_t,
    65     const char *);
    66 static void do_fast_data_access_mmu_miss_fault(istate_t *, uint64_t,
    67     const char *);
    68 static void do_fast_data_access_protection_fault(istate_t *,
    69     uint64_t, const char *);
    7064
    7165/*
     
    235229                 * handler.
    236230                 */
    237                 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
    238                         do_fast_instruction_access_mmu_miss_fault(istate,
    239                             istate->tpc, __func__);
    240                 }
     231                as_page_fault(va, PF_ACCESS_EXEC, istate);
    241232        }
    242233}
     
    264255                if (va == 0) {
    265256                        /* NULL access in kernel */
    266                         do_fast_data_access_mmu_miss_fault(istate, page_and_ctx,
    267                             __func__);
     257                        panic("NULL pointer dereference.");
    268258                }
    269                 do_fast_data_access_mmu_miss_fault(istate, page_and_ctx, "Unexpected "
    270                     "kernel page fault.");
     259                panic("Unexpected kernel page fault.");
    271260        }
    272261
     
    287276                 * handler.
    288277                 */             
    289                 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
    290                         do_fast_data_access_mmu_miss_fault(istate, page_and_ctx,
    291                             __func__);
    292                 }
     278                as_page_fault(va, PF_ACCESS_READ, istate);
    293279        }
    294280}
     
    329315                 * handler.
    330316                 */             
    331                 if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
    332                         do_fast_data_access_protection_fault(istate, page_and_ctx,
    333                             __func__);
    334                 }
     317                as_page_fault(va, PF_ACCESS_WRITE, istate);
    335318        }
    336319}
     
    346329}
    347330
    348 void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, uintptr_t va,
    349     const char *str)
    350 {
    351         fault_if_from_uspace(istate, "%s, address=%p.", str,
    352             (void *) va);
    353         panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
    354 }
    355 
    356 void do_fast_data_access_mmu_miss_fault(istate_t *istate,
    357     uint64_t page_and_ctx, const char *str)
    358 {
    359         fault_if_from_uspace(istate, "%s, page=%p (asid=%" PRId64 ").", str,
    360             (void *) DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
    361         panic_memtrap(istate, PF_ACCESS_UNKNOWN, DMISS_ADDRESS(page_and_ctx),
    362             str);
    363 }
    364 
    365 void do_fast_data_access_protection_fault(istate_t *istate,
    366     uint64_t page_and_ctx, const char *str)
    367 {
    368         fault_if_from_uspace(istate, "%s, page=%p (asid=%" PRId64 ").", str,
    369             (void *) DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
    370         panic_memtrap(istate, PF_ACCESS_WRITE, DMISS_ADDRESS(page_and_ctx),
    371             str);
    372 }
    373 
    374331/**
    375332 * Describes the exact condition which caused the last DMMU fault.
  • kernel/genarch/src/mm/page_ht.c

    r150a2718 r8f88beb7  
    209209                pte->frame = ALIGN_DOWN(frame, FRAME_SIZE);
    210210
     211                /*
     212                 * Make sure that a concurrent ht_mapping_find() will see the
     213                 * new entry only after it is fully initialized.
     214                 */
    211215                write_barrier();
    212216               
  • kernel/genarch/src/mm/page_pt.c

    r150a2718 r8f88beb7  
    8989                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    9090                    PAGE_WRITE);
     91                /*
     92                 * Make sure that a concurrent hardware page table walk or
     93                 * pt_mapping_find() will see the new PTL1 only after it is
     94                 * fully initialized.
     95                 */
    9196                write_barrier();
    9297                SET_PTL1_PRESENT(ptl0, PTL0_INDEX(page));
     
    103108                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    104109                    PAGE_WRITE);
     110                /*
     111                 * Make the new PTL2 visible only after it is fully initialized.
     112                 */
    105113                write_barrier();
    106114                SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));       
     
    117125                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    118126                    PAGE_WRITE);
     127                /*
     128                 * Make the new PTL3 visible only after it is fully initialized.
     129                 */
    119130                write_barrier();
    120131                SET_PTL3_PRESENT(ptl2, PTL2_INDEX(page));
     
    125136        SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
    126137        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags | PAGE_NOT_PRESENT);
     138        /*
     139         * Make the new mapping visible only after it is fully initialized.
     140         */
    127141        write_barrier();
    128142        SET_FRAME_PRESENT(ptl3, PTL3_INDEX(page));
     
    296310
    297311#if (PTL1_ENTRIES != 0)
     312        /*
     313         * Always read ptl2 only after we are sure it is present.
     314         */
    298315        read_barrier();
    299316#endif
     
    304321
    305322#if (PTL2_ENTRIES != 0)
     323        /*
     324         * Always read ptl3 only after we are sure it is present.
     325         */
    306326        read_barrier();
    307327#endif
  • kernel/generic/include/config.h

    r150a2718 r8f88beb7  
    4444#define STACK_FRAMES  TWO_FRAMES
    4545#define STACK_SIZE    ((1 << STACK_FRAMES) << PAGE_WIDTH)
     46
     47#define STACK_SIZE_USER (1 * 1024 * 1024)
    4648
    4749#define CONFIG_INIT_TASKS        32
  • kernel/generic/include/macros.h

    r150a2718 r8f88beb7  
    5252    uint64_t sz2)
    5353{
    54         uint64_t e1 = s1 + sz1;
    55         uint64_t e2 = s2 + sz2;
    56        
    57         return ((s1 < e2) && (s2 < e1));
     54        uint64_t e1 = s1 + sz1 - 1;
     55        uint64_t e2 = s2 + sz2 - 1;
     56
     57        /* both sizes are non-zero */
     58        if (sz1 && sz2)
     59                return ((s1 <= e2) && (s2 <= e1));
     60
     61        /* one size is non-zero */
     62        if (sz2)
     63                return ((s1 >= s2) && (s1 <= e2));
     64        if (sz1)
     65                return ((s2 >= s1) && (s2 <= e1));
     66
     67        /* both are zero */
     68        return (s1 == s2);
    5869}
    5970
     
    119130            | ((((uint64_t) (up)) & UINT32_C(0xffffffff)) << 32))
    120131
     132/* Test for sum overflow. */
     133#define overflows(a, b) \
     134        ((a) + (b) < (a))
     135
     136/* Test for sum overflow into positive numbers. */
     137#define overflows_into_positive(a, b)   \
     138        (overflows((a), (b)) && ((a) + (b) > 0))
     139
    121140/** Pseudorandom generator
    122141 *
  • kernel/generic/include/mm/as.h

    r150a2718 r8f88beb7  
    6161#define USER_ADDRESS_SPACE_END      USER_ADDRESS_SPACE_END_ARCH
    6262
    63 #ifdef USTACK_ADDRESS_ARCH
    64         #define USTACK_ADDRESS  USTACK_ADDRESS_ARCH
    65 #else
    66         #define USTACK_ADDRESS  (USER_ADDRESS_SPACE_END - (STACK_SIZE - 1))
    67 #endif
    68 
    6963/** Kernel address space. */
    7064#define FLAG_AS_KERNEL  (1 << 0)
     
    7468#define AS_AREA_ATTR_PARTIAL  1  /**< Not fully initialized area. */
    7569
     70/** The page fault was resolved by as_page_fault(). */
     71#define AS_PF_OK     0
     72
     73/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
     74#define AS_PF_DEFER  1
     75
    7676/** The page fault was not resolved by as_page_fault(). */
    77 #define AS_PF_FAULT  0
    78 
    79 /** The page fault was resolved by as_page_fault(). */
    80 #define AS_PF_OK  1
    81 
    82 /** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
    83 #define AS_PF_DEFER  2
     77#define AS_PF_FAULT  2
     78
     79/** The page fault was not resolved by as_page_fault(). Non-verbose version. */
     80#define AS_PF_SILENT 3
    8481
    8582/** Address space structure.
     
    224221        void (* destroy)(as_area_t *);
    225222
     223        bool (* is_resizable)(as_area_t *);
     224        bool (* is_shareable)(as_area_t *);
     225
    226226        int (* page_fault)(as_area_t *, uintptr_t, pf_access_t);
    227227        void (* frame_free)(as_area_t *, uintptr_t, uintptr_t);
  • kernel/generic/src/console/cmd.c

    r150a2718 r8f88beb7  
    5656#include <cpu.h>
    5757#include <mm/tlb.h>
     58#include <mm/km.h>
    5859#include <arch/mm/tlb.h>
    5960#include <mm/frame.h>
     
    8182        .func = cmd_help,
    8283        .argc = 0
     84};
     85
     86/* Data and methods for pio_read_8 command */
     87static int cmd_pio_read_8(cmd_arg_t *argv);
     88static cmd_arg_t pio_read_8_argv[] = { { .type = ARG_TYPE_INT } };
     89static cmd_info_t pio_read_8_info = {
     90        .name = "pio_read_8",
     91        .description = "pio_read_8 <address> Read 1 byte from memory (or port).",
     92        .func = cmd_pio_read_8,
     93        .argc = 1,
     94        .argv = pio_read_8_argv
     95};
     96
     97/* Data and methods for pio_read_16 command */
     98static int cmd_pio_read_16(cmd_arg_t *argv);
     99static cmd_arg_t pio_read_16_argv[] = { { .type = ARG_TYPE_INT } };
     100static cmd_info_t pio_read_16_info = {
     101        .name = "pio_read_16",
     102        .description = "pio_read_16 <address> Read 2 bytes from memory (or port).",
     103        .func = cmd_pio_read_16,
     104        .argc = 1,
     105        .argv = pio_read_16_argv
     106};
     107
     108/* Data and methods for pio_read_32 command */
     109static int cmd_pio_read_32(cmd_arg_t *argv);
     110static cmd_arg_t pio_read_32_argv[] = { { .type = ARG_TYPE_INT } };
     111static cmd_info_t pio_read_32_info = {
     112        .name = "pio_read_32",
     113        .description = "pio_read_32 <address> Read 4 bytes from memory (or port).",
     114        .func = cmd_pio_read_32,
     115        .argc = 1,
     116        .argv = pio_read_32_argv
     117};
     118
     119/* Data and methods for pio_write_8 command */
     120static int cmd_pio_write_8(cmd_arg_t *argv);
     121static cmd_arg_t pio_write_8_argv[] = {
     122        { .type = ARG_TYPE_INT },
     123        { .type = ARG_TYPE_INT }
     124};
     125static cmd_info_t pio_write_8_info = {
     126        .name = "pio_write_8",
     127        .description = "pio_write_8 <address> <value> Write 1 byte to memory (or port).",
     128        .func = cmd_pio_write_8,
     129        .argc = 2,
     130        .argv = pio_write_8_argv
     131};
     132
     133/* Data and methods for pio_write_16 command */
     134static int cmd_pio_write_16(cmd_arg_t *argv);
     135static cmd_arg_t pio_write_16_argv[] = {
     136        { .type = ARG_TYPE_INT },
     137        { .type = ARG_TYPE_INT }
     138};
     139static cmd_info_t pio_write_16_info = {
     140        .name = "pio_write_16",
     141        .description = "pio_write_16 <address> <value> Write 2 bytes to memory (or port).",
     142        .func = cmd_pio_write_16,
     143        .argc = 2,
     144        .argv = pio_write_16_argv
     145};
     146
     147/* Data and methods for pio_write_32 command */
     148static int cmd_pio_write_32(cmd_arg_t *argv);
     149static cmd_arg_t pio_write_32_argv[] = {
     150        { .type = ARG_TYPE_INT },
     151        { .type = ARG_TYPE_INT }
     152};
     153static cmd_info_t pio_write_32_info = {
     154        .name = "pio_write_32",
     155        .description = "pio_write_32 <address> <value> Write 4 bytes to memory (or port).",
     156        .func = cmd_pio_write_32,
     157        .argc = 2,
     158        .argv = pio_write_32_argv
    83159};
    84160
     
    531607        &btrace_info,
    532608#endif
     609        &pio_read_8_info,
     610        &pio_read_16_info,
     611        &pio_read_32_info,
     612        &pio_write_8_info,
     613        &pio_write_16_info,
     614        &pio_write_32_info,
    533615        NULL
    534616};
     
    601683        spinlock_unlock(&cmd_lock);
    602684       
     685        return 1;
     686}
     687
     688/** Read 1 byte from phys memory or io port.
     689 *
     690 * @param argv Argument vector.
     691 *
     692 * @return 0 on failure, 1 on success.
     693 */
     694static int cmd_pio_read_8(cmd_arg_t *argv)
     695{
     696        uint8_t *ptr = NULL;
     697       
     698#ifdef IO_SPACE_BOUNDARY
     699        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     700                ptr = (void *) argv[0].intval;
     701        else
     702#endif
     703                ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t),
     704                    PAGE_NOT_CACHEABLE);
     705       
     706        const uint8_t val = pio_read_8(ptr);
     707        printf("read %" PRIxn ": %" PRIx8 "\n", argv[0].intval, val);
     708       
     709#ifdef IO_SPACE_BOUNDARY
     710        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     711                return 1;
     712#endif
     713       
     714        km_unmap((uintptr_t) ptr, sizeof(uint8_t));
     715        return 1;
     716}
     717
     718/** Read 2 bytes from phys memory or io port.
     719 *
     720 * @param argv Argument vector.
     721 *
     722 * @return 0 on failure, 1 on success.
     723 */
     724static int cmd_pio_read_16(cmd_arg_t *argv)
     725{
     726        uint16_t *ptr = NULL;
     727       
     728#ifdef IO_SPACE_BOUNDARY
     729        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     730                ptr = (void *) argv[0].intval;
     731        else
     732#endif
     733                ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t),
     734                    PAGE_NOT_CACHEABLE);
     735       
     736        const uint16_t val = pio_read_16(ptr);
     737        printf("read %" PRIxn ": %" PRIx16 "\n", argv[0].intval, val);
     738       
     739#ifdef IO_SPACE_BOUNDARY
     740        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     741                return 1;
     742#endif
     743       
     744        km_unmap((uintptr_t) ptr, sizeof(uint16_t));
     745        return 1;
     746}
     747
     748/** Read 4 bytes from phys memory or io port.
     749 *
     750 * @param argv Argument vector.
     751 *
     752 * @return 0 on failure, 1 on success.
     753 */
     754static int cmd_pio_read_32(cmd_arg_t *argv)
     755{
     756        uint32_t *ptr = NULL;
     757       
     758#ifdef IO_SPACE_BOUNDARY
     759        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     760                ptr = (void *) argv[0].intval;
     761        else
     762#endif
     763                ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t),
     764                    PAGE_NOT_CACHEABLE);
     765       
     766        const uint32_t val = pio_read_32(ptr);
     767        printf("read %" PRIxn ": %" PRIx32 "\n", argv[0].intval, val);
     768       
     769#ifdef IO_SPACE_BOUNDARY
     770        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     771                return 1;
     772#endif
     773       
     774        km_unmap((uintptr_t) ptr, sizeof(uint32_t));
     775        return 1;
     776}
     777
     778/** Write 1 byte to phys memory or io port.
     779 *
     780 * @param argv Argument vector.
     781 *
     782 * @return 0 on failure, 1 on success.
     783 */
     784static int cmd_pio_write_8(cmd_arg_t *argv)
     785{
     786        uint8_t *ptr = NULL;
     787       
     788#ifdef IO_SPACE_BOUNDARY
     789        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     790                ptr = (void *) argv[0].intval;
     791        else
     792#endif
     793                ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t),
     794                    PAGE_NOT_CACHEABLE);
     795       
     796        printf("write %" PRIxn ": %" PRIx8 "\n", argv[0].intval,
     797            (uint8_t) argv[1].intval);
     798        pio_write_8(ptr, (uint8_t) argv[1].intval);
     799       
     800#ifdef IO_SPACE_BOUNDARY
     801        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     802                return 1;
     803#endif
     804       
     805        km_unmap((uintptr_t) ptr, sizeof(uint8_t));
     806        return 1;
     807}
     808
     809/** Write 2 bytes to phys memory or io port.
     810 *
     811 * @param argv Argument vector.
     812 *
     813 * @return 0 on failure, 1 on success.
     814 */
     815static int cmd_pio_write_16(cmd_arg_t *argv)
     816{
     817        uint16_t *ptr = NULL;
     818       
     819#ifdef IO_SPACE_BOUNDARY
     820        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     821                ptr = (void *) argv[0].intval;
     822        else
     823#endif
     824                ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t),
     825                    PAGE_NOT_CACHEABLE);
     826       
     827        printf("write %" PRIxn ": %" PRIx16 "\n", argv[0].intval,
     828            (uint16_t) argv[1].intval);
     829        pio_write_16(ptr, (uint16_t) argv[1].intval);
     830       
     831#ifdef IO_SPACE_BOUNDARY
     832        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     833                return 1;
     834#endif
     835       
     836        km_unmap((uintptr_t) ptr, sizeof(uint16_t));
     837        return 1;
     838}
     839
     840/** Write 4 bytes to phys memory or io port.
     841 *
     842 * @param argv Argument vector.
     843 *
     844 * @return 0 on failure, 1 on success.
     845 */
     846static int cmd_pio_write_32(cmd_arg_t *argv)
     847{
     848        uint32_t *ptr = NULL;
     849       
     850#ifdef IO_SPACE_BOUNDARY
     851        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     852                ptr = (void *) argv[0].intval;
     853        else
     854#endif
     855                ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t),
     856                    PAGE_NOT_CACHEABLE);
     857       
     858        printf("write %" PRIxn ": %" PRIx32 "\n", argv[0].intval,
     859            (uint32_t) argv[1].intval);
     860        pio_write_32(ptr, (uint32_t) argv[1].intval);
     861       
     862#ifdef IO_SPACE_BOUNDARY
     863        if ((void *) argv->intval < IO_SPACE_BOUNDARY)
     864                return 1;
     865#endif
     866       
     867        km_unmap((uintptr_t) ptr, sizeof(uint32_t));
    603868        return 1;
    604869}
  • kernel/generic/src/console/kconsole.c

    r150a2718 r8f88beb7  
    524524                /* It's a number - convert it */
    525525                uint64_t value;
    526                 int rc = str_uint64_t(text, NULL, 0, true, &value);
     526                char *end;
     527                int rc = str_uint64_t(text, &end, 0, false, &value);
     528                if (end != text + len)
     529                        rc = EINVAL;
    527530                switch (rc) {
    528531                case EINVAL:
    529                         printf("Invalid number.\n");
     532                        printf("Invalid number '%s'.\n", text);
    530533                        return false;
    531534                case EOVERFLOW:
    532                         printf("Integer overflow.\n");
     535                        printf("Integer overflow in '%s'.\n", text);
    533536                        return false;
    534537                case EOK:
     
    538541                        break;
    539542                default:
    540                         printf("Unknown error.\n");
     543                        printf("Unknown error parsing '%s'.\n", text);
    541544                        return false;
    542545                }
  • kernel/generic/src/interrupt/interrupt.c

    r150a2718 r8f88beb7  
    166166}
    167167
    168 static NO_TRACE void fault_from_uspace_core(istate_t *istate, const char *fmt, va_list args)
     168static NO_TRACE
     169void fault_from_uspace_core(istate_t *istate, const char *fmt, va_list args)
    169170{
    170171        printf("Task %s (%" PRIu64 ") killed due to an exception at "
  • kernel/generic/src/main/kinit.c

    r150a2718 r8f88beb7  
    172172#endif /* CONFIG_KCONSOLE */
    173173       
     174        /*
     175         * Store the default stack size in sysinfo so that uspace can create
     176         * stack with this default size.
     177         */
     178        sysinfo_set_item_val("default.stack_size", NULL, STACK_SIZE_USER);
     179       
    174180        interrupts_enable();
    175181       
  • kernel/generic/src/mm/as.c

    r150a2718 r8f88beb7  
    7979#include <syscall/copy.h>
    8080#include <arch/interrupt.h>
     81#include <interrupt.h>
    8182
    8283/**
     
    285286/** Check area conflicts with other areas.
    286287 *
    287  * @param as    Address space.
    288  * @param addr  Starting virtual address of the area being tested.
    289  * @param count Number of pages in the area being tested.
    290  * @param avoid Do not touch this area.
     288 * @param as      Address space.
     289 * @param addr    Starting virtual address of the area being tested.
     290 * @param count   Number of pages in the area being tested.
     291 * @param guarded True if the area being tested is protected by guard pages.
     292 * @param avoid   Do not touch this area.
    291293 *
    292294 * @return True if there is no conflict, false otherwise.
     
    294296 */
    295297NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
    296     size_t count, as_area_t *avoid)
     298    size_t count, bool guarded, as_area_t *avoid)
    297299{
    298300        ASSERT((addr % PAGE_SIZE) == 0);
    299301        ASSERT(mutex_locked(&as->lock));
     302
     303        /*
     304         * If the addition of the supposed area address and size overflows,
     305         * report conflict.
     306         */
     307        if (overflows_into_positive(addr, P2SZ(count)))
     308                return false;
    300309       
    301310        /*
     
    304313        if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))
    305314                return false;
    306        
     315
    307316        /*
    308317         * The leaf node is found in O(log n), where n is proportional to
     
    328337                if (area != avoid) {
    329338                        mutex_lock(&area->lock);
    330                        
     339
     340                        /*
     341                         * If at least one of the two areas are protected
     342                         * by the AS_AREA_GUARD flag then we must be sure
     343                         * that they are separated by at least one unmapped
     344                         * page.
     345                         */
     346                        int const gp = (guarded ||
     347                            (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     348                       
     349                        /*
     350                         * The area comes from the left neighbour node, which
     351                         * means that there already are some areas in the leaf
     352                         * node, which in turn means that adding gp is safe and
     353                         * will not cause an integer overflow.
     354                         */
    331355                        if (overlaps(addr, P2SZ(count), area->base,
     356                            P2SZ(area->pages + gp))) {
     357                                mutex_unlock(&area->lock);
     358                                return false;
     359                        }
     360                       
     361                        mutex_unlock(&area->lock);
     362                }
     363        }
     364       
     365        node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
     366        if (node) {
     367                area = (as_area_t *) node->value[0];
     368               
     369                if (area != avoid) {
     370                        int gp;
     371
     372                        mutex_lock(&area->lock);
     373
     374                        gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     375                        if (gp && overflows(addr, P2SZ(count))) {
     376                                /*
     377                                 * Guard page not needed if the supposed area
     378                                 * is adjacent to the end of the address space.
     379                                 * We already know that the following test is
     380                                 * going to fail...
     381                                 */
     382                                gp--;
     383                        }
     384                       
     385                        if (overlaps(addr, P2SZ(count + gp), area->base,
    332386                            P2SZ(area->pages))) {
    333387                                mutex_unlock(&area->lock);
     
    339393        }
    340394       
    341         node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
    342         if (node) {
    343                 area = (as_area_t *) node->value[0];
    344                
    345                 if (area != avoid) {
    346                         mutex_lock(&area->lock);
    347                        
    348                         if (overlaps(addr, P2SZ(count), area->base,
    349                             P2SZ(area->pages))) {
    350                                 mutex_unlock(&area->lock);
    351                                 return false;
    352                         }
    353                        
    354                         mutex_unlock(&area->lock);
    355                 }
    356         }
    357        
    358395        /* Second, check the leaf node. */
    359396        btree_key_t i;
    360397        for (i = 0; i < leaf->keys; i++) {
    361398                area = (as_area_t *) leaf->value[i];
     399                int agp;
     400                int gp;
    362401               
    363402                if (area == avoid)
     
    365404               
    366405                mutex_lock(&area->lock);
    367                
    368                 if (overlaps(addr, P2SZ(count), area->base,
    369                     P2SZ(area->pages))) {
     406
     407                gp = (guarded || (area->flags & AS_AREA_GUARD)) ? 1 : 0;
     408                agp = gp;
     409
     410                /*
     411                 * Sanitize the two possible unsigned integer overflows.
     412                 */
     413                if (gp && overflows(addr, P2SZ(count)))
     414                        gp--;
     415                if (agp && overflows(area->base, P2SZ(area->pages)))
     416                        agp--;
     417
     418                if (overlaps(addr, P2SZ(count + gp), area->base,
     419                    P2SZ(area->pages + agp))) {
    370420                        mutex_unlock(&area->lock);
    371421                        return false;
     
    377427        /*
    378428         * So far, the area does not conflict with other areas.
    379          * Check if it doesn't conflict with kernel address space.
     429         * Check if it is contained in the user address space.
    380430         */
    381431        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    382                 return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
    383                     KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
     432                return iswithin(USER_ADDRESS_SPACE_START,
     433                    (USER_ADDRESS_SPACE_END - USER_ADDRESS_SPACE_START) + 1,
     434                    addr, P2SZ(count));
    384435        }
    385436       
     
    392443 * this function.
    393444 *
    394  * @param as    Address space.
    395  * @param bound Lowest address bound.
    396  * @param size  Requested size of the allocation.
     445 * @param as      Address space.
     446 * @param bound   Lowest address bound.
     447 * @param size    Requested size of the allocation.
     448 * @param guarded True if the allocation must be protected by guard pages.
    397449 *
    398450 * @return Address of the beginning of unmapped address space area.
     
    401453 */
    402454NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
    403     size_t size)
     455    size_t size, bool guarded)
    404456{
    405457        ASSERT(mutex_locked(&as->lock));
     
    423475        /* First check the bound address itself */
    424476        uintptr_t addr = ALIGN_UP(bound, PAGE_SIZE);
    425         if ((addr >= bound) &&
    426             (check_area_conflicts(as, addr, pages, NULL)))
    427                 return addr;
     477        if (addr >= bound) {
     478                if (guarded) {
     479                        /* Leave an unmapped page between the lower
     480                         * bound and the area's start address.
     481                         */
     482                        addr += P2SZ(1);
     483                }
     484
     485                if (check_area_conflicts(as, addr, pages, guarded, NULL))
     486                        return addr;
     487        }
    428488       
    429489        /* Eventually check the addresses behind each area */
     
    439499                        addr =
    440500                            ALIGN_UP(area->base + P2SZ(area->pages), PAGE_SIZE);
     501
     502                        if (guarded || area->flags & AS_AREA_GUARD) {
     503                                /* We must leave an unmapped page
     504                                 * between the two areas.
     505                                 */
     506                                addr += P2SZ(1);
     507                        }
     508
    441509                        bool avail =
    442510                            ((addr >= bound) && (addr >= area->base) &&
    443                             (check_area_conflicts(as, addr, pages, area)));
     511                            (check_area_conflicts(as, addr, pages, guarded, area)));
    444512                       
    445513                        mutex_unlock(&area->lock);
     
    481549        if (size == 0)
    482550                return NULL;
    483        
     551
    484552        size_t pages = SIZE2FRAMES(size);
    485553       
     
    487555        if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
    488556                return NULL;
     557
     558        bool const guarded = flags & AS_AREA_GUARD;
    489559       
    490560        mutex_lock(&as->lock);
    491561       
    492562        if (*base == (uintptr_t) -1) {
    493                 *base = as_get_unmapped_area(as, bound, size);
     563                *base = as_get_unmapped_area(as, bound, size, guarded);
    494564                if (*base == (uintptr_t) -1) {
    495565                        mutex_unlock(&as->lock);
     
    497567                }
    498568        }
    499        
    500         if (!check_area_conflicts(as, *base, pages, NULL)) {
     569
     570        if (overflows_into_positive(*base, size))
     571                return NULL;
     572
     573        if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
    501574                mutex_unlock(&as->lock);
    502575                return NULL;
     
    625698                return ENOENT;
    626699        }
    627        
    628         if (area->backend == &phys_backend) {
    629                 /*
    630                  * Remapping of address space areas associated
    631                  * with memory mapped devices is not supported.
     700
     701        if (!area->backend->is_resizable(area)) {
     702                /*
     703                 * The backend does not support resizing for this area.
    632704                 */
    633705                mutex_unlock(&area->lock);
     
    776848                /*
    777849                 * Growing the area.
     850                 */
     851
     852                if (overflows_into_positive(address, P2SZ(pages)))
     853                        return EINVAL;
     854
     855                /*
    778856                 * Check for overlaps with other address space areas.
    779857                 */
    780                 if (!check_area_conflicts(as, address, pages, area)) {
     858                bool const guarded = area->flags & AS_AREA_GUARD;
     859                if (!check_area_conflicts(as, address, pages, guarded, area)) {
    781860                        mutex_unlock(&area->lock);
    782861                        mutex_unlock(&as->lock);
     
    9791058        }
    9801059       
    981         if ((!src_area->backend) || (!src_area->backend->share)) {
    982                 /*
    983                  * There is no backend or the backend does not
    984                  * know how to share the area.
     1060        if (!src_area->backend->is_shareable(src_area)) {
     1061                /*
     1062                 * The backend does not permit sharing of this area.
    9851063                 */
    9861064                mutex_unlock(&src_area->lock);
     
    12851363int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
    12861364{
     1365        int rc = AS_PF_FAULT;
     1366
    12871367        if (!THREAD)
    1288                 return AS_PF_FAULT;
     1368                goto page_fault;
    12891369       
    12901370        if (!AS)
    1291                 return AS_PF_FAULT;
     1371                goto page_fault;
    12921372       
    12931373        mutex_lock(&AS->lock);
     
    13451425         * Resort to the backend page fault handler.
    13461426         */
    1347         if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
     1427        rc = area->backend->page_fault(area, page, access);
     1428        if (rc != AS_PF_OK) {
    13481429                page_table_unlock(AS, false);
    13491430                mutex_unlock(&area->lock);
     
    13661447                istate_set_retaddr(istate,
    13671448                    (uintptr_t) &memcpy_to_uspace_failover_address);
     1449        } else if (rc == AS_PF_SILENT) {
     1450                printf("Killing task %" PRIu64 " due to a "
     1451                    "failed late reservation request.\n", TASK->taskid);
     1452                task_kill_self(true);
    13681453        } else {
    1369                 return AS_PF_FAULT;
     1454                fault_if_from_uspace(istate, "Page fault: %p.", (void *) page);
     1455                panic_memtrap(istate, access, page, NULL);
    13701456        }
    13711457       
  • kernel/generic/src/mm/backend_anon.c

    r150a2718 r8f88beb7  
    5959static void anon_destroy(as_area_t *);
    6060
     61static bool anon_is_resizable(as_area_t *);
     62static bool anon_is_shareable(as_area_t *);
     63
    6164static int anon_page_fault(as_area_t *, uintptr_t, pf_access_t);
    6265static void anon_frame_free(as_area_t *, uintptr_t, uintptr_t);
     
    6871        .destroy = anon_destroy,
    6972
     73        .is_resizable = anon_is_resizable,
     74        .is_shareable = anon_is_shareable,
     75
    7076        .page_fault = anon_page_fault,
    7177        .frame_free = anon_frame_free,
     
    7480bool anon_create(as_area_t *area)
    7581{
     82        if (area->flags & AS_AREA_LATE_RESERVE)
     83                return true;
     84
    7685        return reserve_try_alloc(area->pages);
    7786}
     
    7988bool anon_resize(as_area_t *area, size_t new_pages)
    8089{
     90        if (area->flags & AS_AREA_LATE_RESERVE)
     91                return true;
     92
    8193        if (new_pages > area->pages)
    8294                return reserve_try_alloc(new_pages - area->pages);
     
    100112        ASSERT(mutex_locked(&area->as->lock));
    101113        ASSERT(mutex_locked(&area->lock));
     114        ASSERT(!(area->flags & AS_AREA_LATE_RESERVE));
    102115
    103116        /*
     
    139152void anon_destroy(as_area_t *area)
    140153{
     154        if (area->flags & AS_AREA_LATE_RESERVE)
     155                return;
     156
    141157        reserve_free(area->pages);
    142158}
    143159
     160bool anon_is_resizable(as_area_t *area)
     161{
     162        return true;
     163}
     164
     165bool anon_is_shareable(as_area_t *area)
     166{
     167        return !(area->flags & AS_AREA_LATE_RESERVE);
     168}
    144169
    145170/** Service a page fault in the anonymous memory address space area.
     
    225250                 *   the different causes
    226251                 */
     252
     253                if (area->flags & AS_AREA_LATE_RESERVE) {
     254                        /*
     255                         * Reserve the memory for this page now.
     256                         */
     257                        if (!reserve_try_alloc(1))
     258                                return AS_PF_SILENT;
     259                }
     260
    227261                kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE);
    228262                memsetb((void *) kpage, PAGE_SIZE, 0);
     
    255289        ASSERT(mutex_locked(&area->lock));
    256290
    257         frame_free_noreserve(frame);
     291        if (area->flags & AS_AREA_LATE_RESERVE) {
     292                /*
     293                 * In case of the late reserve areas, physical memory will not
     294                 * be unreserved when the area is destroyed so we need to use
     295                 * the normal unreserving frame_free().
     296                 */
     297                frame_free(frame);
     298        } else {
     299                /*
     300                 * The reserve will be given back when the area is destroyed or
     301                 * resized, so use the frame_free_noreserve() which does not
     302                 * manipulate the reserve or it would be given back twice.
     303                 */
     304                frame_free_noreserve(frame);
     305        }
    258306}
    259307
  • kernel/generic/src/mm/backend_elf.c

    r150a2718 r8f88beb7  
    5858static void elf_destroy(as_area_t *);
    5959
     60static bool elf_is_resizable(as_area_t *);
     61static bool elf_is_shareable(as_area_t *);
     62
    6063static int elf_page_fault(as_area_t *, uintptr_t, pf_access_t);
    6164static void elf_frame_free(as_area_t *, uintptr_t, uintptr_t);
     
    6669        .share = elf_share,
    6770        .destroy = elf_destroy,
     71
     72        .is_resizable = elf_is_resizable,
     73        .is_shareable = elf_is_shareable,
    6874
    6975        .page_fault = elf_page_fault,
     
    213219}
    214220
     221bool elf_is_resizable(as_area_t *area)
     222{
     223        return true;
     224}
     225
     226bool elf_is_shareable(as_area_t *area)
     227{
     228        return true;
     229}
     230
     231
    215232/** Service a page fault in the ELF backend address space area.
    216233 *
  • kernel/generic/src/mm/backend_phys.c

    r150a2718 r8f88beb7  
    5252static void phys_destroy(as_area_t *);
    5353
     54static bool phys_is_resizable(as_area_t *);
     55static bool phys_is_shareable(as_area_t *);
     56
     57
    5458static int phys_page_fault(as_area_t *, uintptr_t, pf_access_t);
    5559
     
    5963        .share = phys_share,
    6064        .destroy = phys_destroy,
     65
     66        .is_resizable = phys_is_resizable,
     67        .is_shareable = phys_is_shareable,
    6168
    6269        .page_fault = phys_page_fault,
     
    8794        /* Nothing to do. */
    8895}
     96
     97bool phys_is_resizable(as_area_t *area)
     98{
     99        return false;
     100}
     101
     102bool phys_is_shareable(as_area_t *area)
     103{
     104        return true;
     105}
     106
    89107
    90108/** Service a page fault in the address space area backed by physical memory.
  • kernel/generic/src/mm/km.c

    r150a2718 r8f88beb7  
    233233 * @param[inout] framep Pointer to a variable which will receive the physical
    234234 *                      address of the allocated frame.
    235  * @param[in] flags     Frame allocation flags. FRAME_NONE or FRAME_NO_RESERVE.
     235 * @param[in] flags     Frame allocation flags. FRAME_NONE, FRAME_NO_RESERVE
     236 *                      and FRAME_ATOMIC bits are allowed.
    236237 * @return              Virtual address of the allocated frame.
    237238 */
     
    243244        ASSERT(THREAD);
    244245        ASSERT(framep);
    245         ASSERT(!(flags & ~FRAME_NO_RESERVE));
     246        ASSERT(!(flags & ~(FRAME_NO_RESERVE | FRAME_ATOMIC)));
    246247
    247248        /*
     
    255256                ASSERT(page);   // FIXME
    256257        } else {
    257                 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME,
    258                     FRAME_LOWMEM);
     258                frame = (uintptr_t) frame_alloc(ONE_FRAME,
     259                    FRAME_LOWMEM | flags);
     260                if (!frame)
     261                        return (uintptr_t) NULL;
    259262                page = PA2KA(frame);
    260263        }
  • kernel/generic/src/proc/program.c

    r150a2718 r8f88beb7  
    7979         * Create the stack address space area.
    8080         */
    81         uintptr_t virt = USTACK_ADDRESS;
     81        uintptr_t virt = (uintptr_t) -1;
     82        uintptr_t bound = USER_ADDRESS_SPACE_END - (STACK_SIZE_USER - 1);
     83
     84        /* Adjust bound to create space for the desired guard page. */
     85        bound -= PAGE_SIZE;
     86
    8287        as_area_t *area = as_area_create(as,
    83             AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    84             STACK_SIZE, AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, 0);
     88            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
     89            AS_AREA_LATE_RESERVE, STACK_SIZE_USER, AS_AREA_ATTR_NONE,
     90            &anon_backend, NULL, &virt, bound);
    8591        if (!area) {
    8692                task_destroy(prg->task);
     
    9399        kernel_uarg->uspace_entry = (void *) entry_addr;
    94100        kernel_uarg->uspace_stack = (void *) virt;
    95         kernel_uarg->uspace_stack_size = STACK_SIZE;
     101        kernel_uarg->uspace_stack_size = STACK_SIZE_USER;
    96102        kernel_uarg->uspace_thread_function = NULL;
    97103        kernel_uarg->uspace_thread_arg = NULL;
  • kernel/generic/src/proc/task.c

    r150a2718 r8f88beb7  
    196196        task->ucycles = 0;
    197197        task->kcycles = 0;
    198        
     198
    199199        task->ipc_info.call_sent = 0;
    200200        task->ipc_info.call_received = 0;
Note: See TracChangeset for help on using the changeset viewer.