diff mbox series

MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL

Message ID alpine.DEB.2.21.2110210054080.31442@angie.orcam.me.uk (mailing list archive)
State Superseded
Headers show
Series MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL | expand

Commit Message

Maciej W. Rozycki Oct. 20, 2021, 11:26 p.m. UTC
Fix assembly errors like:

{standard input}: Assembler messages:
{standard input}:287: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32'
{standard input}:680: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32'
{standard input}:1274: Error: opcode not supported on this processor: mips3 (mips3) `dins $12,$9,32,32'
{standard input}:2175: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32'
make[1]: *** [scripts/Makefile.build:277: mm/highmem.o] Error 1

with code produced from `__cmpxchg64' for MIPS64r2 configurations.

This is due to MIPS_ISA_ARCH_LEVEL downgrading the assembly architecture 
to `r4000' for MIPS64r2 configurations while there is a block of code 
containing a DINS MIPS64r2 instruction conditionalized on MIPS_ISA_REV
>= 2 within the scope of the downgrade.

The assembly architecture override is only there for the LLD/SCD 
instructions, so fix the problem by wrapping these instructions on their 
own only, following the practice established with commit cfd54de3b0e4 
("MIPS: Avoid move psuedo-instruction whilst using MIPS_ISA_LEVEL") and 
commit 378ed6f0e3c5 ("MIPS: Avoid using .set mips0 to restore ISA").

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Fixes: c7e2d71dda7a ("MIPS: Fix set_pte() for Netlogic XLR using cmpxchg64()")
Cc: stable@vger.kernel.org # v5.1+
---
 arch/mips/include/asm/cmpxchg.h |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

linux-mips-cmpxchg64-isa-arch-level.diff

Comments

Maciej W. Rozycki Oct. 21, 2021, 10:20 a.m. UTC | #1
On Thu, 21 Oct 2021, Maciej W. Rozycki wrote:

> The assembly architecture override is only there for the LLD/SCD 
> instructions, so fix the problem by wrapping these instructions on their 
> own only, following the practice established with commit cfd54de3b0e4 
> ("MIPS: Avoid move psuedo-instruction whilst using MIPS_ISA_LEVEL") and 
> commit 378ed6f0e3c5 ("MIPS: Avoid using .set mips0 to restore ISA").

 Scrap it!  There's so much accumulated cruft around the handling of LL/SC 
sequences that I forgot what the original intent was.  The whole sequence 
has to be assembled for an explicit 64-bit ISA of course as it's meant to 
work with 32-bit kernels.  The commits referred above are red herrings, 
and should not have been needed in the first place if not for the cruft.

 I don't think I'll get to cleaning up the cruft anytime soon, but I'll 
post v2 tonight to address this specific issue.  Long-term perhaps we can 
make some extraneous hacks (ones to address issues with earlier hacks) go 
away.

  Maciej
diff mbox series

Patch

Index: linux-test/arch/mips/include/asm/cmpxchg.h
===================================================================
--- linux-test.orig/arch/mips/include/asm/cmpxchg.h
+++ linux-test/arch/mips/include/asm/cmpxchg.h
@@ -244,11 +244,12 @@  static inline unsigned long __cmpxchg64(
 	local_irq_save(flags);
 
 	asm volatile(
+	"	" __SYNC(full, loongson3_war) "		\n"
 	"	.set	push				\n"
 	"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"
 	/* Load 64 bits from ptr */
-	"	" __SYNC(full, loongson3_war) "		\n"
 	"1:	lld	%L0, %3		# __cmpxchg64	\n"
+	"	.set	pop				\n"
 	/*
 	 * Split the 64 bit value we loaded into the 2 registers that hold the
 	 * ret variable.
@@ -276,11 +277,13 @@  static inline unsigned long __cmpxchg64(
 	"	or	%L1, %L1, $at			\n"
 	"	.set	at				\n"
 #  endif
+	"	.set	push				\n"
+	"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"
 	/* Attempt to store new at ptr */
 	"	scd	%L1, %2				\n"
+	"	.set	pop				\n"
 	/* If we failed, loop! */
 	"\t" __SC_BEQZ "%L1, 1b				\n"
-	"	.set	pop				\n"
 	"2:	" __SYNC(full, loongson3_war) "		\n"
 	: "=&r"(ret),
 	  "=&r"(tmp),