On 5/17/26 21:28, Eva Kurchatova wrote:
From: Mathieu Desnoyers <[email protected]>

Commit 1d562f197d01a ("ms/objtool: Exclude __tracepoints data from
ENDBR checks") was backported from mainstream, which excludes the
__tracepoints section from objtool's IBT validation. This causes
regfunc/unregfunc function pointers stored directly in struct tracepoint
to have their ENDBR instructions incorrectly sealed at boot, resulting
in a kernel crash when called indirectly with CONFIG_X86_KERNEL_IBT=y.

In mainstream, this commit amends the crash by moving regfunc/unregfunc
into a separate struct tracepoint_ext outside the __tracepoints section,
and should be backported alongside it.

When you backport a commit from mainstream (or from any place),
please do not change the original commit message at all and post the full 
original commit message.

Your add-ons to the commit message should go under the original commit message.


Tested-by: Jordan Rife <[email protected]>
Cc: Michael Jeanson <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Yonghong Song <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Andrii Nakryiko <[email protected]>
Cc: [email protected]
Cc: Joel Fernandes <[email protected]>
Cc: Jordan Rife <[email protected]>
Cc: [email protected]
Link: 
https://lore.kernel.org/[email protected]
Signed-off-by: Mathieu Desnoyers <[email protected]>
Signed-off-by: Steven Rostedt (Google) <[email protected]>

(cherry picked from commit a9cfb8778c43fc473ae16cddb6e9611705721b31)
Signed-off-by: Eva Kurchatova <[email protected]>

https://virtuozzo.atlassian.net/browse/VSTOR-131560
Feature: fix tracepoint
---
  include/linux/tracepoint-defs.h |  8 ++++++--
  include/linux/tracepoint.h      | 19 +++++++++++++------
  kernel/tracepoint.c             |  8 ++++----
  3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h
index 4dc4955f0fbf..e1af02e375d6 100644
--- a/include/linux/tracepoint-defs.h
+++ b/include/linux/tracepoint-defs.h
@@ -29,6 +29,11 @@ struct tracepoint_func {
        int prio;
  };
+struct tracepoint_ext {
+       int (*regfunc)(void);
+       void (*unregfunc)(void);
+};
+
  struct tracepoint {
        const char *name;               /* Tracepoint name */
        struct static_key key;
@@ -36,9 +41,8 @@ struct tracepoint {
        void *static_call_tramp;
        void *iterator;
        void *probestub;
-       int (*regfunc)(void);
-       void (*unregfunc)(void);
        struct tracepoint_func __rcu *funcs;
+       struct tracepoint_ext *ext;
  };
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 93a9f3070b48..583d962abcc3 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -319,7 +319,7 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
   * structures, so we create an array of pointers that will be used for 
iteration
   * on the tracepoints.
   */
-#define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args)              \
+#define __DEFINE_TRACE_EXT(_name, _ext, proto, args)                   \
        static const char __tpstrtab_##_name[]                          \
        __section("__tracepoints_strings") = #_name;                  \
        extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
@@ -333,9 +333,9 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
                .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
                .iterator = &__traceiter_##_name,                   \
                .probestub = &__probestub_##_name,                  \
-               .regfunc = _reg,                                        \
-               .unregfunc = _unreg,                                    \
-               .funcs = NULL };                                        \
+               .funcs = NULL,                                          \
+               .ext = _ext,                                            \
+       };                                                              \
        __TRACEPOINT_ENTRY(_name);                                      \
        int __traceiter_##_name(void *__data, proto)                    \
        {                                                               \
@@ -358,8 +358,15 @@ static inline struct tracepoint 
*tracepoint_ptr_deref(tracepoint_ptr_t *p)
        }                                                               \
        DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
-#define DEFINE_TRACE(name, proto, args) \
-       DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args));
+#define DEFINE_TRACE_FN(_name, _reg, _unreg, _proto, _args)            \
+       static struct tracepoint_ext __tracepoint_ext_##_name = {       \
+               .regfunc = _reg,                                        \
+               .unregfunc = _unreg,                                    \
+       };                                                              \
+       __DEFINE_TRACE_EXT(_name, &__tracepoint_ext_##_name, PARAMS(_proto), 
PARAMS(_args));
+
+#define DEFINE_TRACE(_name, _proto, _args)                             \
+       __DEFINE_TRACE_EXT(_name, NULL, PARAMS(_proto), PARAMS(_args));
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
        EXPORT_SYMBOL_GPL(__tracepoint_##name);                         \
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 8879da16ef4d..ebab4290d486 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -327,8 +327,8 @@ static int tracepoint_add_func(struct tracepoint *tp,
        struct tracepoint_func *old, *tp_funcs;
        int ret;
- if (tp->regfunc && !static_key_enabled(&tp->key)) {
-               ret = tp->regfunc();
+       if (tp->ext && tp->ext->regfunc && !static_key_enabled(&tp->key)) {
+               ret = tp->ext->regfunc();
                if (ret < 0)
                        return ret;
        }
@@ -411,8 +411,8 @@ static int tracepoint_remove_func(struct tracepoint *tp,
        switch (nr_func_state(tp_funcs)) {
        case TP_FUNC_0:         /* 1->0 */
                /* Removed last function */
-               if (tp->unregfunc && static_key_enabled(&tp->key))
-                       tp->unregfunc();
+               if (tp->ext && tp->ext->unregfunc && 
static_key_enabled(&tp->key))
+                       tp->ext->unregfunc();
static_key_disable(&tp->key);
                /* Set iterator static call */

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to