From 3ac23944de570df7a6309425aeef063be38f37c4 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 7 Nov 2018 10:35:34 +0800 Subject: nios2: update_mmu_cache preload the TLB with the new PTE Rather than flush the TLB entry when installing a new PTE to allow the fast TLB reload to re-fill the TLB, just refill the TLB entry when removing the old one. Signed-off-by: Nicholas Piggin Signed-off-by: Ley Foon Tan --- arch/nios2/mm/tlb.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'arch/nios2/mm/tlb.c') diff --git a/arch/nios2/mm/tlb.c b/arch/nios2/mm/tlb.c index 2e49993d29ef..af8711885569 100644 --- a/arch/nios2/mm/tlb.c +++ b/arch/nios2/mm/tlb.c @@ -43,13 +43,11 @@ static unsigned long pteaddr_invalid(unsigned long addr) * This one is only used for pages with the global bit set so we don't care * much about the ASID. */ -void flush_tlb_one_pid(unsigned long addr, unsigned long mmu_pid) +static void replace_tlb_one_pid(unsigned long addr, unsigned long mmu_pid, unsigned long tlbacc) { unsigned int way; unsigned long org_misc, pid_misc; - pr_debug("Flush tlb-entry for vaddr=%#lx\n", addr); - /* remember pid/way until we return. */ get_misc_and_pid(&org_misc, &pid_misc); @@ -72,10 +70,11 @@ void flush_tlb_one_pid(unsigned long addr, unsigned long mmu_pid) if (pid != mmu_pid) continue; - tlbmisc = TLBMISC_WE | (way << TLBMISC_WAY_SHIFT); + tlbmisc = mmu_pid | TLBMISC_WE | (way << TLBMISC_WAY_SHIFT); WRCTL(CTL_TLBMISC, tlbmisc); - WRCTL(CTL_PTEADDR, pteaddr_invalid(addr)); - WRCTL(CTL_TLBACC, 0); + if (tlbacc == 0) + WRCTL(CTL_PTEADDR, pteaddr_invalid(addr)); + WRCTL(CTL_TLBACC, tlbacc); /* * There should be only a single entry that maps a * particular {address,pid} so break after a match. @@ -86,6 +85,20 @@ void flush_tlb_one_pid(unsigned long addr, unsigned long mmu_pid) WRCTL(CTL_TLBMISC, org_misc); } +static void flush_tlb_one_pid(unsigned long addr, unsigned long mmu_pid) +{ + pr_debug("Flush tlb-entry for vaddr=%#lx\n", addr); + + replace_tlb_one_pid(addr, mmu_pid, 0); +} + +static void reload_tlb_one_pid(unsigned long addr, unsigned long mmu_pid, pte_t pte) +{ + pr_debug("Reload tlb-entry for vaddr=%#lx\n", addr); + + replace_tlb_one_pid(addr, mmu_pid, pte_val(pte)); +} + void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { @@ -97,6 +110,13 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, } } +void reload_tlb_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long mmu_pid = get_pid_from_context(&vma->vm_mm->context); + + reload_tlb_one_pid(addr, mmu_pid, pte); +} + /* * This one is only used for pages with the global bit set so we don't care * much about the ASID. -- cgit v1.2.3-59-g8ed1b