diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 6ebb81030d2d..fe77e3395b40 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -124,7 +124,8 @@ #endif #ifdef CONFIG_EVENT_TRACING -#define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \ +#define FTRACE_EVENTS() . = ALIGN(8); \ + VMLINUX_SYMBOL(__start_ftrace_events) = .; \ *(_ftrace_events) \ VMLINUX_SYMBOL(__stop_ftrace_events) = .; #else @@ -140,7 +141,8 @@ #endif #ifdef CONFIG_FTRACE_SYSCALLS -#define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ +#define TRACE_SYSCALLS() . = ALIGN(8); \ + VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ *(__syscalls_metadata) \ VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; #else @@ -165,10 +167,8 @@ CPU_KEEP(exit.data) \ MEM_KEEP(init.data) \ MEM_KEEP(exit.data) \ - . = ALIGN(32); \ - VMLINUX_SYMBOL(__start___tracepoints) = .; \ + STRUCT_ALIGN(); \ *(__tracepoints) \ - VMLINUX_SYMBOL(__stop___tracepoints) = .; \ /* implement dynamic printk debug */ \ . = ALIGN(8); \ VMLINUX_SYMBOL(__start___verbose) = .; \ @@ -176,13 +176,7 @@ VMLINUX_SYMBOL(__stop___verbose) = .; \ LIKELY_PROFILE() \ BRANCH_PROFILE() \ - TRACE_PRINTKS() \ - \ - STRUCT_ALIGN(); \ - FTRACE_EVENTS() \ - \ - STRUCT_ALIGN(); \ - TRACE_SYSCALLS() + TRACE_PRINTKS() /* * Data section helpers @@ -220,6 +214,10 @@ VMLINUX_SYMBOL(__start_rodata) = .; \ *(.rodata) *(.rodata.*) \ *(__vermagic) /* Kernel version magic */ \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .; \ + *(__tracepoints_ptrs) /* Tracepoints: pointer array */\ + VMLINUX_SYMBOL(__stop___tracepoints_ptrs) = .; \ *(__markers_strings) /* Markers: strings */ \ *(__tracepoints_strings)/* Tracepoints: strings */ \ } \ @@ -482,6 +480,8 @@ KERNEL_CTORS() \ *(.init.rodata) \ MCOUNT_REC() \ + FTRACE_EVENTS() \ + TRACE_SYSCALLS() \ DEV_DISCARD(init.rodata) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.rodata) \ diff --git a/include/linux/module.h b/include/linux/module.h index e7c6385c6683..9bdf27c7615b 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -377,7 +377,7 @@ struct module keeping pointers to this stuff */ char *args; #ifdef CONFIG_TRACEPOINTS - struct tracepoint *tracepoints; + struct tracepoint * const *tracepoints_ptrs; unsigned int num_tracepoints; #endif #ifdef HAVE_JUMP_LABEL @@ -389,7 +389,7 @@ struct module unsigned int num_trace_bprintk_fmt; #endif #ifdef CONFIG_EVENT_TRACING - struct ftrace_event_call *trace_events; + struct ftrace_event_call **trace_events; unsigned int num_trace_events; #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 18cd0684fc4e..98664db1be47 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -125,39 +125,37 @@ extern struct trace_event_functions enter_syscall_print_funcs; extern struct trace_event_functions exit_syscall_print_funcs; #define SYSCALL_TRACE_ENTER_EVENT(sname) \ - static struct syscall_metadata \ - __attribute__((__aligned__(4))) __syscall_meta_##sname; \ + static struct syscall_metadata __syscall_meta_##sname; \ static struct ftrace_event_call __used \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_events"))) \ event_enter_##sname = { \ .name = "sys_enter"#sname, \ .class = &event_class_syscall_enter, \ .event.funcs = &enter_syscall_print_funcs, \ .data = (void *)&__syscall_meta_##sname,\ }; \ + static struct ftrace_event_call __used \ + __attribute__((section("_ftrace_events"))) \ + *__event_enter_##sname = &event_enter_##sname; \ __TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY) #define SYSCALL_TRACE_EXIT_EVENT(sname) \ - static struct syscall_metadata \ - __attribute__((__aligned__(4))) __syscall_meta_##sname; \ + static struct syscall_metadata __syscall_meta_##sname; \ static struct ftrace_event_call __used \ - __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_events"))) \ event_exit_##sname = { \ .name = "sys_exit"#sname, \ .class = &event_class_syscall_exit, \ .event.funcs = &exit_syscall_print_funcs, \ .data = (void *)&__syscall_meta_##sname,\ }; \ + static struct ftrace_event_call __used \ + __attribute__((section("_ftrace_events"))) \ + *__event_exit_##sname = &event_exit_##sname; \ __TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY) #define SYSCALL_METADATA(sname, nb) \ SYSCALL_TRACE_ENTER_EVENT(sname); \ SYSCALL_TRACE_EXIT_EVENT(sname); \ static struct syscall_metadata __used \ - __attribute__((__aligned__(4))) \ - __attribute__((section("__syscalls_metadata"))) \ __syscall_meta_##sname = { \ .name = "sys"#sname, \ .nb_args = nb, \ @@ -166,14 +164,15 @@ extern struct trace_event_functions exit_syscall_print_funcs; .enter_event = &event_enter_##sname, \ .exit_event = &event_exit_##sname, \ .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ - }; + }; \ + static struct syscall_metadata __used \ + __attribute__((section("__syscalls_metadata"))) \ + *__p_syscall_meta_##sname = &__syscall_meta_##sname; #define SYSCALL_DEFINE0(sname) \ SYSCALL_TRACE_ENTER_EVENT(_##sname); \ SYSCALL_TRACE_EXIT_EVENT(_##sname); \ static struct syscall_metadata __used \ - __attribute__((__aligned__(4))) \ - __attribute__((section("__syscalls_metadata"))) \ __syscall_meta__##sname = { \ .name = "sys_"#sname, \ .nb_args = 0, \ @@ -181,6 +180,9 @@ extern struct trace_event_functions exit_syscall_print_funcs; .exit_event = &event_exit__##sname, \ .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ }; \ + static struct syscall_metadata __used \ + __attribute__((section("__syscalls_metadata"))) \ + *__p_syscall_meta_##sname = &__syscall_meta__##sname; \ asmlinkage long sys_##sname(void) #else #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index c6814616653b..97c84a58efb8 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -33,12 +33,7 @@ struct tracepoint { void (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; -} __attribute__((aligned(32))); /* - * Aligned on 32 bytes because it is - * globally visible and gcc happily - * align these on the structure size. - * Keep in sync with vmlinux.lds.h. - */ +}; /* * Connect a probe to a tracepoint. @@ -61,15 +56,15 @@ extern void tracepoint_probe_update_all(void); struct tracepoint_iter { struct module *module; - struct tracepoint *tracepoint; + struct tracepoint * const *tracepoint; }; extern void tracepoint_iter_start(struct tracepoint_iter *iter); extern void tracepoint_iter_next(struct tracepoint_iter *iter); extern void tracepoint_iter_stop(struct tracepoint_iter *iter); extern void tracepoint_iter_reset(struct tracepoint_iter *iter); -extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, - struct tracepoint *begin, struct tracepoint *end); +extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, + struct tracepoint * const *begin, struct tracepoint * const *end); /* * tracepoint_synchronize_unregister must be called between the last tracepoint @@ -84,11 +79,13 @@ static inline void tracepoint_synchronize_unregister(void) #define PARAMS(args...) args #ifdef CONFIG_TRACEPOINTS -extern void tracepoint_update_probe_range(struct tracepoint *begin, - struct tracepoint *end); +extern +void tracepoint_update_probe_range(struct tracepoint * const *begin, + struct tracepoint * const *end); #else -static inline void tracepoint_update_probe_range(struct tracepoint *begin, - struct tracepoint *end) +static inline +void tracepoint_update_probe_range(struct tracepoint * const *begin, + struct tracepoint * const *end) { } #endif /* CONFIG_TRACEPOINTS */ @@ -174,12 +171,20 @@ do_trace: \ { \ } +/* + * We have no guarantee that gcc and the linker won't up-align the tracepoint + * structures, so we create an array of pointers that will be used for iteration + * on the tracepoints. + */ #define DEFINE_TRACE_FN(name, reg, unreg) \ static const char __tpstrtab_##name[] \ __attribute__((section("__tracepoints_strings"))) = #name; \ struct tracepoint __tracepoint_##name \ - __attribute__((section("__tracepoints"), aligned(32))) = \ - { __tpstrtab_##name, 0, reg, unreg, NULL } + __attribute__((section("__tracepoints"))) = \ + { __tpstrtab_##name, 0, reg, unreg, NULL }; \ + static struct tracepoint * const __tracepoint_ptr_##name __used \ + __attribute__((section("__tracepoints_ptrs"))) = \ + &__tracepoint_##name; #define DEFINE_TRACE(name) \ DEFINE_TRACE_FN(name, NULL, NULL); diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index e16610c208c9..3e68366d485a 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -446,14 +446,16 @@ static inline notrace int ftrace_get_offsets_##call( \ * .reg = ftrace_event_reg, * }; * - * static struct ftrace_event_call __used - * __attribute__((__aligned__(4))) - * __attribute__((section("_ftrace_events"))) event_ = { + * static struct ftrace_event_call event_ = { * .name = "", * .class = event_class_