From: Magnus Lindholm <linmag7@gmail.com>
To: richard.henderson@linaro.org, mattst88@gmail.com,
linux-kernel@vger.kernel.org, linux-alpha@vger.kernel.org
Cc: linmag7@gmail.com
Subject: [PATCH v3] alpha: Add support for HAVE_ARCH_JUMP_LABEL
Date: Sat, 14 Nov 2026 10:48:19 +0100 [thread overview]
Message-ID: <20261114094826.1282965-2-linmag7@gmail.com> (raw)
In-Reply-To: <20261114094826.1282965-1-linmag7@gmail.com>
Implement static key (jump label) support for Alpha. Emit jump table
entries and patch instruction sites between NOP and BR, synchronizing
instruction caches after each update.
Warn and leave the instruction unchanged if the target is outside the
signed 21-bit branch displacement range.
This relies on kernel and module text being writable; Alpha does not
implement STRICT_KERNEL_RWX or STRICT_MODULE_RWX.
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
---
.../core/jump-labels/arch-support.txt | 2 +-
arch/alpha/Kconfig | 1 +
arch/alpha/include/asm/jump_label.h | 65 +++++++++++++++
arch/alpha/kernel/Makefile | 2 +
arch/alpha/kernel/jump_label.c | 79 +++++++++++++++++++
5 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 arch/alpha/include/asm/jump_label.h
create mode 100644 arch/alpha/kernel/jump_label.c
diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt
index 683de7c15058..119c71b7cec0 100644
--- a/Documentation/features/core/jump-labels/arch-support.txt
+++ b/Documentation/features/core/jump-labels/arch-support.txt
@@ -6,7 +6,7 @@
-----------------------
| arch |status|
-----------------------
- | alpha: | TODO |
+ | alpha: | ok |
| arc: | ok |
| arm: | ok |
| arm64: | ok |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 6ccb2d230326..e7e7cb37d670 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -28,6 +28,7 @@ config ALPHA
select PCI_DOMAINS if PCI
select PCI_SYSCALL if PCI
select HAVE_ARCH_COMPILER_H
+ select HAVE_ARCH_JUMP_LABEL
select HAVE_ASM_MODVERSIONS
select HAVE_DEBUG_KMEMLEAK
select HAVE_GUP_FAST
diff --git a/arch/alpha/include/asm/jump_label.h b/arch/alpha/include/asm/jump_label.h
new file mode 100644
index 000000000000..df0b59530c85
--- /dev/null
+++ b/arch/alpha/include/asm/jump_label.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Alpha architecture jump label (static key) definitions
+ *
+ * Defines patch site emission and jump table layout for
+ * Alpha static key support.
+ *
+ * Copyright (C) 2026 Magnus Lindholm <linmag7@gmail.com>
+ */
+
+#ifndef _ASM_ALPHA_JUMP_LABEL_H
+#define _ASM_ALPHA_JUMP_LABEL_H
+
+#ifndef __ASSEMBLER__
+
+#include <linux/types.h>
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+typedef u64 jump_label_t;
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
+{
+ asm goto("1:\n\t"
+ "nop\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".align 3\n\t"
+ ".quad 1b, %l[l_yes], %0\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 goto("1:\n\t"
+ "br $31, %l[l_yes]\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ ".align 3\n\t"
+ ".quad 1b, %l[l_yes], %0\n\t"
+ ".popsection\n\t"
+ :
+ : "i"(&((char *)key)[branch])
+ :
+ : l_yes);
+
+ return false;
+l_yes:
+ return true;
+}
+
+#endif /* __ASSEMBLER__ */
+#endif /* _ASM_ALPHA_JUMP_LABEL_H */
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 850f1265cc55..4088cd56866e 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -92,3 +92,5 @@ obj-$(CONFIG_ALPHA_TITAN) += err_ev6.o err_titan.o
obj-$(CONFIG_ALPHA_TSUNAMI) += err_ev6.o err_tsunami.o
endif # GENERIC
+
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o
diff --git a/arch/alpha/kernel/jump_label.c b/arch/alpha/kernel/jump_label.c
new file mode 100644
index 000000000000..9168d5da978b
--- /dev/null
+++ b/arch/alpha/kernel/jump_label.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Alpha architecture jump label (static key) support
+ *
+ * Implements runtime patching of static key sites by replacing
+ * a NOP instruction with an unconditional branch and vice versa.
+ *
+ * Copyright (C) 2026 Magnus Lindholm <linmag7@gmail.com>
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Alpha instruction encoding helpers.
+ *
+ * Branch format:
+ * [31:26] opcode
+ * [25:21] Ra
+ * [20:0 ] disp (signed, in instructions; hardware multiplies by 4)
+ *
+ * Unconditional branch:
+ * BR opcode is 0x30. We use Ra=r31 so no link register is written.
+ *
+ * Updated PC semantics:
+ * Target = (pc + 4) + (disp << 2)
+ * so disp = (target - (pc + 4)) >> 2.
+ */
+#define ALPHA_OP_BR 0x30
+#define ALPHA_RA_R31 31
+#define ALPHA_BR_DISP_MASK ((1u << 21) - 1)
+
+#define ALPHA_INSN_NOP 0x47FF041Fu /* BIS r31,r31,r31 */
+
+static inline bool alpha_br_insn(unsigned long pc, unsigned long target,
+ u32 *insn)
+{
+ long off_bytes = (long)target - (long)(pc + 4);
+ long disp = off_bytes >> 2;
+
+ /*
+ * 21-bit signed displacement: range is [-2^20, 2^20-1] instructions.
+ * If this trips, the site/target are too far apart for a BR.
+ */
+ if (WARN_ON_ONCE(disp < -(1L << 20) || disp > ((1L << 20) - 1)))
+ return false;
+
+ *insn = (ALPHA_OP_BR << 26) |
+ (ALPHA_RA_R31 << 21) |
+ ((u32)disp & ALPHA_BR_DISP_MASK);
+ return true;
+}
+
+static inline void alpha_patch_text(u32 *site, u32 insn)
+{
+ WRITE_ONCE(*site, insn);
+ /*
+ * Alpha needs an I-cache sync after patching executable text.
+ */
+ flush_icache_range((unsigned long)site, (unsigned long)site + sizeof(*site));
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ u32 *site = (u32 *)jump_entry_code(entry);
+ u32 insn;
+
+ if (type == JUMP_LABEL_JMP) {
+ if (!alpha_br_insn((unsigned long)site, jump_entry_target(entry),
+ &insn))
+ return;
+ } else {
+ insn = ALPHA_INSN_NOP;
+ }
+
+ alpha_patch_text(site, insn);
+}
base-commit: 0b4cadbe7c39d830dec35c4a2655483de0dae568
--
2.43.0
next prev parent reply other threads:[~2026-11-14 9:48 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 9:48 [PATCH v3 0/1] alpha: Add support for HAVE_ARCH_JUMP_LABEL Magnus Lindholm
2026-11-14 9:48 ` Magnus Lindholm [this message]
2026-11-14 16:54 ` [PATCH v3] " Matt Turner
2026-11-14 17:46 ` Magnus Lindholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261114094826.1282965-2-linmag7@gmail.com \
--to=linmag7@gmail.com \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mattst88@gmail.com \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.