[PATCH v2 0/6] perf Cross platform KVM support

Ian Rogers posted 6 patches 6 days, 14 hours ago
There is a newer version of this series
tools/perf/Makefile.config                    |   4 -
tools/perf/arch/arm64/Makefile                |   1 -
tools/perf/arch/arm64/util/Build              |   1 -
tools/perf/arch/loongarch/Makefile            |   1 -
tools/perf/arch/loongarch/util/Build          |   1 -
tools/perf/arch/powerpc/Makefile              |   1 -
tools/perf/arch/powerpc/util/Build            |   1 -
tools/perf/arch/riscv/Makefile                |   1 -
tools/perf/arch/riscv/util/Build              |   2 -
tools/perf/arch/s390/Makefile                 |   1 -
tools/perf/arch/s390/util/Build               |   1 -
tools/perf/arch/x86/Makefile                  |   1 -
tools/perf/arch/x86/util/Build                |   1 -
tools/perf/builtin-kvm.c                      |  73 +++---
tools/perf/builtin-report.c                   |   4 +-
tools/perf/builtin-script.c                   |   6 +-
tools/perf/tests/shell/kvm.sh                 |  30 ++-
tools/perf/util/Build                         |   3 +-
tools/perf/util/env.h                         |   3 +
tools/perf/util/evsel.c                       |   6 +-
tools/perf/util/evsel.h                       |   1 +
tools/perf/util/header.c                      |  33 +++
tools/perf/util/header.h                      |   1 +
tools/perf/util/kvm-stat-arch/Build           |   6 +
.../kvm-stat-arch}/arm64_exception_types.h    |   0
.../kvm-stat-arch}/book3s_hcalls.h            |   0
.../kvm-stat-arch}/book3s_hv_exits.h          |   0
.../kvm-stat-arch/kvm-stat-arm64.c}           |  43 ++--
.../kvm-stat-arch/kvm-stat-loongarch.c}       |  48 ++--
.../kvm-stat-arch/kvm-stat-powerpc.c}         |  61 ++---
.../kvm-stat-arch/kvm-stat-riscv.c}           |  42 ++--
.../kvm-stat-arch/kvm-stat-s390.c}            |  38 ++--
.../kvm-stat-arch/kvm-stat-x86.c}             |  44 ++--
.../kvm-stat-arch}/riscv_trap_types.h         |   2 +-
tools/perf/util/kvm-stat.c                    | 215 +++++++++++++++++-
tools/perf/util/kvm-stat.h                    |  70 ++++--
.../scripting-engines/trace-event-python.c    |   8 +-
tools/perf/util/session.c                     |  62 ++++-
tools/perf/util/session.h                     |   2 +-
tools/perf/util/thread.c                      |   5 +
40 files changed, 606 insertions(+), 217 deletions(-)
create mode 100644 tools/perf/util/kvm-stat-arch/Build
rename tools/perf/{arch/arm64/util => util/kvm-stat-arch}/arm64_exception_types.h (100%)
rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hcalls.h (100%)
rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hv_exits.h (100%)
rename tools/perf/{arch/arm64/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-arm64.c} (62%)
rename tools/perf/{arch/loongarch/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-loongarch.c} (77%)
rename tools/perf/{arch/powerpc/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-powerpc.c} (78%)
rename tools/perf/{arch/riscv/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-riscv.c} (57%)
rename tools/perf/{arch/s390/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-s390.c} (77%)
rename tools/perf/{arch/x86/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-x86.c} (88%)
rename tools/perf/{arch/riscv/util => util/kvm-stat-arch}/riscv_trap_types.h (96%)
[PATCH v2 0/6] perf Cross platform KVM support
Posted by Ian Rogers 6 days, 14 hours ago
The existing perf kvm code is using the arch directory, which means a
data file can only be processed on the same machine type that it was
recorded. Switch to using the ELF machine of the session at runtime to
set up the KVM support, making it cross-architectural. So that the ELF
machine number is available early in initialization add it to the perf
data file header.

v2: Wire up the perf data header to have the e_machine and allow early
    initialization of the KVM operations based upon it.
v1: https://lore.kernel.org/lkml/20260128074106.788156-1-irogers@google.com/

Ian Rogers (6):
  perf test kvm: Add stat live testing
  perf kvm stat: Remove use of the arch directory
  perf kvm: Wire up e_machine
  perf session: Add e_flags to the e_machine helper
  perf header: Add e_machine/e_flags to the header
  perf thread: Don't require machine to compute the e_machine

 tools/perf/Makefile.config                    |   4 -
 tools/perf/arch/arm64/Makefile                |   1 -
 tools/perf/arch/arm64/util/Build              |   1 -
 tools/perf/arch/loongarch/Makefile            |   1 -
 tools/perf/arch/loongarch/util/Build          |   1 -
 tools/perf/arch/powerpc/Makefile              |   1 -
 tools/perf/arch/powerpc/util/Build            |   1 -
 tools/perf/arch/riscv/Makefile                |   1 -
 tools/perf/arch/riscv/util/Build              |   2 -
 tools/perf/arch/s390/Makefile                 |   1 -
 tools/perf/arch/s390/util/Build               |   1 -
 tools/perf/arch/x86/Makefile                  |   1 -
 tools/perf/arch/x86/util/Build                |   1 -
 tools/perf/builtin-kvm.c                      |  73 +++---
 tools/perf/builtin-report.c                   |   4 +-
 tools/perf/builtin-script.c                   |   6 +-
 tools/perf/tests/shell/kvm.sh                 |  30 ++-
 tools/perf/util/Build                         |   3 +-
 tools/perf/util/env.h                         |   3 +
 tools/perf/util/evsel.c                       |   6 +-
 tools/perf/util/evsel.h                       |   1 +
 tools/perf/util/header.c                      |  33 +++
 tools/perf/util/header.h                      |   1 +
 tools/perf/util/kvm-stat-arch/Build           |   6 +
 .../kvm-stat-arch}/arm64_exception_types.h    |   0
 .../kvm-stat-arch}/book3s_hcalls.h            |   0
 .../kvm-stat-arch}/book3s_hv_exits.h          |   0
 .../kvm-stat-arch/kvm-stat-arm64.c}           |  43 ++--
 .../kvm-stat-arch/kvm-stat-loongarch.c}       |  48 ++--
 .../kvm-stat-arch/kvm-stat-powerpc.c}         |  61 ++---
 .../kvm-stat-arch/kvm-stat-riscv.c}           |  42 ++--
 .../kvm-stat-arch/kvm-stat-s390.c}            |  38 ++--
 .../kvm-stat-arch/kvm-stat-x86.c}             |  44 ++--
 .../kvm-stat-arch}/riscv_trap_types.h         |   2 +-
 tools/perf/util/kvm-stat.c                    | 215 +++++++++++++++++-
 tools/perf/util/kvm-stat.h                    |  70 ++++--
 .../scripting-engines/trace-event-python.c    |   8 +-
 tools/perf/util/session.c                     |  62 ++++-
 tools/perf/util/session.h                     |   2 +-
 tools/perf/util/thread.c                      |   5 +
 40 files changed, 606 insertions(+), 217 deletions(-)
 create mode 100644 tools/perf/util/kvm-stat-arch/Build
 rename tools/perf/{arch/arm64/util => util/kvm-stat-arch}/arm64_exception_types.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hcalls.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hv_exits.h (100%)
 rename tools/perf/{arch/arm64/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-arm64.c} (62%)
 rename tools/perf/{arch/loongarch/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-loongarch.c} (77%)
 rename tools/perf/{arch/powerpc/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-powerpc.c} (78%)
 rename tools/perf/{arch/riscv/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-riscv.c} (57%)
 rename tools/perf/{arch/s390/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-s390.c} (77%)
 rename tools/perf/{arch/x86/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-x86.c} (88%)
 rename tools/perf/{arch/riscv/util => util/kvm-stat-arch}/riscv_trap_types.h (96%)

-- 
2.53.0.rc1.225.gd81095ad13-goog
Re: [PATCH v2 0/6] perf Cross platform KVM support
Posted by Arnaldo Carvalho de Melo 3 days, 20 hours ago
On Sat, Jan 31, 2026 at 12:02:18PM -0800, Ian Rogers wrote:
> The existing perf kvm code is using the arch directory, which means a
> data file can only be processed on the same machine type that it was
> recorded. Switch to using the ELF machine of the session at runtime to
> set up the KVM support, making it cross-architectural. So that the ELF
> machine number is available early in initialization add it to the perf
> data file header.
> 
> v2: Wire up the perf data header to have the e_machine and allow early
>     initialization of the KVM operations based upon it.
> v1: https://lore.kernel.org/lkml/20260128074106.788156-1-irogers@google.com/

Thanks, applied to perf-tools-next,

- Arnaldo
 
> Ian Rogers (6):
>   perf test kvm: Add stat live testing
>   perf kvm stat: Remove use of the arch directory
>   perf kvm: Wire up e_machine
>   perf session: Add e_flags to the e_machine helper
>   perf header: Add e_machine/e_flags to the header
>   perf thread: Don't require machine to compute the e_machine
> 
>  tools/perf/Makefile.config                    |   4 -
>  tools/perf/arch/arm64/Makefile                |   1 -
>  tools/perf/arch/arm64/util/Build              |   1 -
>  tools/perf/arch/loongarch/Makefile            |   1 -
>  tools/perf/arch/loongarch/util/Build          |   1 -
>  tools/perf/arch/powerpc/Makefile              |   1 -
>  tools/perf/arch/powerpc/util/Build            |   1 -
>  tools/perf/arch/riscv/Makefile                |   1 -
>  tools/perf/arch/riscv/util/Build              |   2 -
>  tools/perf/arch/s390/Makefile                 |   1 -
>  tools/perf/arch/s390/util/Build               |   1 -
>  tools/perf/arch/x86/Makefile                  |   1 -
>  tools/perf/arch/x86/util/Build                |   1 -
>  tools/perf/builtin-kvm.c                      |  73 +++---
>  tools/perf/builtin-report.c                   |   4 +-
>  tools/perf/builtin-script.c                   |   6 +-
>  tools/perf/tests/shell/kvm.sh                 |  30 ++-
>  tools/perf/util/Build                         |   3 +-
>  tools/perf/util/env.h                         |   3 +
>  tools/perf/util/evsel.c                       |   6 +-
>  tools/perf/util/evsel.h                       |   1 +
>  tools/perf/util/header.c                      |  33 +++
>  tools/perf/util/header.h                      |   1 +
>  tools/perf/util/kvm-stat-arch/Build           |   6 +
>  .../kvm-stat-arch}/arm64_exception_types.h    |   0
>  .../kvm-stat-arch}/book3s_hcalls.h            |   0
>  .../kvm-stat-arch}/book3s_hv_exits.h          |   0
>  .../kvm-stat-arch/kvm-stat-arm64.c}           |  43 ++--
>  .../kvm-stat-arch/kvm-stat-loongarch.c}       |  48 ++--
>  .../kvm-stat-arch/kvm-stat-powerpc.c}         |  61 ++---
>  .../kvm-stat-arch/kvm-stat-riscv.c}           |  42 ++--
>  .../kvm-stat-arch/kvm-stat-s390.c}            |  38 ++--
>  .../kvm-stat-arch/kvm-stat-x86.c}             |  44 ++--
>  .../kvm-stat-arch}/riscv_trap_types.h         |   2 +-
>  tools/perf/util/kvm-stat.c                    | 215 +++++++++++++++++-
>  tools/perf/util/kvm-stat.h                    |  70 ++++--
>  .../scripting-engines/trace-event-python.c    |   8 +-
>  tools/perf/util/session.c                     |  62 ++++-
>  tools/perf/util/session.h                     |   2 +-
>  tools/perf/util/thread.c                      |   5 +
>  40 files changed, 606 insertions(+), 217 deletions(-)
>  create mode 100644 tools/perf/util/kvm-stat-arch/Build
>  rename tools/perf/{arch/arm64/util => util/kvm-stat-arch}/arm64_exception_types.h (100%)
>  rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hcalls.h (100%)
>  rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hv_exits.h (100%)
>  rename tools/perf/{arch/arm64/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-arm64.c} (62%)
>  rename tools/perf/{arch/loongarch/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-loongarch.c} (77%)
>  rename tools/perf/{arch/powerpc/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-powerpc.c} (78%)
>  rename tools/perf/{arch/riscv/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-riscv.c} (57%)
>  rename tools/perf/{arch/s390/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-s390.c} (77%)
>  rename tools/perf/{arch/x86/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-x86.c} (88%)
>  rename tools/perf/{arch/riscv/util => util/kvm-stat-arch}/riscv_trap_types.h (96%)
> 
> -- 
> 2.53.0.rc1.225.gd81095ad13-goog
>
Re: [PATCH v2 0/6] perf Cross platform KVM support
Posted by Arnaldo Carvalho de Melo 3 days, 19 hours ago
On Tue, Feb 03, 2026 at 11:42:44AM -0300, Arnaldo Carvalho de Melo wrote:
> On Sat, Jan 31, 2026 at 12:02:18PM -0800, Ian Rogers wrote:
> > The existing perf kvm code is using the arch directory, which means a
> > data file can only be processed on the same machine type that it was
> > recorded. Switch to using the ELF machine of the session at runtime to
> > set up the KVM support, making it cross-architectural. So that the ELF
> > machine number is available early in initialization add it to the perf
> > data file header.
> > 
> > v2: Wire up the perf data header to have the e_machine and allow early
> >     initialization of the KVM operations based upon it.
> > v1: https://lore.kernel.org/lkml/20260128074106.788156-1-irogers@google.com/
> 
> Thanks, applied to perf-tools-next,

Removing it for now, the static build is failing, please take a look,

- Arnaldo

                 make_static: cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1 -j32  DESTDIR=/tmp/tmp.XNUPlEfJN3
cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1 -j32 DESTDIR=/tmp/tmp.XNUPlEfJN3
  BUILD:   Doing 'make -j32' parallel build
Warning: Kernel ABI header differences:
  diff -u tools/arch/arm64/include/asm/cputype.h arch/arm64/include/asm/cputype.h
  diff -u tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
Makefile.config:703: Warning: Disabled BPF skeletons as libelf is required by bpftool
Makefile.config:747: Disabling post unwind, no support found.
Makefile.config:794: slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev
Makefile.config:871: No 'Python.h' was found: disables Python support - please install python-devel/python-dev
Makefile.config:963: No libllvm 13+ found, slower source file resolution, please install llvm-devel/llvm-dev
Makefile.config:1009: No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev
Makefile.config:1022: No libzstd found, disables trace compression, please install libzstd-dev[el] and/or set LIBZSTD_DIR
Makefile.config:1035: No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev
Makefile.config:1082: No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev
Makefile.config:1098: No libcapstone found, disables disasm engine support for 'perf script', please install libcapstone-dev/capstone-devel
Makefile.config:1147: libpfm4 not found, disables libpfm4 support. Please install libpfm-devel or libpfm4-dev

Auto-detecting system features:
...                                   libdw: [ OFF ]
...                                   glibc: [ on  ]
...                                  libelf: [ OFF ]
...                                 libnuma: [ OFF ]
...                  numa_num_possible_cpus: [ OFF ]
...                               libpython: [ OFF ]
...                             libcapstone: [ OFF ]
...                               llvm-perf: [ OFF ]
...                                    zlib: [ OFF ]
...                                    lzma: [ OFF ]
...                                     bpf: [ on  ]
...                                  libaio: [ on  ]
...                                 libzstd: [ OFF ]
...                              libopenssl: [ OFF ]

  CC      dlfilters/dlfilter-test-api-v0.o
  CC      dlfilters/dlfilter-test-api-v2.o
  CC      dlfilters/dlfilter-show-cycles.o
  GEN     /home/acme/git/perf-tools-next/tools/perf/arch/arm64/include/generated/asm/sysreg-defs.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/exec-cmd.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/help.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/pager.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/parse-options.h
  PERF_VERSION = 6.19.rc7.gd0144158c595
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/run-command.h
  GEN     perf-archive
  GEN     perf-iostat
  INSTALL libsubcmd_headers
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/core.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/bpf_perf.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/threadmap.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/cpumap.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/evlist.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/core.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/cpumap.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/evsel.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/event.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/mmap.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v15.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v16.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/threadmap.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v17.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/evsel.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/cpumap.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libsymbol/include/symbol/kallsyms.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/evlist.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/evlist.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/evsel.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libsymbol/kallsyms.o
  MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fd/
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/lib.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/cpu.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/debug.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/mmap.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/io.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/cpu.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/io_dir.h
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/rc_check.h
  MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fd/array.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/mmap.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fd/array.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/debug.o
  INSTALL libsymbol_headers
  MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/threadmap.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/str_error_r.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fs/fs.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/zalloc.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/fs.o
  MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fs/tracing_path.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/xyarray.o
  INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/xyarray.h
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/tracing_path.o
  LINK    dlfilters/dlfilter-show-cycles.so
  CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/cgroup.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libperf/lib.o
  INSTALL libperf_headers
  INSTALL libapi_headers
  LINK    dlfilters/dlfilter-test-api-v0.so
  LINK    dlfilters/dlfilter-test-api-v2.so
  LD      /home/acme/git/perf-tools-next/tools/perf/libapi/fd/libapi-in.o
  LD      /home/acme/git/perf-tools-next/tools/perf/libsymbol/libsymbol-in.o
  AR      /home/acme/git/perf-tools-next/tools/perf/libsymbol/libsymbol.a
  LD      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/libapi-in.o
  LD      /home/acme/git/perf-tools-next/tools/perf/libapi/libapi-in.o
  AR      /home/acme/git/perf-tools-next/tools/perf/libapi/libapi.a
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/exec-cmd.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/help.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/pager.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/parse-options.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/run-command.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/sigchain.o
  CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/subcmd-config.o
  LD      /home/acme/git/perf-tools-next/tools/perf/libperf/libperf-in.o
  AR      /home/acme/git/perf-tools-next/tools/perf/libperf/libperf.a
  LD      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/libsubcmd-in.o
  AR      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/libsubcmd.a
  CC      builtin-bench.o
  CC      builtin-annotate.o
  CC      bench/sched-messaging.o
  CC      ui/setup.o
  CC      bench/sched-pipe.o
  CC      ui/helpline.o
  CC      tests/builtin-test.o
  CC      builtin-check.o
  CC      bench/sched-seccomp-notify.o
  CC      tests/tests-scripts.o
  CC      builtin-config.o
  CC      ui/progress.o
  CC      bench/syscall.o
  CC      builtin-diff.o
  CC      tests/parse-events.o
  LD      scripts/perf-util-in.o
  CC      arch/common.o
  CC      bench/mem-functions.o
  CC      ui/util.o
  CC      tests/dso-data.o
  CC      builtin-evlist.o
  CC      builtin-ftrace.o
  CC      tests/vmlinux-kallsyms.o
  CC      bench/futex.o
  CC      ui/hist.o
  CC      bench/futex-hash.o
  CC      builtin-help.o
  CC      bench/futex-wake.o
  CC      arch/x86/tests/arch-tests.o
  CC      arch/x86/util/header.o
  CC      arch/x86/tests/hybrid.o
  CC      ui/stdio/hist.o
  CC      util/annotate-arch/annotate-arc.o
  CC      util/annotate-arch/annotate-arm.o
  CC      bench/futex-wake-parallel.o
  CC      arch/x86/tests/intel-pt-test.o
  CC      arch/x86/tests/bp-modify.o
  CC      arch/x86/tests/amd-ibs-via-core-pmu.o
  CC      arch/x86/util/tsc.o
  CC      arch/x86/util/pmu.o
  CC      tests/openat-syscall.o
  CC      tests/openat-syscall-all-cpus.o
  CC      tests/mmap-basic.o
  CC      tests/perf-record.o
  GEN     pmu-events/arch/x86/amdzen1/extra-metrics.json
  CC      util/annotate-arch/annotate-arm64.o
  CC      util/annotate-arch/annotate-csky.o
  GEN     pmu-events/arch/x86/amdzen2/extra-metrics.json
  CC      tests/evsel-roundtrip-name.o
  GEN     pmu-events/arch/x86/amdzen3/extra-metrics.json
  CC      util/annotate-arch/annotate-loongarch.o
  CC      arch/x86/tests/amd-ibs-period.o
  CC      util/perf-regs-arch/perf_regs_aarch64.o
  CC      builtin-buildid-list.o
  CC      arch/x86/tests/topdown.o
  CC      tests/fdarray.o
  GEN     pmu-events/arch/x86/amdzen4/extra-metrics.json
  CC      arch/x86/util/perf_regs.o
  LD      util/kvm-stat-arch/perf-util-in.o
  GEN     pmu-events/arch/x86/amdzen5/extra-metrics.json
  CC      util/perf-regs-arch/perf_regs_arm.o
  CC      bench/futex-requeue.o
  CC      util/annotate-arch/annotate-mips.o
  CC      util/annotate-arch/annotate-powerpc.o
  CC      util/annotate-arch/annotate-x86.o
  CC      util/intel-pt-decoder/intel-pt-pkt-decoder.o
  GEN     pmu-events/arch/x86/amdzen6/extra-metrics.json
  CC      arch/x86/util/topdown.o
  CC      util/arm-spe-decoder/arm-spe-pkt-decoder.o
  CC      util/perf-regs-arch/perf_regs_csky.o
  CC      util/perf-regs-arch/perf_regs_loongarch.o
  CC      util/perf-regs-arch/perf_regs_mips.o
  CC      util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.o
  CC      arch/x86/util/machine.o
  GEN     pmu-events/arch/x86/amdzen1/extra-metricgroups.json
  CC      bench/futex-lock-pi.o
  CC      util/arm-spe-decoder/arm-spe-decoder.o
  CC      builtin-buildid-cache.o
  GEN     pmu-events/arch/x86/amdzen2/extra-metricgroups.json
  CC      util/perf-regs-arch/perf_regs_powerpc.o
  CC      bench/epoll-wait.o
  CC      util/perf-regs-arch/perf_regs_riscv.o
  LD      util/scripting-engines/perf-util-in.o
  GEN     pmu-events/arch/x86/amdzen3/extra-metricgroups.json
  CC      util/annotate-arch/annotate-riscv64.o
  CC      util/perf-regs-arch/perf_regs_s390.o
  CC      arch/x86/util/event.o
  CC      util/annotate-arch/annotate-s390.o
  CC      tests/pmu.o
  LD      util/hisi-ptt-decoder/perf-util-in.o
  CC      tests/pmu-events.o
  CC      util/arm64-frame-pointer-unwind-support.o
  CC      tests/hists_common.o
  CC      util/perf-regs-arch/perf_regs_x86.o
  GEN     pmu-events/arch/x86/amdzen4/extra-metricgroups.json
  CC      util/intel-pt-decoder/intel-pt-insn-decoder.o
  CC      util/intel-pt-decoder/intel-pt-log.o
  CC      bench/epoll-ctl.o
  CC      util/addr2line.o
  CC      util/addr_location.o
  CC      tests/hists_link.o
  LD      util/perf-regs-arch/perf-util-in.o
  CC      util/intel-pt-decoder/intel-pt-decoder.o
  GEN     util/intel-pt-decoder/inat-tables.c
  CC      arch/x86/util/evlist.o
  GEN     pmu-events/arch/x86/amdzen5/extra-metricgroups.json
  GEN     pmu-events/arch/x86/amdzen6/extra-metricgroups.json
  CC      bench/synthesize.o
  LD      util/arm-spe-decoder/perf-util-in.o
  CC      bench/kallsyms-parse.o
  CC      tests/hists_filter.o
  CC      util/annotate-arch/annotate-sparc.o
  CC      tests/hists_output.o
  CC      arch/x86/util/mem-events.o
  LD      arch/x86/tests/perf-test-in.o
  CC      arch/x86/util/evsel.o
  LD      arch/x86/perf-test-in.o
  CC      bench/find-bit-bench.o
  CC      builtin-kallsyms.o
  LD      arch/perf-test-in.o
  CC      builtin-list.o
  CC      builtin-record.o
  GEN     pmu-events/arch/arm64/arm/cortex-a34/extra-metrics.json
  CC      util/intel-pt-decoder/insn.o
  CC      util/intel-pt-decoder/inat.o
  CC      util/annotate.o
  CC      bench/inject-buildid.o
  CC      tests/hists_cumulate.o
  LD      util/annotate-arch/perf-util-in.o
  CC      tests/bp_signal.o
  CC      builtin-report.o
  CC      builtin-stat.o
  CC      bench/evlist-open-close.o
  CC      bench/breakpoint.o
  CC      bench/pmu-scan.o
  CC      util/blake2s.o
  GEN     pmu-events/arch/arm64/arm/cortex-a35/extra-metrics.json
  CC      bench/uprobe.o
  CC      tests/bp_signal_overflow.o
  CC      arch/x86/util/iostat.o
  CC      builtin-top.o
  CC      util/block-info.o
  CC      util/block-range.o
  GEN     pmu-events/arch/arm64/arm/cortex-a510/extra-metrics.json
  CC      bench/mem-memcpy-x86-64-asm.o
  GEN     pmu-events/arch/arm64/arm/cortex-a53/extra-metrics.json
  CC      builtin-script.o
  CC      arch/x86/util/auxtrace.o
  CC      util/build-id.o
  CC      builtin-kvm.o
  CC      bench/mem-memset-x86-64-asm.o
  CC      builtin-inject.o
  CC      tests/bp_account.o
  CC      arch/x86/util/intel-pt.o
  CC      util/cacheline.o
  CC      builtin-mem.o
  GEN     pmu-events/arch/arm64/arm/cortex-a55/extra-metrics.json
  CC      tests/wp.o
  CC      arch/x86/util/intel-bts.o
  CC      tests/task-exit.o
  CC      builtin-data.o
  LD      bench/perf-bench-in.o
  CC      builtin-version.o
  LD      perf-bench-in.o
  CC      builtin-c2c.o
  GEN     pmu-events/arch/arm64/arm/cortex-a57-a72/extra-metrics.json
  CC      builtin-daemon.o
  AR      libperf-bench.a
  CC      util/config.o
  CC      util/copyfile.o
  CC      perf.o
  GEN     pmu-events/arch/arm64/arm/cortex-a65-e1/extra-metrics.json
  LD      arch/perf-in.o
  CC      tests/sw-clock.o
  CC      tests/mmap-thread-lookup.o
  GEN     pmu-events/arch/arm64/arm/cortex-a710/extra-metrics.json
  CC      tests/thread-maps-share.o
  CC      tests/keep-tracking.o
  CC      util/ctype.o
  CC      util/db-export.o
  GEN     pmu-events/arch/arm64/arm/cortex-a73/extra-metrics.json
  CC      util/disasm.o
  CC      tests/code-reading.o
  CC      tests/sample-parsing.o
  CC      tests/parse-no-sample-id-all.o
  GEN     pmu-events/arch/arm64/arm/cortex-a75/extra-metrics.json
  CC      tests/kmod-path.o
  CC      util/env.o
  CC      tests/thread-map.o
  GEN     pmu-events/arch/arm64/arm/cortex-a76/extra-metrics.json
  CC      util/event.o
  CC      util/evlist.o
  CC      util/sideband_evlist.o
  CC      tests/topology.o
  GEN     pmu-events/arch/arm64/arm/cortex-a77/extra-metrics.json
  CC      util/evsel.o
  CC      tests/mem.o
  CC      util/evsel_fprintf.o
  CC      util/perf_event_attr_fprintf.o
  CC      util/evswitch.o
  CC      util/find_bit.o
  GEN     pmu-events/arch/arm64/arm/cortex-a78/extra-metrics.json
  CC      tests/cpumap.o
  CC      util/levenshtein.o
  CC      tests/stat.o
  GEN     pmu-events/arch/arm64/arm/cortex-x1/extra-metrics.json
  CC      util/llvm.o
  CXX     util/llvm-c-helpers.o
  GEN     pmu-events/arch/arm64/arm/cortex-x2/extra-metrics.json
  CC      util/mmap.o
  CC      tests/event_update.o
  CC      tests/event-times.o
  CC      tests/expr.o
  CC      util/memswap.o
  BISON   util/parse-events-bison.c
  LD      arch/x86/util/perf-util-in.o
  LD      arch/x86/perf-util-in.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n1/extra-metrics.json
  LD      arch/perf-util-in.o
  CC      tests/backward-ring-buffer.o
  CC      tests/sdt.o
  CC      tests/is_printable_array.o
  CC      util/print-events.o
  CC      tests/bitmap.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n2-v2/extra-metrics.json
  CC      tests/perf-hooks.o
  CC      util/tracepoint.o
  CC      tests/unit_number__scnprintf.o
  CC      util/perf_regs.o
  CC      util/path.o
  CC      util/print_binary.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n3/extra-metrics.json
  CC      tests/mem2node.o
  CC      tests/maps.o
  CC      tests/time-utils-test.o
  CC      util/print_insn.o
  CC      tests/genelf.o
  CC      tests/api-io.o
  CC      util/rlimit.o
  CC      util/argv_split.o
  CC      tests/demangle-java-test.o
  GEN     pmu-events/arch/arm64/arm/neoverse-v1/extra-metrics.json
  GEN     pmu-events/arch/arm64/arm/neoverse-v3/extra-metrics.json
  CC      util/rbtree.o
  CC      util/libstring.o
  CC      tests/demangle-ocaml-test.o
  CC      tests/demangle-rust-v0-test.o
  CC      tests/pfm.o
  CC      tests/parse-metric.o
  CC      tests/pe-file-parsing.o
  CC      util/bitmap.o
  CC      tests/expand-cgroup.o
  GEN     pmu-events/arch/arm64/arm/cortex-a34/extra-metricgroups.json
  CC      util/hweight.o
  CC      tests/perf-time-to-tsc.o
  GEN     pmu-events/arch/arm64/arm/cortex-a35/extra-metricgroups.json
  CC      util/smt.o
  CC      tests/dlfilter-test.o
  CC      tests/sigtrap.o
  GEN     pmu-events/arch/arm64/arm/cortex-a510/extra-metricgroups.json
  CC      util/strbuf.o
  CC      tests/event_groups.o
  CC      tests/symbols.o
  CC      tests/util.o
  GEN     pmu-events/arch/arm64/arm/cortex-a53/extra-metricgroups.json
  CC      tests/hwmon_pmu.o
  CC      util/string.o
  GEN     pmu-events/arch/arm64/arm/cortex-a55/extra-metricgroups.json
  CC      tests/tool_pmu.o
  CC      util/strlist.o
  CC      util/strfilter.o
  GEN     pmu-events/arch/arm64/arm/cortex-a57-a72/extra-metricgroups.json
  CC      util/top.o
  GEN     pmu-events/arch/arm64/arm/cortex-a65-e1/extra-metricgroups.json
  CC      util/usage.o
  CC      util/dso.o
  CC      tests/subcmd-help.o
  CC      tests/kallsyms-split.o
  GEN     pmu-events/arch/arm64/arm/cortex-a710/extra-metricgroups.json
  CC      tests/workloads/noploop.o
  CC      util/dsos.o
  CC      util/symbol.o
  GEN     pmu-events/arch/arm64/arm/cortex-a73/extra-metricgroups.json
  CC      util/symbol_fprintf.o
  CC      util/map_symbol.o
  CC      tests/workloads/thloop.o
  CC      tests/workloads/leafloop.o
  GEN     pmu-events/arch/arm64/arm/cortex-a75/extra-metricgroups.json
  CC      util/color.o
  CC      util/color_config.o
  LD      util/intel-pt-decoder/perf-util-in.o
  CC      tests/workloads/sqrtloop.o
  GEN     pmu-events/arch/arm64/arm/cortex-a76/extra-metricgroups.json
  CC      tests/workloads/brstack.o
  CC      tests/workloads/datasym.o
  CC      tests/workloads/landlock.o
  CC      tests/workloads/traploop.o
  CC      tests/workloads/inlineloop.o
  GEN     pmu-events/arch/arm64/arm/cortex-a77/extra-metricgroups.json
  CC      util/metricgroup.o
  CC      util/header.o
  CC      util/callchain.o
  CC      util/values.o
  GEN     pmu-events/arch/arm64/arm/cortex-a78/extra-metricgroups.json
  CC      util/fncache.o
  CC      util/debug.o
  CC      util/machine.o
  CC      util/map.o
  GEN     pmu-events/arch/arm64/arm/cortex-x1/extra-metricgroups.json
  CC      util/maps.o
  CC      util/pstack.o
  GEN     pmu-events/arch/arm64/arm/cortex-x2/extra-metricgroups.json
  CC      util/session.o
  CC      util/tool.o
  CC      util/sample.o
  CC      util/sample-raw.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n1/extra-metricgroups.json
  CC      util/s390-sample-raw.o
  CC      util/amd-sample-raw.o
  LD      tests/workloads/perf-test-in.o
  LD      tests/perf-test-in.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n2-v2/extra-metricgroups.json
  LD      perf-test-in.o
  CC      util/ordered-events.o
  GEN     pmu-events/arch/arm64/arm/neoverse-n3/extra-metricgroups.json
  CC      util/namespaces.o
  CC      util/comm.o
  AR      libperf-test.a
  GEN     pmu-events/arch/arm64/arm/neoverse-v1/extra-metricgroups.json
  CC      util/thread.o
  CC      util/threads.o
  CC      util/thread_map.o
  CC      util/parse-events-bison.o
  GEN     pmu-events/arch/arm64/arm/neoverse-v3/extra-metricgroups.json
  BISON   util/pmu-bison.c
  GEN     pmu-events/arch/x86/alderlake/extra-metrics.json
  CC      util/pmus.o
  CC      util/drm_pmu.o
  GEN     pmu-events/arch/x86/alderlaken/extra-metrics.json
  GEN     pmu-events/arch/x86/arrowlake/extra-metrics.json
  CC      util/hwmon_pmu.o
  GEN     pmu-events/arch/x86/bonnell/extra-metrics.json
  CC      util/tool_pmu.o
  GEN     pmu-events/arch/x86/broadwell/extra-metrics.json
  CC      util/tp_pmu.o
  GEN     pmu-events/arch/x86/broadwellde/extra-metrics.json
  GEN     pmu-events/arch/x86/broadwellx/extra-metrics.json
  GEN     pmu-events/arch/x86/cascadelakex/extra-metrics.json
  CC      util/svghelper.o
  CC      util/trace-event-info.o
  GEN     pmu-events/arch/x86/clearwaterforest/extra-metrics.json
  CC      util/trace-event-scripting.o
  GEN     pmu-events/arch/x86/elkhartlake/extra-metrics.json
  LD      ui/perf-ui-in.o
  LD      perf-ui-in.o
  GEN     pmu-events/arch/x86/emeraldrapids/extra-metrics.json
  CC      util/sort.o
  GEN     pmu-events/arch/x86/goldmont/extra-metrics.json
  GEN     pmu-events/arch/x86/goldmontplus/extra-metrics.json
  AR      libperf-ui.a
  CC      util/hist.o
  GEN     pmu-events/arch/x86/grandridge/extra-metrics.json
  CC      util/util.o
  CC      util/cpumap.o
  CC      util/affinity.o
  CC      util/cputopo.o
  GEN     pmu-events/arch/x86/graniterapids/extra-metrics.json
  GEN     pmu-events/arch/x86/haswell/extra-metrics.json
  CC      util/cgroup.o
  GEN     pmu-events/arch/x86/haswellx/extra-metrics.json
  CC      util/target.o
  GEN     pmu-events/arch/x86/icelake/extra-metrics.json
  CC      util/rblist.o
  CC      util/intlist.o
  CC      util/vdso.o
  GEN     pmu-events/arch/x86/icelakex/extra-metrics.json
  CC      util/counts.o
  CC      util/stat.o
  GEN     pmu-events/arch/x86/ivybridge/extra-metrics.json
  CC      util/stat-shadow.o
  GEN     pmu-events/arch/x86/ivytown/extra-metrics.json
  GEN     pmu-events/arch/x86/jaketown/extra-metrics.json
  GEN     pmu-events/arch/x86/knightslanding/extra-metrics.json
  CC      util/stat-display.o
  GEN     pmu-events/arch/x86/lunarlake/extra-metrics.json
  CC      util/perf_api_probe.o
  CC      util/record.o
  CC      util/srcline.o
  CC      util/srccode.o
  GEN     pmu-events/arch/x86/meteorlake/extra-metrics.json
  CC      util/synthetic-events.o
  CC      util/data.o
  CC      util/tsc.o
  GEN     pmu-events/arch/x86/nehalemep/extra-metrics.json
  GEN     pmu-events/arch/x86/nehalemex/extra-metrics.json
  GEN     pmu-events/arch/x86/pantherlake/extra-metrics.json
  CC      util/cloexec.o
  GEN     pmu-events/arch/x86/rocketlake/extra-metrics.json
  CC      util/call-path.o
  CC      util/rwsem.o
  CC      util/thread-stack.o
  GEN     pmu-events/arch/x86/sandybridge/extra-metrics.json
  CC      util/spark.o
  GEN     pmu-events/arch/x86/sapphirerapids/extra-metrics.json
  GEN     pmu-events/arch/x86/sierraforest/extra-metrics.json
  CC      util/topdown.o
  CC      util/iostat.o
  GEN     pmu-events/arch/x86/silvermont/extra-metrics.json
  CC      util/stream.o
  GEN     pmu-events/arch/x86/skylake/extra-metrics.json
  CC      util/lock-contention.o
  CC      util/auxtrace.o
  GEN     pmu-events/arch/x86/skylakex/extra-metrics.json
  CC      util/intel-pt.o
  GEN     pmu-events/arch/x86/snowridgex/extra-metrics.json
  CC      util/intel-bts.o
  GEN     pmu-events/arch/x86/tigerlake/extra-metrics.json
  CC      util/arm-spe.o
  CC      util/hisi-ptt.o
  CC      util/s390-cpumsf.o
  CC      util/powerpc-vpadtl.o
  GEN     pmu-events/arch/x86/westmereep-dp/extra-metrics.json
  LD      perf-in.o
  GEN     pmu-events/arch/x86/westmereep-sp/extra-metrics.json
  CC      util/cs-etm-base.o
  CC      util/parse-branch-options.o
  CC      util/dump-insn.o
  GEN     pmu-events/arch/x86/westmereex/extra-metrics.json
  GEN     pmu-events/arch/x86/alderlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/alderlaken/extra-metricgroups.json
  CC      util/parse-regs-options.o
  CC      util/parse-sublevel-options.o
  CC      util/term.o
  CC      util/help-unknown-cmd.o
  CC      util/dlfilter.o
  CC      util/mem-events.o
  GEN     pmu-events/arch/x86/arrowlake/extra-metricgroups.json
  CC      util/mem-info.o
  GEN     pmu-events/arch/x86/bonnell/extra-metricgroups.json
  CC      util/vsprintf.o
  CC      util/units.o
  GEN     pmu-events/arch/x86/broadwell/extra-metricgroups.json
  CC      util/time-utils.o
  BISON   util/expr-bison.c
  CC      util/branch.o
  CC      util/mem2node.o
  GEN     pmu-events/arch/x86/broadwellde/extra-metricgroups.json
  CC      util/clockid.o
  CC      util/list_sort.o
  GEN     pmu-events/arch/x86/broadwellx/extra-metricgroups.json
  CC      util/mutex.o
  GEN     pmu-events/arch/x86/cascadelakex/extra-metricgroups.json
  CC      util/sharded_mutex.o
  CC      util/intel-tpebs.o
  CC      util/hashmap.o
  GEN     pmu-events/arch/x86/clearwaterforest/extra-metricgroups.json
  CC      util/symbol-minimal.o
  CC      util/data-convert-json.o
  CC      util/cap.o
  CC      util/demangle-ocaml.o
  CC      util/demangle-java.o
  GEN     pmu-events/arch/x86/elkhartlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/emeraldrapids/extra-metricgroups.json
  CC      util/demangle-rust-v0.o
  CC      util/perf-hooks.o
  GEN     pmu-events/arch/x86/goldmont/extra-metricgroups.json
  FLEX    util/parse-events-flex.c
  FLEX    util/pmu-flex.c
  CC      util/pmu-bison.o
  FLEX    util/expr-flex.c
  CC      util/expr-bison.o
  CC      util/parse-events.o
  GEN     pmu-events/arch/x86/goldmontplus/extra-metricgroups.json
  CC      util/parse-events-flex.o
  GEN     pmu-events/arch/x86/grandridge/extra-metricgroups.json
  GEN     pmu-events/arch/x86/graniterapids/extra-metricgroups.json
  CC      util/pmu.o
  GEN     pmu-events/arch/x86/haswell/extra-metricgroups.json
  CC      util/pmu-flex.o
  GEN     pmu-events/arch/x86/haswellx/extra-metricgroups.json
  CC      util/expr-flex.o
  CC      util/expr.o
  GEN     pmu-events/arch/x86/icelake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/icelakex/extra-metricgroups.json
  GEN     pmu-events/arch/x86/ivybridge/extra-metricgroups.json
  GEN     pmu-events/arch/x86/ivytown/extra-metricgroups.json
  GEN     pmu-events/arch/x86/jaketown/extra-metricgroups.json
  GEN     pmu-events/arch/x86/knightslanding/extra-metricgroups.json
  GEN     pmu-events/arch/x86/lunarlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/meteorlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/nehalemep/extra-metricgroups.json
  GEN     pmu-events/arch/x86/nehalemex/extra-metricgroups.json
  GEN     pmu-events/arch/x86/pantherlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/rocketlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/sandybridge/extra-metricgroups.json
  GEN     pmu-events/arch/x86/sapphirerapids/extra-metricgroups.json
  GEN     pmu-events/arch/x86/sierraforest/extra-metricgroups.json
  GEN     pmu-events/arch/x86/silvermont/extra-metricgroups.json
  GEN     pmu-events/arch/x86/skylake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/skylakex/extra-metricgroups.json
  GEN     pmu-events/arch/x86/snowridgex/extra-metricgroups.json
  GEN     pmu-events/arch/x86/tigerlake/extra-metricgroups.json
  GEN     pmu-events/arch/x86/westmereep-dp/extra-metricgroups.json
  GEN     pmu-events/arch/x86/westmereep-sp/extra-metricgroups.json
  GEN     pmu-events/arch/x86/westmereex/extra-metricgroups.json
  TEST    pmu-events/metric_test.log
  GEN     pmu-events/test-empty-pmu-events.c
  TEST    pmu-events/empty-pmu-events.log
  GEN     pmu-events/pmu-events.c
  LD      util/perf-util-in.o
  LD      perf-util-in.o
  AR      libperf-util.a
  CC      pmu-events/pmu-events.o
  LD      pmu-events/pmu-events-in.o
  AR      libpmu-events.a
  LINK    perf
/usr/bin/ld: libperf-util.a(perf-util-in.o): in function `symbol__disassemble_llvm':
(.text+0x30712): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: libperf-util.a(perf-util-in.o): in function `parse_uid':
(.text+0xb4cd5): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: (.text+0xb4d3a): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: perf-in.o: in function `cmd_kvm':
(.text+0x37078): undefined reference to `kvm_add_default_arch_event'
/usr/bin/ld: (.text+0x3719c): undefined reference to `kvm_add_default_arch_event'
/usr/bin/ld: (.text+0x3735a): undefined reference to `kvm_add_default_arch_event'
/usr/bin/ld: (.text+0x373bb): undefined reference to `kvm_add_default_arch_event'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile.perf:806: perf] Error 1
make[3]: *** [Makefile.perf:286: sub-make] Error 2
make[2]: *** [Makefile:76: all] Error 2
  test: test -x ./perf
make[1]: *** [tests/make:337: make_static] Error 1
make: *** [Makefile:109: build-test] Error 2
make: Leaving directory '/home/acme/git/perf-tools-next/tools/perf'

real	0m21.807s
user	2m35.853s
sys	0m17.941s
⬢ [acme@toolbx perf-tools-next]$


Re: [PATCH v2 0/6] perf Cross platform KVM support
Posted by Arnaldo Carvalho de Melo 3 days, 19 hours ago
On Tue, Feb 03, 2026 at 11:57:57AM -0300, Arnaldo Carvalho de Melo wrote:
> On Tue, Feb 03, 2026 at 11:42:44AM -0300, Arnaldo Carvalho de Melo wrote:
> > On Sat, Jan 31, 2026 at 12:02:18PM -0800, Ian Rogers wrote:
> > > The existing perf kvm code is using the arch directory, which means a
> > > data file can only be processed on the same machine type that it was
> > > recorded. Switch to using the ELF machine of the session at runtime to
> > > set up the KVM support, making it cross-architectural. So that the ELF
> > > machine number is available early in initialization add it to the perf
> > > data file header.
> > > 
> > > v2: Wire up the perf data header to have the e_machine and allow early
> > >     initialization of the KVM operations based upon it.
> > > v1: https://lore.kernel.org/lkml/20260128074106.788156-1-irogers@google.com/
> > 
> > Thanks, applied to perf-tools-next,
> 
> Removing it for now, the static build is failing, please take a look,

I kept the first patch, additionally:

   8    20.68 alpine:3.19                   : FAIL gcc version 13.2.1 20231014 (Alpine 13.2.1_git20231014)
    util/kvm-stat-arch/kvm-stat-loongarch.c: In function 'event_end':
    util/kvm-stat-arch/kvm-stat-loongarch.c:73:54: error: 'EM_LOONGARCH' undeclared (first use in this function)
       73 |         return evsel__name_is(evsel, kvm_entry_trace(EM_LOONGARCH)) ||
          |                                                      ^~~~~~~~~~~~
    util/kvm-stat-arch/kvm-stat-loongarch.c:73:54: note: each undeclared identifier is reported only once for each function it appears in
    util/kvm-stat-arch/kvm-stat-loongarch.c:75:1: error: control reaches end of non-void function [-Werror=return-type]
       75 | }
          | ^
    cc1: all warnings being treated as errors
    make[4]: *** [/git/perf-6.19.0-rc7/tools/build/Makefile.build:142: kvm-stat-arch] Error 2


Some older distros don't have those EM_ defines, I fixed some in the
past but it would be better to have those conditional defines in a more
centralized place, etc.

On 32-bit arches this also happens:

   In file included from util/kvm-stat-arch/kvm-stat-s390.c:13:
    util/kvm-stat-arch/kvm-stat-s390.c: In function ‘event_icpt_insn_get_key’:
    util/kvm-stat-arch/../../../arch/s390/include/uapi/asm/sie.h:231:15: error: right shift count >= width of type [-Werror=shift-count-overflow]
      231 |         (insn >> 56) == (ipa0) ?                                \
          |               ^~
    util/kvm-stat-arch/../../../arch/s390/include/uapi/asm/sie.h:242:9: note: in expansion of macro ‘INSN_DECODE_IPA0’
      242 |         INSN_DECODE_IPA0(0x01, insn, 48, 0xff)  \
          |         ^~~~~~~~~~~~~~~~
    util/kvm-stat-arch/kvm-stat-s390.c:28:20: note: in expansion of macro ‘icpt_insn_decoder’
       28 |         key->key = icpt_insn_decoder(insn);
          |                    ^~~~~~~~~~~~~~~~~
    util/kvm-stat-arch/../../../arch/s390/include/uapi/asm/sie.h:232:39: error: right shift count >= width of type [-Werror=shift-count-overflow]
      232 |                 ((ipa0 << 8) | ((insn >> rshift) & mask)) :
          |                                       ^~


- Arnaldo
> 
>                  make_static: cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1 -j32  DESTDIR=/tmp/tmp.XNUPlEfJN3
> cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1 -j32 DESTDIR=/tmp/tmp.XNUPlEfJN3
>   BUILD:   Doing 'make -j32' parallel build
> Warning: Kernel ABI header differences:
>   diff -u tools/arch/arm64/include/asm/cputype.h arch/arm64/include/asm/cputype.h
>   diff -u tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
> Makefile.config:703: Warning: Disabled BPF skeletons as libelf is required by bpftool
> Makefile.config:747: Disabling post unwind, no support found.
> Makefile.config:794: slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev
> Makefile.config:871: No 'Python.h' was found: disables Python support - please install python-devel/python-dev
> Makefile.config:963: No libllvm 13+ found, slower source file resolution, please install llvm-devel/llvm-dev
> Makefile.config:1009: No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev
> Makefile.config:1022: No libzstd found, disables trace compression, please install libzstd-dev[el] and/or set LIBZSTD_DIR
> Makefile.config:1035: No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev
> Makefile.config:1082: No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev
> Makefile.config:1098: No libcapstone found, disables disasm engine support for 'perf script', please install libcapstone-dev/capstone-devel
> Makefile.config:1147: libpfm4 not found, disables libpfm4 support. Please install libpfm-devel or libpfm4-dev
> 
> Auto-detecting system features:
> ...                                   libdw: [ OFF ]
> ...                                   glibc: [ on  ]
> ...                                  libelf: [ OFF ]
> ...                                 libnuma: [ OFF ]
> ...                  numa_num_possible_cpus: [ OFF ]
> ...                               libpython: [ OFF ]
> ...                             libcapstone: [ OFF ]
> ...                               llvm-perf: [ OFF ]
> ...                                    zlib: [ OFF ]
> ...                                    lzma: [ OFF ]
> ...                                     bpf: [ on  ]
> ...                                  libaio: [ on  ]
> ...                                 libzstd: [ OFF ]
> ...                              libopenssl: [ OFF ]
> 
>   CC      dlfilters/dlfilter-test-api-v0.o
>   CC      dlfilters/dlfilter-test-api-v2.o
>   CC      dlfilters/dlfilter-show-cycles.o
>   GEN     /home/acme/git/perf-tools-next/tools/perf/arch/arm64/include/generated/asm/sysreg-defs.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/exec-cmd.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/help.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/pager.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/parse-options.h
>   PERF_VERSION = 6.19.rc7.gd0144158c595
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsubcmd/include/subcmd/run-command.h
>   GEN     perf-archive
>   GEN     perf-iostat
>   INSTALL libsubcmd_headers
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/core.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/bpf_perf.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/threadmap.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/cpumap.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/evlist.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/core.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/cpumap.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/evsel.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/event.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/mmap.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v15.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v16.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/threadmap.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/perf/schedstat-v17.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/evsel.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/cpumap.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libsymbol/include/symbol/kallsyms.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/evlist.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/evlist.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/evsel.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsymbol/kallsyms.o
>   MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fd/
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/lib.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/cpu.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/debug.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/mmap.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/io.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/cpu.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/io_dir.h
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/rc_check.h
>   MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fd/array.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/mmap.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fd/array.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/debug.o
>   INSTALL libsymbol_headers
>   MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/threadmap.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/str_error_r.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fs/fs.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/zalloc.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/fs.o
>   MKDIR   /home/acme/git/perf-tools-next/tools/perf/libapi/fs/
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libapi/include/api/fs/tracing_path.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/xyarray.o
>   INSTALL /home/acme/git/perf-tools-next/tools/perf/libperf/include/internal/xyarray.h
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/tracing_path.o
>   LINK    dlfilters/dlfilter-show-cycles.so
>   CC      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/cgroup.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libperf/lib.o
>   INSTALL libperf_headers
>   INSTALL libapi_headers
>   LINK    dlfilters/dlfilter-test-api-v0.so
>   LINK    dlfilters/dlfilter-test-api-v2.so
>   LD      /home/acme/git/perf-tools-next/tools/perf/libapi/fd/libapi-in.o
>   LD      /home/acme/git/perf-tools-next/tools/perf/libsymbol/libsymbol-in.o
>   AR      /home/acme/git/perf-tools-next/tools/perf/libsymbol/libsymbol.a
>   LD      /home/acme/git/perf-tools-next/tools/perf/libapi/fs/libapi-in.o
>   LD      /home/acme/git/perf-tools-next/tools/perf/libapi/libapi-in.o
>   AR      /home/acme/git/perf-tools-next/tools/perf/libapi/libapi.a
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/exec-cmd.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/help.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/pager.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/parse-options.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/run-command.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/sigchain.o
>   CC      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/subcmd-config.o
>   LD      /home/acme/git/perf-tools-next/tools/perf/libperf/libperf-in.o
>   AR      /home/acme/git/perf-tools-next/tools/perf/libperf/libperf.a
>   LD      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/libsubcmd-in.o
>   AR      /home/acme/git/perf-tools-next/tools/perf/libsubcmd/libsubcmd.a
>   CC      builtin-bench.o
>   CC      builtin-annotate.o
>   CC      bench/sched-messaging.o
>   CC      ui/setup.o
>   CC      bench/sched-pipe.o
>   CC      ui/helpline.o
>   CC      tests/builtin-test.o
>   CC      builtin-check.o
>   CC      bench/sched-seccomp-notify.o
>   CC      tests/tests-scripts.o
>   CC      builtin-config.o
>   CC      ui/progress.o
>   CC      bench/syscall.o
>   CC      builtin-diff.o
>   CC      tests/parse-events.o
>   LD      scripts/perf-util-in.o
>   CC      arch/common.o
>   CC      bench/mem-functions.o
>   CC      ui/util.o
>   CC      tests/dso-data.o
>   CC      builtin-evlist.o
>   CC      builtin-ftrace.o
>   CC      tests/vmlinux-kallsyms.o
>   CC      bench/futex.o
>   CC      ui/hist.o
>   CC      bench/futex-hash.o
>   CC      builtin-help.o
>   CC      bench/futex-wake.o
>   CC      arch/x86/tests/arch-tests.o
>   CC      arch/x86/util/header.o
>   CC      arch/x86/tests/hybrid.o
>   CC      ui/stdio/hist.o
>   CC      util/annotate-arch/annotate-arc.o
>   CC      util/annotate-arch/annotate-arm.o
>   CC      bench/futex-wake-parallel.o
>   CC      arch/x86/tests/intel-pt-test.o
>   CC      arch/x86/tests/bp-modify.o
>   CC      arch/x86/tests/amd-ibs-via-core-pmu.o
>   CC      arch/x86/util/tsc.o
>   CC      arch/x86/util/pmu.o
>   CC      tests/openat-syscall.o
>   CC      tests/openat-syscall-all-cpus.o
>   CC      tests/mmap-basic.o
>   CC      tests/perf-record.o
>   GEN     pmu-events/arch/x86/amdzen1/extra-metrics.json
>   CC      util/annotate-arch/annotate-arm64.o
>   CC      util/annotate-arch/annotate-csky.o
>   GEN     pmu-events/arch/x86/amdzen2/extra-metrics.json
>   CC      tests/evsel-roundtrip-name.o
>   GEN     pmu-events/arch/x86/amdzen3/extra-metrics.json
>   CC      util/annotate-arch/annotate-loongarch.o
>   CC      arch/x86/tests/amd-ibs-period.o
>   CC      util/perf-regs-arch/perf_regs_aarch64.o
>   CC      builtin-buildid-list.o
>   CC      arch/x86/tests/topdown.o
>   CC      tests/fdarray.o
>   GEN     pmu-events/arch/x86/amdzen4/extra-metrics.json
>   CC      arch/x86/util/perf_regs.o
>   LD      util/kvm-stat-arch/perf-util-in.o
>   GEN     pmu-events/arch/x86/amdzen5/extra-metrics.json
>   CC      util/perf-regs-arch/perf_regs_arm.o
>   CC      bench/futex-requeue.o
>   CC      util/annotate-arch/annotate-mips.o
>   CC      util/annotate-arch/annotate-powerpc.o
>   CC      util/annotate-arch/annotate-x86.o
>   CC      util/intel-pt-decoder/intel-pt-pkt-decoder.o
>   GEN     pmu-events/arch/x86/amdzen6/extra-metrics.json
>   CC      arch/x86/util/topdown.o
>   CC      util/arm-spe-decoder/arm-spe-pkt-decoder.o
>   CC      util/perf-regs-arch/perf_regs_csky.o
>   CC      util/perf-regs-arch/perf_regs_loongarch.o
>   CC      util/perf-regs-arch/perf_regs_mips.o
>   CC      util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.o
>   CC      arch/x86/util/machine.o
>   GEN     pmu-events/arch/x86/amdzen1/extra-metricgroups.json
>   CC      bench/futex-lock-pi.o
>   CC      util/arm-spe-decoder/arm-spe-decoder.o
>   CC      builtin-buildid-cache.o
>   GEN     pmu-events/arch/x86/amdzen2/extra-metricgroups.json
>   CC      util/perf-regs-arch/perf_regs_powerpc.o
>   CC      bench/epoll-wait.o
>   CC      util/perf-regs-arch/perf_regs_riscv.o
>   LD      util/scripting-engines/perf-util-in.o
>   GEN     pmu-events/arch/x86/amdzen3/extra-metricgroups.json
>   CC      util/annotate-arch/annotate-riscv64.o
>   CC      util/perf-regs-arch/perf_regs_s390.o
>   CC      arch/x86/util/event.o
>   CC      util/annotate-arch/annotate-s390.o
>   CC      tests/pmu.o
>   LD      util/hisi-ptt-decoder/perf-util-in.o
>   CC      tests/pmu-events.o
>   CC      util/arm64-frame-pointer-unwind-support.o
>   CC      tests/hists_common.o
>   CC      util/perf-regs-arch/perf_regs_x86.o
>   GEN     pmu-events/arch/x86/amdzen4/extra-metricgroups.json
>   CC      util/intel-pt-decoder/intel-pt-insn-decoder.o
>   CC      util/intel-pt-decoder/intel-pt-log.o
>   CC      bench/epoll-ctl.o
>   CC      util/addr2line.o
>   CC      util/addr_location.o
>   CC      tests/hists_link.o
>   LD      util/perf-regs-arch/perf-util-in.o
>   CC      util/intel-pt-decoder/intel-pt-decoder.o
>   GEN     util/intel-pt-decoder/inat-tables.c
>   CC      arch/x86/util/evlist.o
>   GEN     pmu-events/arch/x86/amdzen5/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/amdzen6/extra-metricgroups.json
>   CC      bench/synthesize.o
>   LD      util/arm-spe-decoder/perf-util-in.o
>   CC      bench/kallsyms-parse.o
>   CC      tests/hists_filter.o
>   CC      util/annotate-arch/annotate-sparc.o
>   CC      tests/hists_output.o
>   CC      arch/x86/util/mem-events.o
>   LD      arch/x86/tests/perf-test-in.o
>   CC      arch/x86/util/evsel.o
>   LD      arch/x86/perf-test-in.o
>   CC      bench/find-bit-bench.o
>   CC      builtin-kallsyms.o
>   LD      arch/perf-test-in.o
>   CC      builtin-list.o
>   CC      builtin-record.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a34/extra-metrics.json
>   CC      util/intel-pt-decoder/insn.o
>   CC      util/intel-pt-decoder/inat.o
>   CC      util/annotate.o
>   CC      bench/inject-buildid.o
>   CC      tests/hists_cumulate.o
>   LD      util/annotate-arch/perf-util-in.o
>   CC      tests/bp_signal.o
>   CC      builtin-report.o
>   CC      builtin-stat.o
>   CC      bench/evlist-open-close.o
>   CC      bench/breakpoint.o
>   CC      bench/pmu-scan.o
>   CC      util/blake2s.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a35/extra-metrics.json
>   CC      bench/uprobe.o
>   CC      tests/bp_signal_overflow.o
>   CC      arch/x86/util/iostat.o
>   CC      builtin-top.o
>   CC      util/block-info.o
>   CC      util/block-range.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a510/extra-metrics.json
>   CC      bench/mem-memcpy-x86-64-asm.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a53/extra-metrics.json
>   CC      builtin-script.o
>   CC      arch/x86/util/auxtrace.o
>   CC      util/build-id.o
>   CC      builtin-kvm.o
>   CC      bench/mem-memset-x86-64-asm.o
>   CC      builtin-inject.o
>   CC      tests/bp_account.o
>   CC      arch/x86/util/intel-pt.o
>   CC      util/cacheline.o
>   CC      builtin-mem.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a55/extra-metrics.json
>   CC      tests/wp.o
>   CC      arch/x86/util/intel-bts.o
>   CC      tests/task-exit.o
>   CC      builtin-data.o
>   LD      bench/perf-bench-in.o
>   CC      builtin-version.o
>   LD      perf-bench-in.o
>   CC      builtin-c2c.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a57-a72/extra-metrics.json
>   CC      builtin-daemon.o
>   AR      libperf-bench.a
>   CC      util/config.o
>   CC      util/copyfile.o
>   CC      perf.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a65-e1/extra-metrics.json
>   LD      arch/perf-in.o
>   CC      tests/sw-clock.o
>   CC      tests/mmap-thread-lookup.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a710/extra-metrics.json
>   CC      tests/thread-maps-share.o
>   CC      tests/keep-tracking.o
>   CC      util/ctype.o
>   CC      util/db-export.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a73/extra-metrics.json
>   CC      util/disasm.o
>   CC      tests/code-reading.o
>   CC      tests/sample-parsing.o
>   CC      tests/parse-no-sample-id-all.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a75/extra-metrics.json
>   CC      tests/kmod-path.o
>   CC      util/env.o
>   CC      tests/thread-map.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a76/extra-metrics.json
>   CC      util/event.o
>   CC      util/evlist.o
>   CC      util/sideband_evlist.o
>   CC      tests/topology.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a77/extra-metrics.json
>   CC      util/evsel.o
>   CC      tests/mem.o
>   CC      util/evsel_fprintf.o
>   CC      util/perf_event_attr_fprintf.o
>   CC      util/evswitch.o
>   CC      util/find_bit.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a78/extra-metrics.json
>   CC      tests/cpumap.o
>   CC      util/levenshtein.o
>   CC      tests/stat.o
>   GEN     pmu-events/arch/arm64/arm/cortex-x1/extra-metrics.json
>   CC      util/llvm.o
>   CXX     util/llvm-c-helpers.o
>   GEN     pmu-events/arch/arm64/arm/cortex-x2/extra-metrics.json
>   CC      util/mmap.o
>   CC      tests/event_update.o
>   CC      tests/event-times.o
>   CC      tests/expr.o
>   CC      util/memswap.o
>   BISON   util/parse-events-bison.c
>   LD      arch/x86/util/perf-util-in.o
>   LD      arch/x86/perf-util-in.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n1/extra-metrics.json
>   LD      arch/perf-util-in.o
>   CC      tests/backward-ring-buffer.o
>   CC      tests/sdt.o
>   CC      tests/is_printable_array.o
>   CC      util/print-events.o
>   CC      tests/bitmap.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n2-v2/extra-metrics.json
>   CC      tests/perf-hooks.o
>   CC      util/tracepoint.o
>   CC      tests/unit_number__scnprintf.o
>   CC      util/perf_regs.o
>   CC      util/path.o
>   CC      util/print_binary.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n3/extra-metrics.json
>   CC      tests/mem2node.o
>   CC      tests/maps.o
>   CC      tests/time-utils-test.o
>   CC      util/print_insn.o
>   CC      tests/genelf.o
>   CC      tests/api-io.o
>   CC      util/rlimit.o
>   CC      util/argv_split.o
>   CC      tests/demangle-java-test.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-v1/extra-metrics.json
>   GEN     pmu-events/arch/arm64/arm/neoverse-v3/extra-metrics.json
>   CC      util/rbtree.o
>   CC      util/libstring.o
>   CC      tests/demangle-ocaml-test.o
>   CC      tests/demangle-rust-v0-test.o
>   CC      tests/pfm.o
>   CC      tests/parse-metric.o
>   CC      tests/pe-file-parsing.o
>   CC      util/bitmap.o
>   CC      tests/expand-cgroup.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a34/extra-metricgroups.json
>   CC      util/hweight.o
>   CC      tests/perf-time-to-tsc.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a35/extra-metricgroups.json
>   CC      util/smt.o
>   CC      tests/dlfilter-test.o
>   CC      tests/sigtrap.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a510/extra-metricgroups.json
>   CC      util/strbuf.o
>   CC      tests/event_groups.o
>   CC      tests/symbols.o
>   CC      tests/util.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a53/extra-metricgroups.json
>   CC      tests/hwmon_pmu.o
>   CC      util/string.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a55/extra-metricgroups.json
>   CC      tests/tool_pmu.o
>   CC      util/strlist.o
>   CC      util/strfilter.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a57-a72/extra-metricgroups.json
>   CC      util/top.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a65-e1/extra-metricgroups.json
>   CC      util/usage.o
>   CC      util/dso.o
>   CC      tests/subcmd-help.o
>   CC      tests/kallsyms-split.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a710/extra-metricgroups.json
>   CC      tests/workloads/noploop.o
>   CC      util/dsos.o
>   CC      util/symbol.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a73/extra-metricgroups.json
>   CC      util/symbol_fprintf.o
>   CC      util/map_symbol.o
>   CC      tests/workloads/thloop.o
>   CC      tests/workloads/leafloop.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a75/extra-metricgroups.json
>   CC      util/color.o
>   CC      util/color_config.o
>   LD      util/intel-pt-decoder/perf-util-in.o
>   CC      tests/workloads/sqrtloop.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a76/extra-metricgroups.json
>   CC      tests/workloads/brstack.o
>   CC      tests/workloads/datasym.o
>   CC      tests/workloads/landlock.o
>   CC      tests/workloads/traploop.o
>   CC      tests/workloads/inlineloop.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a77/extra-metricgroups.json
>   CC      util/metricgroup.o
>   CC      util/header.o
>   CC      util/callchain.o
>   CC      util/values.o
>   GEN     pmu-events/arch/arm64/arm/cortex-a78/extra-metricgroups.json
>   CC      util/fncache.o
>   CC      util/debug.o
>   CC      util/machine.o
>   CC      util/map.o
>   GEN     pmu-events/arch/arm64/arm/cortex-x1/extra-metricgroups.json
>   CC      util/maps.o
>   CC      util/pstack.o
>   GEN     pmu-events/arch/arm64/arm/cortex-x2/extra-metricgroups.json
>   CC      util/session.o
>   CC      util/tool.o
>   CC      util/sample.o
>   CC      util/sample-raw.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n1/extra-metricgroups.json
>   CC      util/s390-sample-raw.o
>   CC      util/amd-sample-raw.o
>   LD      tests/workloads/perf-test-in.o
>   LD      tests/perf-test-in.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n2-v2/extra-metricgroups.json
>   LD      perf-test-in.o
>   CC      util/ordered-events.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-n3/extra-metricgroups.json
>   CC      util/namespaces.o
>   CC      util/comm.o
>   AR      libperf-test.a
>   GEN     pmu-events/arch/arm64/arm/neoverse-v1/extra-metricgroups.json
>   CC      util/thread.o
>   CC      util/threads.o
>   CC      util/thread_map.o
>   CC      util/parse-events-bison.o
>   GEN     pmu-events/arch/arm64/arm/neoverse-v3/extra-metricgroups.json
>   BISON   util/pmu-bison.c
>   GEN     pmu-events/arch/x86/alderlake/extra-metrics.json
>   CC      util/pmus.o
>   CC      util/drm_pmu.o
>   GEN     pmu-events/arch/x86/alderlaken/extra-metrics.json
>   GEN     pmu-events/arch/x86/arrowlake/extra-metrics.json
>   CC      util/hwmon_pmu.o
>   GEN     pmu-events/arch/x86/bonnell/extra-metrics.json
>   CC      util/tool_pmu.o
>   GEN     pmu-events/arch/x86/broadwell/extra-metrics.json
>   CC      util/tp_pmu.o
>   GEN     pmu-events/arch/x86/broadwellde/extra-metrics.json
>   GEN     pmu-events/arch/x86/broadwellx/extra-metrics.json
>   GEN     pmu-events/arch/x86/cascadelakex/extra-metrics.json
>   CC      util/svghelper.o
>   CC      util/trace-event-info.o
>   GEN     pmu-events/arch/x86/clearwaterforest/extra-metrics.json
>   CC      util/trace-event-scripting.o
>   GEN     pmu-events/arch/x86/elkhartlake/extra-metrics.json
>   LD      ui/perf-ui-in.o
>   LD      perf-ui-in.o
>   GEN     pmu-events/arch/x86/emeraldrapids/extra-metrics.json
>   CC      util/sort.o
>   GEN     pmu-events/arch/x86/goldmont/extra-metrics.json
>   GEN     pmu-events/arch/x86/goldmontplus/extra-metrics.json
>   AR      libperf-ui.a
>   CC      util/hist.o
>   GEN     pmu-events/arch/x86/grandridge/extra-metrics.json
>   CC      util/util.o
>   CC      util/cpumap.o
>   CC      util/affinity.o
>   CC      util/cputopo.o
>   GEN     pmu-events/arch/x86/graniterapids/extra-metrics.json
>   GEN     pmu-events/arch/x86/haswell/extra-metrics.json
>   CC      util/cgroup.o
>   GEN     pmu-events/arch/x86/haswellx/extra-metrics.json
>   CC      util/target.o
>   GEN     pmu-events/arch/x86/icelake/extra-metrics.json
>   CC      util/rblist.o
>   CC      util/intlist.o
>   CC      util/vdso.o
>   GEN     pmu-events/arch/x86/icelakex/extra-metrics.json
>   CC      util/counts.o
>   CC      util/stat.o
>   GEN     pmu-events/arch/x86/ivybridge/extra-metrics.json
>   CC      util/stat-shadow.o
>   GEN     pmu-events/arch/x86/ivytown/extra-metrics.json
>   GEN     pmu-events/arch/x86/jaketown/extra-metrics.json
>   GEN     pmu-events/arch/x86/knightslanding/extra-metrics.json
>   CC      util/stat-display.o
>   GEN     pmu-events/arch/x86/lunarlake/extra-metrics.json
>   CC      util/perf_api_probe.o
>   CC      util/record.o
>   CC      util/srcline.o
>   CC      util/srccode.o
>   GEN     pmu-events/arch/x86/meteorlake/extra-metrics.json
>   CC      util/synthetic-events.o
>   CC      util/data.o
>   CC      util/tsc.o
>   GEN     pmu-events/arch/x86/nehalemep/extra-metrics.json
>   GEN     pmu-events/arch/x86/nehalemex/extra-metrics.json
>   GEN     pmu-events/arch/x86/pantherlake/extra-metrics.json
>   CC      util/cloexec.o
>   GEN     pmu-events/arch/x86/rocketlake/extra-metrics.json
>   CC      util/call-path.o
>   CC      util/rwsem.o
>   CC      util/thread-stack.o
>   GEN     pmu-events/arch/x86/sandybridge/extra-metrics.json
>   CC      util/spark.o
>   GEN     pmu-events/arch/x86/sapphirerapids/extra-metrics.json
>   GEN     pmu-events/arch/x86/sierraforest/extra-metrics.json
>   CC      util/topdown.o
>   CC      util/iostat.o
>   GEN     pmu-events/arch/x86/silvermont/extra-metrics.json
>   CC      util/stream.o
>   GEN     pmu-events/arch/x86/skylake/extra-metrics.json
>   CC      util/lock-contention.o
>   CC      util/auxtrace.o
>   GEN     pmu-events/arch/x86/skylakex/extra-metrics.json
>   CC      util/intel-pt.o
>   GEN     pmu-events/arch/x86/snowridgex/extra-metrics.json
>   CC      util/intel-bts.o
>   GEN     pmu-events/arch/x86/tigerlake/extra-metrics.json
>   CC      util/arm-spe.o
>   CC      util/hisi-ptt.o
>   CC      util/s390-cpumsf.o
>   CC      util/powerpc-vpadtl.o
>   GEN     pmu-events/arch/x86/westmereep-dp/extra-metrics.json
>   LD      perf-in.o
>   GEN     pmu-events/arch/x86/westmereep-sp/extra-metrics.json
>   CC      util/cs-etm-base.o
>   CC      util/parse-branch-options.o
>   CC      util/dump-insn.o
>   GEN     pmu-events/arch/x86/westmereex/extra-metrics.json
>   GEN     pmu-events/arch/x86/alderlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/alderlaken/extra-metricgroups.json
>   CC      util/parse-regs-options.o
>   CC      util/parse-sublevel-options.o
>   CC      util/term.o
>   CC      util/help-unknown-cmd.o
>   CC      util/dlfilter.o
>   CC      util/mem-events.o
>   GEN     pmu-events/arch/x86/arrowlake/extra-metricgroups.json
>   CC      util/mem-info.o
>   GEN     pmu-events/arch/x86/bonnell/extra-metricgroups.json
>   CC      util/vsprintf.o
>   CC      util/units.o
>   GEN     pmu-events/arch/x86/broadwell/extra-metricgroups.json
>   CC      util/time-utils.o
>   BISON   util/expr-bison.c
>   CC      util/branch.o
>   CC      util/mem2node.o
>   GEN     pmu-events/arch/x86/broadwellde/extra-metricgroups.json
>   CC      util/clockid.o
>   CC      util/list_sort.o
>   GEN     pmu-events/arch/x86/broadwellx/extra-metricgroups.json
>   CC      util/mutex.o
>   GEN     pmu-events/arch/x86/cascadelakex/extra-metricgroups.json
>   CC      util/sharded_mutex.o
>   CC      util/intel-tpebs.o
>   CC      util/hashmap.o
>   GEN     pmu-events/arch/x86/clearwaterforest/extra-metricgroups.json
>   CC      util/symbol-minimal.o
>   CC      util/data-convert-json.o
>   CC      util/cap.o
>   CC      util/demangle-ocaml.o
>   CC      util/demangle-java.o
>   GEN     pmu-events/arch/x86/elkhartlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/emeraldrapids/extra-metricgroups.json
>   CC      util/demangle-rust-v0.o
>   CC      util/perf-hooks.o
>   GEN     pmu-events/arch/x86/goldmont/extra-metricgroups.json
>   FLEX    util/parse-events-flex.c
>   FLEX    util/pmu-flex.c
>   CC      util/pmu-bison.o
>   FLEX    util/expr-flex.c
>   CC      util/expr-bison.o
>   CC      util/parse-events.o
>   GEN     pmu-events/arch/x86/goldmontplus/extra-metricgroups.json
>   CC      util/parse-events-flex.o
>   GEN     pmu-events/arch/x86/grandridge/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/graniterapids/extra-metricgroups.json
>   CC      util/pmu.o
>   GEN     pmu-events/arch/x86/haswell/extra-metricgroups.json
>   CC      util/pmu-flex.o
>   GEN     pmu-events/arch/x86/haswellx/extra-metricgroups.json
>   CC      util/expr-flex.o
>   CC      util/expr.o
>   GEN     pmu-events/arch/x86/icelake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/icelakex/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/ivybridge/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/ivytown/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/jaketown/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/knightslanding/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/lunarlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/meteorlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/nehalemep/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/nehalemex/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/pantherlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/rocketlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/sandybridge/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/sapphirerapids/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/sierraforest/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/silvermont/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/skylake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/skylakex/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/snowridgex/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/tigerlake/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/westmereep-dp/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/westmereep-sp/extra-metricgroups.json
>   GEN     pmu-events/arch/x86/westmereex/extra-metricgroups.json
>   TEST    pmu-events/metric_test.log
>   GEN     pmu-events/test-empty-pmu-events.c
>   TEST    pmu-events/empty-pmu-events.log
>   GEN     pmu-events/pmu-events.c
>   LD      util/perf-util-in.o
>   LD      perf-util-in.o
>   AR      libperf-util.a
>   CC      pmu-events/pmu-events.o
>   LD      pmu-events/pmu-events-in.o
>   AR      libpmu-events.a
>   LINK    perf
> /usr/bin/ld: libperf-util.a(perf-util-in.o): in function `symbol__disassemble_llvm':
> (.text+0x30712): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
> /usr/bin/ld: libperf-util.a(perf-util-in.o): in function `parse_uid':
> (.text+0xb4cd5): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
> /usr/bin/ld: (.text+0xb4d3a): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
> /usr/bin/ld: perf-in.o: in function `cmd_kvm':
> (.text+0x37078): undefined reference to `kvm_add_default_arch_event'
> /usr/bin/ld: (.text+0x3719c): undefined reference to `kvm_add_default_arch_event'
> /usr/bin/ld: (.text+0x3735a): undefined reference to `kvm_add_default_arch_event'
> /usr/bin/ld: (.text+0x373bb): undefined reference to `kvm_add_default_arch_event'
> collect2: error: ld returned 1 exit status
> make[4]: *** [Makefile.perf:806: perf] Error 1
> make[3]: *** [Makefile.perf:286: sub-make] Error 2
> make[2]: *** [Makefile:76: all] Error 2
>   test: test -x ./perf
> make[1]: *** [tests/make:337: make_static] Error 1
> make: *** [Makefile:109: build-test] Error 2
> make: Leaving directory '/home/acme/git/perf-tools-next/tools/perf'
> 
> real	0m21.807s
> user	2m35.853s
> sys	0m17.941s
> ⬢ [acme@toolbx perf-tools-next]$
> 
> 
[PATCH v3 0/5] perf Cross platform KVM support
Posted by Ian Rogers 3 days, 16 hours ago
The existing perf kvm code is using the arch directory, which means a
data file can only be processed on the same machine type that it was
recorded. Switch to using the ELF machine of the session at runtime to
set up the KVM support, making it cross-architectural. So that the ELF
machine number is available early in initialization add it to the perf
data file header.

v3: Fix NO_LIBTRACEEVENT=1 build, kvm-stat-loongarch.c for old elf.h
    files and 32-bit build of kvm-stat-s390.c as reported by
    Arnaldo. Drop the first kvm stat live test patch that Arnaldo
    reported as merged.

v2: Wire up the perf data header to have the e_machine and allow early
    initialization of the KVM operations based upon it.
    https://lore.kernel.org/lkml/20260131200224.1296136-1-irogers@google.com/#t

v1: https://lore.kernel.org/lkml/20260128074106.788156-1-irogers@google.com/

Ian Rogers (5):
  perf kvm stat: Remove use of the arch directory
  perf kvm: Wire up e_machine
  perf session: Add e_flags to the e_machine helper
  perf header: Add e_machine/e_flags to the header
  perf thread: Don't require machine to compute the e_machine

 tools/perf/Makefile.config                    |   4 -
 tools/perf/arch/arm64/Makefile                |   1 -
 tools/perf/arch/arm64/util/Build              |   1 -
 tools/perf/arch/loongarch/Makefile            |   1 -
 tools/perf/arch/loongarch/util/Build          |   1 -
 tools/perf/arch/powerpc/Makefile              |   1 -
 tools/perf/arch/powerpc/util/Build            |   1 -
 tools/perf/arch/riscv/Makefile                |   1 -
 tools/perf/arch/riscv/util/Build              |   2 -
 tools/perf/arch/s390/Makefile                 |   1 -
 tools/perf/arch/s390/util/Build               |   1 -
 tools/perf/arch/x86/Makefile                  |   1 -
 tools/perf/arch/x86/util/Build                |   1 -
 tools/perf/builtin-kvm.c                      |  73 +++---
 tools/perf/builtin-report.c                   |   4 +-
 tools/perf/builtin-script.c                   |   6 +-
 tools/perf/util/Build                         |   3 +-
 tools/perf/util/env.h                         |   3 +
 tools/perf/util/evsel.c                       |   6 +-
 tools/perf/util/evsel.h                       |   1 +
 tools/perf/util/header.c                      |  33 +++
 tools/perf/util/header.h                      |   1 +
 tools/perf/util/kvm-stat-arch/Build           |   6 +
 .../kvm-stat-arch}/arm64_exception_types.h    |   0
 .../kvm-stat-arch}/book3s_hcalls.h            |   0
 .../kvm-stat-arch}/book3s_hv_exits.h          |   0
 .../kvm-stat-arch/kvm-stat-arm64.c}           |  43 ++--
 .../kvm-stat-arch/kvm-stat-loongarch.c}       |  49 ++--
 .../kvm-stat-arch/kvm-stat-powerpc.c}         |  61 ++---
 .../kvm-stat-arch/kvm-stat-riscv.c}           |  42 ++--
 .../kvm-stat-arch/kvm-stat-s390.c}            |  40 ++--
 .../kvm-stat-arch/kvm-stat-x86.c}             |  44 ++--
 .../kvm-stat-arch}/riscv_trap_types.h         |   2 +-
 tools/perf/util/kvm-stat.c                    | 215 +++++++++++++++++-
 tools/perf/util/kvm-stat.h                    |  79 +++++--
 .../scripting-engines/trace-event-python.c    |   8 +-
 tools/perf/util/session.c                     |  62 ++++-
 tools/perf/util/session.h                     |   2 +-
 tools/perf/util/thread.c                      |   5 +
 39 files changed, 590 insertions(+), 215 deletions(-)
 create mode 100644 tools/perf/util/kvm-stat-arch/Build
 rename tools/perf/{arch/arm64/util => util/kvm-stat-arch}/arm64_exception_types.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hcalls.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hv_exits.h (100%)
 rename tools/perf/{arch/arm64/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-arm64.c} (62%)
 rename tools/perf/{arch/loongarch/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-loongarch.c} (77%)
 rename tools/perf/{arch/powerpc/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-powerpc.c} (78%)
 rename tools/perf/{arch/riscv/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-riscv.c} (57%)
 rename tools/perf/{arch/s390/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-s390.c} (77%)
 rename tools/perf/{arch/x86/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-x86.c} (88%)
 rename tools/perf/{arch/riscv/util => util/kvm-stat-arch}/riscv_trap_types.h (96%)

-- 
2.53.0.rc2.204.g2597b5adb4-goog
[PATCH v3 1/5] perf kvm stat: Remove use of the arch directory
Posted by Ian Rogers 3 days, 16 hours ago
`perf kvm stat` supports record and report options. By using the arch
directory a report for a different machine type cannot be
supported. Move the kvm-stat code out of the arch directory and into
util/kvm-stat-arch following the pattern of perf-regs and
dwarf-regs. Avoid duplicate symbols by renaming functions to have the
architecture name within them. For global variables, wrap them in an
architecture specific function. Selecting the architecture to use with
`perf kvm stat` is selected by EM_HOST, ie no different than before
the change. Later the ELF machine can be determined from the session
or a header feature (ie EM_HOST at the time of the record).

The build and #define HAVE_KVM_STAT_SUPPORT is now redundant so remove
across Makefiles and in the build.

Opportunistically constify architectural structs and arrays.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/Makefile.config                    |   4 -
 tools/perf/arch/arm64/Makefile                |   1 -
 tools/perf/arch/arm64/util/Build              |   1 -
 tools/perf/arch/loongarch/Makefile            |   1 -
 tools/perf/arch/loongarch/util/Build          |   1 -
 tools/perf/arch/powerpc/Makefile              |   1 -
 tools/perf/arch/powerpc/util/Build            |   1 -
 tools/perf/arch/riscv/Makefile                |   1 -
 tools/perf/arch/riscv/util/Build              |   2 -
 tools/perf/arch/s390/Makefile                 |   1 -
 tools/perf/arch/s390/util/Build               |   1 -
 tools/perf/arch/x86/Makefile                  |   1 -
 tools/perf/arch/x86/util/Build                |   1 -
 tools/perf/builtin-kvm.c                      |  37 ++--
 tools/perf/util/Build                         |   3 +-
 tools/perf/util/kvm-stat-arch/Build           |   6 +
 .../kvm-stat-arch}/arm64_exception_types.h    |   0
 .../kvm-stat-arch}/book3s_hcalls.h            |   0
 .../kvm-stat-arch}/book3s_hv_exits.h          |   0
 .../kvm-stat-arch/kvm-stat-arm64.c}           |  43 ++--
 .../kvm-stat-arch/kvm-stat-loongarch.c}       |  48 ++--
 .../kvm-stat-arch/kvm-stat-powerpc.c}         |  61 ++---
 .../kvm-stat-arch/kvm-stat-riscv.c}           |  42 ++--
 .../kvm-stat-arch/kvm-stat-s390.c}            |  40 ++--
 .../kvm-stat-arch/kvm-stat-x86.c}             |  44 ++--
 .../kvm-stat-arch}/riscv_trap_types.h         |   2 +-
 tools/perf/util/kvm-stat.c                    | 209 +++++++++++++++++-
 tools/perf/util/kvm-stat.h                    |  76 +++++--
 28 files changed, 451 insertions(+), 177 deletions(-)
 create mode 100644 tools/perf/util/kvm-stat-arch/Build
 rename tools/perf/{arch/arm64/util => util/kvm-stat-arch}/arm64_exception_types.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hcalls.h (100%)
 rename tools/perf/{arch/powerpc/util => util/kvm-stat-arch}/book3s_hv_exits.h (100%)
 rename tools/perf/{arch/arm64/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-arm64.c} (63%)
 rename tools/perf/{arch/loongarch/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-loongarch.c} (78%)
 rename tools/perf/{arch/powerpc/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-powerpc.c} (78%)
 rename tools/perf/{arch/riscv/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-riscv.c} (58%)
 rename tools/perf/{arch/s390/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-s390.c} (77%)
 rename tools/perf/{arch/x86/util/kvm-stat.c => util/kvm-stat-arch/kvm-stat-x86.c} (88%)
 rename tools/perf/{arch/riscv/util => util/kvm-stat-arch}/riscv_trap_types.h (96%)

diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 63ca9b2be663..c7e493245f34 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -1033,10 +1033,6 @@ ifndef NO_LIBNUMA
   endif
 endif
 
-ifdef HAVE_KVM_STAT_SUPPORT
-    CFLAGS += -DHAVE_KVM_STAT_SUPPORT
-endif
-
 ifeq (${IS_64_BIT}, 1)
   ifndef NO_PERF_READ_VDSO32
     $(call feature_check,compile-32)
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile
index 087e099fb453..44cc3f023318 100644
--- a/tools/perf/arch/arm64/Makefile
+++ b/tools/perf/arch/arm64/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
-HAVE_KVM_STAT_SUPPORT := 1
diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index 0177af19cc00..d25edd9e1883 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -1,4 +1,3 @@
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
 perf-util-y += ../../arm/util/auxtrace.o
 perf-util-y += ../../arm/util/cs-etm.o
diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile
index 087e099fb453..44cc3f023318 100644
--- a/tools/perf/arch/loongarch/Makefile
+++ b/tools/perf/arch/loongarch/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
-HAVE_KVM_STAT_SUPPORT := 1
diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build
index 0aa31986ecb5..1cb06a5f8935 100644
--- a/tools/perf/arch/loongarch/util/Build
+++ b/tools/perf/arch/loongarch/util/Build
@@ -3,4 +3,3 @@ perf-util-y += perf_regs.o
 
 perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
index a295a80ea078..44cc3f023318 100644
--- a/tools/perf/arch/powerpc/Makefile
+++ b/tools/perf/arch/powerpc/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build
index 5fd28ec713a4..e091b6785674 100644
--- a/tools/perf/arch/powerpc/util/Build
+++ b/tools/perf/arch/powerpc/util/Build
@@ -1,5 +1,4 @@
 perf-util-y += header.o
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-y += perf_regs.o
 perf-util-y += mem-events.o
 perf-util-y += pmu.o
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
index 087e099fb453..44cc3f023318 100644
--- a/tools/perf/arch/riscv/Makefile
+++ b/tools/perf/arch/riscv/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
 PERF_HAVE_JITDUMP := 1
-HAVE_KVM_STAT_SUPPORT := 1
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 628b9ebd418b..c01231bcf9c3 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -1,4 +1,2 @@
 perf-util-y += perf_regs.o
 perf-util-y += header.o
-
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile
index 0033698a65ce..8b59ce8efb89 100644
--- a/tools/perf/arch/s390/Makefile
+++ b/tools/perf/arch/s390/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 5391d26fedd4..87229f2c4397 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -1,5 +1,4 @@
 perf-util-y += header.o
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-y += perf_regs.o
 
 perf-util-y += machine.o
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
index a295a80ea078..44cc3f023318 100644
--- a/tools/perf/arch/x86/Makefile
+++ b/tools/perf/arch/x86/Makefile
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-HAVE_KVM_STAT_SUPPORT := 1
 PERF_HAVE_JITDUMP := 1
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 76127eefde8b..0c4cf1dd07bf 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -1,7 +1,6 @@
 perf-util-y += header.o
 perf-util-y += tsc.o
 perf-util-y += pmu.o
-perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-y += perf_regs.o
 perf-util-y += topdown.o
 perf-util-y += machine.o
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index c61369d54dd9..bd9bda32157f 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -52,7 +52,7 @@
 #include <math.h>
 #include <perf/mmap.h>
 
-#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 #define GET_EVENT_KEY(func, field)					\
 static u64 get_event_ ##func(struct kvm_event *event, int vcpu)		\
 {									\
@@ -597,7 +597,7 @@ static void kvm_display(struct perf_kvm_stat *kvm)
 
 #endif /* HAVE_SLANG_SUPPORT */
 
-#endif // defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#endif // defined(HAVE_LIBTRACEEVENT)
 
 static const char *get_filename_for_perf_kvm(void)
 {
@@ -613,13 +613,13 @@ static const char *get_filename_for_perf_kvm(void)
 	return filename;
 }
 
-#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 
 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
 {
-	struct kvm_reg_events_ops *events_ops = kvm_reg_events_ops;
+	const struct kvm_reg_events_ops *events_ops;
 
-	for (events_ops = kvm_reg_events_ops; events_ops->name; events_ops++) {
+	for (events_ops = kvm_reg_events_ops(); events_ops->name; events_ops++) {
 		if (!strcmp(events_ops->name, kvm->report_event)) {
 			kvm->events_ops = events_ops->ops;
 			return true;
@@ -809,7 +809,7 @@ static bool is_child_event(struct perf_kvm_stat *kvm,
 			   struct perf_sample *sample,
 			   struct event_key *key)
 {
-	struct child_event_ops *child_ops;
+	const struct child_event_ops *child_ops;
 
 	child_ops = kvm->events_ops->child_ops;
 
@@ -845,7 +845,7 @@ static bool skip_event(const char *event)
 {
 	const char * const *skip_events;
 
-	for (skip_events = kvm_skip_events; *skip_events; skip_events++)
+	for (skip_events = kvm_skip_events(); *skip_events; skip_events++)
 		if (!strcmp(event, *skip_events))
 			return true;
 
@@ -928,7 +928,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
 			return NULL;
 		}
 
-		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str);
+		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str());
 		thread__set_priv(thread, vcpu_record);
 	}
 
@@ -1636,11 +1636,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
 	return ret;
 }
 
-int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused)
-{
-	return 0;
-}
-
 static int
 kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 {
@@ -1666,7 +1661,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 		return ret;
 	}
 
-	for (events_tp = kvm_events_tp; *events_tp; events_tp++)
+	for (events_tp = kvm_events_tp(); *events_tp; events_tp++)
 		events_tp_size++;
 
 	rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
@@ -1681,7 +1676,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 
 	for (j = 0; j < events_tp_size; j++) {
 		rec_argv[i++] = STRDUP_FAIL_EXIT("-e");
-		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]);
+		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp()[j]);
 	}
 
 	rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
@@ -1775,7 +1770,7 @@ static struct evlist *kvm_live_event_list(void)
 	if (evlist == NULL)
 		return NULL;
 
-	for (events_tp = kvm_events_tp; *events_tp; events_tp++) {
+	for (events_tp = kvm_events_tp(); *events_tp; events_tp++) {
 
 		tp = strdup(*events_tp);
 		if (tp == NULL)
@@ -1985,13 +1980,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 perf_stat:
 	return cmd_stat(argc, argv);
 }
-#endif /* HAVE_KVM_STAT_SUPPORT */
-
-int __weak kvm_add_default_arch_event(int *argc __maybe_unused,
-					const char **argv __maybe_unused)
-{
-	return 0;
-}
+#endif /* HAVE_LIBTRACEEVENT */
 
 static int __cmd_record(const char *file_name, int argc, const char **argv)
 {
@@ -2179,7 +2168,7 @@ int cmd_kvm(int argc, const char **argv)
 		return __cmd_top(argc, argv);
 	else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0]))
 		return __cmd_buildid_list(file_name, argc, argv);
-#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_LIBTRACEEVENT)
 	else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0]))
 		return kvm_cmd_stat(file_name, argc, argv);
 #endif
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index b9925c6902ca..2852ba0f3d4d 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -128,7 +128,8 @@ perf-util-y += spark.o
 perf-util-y += topdown.o
 perf-util-y += iostat.o
 perf-util-y += stream.o
-perf-util-y += kvm-stat.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
+perf-util-y += kvm-stat-arch/
 perf-util-y += lock-contention.o
 perf-util-y += auxtrace.o
 perf-util-y += intel-pt-decoder/
diff --git a/tools/perf/util/kvm-stat-arch/Build b/tools/perf/util/kvm-stat-arch/Build
new file mode 100644
index 000000000000..d84e55656e7a
--- /dev/null
+++ b/tools/perf/util/kvm-stat-arch/Build
@@ -0,0 +1,6 @@
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-arm64.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-loongarch.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-powerpc.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-riscv.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-s390.o
+perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-x86.o
diff --git a/tools/perf/arch/arm64/util/arm64_exception_types.h b/tools/perf/util/kvm-stat-arch/arm64_exception_types.h
similarity index 100%
rename from tools/perf/arch/arm64/util/arm64_exception_types.h
rename to tools/perf/util/kvm-stat-arch/arm64_exception_types.h
diff --git a/tools/perf/arch/powerpc/util/book3s_hcalls.h b/tools/perf/util/kvm-stat-arch/book3s_hcalls.h
similarity index 100%
rename from tools/perf/arch/powerpc/util/book3s_hcalls.h
rename to tools/perf/util/kvm-stat-arch/book3s_hcalls.h
diff --git a/tools/perf/arch/powerpc/util/book3s_hv_exits.h b/tools/perf/util/kvm-stat-arch/book3s_hv_exits.h
similarity index 100%
rename from tools/perf/arch/powerpc/util/book3s_hv_exits.h
rename to tools/perf/util/kvm-stat-arch/book3s_hv_exits.h
diff --git a/tools/perf/arch/arm64/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
similarity index 63%
rename from tools/perf/arch/arm64/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
index 6611aa21cba9..8003ff415b1a 100644
--- a/tools/perf/arch/arm64/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
@@ -1,21 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
 #include <memory.h>
-#include "../../../util/evsel.h"
-#include "../../../util/kvm-stat.h"
+#include "../debug.h"
+#include "../evsel.h"
+#include "../kvm-stat.h"
 #include "arm64_exception_types.h"
-#include "debug.h"
 
 define_exit_reasons_table(arm64_exit_reasons, kvm_arm_exception_type);
 define_exit_reasons_table(arm64_trap_exit_reasons, kvm_arm_exception_class);
 
-const char *kvm_trap_exit_reason = "esr_ec";
-const char *vcpu_id_str = "id";
-const char *kvm_exit_reason = "ret";
-const char *kvm_entry_trace = "kvm:kvm_entry";
-const char *kvm_exit_trace = "kvm:kvm_exit";
+static const char *kvm_trap_exit_reason = "esr_ec";
 
-const char *kvm_events_tp[] = {
+static const char * const __kvm_events_tp[] = {
 	"kvm:kvm_entry",
 	"kvm:kvm_exit",
 	NULL,
@@ -26,7 +22,7 @@ static void event_get_key(struct evsel *evsel,
 			  struct event_key *key)
 {
 	key->info = 0;
-	key->key = evsel__intval(evsel, sample, kvm_exit_reason);
+	key->key = evsel__intval(evsel, sample, kvm_exit_reason());
 	key->exit_reasons = arm64_exit_reasons;
 
 	/*
@@ -44,28 +40,28 @@ static bool event_begin(struct evsel *evsel,
 			struct perf_sample *sample __maybe_unused,
 			struct event_key *key __maybe_unused)
 {
-	return evsel__name_is(evsel, kvm_entry_trace);
+	return evsel__name_is(evsel, kvm_entry_trace());
 }
 
 static bool event_end(struct evsel *evsel,
 		      struct perf_sample *sample,
 		      struct event_key *key)
 {
-	if (evsel__name_is(evsel, kvm_exit_trace)) {
+	if (evsel__name_is(evsel, kvm_exit_trace())) {
 		event_get_key(evsel, sample, key);
 		return true;
 	}
 	return false;
 }
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = event_begin,
 	.is_end_event	= event_end,
 	.decode_key	= exit_event_decode_key,
 	.name		= "VM-EXIT"
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{
 		.name	= "vmexit",
 		.ops	= &exit_events,
@@ -73,12 +69,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = {
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	NULL,
 };
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
+int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm)
 {
 	kvm->exit_reasons_isa = "arm64";
 	return 0;
 }
+
+const char * const *__kvm_events_tp_arm64(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_arm64(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_arm64(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/loongarch/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
similarity index 78%
rename from tools/perf/arch/loongarch/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
index a7859a3a9a51..a15ce072ac34 100644
--- a/tools/perf/arch/loongarch/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
 #include <memory.h>
-#include "util/kvm-stat.h"
-#include "util/parse-events.h"
-#include "util/debug.h"
-#include "util/evsel.h"
-#include "util/evlist.h"
-#include "util/pmus.h"
+#include "../kvm-stat.h"
+#include "../parse-events.h"
+#include "../debug.h"
+#include "../evsel.h"
+#include "../evlist.h"
+#include "../pmus.h"
 
 #define LOONGARCH_EXCEPTION_INT		0
 #define LOONGARCH_EXCEPTION_PIL		1
@@ -43,12 +43,8 @@
 
 define_exit_reasons_table(loongarch_exit_reasons, loongarch_exception_type);
 
-const char *vcpu_id_str = "vcpu_id";
-const char *kvm_exit_reason = "reason";
-const char *kvm_entry_trace = "kvm:kvm_enter";
-const char *kvm_reenter_trace = "kvm:kvm_reenter";
-const char *kvm_exit_trace = "kvm:kvm_exit";
-const char *kvm_events_tp[] = {
+static const char *kvm_reenter_trace = "kvm:kvm_reenter";
+static const char * const __kvm_events_tp[] = {
 	"kvm:kvm_enter",
 	"kvm:kvm_reenter",
 	"kvm:kvm_exit",
@@ -74,7 +70,8 @@ static bool event_end(struct evsel *evsel,
 	 *   kvm:kvm_enter   means returning to vmm and then to guest
 	 *   kvm:kvm_reenter means returning to guest immediately
 	 */
-	return evsel__name_is(evsel, kvm_entry_trace) || evsel__name_is(evsel, kvm_reenter_trace);
+	return evsel__name_is(evsel, kvm_entry_trace()) ||
+	       evsel__name_is(evsel, kvm_reenter_trace);
 }
 
 static void event_gspr_get_key(struct evsel *evsel,
@@ -109,12 +106,12 @@ static void event_gspr_get_key(struct evsel *evsel,
 	}
 }
 
-static struct child_event_ops child_events[] = {
+static const struct child_event_ops child_events[] = {
 	{ .name = "kvm:kvm_exit_gspr", .get_key = event_gspr_get_key },
 	{ NULL, NULL },
 };
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = event_begin,
 	.is_end_event = event_end,
 	.child_ops = child_events,
@@ -122,18 +119,33 @@ static struct kvm_events_ops exit_events = {
 	.name = "VM-EXIT"
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{ .name	= "vmexit", .ops = &exit_events, },
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	NULL,
 };
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
+int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm)
 {
 	kvm->exit_reasons_isa = "loongarch64";
 	kvm->exit_reasons = loongarch_exit_reasons;
 	return 0;
 }
+
+const char * const *__kvm_events_tp_loongarch(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_loongarch(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_loongarch(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
similarity index 78%
rename from tools/perf/arch/powerpc/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
index c8357b571ccf..42182d70beb6 100644
--- a/tools/perf/arch/powerpc/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c
@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
-#include "util/kvm-stat.h"
-#include "util/parse-events.h"
-#include "util/debug.h"
-#include "util/evsel.h"
-#include "util/evlist.h"
-#include "util/pmus.h"
+#include "../kvm-stat.h"
+#include "../parse-events.h"
+#include "../debug.h"
+#include "../evsel.h"
+#include "../evlist.h"
+#include "../pmus.h"
 
 #include "book3s_hv_exits.h"
 #include "book3s_hcalls.h"
@@ -13,15 +13,11 @@
 
 #define NR_TPS 4
 
-const char *vcpu_id_str = "vcpu_id";
-const char *kvm_entry_trace = "kvm_hv:kvm_guest_enter";
-const char *kvm_exit_trace = "kvm_hv:kvm_guest_exit";
-
 define_exit_reasons_table(hv_exit_reasons, kvm_trace_symbol_exit);
 define_exit_reasons_table(hcall_reasons, kvm_trace_symbol_hcall);
 
 /* Tracepoints specific to ppc_book3s_hv */
-const char *ppc_book3s_hv_kvm_tp[] = {
+static const char * const ppc_book3s_hv_kvm_tp[] = {
 	"kvm_hv:kvm_guest_enter",
 	"kvm_hv:kvm_guest_exit",
 	"kvm_hv:kvm_hcall_enter",
@@ -30,8 +26,7 @@ const char *ppc_book3s_hv_kvm_tp[] = {
 };
 
 /* 1 extra placeholder for NULL */
-const char *kvm_events_tp[NR_TPS + 1];
-const char *kvm_exit_reason;
+static const char *__kvm_events_tp[NR_TPS + 1];
 
 static void hcall_event_get_key(struct evsel *evsel,
 				struct perf_sample *sample,
@@ -60,13 +55,13 @@ static bool hcall_event_end(struct evsel *evsel,
 			    struct perf_sample *sample __maybe_unused,
 			    struct event_key *key __maybe_unused)
 {
-	return (evsel__name_is(evsel, kvm_events_tp[3]));
+	return evsel__name_is(evsel, __kvm_events_tp[3]);
 }
 
 static bool hcall_event_begin(struct evsel *evsel,
 			      struct perf_sample *sample, struct event_key *key)
 {
-	if (evsel__name_is(evsel, kvm_events_tp[2])) {
+	if (evsel__name_is(evsel, __kvm_events_tp[2])) {
 		hcall_event_get_key(evsel, sample, key);
 		return true;
 	}
@@ -82,27 +77,27 @@ static void hcall_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
 	scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", hcall_reason);
 }
 
-static struct kvm_events_ops hcall_events = {
+static const struct kvm_events_ops hcall_events = {
 	.is_begin_event = hcall_event_begin,
 	.is_end_event = hcall_event_end,
 	.decode_key = hcall_event_decode_key,
 	.name = "HCALL-EVENT",
 };
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = exit_event_begin,
 	.is_end_event = exit_event_end,
 	.decode_key = exit_event_decode_key,
 	.name = "VM-EXIT"
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{ .name = "vmexit", .ops = &exit_events },
 	{ .name = "hcall", .ops = &hcall_events },
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	NULL,
 };
 
@@ -123,7 +118,7 @@ static int is_tracepoint_available(const char *str, struct evlist *evlist)
 static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
 				struct evlist *evlist)
 {
-	const char **events_ptr;
+	const char * const *events_ptr;
 	int i, nr_tp = 0, err = -1;
 
 	/* Check for book3s_hv tracepoints */
@@ -135,10 +130,9 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
 	}
 
 	for (i = 0; i < nr_tp; i++)
-		kvm_events_tp[i] = ppc_book3s_hv_kvm_tp[i];
+		__kvm_events_tp[i] = ppc_book3s_hv_kvm_tp[i];
 
-	kvm_events_tp[i] = NULL;
-	kvm_exit_reason = "trap";
+	__kvm_events_tp[i] = NULL;
 	kvm->exit_reasons = hv_exit_reasons;
 	kvm->exit_reasons_isa = "HV";
 
@@ -157,12 +151,12 @@ static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm)
 	return ppc__setup_book3s_hv(kvm, evlist);
 }
 
-int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
+int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm)
 {
 	return ppc__setup_kvm_tp(kvm);
 }
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
+int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm)
 {
 	int ret;
 
@@ -184,7 +178,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
  *
  * Function to parse the arguments and return appropriate values.
  */
-int kvm_add_default_arch_event(int *argc, const char **argv)
+int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv)
 {
 	const char **tmp;
 	bool event = false;
@@ -217,3 +211,18 @@ int kvm_add_default_arch_event(int *argc, const char **argv)
 	free(tmp);
 	return 0;
 }
+
+const char * const *__kvm_events_tp_powerpc(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_powerpc(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_powerpc(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/riscv/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
similarity index 58%
rename from tools/perf/arch/riscv/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
index 3ea7acb5e159..b2c5d3220795 100644
--- a/tools/perf/arch/riscv/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
@@ -7,19 +7,14 @@
  */
 #include <errno.h>
 #include <memory.h>
-#include "../../../util/evsel.h"
-#include "../../../util/kvm-stat.h"
+#include "../evsel.h"
+#include "../kvm-stat.h"
 #include "riscv_trap_types.h"
 #include "debug.h"
 
 define_exit_reasons_table(riscv_exit_reasons, kvm_riscv_trap_class);
 
-const char *vcpu_id_str = "id";
-const char *kvm_exit_reason = "scause";
-const char *kvm_entry_trace = "kvm:kvm_entry";
-const char *kvm_exit_trace = "kvm:kvm_exit";
-
-const char *kvm_events_tp[] = {
+static const char * const __kvm_events_tp[] = {
 	"kvm:kvm_entry",
 	"kvm:kvm_exit",
 	NULL,
@@ -29,8 +24,10 @@ static void event_get_key(struct evsel *evsel,
 			  struct perf_sample *sample,
 			  struct event_key *key)
 {
+	int xlen = 64; // TODO: 32-bit support.
+
 	key->info = 0;
-	key->key = evsel__intval(evsel, sample, kvm_exit_reason) & ~CAUSE_IRQ_FLAG;
+	key->key = evsel__intval(evsel, sample, kvm_exit_reason()) & ~CAUSE_IRQ_FLAG(xlen);
 	key->exit_reasons = riscv_exit_reasons;
 }
 
@@ -38,28 +35,28 @@ static bool event_begin(struct evsel *evsel,
 			struct perf_sample *sample __maybe_unused,
 			struct event_key *key __maybe_unused)
 {
-	return evsel__name_is(evsel, kvm_entry_trace);
+	return evsel__name_is(evsel, kvm_entry_trace());
 }
 
 static bool event_end(struct evsel *evsel,
 		      struct perf_sample *sample,
 		      struct event_key *key)
 {
-	if (evsel__name_is(evsel, kvm_exit_trace)) {
+	if (evsel__name_is(evsel, kvm_exit_trace())) {
 		event_get_key(evsel, sample, key);
 		return true;
 	}
 	return false;
 }
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = event_begin,
 	.is_end_event	= event_end,
 	.decode_key	= exit_event_decode_key,
 	.name		= "VM-EXIT"
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{
 		.name	= "vmexit",
 		.ops	= &exit_events,
@@ -67,12 +64,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = {
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	NULL,
 };
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
+int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm)
 {
 	kvm->exit_reasons_isa = "riscv64";
 	return 0;
 }
+
+const char * const *__kvm_events_tp_riscv(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_riscv(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-s390.c
similarity index 77%
rename from tools/perf/arch/s390/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-s390.c
index 0aed92df51ba..7e29169f5bb0 100644
--- a/tools/perf/arch/s390/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-s390.c
@@ -8,9 +8,9 @@
 
 #include <errno.h>
 #include <string.h>
-#include "../../util/kvm-stat.h"
-#include "../../util/evsel.h"
-#include <asm/sie.h>
+#include "../kvm-stat.h"
+#include "../evsel.h"
+#include "../../../arch/s390/include/uapi/asm/sie.h"
 
 define_exit_reasons_table(sie_exit_reasons, sie_intercept_code);
 define_exit_reasons_table(sie_icpt_insn_codes, icpt_insn_codes);
@@ -18,16 +18,11 @@ define_exit_reasons_table(sie_sigp_order_codes, sigp_order_codes);
 define_exit_reasons_table(sie_diagnose_codes, diagnose_codes);
 define_exit_reasons_table(sie_icpt_prog_codes, icpt_prog_codes);
 
-const char *vcpu_id_str = "id";
-const char *kvm_exit_reason = "icptcode";
-const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter";
-const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit";
-
 static void event_icpt_insn_get_key(struct evsel *evsel,
 				    struct perf_sample *sample,
 				    struct event_key *key)
 {
-	unsigned long insn;
+	u64 insn;
 
 	insn = evsel__intval(evsel, sample, "instruction");
 	key->key = icpt_insn_decoder(insn);
@@ -58,7 +53,7 @@ static void event_icpt_prog_get_key(struct evsel *evsel,
 	key->exit_reasons = sie_icpt_prog_codes;
 }
 
-static struct child_event_ops child_events[] = {
+static const struct child_event_ops child_events[] = {
 	{ .name = "kvm:kvm_s390_intercept_instruction",
 	  .get_key = event_icpt_insn_get_key },
 	{ .name = "kvm:kvm_s390_handle_sigp",
@@ -70,7 +65,7 @@ static struct child_event_ops child_events[] = {
 	{ NULL, NULL },
 };
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = exit_event_begin,
 	.is_end_event = exit_event_end,
 	.child_ops = child_events,
@@ -78,7 +73,7 @@ static struct kvm_events_ops exit_events = {
 	.name = "VM-EXIT"
 };
 
-const char *kvm_events_tp[] = {
+static const char * const __kvm_events_tp[] = {
 	"kvm:kvm_s390_sie_enter",
 	"kvm:kvm_s390_sie_exit",
 	"kvm:kvm_s390_intercept_instruction",
@@ -88,17 +83,17 @@ const char *kvm_events_tp[] = {
 	NULL,
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{ .name = "vmexit", .ops = &exit_events },
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	"Wait state",
 	NULL,
 };
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+int __cpu_isa_init_s390(struct perf_kvm_stat *kvm, const char *cpuid)
 {
 	if (strstr(cpuid, "IBM")) {
 		kvm->exit_reasons = sie_exit_reasons;
@@ -108,3 +103,18 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
 
 	return 0;
 }
+
+const char * const *__kvm_events_tp_s390(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_s390(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_s390(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
similarity index 88%
rename from tools/perf/arch/x86/util/kvm-stat.c
rename to tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
index bff36f9345ea..1cf541385a4b 100644
--- a/tools/perf/arch/x86/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c
@@ -1,9 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
 #include <string.h>
-#include "../../../util/kvm-stat.h"
-#include "../../../util/evsel.h"
-#include "../../../util/env.h"
+#include "../kvm-stat.h"
+#include "../evsel.h"
+#include "../env.h"
 #include <asm/svm.h>
 #include <asm/vmx.h>
 #include <asm/kvm.h>
@@ -12,18 +12,13 @@
 define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
 define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
 
-static struct kvm_events_ops exit_events = {
+static const struct kvm_events_ops exit_events = {
 	.is_begin_event = exit_event_begin,
 	.is_end_event = exit_event_end,
 	.decode_key = exit_event_decode_key,
 	.name = "VM-EXIT"
 };
 
-const char *vcpu_id_str = "vcpu_id";
-const char *kvm_exit_reason = "exit_reason";
-const char *kvm_entry_trace = "kvm:kvm_entry";
-const char *kvm_exit_trace = "kvm:kvm_exit";
-
 /*
  * For the mmio events, we treat:
  * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry
@@ -83,7 +78,7 @@ static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
 		  key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R");
 }
 
-static struct kvm_events_ops mmio_events = {
+static const struct kvm_events_ops mmio_events = {
 	.is_begin_event = mmio_event_begin,
 	.is_end_event = mmio_event_end,
 	.decode_key = mmio_event_decode_key,
@@ -127,7 +122,7 @@ static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
 		  key->info ? "POUT" : "PIN");
 }
 
-static struct kvm_events_ops ioport_events = {
+static const struct kvm_events_ops ioport_events = {
 	.is_begin_event = ioport_event_begin,
 	.is_end_event = ioport_event_end,
 	.decode_key = ioport_event_decode_key,
@@ -171,14 +166,14 @@ static void msr_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused,
 		  key->info ? "W" : "R");
 }
 
-static struct kvm_events_ops msr_events = {
+static const struct kvm_events_ops msr_events = {
 	.is_begin_event = msr_event_begin,
 	.is_end_event = msr_event_end,
 	.decode_key = msr_event_decode_key,
 	.name = "MSR Access"
 };
 
-const char *kvm_events_tp[] = {
+static const char * const __kvm_events_tp[] = {
 	"kvm:kvm_entry",
 	"kvm:kvm_exit",
 	"kvm:kvm_mmio",
@@ -187,7 +182,7 @@ const char *kvm_events_tp[] = {
 	NULL,
 };
 
-struct kvm_reg_events_ops kvm_reg_events_ops[] = {
+static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = {
 	{ .name = "vmexit", .ops = &exit_events },
 	{ .name = "mmio", .ops = &mmio_events },
 	{ .name = "ioport", .ops = &ioport_events },
@@ -195,12 +190,12 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = {
 	{ NULL, NULL },
 };
 
-const char * const kvm_skip_events[] = {
+static const char * const __kvm_skip_events[] = {
 	"HLT",
 	NULL,
 };
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid)
 {
 	if (strstr(cpuid, "Intel")) {
 		kvm->exit_reasons = vmx_exit_reasons;
@@ -226,7 +221,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
  * So, to avoid this issue explicitly use "cycles" instead of "cycles:P" event
  * by default to sample guest on Intel platforms.
  */
-int kvm_add_default_arch_event(int *argc, const char **argv)
+int __kvm_add_default_arch_event_x86(int *argc, const char **argv)
 {
 	const char **tmp;
 	bool event = false;
@@ -262,3 +257,18 @@ int kvm_add_default_arch_event(int *argc, const char **argv)
 	free(tmp);
 	return ret;
 }
+
+const char * const *__kvm_events_tp_x86(void)
+{
+	return __kvm_events_tp;
+}
+
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_x86(void)
+{
+	return __kvm_reg_events_ops;
+}
+
+const char * const *__kvm_skip_events_x86(void)
+{
+	return __kvm_skip_events;
+}
diff --git a/tools/perf/arch/riscv/util/riscv_trap_types.h b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
similarity index 96%
rename from tools/perf/arch/riscv/util/riscv_trap_types.h
rename to tools/perf/util/kvm-stat-arch/riscv_trap_types.h
index 6cc71eb01fca..aa5d24fab4ee 100644
--- a/tools/perf/arch/riscv/util/riscv_trap_types.h
+++ b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h
@@ -3,7 +3,7 @@
 #define ARCH_PERF_RISCV_TRAP_TYPES_H
 
 /* Exception cause high bit - is an interrupt if set */
-#define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
+#define CAUSE_IRQ_FLAG(xlen)		(_AC(1, UL) << (xlen - 1))
 
 /* Interrupt causes (minus the high bit) */
 #define IRQ_S_SOFT 1
diff --git a/tools/perf/util/kvm-stat.c b/tools/perf/util/kvm-stat.c
index 38ace736db5c..b1affd97917b 100644
--- a/tools/perf/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat.c
@@ -2,12 +2,11 @@
 #include "debug.h"
 #include "evsel.h"
 #include "kvm-stat.h"
-
-#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#include <dwarf-regs.h>
 
 bool kvm_exit_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_exit_trace);
+	return evsel__name_is(evsel, kvm_exit_trace());
 }
 
 void exit_event_get_key(struct evsel *evsel,
@@ -15,7 +14,7 @@ void exit_event_get_key(struct evsel *evsel,
 			struct event_key *key)
 {
 	key->info = 0;
-	key->key  = evsel__intval(evsel, sample, kvm_exit_reason);
+	key->key  = evsel__intval(evsel, sample, kvm_exit_reason());
 }
 
 
@@ -32,7 +31,7 @@ bool exit_event_begin(struct evsel *evsel,
 
 bool kvm_entry_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_entry_trace);
+	return evsel__name_is(evsel, kvm_entry_trace());
 }
 
 bool exit_event_end(struct evsel *evsel,
@@ -67,4 +66,202 @@ void exit_event_decode_key(struct perf_kvm_stat *kvm,
 	scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", exit_reason);
 }
 
-#endif
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
+{
+	switch (EM_HOST) {
+	case EM_PPC:
+	case EM_PPC64:
+		return __setup_kvm_events_tp_powerpc(kvm);
+	default:
+		return 0;
+	}
+}
+
+int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+		return __cpu_isa_init_arm64(kvm);
+	case EM_LOONGARCH:
+		return __cpu_isa_init_loongarch(kvm);
+	case EM_PPC:
+	case EM_PPC64:
+		return __cpu_isa_init_powerpc(kvm);
+	case EM_RISCV:
+		return __cpu_isa_init_riscv(kvm);
+	case EM_S390:
+		return __cpu_isa_init_s390(kvm, cpuid);
+	case EM_X86_64:
+	case EM_386:
+		return __cpu_isa_init_x86(kvm, cpuid);
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return -1;
+	}
+}
+
+const char *vcpu_id_str(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+	case EM_RISCV:
+	case EM_S390:
+		return "id";
+	case EM_LOONGARCH:
+	case EM_PPC:
+	case EM_PPC64:
+	case EM_X86_64:
+	case EM_386:
+		return "vcpu_id";
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const char *kvm_exit_reason(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+		return "ret";
+	case EM_LOONGARCH:
+		return "reason";
+	case EM_PPC:
+	case EM_PPC64:
+		return "trap";
+	case EM_RISCV:
+		return "scause";
+	case EM_S390:
+		return "icptcode";
+	case EM_X86_64:
+	case EM_386:
+		return "exit_reason";
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const char *kvm_entry_trace(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+	case EM_RISCV:
+	case EM_X86_64:
+	case EM_386:
+		return "kvm:kvm_entry";
+	case EM_LOONGARCH:
+		return "kvm:kvm_enter";
+	case EM_PPC:
+	case EM_PPC64:
+		return "kvm_hv:kvm_guest_enter";
+	case EM_S390:
+		return "kvm:kvm_s390_sie_enter";
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const char *kvm_exit_trace(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+	case EM_LOONGARCH:
+	case EM_RISCV:
+	case EM_X86_64:
+	case EM_386:
+		return "kvm:kvm_exit";
+	case EM_PPC:
+	case EM_PPC64:
+		return "kvm_hv:kvm_guest_exit";
+	case EM_S390:
+		return "kvm:kvm_s390_sie_exit";
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const char * const *kvm_events_tp(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+		return __kvm_events_tp_arm64();
+	case EM_LOONGARCH:
+		return __kvm_events_tp_loongarch();
+	case EM_PPC:
+	case EM_PPC64:
+		return __kvm_events_tp_powerpc();
+	case EM_RISCV:
+		return __kvm_events_tp_riscv();
+	case EM_S390:
+		return __kvm_events_tp_s390();
+	case EM_X86_64:
+	case EM_386:
+		return __kvm_events_tp_x86();
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const struct kvm_reg_events_ops *kvm_reg_events_ops(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+		return __kvm_reg_events_ops_arm64();
+	case EM_LOONGARCH:
+		return __kvm_reg_events_ops_loongarch();
+	case EM_PPC:
+	case EM_PPC64:
+		return __kvm_reg_events_ops_powerpc();
+	case EM_RISCV:
+		return __kvm_reg_events_ops_riscv();
+	case EM_S390:
+		return __kvm_reg_events_ops_s390();
+	case EM_X86_64:
+	case EM_386:
+		return __kvm_reg_events_ops_x86();
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+const char * const *kvm_skip_events(void)
+{
+	switch (EM_HOST) {
+	case EM_AARCH64:
+		return __kvm_skip_events_arm64();
+	case EM_LOONGARCH:
+		return __kvm_skip_events_loongarch();
+	case EM_PPC:
+	case EM_PPC64:
+		return __kvm_skip_events_powerpc();
+	case EM_RISCV:
+		return __kvm_skip_events_riscv();
+	case EM_S390:
+		return __kvm_skip_events_s390();
+	case EM_X86_64:
+	case EM_386:
+		return __kvm_skip_events_x86();
+	default:
+		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		return NULL;
+	}
+}
+
+int kvm_add_default_arch_event(int *argc, const char **argv)
+{
+	switch (EM_HOST) {
+	case EM_PPC:
+	case EM_PPC64:
+		return __kvm_add_default_arch_event_powerpc(argc, argv);
+	case EM_X86_64:
+	case EM_386:
+		return __kvm_add_default_arch_event_x86(argc, argv);
+	default:
+		return 0;
+	}
+}
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index a356b839c2ee..759079b4294c 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -2,8 +2,6 @@
 #ifndef __PERF_KVM_STAT_H
 #define __PERF_KVM_STAT_H
 
-#ifdef HAVE_KVM_STAT_SUPPORT
-
 #include "tool.h"
 #include "sort.h"
 #include "stat.h"
@@ -67,7 +65,7 @@ struct kvm_events_ops {
 			       struct event_key *key);
 	bool (*is_end_event)(struct evsel *evsel,
 			     struct perf_sample *sample, struct event_key *key);
-	struct child_event_ops *child_ops;
+	const struct child_event_ops *child_ops;
 	void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key,
 			   char *decode);
 	const char *name;
@@ -95,7 +93,7 @@ struct perf_kvm_stat {
 	struct exit_reasons_table *exit_reasons;
 	const char *exit_reasons_isa;
 
-	struct kvm_events_ops *events_ops;
+	const struct kvm_events_ops *events_ops;
 
 	u64 total_time;
 	u64 total_count;
@@ -113,10 +111,10 @@ struct perf_kvm_stat {
 
 struct kvm_reg_events_ops {
 	const char *name;
-	struct kvm_events_ops *ops;
+	const struct kvm_events_ops *ops;
 };
 
-#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#ifdef HAVE_LIBTRACEEVENT
 
 void exit_event_get_key(struct evsel *evsel,
 			struct perf_sample *sample,
@@ -130,11 +128,9 @@ bool exit_event_end(struct evsel *evsel,
 void exit_event_decode_key(struct perf_kvm_stat *kvm,
 			   struct event_key *key,
 			   char *decode);
-#endif
 
 bool kvm_exit_event(struct evsel *evsel);
 bool kvm_entry_event(struct evsel *evsel);
-int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
 
 #define define_exit_reasons_table(name, symbols)	\
 	static struct exit_reasons_table name[] = {	\
@@ -144,15 +140,59 @@ int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
 /*
  * arch specific callbacks and data structures
  */
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
+int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm);
+
 int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid);
+int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm);
+int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm);
+int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm);
+int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm);
+int __cpu_isa_init_s390(struct perf_kvm_stat *kvm, const char *cpuid);
+int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid);
+
+const char *vcpu_id_str(void);
+const char *kvm_exit_reason(void);
+const char *kvm_entry_trace(void);
+const char *kvm_exit_trace(void);
+
+const char * const *kvm_events_tp(void);
+const char * const *__kvm_events_tp_arm64(void);
+const char * const *__kvm_events_tp_loongarch(void);
+const char * const *__kvm_events_tp_powerpc(void);
+const char * const *__kvm_events_tp_riscv(void);
+const char * const *__kvm_events_tp_s390(void);
+const char * const *__kvm_events_tp_x86(void);
+
+const struct kvm_reg_events_ops *kvm_reg_events_ops(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_arm64(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_loongarch(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_powerpc(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_s390(void);
+const struct kvm_reg_events_ops *__kvm_reg_events_ops_x86(void);
+
+const char * const *kvm_skip_events(void);
+const char * const *__kvm_skip_events_arm64(void);
+const char * const *__kvm_skip_events_loongarch(void);
+const char * const *__kvm_skip_events_powerpc(void);
+const char * const *__kvm_skip_events_riscv(void);
+const char * const *__kvm_skip_events_s390(void);
+const char * const *__kvm_skip_events_x86(void);
+
+int kvm_add_default_arch_event(int *argc, const char **argv);
+int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv);
+int __kvm_add_default_arch_event_x86(int *argc, const char **argv);
+
+#else /* !HAVE_LIBTRACEEVENT */
+
+static inline int kvm_add_default_arch_event(int *argc __maybe_unused,
+					     const char **argv __maybe_unused)
+{
+	return 0;
+}
 
-extern const char *kvm_events_tp[];
-extern struct kvm_reg_events_ops kvm_reg_events_ops[];
-extern const char * const kvm_skip_events[];
-extern const char *vcpu_id_str;
-extern const char *kvm_exit_reason;
-extern const char *kvm_entry_trace;
-extern const char *kvm_exit_trace;
+#endif /* HAVE_LIBTRACEEVENT */
 
 static inline struct kvm_info *kvm_info__get(struct kvm_info *ki)
 {
@@ -186,11 +226,6 @@ static inline struct kvm_info *kvm_info__new(void)
 	return ki;
 }
 
-#else /* HAVE_KVM_STAT_SUPPORT */
-// We use this unconditionally in hists__findnew_entry() and hist_entry__delete()
-#define kvm_info__zput(ki) do { } while (0)
-#endif /* HAVE_KVM_STAT_SUPPORT */
-
 #define STRDUP_FAIL_EXIT(s)		\
 	({	char *_p;		\
 		_p = strdup(s);		\
@@ -201,5 +236,4 @@ static inline struct kvm_info *kvm_info__new(void)
 		_p;			\
 	})
 
-extern int kvm_add_default_arch_event(int *argc, const char **argv);
 #endif /* __PERF_KVM_STAT_H */
-- 
2.53.0.rc2.204.g2597b5adb4-goog
[PATCH v3 2/5] perf kvm: Wire up e_machine
Posted by Ian Rogers 3 days, 16 hours ago
Pass the e_machine to the kvm functions so that they aren't just wired
to EM_HOST. In the case of a session move some setup until the session
is created. As the session isn't fully running the default EM_HOST is
returned as no e_machine can be found in a running machine. This is,
however, some marginal progress to cross platform support.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-kvm.c                      | 45 ++++++++------
 tools/perf/util/evsel.c                       |  2 +-
 tools/perf/util/evsel.h                       |  1 +
 .../perf/util/kvm-stat-arch/kvm-stat-arm64.c  |  6 +-
 .../util/kvm-stat-arch/kvm-stat-loongarch.c   |  3 +-
 .../perf/util/kvm-stat-arch/kvm-stat-riscv.c  |  6 +-
 tools/perf/util/kvm-stat.c                    | 62 +++++++++----------
 tools/perf/util/kvm-stat.h                    | 23 +++----
 8 files changed, 80 insertions(+), 68 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index bd9bda32157f..93ba07c58290 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -2,6 +2,7 @@
 #include "builtin.h"
 #include "perf.h"
 
+#include <dwarf-regs.h>
 #include "util/build-id.h"
 #include "util/evsel.h"
 #include "util/evlist.h"
@@ -615,11 +616,11 @@ static const char *get_filename_for_perf_kvm(void)
 
 #if defined(HAVE_LIBTRACEEVENT)
 
-static bool register_kvm_events_ops(struct perf_kvm_stat *kvm)
+static bool register_kvm_events_ops(struct perf_kvm_stat *kvm, uint16_t e_machine)
 {
 	const struct kvm_reg_events_ops *events_ops;
 
-	for (events_ops = kvm_reg_events_ops(); events_ops->name; events_ops++) {
+	for (events_ops = kvm_reg_events_ops(e_machine); events_ops->name; events_ops++) {
 		if (!strcmp(events_ops->name, kvm->report_event)) {
 			kvm->events_ops = events_ops->ops;
 			return true;
@@ -841,11 +842,11 @@ static bool handle_child_event(struct perf_kvm_stat *kvm,
 	return true;
 }
 
-static bool skip_event(const char *event)
+static bool skip_event(uint16_t e_machine, const char *event)
 {
 	const char * const *skip_events;
 
-	for (skip_events = kvm_skip_events(); *skip_events; skip_events++)
+	for (skip_events = kvm_skip_events(e_machine); *skip_events; skip_events++)
 		if (!strcmp(event, *skip_events))
 			return true;
 
@@ -901,9 +902,10 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
 
 	if (kvm->duration && time_diff > kvm->duration) {
 		char decode[KVM_EVENT_NAME_LEN];
+		uint16_t e_machine = perf_session__e_machine(kvm->session);
 
 		kvm->events_ops->decode_key(kvm, &event->key, decode);
-		if (!skip_event(decode)) {
+		if (!skip_event(e_machine, decode)) {
 			pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
 				 sample->time, sample->pid, vcpu_record->vcpu_id,
 				 decode, time_diff / NSEC_PER_USEC);
@@ -921,6 +923,8 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
 	/* Only kvm_entry records vcpu id. */
 	if (!thread__priv(thread) && kvm_entry_event(evsel)) {
 		struct vcpu_event_record *vcpu_record;
+		struct machine *machine = maps__machine(thread__maps(thread));
+		uint16_t e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL);
 
 		vcpu_record = zalloc(sizeof(*vcpu_record));
 		if (!vcpu_record) {
@@ -928,7 +932,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
 			return NULL;
 		}
 
-		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str());
+		vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str(e_machine));
 		thread__set_priv(thread, vcpu_record);
 	}
 
@@ -1163,6 +1167,7 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 {
 	char buf[128], *cpuid;
 	int err;
+	uint16_t e_machine;
 
 	if (kvm->live) {
 		struct perf_cpu cpu = {-1};
@@ -1182,7 +1187,8 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 		return -EINVAL;
 	}
 
-	err = cpu_isa_init(kvm, cpuid);
+	e_machine = perf_session__e_machine(kvm->session);
+	err = cpu_isa_init(kvm, e_machine, cpuid);
 	if (err == -ENOTSUP)
 		pr_err("CPU %s is not supported.\n", cpuid);
 
@@ -1413,7 +1419,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 
 	if (!verify_vcpu(kvm->trace_vcpu) ||
 	    !is_valid_key(kvm) ||
-	    !register_kvm_events_ops(kvm)) {
+		!register_kvm_events_ops(kvm, EM_HOST)) {
 		goto out;
 	}
 
@@ -1568,6 +1574,11 @@ static int read_events(struct perf_kvm_stat *kvm)
 		goto out_delete;
 	}
 
+	if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session))) {
+		ret = -EINVAL;
+		goto out_delete;
+	}
+
 	/*
 	 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
 	 * traced in the old kernel.
@@ -1610,9 +1621,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
 	if (!is_valid_key(kvm))
 		goto exit;
 
-	if (!register_kvm_events_ops(kvm))
-		goto exit;
-
 	if (kvm->use_stdio) {
 		use_browser = 0;
 		setup_pager();
@@ -1653,15 +1661,16 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 	};
 	const char * const *events_tp;
 	int ret;
+	uint16_t e_machine = EM_HOST;
 
 	events_tp_size = 0;
-	ret = setup_kvm_events_tp(kvm);
+	ret = setup_kvm_events_tp(kvm, e_machine);
 	if (ret < 0) {
 		pr_err("Unable to setup the kvm tracepoints\n");
 		return ret;
 	}
 
-	for (events_tp = kvm_events_tp(); *events_tp; events_tp++)
+	for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++)
 		events_tp_size++;
 
 	rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
@@ -1676,7 +1685,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 
 	for (j = 0; j < events_tp_size; j++) {
 		rec_argv[i++] = STRDUP_FAIL_EXIT("-e");
-		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp()[j]);
+		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]);
 	}
 
 	rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
@@ -1770,7 +1779,7 @@ static struct evlist *kvm_live_event_list(void)
 	if (evlist == NULL)
 		return NULL;
 
-	for (events_tp = kvm_events_tp(); *events_tp; events_tp++) {
+	for (events_tp = kvm_events_tp(EM_HOST); *events_tp; events_tp++) {
 
 		tp = strdup(*events_tp);
 		if (tp == NULL)
@@ -1895,7 +1904,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
 	/*
 	 * generate the event list
 	 */
-	err = setup_kvm_events_tp(kvm);
+	err = setup_kvm_events_tp(kvm, EM_HOST);
 	if (err < 0) {
 		pr_err("Unable to setup the kvm tracepoints\n");
 		return err;
@@ -2005,7 +2014,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv)
 
 	BUG_ON(i + 2 != rec_argc);
 
-	ret = kvm_add_default_arch_event(&i, rec_argv);
+	ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
 	if (ret)
 		goto EXIT;
 
@@ -2092,7 +2101,7 @@ static int __cmd_top(int argc, const char **argv)
 
 	BUG_ON(i != argc);
 
-	ret = kvm_add_default_arch_event(&i, rec_argv);
+	ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv);
 	if (ret)
 		goto EXIT;
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5ac1a05601b1..848d0faf6698 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1008,7 +1008,7 @@ int evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
 	return ret;
 }
 
-static uint16_t evsel__e_machine(struct evsel *evsel)
+uint16_t evsel__e_machine(struct evsel *evsel)
 {
 	struct perf_session *session = evsel__session(evsel);
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 95c4bd0f0f2e..eefb5d569971 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -546,6 +546,7 @@ static inline bool evsel__is_dummy_event(struct evsel *evsel)
 
 struct perf_session *evsel__session(struct evsel *evsel);
 struct perf_env *evsel__env(struct evsel *evsel);
+uint16_t evsel__e_machine(struct evsel *evsel);
 
 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
 
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
index 8003ff415b1a..c640dcd8af7c 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c
@@ -22,7 +22,7 @@ static void event_get_key(struct evsel *evsel,
 			  struct event_key *key)
 {
 	key->info = 0;
-	key->key = evsel__intval(evsel, sample, kvm_exit_reason());
+	key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_AARCH64));
 	key->exit_reasons = arm64_exit_reasons;
 
 	/*
@@ -40,14 +40,14 @@ static bool event_begin(struct evsel *evsel,
 			struct perf_sample *sample __maybe_unused,
 			struct event_key *key __maybe_unused)
 {
-	return evsel__name_is(evsel, kvm_entry_trace());
+	return evsel__name_is(evsel, kvm_entry_trace(EM_AARCH64));
 }
 
 static bool event_end(struct evsel *evsel,
 		      struct perf_sample *sample,
 		      struct event_key *key)
 {
-	if (evsel__name_is(evsel, kvm_exit_trace())) {
+	if (evsel__name_is(evsel, kvm_exit_trace(EM_AARCH64))) {
 		event_get_key(evsel, sample, key);
 		return true;
 	}
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
index a15ce072ac34..b802e516b138 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
 #include <memory.h>
+#include <dwarf-regs.h>
 #include "../kvm-stat.h"
 #include "../parse-events.h"
 #include "../debug.h"
@@ -70,7 +71,7 @@ static bool event_end(struct evsel *evsel,
 	 *   kvm:kvm_enter   means returning to vmm and then to guest
 	 *   kvm:kvm_reenter means returning to guest immediately
 	 */
-	return evsel__name_is(evsel, kvm_entry_trace()) ||
+	return evsel__name_is(evsel, kvm_entry_trace(EM_LOONGARCH)) ||
 	       evsel__name_is(evsel, kvm_reenter_trace);
 }
 
diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
index b2c5d3220795..8d4d5d6ce720 100644
--- a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
+++ b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c
@@ -27,7 +27,7 @@ static void event_get_key(struct evsel *evsel,
 	int xlen = 64; // TODO: 32-bit support.
 
 	key->info = 0;
-	key->key = evsel__intval(evsel, sample, kvm_exit_reason()) & ~CAUSE_IRQ_FLAG(xlen);
+	key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen);
 	key->exit_reasons = riscv_exit_reasons;
 }
 
@@ -35,14 +35,14 @@ static bool event_begin(struct evsel *evsel,
 			struct perf_sample *sample __maybe_unused,
 			struct event_key *key __maybe_unused)
 {
-	return evsel__name_is(evsel, kvm_entry_trace());
+	return evsel__name_is(evsel, kvm_entry_trace(EM_RISCV));
 }
 
 static bool event_end(struct evsel *evsel,
 		      struct perf_sample *sample,
 		      struct event_key *key)
 {
-	if (evsel__name_is(evsel, kvm_exit_trace())) {
+	if (evsel__name_is(evsel, kvm_exit_trace(EM_RISCV))) {
 		event_get_key(evsel, sample, key);
 		return true;
 	}
diff --git a/tools/perf/util/kvm-stat.c b/tools/perf/util/kvm-stat.c
index b1affd97917b..858b5dbd39f6 100644
--- a/tools/perf/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat.c
@@ -6,7 +6,7 @@
 
 bool kvm_exit_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_exit_trace());
+	return evsel__name_is(evsel, kvm_exit_trace(evsel__e_machine(evsel)));
 }
 
 void exit_event_get_key(struct evsel *evsel,
@@ -14,7 +14,7 @@ void exit_event_get_key(struct evsel *evsel,
 			struct event_key *key)
 {
 	key->info = 0;
-	key->key  = evsel__intval(evsel, sample, kvm_exit_reason());
+	key->key  = evsel__intval(evsel, sample, kvm_exit_reason(evsel__e_machine(evsel)));
 }
 
 
@@ -31,7 +31,7 @@ bool exit_event_begin(struct evsel *evsel,
 
 bool kvm_entry_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_entry_trace());
+	return evsel__name_is(evsel, kvm_entry_trace(evsel__e_machine(evsel)));
 }
 
 bool exit_event_end(struct evsel *evsel,
@@ -66,9 +66,9 @@ void exit_event_decode_key(struct perf_kvm_stat *kvm,
 	scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", exit_reason);
 }
 
-int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm, uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_PPC:
 	case EM_PPC64:
 		return __setup_kvm_events_tp_powerpc(kvm);
@@ -77,9 +77,9 @@ int setup_kvm_events_tp(struct perf_kvm_stat *kvm)
 	}
 }
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+int cpu_isa_init(struct perf_kvm_stat *kvm, uint16_t e_machine, const char *cpuid)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 		return __cpu_isa_init_arm64(kvm);
 	case EM_LOONGARCH:
@@ -95,14 +95,14 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
 	case EM_386:
 		return __cpu_isa_init_x86(kvm, cpuid);
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return -1;
 	}
 }
 
-const char *vcpu_id_str(void)
+const char *vcpu_id_str(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 	case EM_RISCV:
 	case EM_S390:
@@ -114,14 +114,14 @@ const char *vcpu_id_str(void)
 	case EM_386:
 		return "vcpu_id";
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const char *kvm_exit_reason(void)
+const char *kvm_exit_reason(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 		return "ret";
 	case EM_LOONGARCH:
@@ -137,14 +137,14 @@ const char *kvm_exit_reason(void)
 	case EM_386:
 		return "exit_reason";
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const char *kvm_entry_trace(void)
+const char *kvm_entry_trace(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 	case EM_RISCV:
 	case EM_X86_64:
@@ -158,14 +158,14 @@ const char *kvm_entry_trace(void)
 	case EM_S390:
 		return "kvm:kvm_s390_sie_enter";
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const char *kvm_exit_trace(void)
+const char *kvm_exit_trace(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 	case EM_LOONGARCH:
 	case EM_RISCV:
@@ -178,14 +178,14 @@ const char *kvm_exit_trace(void)
 	case EM_S390:
 		return "kvm:kvm_s390_sie_exit";
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const char * const *kvm_events_tp(void)
+const char * const *kvm_events_tp(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 		return __kvm_events_tp_arm64();
 	case EM_LOONGARCH:
@@ -201,14 +201,14 @@ const char * const *kvm_events_tp(void)
 	case EM_386:
 		return __kvm_events_tp_x86();
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const struct kvm_reg_events_ops *kvm_reg_events_ops(void)
+const struct kvm_reg_events_ops *kvm_reg_events_ops(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 		return __kvm_reg_events_ops_arm64();
 	case EM_LOONGARCH:
@@ -224,14 +224,14 @@ const struct kvm_reg_events_ops *kvm_reg_events_ops(void)
 	case EM_386:
 		return __kvm_reg_events_ops_x86();
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-const char * const *kvm_skip_events(void)
+const char * const *kvm_skip_events(uint16_t e_machine)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_AARCH64:
 		return __kvm_skip_events_arm64();
 	case EM_LOONGARCH:
@@ -247,14 +247,14 @@ const char * const *kvm_skip_events(void)
 	case EM_386:
 		return __kvm_skip_events_x86();
 	default:
-		pr_err("Unsupported kvm-stat host %d\n", EM_HOST);
+		pr_err("Unsupported kvm-stat host %d\n", e_machine);
 		return NULL;
 	}
 }
 
-int kvm_add_default_arch_event(int *argc, const char **argv)
+int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv)
 {
-	switch (EM_HOST) {
+	switch (e_machine) {
 	case EM_PPC:
 	case EM_PPC64:
 		return __kvm_add_default_arch_event_powerpc(argc, argv);
diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h
index 759079b4294c..4a998aaece5d 100644
--- a/tools/perf/util/kvm-stat.h
+++ b/tools/perf/util/kvm-stat.h
@@ -140,10 +140,10 @@ bool kvm_entry_event(struct evsel *evsel);
 /*
  * arch specific callbacks and data structures
  */
-int setup_kvm_events_tp(struct perf_kvm_stat *kvm);
+int setup_kvm_events_tp(struct perf_kvm_stat *kvm, uint16_t e_machine);
 int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm);
 
-int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid);
+int cpu_isa_init(struct perf_kvm_stat *kvm, uint16_t e_machine, const char *cpuid);
 int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm);
 int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm);
 int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm);
@@ -151,12 +151,12 @@ int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm);
 int __cpu_isa_init_s390(struct perf_kvm_stat *kvm, const char *cpuid);
 int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid);
 
-const char *vcpu_id_str(void);
-const char *kvm_exit_reason(void);
-const char *kvm_entry_trace(void);
-const char *kvm_exit_trace(void);
+const char *vcpu_id_str(uint16_t e_machine);
+const char *kvm_exit_reason(uint16_t e_machine);
+const char *kvm_entry_trace(uint16_t e_machine);
+const char *kvm_exit_trace(uint16_t e_machine);
 
-const char * const *kvm_events_tp(void);
+const char * const *kvm_events_tp(uint16_t e_machine);
 const char * const *__kvm_events_tp_arm64(void);
 const char * const *__kvm_events_tp_loongarch(void);
 const char * const *__kvm_events_tp_powerpc(void);
@@ -164,7 +164,7 @@ const char * const *__kvm_events_tp_riscv(void);
 const char * const *__kvm_events_tp_s390(void);
 const char * const *__kvm_events_tp_x86(void);
 
-const struct kvm_reg_events_ops *kvm_reg_events_ops(void);
+const struct kvm_reg_events_ops *kvm_reg_events_ops(uint16_t e_machine);
 const struct kvm_reg_events_ops *__kvm_reg_events_ops_arm64(void);
 const struct kvm_reg_events_ops *__kvm_reg_events_ops_loongarch(void);
 const struct kvm_reg_events_ops *__kvm_reg_events_ops_powerpc(void);
@@ -172,7 +172,7 @@ const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void);
 const struct kvm_reg_events_ops *__kvm_reg_events_ops_s390(void);
 const struct kvm_reg_events_ops *__kvm_reg_events_ops_x86(void);
 
-const char * const *kvm_skip_events(void);
+const char * const *kvm_skip_events(uint16_t e_machine);
 const char * const *__kvm_skip_events_arm64(void);
 const char * const *__kvm_skip_events_loongarch(void);
 const char * const *__kvm_skip_events_powerpc(void);
@@ -180,13 +180,14 @@ const char * const *__kvm_skip_events_riscv(void);
 const char * const *__kvm_skip_events_s390(void);
 const char * const *__kvm_skip_events_x86(void);
 
-int kvm_add_default_arch_event(int *argc, const char **argv);
+int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv);
 int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv);
 int __kvm_add_default_arch_event_x86(int *argc, const char **argv);
 
 #else /* !HAVE_LIBTRACEEVENT */
 
-static inline int kvm_add_default_arch_event(int *argc __maybe_unused,
+static inline int kvm_add_default_arch_event(uint16_t e_machine __maybe_unused,
+					     int *argc __maybe_unused,
 					     const char **argv __maybe_unused)
 {
 	return 0;
-- 
2.53.0.rc2.204.g2597b5adb4-goog
[PATCH v3 3/5] perf session: Add e_flags to the e_machine helper
Posted by Ian Rogers 3 days, 16 hours ago
Allow e_flags as well as e_machine to be computed using the e_machine
helper. This isn't currently used, the argument is always NULL, but it
will be used for a new header feature.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-kvm.c    |  9 +++++----
 tools/perf/builtin-report.c |  4 ++--
 tools/perf/builtin-script.c |  6 ++++--
 tools/perf/util/evsel.c     |  6 +++---
 tools/perf/util/evsel.h     |  2 +-
 tools/perf/util/kvm-stat.c  | 12 ++++++++---
 tools/perf/util/session.c   | 40 +++++++++++++++++++++++++++----------
 tools/perf/util/session.h   |  2 +-
 8 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 93ba07c58290..0c5e6b3aac74 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -902,7 +902,7 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
 
 	if (kvm->duration && time_diff > kvm->duration) {
 		char decode[KVM_EVENT_NAME_LEN];
-		uint16_t e_machine = perf_session__e_machine(kvm->session);
+		uint16_t e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL);
 
 		kvm->events_ops->decode_key(kvm, &event->key, decode);
 		if (!skip_event(e_machine, decode)) {
@@ -1187,7 +1187,7 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 		return -EINVAL;
 	}
 
-	e_machine = perf_session__e_machine(kvm->session);
+	e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL);
 	err = cpu_isa_init(kvm, e_machine, cpuid);
 	if (err == -ENOTSUP)
 		pr_err("CPU %s is not supported.\n", cpuid);
@@ -1549,7 +1549,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
 static int read_events(struct perf_kvm_stat *kvm)
 {
 	int ret;
-
+	uint16_t e_machine;
 	struct perf_data file = {
 		.path  = kvm->file_name,
 		.mode  = PERF_DATA_MODE_READ,
@@ -1574,7 +1574,8 @@ static int read_events(struct perf_kvm_stat *kvm)
 		goto out_delete;
 	}
 
-	if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session))) {
+	e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL);
+	if (!register_kvm_events_ops(kvm, e_machine)) {
 		ret = -EINVAL;
 		goto out_delete;
 	}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 810ffd66b11c..3b81f4b3dc49 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -448,7 +448,7 @@ static int report__setup_sample_type(struct report *rep)
 		}
 	}
 
-	callchain_param_setup(sample_type, perf_session__e_machine(session));
+	callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL));
 
 	if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
 		ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
@@ -1296,7 +1296,7 @@ static int process_attr(const struct perf_tool *tool __maybe_unused,
 	 */
 	sample_type = evlist__combined_sample_type(*pevlist);
 	session = (*pevlist)->session;
-	callchain_param_setup(sample_type, perf_session__e_machine(session));
+	callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL));
 	return 0;
 }
 
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index c7d5a325b5cb..14c6f6c3c4f2 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2818,6 +2818,7 @@ static int process_attr(const struct perf_tool *tool, union perf_event *event,
 	struct perf_script *scr = container_of(tool, struct perf_script, tool);
 	struct evlist *evlist;
 	struct evsel *evsel, *pos;
+	uint16_t e_machine;
 	u64 sample_type;
 	int err;
 
@@ -2859,7 +2860,8 @@ static int process_attr(const struct perf_tool *tool, union perf_event *event,
 	 * on events sample_type.
 	 */
 	sample_type = evlist__combined_sample_type(evlist);
-	callchain_param_setup(sample_type, perf_session__e_machine(evsel__session(evsel)));
+	e_machine = perf_session__e_machine(evsel__session(evsel), /*e_flags=*/NULL);
+	callchain_param_setup(sample_type, e_machine);
 
 	/* Enable fields for callchain entries */
 	if (symbol_conf.use_callchain &&
@@ -3834,7 +3836,7 @@ static void script__setup_sample_type(struct perf_script *script)
 	struct perf_session *session = script->session;
 	u64 sample_type = evlist__combined_sample_type(session->evlist);
 
-	callchain_param_setup(sample_type, perf_session__e_machine(session));
+	callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL));
 
 	if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
 		pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 848d0faf6698..aff44ffd3ff1 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1008,11 +1008,11 @@ int evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
 	return ret;
 }
 
-uint16_t evsel__e_machine(struct evsel *evsel)
+uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags)
 {
 	struct perf_session *session = evsel__session(evsel);
 
-	return session ? perf_session__e_machine(session) : EM_HOST;
+	return perf_session__e_machine(session, e_flags);
 }
 
 static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
@@ -1050,7 +1050,7 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o
 
 	if (param->record_mode == CALLCHAIN_DWARF) {
 		if (!function) {
-			uint16_t e_machine = evsel__e_machine(evsel);
+			uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
 
 			evsel__set_sample_bit(evsel, REGS_USER);
 			evsel__set_sample_bit(evsel, STACK_USER);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index eefb5d569971..a3d754c029a0 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -546,7 +546,7 @@ static inline bool evsel__is_dummy_event(struct evsel *evsel)
 
 struct perf_session *evsel__session(struct evsel *evsel);
 struct perf_env *evsel__env(struct evsel *evsel);
-uint16_t evsel__e_machine(struct evsel *evsel);
+uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags);
 
 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
 
diff --git a/tools/perf/util/kvm-stat.c b/tools/perf/util/kvm-stat.c
index 858b5dbd39f6..27f16810498c 100644
--- a/tools/perf/util/kvm-stat.c
+++ b/tools/perf/util/kvm-stat.c
@@ -6,15 +6,19 @@
 
 bool kvm_exit_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_exit_trace(evsel__e_machine(evsel)));
+	uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
+
+	return evsel__name_is(evsel, kvm_exit_trace(e_machine));
 }
 
 void exit_event_get_key(struct evsel *evsel,
 			struct perf_sample *sample,
 			struct event_key *key)
 {
+	uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
+
 	key->info = 0;
-	key->key  = evsel__intval(evsel, sample, kvm_exit_reason(evsel__e_machine(evsel)));
+	key->key  = evsel__intval(evsel, sample, kvm_exit_reason(e_machine));
 }
 
 
@@ -31,7 +35,9 @@ bool exit_event_begin(struct evsel *evsel,
 
 bool kvm_entry_event(struct evsel *evsel)
 {
-	return evsel__name_is(evsel, kvm_entry_trace(evsel__e_machine(evsel)));
+	uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL);
+
+	return evsel__name_is(evsel, kvm_entry_trace(e_machine));
 }
 
 bool exit_event_end(struct evsel *evsel,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index d0053618f540..72e8bb67d740 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2964,27 +2964,47 @@ struct perf_env *perf_session__env(struct perf_session *session)
 	return &session->header.env;
 }
 
-static int perf_session__e_machine_cb(struct thread *thread,
-				      void *arg __maybe_unused)
+struct perf_session__e_machine_cb_args {
+	uint32_t e_flags;
+	uint16_t e_machine;
+	bool need_e_flags;
+};
+
+static int perf_session__e_machine_cb(struct thread *thread, void *_args)
 {
-	uint16_t *result = arg;
+	struct perf_session__e_machine_cb_args *args = _args;
 	struct machine *machine = maps__machine(thread__maps(thread));
 
-	*result = thread__e_machine(thread, machine, /*e_flags=*/NULL);
-	return *result != EM_NONE ? 1 : 0;
+	args->e_machine = thread__e_machine(thread, machine,
+					    args->need_e_flags ? &args->e_flags : NULL);
+	return args->e_machine != EM_NONE ? 1 : 0;
 }
 
 /*
  * Note, a machine may have mixed 32-bit and 64-bit processes and so mixed
  * e_machines. Use thread__e_machine when this matters.
  */
-uint16_t perf_session__e_machine(struct perf_session *session)
+uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags)
 {
-	uint16_t e_machine = EM_NONE;
+	struct perf_session__e_machine_cb_args args = {
+		.e_machine = EM_NONE,
+		.need_e_flags = e_flags != NULL,
+	};
+
+	if (!session) {
+		/* Default to assuming a host machine. */
+		if (e_flags)
+			*e_flags = EF_HOST;
+
+		return EM_HOST;
+	}
 
 	machines__for_each_thread(&session->machines,
-					 perf_session__e_machine_cb,
-					 &e_machine);
+				  perf_session__e_machine_cb,
+				  &args);
+
+	if (e_flags)
+		*e_flags = args.e_flags;
 
-	return e_machine == EM_NONE ? EM_HOST : e_machine;
+	return args.e_machine == EM_NONE ? EM_HOST : args.e_machine;
 }
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index eddc4c630b33..f05f0d4a6c23 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -211,6 +211,6 @@ int perf_event__process_finished_round(const struct perf_tool *tool,
 				       struct ordered_events *oe);
 
 struct perf_env *perf_session__env(struct perf_session *session);
-uint16_t perf_session__e_machine(struct perf_session *session);
+uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags);
 
 #endif /* __PERF_SESSION_H */
-- 
2.53.0.rc2.204.g2597b5adb4-goog
[PATCH v3 4/5] perf header: Add e_machine/e_flags to the header
Posted by Ian Rogers 3 days, 16 hours ago
Add 64-bits of feature data to record the ELF machine and flags. This
allows readers to initialize based on the data. For example, `perf kvm
stat` wants to initialize based on the kind of data to be read, but at
initialization time there are no threads to base this data upon and
using the host means cross platform support won't work. The values in
the perf_env also act as a cache for these within the session.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/env.h     |  3 +++
 tools/perf/util/header.c  | 33 +++++++++++++++++++++++++++++++++
 tools/perf/util/header.h  |  1 +
 tools/perf/util/session.c | 33 +++++++++++++++++++++++++++------
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 76ba1a36e9ff..a4501cbca375 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -74,6 +74,9 @@ struct perf_env {
 	char			*os_release;
 	char			*version;
 	char			*arch;
+	/* e_machine expanded from 16 to 32-bits for alignment. */
+	u32			e_machine;
+	u32			e_flags;
 	int			nr_cpus_online;
 	int			nr_cpus_avail;
 	char			*cpu_desc;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 31c3bab1b10a..9142a8ba4019 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -379,6 +379,21 @@ static int write_arch(struct feat_fd *ff,
 	return do_write_string(ff, uts.machine);
 }
 
+static int write_e_machine(struct feat_fd *ff,
+			   struct evlist *evlist __maybe_unused)
+{
+	/* e_machine expanded from 16 to 32-bits for alignment. */
+	uint32_t e_flags;
+	uint32_t e_machine = perf_session__e_machine(evlist->session, &e_flags);
+	int ret;
+
+	ret = do_write(ff, &e_machine, sizeof(e_machine));
+	if (ret)
+		return ret;
+
+	return do_write(ff, &e_flags, sizeof(e_flags));
+}
+
 static int write_version(struct feat_fd *ff,
 			 struct evlist *evlist __maybe_unused)
 {
@@ -1785,6 +1800,12 @@ static void print_arch(struct feat_fd *ff, FILE *fp)
 	fprintf(fp, "# arch : %s\n", ff->ph->env.arch);
 }
 
+static void print_e_machine(struct feat_fd *ff, FILE *fp)
+{
+	fprintf(fp, "# e_machine : %u\n", ff->ph->env.e_machine);
+	fprintf(fp, "#   e_flags : %u\n", ff->ph->env.e_flags);
+}
+
 static void print_cpudesc(struct feat_fd *ff, FILE *fp)
 {
 	fprintf(fp, "# cpudesc : %s\n", ff->ph->env.cpu_desc);
@@ -2612,6 +2633,17 @@ FEAT_PROCESS_STR_FUN(arch, arch);
 FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc);
 FEAT_PROCESS_STR_FUN(cpuid, cpuid);
 
+static int process_e_machine(struct feat_fd *ff, void *data __maybe_unused)
+{
+	int ret;
+
+	ret = do_read_u32(ff, &ff->ph->env.e_machine);
+	if (ret)
+		return ret;
+
+	return do_read_u32(ff, &ff->ph->env.e_flags);
+}
+
 #ifdef HAVE_LIBTRACEEVENT
 static int process_tracing_data(struct feat_fd *ff, void *data)
 {
@@ -3730,6 +3762,7 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = {
 	FEAT_OPN(HYBRID_TOPOLOGY,	hybrid_topology,	true),
 	FEAT_OPR(PMU_CAPS,	pmu_caps,	false),
 	FEAT_OPR(CPU_DOMAIN_INFO,	cpu_domain_info,	true),
+	FEAT_OPR(E_MACHINE,	e_machine,	false),
 };
 
 struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 36cc74e2d14d..cc40ac796f52 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -54,6 +54,7 @@ enum {
 	HEADER_HYBRID_TOPOLOGY,
 	HEADER_PMU_CAPS,
 	HEADER_CPU_DOMAIN_INFO,
+	HEADER_E_MACHINE,
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
 };
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 72e8bb67d740..53f51c3f9603 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2967,7 +2967,6 @@ struct perf_env *perf_session__env(struct perf_session *session)
 struct perf_session__e_machine_cb_args {
 	uint32_t e_flags;
 	uint16_t e_machine;
-	bool need_e_flags;
 };
 
 static int perf_session__e_machine_cb(struct thread *thread, void *_args)
@@ -2975,8 +2974,7 @@ static int perf_session__e_machine_cb(struct thread *thread, void *_args)
 	struct perf_session__e_machine_cb_args *args = _args;
 	struct machine *machine = maps__machine(thread__maps(thread));
 
-	args->e_machine = thread__e_machine(thread, machine,
-					    args->need_e_flags ? &args->e_flags : NULL);
+	args->e_machine = thread__e_machine(thread, machine, &args->e_flags);
 	return args->e_machine != EM_NONE ? 1 : 0;
 }
 
@@ -2988,8 +2986,8 @@ uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags
 {
 	struct perf_session__e_machine_cb_args args = {
 		.e_machine = EM_NONE,
-		.need_e_flags = e_flags != NULL,
 	};
+	struct perf_env *env;
 
 	if (!session) {
 		/* Default to assuming a host machine. */
@@ -2999,12 +2997,35 @@ uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags
 		return EM_HOST;
 	}
 
+	env = perf_session__env(session);
+	if (env && env->e_machine != EM_NONE) {
+		if (e_flags)
+			*e_flags = env->e_flags;
+
+		return env->e_machine;
+	}
+
 	machines__for_each_thread(&session->machines,
 				  perf_session__e_machine_cb,
 				  &args);
 
+	if (args.e_machine != EM_NONE) {
+		if (env) {
+			env->e_machine = args.e_machine;
+			env->e_flags = args.e_flags;
+		}
+		if (e_flags)
+			*e_flags = args.e_flags;
+
+		return args.e_machine;
+	}
+
+	/*
+	 * Couldn't determine from the perf_env or current set of
+	 * threads. Default to the host.
+	 */
 	if (e_flags)
-		*e_flags = args.e_flags;
+		*e_flags = EF_HOST;
 
-	return args.e_machine == EM_NONE ? EM_HOST : args.e_machine;
+	return EM_HOST;
 }
-- 
2.53.0.rc2.204.g2597b5adb4-goog
[PATCH v3 5/5] perf thread: Don't require machine to compute the e_machine
Posted by Ian Rogers 3 days, 16 hours ago
The machine can be calculated from a thread via its maps. Don't
require the machine argument to simplify callers and also to delay
computing the machine until a little later.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/scripting-engines/trace-event-python.c | 8 +++-----
 tools/perf/util/session.c                              | 3 +--
 tools/perf/util/thread.c                               | 5 +++++
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 62c9c73daef5..2b0df7bd9a46 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -837,7 +837,6 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
 					 PyObject *callchain)
 {
 	PyObject *dict, *dict_sample, *brstack, *brstacksym;
-	struct machine *machine;
 	uint16_t e_machine = EM_HOST;
 	uint32_t e_flags = EF_HOST;
 
@@ -926,10 +925,9 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample,
 			PyLong_FromUnsignedLongLong(sample->cyc_cnt));
 	}
 
-	if (al->thread) {
-		machine = maps__machine(thread__maps(al->thread));
-		e_machine = thread__e_machine(al->thread, machine, &e_flags);
-	}
+	if (al->thread)
+		e_machine = thread__e_machine(al->thread, /*machine=*/NULL, &e_flags);
+
 	if (set_regs_in_dict(dict, sample, evsel, e_machine, e_flags))
 		Py_FatalError("Failed to setting regs in dict");
 
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 53f51c3f9603..4b465abfa36c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2972,9 +2972,8 @@ struct perf_session__e_machine_cb_args {
 static int perf_session__e_machine_cb(struct thread *thread, void *_args)
 {
 	struct perf_session__e_machine_cb_args *args = _args;
-	struct machine *machine = maps__machine(thread__maps(thread));
 
-	args->e_machine = thread__e_machine(thread, machine, &args->e_flags);
+	args->e_machine = thread__e_machine(thread, /*machine=*/NULL, &args->e_flags);
 	return args->e_machine != EM_NONE ? 1 : 0;
 }
 
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 618f29afb160..22be77225bb0 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -499,6 +499,11 @@ uint16_t thread__e_machine(struct thread *thread, struct machine *machine, uint3
 		return e_machine;
 	}
 
+	if (machine == NULL) {
+		struct maps *maps = thread__maps(thread);
+
+		machine = maps__machine(maps);
+	}
 	tid = thread__tid(thread);
 	pid = thread__pid(thread);
 	if (pid != tid) {
-- 
2.53.0.rc2.204.g2597b5adb4-goog