• Josh Poimboeuf's avatar
    x86/asm: Fix inline asm call constraints for Clang · f5caf621
    Josh Poimboeuf authored
    For inline asm statements which have a CALL instruction, we list the
    stack pointer as a constraint to convince GCC to ensure the frame
    pointer is set up first:
      static inline void foo()
    	register void *__sp asm(_ASM_SP);
    	asm("call bar" : "+r" (__sp))
    Unfortunately, that pattern causes Clang to corrupt the stack pointer.
    The fix is easy: convert the stack pointer register variable to a global
    It should be noted that the end result is different based on the GCC
    version.  With GCC 6.4, this patch has exactly the same result as
    	defconfig	defconfig-nofp	distro		distro-nofp
     before	9820389		9491555		8816046		8516940
     after	9820389		9491555		8816046		8516940
    With GCC 7.2, however, GCC's behavior has changed.  It now changes its
    behavior based on the conversion of the register variable to a global.
    That somehow convinces it to *always* set up the frame pointer before
    inserting *any* inline asm.  (Therefore, listing the variable as an
    output constraint is a no-op and is no longer necessary.)  It's a bit
    overkill, but the performance impact should be negligible.  And in fact,
    there's a nice improvement with frame pointers disabled:
    	defconfig	defconfig-nofp	distro		distro-nofp
     before	9796316		9468236		9076191		8790305
     after	9796957		9464267		9076381		8785949
    So in summary, while listing the stack pointer as an output constraint
    is no longer necessary for newer versions of GCC, it's still needed for
    older versions.
    Suggested-by: default avatarAndrey Ryabinin <aryabinin@virtuozzo.com>
    Reported-by: default avatarMatthias Kaehlcke <mka@chromium.org>
    Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
    Cc: Alexander Potapenko <glider@google.com>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Dmitriy Vyukov <dvyukov@google.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Miguel Bernal Marin <miguel.bernal.marin@linux.intel.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/3db862e970c432ae823cf515c52b54fec8270e0e.1505942196.git.jpoimboe@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
preempt.h 3 KB