Commit f02644e3 authored by Youling Tang's avatar Youling Tang Committed by Huacai Chen
Browse files

LoongArch: Add jump-label implementation



Add support for jump labels based on the ARM64 version.

Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarYouling Tang <tangyouling@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 5d553770
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -13,7 +13,7 @@
    |        csky: |  ok  |
    |        csky: |  ok  |
    |     hexagon: | TODO |
    |     hexagon: | TODO |
    |        ia64: | TODO |
    |        ia64: | TODO |
    |   loongarch: | TODO |
    |   loongarch: |  ok  |
    |        m68k: | TODO |
    |        m68k: | TODO |
    |  microblaze: | TODO |
    |  microblaze: | TODO |
    |        mips: |  ok  |
    |        mips: |  ok  |
+2 −0
Original line number Original line Diff line number Diff line
@@ -87,6 +87,8 @@ config LOONGARCH
	select GPIOLIB
	select GPIOLIB
	select HAS_IOPORT
	select HAS_IOPORT
	select HAVE_ARCH_AUDITSYSCALL
	select HAVE_ARCH_AUDITSYSCALL
	select HAVE_ARCH_JUMP_LABEL
	select HAVE_ARCH_JUMP_LABEL_RELATIVE
	select HAVE_ARCH_MMAP_RND_BITS if MMU
	select HAVE_ARCH_MMAP_RND_BITS if MMU
	select HAVE_ARCH_SECCOMP_FILTER
	select HAVE_ARCH_SECCOMP_FILTER
	select HAVE_ARCH_TRACEHOOK
	select HAVE_ARCH_TRACEHOOK
+50 −0
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2023 Loongson Technology Corporation Limited
 *
 * Based on arch/arm64/include/asm/jump_label.h
 */
#ifndef __ASM_JUMP_LABEL_H
#define __ASM_JUMP_LABEL_H

#ifndef __ASSEMBLY__

#include <linux/types.h>

#define JUMP_LABEL_NOP_SIZE	4

#define JUMP_TABLE_ENTRY				\
	 ".pushsection	__jump_table, \"aw\"	\n\t"	\
	 ".align	3			\n\t"	\
	 ".long		1b - ., %l[l_yes] - .	\n\t"	\
	 ".quad		%0 - .			\n\t"	\
	 ".popsection				\n\t"

static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
{
	asm_volatile_goto(
		"1:	nop			\n\t"
		JUMP_TABLE_ENTRY
		:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;

l_yes:
	return true;
}

static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch)
{
	asm_volatile_goto(
		"1:	b	%l[l_yes]	\n\t"
		JUMP_TABLE_ENTRY
		:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;

l_yes:
	return true;
}

#endif  /* __ASSEMBLY__ */
#endif	/* __ASM_JUMP_LABEL_H */
+2 −0
Original line number Original line Diff line number Diff line
@@ -54,4 +54,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o


obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes_trampoline.o
obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes_trampoline.o


obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o

CPPFLAGS_vmlinux.lds		:= $(KBUILD_CFLAGS)
CPPFLAGS_vmlinux.lds		:= $(KBUILD_CFLAGS)
+22 −0
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2023 Loongson Technology Corporation Limited
 *
 * Based on arch/arm64/kernel/jump_label.c
 */
#include <linux/kernel.h>
#include <linux/jump_label.h>
#include <asm/inst.h>

void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type)
{
	u32 insn;
	void *addr = (void *)jump_entry_code(entry);

	if (type == JUMP_LABEL_JMP)
		insn = larch_insn_gen_b(jump_entry_code(entry), jump_entry_target(entry));
	else
		insn = larch_insn_gen_nop();

	larch_insn_patch_text(addr, insn);
}