Hi,
I am trying to use gcc-6.3.0 to cross-compile a kernel for an old mips64
platform, an SGI Onyx2 ("IP27"), however, it looks like a large number of
functions within the compiled code are getting a common instruction emitted at
the top of the function that breaks this particular machine.
Doing a disassembly of the kernel binary, this is what the beginning of several
functions looks like:
a80000000001c400 <run_init_process>:
a80000000001c400: ffa0bff0 sd zero,-16400(sp)
a80000000001c404: 67bdfff0 daddiu sp,sp,-16
a80000000001cea0 <ip27_be_handler>:
a80000000001cea0: ffa0bfe0 sd zero,-16416(sp)
a80000000001cea4: 67bdffe0 daddiu sp,sp,-32
a80000000001c5b0 <name_to_dev_t>:
a80000000001c5b0: ffa0bf90 sd zero,-16496(sp)
a80000000001c5b4: 3c05a800 lui a1,0xa800
a80000000001c5b8: 3c020074 lui v0,0x74
a80000000001c5bc: 64a50000 daddiu a1,a1,0
a80000000001c5c0: 64424840 daddiu v0,v0,18496
a80000000001c5c4: 0005283c dsll32 a1,a1,0x0
a80000000001c5c8: 67bdff90 daddiu sp,sp,-112
If I compare this output against the disassembly of the same kernel tree built
with gcc-5.4.0, I see this:
a80000000001c400 <run_init_process>:
a80000000001c400: 67bdfff0 daddiu sp,sp,-16
a80000000001c404: 3c02007b lui v0,0x7b
a80000000001cec0 <ip27_be_handler>:
a80000000001cec0: 67bdffe0 daddiu sp,sp,-32
a80000000001cec4: ffb00000 sd s0,0(sp)
a80000000001c5a0 <name_to_dev_t>:
a80000000001c5a0: 3c05a800 lui a1,0xa800
a80000000001c5a4: 3c020075 lui v0,0x75
a80000000001c5a8: 64a50000 daddiu a1,a1,0
a80000000001c5ac: 64423f40 daddiu v0,v0,16192
a80000000001c5b0: 0005283c dsll32 a1,a1,0x0
a80000000001c5b4: 67bdff90 daddiu sp,sp,-112
I am not sure what this lone store-doubleword instruction is exactly doing, nor
can I locate where in the gcc MIPS code it is being generated from. On the
IP27 platform, it breaks the '_raw_spin_lock_irq' function, which is a
hard-coded block of assembly code in the kernel at
arch/mips/include/asm/spinlock.h, taking the 'else' branch of the if clause:
https://git.linux-mips.org/cgit/ralf/linux.git/tree/arch/mips/include/asm/spinlock.h
This "sd" instruction triggers an attempted NULL pointer dereference attempt
when processing the load-linked instruction at the top of the assembly, which
crashes the kernel early in the boot process (after checking for the 'daddi'
bug).
I have another SGI platform, an Octane ("IP30") that is architecturally-similar
to an IP27, and it is unaffected by the presence of this instruction. IP27 is
a NUMA system, however, while IP30 is not. I am suspecting this contributes to
the issues.
However, I need to know what this "sd" instruction's purpose at the beginning
of each function is, and where in gcc's source it's located so I can see if
this is something fixable within the Linux kernel in the IP27-specific code, or
if it's a code-generation bug.
Thanks!,
--
Joshua Kinard
Gentoo/MIPS
[email protected]
6144R/F5C6C943 2015-04-27
177C 1972 1FB8 F254 BAD0 3E72 5C63 F4E3 F5C6 C943
"The past tempts us, the present confuses us, the future frightens us. And our
lives slip away, moment by moment, lost in that vast, terrible in-between."
--Emperor Turhan, Centauri Republic