From: Balbir Singh <bsingharora@gmail.com>
To: Michael Ellerman <mpe@ellerman.id.au>, linuxppc-dev@ozlabs.org
Cc: duwe@lst.de, linux-kernel@vger.kernel.org, rostedt@goodmis.org,
kamalesh@linux.vnet.ibm.com, pmladek@suse.com, jeyu@redhat.com,
jkosina@suse.cz, live-patching@vger.kernel.org, mbenes@suse.cz
Subject: Re: [PATCH 02/12] powerpc/module: Mark module stubs with a magic value
Date: Thu, 25 Feb 2016 11:04:08 +1100 [thread overview]
Message-ID: <56CE44F8.8070605@gmail.com> (raw)
In-Reply-To: <1456324115-21144-2-git-send-email-mpe@ellerman.id.au>
On 25/02/16 01:28, Michael Ellerman wrote:
> When a module is loaded, calls out to the kernel go via a stub which is
> generated at runtime. One of these stubs is used to call _mcount(),
> which is the default target of tracing calls generated by the compiler
> with -pg.
>
> If dynamic ftrace is enabled (which it typicall is), another stub is
> used to call ftrace_caller(), which is the target of tracing calls when
> ftrace is actually active.
>
> ftrace then wants to disable the calls to _mcount() at module startup,
> and enable/disable the calls to ftrace_caller() when enabling/disablig
> tracing - all of these it does by patching the code.
>
> As part of that code patching, the ftrace code wants to confirm that the
> branch it is about to modify, is in fact a call to a module stub which
> calls _mcount() or ftrace_caller().
>
> Currently it does that by inspecting the instructions and confirming
> they are what it expects. Although that works, the code to do it is
> pretty intricate because it requires lots of knowledge about the exact
> format of the stub.
>
> We can make that process easier by marking the generated stubs with a
> magic value, and then looking for that magic value. Altough this is not
> as rigorous as the current method, I believe it is sufficient in
> practice.
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/include/asm/module.h | 3 +-
> arch/powerpc/kernel/ftrace.c | 14 ++-----
> arch/powerpc/kernel/module_64.c | 78 +++++++++++++--------------------------
> 3 files changed, 31 insertions(+), 64 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
> index 74d25a749018..5b6b5a427b54 100644
> --- a/arch/powerpc/include/asm/module.h
> +++ b/arch/powerpc/include/asm/module.h
> @@ -78,8 +78,7 @@ struct mod_arch_specific {
> # endif /* MODULE */
> #endif
>
> -bool is_module_trampoline(u32 *insns);
> -int module_trampoline_target(struct module *mod, u32 *trampoline,
> +int module_trampoline_target(struct module *mod, unsigned long trampoline,
> unsigned long *target);
>
> #ifdef CONFIG_DYNAMIC_FTRACE
> diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
> index 44d4d8eb3c85..4505cbfd0e13 100644
> --- a/arch/powerpc/kernel/ftrace.c
> +++ b/arch/powerpc/kernel/ftrace.c
> @@ -106,10 +106,9 @@ static int
> __ftrace_make_nop(struct module *mod,
> struct dyn_ftrace *rec, unsigned long addr)
> {
> - unsigned int op;
> - unsigned long entry, ptr;
> + unsigned long entry, ptr, tramp;
> unsigned long ip = rec->ip;
> - void *tramp;
> + unsigned int op;
>
> /* read where this goes */
> if (probe_kernel_read(&op, (void *)ip, sizeof(int)))
> @@ -122,14 +121,9 @@ __ftrace_make_nop(struct module *mod,
> }
>
> /* lets find where the pointer goes */
> - tramp = (void *)find_bl_target(ip, op);
> -
> - pr_devel("ip:%lx jumps to %p", ip, tramp);
> + tramp = find_bl_target(ip, op);
>
> - if (!is_module_trampoline(tramp)) {
> - pr_err("Not a trampoline\n");
> - return -EINVAL;
> - }
> + pr_devel("ip:%lx jumps to %lx", ip, tramp);
>
> if (module_trampoline_target(mod, tramp, &ptr)) {
> pr_err("Failed to get trampoline target\n");
> diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
> index 599c753c7960..9629966e614b 100644
> --- a/arch/powerpc/kernel/module_64.c
> +++ b/arch/powerpc/kernel/module_64.c
> @@ -96,6 +96,8 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
> }
> #endif
>
> +#define STUB_MAGIC 0x73747562 /* stub */
> +
> /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
> the kernel itself). But on PPC64, these need to be used for every
> jump, actually, to reset r2 (TOC+0x8000). */
> @@ -105,7 +107,8 @@ struct ppc64_stub_entry
> * need 6 instructions on ABIv2 but we always allocate 7 so
> * so we don't have to modify the trampoline load instruction. */
> u32 jump[7];
> - u32 unused;
> + /* Used by ftrace to identify stubs */
> + u32 magic;
> /* Data for the above code */
> func_desc_t funcdata;
> };
> @@ -139,70 +142,39 @@ static u32 ppc64_stub_insns[] = {
> };
>
> #ifdef CONFIG_DYNAMIC_FTRACE
> -
> -static u32 ppc64_stub_mask[] = {
> - 0xffff0000,
> - 0xffff0000,
> - 0xffffffff,
> - 0xffffffff,
> -#if !defined(_CALL_ELF) || _CALL_ELF != 2
> - 0xffffffff,
> -#endif
> - 0xffffffff,
> - 0xffffffff
> -};
> -
> -bool is_module_trampoline(u32 *p)
> +int module_trampoline_target(struct module *mod, unsigned long addr,
> + unsigned long *target)
> {
> - unsigned int i;
> - u32 insns[ARRAY_SIZE(ppc64_stub_insns)];
> -
> - BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask));
> + struct ppc64_stub_entry *stub;
> + func_desc_t funcdata;
> + u32 magic;
>
> - if (probe_kernel_read(insns, p, sizeof(insns)))
> + if (!within_module_core(addr, mod)) {
> + pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name);
> return -EFAULT;
-EFAULT or -EINVAL? I wonder if we can recover from a bad trampoline address.
Reviewed-by: Balbir Singh <bsingharora@gmail.com>
next prev parent reply other threads:[~2016-02-25 0:04 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-24 14:28 [PATCH 01/12] powerpc/module: Only try to generate the ftrace_caller() stub once Michael Ellerman
2016-02-24 14:28 ` [PATCH 02/12] powerpc/module: Mark module stubs with a magic value Michael Ellerman
2016-02-25 0:04 ` Balbir Singh [this message]
2016-02-25 6:43 ` Michael Ellerman
2016-02-25 13:17 ` Torsten Duwe
2016-02-26 10:37 ` Michael Ellerman
2016-02-24 14:28 ` [PATCH 03/12] powerpc/module: Create a special stub for ftrace_caller() Michael Ellerman
2016-02-25 0:08 ` Balbir Singh
2016-02-25 10:48 ` Michael Ellerman
2016-02-25 13:31 ` Torsten Duwe
2016-02-26 10:35 ` Michael Ellerman
2016-02-24 14:28 ` [PATCH 04/12] powerpc/ftrace: Prepare for -mprofile-kernel Michael Ellerman
2016-02-25 0:28 ` Balbir Singh
2016-02-25 10:37 ` Michael Ellerman
2016-02-25 13:52 ` Torsten Duwe
2016-02-26 10:14 ` Michael Ellerman
2016-02-24 14:28 ` [PATCH 05/12] powerpc/ftrace: ftrace_graph_caller() needs to save/restore toc Michael Ellerman
2016-02-25 0:30 ` Balbir Singh
2016-02-25 10:39 ` Michael Ellerman
2016-02-25 14:02 ` Torsten Duwe
2016-02-24 14:28 ` [PATCH 06/12] powerpc/module: Rework is_early_mcount_callsite() Michael Ellerman
2016-02-24 23:39 ` Balbir Singh
2016-02-25 10:28 ` Michael Ellerman
2016-02-25 14:06 ` Torsten Duwe
2016-02-24 14:28 ` [PATCH 07/12] powerpc/ftrace: FTRACE_WITH_REGS implementation for ppc64le Michael Ellerman
2016-02-25 0:48 ` Balbir Singh
2016-02-25 15:11 ` Torsten Duwe
2016-02-26 10:14 ` Michael Ellerman
2016-02-24 14:28 ` [PATCH 08/12] powerpc/ftrace: Rework ftrace_caller() Michael Ellerman
2016-02-25 1:06 ` Balbir Singh
2016-02-25 14:25 ` Torsten Duwe
2016-02-24 14:28 ` [PATCH 09/12] powerpc/ftrace: Use generic ftrace_modify_all_code() Michael Ellerman
2016-02-25 1:10 ` Balbir Singh
2016-02-24 14:28 ` [PATCH 10/12] powerpc/ftrace: FTRACE_WITH_REGS configuration variables Michael Ellerman
2016-02-25 1:11 ` Balbir Singh
2016-02-25 14:34 ` Torsten Duwe
2016-02-24 14:28 ` [PATCH 11/12] powerpc/ftrace: Rework __ftrace_make_nop() Michael Ellerman
2016-02-24 14:28 ` [PATCH 12/12] powerpc/ftrace: Disable profiling for some files Michael Ellerman
2016-02-25 1:13 ` Balbir Singh
2016-02-24 23:55 ` [PATCH 01/12] powerpc/module: Only try to generate the ftrace_caller() stub once Balbir Singh
2016-02-25 4:36 ` Balbir Singh
2016-02-25 13:08 ` Torsten Duwe
2016-02-25 14:38 ` Kamalesh Babulal
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=56CE44F8.8070605@gmail.com \
--to=bsingharora@gmail.com \
--cc=duwe@lst.de \
--cc=jeyu@redhat.com \
--cc=jkosina@suse.cz \
--cc=kamalesh@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=mpe@ellerman.id.au \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).