Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia64/src/mm/tlb.c

    r22f0561 r0ff03f3  
    5252#include <arch.h>
    5353#include <interrupt.h>
    54 #include <arch/legacyio.h>
     54
     55#define IO_FRAME_BASE 0xFFFFC000000
    5556
    5657/** Invalidate all TLB entries. */
     
    466467}
    467468
    468 static bool is_kernel_fault(uintptr_t va)
    469 {
    470         region_register_t rr;
    471 
    472         rr.word = rr_read(VA2VRN(va));
    473         rid_t rid = rr.map.rid;
    474         return (RID2ASID(rid) == ASID_KERNEL) && (VA2VRN(va) == VRN_KERNEL);
    475 }
    476 
    477469/** Instruction TLB fault handler for faults with VHPT turned off.
    478470 *
     
    488480        va = istate->cr_ifa; /* faulting address */
    489481       
    490         ASSERT(!is_kernel_fault(va));
    491 
     482        page_table_lock(AS, true);
    492483        t = page_mapping_find(AS, va, true);
    493484        if (t) {
     
    497488                 */
    498489                itc_pte_copy(t);
     490                page_table_unlock(AS, true);
    499491        } else {
    500492                /*
    501493                 * Forward the page fault to address space page fault handler.
    502494                 */
     495                page_table_unlock(AS, true);
    503496                if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
    504497                        fault_if_from_uspace(istate, "Page fault at %p.",
     
    529522static int try_memmap_io_insertion(uintptr_t va, istate_t *istate)
    530523{
    531         if ((va >= LEGACYIO_USER_BASE) && (va < LEGACYIO_USER_BASE + (1 << LEGACYIO_PAGE_WIDTH))) {
     524        if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) {
    532525                if (TASK) {
    533                         uint64_t io_page = (va & ((1 << LEGACYIO_PAGE_WIDTH) - 1)) >>
    534                             LEGACYIO_SINGLE_PAGE_WIDTH;
     526                        uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >>
     527                            USPACE_IO_PAGE_WIDTH;
    535528                       
    536529                        if (is_io_page_accessible(io_page)) {
    537530                                uint64_t page, frame;
    538531                               
    539                                 page = LEGACYIO_USER_BASE +
    540                                     (1 << LEGACYIO_SINGLE_PAGE_WIDTH) * io_page;
    541                                 frame = LEGACYIO_PHYS_BASE +
    542                                     (1 << LEGACYIO_SINGLE_PAGE_WIDTH) * io_page;
     532                                page = IO_OFFSET +
     533                                    (1 << USPACE_IO_PAGE_WIDTH) * io_page;
     534                                frame = IO_FRAME_BASE +
     535                                    (1 << USPACE_IO_PAGE_WIDTH) * io_page;
    543536                               
    544537                                tlb_entry_t entry;
     
    554547                                entry.ar = AR_READ | AR_WRITE;
    555548                                entry.ppn = frame >> PPN_SHIFT;
    556                                 entry.ps = LEGACYIO_SINGLE_PAGE_WIDTH;
     549                                entry.ps = USPACE_IO_PAGE_WIDTH;
    557550                               
    558551                                dtc_mapping_insert(page, TASK->as->asid, entry);
     
    577570{
    578571        if (istate->cr_isr.sp) {
    579                 /*
    580                  * Speculative load. Deffer the exception until a more clever
    581                  * approach can be used. Currently if we try to find the
    582                  * mapping for the speculative load while in the kernel, we
    583                  * might introduce a livelock because of the possibly invalid
    584                  * values of the address.
    585                  */
     572                /* Speculative load. Deffer the exception
     573                   until a more clever approach can be used.
     574                  
     575                   Currently if we try to find the mapping
     576                   for the speculative load while in the kernel,
     577                   we might introduce a livelock because of
     578                   the possibly invalid values of the address. */
    586579                istate->cr_ipsr.ed = true;
    587580                return;
     
    589582       
    590583        uintptr_t va = istate->cr_ifa;  /* faulting address */
    591         as_t *as = AS;
    592        
    593         if (is_kernel_fault(va)) {
    594                 if (va < end_of_identity) {
     584       
     585        region_register_t rr;
     586        rr.word = rr_read(VA2VRN(va));
     587        rid_t rid = rr.map.rid;
     588        if (RID2ASID(rid) == ASID_KERNEL) {
     589                if (VA2VRN(va) == VRN_KERNEL) {
    595590                        /*
    596                          * Create kernel identity mapping for low memory.
     591                         * Provide KA2PA(identity) mapping for faulting piece of
     592                         * kernel address space.
    597593                         */
    598594                        dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
    599595                        return;
    600                 } else {
    601                         as = AS_KERNEL;
    602596                }
    603597        }
    604598       
    605599       
    606         pte_t *entry = page_mapping_find(as, va, true);
     600        page_table_lock(AS, true);
     601        pte_t *entry = page_mapping_find(AS, va, true);
    607602        if (entry) {
    608603                /*
     
    611606                 */
    612607                dtc_pte_copy(entry);
     608                page_table_unlock(AS, true);
    613609        } else {
     610                page_table_unlock(AS, true);
    614611                if (try_memmap_io_insertion(va, istate))
    615612                        return;
     
    650647        uintptr_t va;
    651648        pte_t *t;
    652         as_t *as = AS;
    653649       
    654650        va = istate->cr_ifa;  /* faulting address */
    655651       
    656         if (is_kernel_fault(va))
    657                 as = AS_KERNEL;
    658 
    659         t = page_mapping_find(as, va, true);
     652        page_table_lock(AS, true);
     653        t = page_mapping_find(AS, va, true);
    660654        ASSERT((t) && (t->p));
    661655        if ((t) && (t->p) && (t->w)) {
     
    673667                }
    674668        }
     669        page_table_unlock(AS, true);
    675670}
    676671
     
    687682       
    688683        va = istate->cr_ifa;  /* faulting address */
    689 
    690         ASSERT(!is_kernel_fault(va));
    691        
     684       
     685        page_table_lock(AS, true);
    692686        t = page_mapping_find(AS, va, true);
    693687        ASSERT((t) && (t->p));
     
    706700                }
    707701        }
     702        page_table_unlock(AS, true);
    708703}
    709704
     
    718713        uintptr_t va;
    719714        pte_t *t;
    720         as_t *as = AS;
    721715       
    722716        va = istate->cr_ifa;  /* faulting address */
    723717       
    724         if (is_kernel_fault(va))
    725                 as = AS_KERNEL;
    726 
    727         t = page_mapping_find(as, va, true);
     718        page_table_lock(AS, true);
     719        t = page_mapping_find(AS, va, true);
    728720        ASSERT((t) && (t->p));
    729721        if ((t) && (t->p)) {
     
    741733                }
    742734        }
     735        page_table_unlock(AS, true);
    743736}
    744737
     
    755748       
    756749        va = istate->cr_ifa;  /* faulting address */
    757 
    758         ASSERT(!is_kernel_fault(va));
    759750       
    760751        /*
    761752         * Assume a write to a read-only page.
    762753         */
     754        page_table_lock(AS, true);
    763755        t = page_mapping_find(AS, va, true);
    764756        ASSERT((t) && (t->p));
     
    769761                panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
    770762        }
     763        page_table_unlock(AS, true);
    771764}
    772765
     
    784777        va = istate->cr_ifa;  /* faulting address */
    785778       
    786         ASSERT(!is_kernel_fault(va));
    787 
     779        page_table_lock(AS, true);
    788780        t = page_mapping_find(AS, va, true);
    789781        ASSERT(t);
     
    798790                else
    799791                        dtc_pte_copy(t);
     792                page_table_unlock(AS, true);
    800793        } else {
     794                page_table_unlock(AS, true);
    801795                if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
    802796                        fault_if_from_uspace(istate, "Page fault at %p.",
Note: See TracChangeset for help on using the changeset viewer.