FAILED: patch "[PATCH] MIPS: Add missing EHB in mtc0 -> mfc0 sequence." failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0b24cae4d535045f4c9e177aa228d4e97bad212c Mon Sep 17 00:00:00 2001
From: Dmitry Korotin <[email protected]>
Date: Mon, 24 Jun 2019 19:05:27 +0000
Subject: [PATCH] MIPS: Add missing EHB in mtc0 -> mfc0 sequence.
Add a missing EHB (Execution Hazard Barrier) in mtc0 -> mfc0 sequence. Without this execution hazard barrier it's possible for the value read back from the KScratch register to be the value from before the mtc0.
Reproducible on P5600 & P6600.
The hazard is documented in the MIPS Architecture Reference Manual Vol.
III: MIPS32/microMIPS32 Privileged Resource Architecture (MD00088), rev 6.03 table 8.1 which includes:
Producer | Consumer | Hazard ----------|----------|---------------------------- mtc0 | mfc0 | any coprocessor 0 register
[[email protected]:
- Commit message tweaks.
- Add Fixes tags.
- Mark for stable back to v3.15 where P5600 support was introduced.]
arch/mips/mm/tlbex.c +20 -9
@@ -391,6 +391,7 @@ static struct work_registers build_get_work_registers(u32 **p)static void build_restore_work_registers (u32 **p) {if (scratch_reg >=0 ) { +uasm_i_ehb (p);UASM_i_MFC0 (p,1 ,c0_kscratch (), scratch_reg);return ; }
@@ -668,10 +669,12 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r,uasm_i_mtc0 (p,0 ,C0_PAGEMASK );uasm_il_b (p, r, lid); } -if (scratch_reg >=0 ) +if (scratch_reg >=0 ) { +uasm_i_ehb (p);UASM_i_MFC0 (p,1 ,c0_kscratch (), scratch_reg); -else + }else {UASM_i_LW (p,1 ,scratchpad_offset (0 ),0 ); + } }else {/* Reset default page size */ if (PM_DEFAULT_MASK >>16 ) {
@@ -938,10 +941,12 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,uasm_i_jr (p, ptr);if (mode == refill_scratch) { -if (scratch_reg >=0 ) +if (scratch_reg >=0 ) { +uasm_i_ehb (p);UASM_i_MFC0 (p,1 ,c0_kscratch (), scratch_reg); -else + }else {UASM_i_LW (p,1 ,scratchpad_offset (0 ),0 ); + } }else {uasm_i_nop (p); }
@@ -1258,6 +1263,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,UASM_i_MTC0 (p, odd,C0_ENTRYLO1 );/* load it */ if (c0_scratch_reg >=0 ) { +uasm_i_ehb (p);UASM_i_MFC0 (p, scratch,c0_kscratch (), c0_scratch_reg);build_tlb_write_entry (p, l, r, tlb_random);uasm_l_leave (l, *p);
@@ -1603,15 +1609,17 @@ static void build_setup_pgd(void)uasm_i_dinsm (&p, a0,0 ,29 ,64 -29 );uasm_l_tlbl_goaround1 (&l, p);UASM_i_SLL (&p, a0, a0,11 ); -uasm_i_jr (&p,31 );UASM_i_MTC0 (&p, a0,C0_CONTEXT ); +uasm_i_jr (&p,31 ); + uasm_i_ehb(&p); }else {/* PGD in c0_KScratch */ -uasm_i_jr (&p,31 );if (cpu_has_ldpte)UASM_i_MTC0 (&p, a0,C0_PWBASE );else UASM_i_MTC0 (&p, a0,c0_kscratch (), pgd_reg); +uasm_i_jr (&p,31 ); +uasm_i_ehb (&p); }#else #ifdef CONFIG_SMP
@@ -1625,13 +1633,16 @@ static void build_setup_pgd(void)UASM_i_LA_mostly (&p, a2, pgdc);UASM_i_SW (&p, a0,uasm_rel_lo (pgdc), a2);#endif /* SMP */ -uasm_i_jr (&p,31 );/* if pgd_reg is allocated, save PGD also to scratch register */ -if (pgd_reg !=-1 ) +if (pgd_reg !=-1 ) {UASM_i_MTC0 (&p, a0,c0_kscratch (), pgd_reg); -else +uasm_i_jr (&p,31 ); +uasm_i_ehb (&p); + }else { +uasm_i_jr (&p,31 );uasm_i_nop (&p); + }#endif if (p >= (u32 *)tlbmiss_handler_setup_pgd_end)panic ("tlbmiss_handler_setup_pgd space exceeded" );