Skip to content

Commit 62de1d4

Browse files
author
Fox Snowpatch
committedDec 3, 2024·
1 parent 1ecdccb commit 62de1d4

File tree

6 files changed

+55
-18
lines changed

6 files changed

+55
-18
lines changed
 

‎arch/powerpc/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ config PPC
282282
select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0)
283283
select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0)
284284
select HAVE_STATIC_CALL if PPC32
285+
select HAVE_STATIC_CALL_INLINE if PPC32
285286
select HAVE_SYSCALL_TRACEPOINTS
286287
select HAVE_VIRT_CPU_ACCOUNTING
287288
select HAVE_VIRT_CPU_ACCOUNTING_GEN

‎arch/powerpc/include/asm/static_call.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@
2626
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) __PPC_SCT(name, "blr")
2727
#define ARCH_DEFINE_STATIC_CALL_RET0_TRAMP(name) __PPC_SCT(name, "b .+20")
2828

29+
#define CALL_INSN_SIZE 4
30+
2931
#endif /* _ASM_POWERPC_STATIC_CALL_H */

‎arch/powerpc/kernel/static_call.c

+43-15
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,54 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
88
{
99
int err;
1010
bool is_ret0 = (func == __static_call_return0);
11-
unsigned long target = (unsigned long)(is_ret0 ? tramp + PPC_SCT_RET0 : func);
12-
bool is_short = is_offset_in_branch_range((long)target - (long)tramp);
13-
14-
if (!tramp)
15-
return;
11+
unsigned long _tramp = (unsigned long)tramp;
12+
unsigned long _func = (unsigned long)func;
13+
unsigned long _ret0 = _tramp + PPC_SCT_RET0;
14+
bool is_short = is_offset_in_branch_range((long)func - (long)(site ? : tramp));
1615

1716
mutex_lock(&text_mutex);
1817

19-
if (func && !is_short) {
20-
err = patch_ulong(tramp + PPC_SCT_DATA, target);
21-
if (err)
22-
goto out;
18+
if (site && tail) {
19+
if (!func)
20+
err = patch_instruction(site, ppc_inst(PPC_RAW_BLR()));
21+
else if (is_ret0)
22+
err = patch_branch(site, _ret0, 0);
23+
else if (is_short)
24+
err = patch_branch(site, _func, 0);
25+
else if (tramp)
26+
err = patch_branch(site, _tramp, 0);
27+
else
28+
err = 0;
29+
} else if (site) {
30+
if (!func)
31+
err = patch_instruction(site, ppc_inst(PPC_RAW_NOP()));
32+
else if (is_ret0)
33+
err = patch_instruction(site, ppc_inst(PPC_RAW_LI(_R3, 0)));
34+
else if (is_short)
35+
err = patch_branch(site, _func, BRANCH_SET_LINK);
36+
else if (tramp)
37+
err = patch_branch(site, _tramp, BRANCH_SET_LINK);
38+
else
39+
err = 0;
40+
} else if (tramp) {
41+
if (func && !is_short) {
42+
err = patch_ulong(tramp + PPC_SCT_DATA, _func);
43+
if (err)
44+
goto out;
45+
}
46+
47+
if (!func)
48+
err = patch_instruction(tramp, ppc_inst(PPC_RAW_BLR()));
49+
else if (is_ret0)
50+
err = patch_branch(tramp, _ret0, 0);
51+
else if (is_short)
52+
err = patch_branch(tramp, _func, 0);
53+
else
54+
err = patch_instruction(tramp, ppc_inst(PPC_RAW_NOP()));
55+
} else {
56+
err = 0;
2357
}
2458

25-
if (!func)
26-
err = patch_instruction(tramp, ppc_inst(PPC_RAW_BLR()));
27-
else if (is_short)
28-
err = patch_branch(tramp, target, 0);
29-
else
30-
err = patch_instruction(tramp, ppc_inst(PPC_RAW_NOP()));
3159
out:
3260
mutex_unlock(&text_mutex);
3361

‎arch/x86/kernel/static_call.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
158158
{
159159
mutex_lock(&text_mutex);
160160

161-
if (tramp) {
161+
if (tramp && !site) {
162162
__static_call_validate(tramp, true, true);
163163
__static_call_transform(tramp, __sc_insn(!func, true), func, false);
164164
}

‎kernel/static_call_inline.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ void __static_call_update(struct static_call_key *key, void *tramp, void *func)
206206
continue;
207207
}
208208

209-
arch_static_call_transform(site_addr, NULL, func,
209+
arch_static_call_transform(site_addr, tramp, func,
210210
static_call_is_tail(site));
211211
}
212212
}

‎tools/objtool/arch/powerpc/decode.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,15 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
5555

5656
switch (opcode) {
5757
case 18: /* b[l][a] */
58-
if ((ins & 3) == 1) /* bl */
58+
if (ins & 1) /* bl[a] */
5959
typ = INSN_CALL;
60+
else /* b[a] */
61+
typ = INSN_JUMP_UNCONDITIONAL;
6062

6163
imm = ins & 0x3fffffc;
6264
if (imm & 0x2000000)
6365
imm -= 0x4000000;
66+
imm |= ins & 2; /* AA flag */
6467
break;
6568
}
6669

@@ -77,6 +80,9 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
7780

7881
unsigned long arch_jump_destination(struct instruction *insn)
7982
{
83+
if (insn->immediate & 2)
84+
return insn->immediate & ~2;
85+
8086
return insn->offset + insn->immediate;
8187
}
8288

0 commit comments

Comments
 (0)
Please sign in to comment.