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>
This commit is contained in:
Wu Fei
2009-09-03 22:29:53 +08:00
committed by Ralf Baechle
parent a7bcb1ae60
commit e0cc87f594
4 changed files with 3 additions and 63 deletions

View File

@@ -499,11 +499,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
* The vmalloc handling is not in the hotpath.
*/
uasm_i_dmfc0(p, tmp, C0_BADVADDR);
#ifdef MODULE_START
uasm_il_bltz(p, r, tmp, label_module_alloc);
#else
uasm_il_bltz(p, r, tmp, label_vmalloc);
#endif
/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_SMP
@@ -556,52 +552,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
{
long swpd = (long)swapper_pg_dir;
#ifdef MODULE_START
long modd = (long)module_pg_dir;
uasm_l_module_alloc(l, *p);
/*
* Assumption:
* VMALLOC_START >= 0xc000000000000000UL
* MODULE_START >= 0xe000000000000000UL
*/
UASM_i_SLL(p, ptr, bvaddr, 2);
uasm_il_bgez(p, r, ptr, label_vmalloc);
if (uasm_in_compat_space_p(MODULE_START) &&
!uasm_rel_lo(MODULE_START)) {
uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */
} else {
/* unlikely configuration */
uasm_i_nop(p); /* delay slot */
UASM_i_LA(p, ptr, MODULE_START);
}
uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) {
uasm_il_b(p, r, label_vmalloc_done);
uasm_i_lui(p, ptr, uasm_rel_hi(modd));
} else {
UASM_i_LA_mostly(p, ptr, modd);
uasm_il_b(p, r, label_vmalloc_done);
if (uasm_in_compat_space_p(modd))
uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd));
else
uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd));
}
uasm_l_vmalloc(l, *p);
if (uasm_in_compat_space_p(MODULE_START) &&
!uasm_rel_lo(MODULE_START) &&
MODULE_START << 32 == VMALLOC_START)
uasm_i_dsll32(p, ptr, ptr, 0); /* typical case */
else
UASM_i_LA(p, ptr, VMALLOC_START);
#else
uasm_l_vmalloc(l, *p);
UASM_i_LA(p, ptr, VMALLOC_START);
#endif
uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
uasm_il_b(p, r, label_vmalloc_done);