aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2015-05-28 12:46:49 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-05-29 14:23:58 -0400
commitc4fca4fdea940bda2cff6b844cda6af8ef1c79cc (patch)
treef66a7522cade4d4a883f4597b29f00dd258cdf7a /arch/mips
parent57b41758230b567218cb5bc3da9068aabc496fc9 (diff)
MIPS: strnlen_user.S: Fix a CPU_DADDI_WORKAROUNDS regression
Correct a regression introduced with 8453eebd [MIPS: Fix strnlen_user() return value in case of overlong strings.] causing assembler warnings and broken code generated in __strnlen_kernel_nocheck_asm: arch/mips/lib/strnlen_user.S: Assembler messages: arch/mips/lib/strnlen_user.S:64: Warning: Macro instruction expanded into multiple instructions in a branch delay slot with the CPU_DADDI_WORKAROUNDS option set, resulting in the function looping indefinitely upon mounting NFS root. Use conditional assembly to avoid a microMIPS code size regression. Using $at unconditionally would cause such a regression as there are no 16-bit instruction encodings available for ALU operations using this register. Using $v1 unconditionally would produce short microMIPS encodings, but would prevent this register from being used across calls to this function. The extra LI operation introduced is free, replacing a NOP originally scheduled into the delay slot of the branch that follows. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10205/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/lib/strnlen_user.S15
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index 7d12c0dded3d..77e64942f004 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -34,7 +34,12 @@ LEAF(__strnlen_\func\()_asm)
34FEXPORT(__strnlen_\func\()_nocheck_asm) 34FEXPORT(__strnlen_\func\()_nocheck_asm)
35 move v0, a0 35 move v0, a0
36 PTR_ADDU a1, a0 # stop pointer 36 PTR_ADDU a1, a0 # stop pointer
371: beq v0, a1, 1f # limit reached? 371:
38#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
39 .set noat
40 li AT, 1
41#endif
42 beq v0, a1, 1f # limit reached?
38.ifeqs "\func", "kernel" 43.ifeqs "\func", "kernel"
39 EX(lb, t0, (v0), .Lfault\@) 44 EX(lb, t0, (v0), .Lfault\@)
40.else 45.else
@@ -42,7 +47,13 @@ FEXPORT(__strnlen_\func\()_nocheck_asm)
42.endif 47.endif
43 .set noreorder 48 .set noreorder
44 bnez t0, 1b 49 bnez t0, 1b
451: PTR_ADDIU v0, 1 501:
51#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
52 PTR_ADDIU v0, 1
53#else
54 PTR_ADDU v0, AT
55 .set at
56#endif
46 .set reorder 57 .set reorder
47 PTR_SUBU v0, a0 58 PTR_SUBU v0, a0
48 jr ra 59 jr ra