Re: [PATCH] kbuild, x86: revert macros in extended asm workarounds

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 13, 2018 at 10:19 AM Masahiro Yamada
<yamada.masahiro@xxxxxxxxxxxxx> wrote:
>
> Revert the following commits:
>
> - 5bdcd510c2ac9efaf55c4cbd8d46421d8e2320cd
>   ("x86/jump-labels: Macrofy inline assembly code to work around GCC inlining bugs")
>
> - d5a581d84ae6b8a4a740464b80d8d9cf1e7947b2
>   ("x86/cpufeature: Macrofy inline assembly code to work around GCC inlining bugs")
>
> - 0474d5d9d2f7f3b11262f7bf87d0e7314ead9200.
>   ("x86/extable: Macrofy inline assembly code to work around GCC inlining bugs")
>
> - 494b5168f2de009eb80f198f668da374295098dd.
>   ("x86/paravirt: Work around GCC inlining bugs when compiling paravirt ops")
>
> - f81f8ad56fd1c7b99b2ed1c314527f7d9ac447c6.
>   ("x86/bug: Macrofy the BUG table section handling, to work around GCC inlining bugs")
>
> - 77f48ec28e4ccff94d2e5f4260a83ac27a7f3099.
>   ("x86/alternatives: Macrofy lock prefixes to work around GCC inlining bugs")
>
> - 9e1725b410594911cc5981b6c7b4cea4ec054ca8.
>   ("x86/refcount: Work around GCC inlining bug")
>   (Conflicts: arch/x86/include/asm/refcount.h)
>
> - c06c4d8090513f2974dfdbed2ac98634357ac475.
>   ("x86/objtool: Use asm macros to work around GCC inlining bugs")
>
> - 77b0bf55bc675233d22cd5df97605d516d64525e.
>   ("kbuild/Makefile: Prepare for using macros in inline assembly code to work around asm() related GCC inlining bugs")
>
> A few days after those commits applied, discussion started to solve
> the issue more elegantly on the compiler side:
>
>   https://lkml.org/lkml/2018/10/7/92
>
> The "asm inline" was implemented by Segher Boessenkool, and now queued
> up for GCC 9. (People were positive even for back-porting it to older
> compilers).
>
> Since the in-kernel workarounds merged, some issues have been reported:
> breakage of building with distcc/icecc, breakage of distro packages for
> module building. (More fundamentally, we cannot build external modules
> after 'make clean')
>
> Patching around the build system would make the code even uglier.
>
> Given that this issue will be solved in a cleaner way sooner or later,
> let's revert the in-kernel workarounds, and wait for GCC 9.
>
> Reported-by: Logan Gunthorpe <logang@xxxxxxxxxxxx> # distcc
> Reported-by: Sedat Dilek <sedat.dilek@xxxxxxxxx> # debian/rpm package

Hi,

I reported the issue with debian package breakage in [1].

I am not subscribed to any involved mailing-list and not following all
the discussions.
I see the situation is not easy as there is especially linux-kbuild
and linux/x86 involved and maybe other interests.
But I am interested in having a fix in v4.20 final and hope this all
still works with LLVM/Clang.

I can offer my help in testing - against Linux v4.20-rc7.
Not sure if all discussed material is in upstream or elsewhere.
What is your suggestion for me as a tester?

Will we have a solution in Linux v4.20 final?

Thanks.

With my best wishes,
- Sedat -

[1] https://marc.info/?t=154212770600037&r=1&w=2

> Signed-off-by: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx>
> Cc: Nadav Amit <namit@xxxxxxxxxx>
> Cc: Segher Boessenkool <segher@xxxxxxxxxxxxxxxxxxx>
> ---
>
> Please consider this for v4.20 release.
> Currently, distro package build is broken.
>
>
>  Makefile                               |  9 +---
>  arch/x86/Makefile                      |  7 ---
>  arch/x86/entry/calling.h               |  2 +-
>  arch/x86/include/asm/alternative-asm.h | 20 +++----
>  arch/x86/include/asm/alternative.h     | 11 +++-
>  arch/x86/include/asm/asm.h             | 53 +++++++++++-------
>  arch/x86/include/asm/bug.h             | 98 +++++++++++++++-------------------
>  arch/x86/include/asm/cpufeature.h      | 82 ++++++++++++----------------
>  arch/x86/include/asm/jump_label.h      | 72 ++++++++++++++++++-------
>  arch/x86/include/asm/paravirt_types.h  | 56 +++++++++----------
>  arch/x86/include/asm/refcount.h        | 81 ++++++++++++----------------
>  arch/x86/kernel/macros.S               | 16 ------
>  include/asm-generic/bug.h              |  8 +--
>  include/linux/compiler.h               | 56 +++++--------------
>  scripts/Kbuild.include                 |  4 +-
>  scripts/mod/Makefile                   |  2 -
>  16 files changed, 262 insertions(+), 315 deletions(-)
>  delete mode 100644 arch/x86/kernel/macros.S
>
> diff --git a/Makefile b/Makefile
> index f2c3423..4cf4c5b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1081,7 +1081,7 @@ scripts: scripts_basic scripts_dtc asm-generic gcc-plugins $(autoksyms_h)
>  # version.h and scripts_basic is processed / created.
>
>  # Listed in dependency order
> -PHONY += prepare archprepare macroprepare prepare0 prepare1 prepare2 prepare3
> +PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
>
>  # prepare3 is used to check if we are building in a separate output directory,
>  # and if so do:
> @@ -1104,9 +1104,7 @@ prepare2: prepare3 outputmakefile asm-generic
>  prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h
>         $(cmd_crmodverdir)
>
> -macroprepare: prepare1 archmacros
> -
> -archprepare: archheaders archscripts macroprepare scripts_basic
> +archprepare: archheaders archscripts prepare1 scripts_basic
>
>  prepare0: archprepare gcc-plugins
>         $(Q)$(MAKE) $(build)=.
> @@ -1174,9 +1172,6 @@ archheaders:
>  PHONY += archscripts
>  archscripts:
>
> -PHONY += archmacros
> -archmacros:
> -
>  PHONY += __headers
>  __headers: $(version_h) scripts_basic uapi-asm-generic archheaders archscripts
>         $(Q)$(MAKE) $(build)=scripts build_unifdef
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 75ef499..85a66c4 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -232,13 +232,6 @@ archscripts: scripts_basic
>  archheaders:
>         $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
>
> -archmacros:
> -       $(Q)$(MAKE) $(build)=arch/x86/kernel arch/x86/kernel/macros.s
> -
> -ASM_MACRO_FLAGS = -Wa,arch/x86/kernel/macros.s
> -export ASM_MACRO_FLAGS
> -KBUILD_CFLAGS += $(ASM_MACRO_FLAGS)
> -
>  ###
>  # Kernel objects
>
> diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
> index 25e5a6b..20d0885 100644
> --- a/arch/x86/entry/calling.h
> +++ b/arch/x86/entry/calling.h
> @@ -352,7 +352,7 @@ For 32-bit we have the following conventions - kernel is built with
>  .macro CALL_enter_from_user_mode
>  #ifdef CONFIG_CONTEXT_TRACKING
>  #ifdef HAVE_JUMP_LABEL
> -       STATIC_BRANCH_JMP l_yes=.Lafter_call_\@, key=context_tracking_enabled, branch=1
> +       STATIC_JUMP_IF_FALSE .Lafter_call_\@, context_tracking_enabled, def=0
>  #endif
>         call enter_from_user_mode
>  .Lafter_call_\@:
> diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h
> index 8e4ea39..31b627b 100644
> --- a/arch/x86/include/asm/alternative-asm.h
> +++ b/arch/x86/include/asm/alternative-asm.h
> @@ -7,24 +7,16 @@
>  #include <asm/asm.h>
>
>  #ifdef CONFIG_SMP
> -.macro LOCK_PREFIX_HERE
> +       .macro LOCK_PREFIX
> +672:   lock
>         .pushsection .smp_locks,"a"
>         .balign 4
> -       .long 671f - .          # offset
> +       .long 672b - .
>         .popsection
> -671:
> -.endm
> -
> -.macro LOCK_PREFIX insn:vararg
> -       LOCK_PREFIX_HERE
> -       lock \insn
> -.endm
> +       .endm
>  #else
> -.macro LOCK_PREFIX_HERE
> -.endm
> -
> -.macro LOCK_PREFIX insn:vararg
> -.endm
> +       .macro LOCK_PREFIX
> +       .endm
>  #endif
>
>  /*
> diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
> index d7faa16..4cd6a3b 100644
> --- a/arch/x86/include/asm/alternative.h
> +++ b/arch/x86/include/asm/alternative.h
> @@ -31,8 +31,15 @@
>   */
>
>  #ifdef CONFIG_SMP
> -#define LOCK_PREFIX_HERE "LOCK_PREFIX_HERE\n\t"
> -#define LOCK_PREFIX "LOCK_PREFIX "
> +#define LOCK_PREFIX_HERE \
> +               ".pushsection .smp_locks,\"a\"\n"       \
> +               ".balign 4\n"                           \
> +               ".long 671f - .\n" /* offset */         \
> +               ".popsection\n"                         \
> +               "671:"
> +
> +#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "
> +
>  #else /* ! CONFIG_SMP */
>  #define LOCK_PREFIX_HERE ""
>  #define LOCK_PREFIX ""
> diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
> index 21b0867..6467757b 100644
> --- a/arch/x86/include/asm/asm.h
> +++ b/arch/x86/include/asm/asm.h
> @@ -120,25 +120,12 @@
>  /* Exception table entry */
>  #ifdef __ASSEMBLY__
>  # define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
> -       ASM_EXTABLE_HANDLE from to handler
> -
> -.macro ASM_EXTABLE_HANDLE from:req to:req handler:req
> -       .pushsection "__ex_table","a"
> -       .balign 4
> -       .long (\from) - .
> -       .long (\to) - .
> -       .long (\handler) - .
> +       .pushsection "__ex_table","a" ;                         \
> +       .balign 4 ;                                             \
> +       .long (from) - . ;                                      \
> +       .long (to) - . ;                                        \
> +       .long (handler) - . ;                                   \
>         .popsection
> -.endm
> -#else /* __ASSEMBLY__ */
> -
> -# define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
> -       "ASM_EXTABLE_HANDLE from=" #from " to=" #to             \
> -       " handler=\"" #handler "\"\n\t"
> -
> -/* For C file, we already have NOKPROBE_SYMBOL macro */
> -
> -#endif /* __ASSEMBLY__ */
>
>  # define _ASM_EXTABLE(from, to)                                        \
>         _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
> @@ -161,7 +148,6 @@
>         _ASM_PTR (entry);                                       \
>         .popsection
>
> -#ifdef __ASSEMBLY__
>  .macro ALIGN_DESTINATION
>         /* check for bad alignment of destination */
>         movl %edi,%ecx
> @@ -185,7 +171,34 @@
>         _ASM_EXTABLE_UA(100b, 103b)
>         _ASM_EXTABLE_UA(101b, 103b)
>         .endm
> -#endif /* __ASSEMBLY__ */
> +
> +#else
> +# define _EXPAND_EXTABLE_HANDLE(x) #x
> +# define _ASM_EXTABLE_HANDLE(from, to, handler)                        \
> +       " .pushsection \"__ex_table\",\"a\"\n"                  \
> +       " .balign 4\n"                                          \
> +       " .long (" #from ") - .\n"                              \
> +       " .long (" #to ") - .\n"                                \
> +       " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n"    \
> +       " .popsection\n"
> +
> +# define _ASM_EXTABLE(from, to)                                        \
> +       _ASM_EXTABLE_HANDLE(from, to, ex_handler_default)
> +
> +# define _ASM_EXTABLE_UA(from, to)                             \
> +       _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess)
> +
> +# define _ASM_EXTABLE_FAULT(from, to)                          \
> +       _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault)
> +
> +# define _ASM_EXTABLE_EX(from, to)                             \
> +       _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext)
> +
> +# define _ASM_EXTABLE_REFCOUNT(from, to)                       \
> +       _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount)
> +
> +/* For C file, we already have NOKPROBE_SYMBOL macro */
> +#endif
>
>  #ifndef __ASSEMBLY__
>  /*
> diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
> index 5090035..6804d66 100644
> --- a/arch/x86/include/asm/bug.h
> +++ b/arch/x86/include/asm/bug.h
> @@ -4,8 +4,6 @@
>
>  #include <linux/stringify.h>
>
> -#ifndef __ASSEMBLY__
> -
>  /*
>   * Despite that some emulators terminate on UD2, we use it for WARN().
>   *
> @@ -22,15 +20,53 @@
>
>  #define LEN_UD2                2
>
> +#ifdef CONFIG_GENERIC_BUG
> +
> +#ifdef CONFIG_X86_32
> +# define __BUG_REL(val)        ".long " __stringify(val)
> +#else
> +# define __BUG_REL(val)        ".long " __stringify(val) " - 2b"
> +#endif
> +
> +#ifdef CONFIG_DEBUG_BUGVERBOSE
> +
> +#define _BUG_FLAGS(ins, flags)                                         \
> +do {                                                                   \
> +       asm volatile("1:\t" ins "\n"                                    \
> +                    ".pushsection __bug_table,\"aw\"\n"                \
> +                    "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
> +                    "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"       \
> +                    "\t.word %c1"        "\t# bug_entry::line\n"       \
> +                    "\t.word %c2"        "\t# bug_entry::flags\n"      \
> +                    "\t.org 2b+%c3\n"                                  \
> +                    ".popsection"                                      \
> +                    : : "i" (__FILE__), "i" (__LINE__),                \
> +                        "i" (flags),                                   \
> +                        "i" (sizeof(struct bug_entry)));               \
> +} while (0)
> +
> +#else /* !CONFIG_DEBUG_BUGVERBOSE */
> +
>  #define _BUG_FLAGS(ins, flags)                                         \
>  do {                                                                   \
> -       asm volatile("ASM_BUG ins=\"" ins "\" file=%c0 line=%c1 "       \
> -                    "flags=%c2 size=%c3"                               \
> -                    : : "i" (__FILE__), "i" (__LINE__),                \
> -                        "i" (flags),                                   \
> +       asm volatile("1:\t" ins "\n"                                    \
> +                    ".pushsection __bug_table,\"aw\"\n"                \
> +                    "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
> +                    "\t.word %c0"        "\t# bug_entry::flags\n"      \
> +                    "\t.org 2b+%c1\n"                                  \
> +                    ".popsection"                                      \
> +                    : : "i" (flags),                                   \
>                          "i" (sizeof(struct bug_entry)));               \
>  } while (0)
>
> +#endif /* CONFIG_DEBUG_BUGVERBOSE */
> +
> +#else
> +
> +#define _BUG_FLAGS(ins, flags)  asm volatile(ins)
> +
> +#endif /* CONFIG_GENERIC_BUG */
> +
>  #define HAVE_ARCH_BUG
>  #define BUG()                                                  \
>  do {                                                           \
> @@ -46,54 +82,4 @@ do {                                                         \
>
>  #include <asm-generic/bug.h>
>
> -#else /* __ASSEMBLY__ */
> -
> -#ifdef CONFIG_GENERIC_BUG
> -
> -#ifdef CONFIG_X86_32
> -.macro __BUG_REL val:req
> -       .long \val
> -.endm
> -#else
> -.macro __BUG_REL val:req
> -       .long \val - 2b
> -.endm
> -#endif
> -
> -#ifdef CONFIG_DEBUG_BUGVERBOSE
> -
> -.macro ASM_BUG ins:req file:req line:req flags:req size:req
> -1:     \ins
> -       .pushsection __bug_table,"aw"
> -2:     __BUG_REL val=1b        # bug_entry::bug_addr
> -       __BUG_REL val=\file     # bug_entry::file
> -       .word \line             # bug_entry::line
> -       .word \flags            # bug_entry::flags
> -       .org 2b+\size
> -       .popsection
> -.endm
> -
> -#else /* !CONFIG_DEBUG_BUGVERBOSE */
> -
> -.macro ASM_BUG ins:req file:req line:req flags:req size:req
> -1:     \ins
> -       .pushsection __bug_table,"aw"
> -2:     __BUG_REL val=1b        # bug_entry::bug_addr
> -       .word \flags            # bug_entry::flags
> -       .org 2b+\size
> -       .popsection
> -.endm
> -
> -#endif /* CONFIG_DEBUG_BUGVERBOSE */
> -
> -#else /* CONFIG_GENERIC_BUG */
> -
> -.macro ASM_BUG ins:req file:req line:req flags:req size:req
> -       \ins
> -.endm
> -
> -#endif /* CONFIG_GENERIC_BUG */
> -
> -#endif /* __ASSEMBLY__ */
> -
>  #endif /* _ASM_X86_BUG_H */
> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
> index 7d44272..aced6c9 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -2,10 +2,10 @@
>  #ifndef _ASM_X86_CPUFEATURE_H
>  #define _ASM_X86_CPUFEATURE_H
>
> -#ifdef __KERNEL__
> -#ifndef __ASSEMBLY__
> -
>  #include <asm/processor.h>
> +
> +#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
> +
>  #include <asm/asm.h>
>  #include <linux/bitops.h>
>
> @@ -161,10 +161,37 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
>   */
>  static __always_inline __pure bool _static_cpu_has(u16 bit)
>  {
> -       asm_volatile_goto("STATIC_CPU_HAS bitnum=%[bitnum] "
> -                         "cap_byte=\"%[cap_byte]\" "
> -                         "feature=%P[feature] t_yes=%l[t_yes] "
> -                         "t_no=%l[t_no] always=%P[always]"
> +       asm_volatile_goto("1: jmp 6f\n"
> +                "2:\n"
> +                ".skip -(((5f-4f) - (2b-1b)) > 0) * "
> +                        "((5f-4f) - (2b-1b)),0x90\n"
> +                "3:\n"
> +                ".section .altinstructions,\"a\"\n"
> +                " .long 1b - .\n"              /* src offset */
> +                " .long 4f - .\n"              /* repl offset */
> +                " .word %P[always]\n"          /* always replace */
> +                " .byte 3b - 1b\n"             /* src len */
> +                " .byte 5f - 4f\n"             /* repl len */
> +                " .byte 3b - 2b\n"             /* pad len */
> +                ".previous\n"
> +                ".section .altinstr_replacement,\"ax\"\n"
> +                "4: jmp %l[t_no]\n"
> +                "5:\n"
> +                ".previous\n"
> +                ".section .altinstructions,\"a\"\n"
> +                " .long 1b - .\n"              /* src offset */
> +                " .long 0\n"                   /* no replacement */
> +                " .word %P[feature]\n"         /* feature bit */
> +                " .byte 3b - 1b\n"             /* src len */
> +                " .byte 0\n"                   /* repl len */
> +                " .byte 0\n"                   /* pad len */
> +                ".previous\n"
> +                ".section .altinstr_aux,\"ax\"\n"
> +                "6:\n"
> +                " testb %[bitnum],%[cap_byte]\n"
> +                " jnz %l[t_yes]\n"
> +                " jmp %l[t_no]\n"
> +                ".previous\n"
>                  : : [feature]  "i" (bit),
>                      [always]   "i" (X86_FEATURE_ALWAYS),
>                      [bitnum]   "i" (1 << (bit & 7)),
> @@ -199,44 +226,5 @@ static __always_inline __pure bool _static_cpu_has(u16 bit)
>  #define CPU_FEATURE_TYPEVAL            boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
>                                         boot_cpu_data.x86_model
>
> -#else /* __ASSEMBLY__ */
> -
> -.macro STATIC_CPU_HAS bitnum:req cap_byte:req feature:req t_yes:req t_no:req always:req
> -1:
> -       jmp 6f
> -2:
> -       .skip -(((5f-4f) - (2b-1b)) > 0) * ((5f-4f) - (2b-1b)),0x90
> -3:
> -       .section .altinstructions,"a"
> -       .long 1b - .            /* src offset */
> -       .long 4f - .            /* repl offset */
> -       .word \always           /* always replace */
> -       .byte 3b - 1b           /* src len */
> -       .byte 5f - 4f           /* repl len */
> -       .byte 3b - 2b           /* pad len */
> -       .previous
> -       .section .altinstr_replacement,"ax"
> -4:
> -       jmp \t_no
> -5:
> -       .previous
> -       .section .altinstructions,"a"
> -       .long 1b - .            /* src offset */
> -       .long 0                 /* no replacement */
> -       .word \feature          /* feature bit */
> -       .byte 3b - 1b           /* src len */
> -       .byte 0                 /* repl len */
> -       .byte 0                 /* pad len */
> -       .previous
> -       .section .altinstr_aux,"ax"
> -6:
> -       testb \bitnum,\cap_byte
> -       jnz \t_yes
> -       jmp \t_no
> -       .previous
> -.endm
> -
> -#endif /* __ASSEMBLY__ */
> -
> -#endif /* __KERNEL__ */
> +#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
>  #endif /* _ASM_X86_CPUFEATURE_H */
> diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
> index a5fb34f..21efc9d 100644
> --- a/arch/x86/include/asm/jump_label.h
> +++ b/arch/x86/include/asm/jump_label.h
> @@ -2,6 +2,19 @@
>  #ifndef _ASM_X86_JUMP_LABEL_H
>  #define _ASM_X86_JUMP_LABEL_H
>
> +#ifndef HAVE_JUMP_LABEL
> +/*
> + * For better or for worse, if jump labels (the gcc extension) are missing,
> + * then the entire static branch patching infrastructure is compiled out.
> + * If that happens, the code in here will malfunction.  Raise a compiler
> + * error instead.
> + *
> + * In theory, jump labels and the static branch patching infrastructure
> + * could be decoupled to fix this.
> + */
> +#error asm/jump_label.h included on a non-jump-label kernel
> +#endif
> +
>  #define JUMP_LABEL_NOP_SIZE 5
>
>  #ifdef CONFIG_X86_64
> @@ -20,9 +33,15 @@
>
>  static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
>  {
> -       asm_volatile_goto("STATIC_BRANCH_NOP l_yes=\"%l[l_yes]\" key=\"%c0\" "
> -                         "branch=\"%c1\""
> -                       : :  "i" (key), "i" (branch) : : l_yes);
> +       asm_volatile_goto("1:"
> +               ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t"
> +               ".pushsection __jump_table,  \"aw\" \n\t"
> +               _ASM_ALIGN "\n\t"
> +               ".long 1b - ., %l[l_yes] - . \n\t"
> +               _ASM_PTR "%c0 + %c1 - .\n\t"
> +               ".popsection \n\t"
> +               : :  "i" (key), "i" (branch) : : l_yes);
> +
>         return false;
>  l_yes:
>         return true;
> @@ -30,8 +49,14 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
>
>  static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
>  {
> -       asm_volatile_goto("STATIC_BRANCH_JMP l_yes=\"%l[l_yes]\" key=\"%c0\" "
> -                         "branch=\"%c1\""
> +       asm_volatile_goto("1:"
> +               ".byte 0xe9\n\t .long %l[l_yes] - 2f\n\t"
> +               "2:\n\t"
> +               ".pushsection __jump_table,  \"aw\" \n\t"
> +               _ASM_ALIGN "\n\t"
> +               ".long 1b - ., %l[l_yes] - . \n\t"
> +               _ASM_PTR "%c0 + %c1 - .\n\t"
> +               ".popsection \n\t"
>                 : :  "i" (key), "i" (branch) : : l_yes);
>
>         return false;
> @@ -41,26 +66,37 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
>
>  #else  /* __ASSEMBLY__ */
>
> -.macro STATIC_BRANCH_NOP l_yes:req key:req branch:req
> -.Lstatic_branch_nop_\@:
> -       .byte STATIC_KEY_INIT_NOP
> -.Lstatic_branch_no_after_\@:
> +.macro STATIC_JUMP_IF_TRUE target, key, def
> +.Lstatic_jump_\@:
> +       .if \def
> +       /* Equivalent to "jmp.d32 \target" */
> +       .byte           0xe9
> +       .long           \target - .Lstatic_jump_after_\@
> +.Lstatic_jump_after_\@:
> +       .else
> +       .byte           STATIC_KEY_INIT_NOP
> +       .endif
>         .pushsection __jump_table, "aw"
>         _ASM_ALIGN
> -       .long           .Lstatic_branch_nop_\@ - ., \l_yes - .
> -       _ASM_PTR        \key + \branch - .
> +       .long           .Lstatic_jump_\@ - ., \target - .
> +       _ASM_PTR        \key - .
>         .popsection
>  .endm
>
> -.macro STATIC_BRANCH_JMP l_yes:req key:req branch:req
> -.Lstatic_branch_jmp_\@:
> -       .byte 0xe9
> -       .long \l_yes - .Lstatic_branch_jmp_after_\@
> -.Lstatic_branch_jmp_after_\@:
> +.macro STATIC_JUMP_IF_FALSE target, key, def
> +.Lstatic_jump_\@:
> +       .if \def
> +       .byte           STATIC_KEY_INIT_NOP
> +       .else
> +       /* Equivalent to "jmp.d32 \target" */
> +       .byte           0xe9
> +       .long           \target - .Lstatic_jump_after_\@
> +.Lstatic_jump_after_\@:
> +       .endif
>         .pushsection __jump_table, "aw"
>         _ASM_ALIGN
> -       .long           .Lstatic_branch_jmp_\@ - ., \l_yes - .
> -       _ASM_PTR        \key + \branch - .
> +       .long           .Lstatic_jump_\@ - ., \target - .
> +       _ASM_PTR        \key + 1 - .
>         .popsection
>  .endm
>
> diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
> index 26942ad..488c596 100644
> --- a/arch/x86/include/asm/paravirt_types.h
> +++ b/arch/x86/include/asm/paravirt_types.h
> @@ -348,11 +348,23 @@ extern struct paravirt_patch_template pv_ops;
>  #define paravirt_clobber(clobber)              \
>         [paravirt_clobber] "i" (clobber)
>
> +/*
> + * Generate some code, and mark it as patchable by the
> + * apply_paravirt() alternate instruction patcher.
> + */
> +#define _paravirt_alt(insn_string, type, clobber)      \
> +       "771:\n\t" insn_string "\n" "772:\n"            \
> +       ".pushsection .parainstructions,\"a\"\n"        \
> +       _ASM_ALIGN "\n"                                 \
> +       _ASM_PTR " 771b\n"                              \
> +       "  .byte " type "\n"                            \
> +       "  .byte 772b-771b\n"                           \
> +       "  .short " clobber "\n"                        \
> +       ".popsection\n"
> +
>  /* Generate patchable code, with the default asm parameters. */
> -#define paravirt_call                                                  \
> -       "PARAVIRT_CALL type=\"%c[paravirt_typenum]\""                   \
> -       " clobber=\"%c[paravirt_clobber]\""                             \
> -       " pv_opptr=\"%c[paravirt_opptr]\";"
> +#define paravirt_alt(insn_string)                                      \
> +       _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
>
>  /* Simple instruction patching code. */
>  #define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t"
> @@ -373,6 +385,16 @@ unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len);
>  int paravirt_disable_iospace(void);
>
>  /*
> + * This generates an indirect call based on the operation type number.
> + * The type number, computed in PARAVIRT_PATCH, is derived from the
> + * offset into the paravirt_patch_template structure, and can therefore be
> + * freely converted back into a structure offset.
> + */
> +#define PARAVIRT_CALL                                  \
> +       ANNOTATE_RETPOLINE_SAFE                         \
> +       "call *%c[paravirt_opptr];"
> +
> +/*
>   * These macros are intended to wrap calls through one of the paravirt
>   * ops structs, so that they can be later identified and patched at
>   * runtime.
> @@ -509,7 +531,7 @@ int paravirt_disable_iospace(void);
>                 /* since this condition will never hold */              \
>                 if (sizeof(rettype) > sizeof(unsigned long)) {          \
>                         asm volatile(pre                                \
> -                                    paravirt_call                      \
> +                                    paravirt_alt(PARAVIRT_CALL)        \
>                                      post                               \
>                                      : call_clbr, ASM_CALL_CONSTRAINT   \
>                                      : paravirt_type(op),               \
> @@ -519,7 +541,7 @@ int paravirt_disable_iospace(void);
>                         __ret = (rettype)((((u64)__edx) << 32) | __eax); \
>                 } else {                                                \
>                         asm volatile(pre                                \
> -                                    paravirt_call                      \
> +                                    paravirt_alt(PARAVIRT_CALL)        \
>                                      post                               \
>                                      : call_clbr, ASM_CALL_CONSTRAINT   \
>                                      : paravirt_type(op),               \
> @@ -546,7 +568,7 @@ int paravirt_disable_iospace(void);
>                 PVOP_VCALL_ARGS;                                        \
>                 PVOP_TEST_NULL(op);                                     \
>                 asm volatile(pre                                        \
> -                            paravirt_call                              \
> +                            paravirt_alt(PARAVIRT_CALL)                \
>                              post                                       \
>                              : call_clbr, ASM_CALL_CONSTRAINT           \
>                              : paravirt_type(op),                       \
> @@ -664,26 +686,6 @@ struct paravirt_patch_site {
>  extern struct paravirt_patch_site __parainstructions[],
>         __parainstructions_end[];
>
> -#else  /* __ASSEMBLY__ */
> -
> -/*
> - * This generates an indirect call based on the operation type number.
> - * The type number, computed in PARAVIRT_PATCH, is derived from the
> - * offset into the paravirt_patch_template structure, and can therefore be
> - * freely converted back into a structure offset.
> - */
> -.macro PARAVIRT_CALL type:req clobber:req pv_opptr:req
> -771:   ANNOTATE_RETPOLINE_SAFE
> -       call *\pv_opptr
> -772:   .pushsection .parainstructions,"a"
> -       _ASM_ALIGN
> -       _ASM_PTR 771b
> -       .byte \type
> -       .byte 772b-771b
> -       .short \clobber
> -       .popsection
> -.endm
> -
>  #endif /* __ASSEMBLY__ */
>
>  #endif /* _ASM_X86_PARAVIRT_TYPES_H */
> diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h
> index a8b5e1e..dbaed55 100644
> --- a/arch/x86/include/asm/refcount.h
> +++ b/arch/x86/include/asm/refcount.h
> @@ -4,41 +4,6 @@
>   * x86-specific implementation of refcount_t. Based on PAX_REFCOUNT from
>   * PaX/grsecurity.
>   */
> -
> -#ifdef __ASSEMBLY__
> -
> -#include <asm/asm.h>
> -#include <asm/bug.h>
> -
> -.macro REFCOUNT_EXCEPTION counter:req
> -       .pushsection .text..refcount
> -111:   lea \counter, %_ASM_CX
> -112:   ud2
> -       ASM_UNREACHABLE
> -       .popsection
> -113:   _ASM_EXTABLE_REFCOUNT(112b, 113b)
> -.endm
> -
> -/* Trigger refcount exception if refcount result is negative. */
> -.macro REFCOUNT_CHECK_LT_ZERO counter:req
> -       js 111f
> -       REFCOUNT_EXCEPTION counter="\counter"
> -.endm
> -
> -/* Trigger refcount exception if refcount result is zero or negative. */
> -.macro REFCOUNT_CHECK_LE_ZERO counter:req
> -       jz 111f
> -       REFCOUNT_CHECK_LT_ZERO counter="\counter"
> -.endm
> -
> -/* Trigger refcount exception unconditionally. */
> -.macro REFCOUNT_ERROR counter:req
> -       jmp 111f
> -       REFCOUNT_EXCEPTION counter="\counter"
> -.endm
> -
> -#else /* __ASSEMBLY__ */
> -
>  #include <linux/refcount.h>
>  #include <asm/bug.h>
>
> @@ -50,12 +15,35 @@
>   * central refcount exception. The fixup address for the exception points
>   * back to the regular execution flow in .text.
>   */
> +#define _REFCOUNT_EXCEPTION                            \
> +       ".pushsection .text..refcount\n"                \
> +       "111:\tlea %[var], %%" _ASM_CX "\n"             \
> +       "112:\t" ASM_UD2 "\n"                           \
> +       ASM_UNREACHABLE                                 \
> +       ".popsection\n"                                 \
> +       "113:\n"                                        \
> +       _ASM_EXTABLE_REFCOUNT(112b, 113b)
> +
> +/* Trigger refcount exception if refcount result is negative. */
> +#define REFCOUNT_CHECK_LT_ZERO                         \
> +       "js 111f\n\t"                                   \
> +       _REFCOUNT_EXCEPTION
> +
> +/* Trigger refcount exception if refcount result is zero or negative. */
> +#define REFCOUNT_CHECK_LE_ZERO                         \
> +       "jz 111f\n\t"                                   \
> +       REFCOUNT_CHECK_LT_ZERO
> +
> +/* Trigger refcount exception unconditionally. */
> +#define REFCOUNT_ERROR                                 \
> +       "jmp 111f\n\t"                                  \
> +       _REFCOUNT_EXCEPTION
>
>  static __always_inline void refcount_add(unsigned int i, refcount_t *r)
>  {
>         asm volatile(LOCK_PREFIX "addl %1,%0\n\t"
> -               "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\""
> -               : [counter] "+m" (r->refs.counter)
> +               REFCOUNT_CHECK_LT_ZERO
> +               : [var] "+m" (r->refs.counter)
>                 : "ir" (i)
>                 : "cc", "cx");
>  }
> @@ -63,32 +51,31 @@ static __always_inline void refcount_add(unsigned int i, refcount_t *r)
>  static __always_inline void refcount_inc(refcount_t *r)
>  {
>         asm volatile(LOCK_PREFIX "incl %0\n\t"
> -               "REFCOUNT_CHECK_LT_ZERO counter=\"%[counter]\""
> -               : [counter] "+m" (r->refs.counter)
> +               REFCOUNT_CHECK_LT_ZERO
> +               : [var] "+m" (r->refs.counter)
>                 : : "cc", "cx");
>  }
>
>  static __always_inline void refcount_dec(refcount_t *r)
>  {
>         asm volatile(LOCK_PREFIX "decl %0\n\t"
> -               "REFCOUNT_CHECK_LE_ZERO counter=\"%[counter]\""
> -               : [counter] "+m" (r->refs.counter)
> +               REFCOUNT_CHECK_LE_ZERO
> +               : [var] "+m" (r->refs.counter)
>                 : : "cc", "cx");
>  }
>
>  static __always_inline __must_check
>  bool refcount_sub_and_test(unsigned int i, refcount_t *r)
>  {
> -
>         return GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl",
> -                                        "REFCOUNT_CHECK_LT_ZERO counter=\"%[var]\"",
> +                                        REFCOUNT_CHECK_LT_ZERO,
>                                          r->refs.counter, e, "er", i, "cx");
>  }
>
>  static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r)
>  {
>         return GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl",
> -                                       "REFCOUNT_CHECK_LT_ZERO counter=\"%[var]\"",
> +                                       REFCOUNT_CHECK_LT_ZERO,
>                                         r->refs.counter, e, "cx");
>  }
>
> @@ -106,8 +93,8 @@ bool refcount_add_not_zero(unsigned int i, refcount_t *r)
>
>                 /* Did we try to increment from/to an undesirable state? */
>                 if (unlikely(c < 0 || c == INT_MAX || result < c)) {
> -                       asm volatile("REFCOUNT_ERROR counter=\"%[counter]\""
> -                                    : : [counter] "m" (r->refs.counter)
> +                       asm volatile(REFCOUNT_ERROR
> +                                    : : [var] "m" (r->refs.counter)
>                                      : "cc", "cx");
>                         break;
>                 }
> @@ -122,6 +109,4 @@ static __always_inline __must_check bool refcount_inc_not_zero(refcount_t *r)
>         return refcount_add_not_zero(1, r);
>  }
>
> -#endif /* __ASSEMBLY__ */
> -
>  #endif
> diff --git a/arch/x86/kernel/macros.S b/arch/x86/kernel/macros.S
> deleted file mode 100644
> index 161c950..0000000
> --- a/arch/x86/kernel/macros.S
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -
> -/*
> - * This file includes headers whose assembly part includes macros which are
> - * commonly used. The macros are precompiled into assmebly file which is later
> - * assembled together with each compiled file.
> - */
> -
> -#include <linux/compiler.h>
> -#include <asm/refcount.h>
> -#include <asm/alternative-asm.h>
> -#include <asm/bug.h>
> -#include <asm/paravirt.h>
> -#include <asm/asm.h>
> -#include <asm/cpufeature.h>
> -#include <asm/jump_label.h>
> diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
> index cdafa5e..20561a6 100644
> --- a/include/asm-generic/bug.h
> +++ b/include/asm-generic/bug.h
> @@ -17,8 +17,10 @@
>  #ifndef __ASSEMBLY__
>  #include <linux/kernel.h>
>
> -struct bug_entry {
> +#ifdef CONFIG_BUG
> +
>  #ifdef CONFIG_GENERIC_BUG
> +struct bug_entry {
>  #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
>         unsigned long   bug_addr;
>  #else
> @@ -33,10 +35,8 @@ struct bug_entry {
>         unsigned short  line;
>  #endif
>         unsigned short  flags;
> -#endif /* CONFIG_GENERIC_BUG */
>  };
> -
> -#ifdef CONFIG_BUG
> +#endif /* CONFIG_GENERIC_BUG */
>
>  /*
>   * Don't use BUG() or BUG_ON() unless there's really no way out; one
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 06396c1..fc5004a 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -99,13 +99,22 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
>   * unique, to convince GCC not to merge duplicate inline asm statements.
>   */
>  #define annotate_reachable() ({                                                \
> -       asm volatile("ANNOTATE_REACHABLE counter=%c0"                   \
> -                    : : "i" (__COUNTER__));                            \
> +       asm volatile("%c0:\n\t"                                         \
> +                    ".pushsection .discard.reachable\n\t"              \
> +                    ".long %c0b - .\n\t"                               \
> +                    ".popsection\n\t" : : "i" (__COUNTER__));          \
>  })
>  #define annotate_unreachable() ({                                      \
> -       asm volatile("ANNOTATE_UNREACHABLE counter=%c0"                 \
> -                    : : "i" (__COUNTER__));                            \
> +       asm volatile("%c0:\n\t"                                         \
> +                    ".pushsection .discard.unreachable\n\t"            \
> +                    ".long %c0b - .\n\t"                               \
> +                    ".popsection\n\t" : : "i" (__COUNTER__));          \
>  })
> +#define ASM_UNREACHABLE                                                        \
> +       "999:\n\t"                                                      \
> +       ".pushsection .discard.unreachable\n\t"                         \
> +       ".long 999b - .\n\t"                                            \
> +       ".popsection\n\t"
>  #else
>  #define annotate_reachable()
>  #define annotate_unreachable()
> @@ -293,45 +302,6 @@ static inline void *offset_to_ptr(const int *off)
>         return (void *)((unsigned long)off + *off);
>  }
>
> -#else /* __ASSEMBLY__ */
> -
> -#ifdef __KERNEL__
> -#ifndef LINKER_SCRIPT
> -
> -#ifdef CONFIG_STACK_VALIDATION
> -.macro ANNOTATE_UNREACHABLE counter:req
> -\counter:
> -       .pushsection .discard.unreachable
> -       .long \counter\()b -.
> -       .popsection
> -.endm
> -
> -.macro ANNOTATE_REACHABLE counter:req
> -\counter:
> -       .pushsection .discard.reachable
> -       .long \counter\()b -.
> -       .popsection
> -.endm
> -
> -.macro ASM_UNREACHABLE
> -999:
> -       .pushsection .discard.unreachable
> -       .long 999b - .
> -       .popsection
> -.endm
> -#else /* CONFIG_STACK_VALIDATION */
> -.macro ANNOTATE_UNREACHABLE counter:req
> -.endm
> -
> -.macro ANNOTATE_REACHABLE counter:req
> -.endm
> -
> -.macro ASM_UNREACHABLE
> -.endm
> -#endif /* CONFIG_STACK_VALIDATION */
> -
> -#endif /* LINKER_SCRIPT */
> -#endif /* __KERNEL__ */
>  #endif /* __ASSEMBLY__ */
>
>  /* Compile time object size, -1 for unknown */
> diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
> index bb01555..3d09844 100644
> --- a/scripts/Kbuild.include
> +++ b/scripts/Kbuild.include
> @@ -115,9 +115,7 @@ __cc-option = $(call try-run,\
>
>  # Do not attempt to build with gcc plugins during cc-option tests.
>  # (And this uses delayed resolution so the flags will be up to date.)
> -# In addition, do not include the asm macros which are built later.
> -CC_OPTION_FILTERED = $(GCC_PLUGINS_CFLAGS) $(ASM_MACRO_FLAGS)
> -CC_OPTION_CFLAGS = $(filter-out $(CC_OPTION_FILTERED),$(KBUILD_CFLAGS))
> +CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
>
>  # cc-option
>  # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
> diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile
> index a5b4af4..42c5d50 100644
> --- a/scripts/mod/Makefile
> +++ b/scripts/mod/Makefile
> @@ -4,8 +4,6 @@ OBJECT_FILES_NON_STANDARD := y
>  hostprogs-y    := modpost mk_elfconfig
>  always         := $(hostprogs-y) empty.o
>
> -CFLAGS_REMOVE_empty.o := $(ASM_MACRO_FLAGS)
> -
>  modpost-objs   := modpost.o file2alias.o sumversion.o
>
>  devicetable-offsets-file := devicetable-offsets.h
> --
> 2.7.4
>



[Index of Archives]     [Linux&nblp;USB Development]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite Secrets]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux