Thiemo, The XTLB refill handler splitter misplaces labels associated with an instruction that gets placed in the branch delay slot of the splitting branch. Here's an example: tlb-handler.img: file format binary Disassembly of section .data: 0000000000000000 <.data>: 0: 001bd83c dsll32 k1,k1,0x0 4: 035bd02f dsubu k0,k0,k1 8: 3c1b803a lui k1,0x803a c: 10000026 b 0xa8 10: 677b4000 daddiu k1,k1,16384 ... 80: 403a4000 dmfc0 k0,c0_badvaddr 84: 403b5000 dmfc0 k1,c0_entryhi 88: 035bd026 xor k0,k0,k1 8c: 001ad37a dsrl k0,k0,0xd 90: 17400018 bnez k0,0xf4 94: 403a4000 dmfc0 k0,c0_badvaddr 98: 07400018 bltz k0,0xfc 9c: 403b2000 dmfc0 k1,c0_context a0: 001bddfb dsra k1,k1,0x17 a4: df7b0000 ld k1,0(k1) a8: 001ad73a dsrl k0,k0,0x1c ac: 335a1ff8 andi k0,k0,0x1ff8 b0: 037ad82d daddu k1,k1,k0 b4: 403a4000 dmfc0 k0,c0_badvaddr b8: df7b0000 ld k1,0(k1) bc: 001ad4ba dsrl k0,k0,0x12 c0: 335a0ff8 andi k0,k0,0xff8 c4: 037ad82d daddu k1,k1,k0 c8: 403aa000 dmfc0 k0,c0_xcontext cc: df7b0000 ld k1,0(k1) d0: 335a0ff0 andi k0,k0,0xff0 d4: 037ad82d daddu k1,k1,k0 d8: df7a0000 ld k0,0(k1) dc: df7b0008 ld k1,8(k1) e0: 001ad1ba dsrl k0,k0,0x6 e4: 409a1000 mtc0 k0,c0_entrylo0 e8: 001bd9ba dsrl k1,k1,0x6 ec: 409b1800 mtc0 k1,c0_entrylo1 f0: 42000006 tlbwr f4: 42000018 eret f8: 1000ffc1 b 0x0 fc: 3c1bc000 lui k1,0xc000 I've fixed it by separating the label mover (and the reloc mover, for consistency) and using it to fix up relevant labels. I'll apply it if it's OK with you. Maciej patch-mips-2.6.10-rc2-20041124-mips-tlb-label-0 diff -up --recursive --new-file linux-mips-2.6.10-rc2-20041124.macro/arch/mips/mm/tlbex.c linux-mips-2.6.10-rc2-20041124/arch/mips/mm/tlbex.c --- linux-mips-2.6.10-rc2-20041124.macro/arch/mips/mm/tlbex.c 2004-11-24 21:37:38.000000000 +0000 +++ linux-mips-2.6.10-rc2-20041124/arch/mips/mm/tlbex.c 2004-12-02 17:41:11.000000000 +0000 @@ -550,22 +550,33 @@ static __init void resolve_relocs(struct __resolve_relocs(rel, l); } -static __init void copy_handler(struct reloc *rel, struct label *lab, - u32 *first, u32 *end, u32* target) +static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, + long off) { - long off = (long)(target - first); - - memcpy(target, first, (end - first) * sizeof(u32)); - for (; rel->lab != label_invalid; rel++) if (rel->addr >= first && rel->addr < end) rel->addr += off; +} +static __init void move_labels(struct label *lab, u32 *first, u32 *end, + long off) +{ for (; lab->lab != label_invalid; lab++) if (lab->addr >= first && lab->addr < end) lab->addr += off; } +static __init void copy_handler(struct reloc *rel, struct label *lab, + u32 *first, u32 *end, u32 *target) +{ + long off = (long)(target - first); + + memcpy(target, first, (end - first) * sizeof(u32)); + + move_relocs(rel, first, end, off); + move_labels(lab, first, end, off); +} + static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel, u32 *addr) { @@ -1110,6 +1121,7 @@ static void __init build_r4000_tlb_refil i_nop(&f); else { copy_handler(relocs, labels, split, split + 1, f); + move_labels(labels, f, f + 1, -1); f++; split++; }