• Paul Burton's avatar
    MIPS: tlbex: Fix build_restore_pagemask KScratch restore · b42aa3fd
    Paul Burton authored
    build_restore_pagemask() will restore the value of register $1/$at when
    its restore_scratch argument is non-zero, and aims to do so by filling a
    branch delay slot. Commit 0b24cae4 ("MIPS: Add missing EHB in mtc0
    -> mfc0 sequence.") added an EHB instruction (Execution Hazard Barrier)
    prior to restoring $1 from a KScratch register, in order to resolve a
    hazard that can result in stale values of the KScratch register being
    observed. In particular, P-class CPUs from MIPS with out of order
    execution pipelines such as the P5600 & P6600 are affected.
    
    Unfortunately this EHB instruction was inserted in the branch delay slot
    causing the MFC0 instruction which performs the restoration to no longer
    execute along with the branch. The result is that the $1 register isn't
    actually restored, ie. the TLB refill exception handler clobbers it -
    which is exactly the problem the EHB is meant to avoid for the P-class
    CPUs.
    
    Similarly build_get_pgd_vmalloc() will restore the value of $1/$at when
    its mode argument equals refill_scratch, and suffers from the same
    problem.
    
    Fix this by in both cases moving the EHB earlier in the emitted code.
    There's no reason it needs to immediately precede the MFC0 - it simply
    needs to be between the MTC0 & MFC0.
    
    This bug only affects Cavium Octeon systems which use
    build_fast_tlb_refill_handler().
    Signed-off-by: default avatarPaul Burton <paulburton@kernel.org>
    Fixes: 0b24cae4 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.")
    Cc: Dmitry Korotin <dkorotin@wavecomp.com>
    Cc: stable@vger.kernel.org # v3.15+
    Cc: linux-mips@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    b42aa3fd
tlbex.c 70.8 KB