All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@csgroup.eu>
To: Naveen N Rao <naveen@kernel.org>,
	"linuxppc-dev@lists.ozlabs.org" <linuxppc-dev@lists.ozlabs.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Subject: Re: [PATCH 11/17] powerpc/ftrace: Simplify ftrace_make_nop()
Date: Fri, 23 Jun 2023 05:30:08 +0000	[thread overview]
Message-ID: <5e4eb0eb-591c-d1f2-4092-0def1a033ba9@csgroup.eu> (raw)
In-Reply-To: <e12ccbf28c50c3a07fb614f4d392e55f7098a729.1687166935.git.naveen@kernel.org>



Le 19/06/2023 à 11:47, Naveen N Rao a écrit :
> Now that we validate the ftrace location during initialization in
> ftrace_init_nop(), we can simplify ftrace_make_nop() to patch-in the nop
> without worrying about the instructions surrounding the ftrace location.
> Note that we continue to ensure that we have a bl to
> ftrace_[regs_]caller at the ftrace location before nop-ing it out.
> 
> Signed-off-by: Naveen N Rao <naveen@kernel.org>

Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>

> ---
>   arch/powerpc/kernel/trace/ftrace.c | 220 +++++------------------------
>   1 file changed, 32 insertions(+), 188 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c
> index 98bd099c428ee0..05153a1038fdff 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -116,112 +116,6 @@ static unsigned long find_bl_target(unsigned long ip, ppc_inst_t op)
>   	return ip + (long)offset;
>   }
>   
> -#ifdef CONFIG_MODULES
> -static int
> -__ftrace_make_nop(struct module *mod,
> -		  struct dyn_ftrace *rec, unsigned long addr)
> -{
> -	unsigned long entry, ptr, tramp;
> -	unsigned long ip = rec->ip;
> -	ppc_inst_t op, pop;
> -
> -	/* read where this goes */
> -	if (copy_inst_from_kernel_nofault(&op, (void *)ip)) {
> -		pr_err("Fetching opcode failed.\n");
> -		return -EFAULT;
> -	}
> -
> -	/* Make sure that this is still a 24bit jump */
> -	if (!is_bl_op(op)) {
> -		pr_err("Not expected bl: opcode is %08lx\n", ppc_inst_as_ulong(op));
> -		return -EINVAL;
> -	}
> -
> -	/* lets find where the pointer goes */
> -	tramp = find_bl_target(ip, op);
> -
> -	pr_devel("ip:%lx jumps to %lx", ip, tramp);
> -
> -	if (module_trampoline_target(mod, tramp, &ptr)) {
> -		pr_err("Failed to get trampoline target\n");
> -		return -EFAULT;
> -	}
> -
> -	pr_devel("trampoline target %lx", ptr);
> -
> -	entry = ppc_global_function_entry((void *)addr);
> -	/* This should match what was called */
> -	if (ptr != entry) {
> -		pr_err("addr %lx does not match expected %lx\n", ptr, entry);
> -		return -EINVAL;
> -	}
> -
> -	if (IS_ENABLED(CONFIG_MPROFILE_KERNEL)) {
> -		if (copy_inst_from_kernel_nofault(&op, (void *)(ip - 4))) {
> -			pr_err("Fetching instruction at %lx failed.\n", ip - 4);
> -			return -EFAULT;
> -		}
> -
> -		/* We expect either a mflr r0, or a std r0, LRSAVE(r1) */
> -		if (!ppc_inst_equal(op, ppc_inst(PPC_RAW_MFLR(_R0))) &&
> -		    !ppc_inst_equal(op, ppc_inst(PPC_INST_STD_LR))) {
> -			pr_err("Unexpected instruction %08lx around bl _mcount\n",
> -			       ppc_inst_as_ulong(op));
> -			return -EINVAL;
> -		}
> -	} else if (IS_ENABLED(CONFIG_PPC64)) {
> -		/*
> -		 * Check what is in the next instruction. We can see ld r2,40(r1), but
> -		 * on first pass after boot we will see mflr r0.
> -		 */
> -		if (copy_inst_from_kernel_nofault(&op, (void *)(ip + 4))) {
> -			pr_err("Fetching op failed.\n");
> -			return -EFAULT;
> -		}
> -
> -		if (!ppc_inst_equal(op,  ppc_inst(PPC_INST_LD_TOC))) {
> -			pr_err("Expected %08lx found %08lx\n", PPC_INST_LD_TOC,
> -			       ppc_inst_as_ulong(op));
> -			return -EINVAL;
> -		}
> -	}
> -
> -	/*
> -	 * When using -mprofile-kernel or PPC32 there is no load to jump over.
> -	 *
> -	 * Otherwise our original call site looks like:
> -	 *
> -	 * bl <tramp>
> -	 * ld r2,XX(r1)
> -	 *
> -	 * Milton Miller pointed out that we can not simply nop the branch.
> -	 * If a task was preempted when calling a trace function, the nops
> -	 * will remove the way to restore the TOC in r2 and the r2 TOC will
> -	 * get corrupted.
> -	 *
> -	 * Use a b +8 to jump over the load.
> -	 * XXX: could make PCREL depend on MPROFILE_KERNEL
> -	 * XXX: check PCREL && MPROFILE_KERNEL calling sequence
> -	 */
> -	if (IS_ENABLED(CONFIG_MPROFILE_KERNEL) || IS_ENABLED(CONFIG_PPC32))
> -		pop = ppc_inst(PPC_RAW_NOP());
> -	else
> -		pop = ppc_inst(PPC_RAW_BRANCH(8));	/* b +8 */
> -
> -	if (patch_instruction((u32 *)ip, pop)) {
> -		pr_err("Patching NOP failed.\n");
> -		return -EPERM;
> -	}
> -
> -	return 0;
> -}
> -#else
> -static int __ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr)
> -{
> -	return 0;
> -}
> -#endif /* CONFIG_MODULES */
> -
>   static unsigned long find_ftrace_tramp(unsigned long ip)
>   {
>   	int i;
> @@ -235,88 +129,6 @@ static unsigned long find_ftrace_tramp(unsigned long ip)
>   	return 0;
>   }
>   
> -static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr)
> -{
> -	unsigned long tramp, ip = rec->ip;
> -	ppc_inst_t op;
> -
> -	/* Read where this goes */
> -	if (copy_inst_from_kernel_nofault(&op, (void *)ip)) {
> -		pr_err("Fetching opcode failed.\n");
> -		return -EFAULT;
> -	}
> -
> -	/* Make sure that this is still a 24bit jump */
> -	if (!is_bl_op(op)) {
> -		pr_err("Not expected bl: opcode is %08lx\n", ppc_inst_as_ulong(op));
> -		return -EINVAL;
> -	}
> -
> -	/* Let's find where the pointer goes */
> -	tramp = find_bl_target(ip, op);
> -
> -	pr_devel("ip:%lx jumps to %lx", ip, tramp);
> -
> -	/* Are ftrace trampolines reachable? */
> -	if (!find_ftrace_tramp(ip)) {
> -		pr_err("No ftrace trampolines reachable from %ps\n", (void *)ip);
> -		return -EINVAL;
> -	}
> -
> -	if (patch_instruction((u32 *)ip, ppc_inst(PPC_RAW_NOP()))) {
> -		pr_err("Patching NOP failed.\n");
> -		return -EPERM;
> -	}
> -
> -	return 0;
> -}
> -
> -int ftrace_make_nop(struct module *mod,
> -		    struct dyn_ftrace *rec, unsigned long addr)
> -{
> -	unsigned long ip = rec->ip;
> -	ppc_inst_t old, new;
> -
> -	/*
> -	 * If the calling address is more that 24 bits away,
> -	 * then we had to use a trampoline to make the call.
> -	 * Otherwise just update the call site.
> -	 */
> -	if (test_24bit_addr(ip, addr)) {
> -		/* within range */
> -		old = ftrace_call_replace(ip, addr, 1);
> -		new = ppc_inst(PPC_RAW_NOP());
> -		return ftrace_modify_code(ip, old, new);
> -	} else if (core_kernel_text(ip)) {
> -		return __ftrace_make_nop_kernel(rec, addr);
> -	} else if (!IS_ENABLED(CONFIG_MODULES)) {
> -		return -EINVAL;
> -	}
> -
> -	/*
> -	 * Out of range jumps are called from modules.
> -	 * We should either already have a pointer to the module
> -	 * or it has been passed in.
> -	 */
> -	if (!rec->arch.mod) {
> -		if (!mod) {
> -			pr_err("No module loaded addr=%lx\n", addr);
> -			return -EFAULT;
> -		}
> -		rec->arch.mod = mod;
> -	} else if (mod) {
> -		if (mod != rec->arch.mod) {
> -			pr_err("Record mod %p not equal to passed in mod %p\n",
> -			       rec->arch.mod, mod);
> -			return -EINVAL;
> -		}
> -		/* nothing to do if mod == rec->arch.mod */
> -	} else
> -		mod = rec->arch.mod;
> -
> -	return __ftrace_make_nop(mod, rec, addr);
> -}
> -
>   #ifdef CONFIG_MODULES
>   /*
>    * Examine the existing instructions for __ftrace_make_call.
> @@ -607,6 +419,38 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
>   }
>   #endif
>   
> +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr)
> +{
> +	unsigned long tramp, ip = rec->ip;
> +	ppc_inst_t old, new;
> +
> +	/* Nop-out the ftrace location */
> +	new = ppc_inst(PPC_RAW_NOP());
> +	if (is_offset_in_branch_range(addr - ip)) {
> +		/* Within range */
> +		old = ftrace_create_branch_inst(ip, addr, 1);
> +		return ftrace_modify_code(ip, old, new);
> +	} else if (core_kernel_text(ip)) {
> +		/* We would be branching to one of our ftrace tramps */
> +		tramp = find_ftrace_tramp(ip);
> +		if (!tramp) {
> +			pr_err("0x%lx: No ftrace trampolines reachable\n", ip);
> +			return -EINVAL;
> +		}
> +		old = ftrace_create_branch_inst(ip, tramp, 1);
> +		return ftrace_modify_code(ip, old, new);
> +	} else if (IS_ENABLED(CONFIG_MODULES)) {
> +		/* Module code would be going to one of the module stubs */
> +		if (!mod)
> +			mod = rec->arch.mod;
> +		tramp = (addr == (unsigned long)ftrace_caller ? mod->arch.tramp : mod->arch.tramp_regs);
> +		old = ftrace_create_branch_inst(ip, tramp, 1);
> +		return ftrace_modify_code(ip, old, new);
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
>   {
>   	unsigned long addr, ip = rec->ip;

  reply	other threads:[~2023-06-23  5:31 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-19  9:47 [PATCH 00/17] powerpc/ftrace: refactor and add support for -fpatchable-function-entry Naveen N Rao
2023-06-19  9:47 ` [PATCH 01/17] powerpc/ftrace: Fix dropping weak symbols with older toolchains Naveen N Rao
2023-06-23  5:10   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 02/17] powerpc/module: Remove unused .ftrace.tramp section Naveen N Rao
2023-06-23  5:12   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 03/17] powerpc64/ftrace: Move ELFv1 and -pg support code into a separate file Naveen N Rao
2023-06-23  5:13   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 04/17] powerpc/ftrace: Simplify function_graph support in ftrace.c Naveen N Rao
2023-06-23  5:14   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 05/17] powerpc/ftrace: Use FTRACE_REGS_ADDR to identify the correct ftrace trampoline Naveen N Rao
2023-06-23  5:15   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 06/17] powerpc/ftrace: Extend ftrace support for large kernels to ppc32 Naveen N Rao
2023-06-23  5:21   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 07/17] powerpc/ftrace: Consolidate ftrace support into fewer files Naveen N Rao
2023-06-23  5:25   ` Christophe Leroy
2023-06-28  7:32     ` Naveen N Rao
2023-06-19  9:47 ` [PATCH 08/17] powerpc/ftrace: Refactor ftrace_modify_code() Naveen N Rao
2023-06-23  5:27   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 09/17] powerpc/ftrace: Stop re-purposing linker generated long branches for ftrace Naveen N Rao
2023-06-23  5:28   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 10/17] powerpc/ftrace: Add separate ftrace_init_nop() with additional validation Naveen N Rao
2023-06-23  5:29   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 11/17] powerpc/ftrace: Simplify ftrace_make_nop() Naveen N Rao
2023-06-23  5:30   ` Christophe Leroy [this message]
2023-06-19  9:47 ` [PATCH 12/17] powerpc/ftrace: Simplify ftrace_make_call() Naveen N Rao
2023-06-23  5:30   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 13/17] powerpc/ftrace: Simplify ftrace_modify_call() Naveen N Rao
2023-06-23  5:31   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 14/17] powerpc/ftrace: Replace use of ftrace_call_replace() with ftrace_create_branch_inst() Naveen N Rao
2023-06-23  5:32   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 15/17] powerpc/ftrace: Implement ftrace_replace_code() Naveen N Rao
2023-06-23  5:32   ` Christophe Leroy
2023-06-19  9:47 ` [PATCH 16/17] powerpc/ftrace: Add support for -fpatchable-function-entry Naveen N Rao
2023-06-23  5:37   ` Christophe Leroy
2023-06-28  7:40     ` Naveen N Rao
2023-06-19  9:47 ` [PATCH 17/17] powerpc/ftrace: Create a dummy stackframe to fix stack unwind Naveen N Rao
2023-06-23  5:40   ` Christophe Leroy
2023-06-28  7:43     ` Naveen N Rao
2023-08-23 11:55 ` [PATCH 00/17] powerpc/ftrace: refactor and add support for -fpatchable-function-entry Michael Ellerman

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=5e4eb0eb-591c-d1f2-4092-0def1a033ba9@csgroup.eu \
    --to=christophe.leroy@csgroup.eu \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=naveen@kernel.org \
    --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 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.