[RFC PATCH 22/25] kvx: Add support for jump labels

Yann Sionneau posted 25 patches 2 years, 8 months ago
There is a newer version of this series
[RFC PATCH 22/25] kvx: Add support for jump labels
Posted by Yann Sionneau 2 years, 8 months ago
Add support for jump labels to kvx arch.

CC: Peter Zijlstra <peterz@infradead.org>
CC: Josh Poimboeuf <jpoimboe@kernel.org>
CC: Jason Baron <jbaron@akamai.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Ard Biesheuvel <ardb@kernel.org>
CC: linux-kernel@vger.kernel.org
Co-developed-by: Clement Leger <clement.leger@bootlin.com>
Signed-off-by: Clement Leger <clement.leger@bootlin.com>
Co-developed-by: Julian Vetter <jvetter@kalray.eu>
Signed-off-by: Julian Vetter <jvetter@kalray.eu>
Co-developed-by: Yann Sionneau <ysionneau@kalray.eu>
Signed-off-by: Yann Sionneau <ysionneau@kalray.eu>
---
 arch/kvx/include/asm/jump_label.h | 59 +++++++++++++++++++++++++++++++
 arch/kvx/kernel/jump_label.c      | 34 ++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100644 arch/kvx/include/asm/jump_label.h
 create mode 100644 arch/kvx/kernel/jump_label.c

diff --git a/arch/kvx/include/asm/jump_label.h b/arch/kvx/include/asm/jump_label.h
new file mode 100644
index 000000000000..5becccaad20c
--- /dev/null
+++ b/arch/kvx/include/asm/jump_label.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017-2023 Kalray Inc.
+ * Author(s): Clement Leger
+ */
+
+#ifndef _ASM_KVX_JUMP_LABEL_H
+#define _ASM_KVX_JUMP_LABEL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+#include <asm/insns_defs.h>
+
+#define JUMP_LABEL_NOP_SIZE (KVX_INSN_NOP_SIZE * KVX_INSN_SYLLABLE_WIDTH)
+
+static __always_inline bool arch_static_branch(struct static_key *key,
+					       bool branch)
+{
+	asm_volatile_goto("1:\n\t"
+			  "nop\n\t"
+			  ";;\n\t"
+			  ".pushsection __jump_table, \"aw\"\n\t"
+			  ".dword 1b, %l[l_yes], %c0\n\t"
+			  ".popsection\n\t"
+			  : :  "i" (&((char *)key)[branch]) :  : l_yes);
+
+	return false;
+l_yes:
+	return true;
+}
+
+static __always_inline bool arch_static_branch_jump(struct static_key *key,
+						    bool branch)
+{
+	asm_volatile_goto("1:\n\t"
+			  "goto %l[l_yes]\n\t"
+			  ";;\n\t"
+			  ".pushsection __jump_table, \"aw\"\n\t"
+			  ".dword 1b, %l[l_yes], %c0\n\t"
+			  ".popsection\n\t"
+			  : :  "i" (&((char *)key)[branch]) :  : l_yes);
+
+	return false;
+l_yes:
+	return true;
+}
+
+typedef u64 jump_label_t;
+
+struct jump_entry {
+	jump_label_t code;
+	jump_label_t target;
+	jump_label_t key;
+};
+
+#endif  /* __ASSEMBLY__ */
+#endif
diff --git a/arch/kvx/kernel/jump_label.c b/arch/kvx/kernel/jump_label.c
new file mode 100644
index 000000000000..5a602dbdede0
--- /dev/null
+++ b/arch/kvx/kernel/jump_label.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017-2023 Kalray Inc.
+ * Author(s): Clement Leger
+ */
+
+#include <linux/cpu.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/stop_machine.h>
+#include <linux/types.h>
+
+#include <asm/cacheflush.h>
+#include <asm/insns.h>
+#include <asm/insns_defs.h>
+
+void arch_jump_label_transform(struct jump_entry *e,
+			       enum jump_label_type type)
+{
+	s32 off = (jump_entry_target(e) - jump_entry_code(e));
+	u32 insn_code;
+	u32 *insn_addr = (u32 *) jump_entry_code(e);
+
+	if (type == JUMP_LABEL_JMP) {
+		BUG_ON(KVX_INSN_GOTO_PCREL27_CHECK(off));
+
+		KVX_INSN_GOTO(&insn_code, KVX_INSN_PARALLEL_EOB, off);
+	} else {
+		KVX_INSN_NOP(&insn_code, KVX_INSN_PARALLEL_EOB);
+	}
+
+	kvx_insns_write(&insn_code, JUMP_LABEL_NOP_SIZE, insn_addr);
+}
-- 
2.37.2