diff options
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 892be426787c..cee502caf398 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -10,7 +10,9 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/smp.h> | ||
13 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/hugetlb.h> | ||
14 | 16 | ||
15 | #include <asm/cpu.h> | 17 | #include <asm/cpu.h> |
16 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
@@ -295,21 +297,41 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
295 | pudp = pud_offset(pgdp, address); | 297 | pudp = pud_offset(pgdp, address); |
296 | pmdp = pmd_offset(pudp, address); | 298 | pmdp = pmd_offset(pudp, address); |
297 | idx = read_c0_index(); | 299 | idx = read_c0_index(); |
298 | ptep = pte_offset_map(pmdp, address); | 300 | #ifdef CONFIG_HUGETLB_PAGE |
301 | /* this could be a huge page */ | ||
302 | if (pmd_huge(*pmdp)) { | ||
303 | unsigned long lo; | ||
304 | write_c0_pagemask(PM_HUGE_MASK); | ||
305 | ptep = (pte_t *)pmdp; | ||
306 | lo = pte_val(*ptep) >> 6; | ||
307 | write_c0_entrylo0(lo); | ||
308 | write_c0_entrylo1(lo + (HPAGE_SIZE >> 7)); | ||
309 | |||
310 | mtc0_tlbw_hazard(); | ||
311 | if (idx < 0) | ||
312 | tlb_write_random(); | ||
313 | else | ||
314 | tlb_write_indexed(); | ||
315 | write_c0_pagemask(PM_DEFAULT_MASK); | ||
316 | } else | ||
317 | #endif | ||
318 | { | ||
319 | ptep = pte_offset_map(pmdp, address); | ||
299 | 320 | ||
300 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 321 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
301 | write_c0_entrylo0(ptep->pte_high); | 322 | write_c0_entrylo0(ptep->pte_high); |
302 | ptep++; | 323 | ptep++; |
303 | write_c0_entrylo1(ptep->pte_high); | 324 | write_c0_entrylo1(ptep->pte_high); |
304 | #else | 325 | #else |
305 | write_c0_entrylo0(pte_val(*ptep++) >> 6); | 326 | write_c0_entrylo0(pte_val(*ptep++) >> 6); |
306 | write_c0_entrylo1(pte_val(*ptep) >> 6); | 327 | write_c0_entrylo1(pte_val(*ptep) >> 6); |
307 | #endif | 328 | #endif |
308 | mtc0_tlbw_hazard(); | 329 | mtc0_tlbw_hazard(); |
309 | if (idx < 0) | 330 | if (idx < 0) |
310 | tlb_write_random(); | 331 | tlb_write_random(); |
311 | else | 332 | else |
312 | tlb_write_indexed(); | 333 | tlb_write_indexed(); |
334 | } | ||
313 | tlbw_use_hazard(); | 335 | tlbw_use_hazard(); |
314 | FLUSH_ITLB_VM(vma); | 336 | FLUSH_ITLB_VM(vma); |
315 | EXIT_CRITICAL(flags); | 337 | EXIT_CRITICAL(flags); |