Skip to content

Commit

Permalink
powerpc64/module: Tighten detection of mcount call sites with -mprofi…
Browse files Browse the repository at this point in the history
…le-kernel

For R_PPC64_REL24 relocations, we suppress emitting instructions for TOC
load/restore in the relocation stub if the relocation is for _mcount()
call when using -mprofile-kernel ABI.

To detect this, we check if the preceding instructions are per the
standard set of instructions emitted by gcc: either the two instruction
sequence of 'mflr r0; std r0,16(r1)', or the more optimized variant of a
single 'mflr r0'. This is not sufficient since nothing prevents users
from hand coding sequences involving a 'mflr r0' followed by a 'bl'.

For removing the toc save instruction from the stub, we additionally
check if the symbol is "_mcount". Add the same check here as well.

Also rename is_early_mcount_callsite() to is_mprofile_mcount_callsite()
since that is what is being checked. The use of "early" is misleading
since there is nothing involving this function that qualifies as early.

Fixes: 1530866 ("powerpc/ftrace: Add support for -mprofile-kernel ftrace ABI")
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Naveen N. Rao authored and Michael Ellerman committed May 3, 2018
1 parent 88b1a85 commit 250122b
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions arch/powerpc/kernel/module_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,11 @@ static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
}

#ifdef CC_USING_MPROFILE_KERNEL
static bool is_early_mcount_callsite(u32 *instruction)
static bool is_mprofile_mcount_callsite(const char *name, u32 *instruction)
{
if (strcmp("_mcount", name))
return false;

/*
* Check if this is one of the -mprofile-kernel sequences.
*/
Expand Down Expand Up @@ -496,20 +499,19 @@ static void squash_toc_save_inst(const char *name, unsigned long addr)
#else
static void squash_toc_save_inst(const char *name, unsigned long addr) { }

/* without -mprofile-kernel, mcount calls are never early */
static bool is_early_mcount_callsite(u32 *instruction)
static bool is_mprofile_mcount_callsite(const char *name, u32 *instruction)
{
return false;
}
#endif

/* We expect a noop next: if it is, replace it with instruction to
restore r2. */
static int restore_r2(u32 *instruction, struct module *me)
static int restore_r2(const char *name, u32 *instruction, struct module *me)
{
u32 *prev_insn = instruction - 1;

if (is_early_mcount_callsite(prev_insn))
if (is_mprofile_mcount_callsite(name, prev_insn))
return 1;

/*
Expand Down Expand Up @@ -650,7 +652,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
value = stub_for_addr(sechdrs, value, me);
if (!value)
return -ENOENT;
if (!restore_r2((u32 *)location + 1, me))
if (!restore_r2(strtab + sym->st_name,
(u32 *)location + 1, me))
return -ENOEXEC;

squash_toc_save_inst(strtab + sym->st_name, value);
Expand Down

0 comments on commit 250122b

Please sign in to comment.