--- /dev/null
+From bac74dcbd48b5b441e47841fd0fe507c7b0bcbaf Mon Sep 17 00:00:00 2001
+From: Ian Rogers <irogers@google.com>
+Date: Wed, 19 Nov 2025 15:36:21 -0800
+Subject: perf tools: Switch printf("...%s", strerror(errno)) to printf("...%m")
+
+From: Ian Rogers <irogers@google.com>
+
+commit bac74dcbd48b5b441e47841fd0fe507c7b0bcbaf upstream.
+
+strerror() has thread safety issues, strerror_r() requires stack
+allocated buffers.
+
+Code in perf has already been using the "%m" formatting flag that is a
+widely support glibc extension to print the current errno's description.
+
+Expand the usage of this formatting flag and remove usage of
+strerror()/strerror_r().
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
+Cc: Blake Jones <blakejones@google.com>
+Cc: Chun-Tse Shao <ctshao@google.com>
+Cc: Dmitriy Vyukov <dvyukov@google.com>
+Cc: Dr. David Alan Gilbert <linux@treblig.org>
+Cc: Haibo Xu <haibo1.xu@intel.com>
+Cc: Howard Chu <howardchu95@gmail.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
+Cc: Thomas Falcon <thomas.falcon@intel.com>
+Cc: Yunseong Kim <ysk@kzalloc.com>
+Cc: Zhongqiu Han <quic_zhonhan@quicinc.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/perf/arch/x86/tests/bp-modify.c | 30 ++++++++++++------------------
+ tools/perf/bench/uprobe.c | 2 +-
+ tools/perf/builtin-daemon.c | 8 +++-----
+ tools/perf/builtin-probe.c | 3 +--
+ tools/perf/builtin-record.c | 24 ++++++++++--------------
+ tools/perf/builtin-stat.c | 9 ++++-----
+ tools/perf/builtin-trace.c | 15 ++++++---------
+ tools/perf/perf.c | 18 +++++++-----------
+ tools/perf/util/bpf-event.c | 11 ++++-------
+ tools/perf/util/bpf-utils.c | 4 ++--
+ tools/perf/util/bpf_lock_contention.c | 2 +-
+ tools/perf/util/cap.c | 3 +--
+ tools/perf/util/data.c | 29 ++++++++++-------------------
+ tools/perf/util/dso.c | 19 ++++++-------------
+ tools/perf/util/evlist.c | 31 +++++++++++++++++--------------
+ tools/perf/util/evsel.c | 17 +++++++++--------
+ tools/perf/util/jitdump.c | 3 ++-
+ tools/perf/util/lzma.c | 6 +++---
+ tools/perf/util/session.c | 5 +++--
+ tools/perf/util/symbol-elf.c | 4 ++--
+ 20 files changed, 104 insertions(+), 139 deletions(-)
+
+--- a/tools/perf/arch/x86/tests/bp-modify.c
++++ b/tools/perf/arch/x86/tests/bp-modify.c
+@@ -80,26 +80,24 @@ static int bp_modify1(void)
+ */
+ if (ptrace(PTRACE_POKEUSER, child,
+ offsetof(struct user, u_debugreg[0]), bp_2)) {
+- pr_debug("failed to set breakpoint, 1st time: %s\n",
+- strerror(errno));
++ pr_debug("failed to set breakpoint, 1st time: %m\n");
+ goto out;
+ }
+
+ if (ptrace(PTRACE_POKEUSER, child,
+ offsetof(struct user, u_debugreg[0]), bp_1)) {
+- pr_debug("failed to set breakpoint, 2nd time: %s\n",
+- strerror(errno));
++ pr_debug("failed to set breakpoint, 2nd time: %m\n");
+ goto out;
+ }
+
+ if (ptrace(PTRACE_POKEUSER, child,
+ offsetof(struct user, u_debugreg[7]), dr7)) {
+- pr_debug("failed to set dr7: %s\n", strerror(errno));
++ pr_debug("failed to set dr7: %m\n");
+ goto out;
+ }
+
+ if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
+- pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
++ pr_debug("failed to PTRACE_CONT: %m\n");
+ goto out;
+ }
+
+@@ -112,19 +110,17 @@ static int bp_modify1(void)
+ rip = ptrace(PTRACE_PEEKUSER, child,
+ offsetof(struct user_regs_struct, rip), NULL);
+ if (rip == (unsigned long) -1) {
+- pr_debug("failed to PTRACE_PEEKUSER: %s\n",
+- strerror(errno));
++ pr_debug("failed to PTRACE_PEEKUSER: %m\n");
+ goto out;
+ }
+
+ pr_debug("rip %lx, bp_1 %p\n", rip, bp_1);
+-
+ out:
+ if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
+- pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
++ pr_debug("failed to PTRACE_DETACH: %m\n");
+ return TEST_FAIL;
+- }
+
++ }
+ return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL;
+ }
+
+@@ -157,14 +153,13 @@ static int bp_modify2(void)
+ */
+ if (ptrace(PTRACE_POKEUSER, child,
+ offsetof(struct user, u_debugreg[0]), bp_1)) {
+- pr_debug("failed to set breakpoint: %s\n",
+- strerror(errno));
++ pr_debug("failed to set breakpoint: %m\n");
+ goto out;
+ }
+
+ if (ptrace(PTRACE_POKEUSER, child,
+ offsetof(struct user, u_debugreg[7]), dr7)) {
+- pr_debug("failed to set dr7: %s\n", strerror(errno));
++ pr_debug("failed to set dr7: %m\n");
+ goto out;
+ }
+
+@@ -175,7 +170,7 @@ static int bp_modify2(void)
+ }
+
+ if (ptrace(PTRACE_CONT, child, NULL, NULL)) {
+- pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno));
++ pr_debug("failed to PTRACE_CONT: %m\n");
+ goto out;
+ }
+
+@@ -188,8 +183,7 @@ static int bp_modify2(void)
+ rip = ptrace(PTRACE_PEEKUSER, child,
+ offsetof(struct user_regs_struct, rip), NULL);
+ if (rip == (unsigned long) -1) {
+- pr_debug("failed to PTRACE_PEEKUSER: %s\n",
+- strerror(errno));
++ pr_debug("failed to PTRACE_PEEKUSER: %m\n");
+ goto out;
+ }
+
+@@ -197,7 +191,7 @@ static int bp_modify2(void)
+
+ out:
+ if (ptrace(PTRACE_DETACH, child, NULL, NULL)) {
+- pr_debug("failed to PTRACE_DETACH: %s", strerror(errno));
++ pr_debug("failed to PTRACE_DETACH: %m\n");
+ return TEST_FAIL;
+ }
+
+--- a/tools/perf/bench/uprobe.c
++++ b/tools/perf/bench/uprobe.c
+@@ -54,7 +54,7 @@ static const char * const bench_uprobe_u
+ /*opts=*/&uprobe_opts); \
+ if (!skel->links.prog) { \
+ err = -errno; \
+- fprintf(stderr, "Failed to attach bench uprobe \"%s\": %s\n", #prog, strerror(errno)); \
++ fprintf(stderr, "Failed to attach bench uprobe \"%s\": %m\n", #prog); \
+ goto cleanup; \
+ }
+
+--- a/tools/perf/builtin-daemon.c
++++ b/tools/perf/builtin-daemon.c
+@@ -265,8 +265,7 @@ static int check_base(struct daemon *dae
+ daemon->base);
+ return -EACCES;
+ default:
+- pr_err("failed: can't access base '%s': %s\n",
+- daemon->base, strerror(errno));
++ pr_err("failed: can't access base '%s': %m\n", daemon->base);
+ return -errno;
+ }
+ }
+@@ -544,8 +543,7 @@ static int daemon_session__control(struc
+
+ err = writen(control, msg, len);
+ if (err != len) {
+- pr_err("failed: write to control pipe: %d (%s)\n",
+- errno, control_path);
++ pr_err("failed: write to control pipe: %m (%s)\n", control_path);
+ goto out;
+ }
+
+@@ -586,7 +584,7 @@ static int setup_server_socket(struct da
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (fd < 0) {
+- fprintf(stderr, "socket: %s\n", strerror(errno));
++ fprintf(stderr, "socket: %m\n");
+ return -1;
+ }
+
+--- a/tools/perf/builtin-probe.c
++++ b/tools/perf/builtin-probe.c
+@@ -211,8 +211,7 @@ static int opt_set_target_ns(const struc
+ ns_pid = (pid_t)strtol(str, NULL, 10);
+ if (errno != 0) {
+ ret = -errno;
+- pr_warning("Failed to parse %s as a pid: %s\n", str,
+- strerror(errno));
++ pr_warning("Failed to parse %s as a pid: %m\n", str);
+ return ret;
+ }
+ nsip = nsinfo__new(ns_pid);
+--- a/tools/perf/builtin-record.c
++++ b/tools/perf/builtin-record.c
+@@ -1323,7 +1323,6 @@ static int record__mmap_evlist(struct re
+ struct record_opts *opts = &rec->opts;
+ bool auxtrace_overwrite = opts->auxtrace_snapshot_mode ||
+ opts->auxtrace_sample_mode;
+- char msg[512];
+
+ if (opts->affinity != PERF_AFFINITY_SYS)
+ cpu__setup_cpunode_map();
+@@ -1342,8 +1341,7 @@ static int record__mmap_evlist(struct re
+ opts->mmap_pages, opts->auxtrace_mmap_pages);
+ return -errno;
+ } else {
+- pr_err("failed to mmap with %d (%s)\n", errno,
+- str_error_r(errno, msg, sizeof(msg)));
++ pr_err("failed to mmap: %m\n");
+ if (errno)
+ return -errno;
+ else
+@@ -1361,7 +1359,8 @@ static int record__mmap_evlist(struct re
+ if (record__threads_enabled(rec)) {
+ ret = perf_data__create_dir(&rec->data, evlist->core.nr_mmaps);
+ if (ret) {
+- pr_err("Failed to create data directory: %s\n", strerror(-ret));
++ errno = -ret;
++ pr_err("Failed to create data directory: %m\n");
+ return ret;
+ }
+ for (i = 0; i < evlist->core.nr_mmaps; i++) {
+@@ -1422,9 +1421,8 @@ try_again:
+ }
+
+ if (evlist__apply_filters(evlist, &pos, &opts->target)) {
+- pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
+- pos->filter ?: "BPF", evsel__name(pos), errno,
+- str_error_r(errno, msg, sizeof(msg)));
++ pr_err("failed to set filter \"%s\" on event %s: %m\n",
++ pos->filter ?: "BPF", evsel__name(pos));
+ rc = -1;
+ goto out;
+ }
+@@ -1709,8 +1707,7 @@ static void *record__thread(void *arg)
+
+ err = write(thread->pipes.ack[1], &msg, sizeof(msg));
+ if (err == -1)
+- pr_warning("threads[%d]: failed to notify on start: %s\n",
+- thread->tid, strerror(errno));
++ pr_warning("threads[%d]: failed to notify on start: %m\n", thread->tid);
+
+ pr_debug("threads[%d]: started on cpu%d\n", thread->tid, sched_getcpu());
+
+@@ -1753,8 +1750,7 @@ static void *record__thread(void *arg)
+
+ err = write(thread->pipes.ack[1], &msg, sizeof(msg));
+ if (err == -1)
+- pr_warning("threads[%d]: failed to notify on termination: %s\n",
+- thread->tid, strerror(errno));
++ pr_warning("threads[%d]: failed to notify on termination: %m\n", thread->tid);
+
+ return NULL;
+ }
+@@ -2300,7 +2296,7 @@ static int record__start_threads(struct
+
+ sigfillset(&full);
+ if (sigprocmask(SIG_SETMASK, &full, &mask)) {
+- pr_err("Failed to block signals on threads start: %s\n", strerror(errno));
++ pr_err("Failed to block signals on threads start: %m\n");
+ return -1;
+ }
+
+@@ -2318,7 +2314,7 @@ static int record__start_threads(struct
+ if (pthread_create(&handle, &attrs, record__thread, &thread_data[t])) {
+ for (tt = 1; tt < t; tt++)
+ record__terminate_thread(&thread_data[t]);
+- pr_err("Failed to start threads: %s\n", strerror(errno));
++ pr_err("Failed to start threads: %m\n");
+ ret = -1;
+ goto out_err;
+ }
+@@ -2341,7 +2337,7 @@ out_err:
+ pthread_attr_destroy(&attrs);
+
+ if (sigprocmask(SIG_SETMASK, &mask, NULL)) {
+- pr_err("Failed to unblock signals on threads start: %s\n", strerror(errno));
++ pr_err("Failed to unblock signals on threads start: %m\n");
+ ret = -1;
+ }
+
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -868,9 +868,8 @@ static int __run_perf_stat(int argc, con
+ }
+
+ if (evlist__apply_filters(evsel_list, &counter, &target)) {
+- pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
+- counter->filter, evsel__name(counter), errno,
+- str_error_r(errno, msg, sizeof(msg)));
++ pr_err("failed to set filter \"%s\" on event %s: %m\n",
++ counter->filter, evsel__name(counter));
+ return -1;
+ }
+
+@@ -932,8 +931,8 @@ static int __run_perf_stat(int argc, con
+ }
+
+ if (workload_exec_errno) {
+- const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
+- pr_err("Workload failed: %s\n", emsg);
++ errno = workload_exec_errno;
++ pr_err("Workload failed: %m\n");
+ err = -1;
+ goto err_out;
+ }
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -2595,12 +2595,10 @@ static struct syscall *trace__syscall_in
+ err = syscall__read_info(sc, trace);
+
+ if (err && verbose > 0) {
+- char sbuf[STRERR_BUFSIZE];
+-
+- fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err,
+- str_error_r(-err, sbuf, sizeof(sbuf)));
++ errno = -err;
++ fprintf(trace->output, "Problems reading syscall %d: %m", id);
+ if (sc && sc->name)
+- fprintf(trace->output, "(%s)", sc->name);
++ fprintf(trace->output, " (%s)", sc->name);
+ fputs(" information\n", trace->output);
+ }
+ return err ? NULL : sc;
+@@ -4652,9 +4650,8 @@ out_error:
+
+ out_error_apply_filters:
+ fprintf(trace->output,
+- "Failed to set filter \"%s\" on event %s with %d (%s)\n",
+- evsel->filter, evsel__name(evsel), errno,
+- str_error_r(errno, errbuf, sizeof(errbuf)));
++ "Failed to set filter \"%s\" on event %s: %m\n",
++ evsel->filter, evsel__name(evsel));
+ goto out_delete_evlist;
+ }
+ out_error_mem:
+@@ -4662,7 +4659,7 @@ out_error_mem:
+ goto out_delete_evlist;
+
+ out_errno:
+- fprintf(trace->output, "errno=%d,%s\n", errno, strerror(errno));
++ fprintf(trace->output, "%m\n");
+ goto out_delete_evlist;
+ }
+
+--- a/tools/perf/perf.c
++++ b/tools/perf/perf.c
+@@ -169,8 +169,8 @@ static int set_debug_file(const char *pa
+ {
+ debug_fp = fopen(path, "w");
+ if (!debug_fp) {
+- fprintf(stderr, "Open debug file '%s' failed: %s\n",
+- path, strerror(errno));
++ fprintf(stderr, "Open debug file '%s' failed: %m\n",
++ path);
+ return -1;
+ }
+
+@@ -335,7 +335,6 @@ static int run_builtin(struct cmd_struct
+ {
+ int status;
+ struct stat st;
+- char sbuf[STRERR_BUFSIZE];
+
+ if (use_browser == -1)
+ use_browser = check_browser_config(p->cmd);
+@@ -363,17 +362,15 @@ static int run_builtin(struct cmd_struct
+ status = 1;
+ /* Check for ENOSPC and EIO errors.. */
+ if (fflush(stdout)) {
+- fprintf(stderr, "write failure on standard output: %s",
+- str_error_r(errno, sbuf, sizeof(sbuf)));
++ fprintf(stderr, "write failure on standard output: %m\n");
+ goto out;
+ }
+ if (ferror(stdout)) {
+- fprintf(stderr, "unknown write failure on standard output");
++ fprintf(stderr, "unknown write failure on standard output\n");
+ goto out;
+ }
+ if (fclose(stdout)) {
+- fprintf(stderr, "close failed on standard output: %s",
+- str_error_r(errno, sbuf, sizeof(sbuf)));
++ fprintf(stderr, "close failed on standard output: %m\n");
+ goto out;
+ }
+ status = 0;
+@@ -459,7 +456,6 @@ int main(int argc, const char **argv)
+ {
+ int err, done_help = 0;
+ const char *cmd;
+- char sbuf[STRERR_BUFSIZE];
+
+ perf_debug_setup();
+
+@@ -573,8 +569,8 @@ int main(int argc, const char **argv)
+ }
+
+ if (cmd) {
+- fprintf(stderr, "Failed to run command '%s': %s\n",
+- cmd, str_error_r(errno, sbuf, sizeof(sbuf)));
++ fprintf(stderr, "Failed to run command '%s': %m\n",
++ cmd);
+ }
+ out:
+ if (debug_fp)
+--- a/tools/perf/util/bpf-event.c
++++ b/tools/perf/util/bpf-event.c
+@@ -787,11 +787,10 @@ int perf_event__synthesize_bpf_events(st
+ err = 0;
+ break;
+ }
+- pr_debug("%s: can't get next program: %s%s\n",
+- __func__, strerror(errno),
+- errno == EINVAL ? " -- kernel too old?" : "");
+ /* don't report error on old kernel or EPERM */
+ err = (errno == EINVAL || errno == EPERM) ? 0 : -1;
++ pr_debug("%s: can\'t get next program: %m%s\n",
++ __func__, errno == EINVAL ? " -- kernel too old?" : "");
+ break;
+ }
+ fd = bpf_prog_get_fd_by_id(id);
+@@ -824,10 +823,8 @@ int perf_event__synthesize_bpf_events(st
+ .tool = session->tool,
+ };
+
+- if (kallsyms__parse(kallsyms_filename, &arg, kallsyms_process_symbol)) {
+- pr_err("%s: failed to synthesize bpf images: %s\n",
+- __func__, strerror(errno));
+- }
++ if (kallsyms__parse(kallsyms_filename, &arg, kallsyms_process_symbol))
++ pr_err("%s: failed to synthesize bpf images: %m\n", __func__);
+
+ free(event);
+ return err;
+--- a/tools/perf/util/bpf-utils.c
++++ b/tools/perf/util/bpf-utils.c
+@@ -123,7 +123,7 @@ get_bpf_prog_info_linear(int fd, __u64 a
+ /* step 1: get array dimensions */
+ err = bpf_obj_get_info_by_fd(fd, &info, &info_len);
+ if (err) {
+- pr_debug("can't get prog info: %s", strerror(errno));
++ pr_debug("can't get prog info: %m\n");
+ return ERR_PTR(-EFAULT);
+ }
+ if (info.type >= __MAX_BPF_PROG_TYPE)
+@@ -186,7 +186,7 @@ get_bpf_prog_info_linear(int fd, __u64 a
+ /* step 5: call syscall again to get required arrays */
+ err = bpf_obj_get_info_by_fd(fd, &info_linear->info, &info_len);
+ if (err) {
+- pr_debug("can't get prog info: %s", strerror(errno));
++ pr_debug("can't get prog info: %m\n");
+ free(info_linear);
+ return ERR_PTR(-EFAULT);
+ }
+--- a/tools/perf/util/bpf_lock_contention.c
++++ b/tools/perf/util/bpf_lock_contention.c
+@@ -42,7 +42,7 @@ static void check_slab_cache_iter(struct
+
+ con->btf = btf__load_vmlinux_btf();
+ if (con->btf == NULL) {
+- pr_debug("BTF loading failed: %s\n", strerror(errno));
++ pr_debug("BTF loading failed: %m\n");
+ return;
+ }
+
+--- a/tools/perf/util/cap.c
++++ b/tools/perf/util/cap.c
+@@ -28,8 +28,7 @@ bool perf_cap__capable(int cap, bool *us
+ header.version == _LINUX_CAPABILITY_VERSION_1)
+ continue;
+
+- pr_debug2("capget syscall failed (%s - %d) fall back on root check\n",
+- strerror(errno), errno);
++ pr_debug2("capget syscall failed (%m) fall back on root check\n");
+ *used_root = true;
+ return geteuid() == 0;
+ }
+--- a/tools/perf/util/data.c
++++ b/tools/perf/util/data.c
+@@ -213,17 +213,15 @@ static int check_backup(struct perf_data
+
+ ret = rm_rf_perf_data(oldname);
+ if (ret) {
+- pr_err("Can't remove old data: %s (%s)\n",
+- ret == -2 ?
+- "Unknown file found" : strerror(errno),
+- oldname);
++ if (ret == -2)
++ pr_err("Can't remove old data: Unknown file found (%s)\n", oldname);
++ else
++ pr_err("Can't remove old data: %m (%s)\n", oldname);
+ return -1;
+ }
+
+ if (rename(data->path, oldname)) {
+- pr_err("Can't move data: %s (%s to %s)\n",
+- strerror(errno),
+- data->path, oldname);
++ pr_err("Can't move data: %m (%s to %s)\n", data->path, oldname);
+ return -1;
+ }
+ }
+@@ -246,14 +244,12 @@ static int open_file_read(struct perf_da
+ int flags = data->in_place_update ? O_RDWR : O_RDONLY;
+ struct stat st;
+ int fd;
+- char sbuf[STRERR_BUFSIZE];
+
+ fd = open(data->file.path, flags);
+ if (fd < 0) {
+ int err = errno;
+
+- pr_err("failed to open %s: %s", data->file.path,
+- str_error_r(err, sbuf, sizeof(sbuf)));
++ pr_err("failed to open %s: %m", data->file.path);
+ if (err == ENOENT && !strcmp(data->file.path, "perf.data"))
+ pr_err(" (try 'perf record' first)");
+ pr_err("\n");
+@@ -285,15 +281,10 @@ static int open_file_read(struct perf_da
+
+ static int open_file_write(struct perf_data *data)
+ {
+- int fd;
+- char sbuf[STRERR_BUFSIZE];
+-
+- fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC,
+- S_IRUSR|S_IWUSR);
++ int fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, S_IRUSR|S_IWUSR);
+
+ if (fd < 0)
+- pr_err("failed to open %s : %s\n", data->file.path,
+- str_error_r(errno, sbuf, sizeof(sbuf)));
++ pr_err("failed to open %s : %m\n", data->file.path);
+
+ return fd;
+ }
+@@ -436,8 +427,8 @@ int perf_data__switch(struct perf_data *
+
+ if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) {
+ ret = -errno;
+- pr_debug("Failed to lseek to %zu: %s",
+- pos, strerror(errno));
++ pr_debug("Failed to lseek to %zu: %m\n",
++ pos);
+ goto out;
+ }
+ }
+--- a/tools/perf/util/dso.c
++++ b/tools/perf/util/dso.c
+@@ -539,16 +539,13 @@ static void close_first_dso(void);
+
+ static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
+ {
+- int fd;
+- char sbuf[STRERR_BUFSIZE];
+-
+ do {
+- fd = open(name, O_RDONLY|O_CLOEXEC);
++ int fd = open(name, O_RDONLY|O_CLOEXEC);
++
+ if (fd >= 0)
+ return fd;
+
+- pr_debug("dso open failed: %s\n",
+- str_error_r(errno, sbuf, sizeof(sbuf)));
++ pr_debug("dso open failed: %m\n");
+ if (!dso__data_open_cnt || errno != EMFILE)
+ break;
+
+@@ -1110,7 +1107,6 @@ static int file_size(struct dso *dso, st
+ {
+ int ret = 0;
+ struct stat st;
+- char sbuf[STRERR_BUFSIZE];
+
+ mutex_lock(dso__data_open_lock());
+
+@@ -1128,8 +1124,7 @@ static int file_size(struct dso *dso, st
+
+ if (fstat(dso__data(dso)->fd, &st) < 0) {
+ ret = -errno;
+- pr_err("dso cache fstat failed: %s\n",
+- str_error_r(errno, sbuf, sizeof(sbuf)));
++ pr_err("dso cache fstat failed: %m\n");
+ dso__data(dso)->status = DSO_DATA_STATUS_ERROR;
+ goto out;
+ }
+@@ -1784,10 +1779,8 @@ int dso__strerror_load(struct dso *dso,
+ BUG_ON(buflen == 0);
+
+ if (errnum >= 0) {
+- const char *err = str_error_r(errnum, buf, buflen);
+-
+- if (err != buf)
+- scnprintf(buf, buflen, "%s", err);
++ errno = errnum;
++ scnprintf(buf, buflen, "%m");
+
+ return 0;
+ }
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -1605,14 +1605,14 @@ int evlist__parse_sample_timestamp(struc
+ int evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size)
+ {
+ int printed, value;
+- char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf));
+
+ switch (err) {
+ case EACCES:
+ case EPERM:
++ errno = err;
+ printed = scnprintf(buf, size,
+- "Error:\t%s.\n"
+- "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
++ "Error:\t%m.\n"
++ "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.");
+
+ value = perf_event_paranoid();
+
+@@ -1639,16 +1639,18 @@ int evlist__strerror_open(struct evlist
+ if (first->core.attr.sample_freq < (u64)max_freq)
+ goto out_default;
+
++ errno = err;
+ printed = scnprintf(buf, size,
+- "Error:\t%s.\n"
++ "Error:\t%m.\n"
+ "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n"
+ "Hint:\tThe current value is %d and %" PRIu64 " is being requested.",
+- emsg, max_freq, first->core.attr.sample_freq);
++ max_freq, first->core.attr.sample_freq);
+ break;
+ }
+ default:
+ out_default:
+- scnprintf(buf, size, "%s", emsg);
++ errno = err;
++ scnprintf(buf, size, "%m");
+ break;
+ }
+
+@@ -1657,17 +1659,17 @@ out_default:
+
+ int evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size)
+ {
+- char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf));
+ int pages_attempted = evlist->core.mmap_len / 1024, pages_max_per_user, printed = 0;
+
+ switch (err) {
+ case EPERM:
+ sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
++ errno = err;
+ printed += scnprintf(buf + printed, size - printed,
+- "Error:\t%s.\n"
++ "Error:\t%m.\n"
+ "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
+ "Hint:\tTried using %zd kB.\n",
+- emsg, pages_max_per_user, pages_attempted);
++ pages_max_per_user, pages_attempted);
+
+ if (pages_attempted >= pages_max_per_user) {
+ printed += scnprintf(buf + printed, size - printed,
+@@ -1679,7 +1681,8 @@ int evlist__strerror_mmap(struct evlist
+ "Hint:\tTry using a smaller -m/--mmap-pages value.");
+ break;
+ default:
+- scnprintf(buf, size, "%s", emsg);
++ errno = err;
++ scnprintf(buf, size, "%m");
+ break;
+ }
+
+@@ -1911,8 +1914,8 @@ static int evlist__parse_control_fifo(co
+ */
+ fd = open(s, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ if (fd < 0) {
+- pr_err("Failed to open '%s'\n", s);
+ ret = -errno;
++ pr_err("Failed to open '%s': %m\n", s);
+ goto out_free;
+ }
+ *ctl_fd = fd;
+@@ -1922,7 +1925,7 @@ static int evlist__parse_control_fifo(co
+ /* O_RDWR | O_NONBLOCK means the other end need not be open */
+ fd = open(p, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ if (fd < 0) {
+- pr_err("Failed to open '%s'\n", p);
++ pr_err("Failed to open '%s': %m\n", p);
+ ret = -errno;
+ goto out_free;
+ }
+@@ -2354,7 +2357,7 @@ int evlist__parse_event_enable_time(stru
+ eet->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+ if (eet->timerfd == -1) {
+ err = -errno;
+- pr_err("timerfd_create failed: %s\n", strerror(errno));
++ pr_err("timerfd_create failed: %m\n");
+ goto free_eet_times;
+ }
+
+@@ -2389,7 +2392,7 @@ static int event_enable_timer__set_timer
+
+ if (timerfd_settime(eet->timerfd, 0, &its, NULL) < 0) {
+ err = -errno;
+- pr_err("timerfd_settime failed: %s\n", strerror(errno));
++ pr_err("timerfd_settime failed: %m\n");
+ }
+ return err;
+ }
+--- a/tools/perf/util/evsel.c
++++ b/tools/perf/util/evsel.c
+@@ -648,8 +648,9 @@ struct tep_event *evsel__tp_format(struc
+ if (IS_ERR(tp_format)) {
+ int err = -PTR_ERR(evsel->tp_format);
+
+- pr_err("Error getting tracepoint format '%s' '%s'(%d)\n",
+- evsel__name(evsel), strerror(err), err);
++ errno = err;
++ pr_err("Error getting tracepoint format '%s': %m\n",
++ evsel__name(evsel));
+ return NULL;
+ }
+ evsel->tp_format = tp_format;
+@@ -2750,8 +2751,8 @@ retry_open:
+ PERF_EVENT_IOC_SET_BPF,
+ bpf_fd);
+ if (err && errno != EEXIST) {
+- pr_err("failed to attach bpf fd %d: %s\n",
+- bpf_fd, strerror(errno));
++ pr_err("failed to attach bpf fd %d: %m\n",
++ bpf_fd);
+ err = -EINVAL;
+ goto out_close;
+ }
+@@ -3815,7 +3816,6 @@ int evsel__open_strerror(struct evsel *e
+ int err, char *msg, size_t size)
+ {
+ struct perf_pmu *pmu;
+- char sbuf[STRERR_BUFSIZE];
+ int printed = 0, enforced = 0;
+ int ret;
+
+@@ -3948,10 +3948,11 @@ int evsel__open_strerror(struct evsel *e
+ if (ret)
+ return ret;
+
++ errno = err;
+ return scnprintf(msg, size,
+- "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
+- "\"dmesg | grep -i perf\" may provide additional information.\n",
+- err, str_error_r(err, sbuf, sizeof(sbuf)), evsel__name(evsel));
++ "The sys_perf_event_open() syscall failed for event (%s): %m\n"
++ "\"dmesg | grep -i perf\" may provide additional information.\n",
++ evsel__name(evsel));
+ }
+
+ struct perf_session *evsel__session(struct evsel *evsel)
+--- a/tools/perf/util/jitdump.c
++++ b/tools/perf/util/jitdump.c
+@@ -90,7 +90,8 @@ jit_emit_elf(struct jit_buf_desc *jd,
+ saved_errno = errno;
+ nsinfo__mountns_exit(&nsc);
+ if (fd == -1) {
+- pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(saved_errno));
++ errno = saved_errno;
++ pr_warning("cannot create jit ELF %s: %m\n", filename);
+ return -1;
+ }
+
+--- a/tools/perf/util/lzma.c
++++ b/tools/perf/util/lzma.c
+@@ -59,7 +59,7 @@ int lzma_decompress_stream_to_file(FILE
+ strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
+
+ if (ferror(infile)) {
+- pr_debug("lzma: read error: %s\n", strerror(errno));
++ pr_debug("lzma: read error: %m\n");
+ goto err_lzma_end;
+ }
+
+@@ -73,7 +73,7 @@ int lzma_decompress_stream_to_file(FILE
+ ssize_t write_size = sizeof(buf_out) - strm.avail_out;
+
+ if (writen(output_fd, buf_out, write_size) != write_size) {
+- pr_debug("lzma: write error: %s\n", strerror(errno));
++ pr_debug("lzma: write error: %m\n");
+ goto err_lzma_end;
+ }
+
+@@ -103,7 +103,7 @@ int lzma_decompress_to_file(const char *
+
+ infile = fopen(input, "rb");
+ if (!infile) {
+- pr_debug("lzma: fopen failed on %s: '%s'\n", input, strerror(errno));
++ pr_debug("lzma: fopen failed on %s: '%m'\n", input);
+ return -1;
+ }
+
+--- a/tools/perf/util/session.c
++++ b/tools/perf/util/session.c
+@@ -2186,9 +2186,10 @@ reader__read_event(struct reader *rd, st
+
+ if (size < sizeof(struct perf_event_header) ||
+ (skip = rd->process(session, event, rd->file_pos, rd->path)) < 0) {
+- pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%s]\n",
++ errno = -skip;
++ pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%m]\n",
+ rd->file_offset + rd->head, event->header.size,
+- event->header.type, strerror(-skip));
++ event->header.type);
+ err = skip;
+ goto out;
+ }
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1102,14 +1102,14 @@ static Elf *read_gnu_debugdata(struct ds
+
+ wrapped = fmemopen(scn_data->d_buf, scn_data->d_size, "r");
+ if (!wrapped) {
+- pr_debug("%s: fmemopen: %s\n", __func__, strerror(errno));
++ pr_debug("%s: fmemopen: %m\n", __func__);
+ *dso__load_errno(dso) = -errno;
+ return NULL;
+ }
+
+ temp_fd = mkstemp(temp_filename);
+ if (temp_fd < 0) {
+- pr_debug("%s: mkstemp: %s\n", __func__, strerror(errno));
++ pr_debug("%s: mkstemp: %m\n", __func__);
+ *dso__load_errno(dso) = -errno;
+ fclose(wrapped);
+ return NULL;