diff options
Diffstat (limited to 'arch/arc/mm/tlb.c')
-rw-r--r-- | arch/arc/mm/tlb.c | 32 |
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 | 426 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, | |
426 | void 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 | */ |
437 | void __init read_decode_mmu_bcr(void) | 451 | void __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) | |||
466 | char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) | 480 | char *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 | ||
483 | void __init arc_mmu_init(void) | 497 | void __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; |