Changeset 2057572 in mainline for kernel/arch/sparc64/src/mm/tlb.c


Ignore:
Timestamp:
2007-03-27T23:40:25Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
399ece9
Parents:
8d37a06
Message:

The Ultimate Solution To Illegal Virtual Aliases.
It is better to avoid them completely than to fight them.
Switch the sparc64 port to 16K pages. The TLBs and TSBs
continue to operate with 8K pages only. Page tables and
other generic parts operate with 16K pages.

Because the MMU doesn't support 16K directly, each 16K
page is emulated by a pair of 8K pages. With 16K pages,
illegal aliases cannot be created in 16K D-cache.

File:
1 edited

Legend:

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

    r8d37a06 r2057572  
    5555#endif
    5656
    57 static void dtlb_pte_copy(pte_t *t, bool ro);
    58 static void itlb_pte_copy(pte_t *t);
    59 static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const
    60         char *str);
     57static void dtlb_pte_copy(pte_t *t, index_t index, bool ro);
     58static void itlb_pte_copy(pte_t *t, index_t index);
     59static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
     60    const char *str);
    6161static void do_fast_data_access_mmu_miss_fault(istate_t *istate,
    62         tlb_tag_access_reg_t tag, const char *str);
     62    tlb_tag_access_reg_t tag, const char *str);
    6363static void do_fast_data_access_protection_fault(istate_t *istate,
    64         tlb_tag_access_reg_t tag, const char *str);
     64    tlb_tag_access_reg_t tag, const char *str);
    6565
    6666char *context_encoding[] = {
     
    9393 * @param cacheable True if the mapping is cacheable, false otherwise.
    9494 */
    95 void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool
    96         locked, bool cacheable)
     95void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
     96    bool locked, bool cacheable)
    9797{
    9898        tlb_tag_access_reg_t tag;
     
    127127/** Copy PTE to TLB.
    128128 *
    129  * @param t Page Table Entry to be copied.
    130  * @param ro If true, the entry will be created read-only, regardless of its w
    131  *      field.
    132  */
    133 void dtlb_pte_copy(pte_t *t, bool ro)
     129 * @param t     Page Table Entry to be copied.
     130 * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
     131 * @param ro    If true, the entry will be created read-only, regardless of its
     132 *              w field.
     133 */
     134void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
    134135{
    135136        tlb_tag_access_reg_t tag;
     
    138139        frame_address_t fr;
    139140
    140         pg.address = t->page;
    141         fr.address = t->frame;
     141        pg.address = t->page + (index << MMU_PAGE_WIDTH);
     142        fr.address = t->frame + (index << MMU_PAGE_WIDTH);
    142143
    143144        tag.value = 0;
    144145        tag.context = t->as->asid;
    145146        tag.vpn = pg.vpn;
    146        
     147
    147148        dtlb_tag_access_write(tag.value);
    148        
     149
    149150        data.value = 0;
    150151        data.v = true;
     
    159160        data.w = ro ? false : t->w;
    160161        data.g = t->g;
    161        
     162
    162163        dtlb_data_in_write(data.value);
    163164}
     
    165166/** Copy PTE to ITLB.
    166167 *
    167  * @param t Page Table Entry to be copied.
    168  */
    169 void itlb_pte_copy(pte_t *t)
     168 * @param t     Page Table Entry to be copied.
     169 * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
     170 */
     171void itlb_pte_copy(pte_t *t, index_t index)
    170172{
    171173        tlb_tag_access_reg_t tag;
     
    174176        frame_address_t fr;
    175177
    176         pg.address = t->page;
    177         fr.address = t->frame;
     178        pg.address = t->page + (index << MMU_PAGE_WIDTH);
     179        fr.address = t->frame + (index << MMU_PAGE_WIDTH);
    178180
    179181        tag.value = 0;
     
    200202{
    201203        uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
     204        index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
    202205        pte_t *t;
    203206
     
    210213                 */
    211214                t->a = true;
    212                 itlb_pte_copy(t);
     215                itlb_pte_copy(t, index);
    213216#ifdef CONFIG_TSB
    214                 itsb_pte_copy(t);
     217                itsb_pte_copy(t, index);
    215218#endif
    216219                page_table_unlock(AS, true);
     
    223226                if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
    224227                        do_fast_instruction_access_mmu_miss_fault(istate,
    225                                 __FUNCTION__);
     228                            __FUNCTION__);
    226229                }
    227230        }
     
    237240        tlb_tag_access_reg_t tag;
    238241        uintptr_t va;
     242        index_t index;
    239243        pte_t *t;
    240244
    241245        tag.value = dtlb_tag_access_read();
    242         va = tag.vpn << PAGE_WIDTH;
     246        va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
     247        index = tag.vpn % MMU_PAGES_PER_PAGE;
    243248
    244249        if (tag.context == ASID_KERNEL) {
     
    246251                        /* NULL access in kernel */
    247252                        do_fast_data_access_mmu_miss_fault(istate, tag,
    248                                 __FUNCTION__);
     253                            __FUNCTION__);
    249254                }
    250255                do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
    251                         "kernel page fault.");
     256                    "kernel page fault.");
    252257        }
    253258
     
    260265                 */
    261266                t->a = true;
    262                 dtlb_pte_copy(t, true);
     267                dtlb_pte_copy(t, index, true);
    263268#ifdef CONFIG_TSB
    264                 dtsb_pte_copy(t, true);
     269                dtsb_pte_copy(t, index, true);
    265270#endif
    266271                page_table_unlock(AS, true);
    267272        } else {
    268273                /*
    269                  * Forward the page fault to the address space page fault handler.
     274                 * Forward the page fault to the address space page fault
     275                 * handler.
    270276                 */             
    271277                page_table_unlock(AS, true);
    272278                if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
    273279                        do_fast_data_access_mmu_miss_fault(istate, tag,
    274                                 __FUNCTION__);
     280                            __FUNCTION__);
    275281                }
    276282        }
     
    282288        tlb_tag_access_reg_t tag;
    283289        uintptr_t va;
     290        index_t index;
    284291        pte_t *t;
    285292
    286293        tag.value = dtlb_tag_access_read();
    287         va = tag.vpn << PAGE_WIDTH;
     294        va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
     295        index = tag.vpn % MMU_PAGES_PER_PAGE;   /* 16K-page emulation */
    288296
    289297        page_table_lock(AS, true);
     
    297305                t->a = true;
    298306                t->d = true;
    299                 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, va);
    300                 dtlb_pte_copy(t, false);
     307                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
     308                    va + index * MMU_PAGE_SIZE);
     309                dtlb_pte_copy(t, index, false);
    301310#ifdef CONFIG_TSB
    302                 dtsb_pte_copy(t, false);
     311                dtsb_pte_copy(t, index, false);
    303312#endif
    304313                page_table_unlock(AS, true);
     
    311320                if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
    312321                        do_fast_data_access_protection_fault(istate, tag,
    313                                 __FUNCTION__);
     322                            __FUNCTION__);
    314323                }
    315324        }
     
    329338
    330339                printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    331                         "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    332                         "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    333                         t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    334                         d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     340                    "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
     341                    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
     342                    t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
     343                    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
    335344        }
    336345
     
    341350               
    342351                printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
    343                         "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
    344                         "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
    345                         t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
    346                         d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
    347         }
    348 
    349 }
    350 
    351 void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char
    352         *str)
     352                    "ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
     353                    "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
     354                    t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
     355                    d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
     356        }
     357
     358}
     359
     360void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
     361    const char *str)
    353362{
    354363        fault_if_from_uspace(istate, "%s\n", str);
     
    357366}
    358367
    359 void do_fast_data_access_mmu_miss_fault(istate_t *istate, tlb_tag_access_reg_t
    360         tag, const char *str)
     368void do_fast_data_access_mmu_miss_fault(istate_t *istate,
     369    tlb_tag_access_reg_t tag, const char *str)
    361370{
    362371        uintptr_t va;
    363372
    364         va = tag.vpn << PAGE_WIDTH;
     373        va = tag.vpn << MMU_PAGE_WIDTH;
    365374
    366375        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
    367                 tag.context);
     376            tag.context);
    368377        dump_istate(istate);
    369378        printf("Faulting page: %p, ASID=%d\n", va, tag.context);
     
    371380}
    372381
    373 void do_fast_data_access_protection_fault(istate_t *istate, tlb_tag_access_reg_t
    374         tag, const char *str)
     382void do_fast_data_access_protection_fault(istate_t *istate,
     383    tlb_tag_access_reg_t tag, const char *str)
    375384{
    376385        uintptr_t va;
    377386
    378         va = tag.vpn << PAGE_WIDTH;
     387        va = tag.vpn << MMU_PAGE_WIDTH;
    379388
    380389        fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
    381                 tag.context);
     390            tag.context);
    382391        printf("Faulting page: %p, ASID=%d\n", va, tag.context);
    383392        dump_istate(istate);
     
    394403       
    395404        printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
    396                 "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
    397                 sfsr.ow, sfsr.fv);
     405            "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
     406            sfsr.ow, sfsr.fv);
    398407        printf("DTLB SFAR: address=%p\n", sfar);
    399408       
     
    482491        mmu_primary_context_write(ctx.v);
    483492       
    484         for (i = 0; i < cnt; i++) {
     493        for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
    485494                itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
    486                     page + i * PAGE_SIZE);
     495                    page + i * MMU_PAGE_SIZE);
    487496                dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
    488                     page + i * PAGE_SIZE);
     497                    page + i * MMU_PAGE_SIZE);
    489498        }
    490499       
Note: See TracChangeset for help on using the changeset viewer.