All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Linus Torvalds <torvalds@linux-foundation.org>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Andrew Cooper <Andrew.Cooper3@citrix.com>,
	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
	Johannes Wikner <kwikner@ethz.ch>,
	Alyssa Milburn <alyssa.milburn@linux.intel.com>,
	Jann Horn <jannh@google.com>, "H.J. Lu" <hjl.tools@gmail.com>,
	Joao Moreira <joao.moreira@intel.com>,
	Joseph Nuzman <joseph.nuzman@intel.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Masami Hiramatsu <mhiramat@kernel.org>
Subject: [patch 33/38] kallsyms: Take callthunks into account
Date: Sun, 17 Jul 2022 01:18:03 +0200 (CEST)	[thread overview]
Message-ID: <20220716230954.651974187@linutronix.de> (raw)
In-Reply-To: 20220716230344.239749011@linutronix.de

From: Peter Zijlstra <peterz@infradead.org>

Similar to ftrace and bpf call thunks are creating symbols which are
interesting for things like printing stack-traces, perf, live-patching
and things like that.

Add the required functionality to the core and implement it in x86.

Callthunks will report the same function name as their target, but
their module name will be "callthunk" or "callthunk:${modname}" for
modules.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
---
 arch/x86/kernel/callthunks.c |  155 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/kallsyms.h     |   24 ++++++
 kernel/kallsyms.c            |   23 ++++++
 3 files changed, 202 insertions(+)

--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -4,6 +4,7 @@
 
 #include <linux/btree.h>
 #include <linux/debugfs.h>
+#include <linux/kallsyms.h>
 #include <linux/memory.h>
 #include <linux/moduleloader.h>
 #include <linux/set_memory.h>
@@ -548,6 +549,160 @@ void *callthunks_translate_call_dest(voi
 	return dest;
 }
 
+static bool is_module_callthunk(void *addr)
+{
+	bool ret = false;
+
+#ifdef CONFIG_MODULES
+	struct module *mod;
+
+	preempt_disable();
+	mod = __module_address((unsigned long)addr);
+	if (mod && within_module_thunk((unsigned long)addr, mod))
+		ret = true;
+	preempt_enable();
+#endif
+	return ret;
+}
+
+static bool is_callthunk(void *addr)
+{
+	if (builtin_layout.base <= addr &&
+	    addr < builtin_layout.base + builtin_layout.size)
+		return true;
+	return is_module_callthunk(addr);
+}
+
+static void *__callthunk_dest(void *addr)
+{
+	unsigned long mask = callthunk_desc.thunk_size - 1;
+	void *thunk;
+
+	thunk = (void *)((unsigned long)addr & ~mask);
+	thunk += callthunk_desc.template_size;
+	return jump_get_dest(thunk);
+}
+
+static void *callthunk_dest(void *addr)
+{
+	if (!is_callthunk(addr))
+		return NULL;
+	return __callthunk_dest(addr);
+}
+
+static void set_modname(char **modname, unsigned long addr)
+{
+	if (!modname || !IS_ENABLED(CONFIG_MODULES))
+		*modname = "callthunk";
+
+#ifdef CONFIG_MODULES
+	else {
+		struct module * mod;
+
+		preempt_disable();
+		mod = __module_address(addr);
+		*modname = mod->callthunk_name;
+		preempt_enable();
+	}
+#endif
+}
+
+const char *
+callthunk_address_lookup(unsigned long addr, unsigned long *size,
+			 unsigned long *off, char **modname, char *sym)
+{
+	unsigned long dest, mask = callthunk_desc.thunk_size - 1;
+	const char *ret;
+
+	if (!thunks_initialized)
+		return NULL;
+
+	dest = (unsigned long)callthunk_dest((void *)addr);
+	if (!dest)
+		return NULL;
+
+	ret = kallsyms_lookup(dest, size, off, modname, sym);
+	if (!ret)
+		return NULL;
+
+	*off = addr & mask;
+	*size = callthunk_desc.thunk_size;
+
+	set_modname(modname, addr);
+	return ret;
+}
+
+static int get_module_thunk(char **modname, struct module_layout **layoutp,
+			    unsigned int symthunk)
+{
+#ifdef CONFIG_MODULES
+	extern struct list_head modules;
+	struct module *mod;
+	unsigned int size;
+
+	symthunk -= (*layoutp)->text_size;
+	list_for_each_entry_rcu(mod, &modules, list) {
+		if (mod->state == MODULE_STATE_UNFORMED)
+			continue;
+
+		*layoutp = &mod->thunk_layout;
+		size = mod->thunk_layout.text_size;
+
+		if (symthunk >= size) {
+			symthunk -= size;
+			continue;
+		}
+		*modname = mod->callthunk_name;
+		return symthunk;
+	}
+#endif
+	return -ERANGE;
+}
+
+int callthunk_get_kallsym(unsigned int symnum, unsigned long *value,
+			  char *type, char *name, char *module_name,
+			  int *exported)
+{
+	int symthunk = symnum * callthunk_desc.thunk_size;
+	struct module_layout *layout = &builtin_layout;
+	char *modname = "callthunk";
+	void *thunk, *dest;
+	int ret = -ERANGE;
+
+	if (!thunks_initialized)
+		return -ERANGE;
+
+	preempt_disable();
+
+	if (symthunk >= layout->text_size) {
+		symthunk = get_module_thunk(&modname, &layout, symthunk);
+		if (symthunk < 0)
+			goto out;
+	}
+
+	thunk = layout->base + symthunk;
+	dest = __callthunk_dest(thunk);
+
+	if (!dest) {
+		strlcpy(name, "(unknown callthunk)", KSYM_NAME_LEN);
+		ret = 0;
+		goto out;
+	}
+
+	ret = lookup_symbol_name((unsigned long)dest, name);
+	if (ret)
+		goto out;
+
+	*value = (unsigned long)thunk;
+	*exported = 0;
+	*type = 't';
+	strlcpy(module_name, modname, MODULE_NAME_LEN);
+
+out:
+	preempt_enable();
+	return ret;
+}
+
 #ifdef CONFIG_MODULES
 void noinline callthunks_patch_module_calls(struct callthunk_sites *cs,
 					    struct module *mod)
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -65,6 +65,30 @@ static inline void *dereference_symbol_d
 	return ptr;
 }
 
+#ifdef CONFIG_CALL_THUNKS
+extern const char *
+callthunk_address_lookup(unsigned long addr, unsigned long *size,
+			 unsigned long *off, char **modname, char *sym);
+extern int callthunk_get_kallsym(unsigned int symnum, unsigned long *value,
+				 char *type, char *name, char *module_name,
+				 int *exported);
+#else
+static inline const char *
+callthunk_address_lookup(unsigned long addr, unsigned long *size,
+			 unsigned long *off, char **modname, char *sym)
+{
+	return NULL;
+}
+
+static inline
+int callthunk_get_kallsym(unsigned int symnum, unsigned long *value,
+			  char *type, char *name, char *module_name,
+			  int *exported)
+{
+	return -1;
+}
+#endif
+
 #ifdef CONFIG_KALLSYMS
 int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
 				      unsigned long),
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -365,6 +365,10 @@ static const char *kallsyms_lookup_build
 		ret = ftrace_mod_address_lookup(addr, symbolsize,
 						offset, modname, namebuf);
 
+	if (!ret)
+		ret = callthunk_address_lookup(addr, symbolsize,
+					       offset, modname, namebuf);
+
 found:
 	cleanup_symbol_name(namebuf);
 	return ret;
@@ -578,6 +582,7 @@ struct kallsym_iter {
 	loff_t pos_mod_end;
 	loff_t pos_ftrace_mod_end;
 	loff_t pos_bpf_end;
+	loff_t pos_callthunk_end;
 	unsigned long value;
 	unsigned int nameoff; /* If iterating in core kernel symbols. */
 	char type;
@@ -657,6 +662,20 @@ static int get_ksymbol_bpf(struct kallsy
 	return 1;
 }
 
+static int get_ksymbol_callthunk(struct kallsym_iter *iter)
+{
+	int ret = callthunk_get_kallsym(iter->pos - iter->pos_bpf_end,
+					&iter->value, &iter->type,
+					iter->name, iter->module_name,
+					&iter->exported);
+	if (ret < 0) {
+		iter->pos_callthunk_end = iter->pos;
+		return 0;
+	}
+
+	return 1;
+}
+
 /*
  * This uses "__builtin__kprobes" as a module name for symbols for pages
  * allocated for kprobes' purposes, even though "__builtin__kprobes" is not a
@@ -724,6 +743,10 @@ static int update_iter_mod(struct kallsy
 	    get_ksymbol_bpf(iter))
 		return 1;
 
+	if ((!iter->pos_callthunk_end || iter->pos_callthunk_end > pos) &&
+	    get_ksymbol_callthunk(iter))
+		return 1;
+
 	return get_ksymbol_kprobe(iter);
 }
 


  parent reply	other threads:[~2022-07-16 23:19 UTC|newest]

Thread overview: 142+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-16 23:17 [patch 00/38] x86/retbleed: Call depth tracking mitigation Thomas Gleixner
2022-07-16 23:17 ` [patch 01/38] x86/paravirt: Ensure proper alignment Thomas Gleixner
2022-07-16 23:17 ` [patch 02/38] x86/cpu: Use native_wrmsrl() in load_percpu_segment() Thomas Gleixner
2022-07-17  0:22   ` Andrew Cooper
2022-07-17 15:20     ` Linus Torvalds
2022-07-17 19:08     ` Thomas Gleixner
2022-07-17 20:08       ` Thomas Gleixner
2022-07-17 20:13         ` Thomas Gleixner
2022-07-17 21:54           ` Thomas Gleixner
2022-07-18  5:11             ` Juergen Gross
2022-07-18  6:54               ` Thomas Gleixner
2022-07-18  8:55                 ` Thomas Gleixner
2022-07-18  9:31                   ` Peter Zijlstra
2022-07-18 10:33                     ` Thomas Gleixner
2022-07-18 11:42                       ` Thomas Gleixner
2022-07-18 17:52   ` [patch 0/3] x86/cpu: Sanitize switch_to_new_gdt() Thomas Gleixner
2022-07-18 17:52   ` [patch 1/3] x86/cpu: Remove segment load from switch_to_new_gdt() Thomas Gleixner
2022-07-18 18:43     ` Linus Torvalds
2022-07-18 18:55       ` Thomas Gleixner
2022-07-18 17:52   ` [patch 2/3] x86/cpu: Get rid of redundant switch_to_new_gdt() invocations Thomas Gleixner
2022-07-18 17:52   ` [patch 3/3] x86/cpu: Re-enable stackprotector Thomas Gleixner
2022-07-16 23:17 ` [patch 03/38] x86/modules: Set VM_FLUSH_RESET_PERMS in module_alloc() Thomas Gleixner
2022-07-16 23:17 ` [patch 04/38] x86/vdso: Ensure all kernel code is seen by objtool Thomas Gleixner
2022-07-16 23:17 ` [patch 05/38] btree: Initialize early when builtin Thomas Gleixner
2022-07-16 23:17 ` [patch 06/38] objtool: Allow GS relative relocs Thomas Gleixner
2022-07-16 23:17 ` [patch 07/38] objtool: Track init section Thomas Gleixner
2022-07-16 23:17 ` [patch 08/38] objtool: Add .call_sites section Thomas Gleixner
2022-07-16 23:17 ` [patch 09/38] objtool: Add .sym_sites section Thomas Gleixner
2022-07-16 23:17 ` [patch 10/38] objtool: Add --hacks=skylake Thomas Gleixner
2022-07-16 23:17 ` [patch 11/38] objtool: Allow STT_NOTYPE -> STT_FUNC+0 tail-calls Thomas Gleixner
2022-07-16 23:17 ` [patch 12/38] x86/entry: Make sync_regs() invocation a tail call Thomas Gleixner
2022-07-16 23:17 ` [patch 13/38] x86/modules: Make module_alloc() generally available Thomas Gleixner
2022-07-16 23:17 ` [patch 14/38] x86/Kconfig: Add CONFIG_CALL_THUNKS Thomas Gleixner
2022-07-16 23:17 ` [patch 15/38] x86/retbleed: Add X86_FEATURE_CALL_DEPTH Thomas Gleixner
2022-07-16 23:17 ` [patch 16/38] modules: Make struct module_layout unconditionally available Thomas Gleixner
2022-07-16 23:17 ` [patch 17/38] module: Add arch_data to module_layout Thomas Gleixner
2022-07-16 23:17 ` [patch 18/38] mm/vmalloc: Provide huge page mappings Thomas Gleixner
2022-07-16 23:17 ` [patch 19/38] x86/module: Provide __module_alloc() Thomas Gleixner
2022-07-16 23:17 ` [patch 20/38] x86/alternatives: Provide text_poke_[copy|set]_locked() Thomas Gleixner
2022-07-16 23:17 ` [patch 21/38] x86/entry: Make some entry symbols global Thomas Gleixner
2022-07-16 23:17 ` [patch 22/38] x86/paravirt: Make struct paravirt_call_site unconditionally available Thomas Gleixner
2022-07-16 23:17 ` [patch 23/38] x86/callthunks: Add call patching for call depth tracking Thomas Gleixner
2022-07-16 23:17 ` [patch 24/38] module: Add layout for callthunks tracking Thomas Gleixner
2022-07-16 23:17 ` [patch 25/38] x86/modules: Add call thunk patching Thomas Gleixner
2022-07-16 23:17 ` [patch 26/38] x86/returnthunk: Allow different return thunks Thomas Gleixner
2022-07-16 23:17 ` [patch 27/38] x86/asm: Provide ALTERNATIVE_3 Thomas Gleixner
2022-07-16 23:17 ` [patch 28/38] x86/retbleed: Add SKL return thunk Thomas Gleixner
2022-07-16 23:17 ` [patch 29/38] x86/retpoline: Add SKL retthunk retpolines Thomas Gleixner
2022-07-16 23:17 ` [patch 30/38] x86/retbleed: Add SKL call thunk Thomas Gleixner
2022-07-16 23:18 ` [patch 31/38] x86/calldepth: Add ret/call counting for debug Thomas Gleixner
2022-07-16 23:18 ` [patch 32/38] static_call: Add call depth tracking support Thomas Gleixner
2022-07-16 23:18 ` Thomas Gleixner [this message]
2022-07-16 23:18 ` [patch 34/38] x86/orc: Make it callthunk aware Thomas Gleixner
2022-07-16 23:18 ` [patch 35/38] kprobes: Add callthunk blacklisting Thomas Gleixner
2022-07-16 23:18 ` [patch 36/38] x86/ftrace: Make it call depth tracking aware Thomas Gleixner
2022-07-18 21:01   ` Steven Rostedt
2022-07-19  8:46     ` Peter Zijlstra
2022-07-19 13:06       ` Steven Rostedt
2022-07-16 23:18 ` [patch 37/38] x86/bpf: Emit call depth accounting if required Thomas Gleixner
2022-07-19  5:30   ` Alexei Starovoitov
2022-07-19  8:34     ` Peter Zijlstra
2022-07-16 23:18 ` [patch 38/38] x86/retbleed: Add call depth tracking mitigation Thomas Gleixner
2022-07-17  9:45 ` [patch 00/38] x86/retbleed: Call " David Laight
2022-07-17 15:07   ` Thomas Gleixner
2022-07-17 17:56     ` David Laight
2022-07-17 19:15       ` Thomas Gleixner
2022-07-18 19:29 ` Thomas Gleixner
2022-07-18 19:30   ` Thomas Gleixner
2022-07-18 19:51     ` Linus Torvalds
2022-07-18 20:44       ` Thomas Gleixner
2022-07-18 21:01         ` Linus Torvalds
2022-07-18 21:43           ` Peter Zijlstra
2022-07-18 22:34             ` Linus Torvalds
2022-07-18 23:52               ` Peter Zijlstra
2022-07-18 21:18         ` Peter Zijlstra
2022-07-18 22:22           ` Thomas Gleixner
2022-07-18 22:47             ` Joao Moreira
2022-07-18 22:55               ` Sami Tolvanen
2022-07-18 23:08                 ` Joao Moreira
2022-07-18 23:19                 ` Thomas Gleixner
2022-07-18 23:42                   ` Linus Torvalds
2022-07-18 23:52                     ` Linus Torvalds
2022-07-18 23:57                       ` Peter Zijlstra
2022-07-19  0:03                         ` Linus Torvalds
2022-07-19  0:11                           ` Linus Torvalds
2022-07-19  0:23                             ` Peter Zijlstra
2022-07-19  1:02                               ` Linus Torvalds
2022-07-19 17:19                             ` Sami Tolvanen
2022-07-20 21:13                               ` Peter Zijlstra
2022-07-21  8:21                                 ` David Laight
2022-07-21 10:56                                   ` David Laight
2022-07-21 15:54                                 ` Peter Zijlstra
2022-07-21 17:55                                   ` Peter Zijlstra
2022-07-21 18:06                                     ` Linus Torvalds
2022-07-21 18:27                                       ` Peter Zijlstra
2022-07-21 18:32                                         ` Linus Torvalds
2022-07-21 20:22                                           ` Joao Moreira
2022-07-22  0:16                                         ` Sami Tolvanen
2022-07-22 10:23                                           ` Peter Zijlstra
2022-07-22 15:38                                             ` Sami Tolvanen
2022-07-21 22:01                                       ` David Laight
2022-07-22 11:03                                         ` Peter Zijlstra
2022-07-22 13:27                                           ` David Laight
2022-07-23  9:50                                   ` Thomas Gleixner
2022-07-19  0:01                       ` Linus Torvalds
2022-07-19  0:19                         ` Joao Moreira
2022-07-19 17:21                           ` Sami Tolvanen
2022-07-19 17:58                             ` Joao Moreira
2022-07-19  8:26                         ` David Laight
2022-07-19 16:27                           ` Linus Torvalds
2022-07-19 17:23                             ` Sami Tolvanen
2022-07-19 17:27                               ` Linus Torvalds
2022-07-19 18:06                                 ` Sami Tolvanen
2022-07-19 20:10                                   ` Peter Zijlstra
2022-07-18 22:48           ` Sami Tolvanen
2022-07-18 22:59             ` Thomas Gleixner
2022-07-18 23:10               ` Sami Tolvanen
2022-07-18 23:39               ` Linus Torvalds
2022-07-18 23:51             ` Peter Zijlstra
2022-07-20  9:00               ` Thomas Gleixner
2022-07-20 16:55               ` Sami Tolvanen
2022-07-20 19:42               ` Sami Tolvanen
2022-07-22 20:11         ` Tim Chen
2022-07-22 22:18           ` Linus Torvalds
2022-07-18 19:55 ` Thomas Gleixner
2022-07-19 10:24 ` Virt " Andrew Cooper
2022-07-19 14:13   ` Thomas Gleixner
2022-07-19 16:23     ` Andrew Cooper
2022-07-19 21:17       ` Thomas Gleixner
2022-07-19 14:45   ` Michael Kelley (LINUX)
2022-07-19 20:16     ` Peter Zijlstra
2022-07-20 16:57 ` [patch 00/38] x86/retbleed: " Steven Rostedt
2022-07-20 17:09   ` Linus Torvalds
2022-07-20 17:24     ` Peter Zijlstra
2022-07-20 17:50       ` Steven Rostedt
2022-07-20 18:07         ` Linus Torvalds
2022-07-20 18:31           ` Steven Rostedt
2022-07-20 18:43             ` Linus Torvalds
2022-07-20 19:11               ` Steven Rostedt
2022-07-20 19:36           ` Kees Cook
2022-07-20 19:43             ` Steven Rostedt
2022-07-20 21:36             ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220716230954.651974187@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=Andrew.Cooper3@citrix.com \
    --cc=alyssa.milburn@linux.intel.com \
    --cc=hjl.tools@gmail.com \
    --cc=jannh@google.com \
    --cc=joao.moreira@intel.com \
    --cc=joseph.nuzman@intel.com \
    --cc=jpoimboe@kernel.org \
    --cc=kwikner@ethz.ch \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=pawan.kumar.gupta@linux.intel.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.