aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlb-r4k.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r--arch/mips/mm/tlb-r4k.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 0d394e0e8837..88dc49cfa163 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,
120 120
121 if (cpu_context(cpu, mm) != 0) { 121 if (cpu_context(cpu, mm) != 0) {
122 unsigned long size, flags; 122 unsigned long size, flags;
123 int huge = is_vm_hugetlb_page(vma);
123 124
124 ENTER_CRITICAL(flags); 125 ENTER_CRITICAL(flags);
125 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 126 if (huge) {
126 size = (size + 1) >> 1; 127 start = round_down(start, HPAGE_SIZE);
128 end = round_up(end, HPAGE_SIZE);
129 size = (end - start) >> HPAGE_SHIFT;
130 } else {
131 start = round_down(start, PAGE_SIZE << 1);
132 end = round_up(end, PAGE_SIZE << 1);
133 size = (end - start) >> (PAGE_SHIFT + 1);
134 }
127 if (size <= current_cpu_data.tlbsize/2) { 135 if (size <= current_cpu_data.tlbsize/2) {
128 int oldpid = read_c0_entryhi(); 136 int oldpid = read_c0_entryhi();
129 int newpid = cpu_asid(cpu, mm); 137 int newpid = cpu_asid(cpu, mm);
130 138
131 start &= (PAGE_MASK << 1);
132 end += ((PAGE_SIZE << 1) - 1);
133 end &= (PAGE_MASK << 1);
134 while (start < end) { 139 while (start < end) {
135 int idx; 140 int idx;
136 141
137 write_c0_entryhi(start | newpid); 142 write_c0_entryhi(start | newpid);
138 start += (PAGE_SIZE << 1); 143 if (huge)
144 start += HPAGE_SIZE;
145 else
146 start += (PAGE_SIZE << 1);
139 mtc0_tlbw_hazard(); 147 mtc0_tlbw_hazard();
140 tlb_probe(); 148 tlb_probe();
141 tlb_probe_hazard(); 149 tlb_probe_hazard();