diff options
author | Hillf Danton <dhillf@gmail.com> | 2012-01-11 15:37:13 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-01-11 15:37:13 +0100 |
commit | f467e4bfb50ca6af042f1b19b3556bd4aca854c3 (patch) | |
tree | 0c8f1d7bc8ac30ee10d7edbb8463f496a75082b2 /arch/mips/mm | |
parent | 8b5690f8847490c1e3ea47266819833a13621253 (diff) | |
download | op-kernel-dev-f467e4bfb50ca6af042f1b19b3556bd4aca854c3.zip op-kernel-dev-f467e4bfb50ca6af042f1b19b3556bd4aca854c3.tar.gz |
MIPS: Flush huge TLB
When flushing TLB, if @vma is backed by huge page, we could flush huge
TLB, due to that huge page is defined to be far from normal page.
Signed-off-by: Hillf Danton <dhillf@gmail.com>
Acked-by: David Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Cc: "Jayachandran C." <jayachandranc@netlogicmicro.com>
Patchwork: https://patchwork.linux-mips.org/patch/2825/
Signed-off-by: David Daney <david.daney@cavium.com>
Acked-by: Hillf Danton <dhillf@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3114/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 0d394e0..88dc49c 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -120,22 +120,30 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, if (cpu_context(cpu, mm) != 0) { unsigned long size, flags; + int huge = is_vm_hugetlb_page(vma); ENTER_CRITICAL(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; + if (huge) { + start = round_down(start, HPAGE_SIZE); + end = round_up(end, HPAGE_SIZE); + size = (end - start) >> HPAGE_SHIFT; + } else { + start = round_down(start, PAGE_SIZE << 1); + end = round_up(end, PAGE_SIZE << 1); + size = (end - start) >> (PAGE_SHIFT + 1); + } if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); while (start < end) { int idx; write_c0_entryhi(start | newpid); - start += (PAGE_SIZE << 1); + if (huge) + start += HPAGE_SIZE; + else + start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); tlb_probe_hazard(); |