When building using clang, the constraints for unreachable inline assembly seem to be checked. A result of this is that a CONFIG_32BIT=y build using clang will result in the constraints for inline assembly in __write_64bit_c0_split() being checked even when the caller ultimately used __write_ulong_c0_register() & the 64-bit path will never be taken. This results in build failures like the following: In file included from kernel/fork.c:98: ./arch/mips/include/asm/mmu_context.h:149:19: error: unsupported inline asm: input with type 'unsigned long' matching output with type 'unsigned long long' write_c0_entryhi(cpu_asid(cpu, next)); ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ ./arch/mips/include/asm/mmu_context.h:93:2: note: expanded from macro 'cpu_asid' (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu])) ^ ./arch/mips/include/asm/mipsregs.h:1617:65: note: expanded from macro 'write_c0_entryhi' #define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ ./arch/mips/include/asm/mipsregs.h:1430:39: note: expanded from macro '__write_ulong_c0_register' __write_64bit_c0_register(reg, sel, val); \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ ./arch/mips/include/asm/mipsregs.h:1400:41: note: expanded from macro '__write_64bit_c0_register' __write_64bit_c0_split(register, sel, value); \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~ ./arch/mips/include/asm/mipsregs.h:1498:13: note: expanded from macro '__write_64bit_c0_split' : "r,0" (val)); \ ^~~ This occurs because __write_64bit_c0_split() declares an unsigned long long (ie. 64-bit) __tmp variable for use as an output from the inline assembly, and then attempts to constrain its input to make use of the same registers without caring whether the input is actually of the same width. Avoid the build failure by simply casting the input value to the same unsigned long long type as the output which we want to use the same registers as. On a CONFIG_32BIT=y build this means that for users of __write_ulong_c0_register() we would zero-extend the input value from 32-bit to 64-bit if the path were ever taken, but we know it never will be. For a CONFIG_64BIT=y build the caller should be providing a 64-bit value already causing our cast to be a no-op. Signed-off-by: Paul Burton <paul.burton@xxxxxxxx> Cc: James Hogan <jhogan@xxxxxxxxxx> Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> Cc: linux-mips@xxxxxxxxxxxxxx --- arch/mips/include/asm/mipsregs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index ae461d91cd1f..d8213dca2ab4 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1495,7 +1495,7 @@ do { \ "dmtc0\t%L0, " #source "\n\t" \ ".set\tmips0" \ : "=&r,r" (__tmp) \ - : "r,0" (val)); \ + : "r,0" ((unsigned long long)val)); \ else \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ @@ -1506,7 +1506,7 @@ do { \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ : "=&r,r" (__tmp) \ - : "r,0" (val)); \ + : "r,0" ((unsigned long long)val)); \ local_irq_restore(__flags); \ } while (0) -- 2.18.0