From: Ralf Baechle <ralf@linux-mips.org>
To: linux-mips@linux-mips.org
Subject: [PATCH] tlbex: Deal with re-definition of label
Date: Sat, 13 Oct 2012 22:44:57 +0200 [thread overview]
Message-ID: <20121013204457.GA5340@linux-mips.org> (raw)
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.
Over the past years there have been a few very mysterious reports about
weird things happening on QED/IDT RM5231 / RM5261 processors; I have
a little hope this bug might be the solution. R4000/R4400 processors
are equally affected.
The fix is a bit cheesy. Among other reasons this is because this was
easier to implement than a gas-like local label feature and also because
it gets away without a memory allocator.
Please test this. Thanks,
Ralf
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 42a5d55..1128c7a 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -147,7 +147,14 @@ enum label_id {
label_leave,
label_vmalloc,
label_vmalloc_done,
- label_tlbw_hazard,
+ label_tlbw_hazard_0,
+ label_tlbw_hazard_1,
+ label_tlbw_hazard_2,
+ label_tlbw_hazard_3,
+ label_tlbw_hazard_4,
+ label_tlbw_hazard_5,
+ label_tlbw_hazard_6,
+ label_tlbw_hazard_7,
label_split,
label_tlbl_goaround1,
label_tlbl_goaround2,
@@ -166,7 +173,14 @@ UASM_L_LA(_second_part)
UASM_L_LA(_leave)
UASM_L_LA(_vmalloc)
UASM_L_LA(_vmalloc_done)
-UASM_L_LA(_tlbw_hazard)
+UASM_L_LA(_tlbw_hazard_0)
+UASM_L_LA(_tlbw_hazard_1)
+UASM_L_LA(_tlbw_hazard_2)
+UASM_L_LA(_tlbw_hazard_3)
+UASM_L_LA(_tlbw_hazard_4)
+UASM_L_LA(_tlbw_hazard_5)
+UASM_L_LA(_tlbw_hazard_6)
+UASM_L_LA(_tlbw_hazard_7)
UASM_L_LA(_split)
UASM_L_LA(_tlbl_goaround1)
UASM_L_LA(_tlbl_goaround2)
@@ -180,6 +194,72 @@ UASM_L_LA(_large_segbits_fault)
UASM_L_LA(_tlb_huge_update)
#endif
+static int hazard_instance;
+
+static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)
+{
+ switch (instance) {
+ case 0:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_0);
+ return;
+ case 1:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_1);
+ return;
+ case 2:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_2);
+ return;
+ case 3:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_3);
+ return;
+ case 4:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_4);
+ return;
+ case 5:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_5);
+ return;
+ case 6:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_6);
+ return;
+ case 7:
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard_7);
+ return;
+ default:
+ BUG();
+ }
+}
+
+static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)
+{
+ switch (instance) {
+ case 0:
+ uasm_l_tlbw_hazard_0(l, *p);
+ break;
+ case 1:
+ uasm_l_tlbw_hazard_1(l, *p);
+ break;
+ case 2:
+ uasm_l_tlbw_hazard_2(l, *p);
+ break;
+ case 3:
+ uasm_l_tlbw_hazard_3(l, *p);
+ break;
+ case 4:
+ uasm_l_tlbw_hazard_4(l, *p);
+ break;
+ case 5:
+ uasm_l_tlbw_hazard_5(l, *p);
+ break;
+ case 6:
+ uasm_l_tlbw_hazard_6(l, *p);
+ break;
+ case 7:
+ uasm_l_tlbw_hazard_7(l, *p);
+ break;
+ default:
+ BUG();
+ }
+}
+
/*
* For debug purposes.
*/
@@ -465,9 +545,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
* two nops after the tlbw instruction.
*/
- uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_bgezl_hazard(p, r, hazard_instance);
tlbw(p);
- uasm_l_tlbw_hazard(l, *p);
+ uasm_bgezl_label(l, p, hazard_instance);
+ hazard_instance++;
uasm_i_nop(p);
break;
@@ -514,13 +595,15 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
case CPU_NEVADA:
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
* a nop after the tlbw instruction.
*/
- uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_bgezl_hazard(p, r, hazard_instance);
tlbw(p);
- uasm_l_tlbw_hazard(l, *p);
+ uasm_bgezl_label(l, p, hazard_instance);
+ hazard_instance++;
break;
case CPU_RM7000:
next reply other threads:[~2012-10-13 20:45 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-13 20:44 Ralf Baechle [this message]
2012-10-15 9:04 ` [PATCH] tlbex: Deal with re-definition of label Ralf Baechle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121013204457.GA5340@linux-mips.org \
--to=ralf@linux-mips.org \
--cc=linux-mips@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox