MIPS: tlbex: Deal with re-definition of label
The microassembler used in tlbex.c does not notice if a label is redefined resulting in relocations against such labels silently missrelocated. The issues exists since commit add6eb04776db4189ea89f596cbcde31b899be9d [Synthesize TLB exception handlers at runtime.] in 2.6.10 and went unnoticed for so long because the relocations for the affected branches got computed to do something *almost* sensible. The issue affects R4000, R4400, QED/IDT RM5230, RM5231, RM5260, RM5261, RM5270 and RM5271 processors. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
5210edcd52
commit
02a5417751
|
@ -148,8 +148,8 @@ enum label_id {
|
||||||
label_leave,
|
label_leave,
|
||||||
label_vmalloc,
|
label_vmalloc,
|
||||||
label_vmalloc_done,
|
label_vmalloc_done,
|
||||||
label_tlbw_hazard,
|
label_tlbw_hazard_0,
|
||||||
label_split,
|
label_split = label_tlbw_hazard_0 + 8,
|
||||||
label_tlbl_goaround1,
|
label_tlbl_goaround1,
|
||||||
label_tlbl_goaround2,
|
label_tlbl_goaround2,
|
||||||
label_nopage_tlbl,
|
label_nopage_tlbl,
|
||||||
|
@ -167,7 +167,7 @@ UASM_L_LA(_second_part)
|
||||||
UASM_L_LA(_leave)
|
UASM_L_LA(_leave)
|
||||||
UASM_L_LA(_vmalloc)
|
UASM_L_LA(_vmalloc)
|
||||||
UASM_L_LA(_vmalloc_done)
|
UASM_L_LA(_vmalloc_done)
|
||||||
UASM_L_LA(_tlbw_hazard)
|
/* _tlbw_hazard_x is handled differently. */
|
||||||
UASM_L_LA(_split)
|
UASM_L_LA(_split)
|
||||||
UASM_L_LA(_tlbl_goaround1)
|
UASM_L_LA(_tlbl_goaround1)
|
||||||
UASM_L_LA(_tlbl_goaround2)
|
UASM_L_LA(_tlbl_goaround2)
|
||||||
|
@ -181,6 +181,30 @@ UASM_L_LA(_large_segbits_fault)
|
||||||
UASM_L_LA(_tlb_huge_update)
|
UASM_L_LA(_tlb_huge_update)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int __cpuinitdata hazard_instance;
|
||||||
|
|
||||||
|
static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)
|
||||||
|
{
|
||||||
|
switch (instance) {
|
||||||
|
case 0 ... 7:
|
||||||
|
uasm_il_bgezl(p, r, 0, label_tlbw_hazard_0 + instance);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)
|
||||||
|
{
|
||||||
|
switch (instance) {
|
||||||
|
case 0 ... 7:
|
||||||
|
uasm_build_label(l, *p, label_tlbw_hazard_0 + instance);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For debug purposes.
|
* For debug purposes.
|
||||||
*/
|
*/
|
||||||
|
@ -478,9 +502,10 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
||||||
* This branch uses up a mtc0 hazard nop slot and saves
|
* This branch uses up a mtc0 hazard nop slot and saves
|
||||||
* two nops after the tlbw instruction.
|
* two nops after the tlbw instruction.
|
||||||
*/
|
*/
|
||||||
uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
|
uasm_bgezl_hazard(p, r, hazard_instance);
|
||||||
tlbw(p);
|
tlbw(p);
|
||||||
uasm_l_tlbw_hazard(l, *p);
|
uasm_bgezl_label(l, p, hazard_instance);
|
||||||
|
hazard_instance++;
|
||||||
uasm_i_nop(p);
|
uasm_i_nop(p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -527,14 +552,16 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_NEVADA:
|
case CPU_NEVADA:
|
||||||
|
uasm_i_nop(p); /* QED specifies 2 nops hazard */
|
||||||
uasm_i_nop(p); /* QED specifies 2 nops hazard */
|
uasm_i_nop(p); /* QED specifies 2 nops hazard */
|
||||||
/*
|
/*
|
||||||
* This branch uses up a mtc0 hazard nop slot and saves
|
* This branch uses up a mtc0 hazard nop slot and saves
|
||||||
* a nop after the tlbw instruction.
|
* a nop after the tlbw instruction.
|
||||||
*/
|
*/
|
||||||
uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
|
uasm_bgezl_hazard(p, r, hazard_instance);
|
||||||
tlbw(p);
|
tlbw(p);
|
||||||
uasm_l_tlbw_hazard(l, *p);
|
uasm_bgezl_label(l, p, hazard_instance);
|
||||||
|
hazard_instance++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPU_RM7000:
|
case CPU_RM7000:
|
||||||
|
|
Loading…
Reference in New Issue