.. | .. |
---|
21 | 21 | #include <asm/bootinfo.h> |
---|
22 | 22 | #include <asm/hazards.h> |
---|
23 | 23 | #include <asm/mmu_context.h> |
---|
24 | | -#include <asm/pgtable.h> |
---|
25 | 24 | #include <asm/tlb.h> |
---|
26 | 25 | #include <asm/tlbmisc.h> |
---|
27 | 26 | |
---|
.. | .. |
---|
35 | 34 | static inline void flush_micro_tlb(void) |
---|
36 | 35 | { |
---|
37 | 36 | switch (current_cpu_type()) { |
---|
38 | | - case CPU_LOONGSON2: |
---|
| 37 | + case CPU_LOONGSON2EF: |
---|
39 | 38 | write_c0_diag(LOONGSON_DIAG_ITLB); |
---|
40 | 39 | break; |
---|
41 | | - case CPU_LOONGSON3: |
---|
| 40 | + case CPU_LOONGSON64: |
---|
42 | 41 | write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB); |
---|
43 | 42 | break; |
---|
44 | 43 | default: |
---|
.. | .. |
---|
104 | 103 | } |
---|
105 | 104 | EXPORT_SYMBOL(local_flush_tlb_all); |
---|
106 | 105 | |
---|
107 | | -/* All entries common to a mm share an asid. To effectively flush |
---|
108 | | - these entries, we just bump the asid. */ |
---|
109 | | -void local_flush_tlb_mm(struct mm_struct *mm) |
---|
110 | | -{ |
---|
111 | | - int cpu; |
---|
112 | | - |
---|
113 | | - preempt_disable(); |
---|
114 | | - |
---|
115 | | - cpu = smp_processor_id(); |
---|
116 | | - |
---|
117 | | - if (cpu_context(cpu, mm) != 0) { |
---|
118 | | - drop_mmu_context(mm, cpu); |
---|
119 | | - } |
---|
120 | | - |
---|
121 | | - preempt_enable(); |
---|
122 | | -} |
---|
123 | | - |
---|
124 | 106 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
---|
125 | 107 | unsigned long end) |
---|
126 | 108 | { |
---|
.. | .. |
---|
137 | 119 | if (size <= (current_cpu_data.tlbsizeftlbsets ? |
---|
138 | 120 | current_cpu_data.tlbsize / 8 : |
---|
139 | 121 | current_cpu_data.tlbsize / 2)) { |
---|
140 | | - int oldpid = read_c0_entryhi(); |
---|
| 122 | + unsigned long old_entryhi, old_mmid; |
---|
141 | 123 | int newpid = cpu_asid(cpu, mm); |
---|
| 124 | + |
---|
| 125 | + old_entryhi = read_c0_entryhi(); |
---|
| 126 | + if (cpu_has_mmid) { |
---|
| 127 | + old_mmid = read_c0_memorymapid(); |
---|
| 128 | + write_c0_memorymapid(newpid); |
---|
| 129 | + } |
---|
142 | 130 | |
---|
143 | 131 | htw_stop(); |
---|
144 | 132 | while (start < end) { |
---|
145 | 133 | int idx; |
---|
146 | 134 | |
---|
147 | | - write_c0_entryhi(start | newpid); |
---|
| 135 | + if (cpu_has_mmid) |
---|
| 136 | + write_c0_entryhi(start); |
---|
| 137 | + else |
---|
| 138 | + write_c0_entryhi(start | newpid); |
---|
148 | 139 | start += (PAGE_SIZE << 1); |
---|
149 | 140 | mtc0_tlbw_hazard(); |
---|
150 | 141 | tlb_probe(); |
---|
.. | .. |
---|
160 | 151 | tlb_write_indexed(); |
---|
161 | 152 | } |
---|
162 | 153 | tlbw_use_hazard(); |
---|
163 | | - write_c0_entryhi(oldpid); |
---|
| 154 | + write_c0_entryhi(old_entryhi); |
---|
| 155 | + if (cpu_has_mmid) |
---|
| 156 | + write_c0_memorymapid(old_mmid); |
---|
164 | 157 | htw_start(); |
---|
165 | 158 | } else { |
---|
166 | | - drop_mmu_context(mm, cpu); |
---|
| 159 | + drop_mmu_context(mm); |
---|
167 | 160 | } |
---|
168 | 161 | flush_micro_tlb(); |
---|
169 | 162 | local_irq_restore(flags); |
---|
.. | .. |
---|
220 | 213 | int cpu = smp_processor_id(); |
---|
221 | 214 | |
---|
222 | 215 | if (cpu_context(cpu, vma->vm_mm) != 0) { |
---|
223 | | - unsigned long flags; |
---|
224 | | - int oldpid, newpid, idx; |
---|
| 216 | + unsigned long old_mmid; |
---|
| 217 | + unsigned long flags, old_entryhi; |
---|
| 218 | + int idx; |
---|
225 | 219 | |
---|
226 | | - newpid = cpu_asid(cpu, vma->vm_mm); |
---|
227 | 220 | page &= (PAGE_MASK << 1); |
---|
228 | 221 | local_irq_save(flags); |
---|
229 | | - oldpid = read_c0_entryhi(); |
---|
| 222 | + old_entryhi = read_c0_entryhi(); |
---|
230 | 223 | htw_stop(); |
---|
231 | | - write_c0_entryhi(page | newpid); |
---|
| 224 | + if (cpu_has_mmid) { |
---|
| 225 | + old_mmid = read_c0_memorymapid(); |
---|
| 226 | + write_c0_entryhi(page); |
---|
| 227 | + write_c0_memorymapid(cpu_asid(cpu, vma->vm_mm)); |
---|
| 228 | + } else { |
---|
| 229 | + write_c0_entryhi(page | cpu_asid(cpu, vma->vm_mm)); |
---|
| 230 | + } |
---|
232 | 231 | mtc0_tlbw_hazard(); |
---|
233 | 232 | tlb_probe(); |
---|
234 | 233 | tlb_probe_hazard(); |
---|
.. | .. |
---|
244 | 243 | tlbw_use_hazard(); |
---|
245 | 244 | |
---|
246 | 245 | finish: |
---|
247 | | - write_c0_entryhi(oldpid); |
---|
| 246 | + write_c0_entryhi(old_entryhi); |
---|
| 247 | + if (cpu_has_mmid) |
---|
| 248 | + write_c0_memorymapid(old_mmid); |
---|
248 | 249 | htw_start(); |
---|
249 | 250 | flush_micro_tlb_vm(vma); |
---|
250 | 251 | local_irq_restore(flags); |
---|
.. | .. |
---|
293 | 294 | { |
---|
294 | 295 | unsigned long flags; |
---|
295 | 296 | pgd_t *pgdp; |
---|
| 297 | + p4d_t *p4dp; |
---|
296 | 298 | pud_t *pudp; |
---|
297 | 299 | pmd_t *pmdp; |
---|
298 | 300 | pte_t *ptep; |
---|
.. | .. |
---|
307 | 309 | local_irq_save(flags); |
---|
308 | 310 | |
---|
309 | 311 | htw_stop(); |
---|
310 | | - pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); |
---|
311 | 312 | address &= (PAGE_MASK << 1); |
---|
312 | | - write_c0_entryhi(address | pid); |
---|
| 313 | + if (cpu_has_mmid) { |
---|
| 314 | + write_c0_entryhi(address); |
---|
| 315 | + } else { |
---|
| 316 | + pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); |
---|
| 317 | + write_c0_entryhi(address | pid); |
---|
| 318 | + } |
---|
313 | 319 | pgdp = pgd_offset(vma->vm_mm, address); |
---|
314 | 320 | mtc0_tlbw_hazard(); |
---|
315 | 321 | tlb_probe(); |
---|
316 | 322 | tlb_probe_hazard(); |
---|
317 | | - pudp = pud_offset(pgdp, address); |
---|
| 323 | + p4dp = p4d_offset(pgdp, address); |
---|
| 324 | + pudp = pud_offset(p4dp, address); |
---|
318 | 325 | pmdp = pmd_offset(pudp, address); |
---|
319 | 326 | idx = read_c0_index(); |
---|
320 | 327 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
---|
.. | .. |
---|
375 | 382 | #ifdef CONFIG_XPA |
---|
376 | 383 | panic("Broken for XPA kernels"); |
---|
377 | 384 | #else |
---|
| 385 | + unsigned int old_mmid; |
---|
378 | 386 | unsigned long flags; |
---|
379 | 387 | unsigned long wired; |
---|
380 | 388 | unsigned long old_pagemask; |
---|
381 | 389 | unsigned long old_ctx; |
---|
382 | 390 | |
---|
383 | 391 | local_irq_save(flags); |
---|
| 392 | + if (cpu_has_mmid) { |
---|
| 393 | + old_mmid = read_c0_memorymapid(); |
---|
| 394 | + write_c0_memorymapid(MMID_KERNEL_WIRED); |
---|
| 395 | + } |
---|
384 | 396 | /* Save old context and create impossible VPN2 value */ |
---|
385 | 397 | old_ctx = read_c0_entryhi(); |
---|
386 | 398 | htw_stop(); |
---|
.. | .. |
---|
398 | 410 | tlbw_use_hazard(); |
---|
399 | 411 | |
---|
400 | 412 | write_c0_entryhi(old_ctx); |
---|
| 413 | + if (cpu_has_mmid) |
---|
| 414 | + write_c0_memorymapid(old_mmid); |
---|
401 | 415 | tlbw_use_hazard(); /* What is the hazard here? */ |
---|
402 | 416 | htw_start(); |
---|
403 | 417 | write_c0_pagemask(old_pagemask); |
---|