diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2012-01-11 09:41:47 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-01-11 09:41:47 -0500 |
commit | 39b741431af7f6f46b2e0e7f7f13ea2351fb4a5f (patch) | |
tree | 89355f4ae7bbb874537bb65f71ba0d19b3d468e1 /arch/mips/mm/tlb-r4k.c | |
parent | 5b0ec2efb7d373faa7b1a7632c459b93895d45cd (diff) | |
parent | d7a887a73dec6c387b02a966a71aac767bbd9ce6 (diff) |
Merge branch 'next/generic' into mips-for-linux-next
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 67 |
1 files changed, 14 insertions, 53 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index d163455552b0..2dc625346c40 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -121,22 +121,30 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
121 | 121 | ||
122 | if (cpu_context(cpu, mm) != 0) { | 122 | if (cpu_context(cpu, mm) != 0) { |
123 | unsigned long size, flags; | 123 | unsigned long size, flags; |
124 | int huge = is_vm_hugetlb_page(vma); | ||
124 | 125 | ||
125 | ENTER_CRITICAL(flags); | 126 | ENTER_CRITICAL(flags); |
126 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 127 | if (huge) { |
127 | size = (size + 1) >> 1; | 128 | start = round_down(start, HPAGE_SIZE); |
129 | end = round_up(end, HPAGE_SIZE); | ||
130 | size = (end - start) >> HPAGE_SHIFT; | ||
131 | } else { | ||
132 | start = round_down(start, PAGE_SIZE << 1); | ||
133 | end = round_up(end, PAGE_SIZE << 1); | ||
134 | size = (end - start) >> (PAGE_SHIFT + 1); | ||
135 | } | ||
128 | if (size <= current_cpu_data.tlbsize/2) { | 136 | if (size <= current_cpu_data.tlbsize/2) { |
129 | int oldpid = read_c0_entryhi(); | 137 | int oldpid = read_c0_entryhi(); |
130 | int newpid = cpu_asid(cpu, mm); | 138 | int newpid = cpu_asid(cpu, mm); |
131 | 139 | ||
132 | start &= (PAGE_MASK << 1); | ||
133 | end += ((PAGE_SIZE << 1) - 1); | ||
134 | end &= (PAGE_MASK << 1); | ||
135 | while (start < end) { | 140 | while (start < end) { |
136 | int idx; | 141 | int idx; |
137 | 142 | ||
138 | write_c0_entryhi(start | newpid); | 143 | write_c0_entryhi(start | newpid); |
139 | start += (PAGE_SIZE << 1); | 144 | if (huge) |
145 | start += HPAGE_SIZE; | ||
146 | else | ||
147 | start += (PAGE_SIZE << 1); | ||
140 | mtc0_tlbw_hazard(); | 148 | mtc0_tlbw_hazard(); |
141 | tlb_probe(); | 149 | tlb_probe(); |
142 | tlb_probe_hazard(); | 150 | tlb_probe_hazard(); |
@@ -369,51 +377,6 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
369 | EXIT_CRITICAL(flags); | 377 | EXIT_CRITICAL(flags); |
370 | } | 378 | } |
371 | 379 | ||
372 | /* | ||
373 | * Used for loading TLB entries before trap_init() has started, when we | ||
374 | * don't actually want to add a wired entry which remains throughout the | ||
375 | * lifetime of the system | ||
376 | */ | ||
377 | |||
378 | static int temp_tlb_entry __cpuinitdata; | ||
379 | |||
380 | __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | ||
381 | unsigned long entryhi, unsigned long pagemask) | ||
382 | { | ||
383 | int ret = 0; | ||
384 | unsigned long flags; | ||
385 | unsigned long wired; | ||
386 | unsigned long old_pagemask; | ||
387 | unsigned long old_ctx; | ||
388 | |||
389 | ENTER_CRITICAL(flags); | ||
390 | /* Save old context and create impossible VPN2 value */ | ||
391 | old_ctx = read_c0_entryhi(); | ||
392 | old_pagemask = read_c0_pagemask(); | ||
393 | wired = read_c0_wired(); | ||
394 | if (--temp_tlb_entry < wired) { | ||
395 | printk(KERN_WARNING | ||
396 | "No TLB space left for add_temporary_entry\n"); | ||
397 | ret = -ENOSPC; | ||
398 | goto out; | ||
399 | } | ||
400 | |||
401 | write_c0_index(temp_tlb_entry); | ||
402 | write_c0_pagemask(pagemask); | ||
403 | write_c0_entryhi(entryhi); | ||
404 | write_c0_entrylo0(entrylo0); | ||
405 | write_c0_entrylo1(entrylo1); | ||
406 | mtc0_tlbw_hazard(); | ||
407 | tlb_write_indexed(); | ||
408 | tlbw_use_hazard(); | ||
409 | |||
410 | write_c0_entryhi(old_ctx); | ||
411 | write_c0_pagemask(old_pagemask); | ||
412 | out: | ||
413 | EXIT_CRITICAL(flags); | ||
414 | return ret; | ||
415 | } | ||
416 | |||
417 | static int __cpuinitdata ntlb; | 380 | static int __cpuinitdata ntlb; |
418 | static int __init set_ntlb(char *str) | 381 | static int __init set_ntlb(char *str) |
419 | { | 382 | { |
@@ -451,8 +414,6 @@ void __cpuinit tlb_init(void) | |||
451 | write_c0_pagegrain(pg); | 414 | write_c0_pagegrain(pg); |
452 | } | 415 | } |
453 | 416 | ||
454 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | ||
455 | |||
456 | /* From this point on the ARC firmware is dead. */ | 417 | /* From this point on the ARC firmware is dead. */ |
457 | local_flush_tlb_all(); | 418 | local_flush_tlb_all(); |
458 | 419 | ||