Skip to content

Commit 7c95d88

Browse files
iamjpnmpe
authored andcommitted
powerpc: Change calling convention for create_branch() et. al.
create_branch(), create_cond_branch() and translate_branch() return the instruction that they create, or return 0 to signal an error. Separate these concerns in preparation for an instruction type that is not just an unsigned int. Fill the created instruction to a pointer passed as the first parameter to the function and use a non-zero return value to signify an error. Signed-off-by: Jordan Niethe <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Reviewed-by: Alistair Popple <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5a7fdca commit 7c95d88

File tree

6 files changed

+119
-84
lines changed

6 files changed

+119
-84
lines changed

arch/powerpc/include/asm/code-patching.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
#define BRANCH_ABSOLUTE 0x2
2323

2424
bool is_offset_in_branch_range(long offset);
25-
unsigned int create_branch(const unsigned int *addr,
26-
unsigned long target, int flags);
27-
unsigned int create_cond_branch(const unsigned int *addr,
28-
unsigned long target, int flags);
25+
int create_branch(unsigned int *instr, const unsigned int *addr,
26+
unsigned long target, int flags);
27+
int create_cond_branch(unsigned int *instr, const unsigned int *addr,
28+
unsigned long target, int flags);
2929
int patch_branch(unsigned int *addr, unsigned long target, int flags);
3030
int patch_instruction(unsigned int *addr, unsigned int instr);
3131
int raw_patch_instruction(unsigned int *addr, unsigned int instr);
@@ -60,8 +60,8 @@ int instr_is_relative_branch(unsigned int instr);
6060
int instr_is_relative_link_branch(unsigned int instr);
6161
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
6262
unsigned long branch_target(const unsigned int *instr);
63-
unsigned int translate_branch(const unsigned int *dest,
64-
const unsigned int *src);
63+
int translate_branch(unsigned int *instr, const unsigned int *dest,
64+
const unsigned int *src);
6565
extern bool is_conditional_branch(unsigned int instr);
6666
#ifdef CONFIG_PPC_BOOK3E_64
6767
void __patch_exception(int exc, unsigned long addr);

arch/powerpc/kernel/optprobes.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,17 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p)
251251
goto error;
252252
}
253253

254-
branch_op_callback = create_branch((unsigned int *)buff + TMPL_CALL_HDLR_IDX,
255-
(unsigned long)op_callback_addr,
256-
BRANCH_SET_LINK);
254+
rc = create_branch(&branch_op_callback,
255+
(unsigned int *)buff + TMPL_CALL_HDLR_IDX,
256+
(unsigned long)op_callback_addr,
257+
BRANCH_SET_LINK);
257258

258-
branch_emulate_step = create_branch((unsigned int *)buff + TMPL_EMULATE_IDX,
259-
(unsigned long)emulate_step_addr,
260-
BRANCH_SET_LINK);
259+
rc |= create_branch(&branch_emulate_step,
260+
(unsigned int *)buff + TMPL_EMULATE_IDX,
261+
(unsigned long)emulate_step_addr,
262+
BRANCH_SET_LINK);
261263

262-
if (!branch_op_callback || !branch_emulate_step)
264+
if (rc)
263265
goto error;
264266

265267
patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback);
@@ -305,6 +307,7 @@ int arch_check_optimized_kprobe(struct optimized_kprobe *op)
305307

306308
void arch_optimize_kprobes(struct list_head *oplist)
307309
{
310+
unsigned int instr;
308311
struct optimized_kprobe *op;
309312
struct optimized_kprobe *tmp;
310313

@@ -315,9 +318,10 @@ void arch_optimize_kprobes(struct list_head *oplist)
315318
*/
316319
memcpy(op->optinsn.copied_insn, op->kp.addr,
317320
RELATIVEJUMP_SIZE);
318-
patch_instruction(op->kp.addr,
319-
create_branch((unsigned int *)op->kp.addr,
320-
(unsigned long)op->optinsn.insn, 0));
321+
create_branch(&instr,
322+
(unsigned int *)op->kp.addr,
323+
(unsigned long)op->optinsn.insn, 0);
324+
patch_instruction(op->kp.addr, instr);
321325
list_del_init(&op->list);
322326
}
323327
}

arch/powerpc/kernel/setup_32.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(DMA_MODE_WRITE);
7575
notrace void __init machine_init(u64 dt_ptr)
7676
{
7777
unsigned int *addr = (unsigned int *)patch_site_addr(&patch__memset_nocache);
78-
unsigned long insn;
78+
unsigned int insn;
7979

8080
/* Configure static keys first, now that we're relocated. */
8181
setup_feature_keys();
@@ -87,7 +87,7 @@ notrace void __init machine_init(u64 dt_ptr)
8787

8888
patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP);
8989

90-
insn = create_cond_branch(addr, branch_target(addr), 0x820000);
90+
create_cond_branch(&insn, addr, branch_target(addr), 0x820000);
9191
patch_instruction(addr, insn); /* replace b by bne cr0 */
9292

9393
/* Do some early initialization based on the flat device tree */

arch/powerpc/kernel/trace/ftrace.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
4848
addr = ppc_function_entry((void *)addr);
4949

5050
/* if (link) set op to 'bl' else 'b' */
51-
op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
51+
create_branch(&op, (unsigned int *)ip, addr, link ? 1 : 0);
5252

5353
return op;
5454
}
@@ -89,10 +89,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
8989
*/
9090
static int test_24bit_addr(unsigned long ip, unsigned long addr)
9191
{
92+
unsigned int op;
9293
addr = ppc_function_entry((void *)addr);
9394

9495
/* use the create_branch to verify that this offset can be branched */
95-
return create_branch((unsigned int *)ip, addr, 0);
96+
return create_branch(&op, (unsigned int *)ip, addr, 0) == 0;
9697
}
9798

9899
static int is_bl_op(unsigned int op)
@@ -287,6 +288,7 @@ __ftrace_make_nop(struct module *mod,
287288
static unsigned long find_ftrace_tramp(unsigned long ip)
288289
{
289290
int i;
291+
unsigned int instr;
290292

291293
/*
292294
* We have the compiler generated long_branch tramps at the end
@@ -295,7 +297,8 @@ static unsigned long find_ftrace_tramp(unsigned long ip)
295297
for (i = NUM_FTRACE_TRAMPS - 1; i >= 0; i--)
296298
if (!ftrace_tramps[i])
297299
continue;
298-
else if (create_branch((void *)ip, ftrace_tramps[i], 0))
300+
else if (create_branch(&instr, (void *)ip,
301+
ftrace_tramps[i], 0) == 0)
299302
return ftrace_tramps[i];
300303

301304
return 0;
@@ -324,6 +327,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
324327
{
325328
int i, op;
326329
unsigned long ptr;
330+
unsigned int instr;
327331
static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS];
328332

329333
/* Is this a known long jump tramp? */
@@ -366,7 +370,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp)
366370
#else
367371
ptr = ppc_global_function_entry((void *)ftrace_caller);
368372
#endif
369-
if (!create_branch((void *)tramp, ptr, 0)) {
373+
if (create_branch(&instr, (void *)tramp, ptr, 0)) {
370374
pr_debug("%ps is not reachable from existing mcount tramp\n",
371375
(void *)ptr);
372376
return -1;
@@ -511,6 +515,7 @@ static int
511515
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
512516
{
513517
unsigned int op[2];
518+
unsigned int instr;
514519
void *ip = (void *)rec->ip;
515520
unsigned long entry, ptr, tramp;
516521
struct module *mod = rec->arch.mod;
@@ -557,7 +562,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
557562
}
558563

559564
/* Ensure branch is within 24 bits */
560-
if (!create_branch(ip, tramp, BRANCH_SET_LINK)) {
565+
if (create_branch(&instr, ip, tramp, BRANCH_SET_LINK)) {
561566
pr_err("Branch out of range\n");
562567
return -EINVAL;
563568
}
@@ -574,6 +579,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
574579
static int
575580
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
576581
{
582+
int err;
577583
unsigned int op;
578584
unsigned long ip = rec->ip;
579585

@@ -594,9 +600,9 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
594600
}
595601

596602
/* create the branch to the trampoline */
597-
op = create_branch((unsigned int *)ip,
598-
rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
599-
if (!op) {
603+
err = create_branch(&op, (unsigned int *)ip,
604+
rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
605+
if (err) {
600606
pr_err("REL24 out of range!\n");
601607
return -EINVAL;
602608
}
@@ -776,7 +782,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
776782
}
777783

778784
/* Ensure branch is within 24 bits */
779-
if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
785+
if (create_branch(&op, (unsigned int *)ip, tramp, BRANCH_SET_LINK)) {
780786
pr_err("Branch out of range\n");
781787
return -EINVAL;
782788
}

0 commit comments

Comments
 (0)