Skip to content

Commit dd8f65a

Browse files
Dmitry Korotingregkh
authored andcommitted
MIPS: Add missing EHB in mtc0 -> mfc0 sequence.
commit 0b24cae upstream. 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 Signed-off-by: Dmitry Korotin <[email protected]> [[email protected]: - Commit message tweaks. - Add Fixes tags. - Mark for stable back to v3.15 where P5600 support was introduced.] Signed-off-by: Paul Burton <[email protected]> Fixes: 3d8bfdd ("MIPS: Use C0_KScratch (if present) to hold PGD pointer.") Fixes: 829dcc0 ("MIPS: Add MIPS P5600 probe support") Cc: [email protected] Cc: [email protected] # v3.15+ Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ea663ab commit dd8f65a

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

arch/mips/mm/tlbex.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ static struct work_registers build_get_work_registers(u32 **p)
386386
static void build_restore_work_registers(u32 **p)
387387
{
388388
if (scratch_reg >= 0) {
389+
uasm_i_ehb(p);
389390
UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
390391
return;
391392
}
@@ -674,10 +675,12 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r,
674675
uasm_i_mtc0(p, 0, C0_PAGEMASK);
675676
uasm_il_b(p, r, lid);
676677
}
677-
if (scratch_reg >= 0)
678+
if (scratch_reg >= 0) {
679+
uasm_i_ehb(p);
678680
UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
679-
else
681+
} else {
680682
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
683+
}
681684
} else {
682685
/* Reset default page size */
683686
if (PM_DEFAULT_MASK >> 16) {
@@ -935,10 +938,12 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
935938
uasm_i_jr(p, ptr);
936939

937940
if (mode == refill_scratch) {
938-
if (scratch_reg >= 0)
941+
if (scratch_reg >= 0) {
942+
uasm_i_ehb(p);
939943
UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
940-
else
944+
} else {
941945
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
946+
}
942947
} else {
943948
uasm_i_nop(p);
944949
}
@@ -1238,6 +1243,7 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
12381243
UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
12391244

12401245
if (c0_scratch_reg >= 0) {
1246+
uasm_i_ehb(p);
12411247
UASM_i_MFC0(p, scratch, c0_kscratch(), c0_scratch_reg);
12421248
build_tlb_write_entry(p, l, r, tlb_random);
12431249
uasm_l_leave(l, *p);
@@ -1592,15 +1598,17 @@ static void build_setup_pgd(void)
15921598
uasm_i_dinsm(&p, a0, 0, 29, 64 - 29);
15931599
uasm_l_tlbl_goaround1(&l, p);
15941600
UASM_i_SLL(&p, a0, a0, 11);
1595-
uasm_i_jr(&p, 31);
15961601
UASM_i_MTC0(&p, a0, C0_CONTEXT);
1602+
uasm_i_jr(&p, 31);
1603+
uasm_i_ehb(&p);
15971604
} else {
15981605
/* PGD in c0_KScratch */
1599-
uasm_i_jr(&p, 31);
16001606
if (cpu_has_ldpte)
16011607
UASM_i_MTC0(&p, a0, C0_PWBASE);
16021608
else
16031609
UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
1610+
uasm_i_jr(&p, 31);
1611+
uasm_i_ehb(&p);
16041612
}
16051613
#else
16061614
#ifdef CONFIG_SMP
@@ -1614,13 +1622,16 @@ static void build_setup_pgd(void)
16141622
UASM_i_LA_mostly(&p, a2, pgdc);
16151623
UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
16161624
#endif /* SMP */
1617-
uasm_i_jr(&p, 31);
16181625

16191626
/* if pgd_reg is allocated, save PGD also to scratch register */
1620-
if (pgd_reg != -1)
1627+
if (pgd_reg != -1) {
16211628
UASM_i_MTC0(&p, a0, c0_kscratch(), pgd_reg);
1622-
else
1629+
uasm_i_jr(&p, 31);
1630+
uasm_i_ehb(&p);
1631+
} else {
1632+
uasm_i_jr(&p, 31);
16231633
uasm_i_nop(&p);
1634+
}
16241635
#endif
16251636
if (p >= tlbmiss_handler_setup_pgd_end)
16261637
panic("tlbmiss_handler_setup_pgd space exceeded");

0 commit comments

Comments
 (0)