All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/1] alpha: Add support for HAVE_ARCH_JUMP_LABEL
@ 2026-11-14  9:48 Magnus Lindholm
  2026-11-14  9:48 ` [PATCH v3] " Magnus Lindholm
  0 siblings, 1 reply; 4+ messages in thread
From: Magnus Lindholm @ 2026-11-14  9:48 UTC (permalink / raw)
  To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7

This revision addresses Matt Turner's review of v2.

Changes since v2:
- Rebase onto the current local alpha-devel branch.
- Place HAVE_ARCH_JUMP_LABEL beside the other HAVE_ARCH selections.
- Warn and return without patching an out-of-range branch target.
- Remove the unused mutex include. Retain JUMP_LABEL_NOP_SIZE: the
  current generic jump_entry_size() requires it on Alpha.
- Clean up the duplicate NOP comment and extra blank line.
- Document the writable kernel and module text requirement.
- Retain Matt's Reviewed-by.

Batching I-cache synchronization and relative jump table entries remain
possible follow-ups.

The previous submission reported UP2000+ SMP tracepoint and stress
checks. Those results do not establish validation of this revision.
This revision cross-builds successfully with W=1 for Alpha SMP, with
CONFIG_JUMP_LABEL=y, CONFIG_STATIC_KEYS_SELFTEST=y and
CONFIG_TEST_STATIC_KEYS=m. On the ES40, the boot selftest passed and
the static-key test modules completed 10 load/unload cycles on each of
three CPUs (30 total), including cross-module keys. This used a combined
kernel with CMA v2. no new kernel warnings or faults appeared during
those tests.

Magnus Lindholm (1):
  alpha: Add support for HAVE_ARCH_JUMP_LABEL

 .../core/jump-labels/arch-support.txt         |  2 +-
 arch/alpha/Kconfig                            |  1 +
 arch/alpha/include/asm/jump_label.h           | 63 +++++++++++++++
 arch/alpha/kernel/Makefile                    |  2 +
 arch/alpha/kernel/jump_label.c                | 79 +++++++++++++++++++
 5 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 arch/alpha/include/asm/jump_label.h
 create mode 100644 arch/alpha/kernel/jump_label.c


base-commit: 0b4cadbe7c39d830dec35c4a2655483de0dae568
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3] alpha: Add support for HAVE_ARCH_JUMP_LABEL
  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
  2026-11-14 16:54   ` Matt Turner
  0 siblings, 1 reply; 4+ messages in thread
From: Magnus Lindholm @ 2026-11-14  9:48 UTC (permalink / raw)
  To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] alpha: Add support for HAVE_ARCH_JUMP_LABEL
  2026-11-14  9:48 ` [PATCH v3] " Magnus Lindholm
@ 2026-11-14 16:54   ` Matt Turner
  2026-11-14 17:46     ` Magnus Lindholm
  0 siblings, 1 reply; 4+ messages in thread
From: Matt Turner @ 2026-11-14 16:54 UTC (permalink / raw)
  To: Magnus Lindholm; +Cc: richard.henderson, linux-kernel, linux-alpha

On Sat, Nov 14, 2026 at 4:48 AM Magnus Lindholm <linmag7@gmail.com> wrote:
> 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

Nit: this would read better up with the other unconditional obj-
lines near the top of the file rather than trailing the GENERIC
block.

> +#include <linux/jump_label.h>
> +#include <linux/kernel.h>
> +#include <asm/cacheflush.h>

Nit: checkpatch --strict suggests <linux/cacheflush.h> here.

> +     if (WARN_ON_ONCE(disp < -(1L << 20) || disp > ((1L << 20) - 1)))
> +             return false;

Thanks. The target is always within the same function and Alpha gcc
doesn't do hot/cold partitioning, so I don't expect this to fire, but
it's a cheap safety net.

> +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));
> +}

On SMP this is smp_imb(), so every key flip IPIs all CPUs once per
site. That's correct, and fine as a starting point; batching via
arch_jump_label_transform_queue()/_apply() would be the natural
follow-up you mention in the cover letter.

I applied this on 0b4cadbe7c39 and cross-built an SMP defconfig with
JUMP_LABEL and STATIC_KEYS_SELFTEST at W=1 with no new warnings. The
patch sites in vmlinux are the expected 0x47ff041f nops with nearby
targets.

The diffstat in the cover letter is stale (63/146 vs. 65/148 in the
patch), but that doesn't matter for applying.

None of the above needs a respin from my side.

Reviewed-by: Matt Turner <mattst88@gmail.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3] alpha: Add support for HAVE_ARCH_JUMP_LABEL
  2026-11-14 16:54   ` Matt Turner
@ 2026-11-14 17:46     ` Magnus Lindholm
  0 siblings, 0 replies; 4+ messages in thread
From: Magnus Lindholm @ 2026-11-14 17:46 UTC (permalink / raw)
  To: Matt Turner; +Cc: richard.henderson, linux-kernel, linux-alpha

Hi Matt,

On Sat, Nov 14, 2026 at 5:54 PM Matt Turner <mattst88@gmail.com> wrote:
>
> On Sat, Nov 14, 2026 at 4:48 AM Magnus Lindholm <linmag7@gmail.com> wrote:
> > 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
>
> Nit: this would read better up with the other unconditional obj-
> lines near the top of the file rather than trailing the GENERIC
> block.
>
> > +#include <linux/jump_label.h>
> > +#include <linux/kernel.h>
> > +#include <asm/cacheflush.h>
>
> Nit: checkpatch --strict suggests <linux/cacheflush.h> here.
>
> > +     if (WARN_ON_ONCE(disp < -(1L << 20) || disp > ((1L << 20) - 1)))
> > +             return false;
>
> Thanks. The target is always within the same function and Alpha gcc
> doesn't do hot/cold partitioning, so I don't expect this to fire, but
> it's a cheap safety net.
>
> > +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));
> > +}
>
> On SMP this is smp_imb(), so every key flip IPIs all CPUs once per
> site. That's correct, and fine as a starting point; batching via
> arch_jump_label_transform_queue()/_apply() would be the natural
> follow-up you mention in the cover letter.
>
> I applied this on 0b4cadbe7c39 and cross-built an SMP defconfig with
> JUMP_LABEL and STATIC_KEYS_SELFTEST at W=1 with no new warnings. The
> patch sites in vmlinux are the expected 0x47ff041f nops with nearby
> targets.
>
> The diffstat in the cover letter is stale (63/146 vs. 65/148 in the
> patch), but that doesn't matter for applying.
>
> None of the above needs a respin from my side.
>
> Reviewed-by: Matt Turner <mattst88@gmail.com>

Thanks for reviewing and build-testing this. I'll fix the Makefile
placement and cacheflush include when applying it, and refresh the
cover-letter diffstat. Batching can remain a follow-up.

The boot selftest and 30 module load/unload cycles also passed on
my three-CPU ES40, including cross-module static keys.

Thanks,
Magnus

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-14 17:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14  9:48 [PATCH v3 0/1] alpha: Add support for HAVE_ARCH_JUMP_LABEL Magnus Lindholm
2026-11-14  9:48 ` [PATCH v3] " Magnus Lindholm
2026-11-14 16:54   ` Matt Turner
2026-11-14 17:46     ` Magnus Lindholm

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.