From 0b0cae7119a0ec9449d7261b5e672a5fed765068 Mon Sep 17 00:00:00 2001 From: "Mike Rapoport (Microsoft)" Date: Tue, 3 Jun 2025 14:14:43 +0300 Subject: x86/its: move its_pages array to struct mod_arch_specific The of pages with ITS thunks allocated for modules are tracked by an array in 'struct module'. Since this is very architecture specific data structure, move it to 'struct mod_arch_specific'. No functional changes. Fixes: 872df34d7c51 ("x86/its: Use dynamic thunks for indirect branches") Suggested-by: Peter Zijlstra (Intel) Signed-off-by: Mike Rapoport (Microsoft) Signed-off-by: Peter Zijlstra (Intel) Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20250603111446.2609381-4-rppt@kernel.org --- include/linux/module.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux/module.h') diff --git a/include/linux/module.h b/include/linux/module.h index 92e1420fccdf..5faa1fb1f4b4 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -586,11 +586,6 @@ struct module { atomic_t refcnt; #endif -#ifdef CONFIG_MITIGATION_ITS - int its_num_pages; - void **its_page_array; -#endif - #ifdef CONFIG_CONSTRUCTORS /* Constructor functions. */ ctor_fn_t *ctors; -- cgit v1.2.3 From e3d6e1b9a34c745b635f122ac471a198867cd0ec Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Tue, 1 Apr 2025 00:36:02 +0900 Subject: tracing: tprobe-events: Support multiple tprobes on the same tracepoint Allow user to set multiple tracepoint-probe events on the same tracepoint. After the last tprobe-event is removed, the tracepoint callback is unregistered. Link: https://lore.kernel.org/all/174343536245.843280.6548776576601537671.stgit@devnote2/ Signed-off-by: Masami Hiramatsu (Google) --- include/linux/module.h | 4 + kernel/trace/trace_fprobe.c | 251 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 205 insertions(+), 50 deletions(-) (limited to 'include/linux/module.h') diff --git a/include/linux/module.h b/include/linux/module.h index 5faa1fb1f4b4..2cb5be5cc7e6 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1019,4 +1020,7 @@ static inline unsigned long find_kallsyms_symbol_value(struct module *mod, #endif /* CONFIG_MODULES && CONFIG_KALLSYMS */ +/* Define __free(module_put) macro for struct module *. */ +DEFINE_FREE(module_put, struct module *, if (_T) module_put(_T)) + #endif /* _LINUX_MODULE_H */ diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 017d6ebfdf8b..4a9ce7b0e084 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -21,7 +21,6 @@ #define FPROBE_EVENT_SYSTEM "fprobes" #define TRACEPOINT_EVENT_SYSTEM "tracepoints" #define RETHOOK_MAXACTIVE_MAX 4096 -#define TRACEPOINT_STUB ERR_PTR(-ENOENT) static int trace_fprobe_create(const char *raw_command); static int trace_fprobe_show(struct seq_file *m, struct dyn_event *ev); @@ -38,6 +37,89 @@ static struct dyn_event_operations trace_fprobe_ops = { .match = trace_fprobe_match, }; +struct tracepoint_user { + struct tracepoint *tpoint; + unsigned int refcount; +}; + +static bool tracepoint_user_is_registered(struct tracepoint_user *tuser) +{ + return tuser && tuser->tpoint; +} + +static int tracepoint_user_register(struct tracepoint_user *tuser) +{ + struct tracepoint *tpoint = tuser->tpoint; + + if (!tpoint) + return 0; + + return tracepoint_probe_register_prio_may_exist(tpoint, + tpoint->probestub, NULL, 0); +} + +static void tracepoint_user_unregister(struct tracepoint_user *tuser) +{ + if (!tuser->tpoint) + return; + + WARN_ON_ONCE(tracepoint_probe_unregister(tuser->tpoint, tuser->tpoint->probestub, NULL)); + tuser->tpoint = NULL; +} + +static unsigned long tracepoint_user_ip(struct tracepoint_user *tuser) +{ + if (!tuser->tpoint) + return 0UL; + + return (unsigned long)tuser->tpoint->probestub; +} + +static bool tracepoint_user_within_module(struct tracepoint_user *tuser, + struct module *mod) +{ + return within_module(tracepoint_user_ip(tuser), mod); +} + +static struct tracepoint_user *tracepoint_user_allocate(struct tracepoint *tpoint) +{ + struct tracepoint_user *tuser; + + tuser = kzalloc(sizeof(*tuser), GFP_KERNEL); + if (!tuser) + return NULL; + tuser->tpoint = tpoint; + tuser->refcount = 1; + + return tuser; +} + +/* These must be called with event_mutex */ +static void tracepoint_user_get(struct tracepoint_user *tuser) +{ + tuser->refcount++; +} + +static void tracepoint_user_put(struct tracepoint_user *tuser) +{ + if (--tuser->refcount > 0) + return; + + if (tracepoint_user_is_registered(tuser)) + tracepoint_user_unregister(tuser); + kfree(tuser); +} + +static const char *tracepoint_user_lookup(struct tracepoint_user *tuser, char *buf) +{ + struct tracepoint *tpoint = tuser->tpoint; + + if (!tpoint) + return NULL; + + return kallsyms_lookup((unsigned long)tpoint->probestub, NULL, NULL, NULL, buf); +} + /* * Fprobe event core functions */ @@ -45,7 +127,7 @@ struct trace_fprobe { struct dyn_event devent; struct fprobe fp; const char *symbol; - struct tracepoint *tpoint; + struct tracepoint_user *tuser; struct trace_probe tp; }; @@ -75,7 +157,7 @@ static bool trace_fprobe_is_return(struct trace_fprobe *tf) static bool trace_fprobe_is_tracepoint(struct trace_fprobe *tf) { - return tf->tpoint != NULL; + return tf->tuser != NULL; } static const char *trace_fprobe_symbol(struct trace_fprobe *tf) @@ -125,6 +207,56 @@ static bool trace_fprobe_is_registered(struct trace_fprobe *tf) return fprobe_is_registered(&tf->fp); } +static struct tracepoint *find_tracepoint(const char *tp_name, + struct module **tp_mod); + +/* + * Get tracepoint_user if exist, or allocate new one. If tracepoint is on a + * module, get its refcounter. + */ +static struct tracepoint_user * +trace_fprobe_get_tracepoint_user(const char *name, struct module **pmod) +{ + struct tracepoint_user *tuser __free(kfree) = NULL; + struct tracepoint *tpoint; + struct trace_fprobe *tf; + struct dyn_event *dpos; + struct module *mod __free(module_put) = NULL; + int ret; + + /* + * Find appropriate tracepoint and locking module. + * Note: tpoint can be NULL if it is unloaded (or failed to get module.) + */ + tpoint = find_tracepoint(name, &mod); + + /* Search existing tracepoint_user */ + for_each_trace_fprobe(tf, dpos) { + if (!trace_fprobe_is_tracepoint(tf)) + continue; + if (!strcmp(tf->symbol, name)) { + tracepoint_user_get(tf->tuser); + *pmod = no_free_ptr(mod); + return tf->tuser; + } + } + + /* Not found, allocate and register new tracepoint_user. */ + tuser = tracepoint_user_allocate(tpoint); + if (!tuser) + return NULL; + + if (tpoint) { + /* If the tracepoint is not loaded, tpoint can be NULL. */ + ret = tracepoint_user_register(tuser); + if (ret) + return ERR_PTR(ret); + } + + *pmod = no_free_ptr(mod); + return_ptr(tuser); +} + /* * Note that we don't verify the fetch_insn code, since it does not come * from user space. @@ -410,6 +542,8 @@ static void free_trace_fprobe(struct trace_fprobe *tf) { if (tf) { trace_probe_cleanup(&tf->tp); + if (tf->tuser) + tracepoint_user_put(tf->tuser); kfree(tf->symbol); kfree(tf); } @@ -424,7 +558,7 @@ DEFINE_FREE(free_trace_fprobe, struct trace_fprobe *, if (!IS_ERR_OR_NULL(_T)) f static struct trace_fprobe *alloc_trace_fprobe(const char *group, const char *event, const char *symbol, - struct tracepoint *tpoint, + struct tracepoint_user *tuser, int nargs, bool is_return) { struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; @@ -443,7 +577,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group, else tf->fp.entry_handler = fentry_dispatcher; - tf->tpoint = tpoint; + tf->tuser = tuser; ret = trace_probe_init(&tf->tp, event, group, false, nargs); if (ret < 0) @@ -709,19 +843,11 @@ static int unregister_fprobe_event(struct trace_fprobe *tf) static int __regsiter_tracepoint_fprobe(struct trace_fprobe *tf) { - struct tracepoint *tpoint = tf->tpoint; - unsigned long ip = (unsigned long)tpoint->probestub; - int ret; + unsigned long ip = tracepoint_user_ip(tf->tuser); + + if (!ip) + return -ENOENT; - /* - * Here, we do 2 steps to enable fprobe on a tracepoint. - * At first, put __probestub_##TP function on the tracepoint - * and put a fprobe on the stub function. - */ - ret = tracepoint_probe_register_prio_may_exist(tpoint, - tpoint->probestub, NULL, 0); - if (ret < 0) - return ret; return register_fprobe_ips(&tf->fp, &ip, 1); } @@ -753,7 +879,7 @@ static int __register_trace_fprobe(struct trace_fprobe *tf) if (trace_fprobe_is_tracepoint(tf)) { /* This tracepoint is not loaded yet */ - if (tf->tpoint == TRACEPOINT_STUB) + if (!tracepoint_user_is_registered(tf->tuser)) return 0; return __regsiter_tracepoint_fprobe(tf); @@ -770,9 +896,8 @@ static void __unregister_trace_fprobe(struct trace_fprobe *tf) unregister_fprobe(&tf->fp); memset(&tf->fp, 0, sizeof(tf->fp)); if (trace_fprobe_is_tracepoint(tf)) { - tracepoint_probe_unregister(tf->tpoint, - tf->tpoint->probestub, NULL); - tf->tpoint = NULL; + tracepoint_user_put(tf->tuser); + tf->tuser = NULL; } } } @@ -988,7 +1113,7 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, unsigned long val, void *data) { struct tp_module *tp_mod = data; - struct tracepoint *tpoint; + struct tracepoint_user *tuser; struct trace_fprobe *tf; struct dyn_event *pos; @@ -999,21 +1124,46 @@ static int __tracepoint_probe_module_cb(struct notifier_block *self, for_each_trace_fprobe(tf, pos) { if (!trace_fprobe_is_tracepoint(tf)) continue; - if (val == MODULE_STATE_COMING && tf->tpoint == TRACEPOINT_STUB) { + + if (val == MODULE_STATE_COMING) { + /* + * If any tracepoint used by tprobe is in the module, + * register the stub. + */ + struct tracepoint *tpoint; + tpoint = find_tracepoint_in_module(tp_mod->mod, tf->symbol); - if (tpoint) { - tf->tpoint = tpoint; - if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && - trace_probe_is_enabled(&tf->tp)) - reenable_trace_fprobe(tf); + /* This is not a tracepoint in this module. Skip it. */ + if (!tpoint) + continue; + + tuser = tf->tuser; + /* If the tracepoint is not registered yet, register it. */ + if (!tracepoint_user_is_registered(tuser)) { + tuser->tpoint = tpoint; + if (WARN_ON_ONCE(tracepoint_user_register(tuser))) + continue; } - } else if (val == MODULE_STATE_GOING && - tf->tpoint != TRACEPOINT_STUB && - within_module((unsigned long)tf->tpoint->probestub, tp_mod->mod)) { - unregister_fprobe(&tf->fp); - tracepoint_probe_unregister(tf->tpoint, - tf->tpoint->probestub, NULL); - tf->tpoint = TRACEPOINT_STUB; + + /* Finally enable fprobe on this module. */ + if (!WARN_ON_ONCE(__regsiter_tracepoint_fprobe(tf)) && + trace_probe_is_enabled(&tf->tp)) + reenable_trace_fprobe(tf); + } else if (val == MODULE_STATE_GOING) { + tuser = tf->tuser; + /* Unregister all tracepoint_user in this module. */ + if (tracepoint_user_is_registered(tuser) && + tracepoint_user_within_module(tuser, tp_mod->mod)) + tracepoint_user_unregister(tuser); + + /* + * Here we need to handle shared tracepoint_user case. + * Such tuser is unregistered, but trace_fprobe itself + * is registered. (Note this only handles tprobes.) + */ + if (!tracepoint_user_is_registered(tuser) && + trace_fprobe_is_registered(tf)) + unregister_fprobe(&tf->fp); } } mutex_unlock(&event_mutex); @@ -1082,7 +1232,9 @@ static int parse_symbol_and_return(int argc, const char *argv[], return 0; } -DEFINE_FREE(module_put, struct module *, if (_T) module_put(_T)) +DEFINE_FREE(tuser_put, struct tracepoint_user *, + if (!IS_ERR_OR_NULL(_T)) + tracepoint_user_put(_T)) static int trace_fprobe_create_internal(int argc, const char *argv[], struct traceprobe_parse_context *ctx) @@ -1112,6 +1264,8 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], * FETCHARG:TYPE : use TYPE instead of unsigned long. */ struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; + struct tracepoint_user *tuser __free(tuser_put) = NULL; + struct module *mod __free(module_put) = NULL; int i, new_argc = 0, ret = 0; bool is_return = false; char *symbol __free(kfree) = NULL; @@ -1123,8 +1277,6 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], char abuf[MAX_BTF_ARGS_LEN]; char *dbuf __free(kfree) = NULL; bool is_tracepoint = false; - struct module *tp_mod __free(module_put) = NULL; - struct tracepoint *tpoint = NULL; if ((argv[0][0] != 'f' && argv[0][0] != 't') || argc < 2) return -ECANCELED; @@ -1177,20 +1329,18 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], if (is_tracepoint) { ctx->flags |= TPARG_FL_TPOINT; - tpoint = find_tracepoint(symbol, &tp_mod); - if (tpoint) { - ctx->funcname = kallsyms_lookup( - (unsigned long)tpoint->probestub, - NULL, NULL, NULL, sbuf); - } else if (IS_ENABLED(CONFIG_MODULES)) { - /* This *may* be loaded afterwards */ - tpoint = TRACEPOINT_STUB; - ctx->funcname = symbol; - } else { + tuser = trace_fprobe_get_tracepoint_user(symbol, &mod); + if (!tuser) + return -ENOMEM; + if (IS_ERR(tuser)) { trace_probe_log_set_index(1); trace_probe_log_err(0, NO_TRACEPOINT); - return -EINVAL; + return PTR_ERR(tuser); } + ctx->funcname = tracepoint_user_lookup(tuser, sbuf); + /* If tracepoint is not loaded yet, use symbol name as funcname. */ + if (!ctx->funcname) + ctx->funcname = symbol; } else ctx->funcname = symbol; @@ -1214,13 +1364,14 @@ static int trace_fprobe_create_internal(int argc, const char *argv[], return ret; /* setup a probe */ - tf = alloc_trace_fprobe(group, event, symbol, tpoint, argc, is_return); + tf = alloc_trace_fprobe(group, event, symbol, tuser, argc, is_return); if (IS_ERR(tf)) { ret = PTR_ERR(tf); /* This must return -ENOMEM, else there is a bug */ WARN_ON_ONCE(ret != -ENOMEM); return ret; } + tuser = NULL; /* Move tuser to tf. */ /* parse arguments */ for (i = 0; i < argc; i++) { -- cgit v1.2.3 From 4d6d0a6263babf7c43faa55de4fa3c6637dec624 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 4 Jul 2025 10:48:38 -0400 Subject: tracing: Remove redundant config HAVE_FTRACE_MCOUNT_RECORD Ftrace is tightly coupled with architecture specific code because it requires the use of trampolines written in assembly. This means that when a new feature or optimization is made, it must be done for all architectures. To simplify the approach, CONFIG_HAVE_FTRACE_* configs are added to denote which architecture has the new enhancement so that other architectures can still function until they too have been updated. The CONFIG_HAVE_FTRACE_MCOUNT was added to help simplify the DYNAMIC_FTRACE work, but now every architecture that implements DYNAMIC_FTRACE also has HAVE_FTRACE_MCOUNT set too, making it redundant with the HAVE_DYNAMIC_FTRACE. Remove the HAVE_FTRACE_MCOUNT config and use DYNAMIC_FTRACE directly where applicable. Link: https://lore.kernel.org/all/20250703154916.48e3ada7@gandalf.local.home/ Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Mark Rutland Cc: Linus Torvalds Link: https://lore.kernel.org/20250704104838.27a18690@gandalf.local.home Signed-off-by: Steven Rostedt (Google) --- Documentation/trace/ftrace-design.rst | 12 ++++-------- arch/arm/Kconfig | 1 - arch/arm64/Kconfig | 1 - arch/csky/Kconfig | 1 - arch/loongarch/Kconfig | 1 - arch/microblaze/Kconfig | 1 - arch/mips/Kconfig | 1 - arch/parisc/Kconfig | 1 - arch/powerpc/Kconfig | 1 - arch/riscv/Kconfig | 1 - arch/s390/Kconfig | 1 - arch/sh/Kconfig | 1 - arch/sparc/Kconfig | 1 - arch/x86/Kconfig | 1 - include/asm-generic/vmlinux.lds.h | 2 +- include/linux/ftrace.h | 2 +- include/linux/kernel.h | 6 +++--- include/linux/module.h | 2 +- kernel/module/main.c | 2 +- kernel/trace/Kconfig | 18 ++++-------------- kernel/trace/ftrace.c | 4 ---- scripts/recordmcount.pl | 2 +- 22 files changed, 16 insertions(+), 47 deletions(-) (limited to 'include/linux/module.h') diff --git a/Documentation/trace/ftrace-design.rst b/Documentation/trace/ftrace-design.rst index dc82d64b3a44..8f4fab3f9324 100644 --- a/Documentation/trace/ftrace-design.rst +++ b/Documentation/trace/ftrace-design.rst @@ -238,19 +238,15 @@ You need very few things to get the syscalls tracing in an arch. - Tag this arch as HAVE_SYSCALL_TRACEPOINTS. -HAVE_FTRACE_MCOUNT_RECORD -------------------------- +HAVE_DYNAMIC_FTRACE +------------------- See scripts/recordmcount.pl for more info. Just fill in the arch-specific details for how to locate the addresses of mcount call sites via objdump. This option doesn't make much sense without also implementing dynamic ftrace. - -HAVE_DYNAMIC_FTRACE -------------------- - -You will first need HAVE_FTRACE_MCOUNT_RECORD and HAVE_FUNCTION_TRACER, so -scroll your reader back up if you got over eager. +You will first need HAVE_FUNCTION_TRACER, so scroll your reader back up if you +got over eager. Once those are out of the way, you will need to implement: - asm/ftrace.h: diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3072731fe09c..33cc9dbb7f68 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -107,7 +107,6 @@ config ARM select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU select HAVE_EXIT_THREAD select HAVE_GUP_FAST if ARM_LPAE - select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_ERROR_INJECTION select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER if !XIP_KERNEL diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 55fc331af337..f943a07db139 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -223,7 +223,6 @@ config ARM64 select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_GUP_FAST select HAVE_FTRACE_GRAPH_FUNC - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_ERROR_INJECTION select HAVE_FUNCTION_GRAPH_FREGS diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index acc431c331b0..4331313a42ff 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig @@ -80,7 +80,6 @@ config CSKY select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_ERROR_INJECTION - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 4b19f93379a1..bead8266dc5c 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -144,7 +144,6 @@ config LOONGARCH select HAVE_EXIT_THREAD select HAVE_GUP_FAST select HAVE_FTRACE_GRAPH_FUNC - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_FUNCTION_ERROR_INJECTION select HAVE_FUNCTION_GRAPH_FREGS diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index f18ec02ddeb2..484ebb3baedf 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -28,7 +28,6 @@ config MICROBLAZE select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_PAGE_SIZE_4KB diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1e48184ecf1e..268730824f75 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -73,7 +73,6 @@ config MIPS select HAVE_EBPF_JIT if !CPU_MICROMIPS select HAVE_EXIT_THREAD select HAVE_GUP_FAST - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index fcc5973f7519..2efa4b08b7b8 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -81,7 +81,6 @@ config PARISC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1) - select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c3e0cc83f120..cb4fb8d73300 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -246,7 +246,6 @@ config PPC select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_GUP_FAST select HAVE_FTRACE_GRAPH_FUNC - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_FUNCTION_DESCRIPTORS if PPC64_ELF_ABI_V1 select HAVE_FUNCTION_ERROR_INJECTION diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d71ea0f4466f..62ec265e2962 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -159,7 +159,6 @@ config RISCV select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG) select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_GRAPH_FUNC - select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS select HAVE_FUNCTION_GRAPH_FREGS select HAVE_FUNCTION_TRACER if !XIP_KERNEL diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 0c16dc443e2f..d956e85f0465 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -199,7 +199,6 @@ config S390 select HAVE_GUP_FAST select HAVE_FENTRY select HAVE_FTRACE_GRAPH_FUNC - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_FUNCTION_ERROR_INJECTION select HAVE_FUNCTION_GRAPH_FREGS diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 89185af7bcc9..d5795067befa 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -40,7 +40,6 @@ config SUPERH select HAVE_GUP_FAST if MMU select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_HW_BREAKPOINT select HAVE_IOREMAP_PROT if MMU && !X2TLB select HAVE_KERNEL_BZIP2 diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 0f88123925a4..f307e730446c 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -78,7 +78,6 @@ config SPARC64 select MMU_GATHER_NO_FLUSH_CACHE select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_PAGE_SIZE_8KB select HAVE_SYSCALL_TRACEPOINTS select HAVE_CONTEXT_TRACKING_USER diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 71019b3b54ea..eb07f236ce53 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -244,7 +244,6 @@ config X86 select HAVE_GUP_FAST select HAVE_FENTRY if X86_64 || DYNAMIC_FTRACE select HAVE_FTRACE_GRAPH_FUNC if HAVE_FUNCTION_GRAPH_TRACER - select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_FREGS if HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER if X86_32 || (X86_64 && DYNAMIC_FTRACE) select HAVE_FUNCTION_TRACER diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index fa5f19b8d53a..ae2d2359b79e 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -167,7 +167,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) #define FTRACE_STUB_HACK #endif -#ifdef CONFIG_FTRACE_MCOUNT_RECORD +#ifdef CONFIG_DYNAMIC_FTRACE /* * The ftrace call sites are logged to a section whose name depends on the * compiler option used. A given kernel image will only use one, AKA diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index b672ca15f265..7ded7df6e9b5 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1108,7 +1108,7 @@ static __always_inline unsigned long get_lock_parent_ip(void) # define trace_preempt_off(a0, a1) do { } while (0) #endif -#ifdef CONFIG_FTRACE_MCOUNT_RECORD +#ifdef CONFIG_DYNAMIC_FTRACE extern void ftrace_init(void); #ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY #define FTRACE_CALLSITE_SECTION "__patchable_function_entries" diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 1cce1f6410a9..989315dabb86 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -373,9 +373,9 @@ ftrace_vprintk(const char *fmt, va_list ap) static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #endif /* CONFIG_TRACING */ -/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ -#ifdef CONFIG_FTRACE_MCOUNT_RECORD -# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD +/* Rebuild everything on CONFIG_DYNAMIC_FTRACE */ +#ifdef CONFIG_DYNAMIC_FTRACE +# define REBUILD_DUE_TO_DYNAMIC_FTRACE #endif /* Permissions on a sysfs file: you didn't miss the 0 prefix did you? */ diff --git a/include/linux/module.h b/include/linux/module.h index 5faa1fb1f4b4..800e6fde9bf7 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -539,7 +539,7 @@ struct module { struct trace_eval_map **trace_evals; unsigned int num_trace_evals; #endif -#ifdef CONFIG_FTRACE_MCOUNT_RECORD +#ifdef CONFIG_DYNAMIC_FTRACE unsigned int num_ftrace_callsites; unsigned long *ftrace_callsites; #endif diff --git a/kernel/module/main.c b/kernel/module/main.c index 413ac6ea3702..58d36f8cef0d 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2639,7 +2639,7 @@ static int find_module_sections(struct module *mod, struct load_info *info) sizeof(*mod->trace_bprintk_fmt_start), &mod->num_trace_bprintk_fmt); #endif -#ifdef CONFIG_FTRACE_MCOUNT_RECORD +#ifdef CONFIG_DYNAMIC_FTRACE /* sechdrs[0].sh_size is always zero */ mod->ftrace_callsites = section_objs(info, FTRACE_CALLSITE_SECTION, sizeof(*mod->ftrace_callsites), diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 28afc6941e7a..9f2b1661a8ac 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -74,11 +74,6 @@ config HAVE_DYNAMIC_FTRACE_NO_PATCHABLE If the architecture generates __patchable_function_entries sections but does not want them included in the ftrace locations. -config HAVE_FTRACE_MCOUNT_RECORD - bool - help - See Documentation/trace/ftrace-design.rst - config HAVE_SYSCALL_TRACEPOINTS bool help @@ -803,27 +798,22 @@ config BPF_KPROBE_OVERRIDE Allows BPF to override the execution of a probed function and set a different return value. This is used for error injection. -config FTRACE_MCOUNT_RECORD - def_bool y - depends on DYNAMIC_FTRACE - depends on HAVE_FTRACE_MCOUNT_RECORD - config FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY bool - depends on FTRACE_MCOUNT_RECORD + depends on DYNAMIC_FTRACE config FTRACE_MCOUNT_USE_CC def_bool y depends on $(cc-option,-mrecord-mcount) depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY - depends on FTRACE_MCOUNT_RECORD + depends on DYNAMIC_FTRACE config FTRACE_MCOUNT_USE_OBJTOOL def_bool y depends on HAVE_OBJTOOL_MCOUNT depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY depends on !FTRACE_MCOUNT_USE_CC - depends on FTRACE_MCOUNT_RECORD + depends on DYNAMIC_FTRACE select OBJTOOL config FTRACE_MCOUNT_USE_RECORDMCOUNT @@ -831,7 +821,7 @@ config FTRACE_MCOUNT_USE_RECORDMCOUNT depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY depends on !FTRACE_MCOUNT_USE_CC depends on !FTRACE_MCOUNT_USE_OBJTOOL - depends on FTRACE_MCOUNT_RECORD + depends on DYNAMIC_FTRACE config TRACING_MAP bool diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4203fad56b6c..00b76d450a89 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1042,10 +1042,6 @@ static struct ftrace_ops *removed_ops; */ static bool update_all_ops; -#ifndef CONFIG_FTRACE_MCOUNT_RECORD -# error Dynamic ftrace depends on MCOUNT_RECORD -#endif - struct ftrace_func_probe { struct ftrace_probe_ops *probe_ops; struct ftrace_ops ops; diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 0871b2e92584..861b56dda64e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -359,7 +359,7 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_CKCORE_PCREL_JSR_IMM26BY2\\s+_mcount\$"; $alignment = 2; } else { - die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; + die "Arch $arch is not supported with CONFIG_DYNAMIC_FTRACE"; } my $text_found = 0; -- cgit v1.2.3 From d0d05f602c1504fb868ed4a560d1465d88a3c5e5 Mon Sep 17 00:00:00 2001 From: Joel Granados Date: Tue, 29 Apr 2025 14:30:00 +0200 Subject: module: Move modprobe_path and modules_disabled ctl_tables into the module subsys Move module sysctl (modprobe_path and modules_disabled) out of sysctl.c and into the modules subsystem. Make modules_disabled static as it no longer needs to be exported. Remove module.h from the includes in sysctl as it no longer uses any module exported variables. This is part of a greater effort to move ctl tables into their respective subsystems which will reduce the merge conflicts in kernel/sysctl.c. Reviewed-by: Luis Chamberlain Reviewed-by: Petr Pavlu Signed-off-by: Joel Granados --- include/linux/kmod.h | 3 --- include/linux/module.h | 1 - kernel/module/internal.h | 3 +++ kernel/module/main.c | 30 +++++++++++++++++++++++++++++- kernel/sysctl.c | 20 -------------------- 5 files changed, 32 insertions(+), 25 deletions(-) (limited to 'include/linux/module.h') diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 68f69362d427..9a07c3215389 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -14,10 +14,7 @@ #include #include -#define KMOD_PATH_LEN 256 - #ifdef CONFIG_MODULES -extern char modprobe_path[]; /* for sysctl */ /* modprobe exit status on success, -ve on error. Return value * usually useless though. */ extern __printf(2, 3) diff --git a/include/linux/module.h b/include/linux/module.h index 92e1420fccdf..e93cdb92ad92 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -304,7 +304,6 @@ struct notifier_block; #ifdef CONFIG_MODULES -extern int modules_disabled; /* for sysctl */ /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 8d74b0a21c82..51ddd8866ef3 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -58,6 +58,9 @@ extern const struct kernel_symbol __stop___ksymtab_gpl[]; extern const u32 __start___kcrctab[]; extern const u32 __start___kcrctab_gpl[]; +#define KMOD_PATH_LEN 256 +extern char modprobe_path[]; + struct load_info { const char *name; /* pointer to module in temporary copy, freed at end of load_module() */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 413ac6ea3702..c11d9a125001 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -126,9 +126,37 @@ static void mod_update_bounds(struct module *mod) } /* Block module loading/unloading? */ -int modules_disabled; +static int modules_disabled; core_param(nomodule, modules_disabled, bint, 0); +static const struct ctl_table module_sysctl_table[] = { + { + .procname = "modprobe", + .data = &modprobe_path, + .maxlen = KMOD_PATH_LEN, + .mode = 0644, + .proc_handler = proc_dostring, + }, + { + .procname = "modules_disabled", + .data = &modules_disabled, + .maxlen = sizeof(int), + .mode = 0644, + /* only handle a transition from default "0" to "1" */ + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ONE, + .extra2 = SYSCTL_ONE, + }, +}; + +static int __init init_module_sysctl(void) +{ + register_sysctl_init("kernel", module_sysctl_table); + return 0; +} + +subsys_initcall(init_module_sysctl); + /* Waiting for a module to finish initializing? */ static DECLARE_WAIT_QUEUE_HEAD(module_wq); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9b4f0cff76ea..473133d9651e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -19,7 +19,6 @@ * Removed it and replaced it with older style, 03/23/00, Bill Wendling */ -#include #include #include #include @@ -1616,25 +1615,6 @@ static const struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, #endif -#ifdef CONFIG_MODULES - { - .procname = "modprobe", - .data = &modprobe_path, - .maxlen = KMOD_PATH_LEN, - .mode = 0644, - .proc_handler = proc_dostring, - }, - { - .procname = "modules_disabled", - .data = &modules_disabled, - .maxlen = sizeof(int), - .mode = 0644, - /* only handle a transition from default "0" to "1" */ - .proc_handler = proc_dointvec_minmax, - .extra1 = SYSCTL_ONE, - .extra2 = SYSCTL_ONE, - }, -#endif #ifdef CONFIG_UEVENT_HELPER { .procname = "hotplug", -- cgit v1.2.3