mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
tracepoint: Fix tracepoint array element size mismatch
commit 46e0c9be20 ("kernel: tracepoints: add support for relative
references") changes the layout of the __tracepoint_ptrs section on
architectures supporting relative references. However, it does so
without turning struct tracepoint * const into const int elsewhere in
the tracepoint code, which has the following side-effect:
Setting mod->num_tracepoints is done in by module.c:
mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs",
sizeof(*mod->tracepoints_ptrs),
&mod->num_tracepoints);
Basically, since sizeof(*mod->tracepoints_ptrs) is a pointer size
(rather than sizeof(int)), num_tracepoints is erroneously set to half the
size it should be on 64-bit arch. So a module with an odd number of
tracepoints misses the last tracepoint due to effect of integer
division.
So in the module going notifier:
for_each_tracepoint_range(mod->tracepoints_ptrs,
mod->tracepoints_ptrs + mod->num_tracepoints,
tp_module_going_check_quiescent, NULL);
the expression (mod->tracepoints_ptrs + mod->num_tracepoints) actually
evaluates to something within the bounds of the array, but miss the
last tracepoint if the number of tracepoints is odd on 64-bit arch.
Fix this by introducing a new typedef: tracepoint_ptr_t, which
is either "const int" on architectures that have PREL32 relocations,
or "struct tracepoint * const" on architectures that does not have
this feature.
Also provide a new tracepoint_ptr_defer() static inline to
encapsulate deferencing this type rather than duplicate code and
ugly idefs within the for_each_tracepoint_range() implementation.
This issue appears in 4.19-rc kernels, and should ideally be fixed
before the end of the rc cycle.
Acked-by: Ard Biesheuvel <[email protected]>
Acked-by: Jessica Yu <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Cc: Michael Ellerman <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: James Morris <[email protected]>
Cc: James Morris <[email protected]>
Cc: Josh Poimboeuf <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Nicolas Pitre <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Petr Mladek <[email protected]>
Cc: Russell King <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: Sergey Senozhatsky <[email protected]>
Cc: Thomas Garnier <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Mathieu Desnoyers <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
This commit is contained in:
parent
62165600ae
commit
9c0be3f6b5
4 changed files with 39 additions and 30 deletions
|
|
@ -28,8 +28,8 @@
|
|||
#include <linux/sched/task.h>
|
||||
#include <linux/static_key.h>
|
||||
|
||||
extern struct tracepoint * const __start___tracepoints_ptrs[];
|
||||
extern struct tracepoint * const __stop___tracepoints_ptrs[];
|
||||
extern tracepoint_ptr_t __start___tracepoints_ptrs[];
|
||||
extern tracepoint_ptr_t __stop___tracepoints_ptrs[];
|
||||
|
||||
DEFINE_SRCU(tracepoint_srcu);
|
||||
EXPORT_SYMBOL_GPL(tracepoint_srcu);
|
||||
|
|
@ -371,25 +371,17 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
|
||||
|
||||
static void for_each_tracepoint_range(struct tracepoint * const *begin,
|
||||
struct tracepoint * const *end,
|
||||
static void for_each_tracepoint_range(
|
||||
tracepoint_ptr_t *begin, tracepoint_ptr_t *end,
|
||||
void (*fct)(struct tracepoint *tp, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
tracepoint_ptr_t *iter;
|
||||
|
||||
if (!begin)
|
||||
return;
|
||||
|
||||
if (IS_ENABLED(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)) {
|
||||
const int *iter;
|
||||
|
||||
for (iter = (const int *)begin; iter < (const int *)end; iter++)
|
||||
fct(offset_to_ptr(iter), priv);
|
||||
} else {
|
||||
struct tracepoint * const *iter;
|
||||
|
||||
for (iter = begin; iter < end; iter++)
|
||||
fct(*iter, priv);
|
||||
}
|
||||
for (iter = begin; iter < end; iter++)
|
||||
fct(tracepoint_ptr_deref(iter), priv);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
|
|
|||
Loading…
Reference in a new issue