powerpc/ftrace: Handle large kernel configs
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tue, 16 Oct 2018 20:25:00 +0000 (01:55 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 20 Oct 2018 02:26:47 +0000 (13:26 +1100)
commit67361cf80712867329a9cd3ff0e3171545cfc867
tree1946e36e656030e2dbd947f0190dcd3e56e748f5
parentdd0e144a632bcf2b5a6f04e2628e32b16d499277
powerpc/ftrace: Handle large kernel configs

Currently, we expect to be able to reach ftrace_caller() from all
ftrace-enabled functions through a single relative branch. With large
kernel configs, we see functions outside of 32MB of ftrace_caller()
causing ftrace_init() to bail.

In such configurations, gcc/ld emits two types of trampolines for mcount():
1. A long_branch, which has a single branch to mcount() for functions that
   are one hop away from mcount():
c0000000019e8544 <00031b56.long_branch._mcount>:
c0000000019e8544: 4a 69 3f ac  b       c00000000007c4f0 <._mcount>

2. A plt_branch, for functions that are farther away from mcount():
c0000000051f33f8 <0008ba04.plt_branch._mcount>:
c0000000051f33f8: 3d 82 ff a4  addis   r12,r2,-92
c0000000051f33fc: e9 8c 04 20  ld      r12,1056(r12)
c0000000051f3400: 7d 89 03 a6  mtctr   r12
c0000000051f3404: 4e 80 04 20  bctr

We can reuse those trampolines for ftrace if we can have those
trampolines go to ftrace_caller() instead. However, with ABIv2, we
cannot depend on r2 being valid. As such, we use only the long_branch
trampolines by patching those to instead branch to ftrace_caller or
ftrace_regs_caller.

In addition, we add additional trampolines around .text and .init.text
to catch locations that are covered by the plt branches. This allows
ftrace to work with most large kernel configurations.

For now, we always patch the trampolines to go to ftrace_regs_caller,
which is slightly inefficient. This can be optimized further at a later
point.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/trace/ftrace.c
arch/powerpc/kernel/trace/ftrace_64.S
arch/powerpc/kernel/vmlinux.lds.S