Skip to content

Commit 0029ff8

Browse files
Steven RostedtIngo Molnar
authored andcommitted
powerpc: ftrace, use create_branch
Impact: clean up Paul Mackerras pointed out that the code to determine if the branch can reach the destination is incorrect. Michael Ellerman suggested to pull out the code from create_branch and use that. Simply using create_branch is probably the best. Reported-by: Michael Ellerman <[email protected]> Reported-by: Paul Mackerras <[email protected]> Signed-off-by: Steven Rostedt <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent ec682ce commit 0029ff8

File tree

1 file changed

+12
-42
lines changed

1 file changed

+12
-42
lines changed

arch/powerpc/kernel/ftrace.c

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -114,31 +114,16 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
114114
*/
115115
static int test_24bit_addr(unsigned long ip, unsigned long addr)
116116
{
117-
long diff;
118117

119-
/*
120-
* Can we get to addr from ip in 24 bits?
121-
* (26 really, since we mulitply by 4 for 4 byte alignment)
122-
*/
123-
diff = addr - ip;
124-
125-
/*
126-
* Return true if diff is less than 1 << 25
127-
* and greater than -1 << 26.
128-
*/
129-
return (diff < (1 << 25)) && (diff > (-1 << 26));
118+
/* use the create_branch to verify that this offset can be branched */
119+
return create_branch((unsigned int *)ip, addr, 0);
130120
}
131121

132122
static int is_bl_op(unsigned int op)
133123
{
134124
return (op & 0xfc000003) == 0x48000001;
135125
}
136126

137-
static int test_offset(unsigned long offset)
138-
{
139-
return (offset + 0x2000000 > 0x3ffffff) || ((offset & 3) != 0);
140-
}
141-
142127
static unsigned long find_bl_target(unsigned long ip, unsigned int op)
143128
{
144129
static int offset;
@@ -151,12 +136,6 @@ static unsigned long find_bl_target(unsigned long ip, unsigned int op)
151136
return ip + (long)offset;
152137
}
153138

154-
static unsigned int branch_offset(unsigned long offset)
155-
{
156-
/* return "bl ip+offset" */
157-
return 0x48000001 | (offset & 0x03fffffc);
158-
}
159-
160139
#ifdef CONFIG_PPC64
161140
static int
162141
__ftrace_make_nop(struct module *mod,
@@ -402,7 +381,6 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
402381
{
403382
unsigned int op[2];
404383
unsigned long ip = rec->ip;
405-
unsigned long offset;
406384

407385
/* read where this goes */
408386
if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2))
@@ -424,17 +402,14 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
424402
return -EINVAL;
425403
}
426404

427-
/* now calculate a jump to the ftrace caller trampoline */
428-
offset = rec->arch.mod->arch.tramp - ip;
429-
430-
if (test_offset(offset)) {
431-
printk(KERN_ERR "REL24 %li out of range!\n",
432-
(long int)offset);
405+
/* create the branch to the trampoline */
406+
op[0] = create_branch((unsigned int *)ip,
407+
rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
408+
if (!op[0]) {
409+
printk(KERN_ERR "REL24 out of range!\n");
433410
return -EINVAL;
434411
}
435412

436-
/* Set to "bl addr" */
437-
op[0] = branch_offset(offset);
438413
/* ld r2,40(r1) */
439414
op[1] = 0xe8410028;
440415

@@ -453,7 +428,6 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
453428
{
454429
unsigned int op;
455430
unsigned long ip = rec->ip;
456-
unsigned long offset;
457431

458432
/* read where this goes */
459433
if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
@@ -471,18 +445,14 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
471445
return -EINVAL;
472446
}
473447

474-
/* now calculate a jump to the ftrace caller trampoline */
475-
offset = rec->arch.mod->arch.tramp - ip;
476-
477-
if (test_offset(offset)) {
478-
printk(KERN_ERR "REL24 %li out of range!\n",
479-
(long int)offset);
448+
/* create the branch to the trampoline */
449+
op = create_branch((unsigned int *)ip,
450+
rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
451+
if (!op) {
452+
printk(KERN_ERR "REL24 out of range!\n");
480453
return -EINVAL;
481454
}
482455

483-
/* Set to "bl addr" */
484-
op = branch_offset(offset);
485-
486456
DEBUGP("write to %lx\n", rec->ip);
487457

488458
if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))

0 commit comments

Comments
 (0)