Skip to content

Commit f3993a0

Browse files
rnavmpe
authored andcommitted
powerpc/ftrace: Extend ftrace support for large kernels to ppc32
Commit 67361cf ("powerpc/ftrace: Handle large kernel configs") added ftrace support for ppc64 kernel images with a text section larger than 32MB. The approach itself isn't specific to ppc64, so extend the same to also work on ppc32. While at it, reduce the space reserved for the stub from 64 bytes to 32 bytes since the different stub variants are all less than 8 instructions. To reduce use of #ifdef, a stub implementation is provided for kernel_toc_address() and -SZ_2G is cast to 'long long' to prevent errors on ppc32. Signed-off-by: Naveen N Rao <naveen@kernel.org> Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/9fa3258cbb9105cf8a0a8135214d44ffbc75fe84.1687166935.git.naveen@kernel.org
1 parent b5efb61 commit f3993a0

5 files changed

Lines changed: 32 additions & 29 deletions

File tree

arch/powerpc/include/asm/ftrace.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,19 @@ static inline u8 this_cpu_get_ftrace_enabled(void)
124124
{
125125
return get_paca()->ftrace_enabled;
126126
}
127-
128-
void ftrace_free_init_tramp(void);
129127
#else /* CONFIG_PPC64 */
130128
static inline void this_cpu_disable_ftrace(void) { }
131129
static inline void this_cpu_enable_ftrace(void) { }
132130
static inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled) { }
133131
static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }
134-
static inline void ftrace_free_init_tramp(void) { }
135132
#endif /* CONFIG_PPC64 */
133+
134+
#ifdef CONFIG_FUNCTION_TRACER
135+
extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[];
136+
void ftrace_free_init_tramp(void);
137+
#else
138+
static inline void ftrace_free_init_tramp(void) { }
139+
#endif
136140
#endif /* !__ASSEMBLY__ */
137141

138142
#endif /* _ASM_POWERPC_FTRACE */

arch/powerpc/include/asm/sections.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
7474
(unsigned long)_stext < end;
7575
}
7676

77+
#else
78+
static inline unsigned long kernel_toc_addr(void) { BUILD_BUG(); return -1UL; }
7779
#endif
7880

7981
#endif /* __KERNEL__ */

arch/powerpc/kernel/trace/ftrace.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,6 @@ void arch_ftrace_update_code(int command)
707707
ftrace_modify_all_code(command);
708708
}
709709

710-
#ifdef CONFIG_PPC64
711-
#define PACATOC offsetof(struct paca_struct, kernel_toc)
712-
713-
extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[];
714-
715710
void ftrace_free_init_tramp(void)
716711
{
717712
int i;
@@ -725,28 +720,30 @@ void ftrace_free_init_tramp(void)
725720

726721
int __init ftrace_dyn_arch_init(void)
727722
{
728-
int i;
729723
unsigned int *tramp[] = { ftrace_tramp_text, ftrace_tramp_init };
730-
#ifdef CONFIG_PPC_KERNEL_PCREL
724+
unsigned long addr = FTRACE_REGS_ADDR;
725+
long reladdr;
726+
int i;
731727
u32 stub_insns[] = {
728+
#ifdef CONFIG_PPC_KERNEL_PCREL
732729
/* pla r12,addr */
733730
PPC_PREFIX_MLS | __PPC_PRFX_R(1),
734731
PPC_INST_PADDI | ___PPC_RT(_R12),
735732
PPC_RAW_MTCTR(_R12),
736733
PPC_RAW_BCTR()
737-
};
738-
#else
739-
u32 stub_insns[] = {
740-
PPC_RAW_LD(_R12, _R13, PACATOC),
734+
#elif defined(CONFIG_PPC64)
735+
PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernel_toc)),
741736
PPC_RAW_ADDIS(_R12, _R12, 0),
742737
PPC_RAW_ADDI(_R12, _R12, 0),
743738
PPC_RAW_MTCTR(_R12),
744739
PPC_RAW_BCTR()
745-
};
740+
#else
741+
PPC_RAW_LIS(_R12, 0),
742+
PPC_RAW_ADDI(_R12, _R12, 0),
743+
PPC_RAW_MTCTR(_R12),
744+
PPC_RAW_BCTR()
746745
#endif
747-
748-
unsigned long addr = FTRACE_REGS_ADDR;
749-
long reladdr;
746+
};
750747

751748
if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) {
752749
for (i = 0; i < 2; i++) {
@@ -763,10 +760,10 @@ int __init ftrace_dyn_arch_init(void)
763760
tramp[i][1] |= IMM_L(reladdr);
764761
add_ftrace_tramp((unsigned long)tramp[i]);
765762
}
766-
} else {
763+
} else if (IS_ENABLED(CONFIG_PPC64)) {
767764
reladdr = addr - kernel_toc_addr();
768765

769-
if (reladdr >= (long)SZ_2G || reladdr < -(long)SZ_2G) {
766+
if (reladdr >= (long)SZ_2G || reladdr < -(long long)SZ_2G) {
770767
pr_err("Address of %ps out of range of kernel_toc.\n",
771768
(void *)addr);
772769
return -1;
@@ -778,11 +775,17 @@ int __init ftrace_dyn_arch_init(void)
778775
tramp[i][2] |= PPC_LO(reladdr);
779776
add_ftrace_tramp((unsigned long)tramp[i]);
780777
}
778+
} else {
779+
for (i = 0; i < 2; i++) {
780+
memcpy(tramp[i], stub_insns, sizeof(stub_insns));
781+
tramp[i][0] |= PPC_HA(addr);
782+
tramp[i][1] |= PPC_LO(addr);
783+
add_ftrace_tramp((unsigned long)tramp[i]);
784+
}
781785
}
782786

783787
return 0;
784788
}
785-
#endif
786789

787790
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
788791
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,

arch/powerpc/kernel/trace/ftrace_low.S

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,17 @@
1010
#include <asm/ftrace.h>
1111
#include <asm/ppc-opcode.h>
1212

13-
#ifdef CONFIG_PPC64
1413
.pushsection ".tramp.ftrace.text","aw",@progbits;
1514
.globl ftrace_tramp_text
1615
ftrace_tramp_text:
17-
.space 64
16+
.space 32
1817
.popsection
1918

2019
.pushsection ".tramp.ftrace.init","aw",@progbits;
2120
.globl ftrace_tramp_init
2221
ftrace_tramp_init:
23-
.space 64
22+
.space 32
2423
.popsection
25-
#endif
2624

2725
_GLOBAL(mcount)
2826
_GLOBAL(_mcount)

arch/powerpc/kernel/vmlinux.lds.S

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ SECTIONS
107107
#endif
108108
/* careful! __ftr_alt_* sections need to be close to .text */
109109
*(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text);
110-
#ifdef CONFIG_PPC64
111110
*(.tramp.ftrace.text);
112-
#endif
113111
NOINSTR_TEXT
114112
SCHED_TEXT
115113
LOCK_TEXT
@@ -276,9 +274,7 @@ SECTIONS
276274
*/
277275
. = ALIGN(PAGE_SIZE);
278276
_einittext = .;
279-
#ifdef CONFIG_PPC64
280277
*(.tramp.ftrace.init);
281-
#endif
282278
} :text
283279

284280
/* .exit.text is discarded at runtime, not link time,

0 commit comments

Comments
 (0)