Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

LoongArch: Add jump-label implementation

Add support for jump labels based on the ARM64 version.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Youling Tang <tangyouling@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

authored by

Youling Tang and committed by
Huacai Chen
f02644e3 5d553770

+77 -1
+1 -1
Documentation/features/core/jump-labels/arch-support.txt
··· 13 13 | csky: | ok | 14 14 | hexagon: | TODO | 15 15 | ia64: | TODO | 16 - | loongarch: | TODO | 16 + | loongarch: | ok | 17 17 | m68k: | TODO | 18 18 | microblaze: | TODO | 19 19 | mips: | ok |
+2
arch/loongarch/Kconfig
··· 87 87 select GPIOLIB 88 88 select HAS_IOPORT 89 89 select HAVE_ARCH_AUDITSYSCALL 90 + select HAVE_ARCH_JUMP_LABEL 91 + select HAVE_ARCH_JUMP_LABEL_RELATIVE 90 92 select HAVE_ARCH_MMAP_RND_BITS if MMU 91 93 select HAVE_ARCH_SECCOMP_FILTER 92 94 select HAVE_ARCH_TRACEHOOK
+50
arch/loongarch/include/asm/jump_label.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (C) 2023 Loongson Technology Corporation Limited 4 + * 5 + * Based on arch/arm64/include/asm/jump_label.h 6 + */ 7 + #ifndef __ASM_JUMP_LABEL_H 8 + #define __ASM_JUMP_LABEL_H 9 + 10 + #ifndef __ASSEMBLY__ 11 + 12 + #include <linux/types.h> 13 + 14 + #define JUMP_LABEL_NOP_SIZE 4 15 + 16 + #define JUMP_TABLE_ENTRY \ 17 + ".pushsection __jump_table, \"aw\" \n\t" \ 18 + ".align 3 \n\t" \ 19 + ".long 1b - ., %l[l_yes] - . \n\t" \ 20 + ".quad %0 - . \n\t" \ 21 + ".popsection \n\t" 22 + 23 + static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) 24 + { 25 + asm_volatile_goto( 26 + "1: nop \n\t" 27 + JUMP_TABLE_ENTRY 28 + : : "i"(&((char *)key)[branch]) : : l_yes); 29 + 30 + return false; 31 + 32 + l_yes: 33 + return true; 34 + } 35 + 36 + static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) 37 + { 38 + asm_volatile_goto( 39 + "1: b %l[l_yes] \n\t" 40 + JUMP_TABLE_ENTRY 41 + : : "i"(&((char *)key)[branch]) : : l_yes); 42 + 43 + return false; 44 + 45 + l_yes: 46 + return true; 47 + } 48 + 49 + #endif /* __ASSEMBLY__ */ 50 + #endif /* __ASM_JUMP_LABEL_H */
+2
arch/loongarch/kernel/Makefile
··· 54 54 55 55 obj-$(CONFIG_KPROBES) += kprobes.o kprobes_trampoline.o 56 56 57 + obj-$(CONFIG_JUMP_LABEL) += jump_label.o 58 + 57 59 CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
+22
arch/loongarch/kernel/jump_label.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2023 Loongson Technology Corporation Limited 4 + * 5 + * Based on arch/arm64/kernel/jump_label.c 6 + */ 7 + #include <linux/kernel.h> 8 + #include <linux/jump_label.h> 9 + #include <asm/inst.h> 10 + 11 + void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type) 12 + { 13 + u32 insn; 14 + void *addr = (void *)jump_entry_code(entry); 15 + 16 + if (type == JUMP_LABEL_JMP) 17 + insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry)); 18 + else 19 + insn = larch_insn_gen_nop(); 20 + 21 + larch_insn_patch_text(addr, insn); 22 + }