aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/mm/tlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/mm/tlb.c')
-rw-r--r--arch/arc/mm/tlb.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 9b9ce23f4ec3..003d69ac6ffa 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -418,23 +418,37 @@ void create_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
418 local_irq_restore(flags); 418 local_irq_restore(flags);
419} 419}
420 420
421/* arch hook called by core VM at the end of handle_mm_fault( ), 421/*
422 * when a new PTE is entered in Page Tables or an existing one 422 * Called at the end of pagefault, for a userspace mapped page
423 * is modified. We aggresively pre-install a TLB entry 423 * -pre-install the corresponding TLB entry into MMU
424 * -Finalize the delayed D-cache flush (wback+inv kernel mapping)
424 */ 425 */
425 426void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned,
426void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddress,
427 pte_t *ptep) 427 pte_t *ptep)
428{ 428{
429 unsigned long vaddr = vaddr_unaligned & PAGE_MASK;
430
431 create_tlb(vma, vaddr, ptep);
429 432
430 create_tlb(vma, vaddress, ptep); 433 /* icache doesn't snoop dcache, thus needs to be made coherent here */
434 if (vma->vm_flags & VM_EXEC) {
435 struct page *page = pfn_to_page(pte_pfn(*ptep));
436
437 /* if page was dcache dirty, flush now */
438 int dirty = test_and_clear_bit(PG_arch_1, &page->flags);
439 if (dirty) {
440 unsigned long paddr = pte_val(*ptep) & PAGE_MASK;
441 __flush_dcache_page(paddr);
442 __inv_icache_page(paddr, vaddr);
443 }
444 }
431} 445}
432 446
433/* Read the Cache Build Confuration Registers, Decode them and save into 447/* Read the Cache Build Confuration Registers, Decode them and save into
434 * the cpuinfo structure for later use. 448 * the cpuinfo structure for later use.
435 * No Validation is done here, simply read/convert the BCRs 449 * No Validation is done here, simply read/convert the BCRs
436 */ 450 */
437void __init read_decode_mmu_bcr(void) 451void __cpuinit read_decode_mmu_bcr(void)
438{ 452{
439 unsigned int tmp; 453 unsigned int tmp;
440 struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */ 454 struct bcr_mmu_1_2 *mmu2; /* encoded MMU2 attr */
@@ -466,7 +480,7 @@ void __init read_decode_mmu_bcr(void)
466char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) 480char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
467{ 481{
468 int n = 0; 482 int n = 0;
469 struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 483 struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu;
470 484
471 n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", 485 n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ",
472 p_mmu->ver, TO_KB(p_mmu->pg_sz)); 486 p_mmu->ver, TO_KB(p_mmu->pg_sz));
@@ -480,7 +494,7 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len)
480 return buf; 494 return buf;
481} 495}
482 496
483void __init arc_mmu_init(void) 497void __cpuinit arc_mmu_init(void)
484{ 498{
485 char str[256]; 499 char str[256];
486 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; 500 struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;