aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>2014-11-27 06:13:08 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-11-27 11:21:56 -0500
commit070e76cb3ffe43f6855492e77c96680c562598f0 (patch)
treea873e8a0d4424ab18274d7b6ecc32537f5f8cccc /arch
parentb4da18b3714a35c1123522810cc5ec0cd2ee4101 (diff)
MIPS: tlbex: Fix potential HTW race on TLBL/M/S handlers
There is a potential race when probing the TLB in TLBL/M/S exception handlers for a matching entry. Between the time we hit a TLBL/S/M exception and the time we get to execute the TLBP instruction, the HTW may have replaced the TLB entry we are interested in hence the TLB probe may fail. However, in the existing handlers, we never checked the status of the TLBP (ie check the result in the C0/Index register). We fix this by adding such a check when the core implements the HTW. If we couldn't find a matching entry, we return back and try again. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Reviewed-by: James Hogan <james.hogan@imgtec.com> Cc: <stable@vger.kernel.org> # v3.17+ Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8599/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/mm/tlbex.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index b5f228e7eae6..e3328a96e809 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1872,8 +1872,16 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
1872 uasm_l_smp_pgtable_change(l, *p); 1872 uasm_l_smp_pgtable_change(l, *p);
1873#endif 1873#endif
1874 iPTE_LW(p, wr.r1, wr.r2); /* get even pte */ 1874 iPTE_LW(p, wr.r1, wr.r2); /* get even pte */
1875 if (!m4kc_tlbp_war()) 1875 if (!m4kc_tlbp_war()) {
1876 build_tlb_probe_entry(p); 1876 build_tlb_probe_entry(p);
1877 if (cpu_has_htw) {
1878 /* race condition happens, leaving */
1879 uasm_i_ehb(p);
1880 uasm_i_mfc0(p, wr.r3, C0_INDEX);
1881 uasm_il_bltz(p, r, wr.r3, label_leave);
1882 uasm_i_nop(p);
1883 }
1884 }
1877 return wr; 1885 return wr;
1878} 1886}
1879 1887