diff options
author | Wu Fei <at.wufei@gmail.com> | 2009-09-03 10:29:53 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-09-17 14:07:51 -0400 |
commit | e0cc87f59490d7d62a8ab2a76498dc8a2b64927a (patch) | |
tree | d68107417b92d83493bbb95c08af98b0f8597220 /arch/mips/mm | |
parent | a7bcb1ae6094db78b077ae17e92c69de7643014f (diff) |
MIPS: Shrink the size of tlb handler
By combining swapper_pg_dir and module_pg_dir, several if conditions
can be eliminated from the tlb exception handler. The reason they
can be combined is that, the effective virtual address of vmalloc
returned is at the bottom, and of module_alloc returned is at the
top. It also fixes the bug in vmalloc(), which happens when its
return address is not covered by the first pgd.
Signed-off-by: Wu Fei <at.wufei@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/init.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/pgtable-64.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 49 |
3 files changed, 0 insertions, 55 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 0e820508ff23..38c79c55b060 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -475,9 +475,6 @@ unsigned long pgd_current[NR_CPUS]; | |||
475 | */ | 475 | */ |
476 | pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); | 476 | pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); |
477 | #ifdef CONFIG_64BIT | 477 | #ifdef CONFIG_64BIT |
478 | #ifdef MODULE_START | ||
479 | pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER); | ||
480 | #endif | ||
481 | pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER); | 478 | pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER); |
482 | #endif | 479 | #endif |
483 | pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER); | 480 | pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER); |
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index e4b565aeb008..1121019fa456 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c | |||
@@ -59,9 +59,6 @@ void __init pagetable_init(void) | |||
59 | 59 | ||
60 | /* Initialize the entire pgd. */ | 60 | /* Initialize the entire pgd. */ |
61 | pgd_init((unsigned long)swapper_pg_dir); | 61 | pgd_init((unsigned long)swapper_pg_dir); |
62 | #ifdef MODULE_START | ||
63 | pgd_init((unsigned long)module_pg_dir); | ||
64 | #endif | ||
65 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); | 62 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); |
66 | 63 | ||
67 | pgd_base = swapper_pg_dir; | 64 | pgd_base = swapper_pg_dir; |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 9a17bf8395df..bc66f57f3257 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -499,11 +499,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, | |||
499 | * The vmalloc handling is not in the hotpath. | 499 | * The vmalloc handling is not in the hotpath. |
500 | */ | 500 | */ |
501 | uasm_i_dmfc0(p, tmp, C0_BADVADDR); | 501 | uasm_i_dmfc0(p, tmp, C0_BADVADDR); |
502 | #ifdef MODULE_START | ||
503 | uasm_il_bltz(p, r, tmp, label_module_alloc); | ||
504 | #else | ||
505 | uasm_il_bltz(p, r, tmp, label_vmalloc); | 502 | uasm_il_bltz(p, r, tmp, label_vmalloc); |
506 | #endif | ||
507 | /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */ | 503 | /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */ |
508 | 504 | ||
509 | #ifdef CONFIG_SMP | 505 | #ifdef CONFIG_SMP |
@@ -556,52 +552,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, | |||
556 | { | 552 | { |
557 | long swpd = (long)swapper_pg_dir; | 553 | long swpd = (long)swapper_pg_dir; |
558 | 554 | ||
559 | #ifdef MODULE_START | ||
560 | long modd = (long)module_pg_dir; | ||
561 | |||
562 | uasm_l_module_alloc(l, *p); | ||
563 | /* | ||
564 | * Assumption: | ||
565 | * VMALLOC_START >= 0xc000000000000000UL | ||
566 | * MODULE_START >= 0xe000000000000000UL | ||
567 | */ | ||
568 | UASM_i_SLL(p, ptr, bvaddr, 2); | ||
569 | uasm_il_bgez(p, r, ptr, label_vmalloc); | ||
570 | |||
571 | if (uasm_in_compat_space_p(MODULE_START) && | ||
572 | !uasm_rel_lo(MODULE_START)) { | ||
573 | uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */ | ||
574 | } else { | ||
575 | /* unlikely configuration */ | ||
576 | uasm_i_nop(p); /* delay slot */ | ||
577 | UASM_i_LA(p, ptr, MODULE_START); | ||
578 | } | ||
579 | uasm_i_dsubu(p, bvaddr, bvaddr, ptr); | ||
580 | |||
581 | if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) { | ||
582 | uasm_il_b(p, r, label_vmalloc_done); | ||
583 | uasm_i_lui(p, ptr, uasm_rel_hi(modd)); | ||
584 | } else { | ||
585 | UASM_i_LA_mostly(p, ptr, modd); | ||
586 | uasm_il_b(p, r, label_vmalloc_done); | ||
587 | if (uasm_in_compat_space_p(modd)) | ||
588 | uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd)); | ||
589 | else | ||
590 | uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd)); | ||
591 | } | ||
592 | |||
593 | uasm_l_vmalloc(l, *p); | 555 | uasm_l_vmalloc(l, *p); |
594 | if (uasm_in_compat_space_p(MODULE_START) && | ||
595 | !uasm_rel_lo(MODULE_START) && | ||
596 | MODULE_START << 32 == VMALLOC_START) | ||
597 | uasm_i_dsll32(p, ptr, ptr, 0); /* typical case */ | ||
598 | else | ||
599 | UASM_i_LA(p, ptr, VMALLOC_START); | ||
600 | #else | ||
601 | uasm_l_vmalloc(l, *p); | ||
602 | UASM_i_LA(p, ptr, VMALLOC_START); | ||
603 | #endif | ||
604 | uasm_i_dsubu(p, bvaddr, bvaddr, ptr); | ||
605 | 556 | ||
606 | if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) { | 557 | if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) { |
607 | uasm_il_b(p, r, label_vmalloc_done); | 558 | uasm_il_b(p, r, label_vmalloc_done); |