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
ku...@gentoo.org
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

Reply via email to