LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ARM: Implement MODULE_PLT support in FTRACE
@ 2018-02-23 16:58 Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Alexander Sverdlin @ 2018-02-23 16:58 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, linux-arm-kernel, linux-kernel
  Cc: Alexander Sverdlin, Russell King, Catalin Marinas, Will Deacon,
	Steven Miao, Tony Luck, Fenghua Yu, James Hogan, Michal Simek,
	Ralf Baechle, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Yoshinori Sato, Rich Felker, David S. Miller, Chris Metcalf,
	Thomas Gleixner, H. Peter Anvin, x86, adi-buildroot-devel,
	linux-ia64, linux-metag, linux-mips, linuxppc-dev, linux-s390,
	linux-sh, sparclinux

FTRACE's function tracer currently doesn't always work on ARM with
MODULE_PLT option enabled. If the module is loaded too far, FTRACE's
code modifier cannot cope with introduced veneers and turns the
function tracer off globally.

ARM64 already has a solution for the problem, refer to the following
patches:

arm64: ftrace: emit ftrace-mod.o contents through code
arm64: module-plts: factor out PLT generation code for ftrace
arm64: ftrace: fix !CONFIG_ARM64_MODULE_PLTS kernels
arm64: ftrace: fix building without CONFIG_MODULES
arm64: ftrace: add support for far branches to dynamic ftrace
arm64: ftrace: don't validate branch via PLT in ftrace_make_nop()

But the presented ARM variant has just a half of the footprint in terms of
the changed LoCs. It also retains the code validation-before-modification
instead of switching it off.

Alexander Sverdlin (3):
  ftrace: Add module to ftrace_make_call() parameters
  ARM: PLT: Move struct plt_entries definition to header
  ftrace: Add MODULE_PLTS support

 arch/arm/include/asm/module.h      | 10 ++++++
 arch/arm/kernel/ftrace.c           | 73 ++++++++++++++++++++++++++++++++------
 arch/arm/kernel/module-plts.c      | 58 +++++++++++++++++++-----------
 arch/arm64/kernel/ftrace.c         |  3 +-
 arch/blackfin/kernel/ftrace.c      |  3 +-
 arch/ia64/kernel/ftrace.c          |  3 +-
 arch/metag/kernel/ftrace.c         |  3 +-
 arch/microblaze/kernel/ftrace.c    |  3 +-
 arch/mips/kernel/ftrace.c          |  3 +-
 arch/powerpc/kernel/trace/ftrace.c |  3 +-
 arch/s390/kernel/ftrace.c          |  3 +-
 arch/sh/kernel/ftrace.c            |  3 +-
 arch/sparc/kernel/ftrace.c         |  3 +-
 arch/tile/kernel/ftrace.c          |  3 +-
 arch/x86/kernel/ftrace.c           |  3 +-
 include/linux/ftrace.h             |  4 ++-
 kernel/trace/ftrace.c              |  6 ++--
 17 files changed, 140 insertions(+), 47 deletions(-)

-- 
2.4.6

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters
  2018-02-23 16:58 [PATCH 0/3] ARM: Implement MODULE_PLT support in FTRACE Alexander Sverdlin
@ 2018-02-23 16:58 ` Alexander Sverdlin
  2018-02-25 11:53   ` kbuild test robot
  2018-02-25 14:57   ` kbuild test robot
  2018-02-23 16:58 ` [PATCH 2/3] ARM: PLT: Move struct plt_entries definition to header Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 3/3] ftrace: Add MODULE_PLTS support Alexander Sverdlin
  2 siblings, 2 replies; 6+ messages in thread
From: Alexander Sverdlin @ 2018-02-23 16:58 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, linux-arm-kernel, linux-kernel
  Cc: Alexander Sverdlin, Russell King, Catalin Marinas, Will Deacon,
	Steven Miao, Tony Luck, Fenghua Yu, James Hogan, Michal Simek,
	Ralf Baechle, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Yoshinori Sato, Rich Felker, David S. Miller, Chris Metcalf,
	Thomas Gleixner, H. Peter Anvin, x86, adi-buildroot-devel,
	linux-ia64, linux-metag, linux-mips, linuxppc-dev, linux-s390,
	linux-sh, sparclinux

ARM support for modules' PLTs will require a module pointer in
ftrace_make_call() exactly as ftrace_make_nop() has it. Change the function
signature without functional change for now.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
---
 arch/arm/kernel/ftrace.c           | 3 ++-
 arch/arm64/kernel/ftrace.c         | 3 ++-
 arch/blackfin/kernel/ftrace.c      | 3 ++-
 arch/ia64/kernel/ftrace.c          | 3 ++-
 arch/metag/kernel/ftrace.c         | 3 ++-
 arch/microblaze/kernel/ftrace.c    | 3 ++-
 arch/mips/kernel/ftrace.c          | 3 ++-
 arch/powerpc/kernel/trace/ftrace.c | 3 ++-
 arch/s390/kernel/ftrace.c          | 3 ++-
 arch/sh/kernel/ftrace.c            | 3 ++-
 arch/sparc/kernel/ftrace.c         | 3 ++-
 arch/tile/kernel/ftrace.c          | 3 ++-
 arch/x86/kernel/ftrace.c           | 3 ++-
 include/linux/ftrace.h             | 4 +++-
 kernel/trace/ftrace.c              | 6 +++---
 15 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 5617932..be20adc 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -162,7 +162,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	return ret;
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long new, old;
 	unsigned long ip = rec->ip;
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index 50986e3..e3a95d3 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -68,7 +68,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 /*
  * Turn on the call to ftrace_caller() in instrumented function
  */
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long pc = rec->ip;
 	u32 old, new;
diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c
index 8dad758..61ffc99 100644
--- a/arch/blackfin/kernel/ftrace.c
+++ b/arch/blackfin/kernel/ftrace.c
@@ -45,7 +45,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 	return ftrace_modify_code(rec->ip, mnop, sizeof(mnop));
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	/* Restore the mcount call site */
 	unsigned char call[8];
diff --git a/arch/ia64/kernel/ftrace.c b/arch/ia64/kernel/ftrace.c
index cee411e..658a011 100644
--- a/arch/ia64/kernel/ftrace.c
+++ b/arch/ia64/kernel/ftrace.c
@@ -169,7 +169,8 @@ int ftrace_make_nop(struct module *mod,
 	return ftrace_modify_code(rec->ip, NULL, new, 0);
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long ip = rec->ip;
 	unsigned char *old, *new;
diff --git a/arch/metag/kernel/ftrace.c b/arch/metag/kernel/ftrace.c
index f7b23d3..635652a 100644
--- a/arch/metag/kernel/ftrace.c
+++ b/arch/metag/kernel/ftrace.c
@@ -104,7 +104,8 @@ int ftrace_make_nop(struct module *mod,
 	return ftrace_modify_code(ip, old, new);
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned char *new, *old;
 	unsigned long ip = rec->ip;
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index d57563c..01b314a 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -161,7 +161,8 @@ int ftrace_make_nop(struct module *mod,
 }
 
 /* I believe that first is called ftrace_make_nop before this function */
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	int ret;
 	pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n",
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 7f3dfdb..9dcec19 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -200,7 +200,8 @@ int ftrace_make_nop(struct module *mod,
 #endif
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned int new;
 	unsigned long ip = rec->ip;
diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
index 4741fe1..b198433 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -437,7 +437,8 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 #endif /* CONFIG_PPC64 */
 #endif /* CONFIG_MODULES */
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long ip = rec->ip;
 	unsigned int old, new;
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index dc76d81..1691d53 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -136,7 +136,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 	return 0;
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	struct ftrace_insn orig, new, old;
 
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 96dd9f7..2d3cacd 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -242,7 +242,8 @@ int ftrace_make_nop(struct module *mod,
 	return ftrace_modify_code(rec->ip, old, new);
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned char *new, *old;
 	unsigned long ip = rec->ip;
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c
index 915dda4..36117b5 100644
--- a/arch/sparc/kernel/ftrace.c
+++ b/arch/sparc/kernel/ftrace.c
@@ -63,7 +63,8 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long ad
 	return ftrace_modify_code(ip, old, new);
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long ip = rec->ip;
 	u32 old, new;
diff --git a/arch/tile/kernel/ftrace.c b/arch/tile/kernel/ftrace.c
index b827a41..749e50f 100644
--- a/arch/tile/kernel/ftrace.c
+++ b/arch/tile/kernel/ftrace.c
@@ -136,7 +136,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
 	return ret;
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned long new, old;
 	unsigned long ip = rec->ip;
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 01ebcb6..389f15c 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -162,7 +162,8 @@ int ftrace_make_nop(struct module *mod,
 	return -EINVAL;
 }
 
-int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+		     unsigned long addr)
 {
 	unsigned const char *new, *old;
 	unsigned long ip = rec->ip;
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 9c3c9a3..1e8c421 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -536,6 +536,7 @@ extern int ftrace_make_nop(struct module *mod,
 
 /**
  * ftrace_make_call - convert a nop call site into a call to addr
+ * @mod: module structure if called by module load initialization
  * @rec: the mcount call site record
  * @addr: the address that the call site should call
  *
@@ -554,7 +555,8 @@ extern int ftrace_make_nop(struct module *mod,
  *  -EPERM  on error writing to the location
  * Any other value will be considered a failure.
  */
-extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
+extern int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
+			    unsigned long addr);
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
 /**
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eac9ce2..d32f2f5 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2421,7 +2421,7 @@ unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec)
 }
 
 static int
-__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
+__ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
 {
 	unsigned long ftrace_old_addr;
 	unsigned long ftrace_addr;
@@ -2442,7 +2442,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
 
 	case FTRACE_UPDATE_MAKE_CALL:
 		ftrace_bug_type = FTRACE_BUG_CALL;
-		return ftrace_make_call(rec, ftrace_addr);
+		return ftrace_make_call(mod, rec, ftrace_addr);
 
 	case FTRACE_UPDATE_MAKE_NOP:
 		ftrace_bug_type = FTRACE_BUG_NOP;
@@ -2470,7 +2470,7 @@ void __weak ftrace_replace_code(int enable)
 		if (rec->flags & FTRACE_FL_DISABLED)
 			continue;
 
-		failed = __ftrace_replace_code(rec, enable);
+		failed = __ftrace_replace_code(NULL, rec, enable);
 		if (failed) {
 			ftrace_bug(failed, rec);
 			/* Stop processing */
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] ARM: PLT: Move struct plt_entries definition to header
  2018-02-23 16:58 [PATCH 0/3] ARM: Implement MODULE_PLT support in FTRACE Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
@ 2018-02-23 16:58 ` Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 3/3] ftrace: Add MODULE_PLTS support Alexander Sverdlin
  2 siblings, 0 replies; 6+ messages in thread
From: Alexander Sverdlin @ 2018-02-23 16:58 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, linux-arm-kernel, linux-kernel
  Cc: Alexander Sverdlin, Russell King, Catalin Marinas, Will Deacon,
	Steven Miao, Tony Luck, Fenghua Yu, James Hogan, Michal Simek,
	Ralf Baechle, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Yoshinori Sato, Rich Felker, David S. Miller, Chris Metcalf,
	Thomas Gleixner, H. Peter Anvin, x86, adi-buildroot-devel,
	linux-ia64, linux-metag, linux-mips, linuxppc-dev, linux-s390,
	linux-sh, sparclinux

No functional change, later it will be re-used in several files.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
---
 arch/arm/include/asm/module.h | 9 +++++++++
 arch/arm/kernel/module-plts.c | 9 ---------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index 89ad059..6996405 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -19,6 +19,15 @@ enum {
 };
 #endif
 
+#define PLT_ENT_STRIDE		L1_CACHE_BYTES
+#define PLT_ENT_COUNT		(PLT_ENT_STRIDE / sizeof(u32))
+#define PLT_ENT_SIZE		(sizeof(struct plt_entries) / PLT_ENT_COUNT)
+
+struct plt_entries {
+	u32	ldr[PLT_ENT_COUNT];
+	u32	lit[PLT_ENT_COUNT];
+};
+
 struct mod_plt_sec {
 	struct elf32_shdr	*plt;
 	int			plt_count;
diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
index 3d0c2e4..f272711 100644
--- a/arch/arm/kernel/module-plts.c
+++ b/arch/arm/kernel/module-plts.c
@@ -14,10 +14,6 @@
 #include <asm/cache.h>
 #include <asm/opcodes.h>
 
-#define PLT_ENT_STRIDE		L1_CACHE_BYTES
-#define PLT_ENT_COUNT		(PLT_ENT_STRIDE / sizeof(u32))
-#define PLT_ENT_SIZE		(sizeof(struct plt_entries) / PLT_ENT_COUNT)
-
 #ifdef CONFIG_THUMB2_KERNEL
 #define PLT_ENT_LDR		__opcode_to_mem_thumb32(0xf8dff000 | \
 							(PLT_ENT_STRIDE - 4))
@@ -26,11 +22,6 @@
 						    (PLT_ENT_STRIDE - 8))
 #endif
 
-struct plt_entries {
-	u32	ldr[PLT_ENT_COUNT];
-	u32	lit[PLT_ENT_COUNT];
-};
-
 static bool in_init(const struct module *mod, unsigned long loc)
 {
 	return loc - (u32)mod->init_layout.base < mod->init_layout.size;
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] ftrace: Add MODULE_PLTS support
  2018-02-23 16:58 [PATCH 0/3] ARM: Implement MODULE_PLT support in FTRACE Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
  2018-02-23 16:58 ` [PATCH 2/3] ARM: PLT: Move struct plt_entries definition to header Alexander Sverdlin
@ 2018-02-23 16:58 ` Alexander Sverdlin
  2 siblings, 0 replies; 6+ messages in thread
From: Alexander Sverdlin @ 2018-02-23 16:58 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar, linux-arm-kernel, linux-kernel
  Cc: Alexander Sverdlin, Russell King, Catalin Marinas, Will Deacon,
	Steven Miao, Tony Luck, Fenghua Yu, James Hogan, Michal Simek,
	Ralf Baechle, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Martin Schwidefsky, Heiko Carstens,
	Yoshinori Sato, Rich Felker, David S. Miller, Chris Metcalf,
	Thomas Gleixner, H. Peter Anvin, x86, adi-buildroot-devel,
	linux-ia64, linux-metag, linux-mips, linuxppc-dev, linux-s390,
	linux-sh, sparclinux

Teach ftrace_make_call() and ftrace_make_nop() about PLTs.
Teach PLT code about FTRACE and all its callbacks.
Otherwise the following might happen:

------------[ cut here ]------------
WARNING: CPU: 14 PID: 2265 at .../arch/arm/kernel/insn.c:14 __arm_gen_branch+0x83/0x8c()
...
Hardware name: LSI Axxia AXM55XX
[<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14)
[<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8)
[<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90)
[<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c)
[<c03218f3>] (warn_slowpath_null) from [<c03143cf>] (__arm_gen_branch+0x83/0x8c)
[<c03143cf>] (__arm_gen_branch) from [<c0314337>] (ftrace_make_nop+0xf/0x24)
[<c0314337>] (ftrace_make_nop) from [<c038ebcb>] (ftrace_process_locs+0x27b/0x3e8)
[<c038ebcb>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44)
[<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84)
[<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18)
---[ end trace e1b64ced7a89adcc ]---
------------[ cut here ]------------
WARNING: CPU: 14 PID: 2265 at .../kernel/trace/ftrace.c:1979 ftrace_bug+0x1b1/0x234()
...
Hardware name: LSI Axxia AXM55XX
[<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14)
[<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8)
[<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90)
[<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c)
[<c03218f3>] (warn_slowpath_null) from [<c038e87d>] (ftrace_bug+0x1b1/0x234)
[<c038e87d>] (ftrace_bug) from [<c038ebd5>] (ftrace_process_locs+0x285/0x3e8)
[<c038ebd5>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44)
[<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84)
[<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18)
---[ end trace e1b64ced7a89adcd ]---
ftrace failed to modify [<e9ef7006>] 0xe9ef7006
actual: 02:f0:3b:fa
ftrace record flags: 0
(0) expected tramp: c0314265

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
---
 arch/arm/include/asm/module.h |  1 +
 arch/arm/kernel/ftrace.c      | 70 ++++++++++++++++++++++++++++++++++++-------
 arch/arm/kernel/module-plts.c | 53 ++++++++++++++++++++++++--------
 3 files changed, 101 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index 6996405..e3d7a51 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -30,6 +30,7 @@ struct plt_entries {
 
 struct mod_plt_sec {
 	struct elf32_shdr	*plt;
+	struct plt_entries	*plt_ent;
 	int			plt_count;
 };
 
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index be20adc..0a0da25 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -98,6 +98,19 @@ int ftrace_arch_code_modify_post_process(void)
 
 static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
 {
+	s32 offset = addr - pc;
+	s32 blim = 0xfe000008;
+	s32 flim = 0x02000004;
+
+	if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+		blim = 0xff000004;
+		flim = 0x01000002;
+	}
+
+	if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) &&
+	    (offset < blim || offset > flim))
+		return 0;
+
 	return arm_gen_branch_link(pc, addr);
 }
 
@@ -167,10 +180,27 @@ int ftrace_make_call(struct module *mod, struct dyn_ftrace *rec,
 {
 	unsigned long new, old;
 	unsigned long ip = rec->ip;
+	unsigned long aaddr = adjust_address(rec, addr);
 
 	old = ftrace_nop_replace(rec);
 
-	new = ftrace_call_replace(ip, adjust_address(rec, addr));
+	new = ftrace_call_replace(ip, aaddr);
+
+#ifdef CONFIG_ARM_MODULE_PLTS
+	if (!new) {
+		/*
+		 * mod is only supplied during module loading, later we have to
+		 * search for it
+		 */
+		if (!mod)
+			mod = __module_address(ip);
+
+		if (mod) {
+			aaddr = get_module_plt(mod, ip, aaddr);
+			new = ftrace_call_replace(ip, aaddr);
+		}
+	}
+#endif
 
 	return ftrace_modify_code(rec->ip, old, new, true);
 }
@@ -200,20 +230,40 @@ int ftrace_make_nop(struct module *mod,
 	unsigned long new;
 	int ret;
 
-	old = ftrace_call_replace(ip, adjust_address(rec, addr));
-	new = ftrace_nop_replace(rec);
-	ret = ftrace_modify_code(ip, old, new, true);
-
-#ifdef CONFIG_OLD_MCOUNT
-	if (ret == -EINVAL && addr == MCOUNT_ADDR) {
-		rec->arch.old_mcount = true;
+	for (;;) {
+		unsigned long aaddr = adjust_address(rec, addr);
+
+		old = ftrace_call_replace(ip, aaddr);
+
+#ifdef CONFIG_ARM_MODULE_PLTS
+		if (!old) {
+			/*
+			 * mod is only supplied during module loading, later we
+			 * have to search for it
+			 */
+			if (!mod)
+				mod = __module_address(ip);
+
+			if (mod) {
+				aaddr = get_module_plt(mod, ip, aaddr);
+				old = ftrace_call_replace(ip, aaddr);
+			}
+		}
+#endif
 
-		old = ftrace_call_replace(ip, adjust_address(rec, addr));
 		new = ftrace_nop_replace(rec);
 		ret = ftrace_modify_code(ip, old, new, true);
-	}
+
+#ifdef CONFIG_OLD_MCOUNT
+		if (ret == -EINVAL && !rec->arch.old_mcount) {
+			rec->arch.old_mcount = true;
+			continue;
+		}
 #endif
 
+		break;
+	}
+
 	return ret;
 }
 
diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
index f272711..a216256 100644
--- a/arch/arm/kernel/module-plts.c
+++ b/arch/arm/kernel/module-plts.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/elf.h>
+#include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sort.h>
@@ -22,6 +23,15 @@
 						    (PLT_ENT_STRIDE - 8))
 #endif
 
+static u32 fixed_plts[] = {
+	FTRACE_ADDR,
+	MCOUNT_ADDR,
+#ifdef CONFIG_OLD_MCOUNT
+	(unsigned long)ftrace_caller_old,
+	(unsigned long)mcount,
+#endif
+};
+
 static bool in_init(const struct module *mod, unsigned long loc)
 {
 	return loc - (u32)mod->init_layout.base < mod->init_layout.size;
@@ -31,26 +41,43 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
 {
 	struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
 							  &mod->arch.init;
+	int idx;
+	struct plt_entries *plt;
+
+	/* Pre-allocate entries in the first plt */
+	if (!pltsec->plt_count) {
+		plt = (struct plt_entries *)pltsec->plt->sh_addr;
+		for (idx = 0; idx < ARRAY_SIZE(plt->ldr); ++idx)
+			plt->ldr[idx] = PLT_ENT_LDR;
+		memcpy(plt->lit, fixed_plts, sizeof(fixed_plts));
+		pltsec->plt_count = ARRAY_SIZE(fixed_plts);
+		/*
+		 * cache the address,
+		 * ELF header is available only during module load
+		 */
+		pltsec->plt_ent = plt;
+	}
+	plt = pltsec->plt_ent;
 
-	struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr;
-	int idx = 0;
+	idx = ARRAY_SIZE(fixed_plts);
+	while (idx)
+		if (plt->lit[--idx] == val)
+			return (u32)&plt->ldr[idx];
 
 	/*
 	 * Look for an existing entry pointing to 'val'. Given that the
 	 * relocations are sorted, this will be the last entry we allocated.
 	 * (if one exists).
 	 */
-	if (pltsec->plt_count > 0) {
-		plt += (pltsec->plt_count - 1) / PLT_ENT_COUNT;
-		idx = (pltsec->plt_count - 1) % PLT_ENT_COUNT;
+	plt += (pltsec->plt_count - 1) / PLT_ENT_COUNT;
+	idx = (pltsec->plt_count - 1) % PLT_ENT_COUNT;
 
-		if (plt->lit[idx] == val)
-			return (u32)&plt->ldr[idx];
+	if (plt->lit[idx] == val)
+		return (u32)&plt->ldr[idx];
 
-		idx = (idx + 1) % PLT_ENT_COUNT;
-		if (!idx)
-			plt++;
-	}
+	idx = (idx + 1) % PLT_ENT_COUNT;
+	if (!idx)
+		plt++;
 
 	pltsec->plt_count++;
 	BUG_ON(pltsec->plt_count * PLT_ENT_SIZE > pltsec->plt->sh_size);
@@ -182,8 +209,8 @@ static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
 int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 			      char *secstrings, struct module *mod)
 {
-	unsigned long core_plts = 0;
-	unsigned long init_plts = 0;
+	unsigned long core_plts = ARRAY_SIZE(fixed_plts);
+	unsigned long init_plts = ARRAY_SIZE(fixed_plts);
 	Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
 	Elf32_Sym *syms = NULL;
 
-- 
2.4.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters
  2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
@ 2018-02-25 11:53   ` kbuild test robot
  2018-02-25 14:57   ` kbuild test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2018-02-25 11:53 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: kbuild-all, Steven Rostedt, Ingo Molnar, linux-arm-kernel,
	linux-kernel, Alexander Sverdlin, Russell King, Catalin Marinas,
	Will Deacon, Steven Miao, Tony Luck, Fenghua Yu, James Hogan,
	Michal Simek, Ralf Baechle, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Yoshinori Sato, Rich Felker, David S. Miller,
	Chris Metcalf, Thomas Gleixner, H. Peter Anvin, x86,
	adi-buildroot-devel, linux-ia64, linux-metag, linux-mips,
	linuxppc-dev, linux-s390, linux-sh, sparclinux

[-- Attachment #1: Type: text/plain, Size: 8111 bytes --]

Hi Alexander,

I love your patch! Yet something to improve:

[auto build test ERROR on tip/perf/core]
[also build test ERROR on v4.16-rc2 next-20180223]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Alexander-Sverdlin/ARM-Implement-MODULE_PLT-support-in-FTRACE/20180225-191957
config: x86_64-randconfig-x011-201808 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   kernel/trace/ftrace.c: In function 'ftrace_module_enable':
>> kernel/trace/ftrace.c:5851:39: error: passing argument 1 of '__ftrace_replace_code' from incompatible pointer type [-Werror=incompatible-pointer-types]
       int failed = __ftrace_replace_code(rec, 1);
                                          ^~~
   kernel/trace/ftrace.c:2424:1: note: expected 'struct module *' but argument is of type 'struct dyn_ftrace *'
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^~~~~~~~~~~~~~~~~~~~~
>> kernel/trace/ftrace.c:5851:44: warning: passing argument 2 of '__ftrace_replace_code' makes pointer from integer without a cast [-Wint-conversion]
       int failed = __ftrace_replace_code(rec, 1);
                                               ^
   kernel/trace/ftrace.c:2424:1: note: expected 'struct dyn_ftrace *' but argument is of type 'int'
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^~~~~~~~~~~~~~~~~~~~~
>> kernel/trace/ftrace.c:5851:17: error: too few arguments to function '__ftrace_replace_code'
       int failed = __ftrace_replace_code(rec, 1);
                    ^~~~~~~~~~~~~~~~~~~~~
   kernel/trace/ftrace.c:2424:1: note: declared here
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/__ftrace_replace_code +5851 kernel/trace/ftrace.c

93eb677d Steven Rostedt           2009-04-15  5797  
7dcd182b Jessica Yu               2016-02-16  5798  void ftrace_module_enable(struct module *mod)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5799) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5800) 	struct dyn_ftrace *rec;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5801) 	struct ftrace_page *pg;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5802) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5803) 	mutex_lock(&ftrace_lock);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5804) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5805) 	if (ftrace_disabled)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5806) 		goto out_unlock;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5807) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5808) 	/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5809) 	 * If the tracing is enabled, go ahead and enable the record.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5810) 	 *
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5811) 	 * The reason not to enable the record immediatelly is the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5812) 	 * inherent check of ftrace_make_nop/ftrace_make_call for
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5813) 	 * correct previous instructions.  Making first the NOP
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5814) 	 * conversion puts the module to the correct state, thus
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5815) 	 * passing the ftrace_make_call check.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5816) 	 *
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5817) 	 * We also delay this to after the module code already set the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5818) 	 * text to read-only, as we now need to set it back to read-write
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5819) 	 * so that we can modify the text.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5820) 	 */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5821) 	if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5822) 		ftrace_arch_code_modify_prepare();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5823) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5824) 	do_for_each_ftrace_rec(pg, rec) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5825) 		int cnt;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5826) 		/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5827) 		 * do_for_each_ftrace_rec() is a double loop.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5828) 		 * module text shares the pg. If a record is
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5829) 		 * not part of this module, then skip this pg,
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5830) 		 * which the "break" will do.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5831) 		 */
3e234289 Steven Rostedt (VMware   2017-03-03  5832) 		if (!within_module_core(rec->ip, mod) &&
3e234289 Steven Rostedt (VMware   2017-03-03  5833) 		    !within_module_init(rec->ip, mod))
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5834) 			break;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5835) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5836) 		cnt = 0;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5837) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5838) 		/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5839) 		 * When adding a module, we need to check if tracers are
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5840) 		 * currently enabled and if they are, and can trace this record,
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5841) 		 * we need to enable the module functions as well as update the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5842) 		 * reference counts for those function records.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5843) 		 */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5844) 		if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5845) 			cnt += referenced_filters(rec);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5846) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5847) 		/* This clears FTRACE_FL_DISABLED */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5848) 		rec->flags = cnt;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5849) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5850) 		if (ftrace_start_up && cnt) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07 @5851) 			int failed = __ftrace_replace_code(rec, 1);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5852) 			if (failed) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5853) 				ftrace_bug(failed, rec);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5854) 				goto out_loop;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5855) 			}
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5856) 		}
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5857) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5858) 	} while_for_each_ftrace_rec();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5859) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5860)  out_loop:
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5861) 	if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5862) 		ftrace_arch_code_modify_post_process();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5863) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5864)  out_unlock:
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5865) 	mutex_unlock(&ftrace_lock);
d7fbf8df Steven Rostedt (VMware   2017-06-26  5866) 
d7fbf8df Steven Rostedt (VMware   2017-06-26  5867) 	process_cached_mods(mod->name);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5868) }
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5869) 

:::::: The code at line 5851 was first introduced by commit
:::::: b7ffffbb46f205e7727a18bcc7a46c3c2b534f7c ftrace: Add infrastructure for delayed enabling of module functions

:::::: TO: Steven Rostedt (Red Hat) <rostedt@goodmis.org>
:::::: CC: Steven Rostedt <rostedt@goodmis.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27148 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters
  2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
  2018-02-25 11:53   ` kbuild test robot
@ 2018-02-25 14:57   ` kbuild test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2018-02-25 14:57 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: kbuild-all, Steven Rostedt, Ingo Molnar, linux-arm-kernel,
	linux-kernel, Alexander Sverdlin, Russell King, Catalin Marinas,
	Will Deacon, Steven Miao, Tony Luck, Fenghua Yu, James Hogan,
	Michal Simek, Ralf Baechle, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, Martin Schwidefsky,
	Heiko Carstens, Yoshinori Sato, Rich Felker, David S. Miller,
	Chris Metcalf, Thomas Gleixner, H. Peter Anvin, x86,
	adi-buildroot-devel, linux-ia64, linux-metag, linux-mips,
	linuxppc-dev, linux-s390, linux-sh, sparclinux

[-- Attachment #1: Type: text/plain, Size: 7929 bytes --]

Hi Alexander,

I love your patch! Perhaps something to improve:

[auto build test WARNING on tip/perf/core]
[also build test WARNING on v4.16-rc2 next-20180223]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Alexander-Sverdlin/ARM-Implement-MODULE_PLT-support-in-FTRACE/20180225-191957
config: i386-randconfig-h1-02251623 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   kernel/trace/ftrace.c: In function 'ftrace_module_enable':
>> kernel/trace/ftrace.c:5851:39: warning: passing argument 1 of '__ftrace_replace_code' from incompatible pointer type
       int failed = __ftrace_replace_code(rec, 1);
                                          ^
   kernel/trace/ftrace.c:2424:1: note: expected 'struct module *' but argument is of type 'struct dyn_ftrace *'
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^
   kernel/trace/ftrace.c:5851:44: warning: passing argument 2 of '__ftrace_replace_code' makes pointer from integer without a cast
       int failed = __ftrace_replace_code(rec, 1);
                                               ^
   kernel/trace/ftrace.c:2424:1: note: expected 'struct dyn_ftrace *' but argument is of type 'int'
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^
   kernel/trace/ftrace.c:5851:17: error: too few arguments to function '__ftrace_replace_code'
       int failed = __ftrace_replace_code(rec, 1);
                    ^
   kernel/trace/ftrace.c:2424:1: note: declared here
    __ftrace_replace_code(struct module *mod, struct dyn_ftrace *rec, int enable)
    ^

vim +/__ftrace_replace_code +5851 kernel/trace/ftrace.c

93eb677d Steven Rostedt           2009-04-15  5797  
7dcd182b Jessica Yu               2016-02-16  5798  void ftrace_module_enable(struct module *mod)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5799) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5800) 	struct dyn_ftrace *rec;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5801) 	struct ftrace_page *pg;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5802) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5803) 	mutex_lock(&ftrace_lock);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5804) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5805) 	if (ftrace_disabled)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5806) 		goto out_unlock;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5807) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5808) 	/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5809) 	 * If the tracing is enabled, go ahead and enable the record.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5810) 	 *
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5811) 	 * The reason not to enable the record immediatelly is the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5812) 	 * inherent check of ftrace_make_nop/ftrace_make_call for
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5813) 	 * correct previous instructions.  Making first the NOP
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5814) 	 * conversion puts the module to the correct state, thus
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5815) 	 * passing the ftrace_make_call check.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5816) 	 *
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5817) 	 * We also delay this to after the module code already set the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5818) 	 * text to read-only, as we now need to set it back to read-write
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5819) 	 * so that we can modify the text.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5820) 	 */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5821) 	if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5822) 		ftrace_arch_code_modify_prepare();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5823) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5824) 	do_for_each_ftrace_rec(pg, rec) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5825) 		int cnt;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5826) 		/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5827) 		 * do_for_each_ftrace_rec() is a double loop.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5828) 		 * module text shares the pg. If a record is
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5829) 		 * not part of this module, then skip this pg,
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5830) 		 * which the "break" will do.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5831) 		 */
3e234289 Steven Rostedt (VMware   2017-03-03  5832) 		if (!within_module_core(rec->ip, mod) &&
3e234289 Steven Rostedt (VMware   2017-03-03  5833) 		    !within_module_init(rec->ip, mod))
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5834) 			break;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5835) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5836) 		cnt = 0;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5837) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5838) 		/*
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5839) 		 * When adding a module, we need to check if tracers are
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5840) 		 * currently enabled and if they are, and can trace this record,
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5841) 		 * we need to enable the module functions as well as update the
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5842) 		 * reference counts for those function records.
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5843) 		 */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5844) 		if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5845) 			cnt += referenced_filters(rec);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5846) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5847) 		/* This clears FTRACE_FL_DISABLED */
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5848) 		rec->flags = cnt;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5849) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5850) 		if (ftrace_start_up && cnt) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07 @5851) 			int failed = __ftrace_replace_code(rec, 1);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5852) 			if (failed) {
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5853) 				ftrace_bug(failed, rec);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5854) 				goto out_loop;
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5855) 			}
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5856) 		}
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5857) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5858) 	} while_for_each_ftrace_rec();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5859) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5860)  out_loop:
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5861) 	if (ftrace_start_up)
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5862) 		ftrace_arch_code_modify_post_process();
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5863) 
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5864)  out_unlock:
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5865) 	mutex_unlock(&ftrace_lock);
d7fbf8df Steven Rostedt (VMware   2017-06-26  5866) 
d7fbf8df Steven Rostedt (VMware   2017-06-26  5867) 	process_cached_mods(mod->name);
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5868) }
b7ffffbb Steven Rostedt (Red Hat  2016-01-07  5869) 

:::::: The code at line 5851 was first introduced by commit
:::::: b7ffffbb46f205e7727a18bcc7a46c3c2b534f7c ftrace: Add infrastructure for delayed enabling of module functions

:::::: TO: Steven Rostedt (Red Hat) <rostedt@goodmis.org>
:::::: CC: Steven Rostedt <rostedt@goodmis.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28472 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-02-25 14:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-23 16:58 [PATCH 0/3] ARM: Implement MODULE_PLT support in FTRACE Alexander Sverdlin
2018-02-23 16:58 ` [PATCH 1/3] ftrace: Add module to ftrace_make_call() parameters Alexander Sverdlin
2018-02-25 11:53   ` kbuild test robot
2018-02-25 14:57   ` kbuild test robot
2018-02-23 16:58 ` [PATCH 2/3] ARM: PLT: Move struct plt_entries definition to header Alexander Sverdlin
2018-02-23 16:58 ` [PATCH 3/3] ftrace: Add MODULE_PLTS support Alexander Sverdlin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox