Skip to content

Commit 520a13c

Browse files
jpoimboeIngo Molnar
authored andcommitted
x86/asm: Fix inline asm call constraints for GCC 4.4
The kernel test bot (run by Xiaolong Ye) reported that the following commit: f5caf62 ("x86/asm: Fix inline asm call constraints for Clang") is causing double faults in a kernel compiled with GCC 4.4. Linus subsequently diagnosed the crash pattern and the buggy commit and found that the issue is with this code: register unsigned int __asm_call_sp asm("esp"); #define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp) Even on a 64-bit kernel, it's using ESP instead of RSP. That causes GCC to produce the following bogus code: ffffffff8147461d: 89 e0 mov %esp,%eax ffffffff8147461f: 4c 89 f7 mov %r14,%rdi ffffffff81474622: 4c 89 fe mov %r15,%rsi ffffffff81474625: ba 20 00 00 00 mov $0x20,%edx ffffffff8147462a: 89 c4 mov %eax,%esp ffffffff8147462c: e8 bf 52 05 00 callq ffffffff814c98f0 <copy_user_generic_unrolled> Despite the absurdity of it backing up and restoring the stack pointer for no reason, the bug is actually the fact that it's only backing up and restoring the lower 32 bits of the stack pointer. The upper 32 bits are getting cleared out, corrupting the stack pointer. So change the '__asm_call_sp' register variable to be associated with the actual full-size stack pointer. This also requires changing the __ASM_SEL() macro to be based on the actual compiled arch size, rather than the CONFIG value, because CONFIG_X86_64 compiles some files with '-m32' (e.g., realmode and vdso). Otherwise Clang fails to build the kernel because it complains about the use of a 64-bit register (RSP) in a 32-bit file. Reported-and-Bisected-and-Tested-by: kernel test robot <[email protected]> Diagnosed-by: Linus Torvalds <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Cc: Alexander Potapenko <[email protected]> Cc: Andrey Ryabinin <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Dmitriy Vyukov <[email protected]> Cc: LKP <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Matthias Kaehlcke <[email protected]> Cc: Miguel Bernal Marin <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Fixes: f5caf62 ("x86/asm: Fix inline asm call constraints for Clang") Link: http://lkml.kernel.org/r/20170928215826.6sdpmwtkiydiytim@treble Signed-off-by: Ingo Molnar <[email protected]>
1 parent 29b46df commit 520a13c

File tree

1 file changed

+4
-2
lines changed
  • arch/x86/include/asm

1 file changed

+4
-2
lines changed

arch/x86/include/asm/asm.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
# define __ASM_FORM_COMMA(x) " " #x ","
1212
#endif
1313

14-
#ifdef CONFIG_X86_32
14+
#ifndef __x86_64__
15+
/* 32 bit */
1516
# define __ASM_SEL(a,b) __ASM_FORM(a)
1617
# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a)
1718
#else
19+
/* 64 bit */
1820
# define __ASM_SEL(a,b) __ASM_FORM(b)
1921
# define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b)
2022
#endif
@@ -139,7 +141,7 @@
139141
* gets set up by the containing function. If you forget to do this, objtool
140142
* may print a "call without frame pointer save/setup" warning.
141143
*/
142-
register unsigned int __asm_call_sp asm("esp");
144+
register unsigned long __asm_call_sp asm(_ASM_SP);
143145
#define ASM_CALL_CONSTRAINT "+r" (__asm_call_sp)
144146
#endif
145147

0 commit comments

Comments
 (0)