Skip to content

Commit 7888af4

Browse files
committed
ftrace: Make ftrace_regs abstract from direct use
ftrace_regs was created to hold registers that store information to save function parameters, return value and stack. Since it is a subset of pt_regs, it should only be used by its accessor functions. But because pt_regs can easily be taken from ftrace_regs (on most archs), it is tempting to use it directly. But when running on other architectures, it may fail to build or worse, build but crash the kernel! Instead, make struct ftrace_regs an empty structure and have the architectures define __arch_ftrace_regs and all the accessor functions will typecast to it to get to the actual fields. This will help avoid usage of ftrace_regs directly. Link: https://lore.kernel.org/all/[email protected]/ Cc: "[email protected]" <[email protected]> Cc: "[email protected]" <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Will Deacon <[email protected]> Cc: Huacai Chen <[email protected]> Cc: WANG Xuerui <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Naveen N Rao <[email protected]> Cc: Madhavan Srinivasan <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Albert Ou <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Vasily Gorbik <[email protected]> Cc: Alexander Gordeev <[email protected]> Cc: Christian Borntraeger <[email protected]> Cc: Sven Schnelle <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Link: https://lore.kernel.org/[email protected] Acked-by: Catalin Marinas <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]> Acked-by: Masami Hiramatsu (Google) <[email protected]> Acked-by: Heiko Carstens <[email protected]> # s390 Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent c73eb02 commit 7888af4

File tree

19 files changed

+134
-103
lines changed

19 files changed

+134
-103
lines changed

arch/arm64/include/asm/ftrace.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,16 @@ unsigned long ftrace_call_adjust(unsigned long addr);
5656
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
5757
struct dyn_ftrace;
5858
struct ftrace_ops;
59+
struct ftrace_regs;
60+
#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs))
5961

6062
#define arch_ftrace_get_regs(regs) NULL
6163

6264
/*
6365
* Note: sizeof(struct ftrace_regs) must be a multiple of 16 to ensure correct
6466
* stack alignment
6567
*/
66-
struct ftrace_regs {
68+
struct __arch_ftrace_regs {
6769
/* x0 - x8 */
6870
unsigned long regs[9];
6971

@@ -83,47 +85,47 @@ struct ftrace_regs {
8385
static __always_inline unsigned long
8486
ftrace_regs_get_instruction_pointer(const struct ftrace_regs *fregs)
8587
{
86-
return fregs->pc;
88+
return arch_ftrace_regs(fregs)->pc;
8789
}
8890

8991
static __always_inline void
9092
ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
9193
unsigned long pc)
9294
{
93-
fregs->pc = pc;
95+
arch_ftrace_regs(fregs)->pc = pc;
9496
}
9597

9698
static __always_inline unsigned long
9799
ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs)
98100
{
99-
return fregs->sp;
101+
return arch_ftrace_regs(fregs)->sp;
100102
}
101103

102104
static __always_inline unsigned long
103105
ftrace_regs_get_argument(struct ftrace_regs *fregs, unsigned int n)
104106
{
105107
if (n < 8)
106-
return fregs->regs[n];
108+
return arch_ftrace_regs(fregs)->regs[n];
107109
return 0;
108110
}
109111

110112
static __always_inline unsigned long
111113
ftrace_regs_get_return_value(const struct ftrace_regs *fregs)
112114
{
113-
return fregs->regs[0];
115+
return arch_ftrace_regs(fregs)->regs[0];
114116
}
115117

116118
static __always_inline void
117119
ftrace_regs_set_return_value(struct ftrace_regs *fregs,
118120
unsigned long ret)
119121
{
120-
fregs->regs[0] = ret;
122+
arch_ftrace_regs(fregs)->regs[0] = ret;
121123
}
122124

123125
static __always_inline void
124126
ftrace_override_function_with_return(struct ftrace_regs *fregs)
125127
{
126-
fregs->pc = fregs->lr;
128+
arch_ftrace_regs(fregs)->pc = arch_ftrace_regs(fregs)->lr;
127129
}
128130

129131
int ftrace_regs_query_register_offset(const char *name);
@@ -143,7 +145,7 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs,
143145
* The ftrace trampoline will return to this address instead of the
144146
* instrumented function.
145147
*/
146-
fregs->direct_tramp = addr;
148+
arch_ftrace_regs(fregs)->direct_tramp = addr;
147149
}
148150
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
149151

arch/arm64/kernel/asm-offsets.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,19 @@ int main(void)
8484
DEFINE(PT_REGS_SIZE, sizeof(struct pt_regs));
8585
BLANK();
8686
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
87-
DEFINE(FREGS_X0, offsetof(struct ftrace_regs, regs[0]));
88-
DEFINE(FREGS_X2, offsetof(struct ftrace_regs, regs[2]));
89-
DEFINE(FREGS_X4, offsetof(struct ftrace_regs, regs[4]));
90-
DEFINE(FREGS_X6, offsetof(struct ftrace_regs, regs[6]));
91-
DEFINE(FREGS_X8, offsetof(struct ftrace_regs, regs[8]));
92-
DEFINE(FREGS_FP, offsetof(struct ftrace_regs, fp));
93-
DEFINE(FREGS_LR, offsetof(struct ftrace_regs, lr));
94-
DEFINE(FREGS_SP, offsetof(struct ftrace_regs, sp));
95-
DEFINE(FREGS_PC, offsetof(struct ftrace_regs, pc));
87+
DEFINE(FREGS_X0, offsetof(struct __arch_ftrace_regs, regs[0]));
88+
DEFINE(FREGS_X2, offsetof(struct __arch_ftrace_regs, regs[2]));
89+
DEFINE(FREGS_X4, offsetof(struct __arch_ftrace_regs, regs[4]));
90+
DEFINE(FREGS_X6, offsetof(struct __arch_ftrace_regs, regs[6]));
91+
DEFINE(FREGS_X8, offsetof(struct __arch_ftrace_regs, regs[8]));
92+
DEFINE(FREGS_FP, offsetof(struct __arch_ftrace_regs, fp));
93+
DEFINE(FREGS_LR, offsetof(struct __arch_ftrace_regs, lr));
94+
DEFINE(FREGS_SP, offsetof(struct __arch_ftrace_regs, sp));
95+
DEFINE(FREGS_PC, offsetof(struct __arch_ftrace_regs, pc));
9696
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
97-
DEFINE(FREGS_DIRECT_TRAMP, offsetof(struct ftrace_regs, direct_tramp));
97+
DEFINE(FREGS_DIRECT_TRAMP, offsetof(struct __arch_ftrace_regs, direct_tramp));
9898
#endif
99-
DEFINE(FREGS_SIZE, sizeof(struct ftrace_regs));
99+
DEFINE(FREGS_SIZE, sizeof(struct __arch_ftrace_regs));
100100
BLANK();
101101
#endif
102102
#ifdef CONFIG_COMPAT

arch/arm64/kernel/ftrace.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ struct fregs_offset {
2323
int offset;
2424
};
2525

26-
#define FREGS_OFFSET(n, field) \
27-
{ \
28-
.name = n, \
29-
.offset = offsetof(struct ftrace_regs, field), \
26+
#define FREGS_OFFSET(n, field) \
27+
{ \
28+
.name = n, \
29+
.offset = offsetof(struct __arch_ftrace_regs, field), \
3030
}
3131

3232
static const struct fregs_offset fregs_offsets[] = {
@@ -481,7 +481,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
481481
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
482482
struct ftrace_ops *op, struct ftrace_regs *fregs)
483483
{
484-
prepare_ftrace_return(ip, &fregs->lr, fregs->fp);
484+
prepare_ftrace_return(ip, &arch_ftrace_regs(fregs)->lr, arch_ftrace_regs(fregs)->fp);
485485
}
486486
#else
487487
/*

arch/loongarch/include/asm/ftrace.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,38 +43,40 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent);
4343

4444
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
4545
struct ftrace_ops;
46+
struct ftrace_regs;
47+
#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs))
4648

47-
struct ftrace_regs {
49+
struct __arch_ftrace_regs {
4850
struct pt_regs regs;
4951
};
5052

5153
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
5254
{
53-
return &fregs->regs;
55+
return &arch_ftrace_regs(fregs)->regs;
5456
}
5557

5658
static __always_inline unsigned long
5759
ftrace_regs_get_instruction_pointer(struct ftrace_regs *fregs)
5860
{
59-
return instruction_pointer(&fregs->regs);
61+
return instruction_pointer(&arch_ftrace_regs(fregs)->regs);
6062
}
6163

6264
static __always_inline void
6365
ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs, unsigned long ip)
6466
{
65-
instruction_pointer_set(&fregs->regs, ip);
67+
instruction_pointer_set(&arch_ftrace_regs(fregs)->regs, ip);
6668
}
6769

6870
#define ftrace_regs_get_argument(fregs, n) \
69-
regs_get_kernel_argument(&(fregs)->regs, n)
71+
regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)
7072
#define ftrace_regs_get_stack_pointer(fregs) \
71-
kernel_stack_pointer(&(fregs)->regs)
73+
kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)
7274
#define ftrace_regs_return_value(fregs) \
73-
regs_return_value(&(fregs)->regs)
75+
regs_return_value(&arch_ftrace_regs(fregs)->regs)
7476
#define ftrace_regs_set_return_value(fregs, ret) \
75-
regs_set_return_value(&(fregs)->regs, ret)
77+
regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)
7678
#define ftrace_override_function_with_return(fregs) \
77-
override_function_with_return(&(fregs)->regs)
79+
override_function_with_return(&arch_ftrace_regs(fregs)->regs)
7880
#define ftrace_regs_query_register_offset(name) \
7981
regs_query_register_offset(name)
8082

@@ -90,7 +92,7 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
9092
}
9193

9294
#define arch_ftrace_set_direct_caller(fregs, addr) \
93-
__arch_ftrace_set_direct_caller(&(fregs)->regs, addr)
95+
__arch_ftrace_set_direct_caller(&arch_ftrace_regs(fregs)->regs, addr)
9496
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
9597

9698
#endif

arch/loongarch/kernel/ftrace_dyn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent)
241241
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
242242
struct ftrace_ops *op, struct ftrace_regs *fregs)
243243
{
244-
struct pt_regs *regs = &fregs->regs;
244+
struct pt_regs *regs = &arch_ftrace_regs(fregs)->regs;
245245
unsigned long *parent = (unsigned long *)&regs->regs[1];
246246

247247
prepare_ftrace_return(ip, (unsigned long *)parent);

arch/powerpc/include/asm/ftrace.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,39 +32,42 @@ struct dyn_arch_ftrace {
3232
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
3333
#define ftrace_init_nop ftrace_init_nop
3434

35-
struct ftrace_regs {
35+
struct ftrace_regs;
36+
#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs))
37+
38+
struct __arch_ftrace_regs {
3639
struct pt_regs regs;
3740
};
3841

3942
static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
4043
{
4144
/* We clear regs.msr in ftrace_call */
42-
return fregs->regs.msr ? &fregs->regs : NULL;
45+
return arch_ftrace_regs(fregs)->regs.msr ? &arch_ftrace_regs(fregs)->regs : NULL;
4346
}
4447

4548
static __always_inline void
4649
ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
4750
unsigned long ip)
4851
{
49-
regs_set_return_ip(&fregs->regs, ip);
52+
regs_set_return_ip(&arch_ftrace_regs(fregs)->regs, ip);
5053
}
5154

5255
static __always_inline unsigned long
5356
ftrace_regs_get_instruction_pointer(struct ftrace_regs *fregs)
5457
{
55-
return instruction_pointer(&fregs->regs);
58+
return instruction_pointer(&arch_ftrace_regs(fregs)->regs);
5659
}
5760

5861
#define ftrace_regs_get_argument(fregs, n) \
59-
regs_get_kernel_argument(&(fregs)->regs, n)
62+
regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)
6063
#define ftrace_regs_get_stack_pointer(fregs) \
61-
kernel_stack_pointer(&(fregs)->regs)
64+
kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)
6265
#define ftrace_regs_return_value(fregs) \
63-
regs_return_value(&(fregs)->regs)
66+
regs_return_value(&arch_ftrace_regs(fregs)->regs)
6467
#define ftrace_regs_set_return_value(fregs, ret) \
65-
regs_set_return_value(&(fregs)->regs, ret)
68+
regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)
6669
#define ftrace_override_function_with_return(fregs) \
67-
override_function_with_return(&(fregs)->regs)
70+
override_function_with_return(&arch_ftrace_regs(fregs)->regs)
6871
#define ftrace_regs_query_register_offset(name) \
6972
regs_query_register_offset(name)
7073

arch/powerpc/kernel/trace/ftrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ int __init ftrace_dyn_arch_init(void)
421421
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
422422
struct ftrace_ops *op, struct ftrace_regs *fregs)
423423
{
424-
unsigned long sp = fregs->regs.gpr[1];
424+
unsigned long sp = arch_ftrace_regs(fregs)->regs.gpr[1];
425425
int bit;
426426

427427
if (unlikely(ftrace_graph_is_dead()))
@@ -439,6 +439,6 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
439439

440440
ftrace_test_recursion_unlock(bit);
441441
out:
442-
fregs->regs.link = parent_ip;
442+
arch_ftrace_regs(fregs)->regs.link = parent_ip;
443443
}
444444
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

arch/powerpc/kernel/trace/ftrace_64_pg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ __prepare_ftrace_return(unsigned long parent, unsigned long ip, unsigned long sp
829829
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
830830
struct ftrace_ops *op, struct ftrace_regs *fregs)
831831
{
832-
fregs->regs.link = __prepare_ftrace_return(parent_ip, ip, fregs->regs.gpr[1]);
832+
arch_ftrace_regs(fregs)->regs.link = __prepare_ftrace_return(parent_ip, ip, arch_ftrace_regs(fregs)->regs.gpr[1]);
833833
}
834834
#else
835835
unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,

arch/riscv/include/asm/ftrace.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
126126
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
127127
#define arch_ftrace_get_regs(regs) NULL
128128
struct ftrace_ops;
129-
struct ftrace_regs {
129+
struct ftrace_regs;
130+
#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs))
131+
132+
struct __arch_ftrace_regs {
130133
unsigned long epc;
131134
unsigned long ra;
132135
unsigned long sp;
@@ -150,42 +153,42 @@ struct ftrace_regs {
150153
static __always_inline unsigned long ftrace_regs_get_instruction_pointer(const struct ftrace_regs
151154
*fregs)
152155
{
153-
return fregs->epc;
156+
return arch_ftrace_regs(fregs)->epc;
154157
}
155158

156159
static __always_inline void ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
157160
unsigned long pc)
158161
{
159-
fregs->epc = pc;
162+
arch_ftrace_regs(fregs)->epc = pc;
160163
}
161164

162165
static __always_inline unsigned long ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs)
163166
{
164-
return fregs->sp;
167+
return arch_ftrace_regs(fregs)->sp;
165168
}
166169

167170
static __always_inline unsigned long ftrace_regs_get_argument(struct ftrace_regs *fregs,
168171
unsigned int n)
169172
{
170173
if (n < 8)
171-
return fregs->args[n];
174+
return arch_ftrace_regs(fregs)->args[n];
172175
return 0;
173176
}
174177

175178
static __always_inline unsigned long ftrace_regs_get_return_value(const struct ftrace_regs *fregs)
176179
{
177-
return fregs->a0;
180+
return arch_ftrace_regs(fregs)->a0;
178181
}
179182

180183
static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,
181184
unsigned long ret)
182185
{
183-
fregs->a0 = ret;
186+
arch_ftrace_regs(fregs)->a0 = ret;
184187
}
185188

186189
static __always_inline void ftrace_override_function_with_return(struct ftrace_regs *fregs)
187190
{
188-
fregs->epc = fregs->ra;
191+
arch_ftrace_regs(fregs)->epc = arch_ftrace_regs(fregs)->ra;
189192
}
190193

191194
int ftrace_regs_query_register_offset(const char *name);
@@ -196,7 +199,7 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
196199

197200
static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsigned long addr)
198201
{
199-
fregs->t1 = addr;
202+
arch_ftrace_regs(fregs)->t1 = addr;
200203
}
201204
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
202205

arch/riscv/kernel/asm-offsets.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -498,19 +498,19 @@ void asm_offsets(void)
498498
OFFSET(STACKFRAME_RA, stackframe, ra);
499499

500500
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
501-
DEFINE(FREGS_SIZE_ON_STACK, ALIGN(sizeof(struct ftrace_regs), STACK_ALIGN));
502-
DEFINE(FREGS_EPC, offsetof(struct ftrace_regs, epc));
503-
DEFINE(FREGS_RA, offsetof(struct ftrace_regs, ra));
504-
DEFINE(FREGS_SP, offsetof(struct ftrace_regs, sp));
505-
DEFINE(FREGS_S0, offsetof(struct ftrace_regs, s0));
506-
DEFINE(FREGS_T1, offsetof(struct ftrace_regs, t1));
507-
DEFINE(FREGS_A0, offsetof(struct ftrace_regs, a0));
508-
DEFINE(FREGS_A1, offsetof(struct ftrace_regs, a1));
509-
DEFINE(FREGS_A2, offsetof(struct ftrace_regs, a2));
510-
DEFINE(FREGS_A3, offsetof(struct ftrace_regs, a3));
511-
DEFINE(FREGS_A4, offsetof(struct ftrace_regs, a4));
512-
DEFINE(FREGS_A5, offsetof(struct ftrace_regs, a5));
513-
DEFINE(FREGS_A6, offsetof(struct ftrace_regs, a6));
514-
DEFINE(FREGS_A7, offsetof(struct ftrace_regs, a7));
501+
DEFINE(FREGS_SIZE_ON_STACK, ALIGN(sizeof(struct __arch_ftrace_regs), STACK_ALIGN));
502+
DEFINE(FREGS_EPC, offsetof(struct __arch_ftrace_regs, epc));
503+
DEFINE(FREGS_RA, offsetof(struct __arch_ftrace_regs, ra));
504+
DEFINE(FREGS_SP, offsetof(struct __arch_ftrace_regs, sp));
505+
DEFINE(FREGS_S0, offsetof(struct __arch_ftrace_regs, s0));
506+
DEFINE(FREGS_T1, offsetof(struct __arch_ftrace_regs, t1));
507+
DEFINE(FREGS_A0, offsetof(struct __arch_ftrace_regs, a0));
508+
DEFINE(FREGS_A1, offsetof(struct __arch_ftrace_regs, a1));
509+
DEFINE(FREGS_A2, offsetof(struct __arch_ftrace_regs, a2));
510+
DEFINE(FREGS_A3, offsetof(struct __arch_ftrace_regs, a3));
511+
DEFINE(FREGS_A4, offsetof(struct __arch_ftrace_regs, a4));
512+
DEFINE(FREGS_A5, offsetof(struct __arch_ftrace_regs, a5));
513+
DEFINE(FREGS_A6, offsetof(struct __arch_ftrace_regs, a6));
514+
DEFINE(FREGS_A7, offsetof(struct __arch_ftrace_regs, a7));
515515
#endif
516516
}

0 commit comments

Comments
 (0)