* [PATCH] MIPS: Fix genex.S build with LLVM before 21
@ 2026-11-04 3:01 Tzu-Ching Yang
2026-11-04 8:44 ` Maciej W. Rozycki
0 siblings, 1 reply; 2+ messages in thread
From: Tzu-Ching Yang @ 2026-11-04 3:01 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Maciej W. Rozycki, Marco Crivellari, Frederic Weisbecker,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linux-mips, llvm, linux-kernel, kernel test robot, stable
Since commit 56651128e2fb ("MIPS: Fix idle VS timer enqueue"),
BUILD_SKIPOVER_PROLOGUE uses label differences as the immediates of ORI
and PTR_ADDIU. The LLVM integrated assembler accepts such an immediate
only from LLVM 21 on, so LLVM=1 builds of every MIPS configuration fail
with LLVM 17 to 20 unless LLVM_IAS=0 is set:
<instantiation>:7:11: error: expected an immediate
ori $26, r4k_wait_idle_size - 2
^
<instantiation>:10:14: error: expected an immediate
addiu $26, r4k_wait_exit - r4k_wait_insn + 2
^
Wrap both expressions in %lo(). For that operator, LLVM 17 to 20
emit a LO16 fixup instead of rejecting the operand, and resolve it when
writing the object, since both expressions are constants by then; no
relocation is left. Both values are between 2 and 30, so %lo() does
not change them. GNU as and LLVM 21 to 23 emit the same code as
before, except on microMIPS, where GNU as now uses the 32-bit ADDIU in
the delay slot instead of the 16-bit one. With GCC, the 2 extra bytes
replace the 16-bit NOP that padded the end of the prologue, so all
symbols keep their addresses; with Clang and LLVM_IAS=0, except_vec_vi
and the code after it, up to nmi_handler, move by 4 bytes.
Fixes: 56651128e2fb ("MIPS: Fix idle VS timer enqueue")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202505071331.Z0N2eSkr-lkp@intel.com/
Link: https://github.com/llvm/llvm-project/commit/b65e0947cade9bd39036a7700b54c1df4ec00756
Cc: stable@vger.kernel.org # 6.18.x: 2b6d718c8dbe: MIPS: Fix whitespace damage in r4k_wait from VS timer fix
Cc: stable@vger.kernel.org # 6.18.x
Signed-off-by: Tzu-Ching Yang <shingekinocore@gmail.com>
---
No MIPS hardware here. Against mips-fixes (v7.4-rc1). All builds use
W=1 and kernel.org toolchains.
- genex.o, before and after, with GCC 8.1 to 16.2 and with LLVM 17 to
23, both with the integrated assembler and with LLVM_IAS=0. Configs:
64r6el, 32r6el, 64r2el, 32r2el, eyeq5, eyeq6, malta (little and big
endian, MIPS32r1, microMIPS little and big endian), ip22, ip27,
loongson3 and cavium_octeon.
- The objects are byte-identical before and after with GCC, with
LLVM_IAS=0 and with LLVM 21 to 23. The only exception is the
microMIPS ADDIU above. The 4-byte move with LLVM_IAS=0 is harmless:
set_vi_handler() computes the offsets and the length of the vectored
handler from symbols before copying it, and ejtag_debug_handler and
nmi_handler are only referenced through their symbols.
- LLVM 17 to 20 now assemble genex.o for all of these configs except
microMIPS and Octeon, which the integrated assembler rejects for
other reasons. For malta (little and big endian, MIPS32r1), ip22
and ip27, these objects are byte-identical to the LLVM 21 genex.o.
- vmlinux of 64r2el, 32r2el and malta, built with GCC 8.1 and 16.2,
LLVM 17, 20, 21 and 23, and LLVM 17 with LLVM_IAS=0. Where both sides
build, vmlinux is byte-identical before and after. With LLVM 17 and
20, genex.o was the only object that failed before, and vmlinux links
after. No new warnings.
- The malta kernels built with GCC 8.1 and 16.2, LLVM 17, 20 and 23, and
LLVM 17 with LLVM_IAS=0 boot under QEMU 6.2 -cpu 24Kf. That CPU uses
r4k_wait(), so interrupts go through skipover_handle_int. Each kernel
boots to an init that keeps the CPU going in and out of idle and then
reboots; a QEMU trace shows every interrupt that lands in the idle
region resuming at r4k_wait_exit. A microMIPS kernel does not boot
under QEMU -cpu M14Kc with or without this patch, so the microMIPS
change was not run.
In the 2025 thread [2], Nathan suggested requiring LLVM 21 for MIPS in
min-tool-version.sh, and Maciej an #error for older Clang. Both would
also stop LLVM 17 to 20 builds with LLVM_IAS=0, which work today, and
the stable trees would need the same change before 56651128e2fb could
go back to them.
On 6.18.y, which also allows LLVM 15 and 16, the patch applies after
2b6d718c8dbe, and LLVM 15 and 16 fail and are fixed the same way.
The 56651128e2fb backport was dropped from the 6.14, 6.12 and 6.6
stable queues because of this build failure [1], so 6.12.y and 6.6.y
still lack that fix.
[1] https://lore.kernel.org/r/2025051415-unloader-likely-b0e6@gregkh/
[2] https://lore.kernel.org/r/20250521224450.GA2412476@ax162/
arch/mips/kernel/genex.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index be1b049d856f..ef27965f6ad9 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -146,10 +146,10 @@ r4k_wait_exit:
MFC0 k0, CP0_EPC
/* Subtract/add 2 to let the ISA bit propagate through the mask. */
PTR_LA k1, r4k_wait_insn - 2
- ori k0, r4k_wait_idle_size - 2
+ ori k0, %lo(r4k_wait_idle_size - 2) /* %lo() for LLVM < 21 */
.set noreorder
bne k0, k1, \handler
- PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2
+ PTR_ADDIU k0, %lo(r4k_wait_exit - r4k_wait_insn + 2) /* ditto */
.set reorder
MTC0 k0, CP0_EPC
.set pop
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] MIPS: Fix genex.S build with LLVM before 21
2026-11-04 3:01 [PATCH] MIPS: Fix genex.S build with LLVM before 21 Tzu-Ching Yang
@ 2026-11-04 8:44 ` Maciej W. Rozycki
0 siblings, 0 replies; 2+ messages in thread
From: Maciej W. Rozycki @ 2026-11-04 8:44 UTC (permalink / raw)
To: Tzu-Ching Yang
Cc: Thomas Bogendoerfer, Marco Crivellari, Frederic Weisbecker,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
linux-mips, llvm, linux-kernel, kernel test robot, stable
On Wed, 4 Nov 2026, Tzu-Ching Yang wrote:
> Wrap both expressions in %lo(). For that operator, LLVM 17 to 20
> emit a LO16 fixup instead of rejecting the operand, and resolve it when
> writing the object, since both expressions are constants by then; no
> relocation is left. Both values are between 2 and 30, so %lo() does
> not change them.
Seems fair.
> - The objects are byte-identical before and after with GCC, with
> LLVM_IAS=0 and with LLVM 21 to 23. The only exception is the
> microMIPS ADDIU above. The 4-byte move with LLVM_IAS=0 is harmless:
> set_vi_handler() computes the offsets and the length of the vectored
> handler from symbols before copying it, and ejtag_debug_handler and
> nmi_handler are only referenced through their symbols.
I would be tempted to accept the GAS microMIPS code size regression as a
missed optimisation. This is a general issue with forward references and
%lo() calculation is only one example: we're missing microMIPS relaxation
for 16-bit vs 32-bit instruction encodings, except for branches. We only
do it for MIPS16 code.
> - The malta kernels built with GCC 8.1 and 16.2, LLVM 17, 20 and 23, and
> LLVM 17 with LLVM_IAS=0 boot under QEMU 6.2 -cpu 24Kf. That CPU uses
> r4k_wait(), so interrupts go through skipover_handle_int. Each kernel
> boots to an init that keeps the CPU going in and out of idle and then
> reboots; a QEMU trace shows every interrupt that lands in the idle
> region resuming at r4k_wait_exit. A microMIPS kernel does not boot
> under QEMU -cpu M14Kc with or without this patch, so the microMIPS
> change was not run.
I wouldn't be surprised with a microMIPS kernel not booting. Support was
messy right from the beginning and despite my opposition it was merged as
it stood. Maybe one of the fragile assumptions broke here or there. Or
it could be a QEMU emulation bug too; it doesn't seem too stable compared
to actual hardware, microMIPS or not. I could try bisecting it sometime
as I do have an otherwise working microMIPS QEMU setup; sadly no actual
microMIPS hardware.
> On 6.18.y, which also allows LLVM 15 and 16, the patch applies after
> 2b6d718c8dbe, and LLVM 15 and 16 fail and are fixed the same way.
>
> The 56651128e2fb backport was dropped from the 6.14, 6.12 and 6.6
> stable queues because of this build failure [1], so 6.12.y and 6.6.y
> still lack that fix.
Shouldn't this use:
Cc: <stable@vger.kernel.org> # 6.6.x: 56651128e2fb: MIPS: Fix idle VS timer enqueue
Cc: <stable@vger.kernel.org> # 6.6.x: 2b6d718c8dbe: MIPS: Fix whitespace damage in r4k_wait from VS timer fix
Cc: <stable@vger.kernel.org> # 6.6.x
then to get this all picked up? Or is it unsupported annotation syntax
where a prerequisite matches a Fixes: tag?
Maciej
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-04 8:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 3:01 [PATCH] MIPS: Fix genex.S build with LLVM before 21 Tzu-Ching Yang
2026-11-04 8:44 ` Maciej W. Rozycki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®