mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 09:59:32 +00:00
MIPS: Avoid move psuedo-instruction whilst using MIPS_ISA_LEVEL
MIPS_ISA_LEVEL is always defined as the 64 bit ISA that is a compatible superset of the ISA that the kernel build is targeting, and is used to allow us to emit instructions that we may detect support for at runtime. When we use a .set MIPS_ISA_LEVEL directive & are building a 32-bit kernel, we therefore are temporarily allowing the assembler to generate MIPS64 instructions. Using the move pseudo-instruction whilst this is the case is problematic because the assembler is likely to emit a daddu instruction which will generate a reserved instruction exception when executed on a MIPS32 machine. Unfortunately the combination of commita0a5ac3ce8
("MIPS: Fix delay slot bug in `atomic*_sub_if_positive' for R10000_LLSC_WAR") and commit4936084c2e
("MIPS: Cleanup R10000_LLSC_WAR logic in atomic.h") causes us to do exactly this in atomic_sub_if_positive(), and the result is MIPS64 daddu instructions in 32-bit kernels. Fix this by using .set mips0 to restore the default ISA after the ll instruction, and use .set MIPS_ISA_LEVEL again prior to the sc. This ensures everything but the ll & sc are assembled using the default ISA for the kernel build & the move pseudo-instruction is emitted as a MIPS32 addu instruction. We appear to have another pre-existing instance of the same issue in our atomic_fetch_*_relaxed() functions, and fix that up too by moving our .set move0 such that it occurs prior to use of the move pseudo-instruction. Signed-off-by: Paul Burton <paul.burton@mips.com> Fixes:a0a5ac3ce8
("MIPS: Fix delay slot bug in `atomic*_sub_if_positive' for R10000_LLSC_WAR") Fixes:4936084c2e
("MIPS: Cleanup R10000_LLSC_WAR logic in atomic.h") Patchwork: https://patchwork.linux-mips.org/patch/20253/ Cc: James Hogan <jhogan@kernel.org> Cc: Joshua Kinard <kumba@gentoo.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org
This commit is contained in:
parent
4bcb4ad663
commit
cfd54de3b0
1 changed files with 3 additions and 1 deletions
|
@ -122,8 +122,8 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
|
|||
" " #asm_op " %0, %1, %3 \n" \
|
||||
" sc %0, %2 \n" \
|
||||
"\t" __scbeqz " %0, 1b \n" \
|
||||
" move %0, %1 \n" \
|
||||
" .set mips0 \n" \
|
||||
" move %0, %1 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
|
@ -190,9 +190,11 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
|||
__asm__ __volatile__(
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
"1: ll %1, %2 # atomic_sub_if_positive\n"
|
||||
" .set mips0 \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" move %1, %0 \n"
|
||||
" bltz %0, 1f \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
" sc %1, %2 \n"
|
||||
"\t" __scbeqz " %1, 1b \n"
|
||||
"1: \n"
|
||||
|
|
Loading…
Reference in a new issue