summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/page.h8
-rw-r--r--arch/mips/mm/tlb-r4k.c20
2 files changed, 22 insertions, 6 deletions
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index e59cd1ac09c..d41790928c6 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -38,6 +38,14 @@
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+#else /* !CONFIG_HUGETLB_PAGE */
+# ifndef BUILD_BUG
+# define BUILD_BUG() do { extern void __build_bug(void); __build_bug(); } while (0)
+# endif
+#define HPAGE_SHIFT ({BUILD_BUG(); 0; })
+#define HPAGE_SIZE ({BUILD_BUG(); 0; })
+#define HPAGE_MASK ({BUILD_BUG(); 0; })
+#define HUGETLB_PAGE_ORDER ({BUILD_BUG(); 0; })
#endif /* CONFIG_HUGETLB_PAGE */
#ifndef __ASSEMBLY__
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 0d394e0e883..88dc49cfa16 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();