Skip to content

Commit 4e8bb4b

Browse files
committed
csky: Add jump-label implementation
Add jump-label implementation for static branch Signed-off-by: Guo Ren <[email protected]> Signed-off-by: Guo Ren <[email protected]>
1 parent 01ab464 commit 4e8bb4b

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

arch/csky/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ config CSKY
4040
select GX6605S_TIMER if CPU_CK610
4141
select HAVE_ARCH_TRACEHOOK
4242
select HAVE_ARCH_AUDITSYSCALL
43+
select HAVE_ARCH_JUMP_LABEL if !CPU_CK610
44+
select HAVE_ARCH_JUMP_LABEL_RELATIVE
4345
select HAVE_ARCH_MMAP_RND_BITS
4446
select HAVE_ARCH_SECCOMP_FILTER
4547
select HAVE_CONTEXT_TRACKING

arch/csky/include/asm/jump_label.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+
#ifndef __ASM_CSKY_JUMP_LABEL_H
4+
#define __ASM_CSKY_JUMP_LABEL_H
5+
6+
#ifndef __ASSEMBLY__
7+
8+
#include <linux/types.h>
9+
10+
#define JUMP_LABEL_NOP_SIZE 4
11+
12+
static __always_inline bool arch_static_branch(struct static_key *key,
13+
bool branch)
14+
{
15+
asm_volatile_goto(
16+
"1: nop32 \n"
17+
" .pushsection __jump_table, \"aw\" \n"
18+
" .align 2 \n"
19+
" .long 1b - ., %l[label] - . \n"
20+
" .long %0 - . \n"
21+
" .popsection \n"
22+
: : "i"(&((char *)key)[branch]) : : label);
23+
24+
return false;
25+
label:
26+
return true;
27+
}
28+
29+
static __always_inline bool arch_static_branch_jump(struct static_key *key,
30+
bool branch)
31+
{
32+
asm_volatile_goto(
33+
"1: bsr32 %l[label] \n"
34+
" .pushsection __jump_table, \"aw\" \n"
35+
" .align 2 \n"
36+
" .long 1b - ., %l[label] - . \n"
37+
" .long %0 - . \n"
38+
" .popsection \n"
39+
: : "i"(&((char *)key)[branch]) : : label);
40+
41+
return false;
42+
label:
43+
return true;
44+
}
45+
46+
#endif /* __ASSEMBLY__ */
47+
#endif /* __ASM_CSKY_JUMP_LABEL_H */

arch/csky/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o
1313
obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o
1414
obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o
1515
obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o
16+
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
1617

1718
ifdef CONFIG_FUNCTION_TRACER
1819
CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)

arch/csky/kernel/jump_label.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include <linux/jump_label.h>
4+
#include <linux/kernel.h>
5+
#include <linux/memory.h>
6+
#include <linux/mutex.h>
7+
#include <linux/uaccess.h>
8+
#include <asm/cacheflush.h>
9+
10+
#define NOP32_HI 0xc400
11+
#define NOP32_LO 0x4820
12+
#define BSR_LINK 0xe000
13+
14+
void arch_jump_label_transform(struct jump_entry *entry,
15+
enum jump_label_type type)
16+
{
17+
unsigned long addr = jump_entry_code(entry);
18+
u16 insn[2];
19+
int ret = 0;
20+
21+
if (type == JUMP_LABEL_JMP) {
22+
long offset = jump_entry_target(entry) - jump_entry_code(entry);
23+
24+
if (WARN_ON(offset & 1 || offset < -67108864 || offset >= 67108864))
25+
return;
26+
27+
offset = offset >> 1;
28+
29+
insn[0] = BSR_LINK |
30+
((uint16_t)((unsigned long) offset >> 16) & 0x3ff);
31+
insn[1] = (uint16_t)((unsigned long) offset & 0xffff);
32+
} else {
33+
insn[0] = NOP32_HI;
34+
insn[1] = NOP32_LO;
35+
}
36+
37+
ret = copy_to_kernel_nofault((void *)addr, insn, 4);
38+
WARN_ON(ret);
39+
40+
flush_icache_range(addr, addr + 4);
41+
}
42+
43+
void arch_jump_label_transform_static(struct jump_entry *entry,
44+
enum jump_label_type type)
45+
{
46+
/*
47+
* We use the same instructions in the arch_static_branch and
48+
* arch_static_branch_jump inline functions, so there's no
49+
* need to patch them up here.
50+
* The core will call arch_jump_label_transform when those
51+
* instructions need to be replaced.
52+
*/
53+
arch_jump_label_transform(entry, type);
54+
}

0 commit comments

Comments
 (0)