From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net,
Leon Hwang <leon.hwang@linux.dev>
Subject: [RFC PATCH bpf-next 2/4] bpf, x86: Add 64bit bitops kfuncs support for x86_64
Date: Mon, 9 Feb 2026 23:59:13 +0800 [thread overview]
Message-ID: <20260209155919.19015-3-leon.hwang@linux.dev> (raw)
In-Reply-To: <20260209155919.19015-1-leon.hwang@linux.dev>
Implement JIT inlining of the 64bit bitops kfuncs on x86_64.
bpf_rol64() and bpf_ror64() are always supported via ROL/ROR.
bpf_clz64(), bpf_ctz64(), bpf_ffs64(), and bpf_fls64() are supported
when the CPU has X86_FEATURE_ABM (LZCNT/TZCNT).
bpf_popcnt64() is supported when the CPU has X86_FEATURE_POPCNT.
bpf_bitrev64() is not supported as x86_64 has no native bit-reverse
instruction.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
arch/x86/net/bpf_jit_comp.c | 153 ++++++++++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 070ba80e39d7..5d6215071cbd 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -19,6 +19,7 @@
#include <asm/text-patching.h>
#include <asm/unwind.h>
#include <asm/cfi.h>
+#include <asm/cpufeatures.h>
static bool all_callee_regs_used[4] = {true, true, true, true};
@@ -1604,6 +1605,134 @@ static void emit_priv_frame_ptr(u8 **pprog, void __percpu *priv_frame_ptr)
*pprog = prog;
}
+static int emit_bitops(u8 **pprog, u32 bitops)
+{
+ u8 *prog = *pprog;
+
+ /*
+ * x86 Bit manipulation instruction set
+ * https://en.wikipedia.org/wiki/X86_Bit_manipulation_instruction_set
+ */
+
+ switch (bitops) {
+ case BPF_CLZ64:
+ /*
+ * Intel® 64 and IA-32 Architectures Software Developer's Manual (June 2023)
+ *
+ * LZCNT - Count the Number of Leading Zero Bits
+ *
+ * Opcode/Instruction
+ * F3 REX.W 0F BD /r
+ * LZCNT r64, r/m64
+ *
+ * Op/En
+ * RVM
+ *
+ * 64/32-bit Mode
+ * V/N.E.
+ *
+ * CPUID Feature Flag
+ * LZCNT
+ *
+ * Description
+ * Count the number of leading zero bits in r/m64, return
+ * result in r64.
+ */
+ /* emit: x ? 64 - fls64(x) : 64 */
+ /* lzcnt rax, rdi */
+ EMIT5(0xF3, 0x48, 0x0F, 0xBD, 0xC7);
+ break;
+
+ case BPF_CTZ64:
+ /*
+ * Intel® 64 and IA-32 Architectures Software Developer's Manual (June 2023)
+ *
+ * TZCNT - Count the Number of Trailing Zero Bits
+ *
+ * Opcode/Instruction
+ * F3 REX.W 0F BC /r
+ * TZCNT r64, r/m64
+ *
+ * Op/En
+ * RVM
+ *
+ * 64/32-bit Mode
+ * V/N.E.
+ *
+ * CPUID Feature Flag
+ * BMI1
+ *
+ * Description
+ * Count the number of trailing zero bits in r/m64, return
+ * result in r64.
+ */
+ /* emit: x ? __ffs64(x) : 64 */
+ /* tzcnt rax, rdi */
+ EMIT5(0xF3, 0x48, 0x0F, 0xBC, 0xC7);
+ break;
+
+ case BPF_FFS64:
+ /* emit: __ffs64(x), 'x == 0' was handled by verifier */
+ /* tzcnt rax, rdi */
+ EMIT5(0xF3, 0x48, 0x0F, 0xBC, 0xC7);
+ break;
+
+ case BPF_FLS64:
+ /* emit: fls64(x) */
+ /* lzcnt rax, rdi; neg rax; add rax, 64 */
+ EMIT5(0xF3, 0x48, 0x0F, 0xBD, 0xC7);
+ EMIT3(0x48, 0xF7, 0xD8); /* neg rax */
+ EMIT4(0x48, 0x83, 0xC0, 0x40); /* add rax, 64 */
+ break;
+
+ case BPF_POPCNT64:
+ /*
+ * Intel® 64 and IA-32 Architectures Software Developer's Manual (June 2023)
+ *
+ * POPCNT - Return the Count of Number of Bits Set to 1
+ *
+ * Opcode/Instruction
+ * F3 REX.W 0F B8 /r
+ * POPCNT r64, r/m64
+ *
+ * Op/En
+ * RM
+ *
+ * 64 Mode
+ * Valid
+ *
+ * Compat/Leg Mode
+ * N.E.
+ *
+ * Description
+ * POPCNT on r/m64
+ */
+ /* popcnt rax, rdi */
+ EMIT5(0xF3, 0x48, 0x0F, 0xB8, 0xC7);
+ break;
+
+ case BPF_ROL64:
+ /* emit: rol64(x, s) */
+ EMIT3(0x48, 0x89, 0xF1); /* mov rcx, rsi */
+ EMIT3(0x48, 0x89, 0xF8); /* mov rax, rdi */
+ EMIT3(0x48, 0xD3, 0xC0); /* rol rax, cl */
+ break;
+
+ case BPF_ROR64:
+ /* emit: ror64(x, s) */
+ EMIT3(0x48, 0x89, 0xF1); /* mov rcx, rsi */
+ EMIT3(0x48, 0x89, 0xF8); /* mov rax, rdi */
+ EMIT3(0x48, 0xD3, 0xC8); /* ror rax, cl */
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ *pprog = prog;
+ return 0;
+}
+
#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
#define __LOAD_TCC_PTR(off) \
@@ -2113,6 +2242,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
}
break;
+ case BPF_ALU64 | BPF_BITOPS:
+ err = emit_bitops(&prog, insn->imm);
+ if (err)
+ return err;
+ break;
+
/* speculation barrier */
case BPF_ST | BPF_NOSPEC:
EMIT_LFENCE();
@@ -4117,3 +4252,21 @@ bool bpf_jit_supports_fsession(void)
{
return true;
}
+
+bool bpf_jit_inlines_bitops(s32 imm)
+{
+ switch (imm) {
+ case BPF_CLZ64:
+ case BPF_CTZ64:
+ case BPF_FFS64:
+ case BPF_FLS64:
+ return boot_cpu_has(X86_FEATURE_ABM);
+ case BPF_POPCNT64:
+ return boot_cpu_has(X86_FEATURE_POPCNT);
+ case BPF_ROL64:
+ case BPF_ROR64:
+ return true;
+ default:
+ return false;
+ }
+}
--
2.52.0
next prev parent reply other threads:[~2026-02-09 15:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-09 15:59 [RFC PATCH bpf-next 0/4] bpf: Introduce 64bit bitops kfuncs Leon Hwang
2026-02-09 15:59 ` [RFC PATCH bpf-next 1/4] " Leon Hwang
2026-02-11 3:05 ` Alexei Starovoitov
2026-02-11 3:29 ` Leon Hwang
2026-02-09 15:59 ` Leon Hwang [this message]
2026-02-09 15:59 ` [RFC PATCH bpf-next 3/4] bpf, arm64: Add 64bit bitops kfuncs support Leon Hwang
2026-02-09 15:59 ` [RFC PATCH bpf-next 4/4] selftests/bpf: Add tests for 64bit bitops kfuncs Leon Hwang
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=20260209155919.19015-3-leon.hwang@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox