From 6d2a32e276d8568362cba36a27726c42424e0651 Mon Sep 17 00:00:00 2001 From: Simone Magnani Date: Mon, 11 Nov 2024 12:00:25 +0100 Subject: [PATCH 1/2] features: add haveV4ISA probe for checking ISA v4 support in the kernel This commit introduces the haveV4ISA probe features.HaveV4ISA to check if the kernel supports instructions of the v4 ISA, introduced in Linux commit 1f9a1ea821ff ("bpf: Support new sign-extension load insns"). The probe tests the new asm.LongJump insn given by `BPF_JMP32 | BPF_JA`. On arm64 with kernel prior to ISA v4 support (<= v6.6), this would return sys.ENOTSUPP: handle this case by returning our ebpf.ErrNotSupported instead. Signed-off-by: Simone Magnani --- features/misc.go | 27 +++++++++++++++++++++++++++ features/misc_test.go | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/features/misc.go b/features/misc.go index 0c4e1a261..78e85639c 100644 --- a/features/misc.go +++ b/features/misc.go @@ -93,3 +93,30 @@ var haveV3ISA = internal.NewFeatureTest("v3 ISA", func() error { }, }) }, "5.1") + +// HaveV4ISA probes the running kernel if instructions of the v4 ISA are supported. +// +// Upstream commit 1f9a1ea821ff ("bpf: Support new sign-extension load insns"). +// +// See the package documentation for the meaning of the error return value. +func HaveV4ISA() error { + return haveV4ISA() +} + +var haveV4ISA = internal.NewFeatureTest("v4 ISA", func() error { + err := probeProgram(&ebpf.ProgramSpec{ + Type: ebpf.SocketFilter, + Instructions: asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.JEq.Imm(asm.R0, 1, "error"), + asm.LongJump("exit"), + asm.Mov.Imm(asm.R0, 1).WithSymbol("error"), + asm.Return().WithSymbol("exit"), + }, + }) + // This sometimes bubbles up from the JIT on aarch64. + if errors.Is(err, sys.ENOTSUPP) { + return ebpf.ErrNotSupported + } + return err +}, "6.6") diff --git a/features/misc_test.go b/features/misc_test.go index 95fa0e09f..7e261039c 100644 --- a/features/misc_test.go +++ b/features/misc_test.go @@ -21,3 +21,7 @@ func TestHaveV2ISA(t *testing.T) { func TestHaveV3ISA(t *testing.T) { testutils.CheckFeatureTest(t, HaveV3ISA) } + +func TestHaveV4ISA(t *testing.T) { + testutils.CheckFeatureTest(t, HaveV4ISA) +} From e987b164891c2db6879e821b66f332f698d99e0d Mon Sep 17 00:00:00 2001 From: Timo Beckers Date: Thu, 12 Dec 2024 13:49:48 +0100 Subject: [PATCH 2/2] features: consider ENOTSUPP in v2 and v4 ISA probes as conclusive With the addition of the v4 ISA probe, we noticed an ENOTSUPP being returned by BPF_PROG_LOAD on aarch64. Typically, this is an error code internal to the verifier/JIT, but on aarch64 it seems to bubble up. Since we cannot currently test older arm kernels, apply this logic to the older ISA probes as well. Signed-off-by: Timo Beckers --- features/misc.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/features/misc.go b/features/misc.go index 78e85639c..c039020a9 100644 --- a/features/misc.go +++ b/features/misc.go @@ -1,9 +1,12 @@ package features import ( + "errors" + "github.com/cilium/ebpf" "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/internal" + "github.com/cilium/ebpf/internal/sys" ) // HaveLargeInstructions probes the running kernel if more than 4096 instructions @@ -62,7 +65,7 @@ func HaveV2ISA() error { } var haveV2ISA = internal.NewFeatureTest("v2 ISA", func() error { - return probeProgram(&ebpf.ProgramSpec{ + err := probeProgram(&ebpf.ProgramSpec{ Type: ebpf.SocketFilter, Instructions: asm.Instructions{ asm.Mov.Imm(asm.R0, 0), @@ -71,6 +74,11 @@ var haveV2ISA = internal.NewFeatureTest("v2 ISA", func() error { asm.Return().WithSymbol("exit"), }, }) + // This sometimes bubbles up from the JIT on aarch64. + if errors.Is(err, sys.ENOTSUPP) { + return ebpf.ErrNotSupported + } + return err }, "4.14") // HaveV3ISA probes the running kernel if instructions of the v3 ISA are supported. @@ -83,7 +91,7 @@ func HaveV3ISA() error { } var haveV3ISA = internal.NewFeatureTest("v3 ISA", func() error { - return probeProgram(&ebpf.ProgramSpec{ + err := probeProgram(&ebpf.ProgramSpec{ Type: ebpf.SocketFilter, Instructions: asm.Instructions{ asm.Mov.Imm(asm.R0, 0), @@ -92,6 +100,11 @@ var haveV3ISA = internal.NewFeatureTest("v3 ISA", func() error { asm.Return().WithSymbol("exit"), }, }) + // This sometimes bubbles up from the JIT on aarch64. + if errors.Is(err, sys.ENOTSUPP) { + return ebpf.ErrNotSupported + } + return err }, "5.1") // HaveV4ISA probes the running kernel if instructions of the v4 ISA are supported.