Merge tag 'v6.8-rc4' into x86/percpu, to resolve conflicts and refresh the branch
authorIngo Molnar <mingo@kernel.org>
Wed, 14 Feb 2024 09:45:07 +0000 (10:45 +0100)
committerIngo Molnar <mingo@kernel.org>
Wed, 14 Feb 2024 09:45:07 +0000 (10:45 +0100)
Conflicts:
arch/x86/include/asm/percpu.h
arch/x86/include/asm/text-patching.h

Signed-off-by: Ingo Molnar <mingo@kernel.org>
26 files changed:
arch/x86/Kconfig
arch/x86/entry/calling.h
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/include/asm/current.h
arch/x86/include/asm/fpu/sched.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/preempt.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/text-patching.h
arch/x86/include/asm/uaccess_64.h
arch/x86/kernel/acpi/wakeup_64.S
arch/x86/kernel/alternative.c
arch/x86/kernel/callthunks.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/head_64.S
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/smp.c
arch/x86/kernel/traps.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/lib/cmpxchg16b_emu.S
arch/x86/lib/cmpxchg8b_emu.S
arch/x86/xen/xen-asm.S
include/linux/compiler.h

index 5edec175b9bfc92dfac8832fc3600b843407828b..0a31b515d1205d0246e72fb796083e74c70049b6 100644 (file)
@@ -2434,6 +2434,18 @@ source "kernel/livepatch/Kconfig"
 
 endmenu
 
+config CC_HAS_NAMED_AS
+       def_bool CC_IS_GCC && GCC_VERSION >= 120100
+
+config USE_X86_SEG_SUPPORT
+       def_bool y
+       depends on CC_HAS_NAMED_AS
+       #
+       # -fsanitize=kernel-address (KASAN) is at the moment incompatible
+       # with named address spaces - see GCC PR sanitizer/111736.
+       #
+       depends on !KASAN
+
 config CC_HAS_SLS
        def_bool $(cc-option,-mharden-sls=all)
 
index 9f1d94790a54912cc431e9e39fc0a4a7e6069398..e59d3073e7cf2e4daaccf986108c5c8ea21c1504 100644 (file)
@@ -173,7 +173,7 @@ For 32-bit we have the following conventions - kernel is built with
 .endm
 
 #define THIS_CPU_user_pcid_flush_mask   \
-       PER_CPU_VAR(cpu_tlbstate) + TLB_STATE_user_pcid_flush_mask
+       PER_CPU_VAR(cpu_tlbstate + TLB_STATE_user_pcid_flush_mask)
 
 .macro SWITCH_TO_USER_CR3 scratch_reg:req scratch_reg2:req
        mov     %cr3, \scratch_reg
index c73047bf9f4bff9c4631c0eab383cedceda41918..4e295798638b8176de7bd5f341f063124c60ce49 100644 (file)
 .macro CHECK_AND_APPLY_ESPFIX
 #ifdef CONFIG_X86_ESPFIX32
 #define GDT_ESPFIX_OFFSET (GDT_ENTRY_ESPFIX_SS * 8)
-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + GDT_ESPFIX_OFFSET
+#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page + GDT_ESPFIX_OFFSET)
 
        ALTERNATIVE     "jmp .Lend_\@", "", X86_BUG_ESPFIX
 
index c40f89ab1b4c70a18b632a50c1e659e3fd83cfa9..567d973eed0381810ed276a5b8c8561573a13374 100644 (file)
@@ -190,7 +190,7 @@ SYM_FUNC_START(__switch_to_asm)
 
 #ifdef CONFIG_STACKPROTECTOR
        movq    TASK_stack_canary(%rsi), %rbx
-       movq    %rbx, PER_CPU_VAR(fixed_percpu_data) + FIXED_stack_canary
+       movq    %rbx, PER_CPU_VAR(fixed_percpu_data + FIXED_stack_canary)
 #endif
 
        /*
index dd4b67101bb7ed40013584f66cc80e805ea0ece1..fb7702d4170c554dd9f34737d76ac69e7b07fee0 100644 (file)
@@ -37,8 +37,15 @@ static_assert(sizeof(struct pcpu_hot) == 64);
 
 DECLARE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot);
 
+/* const-qualified alias to pcpu_hot, aliased by linker. */
+DECLARE_PER_CPU_ALIGNED(const struct pcpu_hot __percpu_seg_override,
+                       const_pcpu_hot);
+
 static __always_inline struct task_struct *get_current(void)
 {
+       if (IS_ENABLED(CONFIG_USE_X86_SEG_SUPPORT))
+               return this_cpu_read_const(const_pcpu_hot.current_task);
+
        return this_cpu_read_stable(pcpu_hot.current_task);
 }
 
index ca6e5e5f16b2eca0e02222956951c628b556ec50..c485f1944c5f86a0ab0ecad38ce0e5bb65569bb8 100644 (file)
@@ -37,10 +37,12 @@ extern void fpu_flush_thread(void);
  * The FPU context is only stored/restored for a user task and
  * PF_KTHREAD is used to distinguish between kernel and user threads.
  */
-static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
+static inline void switch_fpu_prepare(struct task_struct *old, int cpu)
 {
        if (cpu_feature_enabled(X86_FEATURE_FPU) &&
-           !(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
+           !(old->flags & (PF_KTHREAD | PF_USER_WORKER))) {
+               struct fpu *old_fpu = &old->thread.fpu;
+
                save_fpregs_to_fpstate(old_fpu);
                /*
                 * The save operation preserved register state, so the
@@ -60,10 +62,10 @@ static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
  * Delay loading of the complete FPU state until the return to userland.
  * PKRU is handled separately.
  */
-static inline void switch_fpu_finish(void)
+static inline void switch_fpu_finish(struct task_struct *new)
 {
        if (cpu_feature_enabled(X86_FEATURE_FPU))
-               set_thread_flag(TIF_NEED_FPU_LOAD);
+               set_tsk_thread_flag(new, TIF_NEED_FPU_LOAD);
 }
 
 #endif /* _ASM_X86_FPU_SCHED_H */
index 262e65539f83c86d140552305c8a9d330b313c20..691ff1ef701b623b8d671ea89b9b258cd25562be 100644 (file)
 
 #ifdef CONFIG_CALL_THUNKS_DEBUG
 # define CALL_THUNKS_DEBUG_INC_CALLS                           \
-       incq    %gs:__x86_call_count;
+       incq    PER_CPU_VAR(__x86_call_count);
 # define CALL_THUNKS_DEBUG_INC_RETS                            \
-       incq    %gs:__x86_ret_count;
+       incq    PER_CPU_VAR(__x86_ret_count);
 # define CALL_THUNKS_DEBUG_INC_STUFFS                          \
-       incq    %gs:__x86_stuffs_count;
+       incq    PER_CPU_VAR(__x86_stuffs_count);
 # define CALL_THUNKS_DEBUG_INC_CTXSW                           \
-       incq    %gs:__x86_ctxsw_count;
+       incq    PER_CPU_VAR(__x86_ctxsw_count);
 #else
 # define CALL_THUNKS_DEBUG_INC_CALLS
 # define CALL_THUNKS_DEBUG_INC_RETS
@@ -80,9 +80,6 @@
 #define CREDIT_CALL_DEPTH                                      \
        movq    $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth);
 
-#define ASM_CREDIT_CALL_DEPTH                                  \
-       movq    $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth);
-
 #define RESET_CALL_DEPTH                                       \
        xor     %eax, %eax;                                     \
        bts     $63, %rax;                                      \
        CALL_THUNKS_DEBUG_INC_CALLS
 
 #define INCREMENT_CALL_DEPTH                                   \
-       sarq    $5, %gs:pcpu_hot + X86_call_depth;              \
-       CALL_THUNKS_DEBUG_INC_CALLS
-
-#define ASM_INCREMENT_CALL_DEPTH                               \
        sarq    $5, PER_CPU_VAR(pcpu_hot + X86_call_depth);     \
        CALL_THUNKS_DEBUG_INC_CALLS
 
 #else
 #define CREDIT_CALL_DEPTH
-#define ASM_CREDIT_CALL_DEPTH
 #define RESET_CALL_DEPTH
-#define INCREMENT_CALL_DEPTH
-#define ASM_INCREMENT_CALL_DEPTH
 #define RESET_CALL_DEPTH_FROM_CALL
+#define INCREMENT_CALL_DEPTH
 #endif
 
 /*
        jnz     771b;                                   \
        /* barrier for jnz misprediction */             \
        lfence;                                         \
-       ASM_CREDIT_CALL_DEPTH                           \
+       CREDIT_CALL_DEPTH                               \
        CALL_THUNKS_DEBUG_INC_CTXSW
 #else
 /*
 .macro CALL_DEPTH_ACCOUNT
 #ifdef CONFIG_CALL_DEPTH_TRACKING
        ALTERNATIVE "",                                                 \
-                   __stringify(ASM_INCREMENT_CALL_DEPTH), X86_FEATURE_CALL_DEPTH
+                   __stringify(INCREMENT_CALL_DEPTH), X86_FEATURE_CALL_DEPTH
 #endif
 .endm
 
index 5e01883eb51ee8e576e70db0577bfbe0c20c2e4f..44958ebaf626e20c970acaacaad012f93cba2671 100644 (file)
@@ -4,17 +4,21 @@
 
 #ifdef CONFIG_X86_64
 #define __percpu_seg           gs
+#define __percpu_rel           (%rip)
 #else
 #define __percpu_seg           fs
+#define __percpu_rel
 #endif
 
 #ifdef __ASSEMBLY__
 
 #ifdef CONFIG_SMP
-#define PER_CPU_VAR(var)       %__percpu_seg:var
-#else /* ! SMP */
-#define PER_CPU_VAR(var)       var
-#endif /* SMP */
+#define __percpu               %__percpu_seg:
+#else
+#define __percpu
+#endif
+
+#define PER_CPU_VAR(var)       __percpu(var)__percpu_rel
 
 #ifdef CONFIG_X86_64_SMP
 #define INIT_PER_CPU_VAR(var)  init_per_cpu__##var
 
 #else /* ...!ASSEMBLY */
 
+#include <linux/build_bug.h>
 #include <linux/stringify.h>
 #include <asm/asm.h>
 
 #ifdef CONFIG_SMP
+
+#ifdef CONFIG_CC_HAS_NAMED_AS
+
+#ifdef __CHECKER__
+#define __seg_gs               __attribute__((address_space(__seg_gs)))
+#define __seg_fs               __attribute__((address_space(__seg_fs)))
+#endif
+
+#ifdef CONFIG_X86_64
+#define __percpu_seg_override  __seg_gs
+#else
+#define __percpu_seg_override  __seg_fs
+#endif
+
+#define __percpu_prefix                ""
+
+#else /* CONFIG_CC_HAS_NAMED_AS */
+
+#define __percpu_seg_override
 #define __percpu_prefix                "%%"__stringify(__percpu_seg)":"
+
+#endif /* CONFIG_CC_HAS_NAMED_AS */
+
+#define __force_percpu_prefix  "%%"__stringify(__percpu_seg)":"
 #define __my_cpu_offset                this_cpu_read(this_cpu_off)
 
+#ifdef CONFIG_USE_X86_SEG_SUPPORT
+/*
+ * Efficient implementation for cases in which the compiler supports
+ * named address spaces.  Allows the compiler to perform additional
+ * optimizations that can save more instructions.
+ */
+#define arch_raw_cpu_ptr(ptr)                                  \
+({                                                             \
+       unsigned long tcp_ptr__;                                \
+       tcp_ptr__ = __raw_cpu_read(, this_cpu_off);             \
+                                                               \
+       tcp_ptr__ += (unsigned long)(ptr);                      \
+       (typeof(*(ptr)) __kernel __force *)tcp_ptr__;           \
+})
+#else /* CONFIG_USE_X86_SEG_SUPPORT */
 /*
  * Compared to the generic __my_cpu_offset version, the following
  * saves one instruction and avoids clobbering a temp register.
  */
-#define arch_raw_cpu_ptr(ptr)                          \
-({                                                     \
-       unsigned long tcp_ptr__;                        \
-       asm ("add " __percpu_arg(1) ", %0"              \
-            : "=r" (tcp_ptr__)                         \
-            : "m" (this_cpu_off), "0" (ptr));          \
-       (typeof(*(ptr)) __kernel __force *)tcp_ptr__;   \
+#define arch_raw_cpu_ptr(ptr)                                  \
+({                                                             \
+       unsigned long tcp_ptr__;                                \
+       asm ("mov " __percpu_arg(1) ", %0"                      \
+            : "=r" (tcp_ptr__)                                 \
+            : "m" (__my_cpu_var(this_cpu_off)));               \
+                                                               \
+       tcp_ptr__ += (unsigned long)(ptr);                      \
+       (typeof(*(ptr)) __kernel __force *)tcp_ptr__;           \
 })
-#else
+#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+
+#define PER_CPU_VAR(var)       %__percpu_seg:(var)__percpu_rel
+
+#else /* CONFIG_SMP */
+#define __percpu_seg_override
 #define __percpu_prefix                ""
-#endif
+#define __force_percpu_prefix  ""
+
+#define PER_CPU_VAR(var)       (var)__percpu_rel
 
+#endif /* CONFIG_SMP */
+
+#define __my_cpu_type(var)     typeof(var) __percpu_seg_override
+#define __my_cpu_ptr(ptr)      (__my_cpu_type(*ptr) *)(uintptr_t)(ptr)
+#define __my_cpu_var(var)      (*__my_cpu_ptr(&var))
 #define __percpu_arg(x)                __percpu_prefix "%" #x
+#define __force_percpu_arg(x)  __force_percpu_prefix "%" #x
 
 /*
  * Initialized pointers to per-cpu variables needed for the boot
@@ -107,14 +165,14 @@ do {                                                                      \
                (void)pto_tmp__;                                        \
        }                                                               \
        asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var]))   \
-           : [var] "+m" (_var)                                         \
+           : [var] "+m" (__my_cpu_var(_var))                           \
            : [val] __pcpu_reg_imm_##size(pto_val__));                  \
 } while (0)
 
 #define percpu_unary_op(size, qual, op, _var)                          \
 ({                                                                     \
        asm qual (__pcpu_op1_##size(op, __percpu_arg([var]))            \
-           : [var] "+m" (_var));                                       \
+           : [var] "+m" (__my_cpu_var(_var)));                         \
 })
 
 /*
@@ -144,16 +202,16 @@ do {                                                                      \
        __pcpu_type_##size pfo_val__;                                   \
        asm qual (__pcpu_op2_##size(op, __percpu_arg([var]), "%[val]")  \
            : [val] __pcpu_reg_##size("=", pfo_val__)                   \
-           : [var] "m" (_var));                                        \
+           : [var] "m" (__my_cpu_var(_var)));                          \
        (typeof(_var))(unsigned long) pfo_val__;                        \
 })
 
 #define percpu_stable_op(size, op, _var)                               \
 ({                                                                     \
        __pcpu_type_##size pfo_val__;                                   \
-       asm(__pcpu_op2_##size(op, __percpu_arg(P[var]), "%[val]")       \
+       asm(__pcpu_op2_##size(op, __force_percpu_arg(a[var]), "%[val]") \
            : [val] __pcpu_reg_##size("=", pfo_val__)                   \
-           : [var] "p" (&(_var)));                                     \
+           : [var] "i" (&(_var)));                                     \
        (typeof(_var))(unsigned long) pfo_val__;                        \
 })
 
@@ -166,7 +224,7 @@ do {                                                                        \
        asm qual (__pcpu_op2_##size("xadd", "%[tmp]",                   \
                                     __percpu_arg([var]))               \
                  : [tmp] __pcpu_reg_##size("+", paro_tmp__),           \
-                   [var] "+m" (_var)                                   \
+                   [var] "+m" (__my_cpu_var(_var))                     \
                  : : "memory");                                        \
        (typeof(_var))(unsigned long) (paro_tmp__ + _val);              \
 })
@@ -187,7 +245,7 @@ do {                                                                        \
                                    __percpu_arg([var]))                \
                  "\n\tjnz 1b"                                          \
                  : [oval] "=&a" (pxo_old__),                           \
-                   [var] "+m" (_var)                                   \
+                   [var] "+m" (__my_cpu_var(_var))                     \
                  : [nval] __pcpu_reg_##size(, pxo_new__)               \
                  : "memory");                                          \
        (typeof(_var))(unsigned long) pxo_old__;                        \
@@ -204,7 +262,7 @@ do {                                                                        \
        asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]",               \
                                    __percpu_arg([var]))                \
                  : [oval] "+a" (pco_old__),                            \
-                   [var] "+m" (_var)                                   \
+                   [var] "+m" (__my_cpu_var(_var))                     \
                  : [nval] __pcpu_reg_##size(, pco_new__)               \
                  : "memory");                                          \
        (typeof(_var))(unsigned long) pco_old__;                        \
@@ -221,7 +279,7 @@ do {                                                                        \
                  CC_SET(z)                                             \
                  : CC_OUT(z) (success),                                \
                    [oval] "+a" (pco_old__),                            \
-                   [var] "+m" (_var)                                   \
+                   [var] "+m" (__my_cpu_var(_var))                     \
                  : [nval] __pcpu_reg_##size(, pco_new__)               \
                  : "memory");                                          \
        if (unlikely(!success))                                         \
@@ -244,7 +302,7 @@ do {                                                                        \
                                                                        \
        asm qual (ALTERNATIVE("call this_cpu_cmpxchg8b_emu",            \
                              "cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
-                 : [var] "+m" (_var),                                  \
+                 : [var] "+m" (__my_cpu_var(_var)),                    \
                    "+a" (old__.low),                                   \
                    "+d" (old__.high)                                   \
                  : "b" (new__.low),                                    \
@@ -276,7 +334,7 @@ do {                                                                        \
                              "cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
                  CC_SET(z)                                             \
                  : CC_OUT(z) (success),                                \
-                   [var] "+m" (_var),                                  \
+                   [var] "+m" (__my_cpu_var(_var)),                    \
                    "+a" (old__.low),                                   \
                    "+d" (old__.high)                                   \
                  : "b" (new__.low),                                    \
@@ -313,7 +371,7 @@ do {                                                                        \
                                                                        \
        asm qual (ALTERNATIVE("call this_cpu_cmpxchg16b_emu",           \
                              "cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
-                 : [var] "+m" (_var),                                  \
+                 : [var] "+m" (__my_cpu_var(_var)),                    \
                    "+a" (old__.low),                                   \
                    "+d" (old__.high)                                   \
                  : "b" (new__.low),                                    \
@@ -345,7 +403,7 @@ do {                                                                        \
                              "cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
                  CC_SET(z)                                             \
                  : CC_OUT(z) (success),                                \
-                   [var] "+m" (_var),                                  \
+                   [var] "+m" (__my_cpu_var(_var)),                    \
                    "+a" (old__.low),                                   \
                    "+d" (old__.high)                                   \
                  : "b" (new__.low),                                    \
@@ -366,9 +424,9 @@ do {                                                                        \
  * accessed while this_cpu_read_stable() allows the value to be cached.
  * this_cpu_read_stable() is more efficient and can be used if its value
  * is guaranteed to be valid across cpus.  The current users include
- * get_current() and get_thread_info() both of which are actually
- * per-thread variables implemented as per-cpu variables and thus
- * stable for the duration of the respective task.
+ * pcpu_hot.current_task and pcpu_hot.top_of_stack, both of which are
+ * actually per-thread variables implemented as per-CPU variables and
+ * thus stable for the duration of the respective task.
  */
 #define this_cpu_read_stable_1(pcp)    percpu_stable_op(1, "mov", pcp)
 #define this_cpu_read_stable_2(pcp)    percpu_stable_op(2, "mov", pcp)
@@ -376,13 +434,72 @@ do {                                                                      \
 #define this_cpu_read_stable_8(pcp)    percpu_stable_op(8, "mov", pcp)
 #define this_cpu_read_stable(pcp)      __pcpu_size_call_return(this_cpu_read_stable_, pcp)
 
+#ifdef CONFIG_USE_X86_SEG_SUPPORT
+
+#define __raw_cpu_read(qual, pcp)                                      \
+({                                                                     \
+       *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp));               \
+})
+
+#define __raw_cpu_write(qual, pcp, val)                                        \
+do {                                                                   \
+       *(qual __my_cpu_type(pcp) *)__my_cpu_ptr(&(pcp)) = (val);       \
+} while (0)
+
+#define raw_cpu_read_1(pcp)            __raw_cpu_read(, pcp)
+#define raw_cpu_read_2(pcp)            __raw_cpu_read(, pcp)
+#define raw_cpu_read_4(pcp)            __raw_cpu_read(, pcp)
+#define raw_cpu_write_1(pcp, val)      __raw_cpu_write(, pcp, val)
+#define raw_cpu_write_2(pcp, val)      __raw_cpu_write(, pcp, val)
+#define raw_cpu_write_4(pcp, val)      __raw_cpu_write(, pcp, val)
+
+#define this_cpu_read_1(pcp)           __raw_cpu_read(volatile, pcp)
+#define this_cpu_read_2(pcp)           __raw_cpu_read(volatile, pcp)
+#define this_cpu_read_4(pcp)           __raw_cpu_read(volatile, pcp)
+#define this_cpu_write_1(pcp, val)     __raw_cpu_write(volatile, pcp, val)
+#define this_cpu_write_2(pcp, val)     __raw_cpu_write(volatile, pcp, val)
+#define this_cpu_write_4(pcp, val)     __raw_cpu_write(volatile, pcp, val)
+
+#ifdef CONFIG_X86_64
+#define raw_cpu_read_8(pcp)            __raw_cpu_read(, pcp)
+#define raw_cpu_write_8(pcp, val)      __raw_cpu_write(, pcp, val)
+
+#define this_cpu_read_8(pcp)           __raw_cpu_read(volatile, pcp)
+#define this_cpu_write_8(pcp, val)     __raw_cpu_write(volatile, pcp, val)
+#endif
+
+#define this_cpu_read_const(pcp)       __raw_cpu_read(, pcp)
+#else /* CONFIG_USE_X86_SEG_SUPPORT */
+
 #define raw_cpu_read_1(pcp)            percpu_from_op(1, , "mov", pcp)
 #define raw_cpu_read_2(pcp)            percpu_from_op(2, , "mov", pcp)
 #define raw_cpu_read_4(pcp)            percpu_from_op(4, , "mov", pcp)
-
 #define raw_cpu_write_1(pcp, val)      percpu_to_op(1, , "mov", (pcp), val)
 #define raw_cpu_write_2(pcp, val)      percpu_to_op(2, , "mov", (pcp), val)
 #define raw_cpu_write_4(pcp, val)      percpu_to_op(4, , "mov", (pcp), val)
+
+#define this_cpu_read_1(pcp)           percpu_from_op(1, volatile, "mov", pcp)
+#define this_cpu_read_2(pcp)           percpu_from_op(2, volatile, "mov", pcp)
+#define this_cpu_read_4(pcp)           percpu_from_op(4, volatile, "mov", pcp)
+#define this_cpu_write_1(pcp, val)     percpu_to_op(1, volatile, "mov", (pcp), val)
+#define this_cpu_write_2(pcp, val)     percpu_to_op(2, volatile, "mov", (pcp), val)
+#define this_cpu_write_4(pcp, val)     percpu_to_op(4, volatile, "mov", (pcp), val)
+
+#ifdef CONFIG_X86_64
+#define raw_cpu_read_8(pcp)            percpu_from_op(8, , "mov", pcp)
+#define raw_cpu_write_8(pcp, val)      percpu_to_op(8, , "mov", (pcp), val)
+
+#define this_cpu_read_8(pcp)           percpu_from_op(8, volatile, "mov", pcp)
+#define this_cpu_write_8(pcp, val)     percpu_to_op(8, volatile, "mov", (pcp), val)
+#endif
+
+/*
+ * The generic per-cpu infrastrucutre is not suitable for
+ * reading const-qualified variables.
+ */
+#define this_cpu_read_const(pcp)       ({ BUILD_BUG(); (typeof(pcp))0; })
+#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+
 #define raw_cpu_add_1(pcp, val)                percpu_add_op(1, , (pcp), val)
 #define raw_cpu_add_2(pcp, val)                percpu_add_op(2, , (pcp), val)
 #define raw_cpu_add_4(pcp, val)                percpu_add_op(4, , (pcp), val)
@@ -408,12 +525,6 @@ do {                                                                       \
 #define raw_cpu_xchg_2(pcp, val)       raw_percpu_xchg_op(pcp, val)
 #define raw_cpu_xchg_4(pcp, val)       raw_percpu_xchg_op(pcp, val)
 
-#define this_cpu_read_1(pcp)           percpu_from_op(1, volatile, "mov", pcp)
-#define this_cpu_read_2(pcp)           percpu_from_op(2, volatile, "mov", pcp)
-#define this_cpu_read_4(pcp)           percpu_from_op(4, volatile, "mov", pcp)
-#define this_cpu_write_1(pcp, val)     percpu_to_op(1, volatile, "mov", (pcp), val)
-#define this_cpu_write_2(pcp, val)     percpu_to_op(2, volatile, "mov", (pcp), val)
-#define this_cpu_write_4(pcp, val)     percpu_to_op(4, volatile, "mov", (pcp), val)
 #define this_cpu_add_1(pcp, val)       percpu_add_op(1, volatile, (pcp), val)
 #define this_cpu_add_2(pcp, val)       percpu_add_op(2, volatile, (pcp), val)
 #define this_cpu_add_4(pcp, val)       percpu_add_op(4, volatile, (pcp), val)
@@ -452,8 +563,6 @@ do {                                                                        \
  * 32 bit must fall back to generic operations.
  */
 #ifdef CONFIG_X86_64
-#define raw_cpu_read_8(pcp)                    percpu_from_op(8, , "mov", pcp)
-#define raw_cpu_write_8(pcp, val)              percpu_to_op(8, , "mov", (pcp), val)
 #define raw_cpu_add_8(pcp, val)                        percpu_add_op(8, , (pcp), val)
 #define raw_cpu_and_8(pcp, val)                        percpu_to_op(8, , "and", (pcp), val)
 #define raw_cpu_or_8(pcp, val)                 percpu_to_op(8, , "or", (pcp), val)
@@ -462,8 +571,6 @@ do {                                                                        \
 #define raw_cpu_cmpxchg_8(pcp, oval, nval)     percpu_cmpxchg_op(8, , pcp, oval, nval)
 #define raw_cpu_try_cmpxchg_8(pcp, ovalp, nval)        percpu_try_cmpxchg_op(8, , pcp, ovalp, nval)
 
-#define this_cpu_read_8(pcp)                   percpu_from_op(8, volatile, "mov", pcp)
-#define this_cpu_write_8(pcp, val)             percpu_to_op(8, volatile, "mov", (pcp), val)
 #define this_cpu_add_8(pcp, val)               percpu_add_op(8, volatile, (pcp), val)
 #define this_cpu_and_8(pcp, val)               percpu_to_op(8, volatile, "and", (pcp), val)
 #define this_cpu_or_8(pcp, val)                        percpu_to_op(8, volatile, "or", (pcp), val)
@@ -494,7 +601,7 @@ static inline bool x86_this_cpu_variable_test_bit(int nr,
        asm volatile("btl "__percpu_arg(2)",%1"
                        CC_SET(c)
                        : CC_OUT(c) (oldbit)
-                       : "m" (*(unsigned long __percpu *)addr), "Ir" (nr));
+                       : "m" (*__my_cpu_ptr((unsigned long __percpu *)(addr))), "Ir" (nr));
 
        return oldbit;
 }
index af77235fded63b64ec99844778796a294cf29d0a..919909d8cb77e3d630af36bf7df00f10fc3765f2 100644 (file)
@@ -91,7 +91,7 @@ static __always_inline void __preempt_count_sub(int val)
  */
 static __always_inline bool __preempt_count_dec_and_test(void)
 {
-       return GEN_UNARY_RMWcc("decl", pcpu_hot.preempt_count, e,
+       return GEN_UNARY_RMWcc("decl", __my_cpu_var(pcpu_hot.preempt_count), e,
                               __percpu_arg([var]));
 }
 
index 26620d7642a9fcf9d4a822140a1dd009399ee16a..1188e8bf76a2998d9d8cb50d0da0ae9a9d28351e 100644 (file)
@@ -533,6 +533,9 @@ static __always_inline unsigned long current_top_of_stack(void)
         *  and around vm86 mode and sp0 on x86_64 is special because of the
         *  entry trampoline.
         */
+       if (IS_ENABLED(CONFIG_USE_X86_SEG_SUPPORT))
+               return this_cpu_read_const(const_pcpu_hot.top_of_stack);
+
        return this_cpu_read_stable(pcpu_hot.top_of_stack);
 }
 
index 0b70653a98c1573a475edf808601cb1c33f9a45e..345aafbc19648865f7262b64e43d1ae5176aae4c 100644 (file)
@@ -15,6 +15,8 @@
 
 extern void text_poke_early(void *addr, const void *opcode, size_t len);
 
+extern void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len);
+
 /*
  * Clear and restore the kernel write-protection flag on the local CPU.
  * Allows the kernel to edit read-only pages.
index f2c02e4469ccc3db6265b2e36a6bd336f5e822fc..01455c0b070ccee053f6de67ec86e4ac20676c41 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/alternative.h>
 #include <asm/cpufeatures.h>
 #include <asm/page.h>
+#include <asm/percpu.h>
 
 #ifdef CONFIG_ADDRESS_MASKING
 /*
  */
 static inline unsigned long __untagged_addr(unsigned long addr)
 {
-       /*
-        * Refer tlbstate_untag_mask directly to avoid RIP-relative relocation
-        * in alternative instructions. The relocation gets wrong when gets
-        * copied to the target place.
-        */
        asm (ALTERNATIVE("",
-                        "and %%gs:tlbstate_untag_mask, %[addr]\n\t", X86_FEATURE_LAM)
-            : [addr] "+r" (addr) : "m" (tlbstate_untag_mask));
+                        "and " __percpu_arg([mask]) ", %[addr]", X86_FEATURE_LAM)
+            : [addr] "+r" (addr)
+            : [mask] "m" (__my_cpu_var(tlbstate_untag_mask)));
 
        return addr;
 }
index d5d8a352eafaa1b0bf77bd61a1f4edf444d9b23b..94ff83f3d3fe927dbd67a00f8ad2cb91eb276486 100644 (file)
@@ -17,7 +17,7 @@
         * Hooray, we are in Long 64-bit mode (but still running in low memory)
         */
 SYM_FUNC_START(wakeup_long64)
-       movq    saved_magic, %rax
+       movq    saved_magic(%rip), %rax
        movq    $0x123456789abcdef0, %rdx
        cmpq    %rdx, %rax
        je      2f
@@ -33,14 +33,14 @@ SYM_FUNC_START(wakeup_long64)
        movw    %ax, %es
        movw    %ax, %fs
        movw    %ax, %gs
-       movq    saved_rsp, %rsp
+       movq    saved_rsp(%rip), %rsp
 
-       movq    saved_rbx, %rbx
-       movq    saved_rdi, %rdi
-       movq    saved_rsi, %rsi
-       movq    saved_rbp, %rbp
+       movq    saved_rbx(%rip), %rbx
+       movq    saved_rdi(%rip), %rdi
+       movq    saved_rsi(%rip), %rsi
+       movq    saved_rbp(%rip), %rbp
 
-       movq    saved_rip, %rax
+       movq    saved_rip(%rip), %rax
        ANNOTATE_RETPOLINE_SAFE
        jmp     *%rax
 SYM_FUNC_END(wakeup_long64)
@@ -72,11 +72,11 @@ SYM_FUNC_START(do_suspend_lowlevel)
 
        movq    $.Lresume_point, saved_rip(%rip)
 
-       movq    %rsp, saved_rsp
-       movq    %rbp, saved_rbp
-       movq    %rbx, saved_rbx
-       movq    %rdi, saved_rdi
-       movq    %rsi, saved_rsi
+       movq    %rsp, saved_rsp(%rip)
+       movq    %rbp, saved_rbp(%rip)
+       movq    %rbx, saved_rbx(%rip)
+       movq    %rdi, saved_rdi(%rip)
+       movq    %rsi, saved_rsi(%rip)
 
        addq    $8, %rsp
        movl    $3, %edi
index 1d85cb7071cb21c84899477ec4a150d2fcc4da43..e7aeae02aacaf6a63deb7ac065fc1bbca5e049a3 100644 (file)
@@ -45,7 +45,7 @@ EXPORT_SYMBOL_GPL(alternatives_patched);
 #define DA_ENDBR       0x08
 #define DA_SMP         0x10
 
-static unsigned int __initdata_or_module debug_alternative;
+static unsigned int debug_alternative;
 
 static int __init debug_alt(char *str)
 {
@@ -133,7 +133,7 @@ const unsigned char * const x86_nops[ASM_NOP_MAX+1] =
  * each single-byte NOPs). If @len to fill out is > ASM_NOP_MAX, pad with INT3 and
  * *jump* over instead of executing long and daft NOPs.
  */
-static void __init_or_module add_nop(u8 *instr, unsigned int len)
+static void add_nop(u8 *instr, unsigned int len)
 {
        u8 *target = instr + len;
 
@@ -206,7 +206,7 @@ static int skip_nops(u8 *instr, int offset, int len)
  * Optimize a sequence of NOPs, possibly preceded by an unconditional jump
  * to the end of the NOP sequence into a single NOP.
  */
-static bool __init_or_module
+static bool
 __optimize_nops(u8 *instr, size_t len, struct insn *insn, int *next, int *prev, int *target)
 {
        int i = *next - insn->length;
@@ -335,8 +335,7 @@ bool need_reloc(unsigned long offset, u8 *src, size_t src_len)
        return (target < src || target > src + src_len);
 }
 
-static void __init_or_module noinline
-apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
+void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
 {
        int prev, target = 0;
 
index 64ad2ddea121940a99a8c55746986ef0b84c1c41..cf7e5be1b844b2316aab120b21e41b0831dac2b4 100644 (file)
@@ -24,6 +24,8 @@
 
 static int __initdata_or_module debug_callthunks;
 
+#define MAX_PATCH_LEN (255-1)
+
 #define prdbg(fmt, args...)                                    \
 do {                                                           \
        if (debug_callthunks)                                   \
@@ -179,10 +181,15 @@ static const u8 nops[] = {
 static void *patch_dest(void *dest, bool direct)
 {
        unsigned int tsize = SKL_TMPL_SIZE;
+       u8 insn_buff[MAX_PATCH_LEN];
        u8 *pad = dest - tsize;
 
+       memcpy(insn_buff, skl_call_thunk_template, tsize);
+       apply_relocation(insn_buff, tsize, pad,
+                        skl_call_thunk_template, tsize);
+
        /* Already patched? */
-       if (!bcmp(pad, skl_call_thunk_template, tsize))
+       if (!bcmp(pad, insn_buff, tsize))
                return pad;
 
        /* Ensure there are nops */
@@ -192,9 +199,9 @@ static void *patch_dest(void *dest, bool direct)
        }
 
        if (direct)
-               memcpy(pad, skl_call_thunk_template, tsize);
+               memcpy(pad, insn_buff, tsize);
        else
-               text_poke_copy_locked(pad, skl_call_thunk_template, tsize, true);
+               text_poke_copy_locked(pad, insn_buff, tsize, true);
        return pad;
 }
 
@@ -290,20 +297,27 @@ void *callthunks_translate_call_dest(void *dest)
 static bool is_callthunk(void *addr)
 {
        unsigned int tmpl_size = SKL_TMPL_SIZE;
-       void *tmpl = skl_call_thunk_template;
+       u8 insn_buff[MAX_PATCH_LEN];
        unsigned long dest;
+       u8 *pad;
 
        dest = roundup((unsigned long)addr, CONFIG_FUNCTION_ALIGNMENT);
        if (!thunks_initialized || skip_addr((void *)dest))
                return false;
 
-       return !bcmp((void *)(dest - tmpl_size), tmpl, tmpl_size);
+       pad = (void *)(dest - tmpl_size);
+
+       memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
+       apply_relocation(insn_buff, tmpl_size, pad,
+                        skl_call_thunk_template, tmpl_size);
+
+       return !bcmp(pad, insn_buff, tmpl_size);
 }
 
 int x86_call_depth_emit_accounting(u8 **pprog, void *func)
 {
        unsigned int tmpl_size = SKL_TMPL_SIZE;
-       void *tmpl = skl_call_thunk_template;
+       u8 insn_buff[MAX_PATCH_LEN];
 
        if (!thunks_initialized)
                return 0;
@@ -312,7 +326,11 @@ int x86_call_depth_emit_accounting(u8 **pprog, void *func)
        if (func && is_callthunk(func))
                return 0;
 
-       memcpy(*pprog, tmpl, tmpl_size);
+       memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
+       apply_relocation(insn_buff, tmpl_size, *pprog,
+                        skl_call_thunk_template, tmpl_size);
+
+       memcpy(*pprog, insn_buff, tmpl_size);
        *pprog += tmpl_size;
        return tmpl_size;
 }
index 0b97bcde70c6102a4b82b561c3256ec53b614770..8f367d3765208c215c3ad1f560ad5121295cf1e7 100644 (file)
@@ -2050,6 +2050,7 @@ DEFINE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot) = {
        .top_of_stack   = TOP_OF_INIT_STACK,
 };
 EXPORT_PER_CPU_SYMBOL(pcpu_hot);
+EXPORT_PER_CPU_SYMBOL(const_pcpu_hot);
 
 #ifdef CONFIG_X86_64
 DEFINE_PER_CPU_FIRST(struct fixed_percpu_data,
index d4918d03efb4b7765bff35d3e5f28a8c3a2bc99d..bb8ee1ce696836667caa5700b4bcce6cb2ab5488 100644 (file)
@@ -477,7 +477,7 @@ SYM_CODE_START(soft_restart_cpu)
        UNWIND_HINT_END_OF_STACK
 
        /* Find the idle task stack */
-       movq    PER_CPU_VAR(pcpu_hot) + X86_current_task, %rcx
+       movq    PER_CPU_VAR(pcpu_hot + X86_current_task), %rcx
        movq    TASK_threadsp(%rcx), %rsp
 
        jmp     .Ljump_to_C_code
index 708c87b88cc150ee64145de90de938e0482afa3f..0917c7f25720be91372bacddb1a3032323b8996f 100644 (file)
@@ -156,13 +156,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
        struct thread_struct *prev = &prev_p->thread,
                             *next = &next_p->thread;
-       struct fpu *prev_fpu = &prev->fpu;
        int cpu = smp_processor_id();
 
        /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
-       if (!test_thread_flag(TIF_NEED_FPU_LOAD))
-               switch_fpu_prepare(prev_fpu, cpu);
+       if (!test_tsk_thread_flag(prev_p, TIF_NEED_FPU_LOAD))
+               switch_fpu_prepare(prev_p, cpu);
 
        /*
         * Save away %gs. No need to save %fs, as it was saved on the
@@ -209,7 +208,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        raw_cpu_write(pcpu_hot.current_task, next_p);
 
-       switch_fpu_finish();
+       switch_fpu_finish(next_p);
 
        /* Load the Intel cache allocation PQR MSR. */
        resctrl_sched_in(next_p);
index 33b268747bb7bbce00e1b12b8e00928ce7305acc..1553e19904e05fba773cd7064ce19bf00d2b70db 100644 (file)
@@ -562,14 +562,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
        struct thread_struct *prev = &prev_p->thread;
        struct thread_struct *next = &next_p->thread;
-       struct fpu *prev_fpu = &prev->fpu;
        int cpu = smp_processor_id();
 
        WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&
                     this_cpu_read(pcpu_hot.hardirq_stack_inuse));
 
-       if (!test_thread_flag(TIF_NEED_FPU_LOAD))
-               switch_fpu_prepare(prev_fpu, cpu);
+       if (!test_tsk_thread_flag(prev_p, TIF_NEED_FPU_LOAD))
+               switch_fpu_prepare(prev_p, cpu);
 
        /* We must save %fs and %gs before load_TLS() because
         * %fs and %gs may be cleared by load_TLS().
@@ -623,7 +622,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        raw_cpu_write(pcpu_hot.current_task, next_p);
        raw_cpu_write(pcpu_hot.top_of_stack, task_top_of_stack(next_p));
 
-       switch_fpu_finish();
+       switch_fpu_finish(next_p);
 
        /* Reload sp0. */
        update_task_stack(next_p);
index 96a771f9f930a6aba1b77967169808bce3b3eace..2908e063d7d830db32decbfefbd017fd05292700 100644 (file)
@@ -148,14 +148,16 @@ static int register_stop_handler(void)
 
 static void native_stop_other_cpus(int wait)
 {
-       unsigned int cpu = smp_processor_id();
+       unsigned int old_cpu, this_cpu;
        unsigned long flags, timeout;
 
        if (reboot_force)
                return;
 
        /* Only proceed if this is the first CPU to reach this code */
-       if (atomic_cmpxchg(&stopping_cpu, -1, cpu) != -1)
+       old_cpu = -1;
+       this_cpu = smp_processor_id();
+       if (!atomic_try_cmpxchg(&stopping_cpu, &old_cpu, this_cpu))
                return;
 
        /* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */
@@ -186,7 +188,7 @@ static void native_stop_other_cpus(int wait)
         * NMIs.
         */
        cpumask_copy(&cpus_stop_mask, cpu_online_mask);
-       cpumask_clear_cpu(cpu, &cpus_stop_mask);
+       cpumask_clear_cpu(this_cpu, &cpus_stop_mask);
 
        if (!cpumask_empty(&cpus_stop_mask)) {
                apic_send_IPI_allbutself(REBOOT_VECTOR);
@@ -210,6 +212,8 @@ static void native_stop_other_cpus(int wait)
                 * CPUs to stop.
                 */
                if (!smp_no_nmi_ipi && !register_stop_handler()) {
+                       unsigned int cpu;
+
                        pr_emerg("Shutting down cpus with NMI\n");
 
                        for_each_cpu(cpu, &cpus_stop_mask)
index c3b2f863acf0f3f28c7402c86de8cbaa47eb930c..4b256de7c58ac983b9f521122529b18e3d50ed09 100644 (file)
@@ -773,7 +773,7 @@ DEFINE_IDTENTRY_RAW(exc_int3)
  */
 asmlinkage __visible noinstr struct pt_regs *sync_regs(struct pt_regs *eregs)
 {
-       struct pt_regs *regs = (struct pt_regs *)this_cpu_read(pcpu_hot.top_of_stack) - 1;
+       struct pt_regs *regs = (struct pt_regs *)current_top_of_stack() - 1;
        if (regs != eregs)
                *regs = *eregs;
        return regs;
@@ -791,7 +791,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r
         * trust it and switch to the current kernel stack
         */
        if (ip_within_syscall_gap(regs)) {
-               sp = this_cpu_read(pcpu_hot.top_of_stack);
+               sp = current_top_of_stack();
                goto sync;
        }
 
index a349dbfc6d5ab47b2f8963bacd24915a963cb2a2..9be175c8ac975b46c61ebb75a47160fb6bf1deb1 100644 (file)
@@ -46,6 +46,7 @@ ENTRY(phys_startup_64)
 #endif
 
 jiffies = jiffies_64;
+const_pcpu_hot = pcpu_hot;
 
 #if defined(CONFIG_X86_64)
 /*
index 6962df3157938d9936895d67d5b18806844fb761..4fb44894ad87593266f9de2b8c71ddbad2166cbe 100644 (file)
@@ -23,14 +23,14 @@ SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
        cli
 
        /* if (*ptr == old) */
-       cmpq    PER_CPU_VAR(0(%rsi)), %rax
+       cmpq    __percpu (%rsi), %rax
        jne     .Lnot_same
-       cmpq    PER_CPU_VAR(8(%rsi)), %rdx
+       cmpq    __percpu 8(%rsi), %rdx
        jne     .Lnot_same
 
        /* *ptr = new */
-       movq    %rbx, PER_CPU_VAR(0(%rsi))
-       movq    %rcx, PER_CPU_VAR(8(%rsi))
+       movq    %rbx, __percpu (%rsi)
+       movq    %rcx, __percpu 8(%rsi)
 
        /* set ZF in EFLAGS to indicate success */
        orl     $X86_EFLAGS_ZF, (%rsp)
@@ -42,8 +42,8 @@ SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
        /* *ptr != old */
 
        /* old = *ptr */
-       movq    PER_CPU_VAR(0(%rsi)), %rax
-       movq    PER_CPU_VAR(8(%rsi)), %rdx
+       movq    __percpu (%rsi), %rax
+       movq    __percpu 8(%rsi), %rdx
 
        /* clear ZF in EFLAGS to indicate failure */
        andl    $(~X86_EFLAGS_ZF), (%rsp)
index 873e4ef23e49578989634629b728d4c61bcd96b4..1c96be769adc3e98c87d63dc623ed21cf770129b 100644 (file)
@@ -24,12 +24,12 @@ SYM_FUNC_START(cmpxchg8b_emu)
        pushfl
        cli
 
-       cmpl    0(%esi), %eax
+       cmpl    (%esi), %eax
        jne     .Lnot_same
        cmpl    4(%esi), %edx
        jne     .Lnot_same
 
-       movl    %ebx, 0(%esi)
+       movl    %ebx, (%esi)
        movl    %ecx, 4(%esi)
 
        orl     $X86_EFLAGS_ZF, (%esp)
@@ -38,7 +38,7 @@ SYM_FUNC_START(cmpxchg8b_emu)
        RET
 
 .Lnot_same:
-       movl    0(%esi), %eax
+       movl    (%esi), %eax
        movl    4(%esi), %edx
 
        andl    $(~X86_EFLAGS_ZF), (%esp)
@@ -53,18 +53,30 @@ EXPORT_SYMBOL(cmpxchg8b_emu)
 
 #ifndef CONFIG_UML
 
+/*
+ * Emulate 'cmpxchg8b %fs:(%rsi)'
+ *
+ * Inputs:
+ * %esi : memory location to compare
+ * %eax : low 32 bits of old value
+ * %edx : high 32 bits of old value
+ * %ebx : low 32 bits of new value
+ * %ecx : high 32 bits of new value
+ *
+ * Notably this is not LOCK prefixed and is not safe against NMIs
+ */
 SYM_FUNC_START(this_cpu_cmpxchg8b_emu)
 
        pushfl
        cli
 
-       cmpl    PER_CPU_VAR(0(%esi)), %eax
+       cmpl    __percpu (%esi), %eax
        jne     .Lnot_same2
-       cmpl    PER_CPU_VAR(4(%esi)), %edx
+       cmpl    __percpu 4(%esi), %edx
        jne     .Lnot_same2
 
-       movl    %ebx, PER_CPU_VAR(0(%esi))
-       movl    %ecx, PER_CPU_VAR(4(%esi))
+       movl    %ebx, __percpu (%esi)
+       movl    %ecx, __percpu 4(%esi)
 
        orl     $X86_EFLAGS_ZF, (%esp)
 
@@ -72,8 +84,8 @@ SYM_FUNC_START(this_cpu_cmpxchg8b_emu)
        RET
 
 .Lnot_same2:
-       movl    PER_CPU_VAR(0(%esi)), %eax
-       movl    PER_CPU_VAR(4(%esi)), %edx
+       movl    __percpu (%esi), %eax
+       movl    __percpu 4(%esi), %edx
 
        andl    $(~X86_EFLAGS_ZF), (%esp)
 
index 1a9cd18dfbd31208e5d1bcfa53f4a6e90bc81cf6..83189cf5cdce9361c6a878f1e8ce86e285ad9ba1 100644 (file)
@@ -28,7 +28,7 @@
  * non-zero.
  */
 SYM_FUNC_START(xen_irq_disable_direct)
-       movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+       movb $1, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
        RET
 SYM_FUNC_END(xen_irq_disable_direct)
 
@@ -69,7 +69,7 @@ SYM_FUNC_END(check_events)
 SYM_FUNC_START(xen_irq_enable_direct)
        FRAME_BEGIN
        /* Unmask events */
-       movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+       movb $0, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
 
        /*
         * Preempt here doesn't matter because that will deal with any
@@ -78,7 +78,7 @@ SYM_FUNC_START(xen_irq_enable_direct)
         */
 
        /* Test for pending */
-       testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_pending)
        jz 1f
 
        call check_events
@@ -97,7 +97,7 @@ SYM_FUNC_END(xen_irq_enable_direct)
  * x86 use opposite senses (mask vs enable).
  */
 SYM_FUNC_START(xen_save_fl_direct)
-       testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
        setz %ah
        addb %ah, %ah
        RET
@@ -113,7 +113,7 @@ SYM_FUNC_END(xen_read_cr2);
 
 SYM_FUNC_START(xen_read_cr2_direct)
        FRAME_BEGIN
-       _ASM_MOV PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_arch_cr2, %_ASM_AX
+       _ASM_MOV PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_arch_cr2), %_ASM_AX
        FRAME_END
        RET
 SYM_FUNC_END(xen_read_cr2_direct);
index bb1339c7057b49c877907e9db968e828a28d0f3f..cdcdaa48b4d2d705f0aa59dfe3450f73bc76b180 100644 (file)
@@ -209,7 +209,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
  */
 #define ___ADDRESSABLE(sym, __attrs) \
        static void * __used __attrs \
-               __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)&sym;
+       __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)(uintptr_t)&sym;
 #define __ADDRESSABLE(sym) \
        ___ADDRESSABLE(sym, __section(".discard.addressable"))