• James Hogan's avatar
    MIPS: Fix input modify in __write_64bit_c0_split() · c22c8043
    James Hogan authored
    The inline asm in __write_64bit_c0_split() modifies the 64-bit input
    operand by shifting the high register left by 32, and constructing the
    full 64-bit value in the low register (even on a 32-bit kernel), so if
    that value is used again it could cause breakage as GCC would assume the
    registers haven't changed when they have.
    
    To quote the GCC extended asm documentation:
    > Warning: Do not modify the contents of input-only operands (except for
    > inputs tied to outputs). The compiler assumes that on exit from the
    > asm statement these operands contain the same values as they had
    > before executing the statement.
    
    Avoid modifying the input by using a temporary variable as an output
    which is modified instead of the input and not otherwise used. The asm
    is always __volatile__ so GCC shouldn't optimise it out. The low
    register of the temporary output is written before the high register of
    the input is read, so we have two constraint alternatives, one where
    both use the same registers (for when the input value isn't subsequently
    used), and one with an early clobber on the output in case the low
    output uses the same register as the high input. This allows the
    resulting assembly to remain mostly unchanged.
    
    A diff of a MIPS32r6 kernel reveals only three differences, two in
    relation to write_c0_r10k_diag() in cpu_probe() (register allocation
    rearranged slightly but otherwise identical), and one in relation to
    write_c0_cvmmemctl2() in kvm_vz_local_flush_guesttlb_all(), but the
    octeon CPU is only supported on 64-bit kernels where
    __write_64bit_c0_split() isn't used so that shouldn't matter in
    practice. So there currently doesn't appear to be anything broken by
    this bug.
    Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/17315/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
    c22c8043
mipsregs.h 88.2 KB