diff --git a/pkgs/os-specific/linux/kernel/perf/default.nix b/pkgs/os-specific/linux/kernel/perf/default.nix index b947a2650f2d7..e223bf855bf6f 100644 --- a/pkgs/os-specific/linux/kernel/perf/default.nix +++ b/pkgs/os-specific/linux/kernel/perf/default.nix @@ -39,6 +39,8 @@ zstd, withLibcap ? true, libcap, + buildPackages, + writeShellScript, }: let d3-flame-graph-templates = stdenv.mkDerivation rec { @@ -54,6 +56,15 @@ let install -D -m 0755 -t $out/share/d3-flame-graph/ ./dist/templates/* ''; }; + # The cc-wrapper adds `-fzero-call-used-regs` as part of the default + # hardening to the compiler command line, but clang aborts with an error when + # that is used together with a target arch that is not x86 or x86_64. + # This wrapper works around that issue by instructing the machinery to not + # add that flag for those particular invocations. + clang-bpf = writeShellScript "clang-bpf" '' + NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/zerocallusedregs/} + exec ${lib.getExe buildPackages.clang} "$@" + ''; in stdenv.mkDerivation { @@ -78,6 +89,9 @@ stdenv.mkDerivation { url = "https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/patch/?id=1d302f626c2a23e4fd05bb810eff300e8f2174fd"; hash = "sha256-KhCmof8LkyTcBBpfMEtolL3m3kmC5rukKzQvufVKCdI="; }) + ] + ++ lib.optionals (lib.versions.majorMinor kernel.version == "6.12") [ + ./fix-augmented-raw-syscalls.bpf.diff # Loading this bpf object can fail with E2BIG in perf trace without the fix ]; postPatch = @@ -85,6 +99,9 @@ stdenv.mkDerivation { # Linux scripts patchShebangs scripts patchShebangs tools/perf/check-headers.sh + + # Expose warnings and errors of feature detection + sed -i -e 's/2>\/dev\/null//g' tools/build/Makefile.feature '' + lib.optionalString (lib.versionAtLeast kernel.version "6.3") '' # perf-specific scripts @@ -113,6 +130,7 @@ stdenv.mkDerivation { "prefix=$(out)" "WERROR=0" "ASCIIDOC8=1" + "CLANG=${clang-bpf}" ] ++ kernel.makeFlags ++ lib.optional (!withGtk) "NO_GTK2=1" diff --git a/pkgs/os-specific/linux/kernel/perf/fix-augmented-raw-syscalls.bpf.diff b/pkgs/os-specific/linux/kernel/perf/fix-augmented-raw-syscalls.bpf.diff new file mode 100644 index 0000000000000..92b7eaf824717 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/perf/fix-augmented-raw-syscalls.bpf.diff @@ -0,0 +1,31 @@ +--- a/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c ++++ b/tools/perf/util/bpf_skel/augmented_raw_syscalls.bpf.c +@@ -431,9 +431,9 @@ static bool pid_filter__has(struct pids_filtered *pids, pid_t pid) + static int augment_sys_enter(void *ctx, struct syscall_enter_args *args) + { + bool augmented, do_output = false; +- int zero = 0, size, aug_size, index, +- value_size = sizeof(struct augmented_arg) - offsetof(struct augmented_arg, value); ++ int zero = 0, index, value_size = sizeof(struct augmented_arg) - offsetof(struct augmented_arg, value); + u64 output = 0; /* has to be u64, otherwise it won't pass the verifier */ ++ s64 aug_size, size; + unsigned int nr, *beauty_map; + struct beauty_payload_enter *payload; + void *arg, *payload_offset; +@@ -484,14 +484,11 @@ static int augment_sys_enter(void *ctx, struct syscall_enter_args *args) + } else if (size > 0 && size <= value_size) { /* struct */ + if (!bpf_probe_read_user(((struct augmented_arg *)payload_offset)->value, size, arg)) + augmented = true; +- } else if (size < 0 && size >= -6) { /* buffer */ ++ } else if ((int)size < 0 && size >= -6) { /* buffer */ + index = -(size + 1); + barrier_var(index); // Prevent clang (noticed with v18) from removing the &= 7 trick. + index &= 7; // Satisfy the bounds checking with the verifier in some kernels. +- aug_size = args->args[index]; +- +- if (aug_size > TRACE_AUG_MAX_BUF) +- aug_size = TRACE_AUG_MAX_BUF; ++ aug_size = args->args[index] > TRACE_AUG_MAX_BUF ? TRACE_AUG_MAX_BUF : args->args[index]; + + if (aug_size > 0) { + if (!bpf_probe_read_user(((struct augmented_arg *)payload_offset)->value, aug_size, arg))