https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61904
Bug ID: 61904 Summary: Incorrect stack red-zoning on x86-64 code generation Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: torva...@linux-foundation.org gcc-4.9.0 in Debian seems to miscompile the linux kernel for x86-64 in certain configurations, creating accesses to below the stack pointer even though the kernel uses -mno-red-zone. The kernel cannot use the x86-64 stack red-zoning, because the hardware only switches stacks on privilege transfers, so interrupts that happen in kernel mode will not honor the normal 128-byte stack red-zone. Attached is the pre-processed C code of the current kernel file kernel/sched/fair.c which apparently on gcc-4.9.0 will miscompile the function "load_balance()", creating code like this: load_balance: .LFB2408: .loc 2 6487 0 .cfi_startproc .LVL1355: pushq %rbp # .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp #, .cfi_def_cfa_register 6 pushq %r15 # pushq %r14 # pushq %r13 # pushq %r12 # .cfi_offset 15, -24 .cfi_offset 14, -32 .cfi_offset 13, -40 .cfi_offset 12, -48 movq %rdx, %r12 # sd, sd pushq %rbx # .LBB2877: .loc 2 6493 0 movq $load_balance_mask, -136(%rbp) #, %sfp .LBE2877: .loc 2 6487 0 subq $184, %rsp #, .cfi_offset 3, -56 .loc 2 6489 0 .... Note the "subq $184, %rsp" *after* the compiler has already spilled to the stack (the spill is insane, btw, since it's spilling a constant value!) The second attachement is the reported mis-compiled result. I don't personally have the affected gcc version, but you can see the options passed into the compiler in the resulting "fair.s" file. The "-Os" in particular seems to be important, with the bug not happening with "-O2".