From nobody Sat Feb 7 18:20:40 2026 Received: from mail-dl1-f74.google.com (mail-dl1-f74.google.com [74.125.82.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A032031ED73 for ; Tue, 3 Feb 2026 18:27:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143233; cv=none; b=PbwgHv/3yjINQgwcBikQfEkV629DL2t00WQ2rfunMLre5M2NsUMhHqi/e+kbqPvatZo3ugdMkn/Wkpky6wl2j6eS7wgfzjKFvw3+Eh/cnpJ8QGfz+i610nCbX2mbSOgRZaCF0ajAi7Eyr/RLXIF/1Aa1EDZNPNiT7WB8Vc8oizE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143233; c=relaxed/simple; bh=/R5eM4QeANKoAXK/26208tlrdJEK+LT09WXiwRS2zdw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=d95BYp4ICVJOxW5mQiYFJL6S9uO1Ft+WThsEXqjm7HHn0pwibNJcbi7BJQ9MvNyhoe31SrZUislrgLpTbxK3Lo/pJZw4C60ug4FVR0qDyd9KxUR2ZOVnvRiW+VCkWy2RDeCibYaHSR9RAXRULfQc/Aa08pO+fmzXZpz//obpsaM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dSp0leqa; arc=none smtp.client-ip=74.125.82.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dSp0leqa" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-124743cf760so18651339c88.1 for ; Tue, 03 Feb 2026 10:27:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770143230; x=1770748030; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=X+mFf4GKdwMpaiFtj2IUCvDo65qkwWf1fTXB5xHV+7M=; b=dSp0leqaTvi48cpgm0sIPY8t6Vkv3yOQOGaOJrokLJvkP5gs2CTiW8T6WoTMSu6vUt vp1DP4m7/QrtUA2MfzwDPTiqer0PEbkZUqLr1EEA7h7J4PPVH5UE3neZxqtk51wYgzM+ AyQKZNfRRZAQ06EJDynO8M2HGU/43p6oQj6eei7BPX62oMFoUaM9JRUv9esDf7vcZTnS J6fprK953w4/zhBkHBxCTs72FTd6rB4pT30m1BflGCXOCCJUic9bUlmqWdXMJHrozHd/ XyJ41j6YvZj16Wr6wmQF5fZbNTv9zZWgw/gYsiGEMzjl8TfKrzKH0O0Z8UYFAXuiD0d5 mdYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770143230; x=1770748030; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=X+mFf4GKdwMpaiFtj2IUCvDo65qkwWf1fTXB5xHV+7M=; b=O+0H+OWx6iChg8XzD8PtgPZlqrHaRDs9l5pWMcTcyfVU4DZUOthA2Mc7/TAz9DL6am IylaMLpJMIdWwgaCkVgOMPRqxsoZ28RK135hE7LuPxW9OyKBlBfrs3OTg0AJCexYL9G8 8R2ijmbW5yJXDB1mqfLnbka1wyFDRNrVNgadJ/Cu5PzzmtQG5wjb+BEBDCgamPRcsZf/ J9VyKhDD6qKDKiW34Q6ZxkHMfvctLdNJUexyGIRl9uHzBLKvXmK2eu0IJIrJgSZYQ+lS ayuH7ZZIX2056/hhP8SouT7YpHVgoA7Y5zeN2kS0739dlts6ugC6J8c3DAPxU8jEPfsr Cf0A== X-Forwarded-Encrypted: i=1; AJvYcCVEta4F3Yrlck17saL8hI3XOcsp9F9Mz/YQDsw9Sj+PnZgeJPXmefoRSFqEy/hSPsHXrHlLbrXIAGxqdco=@vger.kernel.org X-Gm-Message-State: AOJu0YxYm+qkYozBof2aFMt8mfoZwHJMUexhfge8lHVQa22g8azhlHNR WAMyaydzguhEhAXpaHDE/xS4CaAMx2Nv8gokToS/lJydsylsEVu/DXg/MDRE0JlAIF6YbtMjyGx zlfv2Yu7PPQ== X-Received: from dlbqi7.prod.google.com ([2002:a05:7022:ebc7:b0:11a:1004:5049]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:426:b0:11d:c86c:652e with SMTP id a92af1059eb24-126f4770a81mr158732c88.5.1770143229620; Tue, 03 Feb 2026 10:27:09 -0800 (PST) Date: Tue, 3 Feb 2026 10:26:36 -0800 In-Reply-To: <20260203182640.3911987-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260203182640.3911987-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203182640.3911987-2-irogers@google.com> Subject: [PATCH v3 1/5] perf kvm stat: Remove use of the arch directory From: Ian Rogers To: acme@kernel.org Cc: aditya.b1@linux.ibm.com, adrian.hunter@intel.com, ajones@ventanamicro.com, ak@linux.intel.com, alex@ghiti.fr, alexander.shishkin@linux.intel.com, anup@brainfault.org, aou@eecs.berkeley.edu, ashelat@redhat.com, atrajeev@linux.ibm.com, blakejones@google.com, ctshao@google.com, dapeng1.mi@linux.intel.com, dvyukov@google.com, howardchu95@gmail.com, irogers@google.com, james.clark@linaro.org, john.g.garry@oracle.com, jolsa@kernel.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, mingo@redhat.com, namhyung@kernel.org, palmer@dabbelt.com, peterz@infradead.org, pjw@kernel.org, shimin.guo@skydio.com, swapnil.sapkal@amd.com, thomas.falcon@intel.com, will@kernel.org, ysk@kzalloc.com, zhouquan@iscas.ac.cn Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" `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 --- 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 =3D> util/kvm-stat-arch}/arm64_exceptio= n_types.h (100%) rename tools/perf/{arch/powerpc/util =3D> util/kvm-stat-arch}/book3s_hcall= s.h (100%) rename tools/perf/{arch/powerpc/util =3D> util/kvm-stat-arch}/book3s_hv_ex= its.h (100%) rename tools/perf/{arch/arm64/util/kvm-stat.c =3D> util/kvm-stat-arch/kvm-= stat-arm64.c} (63%) rename tools/perf/{arch/loongarch/util/kvm-stat.c =3D> util/kvm-stat-arch/= kvm-stat-loongarch.c} (78%) rename tools/perf/{arch/powerpc/util/kvm-stat.c =3D> util/kvm-stat-arch/kv= m-stat-powerpc.c} (78%) rename tools/perf/{arch/riscv/util/kvm-stat.c =3D> util/kvm-stat-arch/kvm-= stat-riscv.c} (58%) rename tools/perf/{arch/s390/util/kvm-stat.c =3D> util/kvm-stat-arch/kvm-s= tat-s390.c} (77%) rename tools/perf/{arch/x86/util/kvm-stat.c =3D> util/kvm-stat-arch/kvm-st= at-x86.c} (88%) rename tools/perf/{arch/riscv/util =3D> util/kvm-stat-arch}/riscv_trap_typ= es.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 =20 -ifdef HAVE_KVM_STAT_SUPPORT - CFLAGS +=3D -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 :=3D 1 -HAVE_KVM_STAT_SUPPORT :=3D 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) +=3D kvm-stat.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) +=3D unwind-libunwind.o perf-util-y +=3D ../../arm/util/auxtrace.o perf-util-y +=3D ../../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 :=3D 1 -HAVE_KVM_STAT_SUPPORT :=3D 1 diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongar= ch/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 +=3D perf_regs.o =20 perf-util-$(CONFIG_LOCAL_LIBUNWIND) +=3D unwind-libunwind.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) +=3D unwind-libdw.o -perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Mak= efile 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 :=3D 1 PERF_HAVE_JITDUMP :=3D 1 diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/u= til/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 +=3D header.o -perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o perf-util-y +=3D perf_regs.o perf-util-y +=3D mem-events.o perf-util-y +=3D 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 :=3D 1 -HAVE_KVM_STAT_SUPPORT :=3D 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 +=3D perf_regs.o perf-util-y +=3D header.o - -perf-util-$(CONFIG_LIBTRACEEVENT) +=3D 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 :=3D 1 PERF_HAVE_JITDUMP :=3D 1 diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Bu= ild 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 +=3D header.o -perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o perf-util-y +=3D perf_regs.o =20 perf-util-y +=3D 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 :=3D 1 PERF_HAVE_JITDUMP :=3D 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 +=3D header.o perf-util-y +=3D tsc.o perf-util-y +=3D pmu.o -perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o perf-util-y +=3D perf_regs.o perf-util-y +=3D topdown.o perf-util-y +=3D 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 #include =20 -#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) =20 #endif /* HAVE_SLANG_SUPPORT */ =20 -#endif // defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#endif // defined(HAVE_LIBTRACEEVENT) =20 static const char *get_filename_for_perf_kvm(void) { @@ -613,13 +613,13 @@ static const char *get_filename_for_perf_kvm(void) return filename; } =20 -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#if defined(HAVE_LIBTRACEEVENT) =20 static bool register_kvm_events_ops(struct perf_kvm_stat *kvm) { - struct kvm_reg_events_ops *events_ops =3D kvm_reg_events_ops; + const struct kvm_reg_events_ops *events_ops; =20 - for (events_ops =3D kvm_reg_events_ops; events_ops->name; events_ops++) { + for (events_ops =3D kvm_reg_events_ops(); events_ops->name; events_ops++)= { if (!strcmp(events_ops->name, kvm->report_event)) { kvm->events_ops =3D 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; =20 child_ops =3D kvm->events_ops->child_ops; =20 @@ -845,7 +845,7 @@ static bool skip_event(const char *event) { const char * const *skip_events; =20 - for (skip_events =3D kvm_skip_events; *skip_events; skip_events++) + for (skip_events =3D kvm_skip_events(); *skip_events; skip_events++) if (!strcmp(event, *skip_events)) return true; =20 @@ -928,7 +928,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread= *thread, return NULL; } =20 - vcpu_record->vcpu_id =3D evsel__intval(evsel, sample, vcpu_id_str); + vcpu_record->vcpu_id =3D evsel__intval(evsel, sample, vcpu_id_str()); thread__set_priv(thread, vcpu_record); } =20 @@ -1636,11 +1636,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_st= at *kvm) return ret; } =20 -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; } =20 - for (events_tp =3D kvm_events_tp; *events_tp; events_tp++) + for (events_tp =3D kvm_events_tp(); *events_tp; events_tp++) events_tp_size++; =20 rec_argc =3D ARRAY_SIZE(record_args) + argc + 2 + @@ -1681,7 +1676,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc= , const char **argv) =20 for (j =3D 0; j < events_tp_size; j++) { rec_argv[i++] =3D STRDUP_FAIL_EXIT("-e"); - rec_argv[i++] =3D STRDUP_FAIL_EXIT(kvm_events_tp[j]); + rec_argv[i++] =3D STRDUP_FAIL_EXIT(kvm_events_tp()[j]); } =20 rec_argv[i++] =3D STRDUP_FAIL_EXIT("-o"); @@ -1775,7 +1770,7 @@ static struct evlist *kvm_live_event_list(void) if (evlist =3D=3D NULL) return NULL; =20 - for (events_tp =3D kvm_events_tp; *events_tp; events_tp++) { + for (events_tp =3D kvm_events_tp(); *events_tp; events_tp++) { =20 tp =3D strdup(*events_tp); if (tp =3D=3D NULL) @@ -1985,13 +1980,7 @@ static int kvm_cmd_stat(const char *file_name, int a= rgc, 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 */ =20 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 +=3D spark.o perf-util-y +=3D topdown.o perf-util-y +=3D iostat.o perf-util-y +=3D stream.o -perf-util-y +=3D kvm-stat.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o +perf-util-y +=3D kvm-stat-arch/ perf-util-y +=3D lock-contention.o perf-util-y +=3D auxtrace.o perf-util-y +=3D 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) +=3D kvm-stat-arm64.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat-loongarch.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat-powerpc.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat-riscv.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat-s390.o +perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat-x86.o diff --git a/tools/perf/arch/arm64/util/arm64_exception_types.h b/tools/per= f/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/ut= il/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-st= at-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 #include -#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" =20 define_exit_reasons_table(arm64_exit_reasons, kvm_arm_exception_type); define_exit_reasons_table(arm64_trap_exit_reasons, kvm_arm_exception_class= ); =20 -const char *kvm_trap_exit_reason =3D "esr_ec"; -const char *vcpu_id_str =3D "id"; -const char *kvm_exit_reason =3D "ret"; -const char *kvm_entry_trace =3D "kvm:kvm_entry"; -const char *kvm_exit_trace =3D "kvm:kvm_exit"; +static const char *kvm_trap_exit_reason =3D "esr_ec"; =20 -const char *kvm_events_tp[] =3D { +static const char * const __kvm_events_tp[] =3D { "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 =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()); key->exit_reasons =3D arm64_exit_reasons; =20 /* @@ -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()); } =20 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; } =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D event_begin, .is_end_event =3D event_end, .decode_key =3D exit_event_decode_key, .name =3D "VM-EXIT" }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events, @@ -73,12 +69,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { NULL, }; =20 -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unus= ed) +int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa =3D "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/kv= m-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 #include -#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" =20 #define LOONGARCH_EXCEPTION_INT 0 #define LOONGARCH_EXCEPTION_PIL 1 @@ -43,12 +43,8 @@ =20 define_exit_reasons_table(loongarch_exit_reasons, loongarch_exception_type= ); =20 -const char *vcpu_id_str =3D "vcpu_id"; -const char *kvm_exit_reason =3D "reason"; -const char *kvm_entry_trace =3D "kvm:kvm_enter"; -const char *kvm_reenter_trace =3D "kvm:kvm_reenter"; -const char *kvm_exit_trace =3D "kvm:kvm_exit"; -const char *kvm_events_tp[] =3D { +static const char *kvm_reenter_trace =3D "kvm:kvm_reenter"; +static const char * const __kvm_events_tp[] =3D { "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, kv= m_reenter_trace); + return evsel__name_is(evsel, kvm_entry_trace()) || + evsel__name_is(evsel, kvm_reenter_trace); } =20 static void event_gspr_get_key(struct evsel *evsel, @@ -109,12 +106,12 @@ static void event_gspr_get_key(struct evsel *evsel, } } =20 -static struct child_event_ops child_events[] =3D { +static const struct child_event_ops child_events[] =3D { { .name =3D "kvm:kvm_exit_gspr", .get_key =3D event_gspr_get_key }, { NULL, NULL }, }; =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D event_begin, .is_end_event =3D event_end, .child_ops =3D child_events, @@ -122,18 +119,33 @@ static struct kvm_events_ops exit_events =3D { .name =3D "VM-EXIT" }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events, }, { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { NULL, }; =20 -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unus= ed) +int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa =3D "loongarch64"; kvm->exit_reasons =3D 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 -#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" =20 #include "book3s_hv_exits.h" #include "book3s_hcalls.h" @@ -13,15 +13,11 @@ =20 #define NR_TPS 4 =20 -const char *vcpu_id_str =3D "vcpu_id"; -const char *kvm_entry_trace =3D "kvm_hv:kvm_guest_enter"; -const char *kvm_exit_trace =3D "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); =20 /* Tracepoints specific to ppc_book3s_hv */ -const char *ppc_book3s_hv_kvm_tp[] =3D { +static const char * const ppc_book3s_hv_kvm_tp[] =3D { "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[] =3D { }; =20 /* 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]; =20 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]); } =20 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); } =20 -static struct kvm_events_ops hcall_events =3D { +static const struct kvm_events_ops hcall_events =3D { .is_begin_event =3D hcall_event_begin, .is_end_event =3D hcall_event_end, .decode_key =3D hcall_event_decode_key, .name =3D "HCALL-EVENT", }; =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D exit_event_begin, .is_end_event =3D exit_event_end, .decode_key =3D exit_event_decode_key, .name =3D "VM-EXIT" }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events }, { .name =3D "hcall", .ops =3D &hcall_events }, { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { NULL, }; =20 @@ -123,7 +118,7 @@ static int is_tracepoint_available(const char *str, str= uct 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 =3D 0, err =3D -1; =20 /* Check for book3s_hv tracepoints */ @@ -135,10 +130,9 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *= kvm, } =20 for (i =3D 0; i < nr_tp; i++) - kvm_events_tp[i] =3D ppc_book3s_hv_kvm_tp[i]; + __kvm_events_tp[i] =3D ppc_book3s_hv_kvm_tp[i]; =20 - kvm_events_tp[i] =3D NULL; - kvm_exit_reason =3D "trap"; + __kvm_events_tp[i] =3D NULL; kvm->exit_reasons =3D hv_exit_reasons; kvm->exit_reasons_isa =3D "HV"; =20 @@ -157,12 +151,12 @@ static int ppc__setup_kvm_tp(struct perf_kvm_stat *kv= m) return ppc__setup_book3s_hv(kvm, evlist); } =20 -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); } =20 -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unus= ed) +int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm) { int ret; =20 @@ -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 =3D 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-st= at-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 #include -#include "../../../util/evsel.h" -#include "../../../util/kvm-stat.h" +#include "../evsel.h" +#include "../kvm-stat.h" #include "riscv_trap_types.h" #include "debug.h" =20 define_exit_reasons_table(riscv_exit_reasons, kvm_riscv_trap_class); =20 -const char *vcpu_id_str =3D "id"; -const char *kvm_exit_reason =3D "scause"; -const char *kvm_entry_trace =3D "kvm:kvm_entry"; -const char *kvm_exit_trace =3D "kvm:kvm_exit"; - -const char *kvm_events_tp[] =3D { +static const char * const __kvm_events_tp[] =3D { "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 =3D 64; // TODO: 32-bit support. + key->info =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason) & ~CAUSE_IRQ_F= LAG; + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()) & ~CAUSE_IRQ= _FLAG(xlen); key->exit_reasons =3D riscv_exit_reasons; } =20 @@ -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()); } =20 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; } =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D event_begin, .is_end_event =3D event_end, .decode_key =3D exit_event_decode_key, .name =3D "VM-EXIT" }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events, @@ -67,12 +64,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { NULL, }; =20 -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unus= ed) +int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa =3D "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-sta= t-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 @@ =20 #include #include -#include "../../util/kvm-stat.h" -#include "../../util/evsel.h" -#include +#include "../kvm-stat.h" +#include "../evsel.h" +#include "../../../arch/s390/include/uapi/asm/sie.h" =20 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_or= der_codes); define_exit_reasons_table(sie_diagnose_codes, diagnose_codes); define_exit_reasons_table(sie_icpt_prog_codes, icpt_prog_codes); =20 -const char *vcpu_id_str =3D "id"; -const char *kvm_exit_reason =3D "icptcode"; -const char *kvm_entry_trace =3D "kvm:kvm_s390_sie_enter"; -const char *kvm_exit_trace =3D "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; =20 insn =3D evsel__intval(evsel, sample, "instruction"); key->key =3D icpt_insn_decoder(insn); @@ -58,7 +53,7 @@ static void event_icpt_prog_get_key(struct evsel *evsel, key->exit_reasons =3D sie_icpt_prog_codes; } =20 -static struct child_event_ops child_events[] =3D { +static const struct child_event_ops child_events[] =3D { { .name =3D "kvm:kvm_s390_intercept_instruction", .get_key =3D event_icpt_insn_get_key }, { .name =3D "kvm:kvm_s390_handle_sigp", @@ -70,7 +65,7 @@ static struct child_event_ops child_events[] =3D { { NULL, NULL }, }; =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D exit_event_begin, .is_end_event =3D exit_event_end, .child_ops =3D child_events, @@ -78,7 +73,7 @@ static struct kvm_events_ops exit_events =3D { .name =3D "VM-EXIT" }; =20 -const char *kvm_events_tp[] =3D { +static const char * const __kvm_events_tp[] =3D { "kvm:kvm_s390_sie_enter", "kvm:kvm_s390_sie_exit", "kvm:kvm_s390_intercept_instruction", @@ -88,17 +83,17 @@ const char *kvm_events_tp[] =3D { NULL, }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events }, { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { "Wait state", NULL, }; =20 -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 =3D sie_exit_reasons; @@ -108,3 +103,18 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char= *cpuid) =20 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 #include -#include "../../../util/kvm-stat.h" -#include "../../../util/evsel.h" -#include "../../../util/env.h" +#include "../kvm-stat.h" +#include "../evsel.h" +#include "../env.h" #include #include #include @@ -12,18 +12,13 @@ define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS); define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS); =20 -static struct kvm_events_ops exit_events =3D { +static const struct kvm_events_ops exit_events =3D { .is_begin_event =3D exit_event_begin, .is_end_event =3D exit_event_end, .decode_key =3D exit_event_decode_key, .name =3D "VM-EXIT" }; =20 -const char *vcpu_id_str =3D "vcpu_id"; -const char *kvm_exit_reason =3D "exit_reason"; -const char *kvm_entry_trace =3D "kvm:kvm_entry"; -const char *kvm_exit_trace =3D "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 *k= vm __maybe_unused, key->info =3D=3D KVM_TRACE_MMIO_WRITE ? "W" : "R"); } =20 -static struct kvm_events_ops mmio_events =3D { +static const struct kvm_events_ops mmio_events =3D { .is_begin_event =3D mmio_event_begin, .is_end_event =3D mmio_event_end, .decode_key =3D mmio_event_decode_key, @@ -127,7 +122,7 @@ static void ioport_event_decode_key(struct perf_kvm_sta= t *kvm __maybe_unused, key->info ? "POUT" : "PIN"); } =20 -static struct kvm_events_ops ioport_events =3D { +static const struct kvm_events_ops ioport_events =3D { .is_begin_event =3D ioport_event_begin, .is_end_event =3D ioport_event_end, .decode_key =3D 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"); } =20 -static struct kvm_events_ops msr_events =3D { +static const struct kvm_events_ops msr_events =3D { .is_begin_event =3D msr_event_begin, .is_end_event =3D msr_event_end, .decode_key =3D msr_event_decode_key, .name =3D "MSR Access" }; =20 -const char *kvm_events_tp[] =3D { +static const char * const __kvm_events_tp[] =3D { "kvm:kvm_entry", "kvm:kvm_exit", "kvm:kvm_mmio", @@ -187,7 +182,7 @@ const char *kvm_events_tp[] =3D { NULL, }; =20 -struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] =3D { { .name =3D "vmexit", .ops =3D &exit_events }, { .name =3D "mmio", .ops =3D &mmio_events }, { .name =3D "ioport", .ops =3D &ioport_events }, @@ -195,12 +190,12 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] =3D { { NULL, NULL }, }; =20 -const char * const kvm_skip_events[] =3D { +static const char * const __kvm_skip_events[] =3D { "HLT", NULL, }; =20 -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 =3D 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" e= vent * 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 =3D 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/uti= l/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 =20 /* 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)) =20 /* 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 =20 bool kvm_exit_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_exit_trace); + return evsel__name_is(evsel, kvm_exit_trace()); } =20 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 =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()); } =20 =20 @@ -32,7 +31,7 @@ bool exit_event_begin(struct evsel *evsel, =20 bool kvm_entry_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_entry_trace); + return evsel__name_is(evsel, kvm_entry_trace()); } =20 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); } =20 -#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 =20 -#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; =20 - struct kvm_events_ops *events_ops; + const struct kvm_events_ops *events_ops; =20 u64 total_time; u64 total_count; @@ -113,10 +111,10 @@ struct perf_kvm_stat { =20 struct kvm_reg_events_ops { const char *name; - struct kvm_events_ops *ops; + const struct kvm_events_ops *ops; }; =20 -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#ifdef HAVE_LIBTRACEEVENT =20 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 =20 bool kvm_exit_event(struct evsel *evsel); bool kvm_entry_event(struct evsel *evsel); -int setup_kvm_events_tp(struct perf_kvm_stat *kvm); =20 #define define_exit_reasons_table(name, symbols) \ static struct exit_reasons_table name[] =3D { \ @@ -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; +} =20 -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 */ =20 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; } =20 -#else /* HAVE_KVM_STAT_SUPPORT */ -// We use this unconditionally in hists__findnew_entry() and hist_entry__d= elete() -#define kvm_info__zput(ki) do { } while (0) -#endif /* HAVE_KVM_STAT_SUPPORT */ - #define STRDUP_FAIL_EXIT(s) \ ({ char *_p; \ _p =3D strdup(s); \ @@ -201,5 +236,4 @@ static inline struct kvm_info *kvm_info__new(void) _p; \ }) =20 -extern int kvm_add_default_arch_event(int *argc, const char **argv); #endif /* __PERF_KVM_STAT_H */ --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 18:20:40 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 878E031B83B for ; Tue, 3 Feb 2026 18:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143234; cv=none; b=ZEDq5ziqhQy6faHMBZgZw2TAalZ9IJek6ep6mZ768Z88jUPPThqaCm7stovYwNFlT+aXqJjX2EQYWzhgex3j6H4m/lb+ZRaiaCRHF5T3aVo7tq+OFxTBJ0pARN44xms1VU5CiACvdHsX3isbSMbolU4RwH96NTmqyFM765WlzfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143234; c=relaxed/simple; bh=kHpcTJCZV+aUWok+Qq4YcCfFJIaLag+5P6lM1gxsnP8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=t5JU0JIxTB5STpQe13uE4PHVAweYJjpIbPOfFXaBGPtf8DnwRGhi+gzGlhjHVQst8WLZVF7tECVBONNunZ3EUBseVISUcCQjFOS6GPZM62WWCrpPmlS/xWwsgweAKMQtgltTp1NZoQOy+C+1xyYTDgRcnngdEl1ZrLqjI83v85Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ifr/xalP; arc=none smtp.client-ip=74.125.82.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ifr/xalP" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b82974bd26so712408eec.1 for ; Tue, 03 Feb 2026 10:27:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770143232; x=1770748032; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=os2xaUwPSOKN1Qn0Q1X9vU6deQDG0YlYowBgBpJaS3I=; b=Ifr/xalPjegwYa0JjjSUjN+i+FPPMFu2agbs/WouLFjBBHQIIzRgCX27zqUEGbwyG8 WDWRCLTetkkagc34Y5NeRDFDmwhbAcYMtzkl74wGPf1ehUi2oqcoh1qn0024q6t9k0b1 S/39AZLR5YqZKFwkfHSYoDduNtgbEJ+/DtLYNk+dnXimiEfdS8CBtbgwuY77B5WUPdw7 qx2hnnoRVtzhYxp3f0iXDuIHTpOaWmOHUQQRf9hJxqzcT0MAq0gAJdIIuCdgp7xnGgtS 9msAiEnpHBSqoBsXACNiRbSyyFfbaiVd1d3pfYHwXBlNqehFkw+HuKTJdc2G2j6Oe2Er wD0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770143232; x=1770748032; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=os2xaUwPSOKN1Qn0Q1X9vU6deQDG0YlYowBgBpJaS3I=; b=gPRrH94KooIEx08qvYnjy9EyKYfo6GcJuUQ3IZwmvZhvf6Bn6Jx5+o30xxsO0JH/VG GNNSGDHmMSzpaoPEMSqvghNqqDud6A48huHf9X7cwRbTuAWbDdp/spL9noU+EVNjXcaD 1BilRlBH8dMCTBfHF7fPC9HfqArsAsoF04wAvW5YK+/oGrCLakck8I9z8WMyvqpzd6hJ xXR6C7SQyRQRtbGCxyGmzu6UiBKNWahx72RdBH3n1R7fcQDs9EIW2/6u/vYoY98wEd7Z Sjzb0RSJmn/SOKfmLXlvNxK+vcA1HZq4k8mpyufYbishb6ZCaC4TnwBPthjG6LcBINp2 F/7Q== X-Forwarded-Encrypted: i=1; AJvYcCWADfqEXvub9valVtDT1YPKuLAOeQiKFQKm7RL4VGTE6pIjUhsy3SW4TOOEAvq2FMJDjji4K9Irp/PVbV4=@vger.kernel.org X-Gm-Message-State: AOJu0YwkdbZExQD4RVlU3t4/z3AgfpH/zP4eSgsyZh4xZ6riRocoKX0i lf5/+nU8BBXP6mk1zJJETFL3voXJePetrn6n/ZTbydBt8EQyLmk7OQWR601OWUIB5+I6vgPhWiO DgELWtFSXuw== X-Received: from dycmq7.prod.google.com ([2002:a05:7301:787:b0:2b6:c3b1:69d4]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:ea2:b0:2b7:ff39:30eb with SMTP id 5a478bee46e88-2b832722b9fmr162822eec.0.1770143231506; Tue, 03 Feb 2026 10:27:11 -0800 (PST) Date: Tue, 3 Feb 2026 10:26:37 -0800 In-Reply-To: <20260203182640.3911987-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260203182640.3911987-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203182640.3911987-3-irogers@google.com> Subject: [PATCH v3 2/5] perf kvm: Wire up e_machine From: Ian Rogers To: acme@kernel.org Cc: aditya.b1@linux.ibm.com, adrian.hunter@intel.com, ajones@ventanamicro.com, ak@linux.intel.com, alex@ghiti.fr, alexander.shishkin@linux.intel.com, anup@brainfault.org, aou@eecs.berkeley.edu, ashelat@redhat.com, atrajeev@linux.ibm.com, blakejones@google.com, ctshao@google.com, dapeng1.mi@linux.intel.com, dvyukov@google.com, howardchu95@gmail.com, irogers@google.com, james.clark@linaro.org, john.g.garry@oracle.com, jolsa@kernel.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, mingo@redhat.com, namhyung@kernel.org, palmer@dabbelt.com, peterz@infradead.org, pjw@kernel.org, shimin.guo@skydio.com, swapnil.sapkal@amd.com, thomas.falcon@intel.com, will@kernel.org, ysk@kzalloc.com, zhouquan@iscas.ac.cn Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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" =20 +#include #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) =20 #if defined(HAVE_LIBTRACEEVENT) =20 -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; =20 - for (events_ops =3D kvm_reg_events_ops(); events_ops->name; events_ops++)= { + for (events_ops =3D kvm_reg_events_ops(e_machine); events_ops->name; even= ts_ops++) { if (!strcmp(events_ops->name, kvm->report_event)) { kvm->events_ops =3D events_ops->ops; return true; @@ -841,11 +842,11 @@ static bool handle_child_event(struct perf_kvm_stat *= kvm, return true; } =20 -static bool skip_event(const char *event) +static bool skip_event(uint16_t e_machine, const char *event) { const char * const *skip_events; =20 - for (skip_events =3D kvm_skip_events(); *skip_events; skip_events++) + for (skip_events =3D kvm_skip_events(e_machine); *skip_events; skip_event= s++) if (!strcmp(event, *skip_events)) return true; =20 @@ -901,9 +902,10 @@ static bool handle_end_event(struct perf_kvm_stat *kvm, =20 if (kvm->duration && time_diff > kvm->duration) { char decode[KVM_EVENT_NAME_LEN]; + uint16_t e_machine =3D perf_session__e_machine(kvm->session); =20 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 =3D maps__machine(thread__maps(thread)); + uint16_t e_machine =3D thread__e_machine(thread, machine, /*e_flags=3D*/= NULL); =20 vcpu_record =3D zalloc(sizeof(*vcpu_record)); if (!vcpu_record) { @@ -928,7 +932,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread= *thread, return NULL; } =20 - vcpu_record->vcpu_id =3D evsel__intval(evsel, sample, vcpu_id_str()); + vcpu_record->vcpu_id =3D evsel__intval(evsel, sample, vcpu_id_str(e_mach= ine)); thread__set_priv(thread, vcpu_record); } =20 @@ -1163,6 +1167,7 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm) { char buf[128], *cpuid; int err; + uint16_t e_machine; =20 if (kvm->live) { struct perf_cpu cpu =3D {-1}; @@ -1182,7 +1187,8 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm) return -EINVAL; } =20 - err =3D cpu_isa_init(kvm, cpuid); + e_machine =3D perf_session__e_machine(kvm->session); + err =3D cpu_isa_init(kvm, e_machine, cpuid); if (err =3D=3D -ENOTSUP) pr_err("CPU %s is not supported.\n", cpuid); =20 @@ -1413,7 +1419,7 @@ static int kvm_events_live_report(struct perf_kvm_sta= t *kvm) =20 if (!verify_vcpu(kvm->trace_vcpu) || !is_valid_key(kvm) || - !register_kvm_events_ops(kvm)) { + !register_kvm_events_ops(kvm, EM_HOST)) { goto out; } =20 @@ -1568,6 +1574,11 @@ static int read_events(struct perf_kvm_stat *kvm) goto out_delete; } =20 + if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session)))= { + ret =3D -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_sta= t *kvm) if (!is_valid_key(kvm)) goto exit; =20 - if (!register_kvm_events_ops(kvm)) - goto exit; - if (kvm->use_stdio) { use_browser =3D 0; setup_pager(); @@ -1653,15 +1661,16 @@ kvm_events_record(struct perf_kvm_stat *kvm, int ar= gc, const char **argv) }; const char * const *events_tp; int ret; + uint16_t e_machine =3D EM_HOST; =20 events_tp_size =3D 0; - ret =3D setup_kvm_events_tp(kvm); + ret =3D setup_kvm_events_tp(kvm, e_machine); if (ret < 0) { pr_err("Unable to setup the kvm tracepoints\n"); return ret; } =20 - for (events_tp =3D kvm_events_tp(); *events_tp; events_tp++) + for (events_tp =3D kvm_events_tp(e_machine); *events_tp; events_tp++) events_tp_size++; =20 rec_argc =3D ARRAY_SIZE(record_args) + argc + 2 + @@ -1676,7 +1685,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc= , const char **argv) =20 for (j =3D 0; j < events_tp_size; j++) { rec_argv[i++] =3D STRDUP_FAIL_EXIT("-e"); - rec_argv[i++] =3D STRDUP_FAIL_EXIT(kvm_events_tp()[j]); + rec_argv[i++] =3D STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]); } =20 rec_argv[i++] =3D STRDUP_FAIL_EXIT("-o"); @@ -1770,7 +1779,7 @@ static struct evlist *kvm_live_event_list(void) if (evlist =3D=3D NULL) return NULL; =20 - for (events_tp =3D kvm_events_tp(); *events_tp; events_tp++) { + for (events_tp =3D kvm_events_tp(EM_HOST); *events_tp; events_tp++) { =20 tp =3D strdup(*events_tp); if (tp =3D=3D NULL) @@ -1895,7 +1904,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, /* * generate the event list */ - err =3D setup_kvm_events_tp(kvm); + err =3D 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 ar= gc, const char **argv) =20 BUG_ON(i + 2 !=3D rec_argc); =20 - ret =3D kvm_add_default_arch_event(&i, rec_argv); + ret =3D kvm_add_default_arch_event(EM_HOST, &i, rec_argv); if (ret) goto EXIT; =20 @@ -2092,7 +2101,7 @@ static int __cmd_top(int argc, const char **argv) =20 BUG_ON(i !=3D argc); =20 - ret =3D kvm_add_default_arch_event(&i, rec_argv); + ret =3D kvm_add_default_arch_event(EM_HOST, &i, rec_argv); if (ret) goto EXIT; =20 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; } =20 -static uint16_t evsel__e_machine(struct evsel *evsel) +uint16_t evsel__e_machine(struct evsel *evsel) { struct perf_session *session =3D evsel__session(evsel); =20 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) =20 struct perf_session *evsel__session(struct evsel *evsel); struct perf_env *evsel__env(struct evsel *evsel); +uint16_t evsel__e_machine(struct evsel *evsel); =20 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist); =20 diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c b/tools/perf/ut= il/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 =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason(EM_AARCH64)); key->exit_reasons =3D arm64_exit_reasons; =20 /* @@ -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)); } =20 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/per= f/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 #include +#include #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); } =20 diff --git a/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c b/tools/perf/ut= il/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 =3D 64; // TODO: 32-bit support. =20 key->info =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()) & ~CAUSE_IRQ= _FLAG(xlen); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason(EM_RISCV)) & ~C= AUSE_IRQ_FLAG(xlen); key->exit_reasons =3D riscv_exit_reasons; } =20 @@ -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)); } =20 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 @@ =20 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))); } =20 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 =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason()); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason(evsel__e_machi= ne(evsel))); } =20 =20 @@ -31,7 +31,7 @@ bool exit_event_begin(struct evsel *evsel, =20 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))); } =20 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); } =20 -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) } } =20 -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; } } =20 -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; } } =20 -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; } } =20 -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; } } =20 -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; } } =20 -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; } } =20 -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(v= oid) 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; } } =20 -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; } } =20 -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); =20 -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); =20 -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); =20 -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); =20 -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_r= iscv(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); =20 -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); =20 -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); =20 #else /* !HAVE_LIBTRACEEVENT */ =20 -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_un= used, + int *argc __maybe_unused, const char **argv __maybe_unused) { return 0; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 18:20:40 2026 Received: from mail-dl1-f73.google.com (mail-dl1-f73.google.com [74.125.82.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C413736656F for ; Tue, 3 Feb 2026 18:27:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143239; cv=none; b=bNppmf+jDJ59Y822FiXQfWNnGsGC6Acvrzqs0AcUXWpdk0rozDjptHrS/pB/Z4T7v1ztrWPrfetP74X9sd3Bid7d+21mA4AZAGHwU7Fjt2iyPzPXmDvS2ayA9nk93gJkb6q3mk/5F2Xe0zPHJMxLykEsgxRCUfPNV8MMv7GeUNo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143239; c=relaxed/simple; bh=a+Y4py5jBynuEDeCwPw/Te+ijF9HqtSNvPZC2XbL9xw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tMWzV5xtwmlxNlj50nGkrZBr9MYEfpIZBFITtFAZLZY1Et3FoalgAnWrKY1BtEzmyYIMlkgs2QWXLlBe/sqIm2OdTSwr9NF5XnMMldmwXL4L9vfzHL1Gk+ssobi2JIFPUuLPiJ1bSfw2QOAfZI+HapyFtb5duUU0OqGsheTBPDQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=DI3/zVfm; arc=none smtp.client-ip=74.125.82.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="DI3/zVfm" Received: by mail-dl1-f73.google.com with SMTP id a92af1059eb24-124a978ba9bso7055496c88.0 for ; Tue, 03 Feb 2026 10:27:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770143237; x=1770748037; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=IQ/mKH6xXSRuds8KmNTYjhBcMp07hv028GEXnHNtdUs=; b=DI3/zVfmSbviv6mPwto5aYGO+TVEVKLY/hhMwI83tqTwiZ2giTvLOOyVn3vz6rQmDn YgV7qNRlFNuHux4aKI/f6XS6OOZFEO+j+DJpGlksTUuFGOMGgHz0fQYWuwEjeKoF47fS hQN5GjJvzbEpVVQPs3e0i3rk1ljbQmQ5xFhdFV9HukEOC1XiRilcLnJIfVV/x6/9fvUg WIwNrnrFIAndlpjm46u3JFu9fqISNKLYvNVcTYGIEGbmjXl54BtCG1l3aTWf8sfOJfBh /W/qNJLivv2zEjjZQBoHtfrDPmmGiF7FKFm1QANElJ2YkxCX72TpecoswQgrJk7Zns8v zN0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770143237; x=1770748037; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IQ/mKH6xXSRuds8KmNTYjhBcMp07hv028GEXnHNtdUs=; b=cmS1weLpsgpstg9AfeeVLyM5PiJDsQ6o8Ou17bOkR1X6OqMJ7/sbl8l8gGHrJ5uEGL oiM2tU4ckIURD724/y0CX/3Y9rqrDuxYXN2+nXWZ2h6BJFZtZHl0as4m7hQoy/R/9Qdf CzPRT7bed6Wqy7BzIvwRUNMc98+DjI9gjz92dxN5ytgaJpfzXOE5IMnqUuqckR3zL5j0 Wvn/JP5V0WAMdB6PJbZfrXBghiy50k52ozKctJcRoQE2hoqq+u/rqoQmZZLP10lQjSzr s+r1/2xE6qZEA4620tBjzQppHd1IbrXzrVzeXguzGl4ubOsJr5SHNarWhCKADKDcyxjv Vtkw== X-Forwarded-Encrypted: i=1; AJvYcCUYkgTKG7lcuMPamdmAy1CrJmbq4hNDVvp6EDZjpULn6Hl0EXIfbw4p5b97N/dAzRznTrOI/17rGSthBkA=@vger.kernel.org X-Gm-Message-State: AOJu0YwHuw0t6T4VFECXJmrkrHxthluMzh5htaSi9D5D4ZSCWd+3YuRH 6q7E+091j+TPyD4vJ7fwtPRUAs27w7K/BogvlzRARj8EJ1yFs8DuOEfhTp/yburFrYYqe06AKlh D6BBLILKQyQ== X-Received: from dlboy9.prod.google.com ([2002:a05:7022:1289:b0:124:9d31:3581]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:b81:b0:119:e56b:989b with SMTP id a92af1059eb24-126f4780cc5mr128964c88.2.1770143236840; Tue, 03 Feb 2026 10:27:16 -0800 (PST) Date: Tue, 3 Feb 2026 10:26:38 -0800 In-Reply-To: <20260203182640.3911987-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260203182640.3911987-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203182640.3911987-4-irogers@google.com> Subject: [PATCH v3 3/5] perf session: Add e_flags to the e_machine helper From: Ian Rogers To: acme@kernel.org Cc: aditya.b1@linux.ibm.com, adrian.hunter@intel.com, ajones@ventanamicro.com, ak@linux.intel.com, alex@ghiti.fr, alexander.shishkin@linux.intel.com, anup@brainfault.org, aou@eecs.berkeley.edu, ashelat@redhat.com, atrajeev@linux.ibm.com, blakejones@google.com, ctshao@google.com, dapeng1.mi@linux.intel.com, dvyukov@google.com, howardchu95@gmail.com, irogers@google.com, james.clark@linaro.org, john.g.garry@oracle.com, jolsa@kernel.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, mingo@redhat.com, namhyung@kernel.org, palmer@dabbelt.com, peterz@infradead.org, pjw@kernel.org, shimin.guo@skydio.com, swapnil.sapkal@amd.com, thomas.falcon@intel.com, will@kernel.org, ysk@kzalloc.com, zhouquan@iscas.ac.cn Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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, =20 if (kvm->duration && time_diff > kvm->duration) { char decode[KVM_EVENT_NAME_LEN]; - uint16_t e_machine =3D perf_session__e_machine(kvm->session); + uint16_t e_machine =3D perf_session__e_machine(kvm->session, /*e_flags= =3D*/NULL); =20 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; } =20 - e_machine =3D perf_session__e_machine(kvm->session); + e_machine =3D perf_session__e_machine(kvm->session, /*e_flags=3D*/NULL); err =3D cpu_isa_init(kvm, e_machine, cpuid); if (err =3D=3D -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 =3D { .path =3D kvm->file_name, .mode =3D PERF_DATA_MODE_READ, @@ -1574,7 +1574,8 @@ static int read_events(struct perf_kvm_stat *kvm) goto out_delete; } =20 - if (!register_kvm_events_ops(kvm, perf_session__e_machine(kvm->session)))= { + e_machine =3D perf_session__e_machine(kvm->session, /*e_flags=3D*/NULL); + if (!register_kvm_events_ops(kvm, e_machine)) { ret =3D -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) } } =20 - callchain_param_setup(sample_type, perf_session__e_machine(session)); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_f= lags=3D*/NULL)); =20 if (rep->stitch_lbr && (callchain_param.record_mode !=3D 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 =3D evlist__combined_sample_type(*pevlist); session =3D (*pevlist)->session; - callchain_param_setup(sample_type, perf_session__e_machine(session)); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_f= lags=3D*/NULL)); return 0; } =20 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 =3D container_of(tool, struct perf_script, tool); struct evlist *evlist; struct evsel *evsel, *pos; + uint16_t e_machine; u64 sample_type; int err; =20 @@ -2859,7 +2860,8 @@ static int process_attr(const struct perf_tool *tool,= union perf_event *event, * on events sample_type. */ sample_type =3D evlist__combined_sample_type(evlist); - callchain_param_setup(sample_type, perf_session__e_machine(evsel__session= (evsel))); + e_machine =3D perf_session__e_machine(evsel__session(evsel), /*e_flags=3D= */NULL); + callchain_param_setup(sample_type, e_machine); =20 /* Enable fields for callchain entries */ if (symbol_conf.use_callchain && @@ -3834,7 +3836,7 @@ static void script__setup_sample_type(struct perf_scr= ipt *script) struct perf_session *session =3D script->session; u64 sample_type =3D evlist__combined_sample_type(session->evlist); =20 - callchain_param_setup(sample_type, perf_session__e_machine(session)); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_f= lags=3D*/NULL)); =20 if (script->stitch_lbr && (callchain_param.record_mode !=3D 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 *bu= f, size_t size) return ret; } =20 -uint16_t evsel__e_machine(struct evsel *evsel) +uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags) { struct perf_session *session =3D evsel__session(evsel); =20 - return session ? perf_session__e_machine(session) : EM_HOST; + return perf_session__e_machine(session, e_flags); } =20 static void __evsel__config_callchain(struct evsel *evsel, struct record_o= pts *opts, @@ -1050,7 +1050,7 @@ static void __evsel__config_callchain(struct evsel *e= vsel, struct record_opts *o =20 if (param->record_mode =3D=3D CALLCHAIN_DWARF) { if (!function) { - uint16_t e_machine =3D evsel__e_machine(evsel); + uint16_t e_machine =3D evsel__e_machine(evsel, /*e_flags=3D*/NULL); =20 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) =20 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); =20 int evsel__store_ids(struct evsel *evsel, struct evlist *evlist); =20 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 @@ =20 bool kvm_exit_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_exit_trace(evsel__e_machine(evsel))); + uint16_t e_machine =3D evsel__e_machine(evsel, /*e_flags=3D*/NULL); + + return evsel__name_is(evsel, kvm_exit_trace(e_machine)); } =20 void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { + uint16_t e_machine =3D evsel__e_machine(evsel, /*e_flags=3D*/NULL); + key->info =3D 0; - key->key =3D evsel__intval(evsel, sample, kvm_exit_reason(evsel__e_machi= ne(evsel))); + key->key =3D evsel__intval(evsel, sample, kvm_exit_reason(e_machine)); } =20 =20 @@ -31,7 +35,9 @@ bool exit_event_begin(struct evsel *evsel, =20 bool kvm_entry_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_entry_trace(evsel__e_machine(evsel))); + uint16_t e_machine =3D evsel__e_machine(evsel, /*e_flags=3D*/NULL); + + return evsel__name_is(evsel, kvm_entry_trace(e_machine)); } =20 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_sess= ion *session) return &session->header.env; } =20 -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 =3D arg; + struct perf_session__e_machine_cb_args *args =3D _args; struct machine *machine =3D maps__machine(thread__maps(thread)); =20 - *result =3D thread__e_machine(thread, machine, /*e_flags=3D*/NULL); - return *result !=3D EM_NONE ? 1 : 0; + args->e_machine =3D thread__e_machine(thread, machine, + args->need_e_flags ? &args->e_flags : NULL); + return args->e_machine !=3D EM_NONE ? 1 : 0; } =20 /* * 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 =3D EM_NONE; + struct perf_session__e_machine_cb_args args =3D { + .e_machine =3D EM_NONE, + .need_e_flags =3D e_flags !=3D NULL, + }; + + if (!session) { + /* Default to assuming a host machine. */ + if (e_flags) + *e_flags =3D EF_HOST; + + return EM_HOST; + } =20 machines__for_each_thread(&session->machines, - perf_session__e_machine_cb, - &e_machine); + perf_session__e_machine_cb, + &args); + + if (e_flags) + *e_flags =3D args.e_flags; =20 - return e_machine =3D=3D EM_NONE ? EM_HOST : e_machine; + return args.e_machine =3D=3D 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 per= f_tool *tool, struct ordered_events *oe); =20 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); =20 #endif /* __PERF_SESSION_H */ --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 18:20:40 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E80F1369997 for ; Tue, 3 Feb 2026 18:27:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143244; cv=none; b=mKSUP4d3YYG5JrHiLZZVWN++MNUeGT3WS/qOiSnsI2BKwfEEa4nr2w+0Y5JSl7c03u0jNMvuHtb98tgnKFbzoEEO63tOFMS61duDQSmgPLpehW9f9NvGJz3wEEJdy5PG+HPu2nAKvXtrD7cbty/dUIcEN4cU8PVyqTlHCaCOPLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143244; c=relaxed/simple; bh=sXKSOtLcPaTeWkO/mEs3KygOYQnKMmsW10C7VrPm5yA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=OQzz2jy8P1uKa7Vgb4/H/Z76nv2gj0flb5zvmZBUugGdoj69P0NDiBcACPKzATsHRx/+sD+T9r7k8WYTScgECF06C/hFkz4o5856bkkYQt9j/lB53DbEYYB42x1qjScYMwuJrYyvhx8Hx81pYWSt7SERY9btq8HUfJ9M6DD5wec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ED/6hEJu; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ED/6hEJu" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2b7eddde359so3667564eec.0 for ; Tue, 03 Feb 2026 10:27:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770143242; x=1770748042; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yIM5+Of9W90WeHpl1KAdtOvtvkuL79tdVDHtpDNPDbc=; b=ED/6hEJuEHnwAhQWVkfVKOBB++5rnKW28S3EC1D/2R8wG8ri177jK6sHT2JVP/lgEO Ca//cpXler1yWifU1ofZlqq5No7FoOT85oxGJC42e8wkssn0cwGquGup1+jeljld3prV 3de+FoMdL1rqhRwSacJFwxhU2opZfbJBFdZAd6RhekmyH0NAHqnr4e/Vc6T/qlUxpec4 1sjzkpfsKMjLi1LOL9hfT6itf67aYA13GA4sCsf6eRcWnzMhJBuGqhBhxqyA4Ke41cyl R8i8p6XNhbwx4NQ42F+7UpEEJs9VtKN808SoLbrnUcAts+PGa0zwycGi996JOIayekhw /iYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770143242; x=1770748042; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yIM5+Of9W90WeHpl1KAdtOvtvkuL79tdVDHtpDNPDbc=; b=ZJAGqpafyghOdosc30/pIAhLOezok/VNVH3LqJqEhy2cP1veWZKEFW8wibPukkq36G yZ2lzoaamXwigthVrFGPuJyc2jaw6JZyn1buNLxW9TFh/rdJebB8dbb6lHbuSX1r0Hip RFsuNsvAnCNZfUpWNx2rLwRMw1SsPeCB1iOSmOF+74Nr13l8F1jCaM1LXFxF4nqMmlG3 KkbQd+UgTF6IfbtrBAy44J4ig0/7As9jnLHObpAH1x0vyda31n1jYTxVACTHUZNKTn01 WHyB5iBCC+9zrbKLqDFDu8jy/pdz2fYJryqF/nOj/Z13PT1V2JvZeMKvwVQwWtY1lIUH xa0w== X-Forwarded-Encrypted: i=1; AJvYcCUCtuvhl1Y27vgQxMn7PrCGYzmXnvGOgAa95oY8uEOL1MTx0SgEY1+WnEm/mvaviZWSmL5R6K4ygUl8xoM=@vger.kernel.org X-Gm-Message-State: AOJu0YxYMOhcgDZ/yPOSLpeyNhdOEQ5iI2qUVb9XV6D3a86YGsuz/icX KnyOJtlOtFxx6vgzdYW9s1XZlo6Apz9x1EmSS/kIl+/3h9QFfG8Y5wWDPgmmdcPE63L6atxEYOr WACSLQXQgSg== X-Received: from dyaw27-n1.prod.google.com ([2002:a05:693c:415b:10b0:2b0:5041:8a8b]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7301:7bc2:b0:2b7:18eb:a0b9 with SMTP id 5a478bee46e88-2b8329b3935mr163770eec.43.1770143242111; Tue, 03 Feb 2026 10:27:22 -0800 (PST) Date: Tue, 3 Feb 2026 10:26:39 -0800 In-Reply-To: <20260203182640.3911987-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260203182640.3911987-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203182640.3911987-5-irogers@google.com> Subject: [PATCH v3 4/5] perf header: Add e_machine/e_flags to the header From: Ian Rogers To: acme@kernel.org Cc: aditya.b1@linux.ibm.com, adrian.hunter@intel.com, ajones@ventanamicro.com, ak@linux.intel.com, alex@ghiti.fr, alexander.shishkin@linux.intel.com, anup@brainfault.org, aou@eecs.berkeley.edu, ashelat@redhat.com, atrajeev@linux.ibm.com, blakejones@google.com, ctshao@google.com, dapeng1.mi@linux.intel.com, dvyukov@google.com, howardchu95@gmail.com, irogers@google.com, james.clark@linaro.org, john.g.garry@oracle.com, jolsa@kernel.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, mingo@redhat.com, namhyung@kernel.org, palmer@dabbelt.com, peterz@infradead.org, pjw@kernel.org, shimin.guo@skydio.com, swapnil.sapkal@amd.com, thomas.falcon@intel.com, will@kernel.org, ysk@kzalloc.com, zhouquan@iscas.ac.cn Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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); } =20 +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 =3D perf_session__e_machine(evlist->session, &e_flags); + int ret; + + ret =3D 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); } =20 +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); =20 +static int process_e_machine(struct feat_fd *ff, void *data __maybe_unused) +{ + int ret; + + ret =3D 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] =3D { 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), }; =20 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 =3D 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_sessio= n *session) struct perf_session__e_machine_cb_args { uint32_t e_flags; uint16_t e_machine; - bool need_e_flags; }; =20 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 =3D _args; struct machine *machine =3D maps__machine(thread__maps(thread)); =20 - args->e_machine =3D thread__e_machine(thread, machine, - args->need_e_flags ? &args->e_flags : NULL); + args->e_machine =3D thread__e_machine(thread, machine, &args->e_flags); return args->e_machine !=3D EM_NONE ? 1 : 0; } =20 @@ -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 =3D { .e_machine =3D EM_NONE, - .need_e_flags =3D e_flags !=3D NULL, }; + struct perf_env *env; =20 if (!session) { /* Default to assuming a host machine. */ @@ -2999,12 +2997,35 @@ uint16_t perf_session__e_machine(struct perf_sessio= n *session, uint32_t *e_flags return EM_HOST; } =20 + env =3D perf_session__env(session); + if (env && env->e_machine !=3D EM_NONE) { + if (e_flags) + *e_flags =3D env->e_flags; + + return env->e_machine; + } + machines__for_each_thread(&session->machines, perf_session__e_machine_cb, &args); =20 + if (args.e_machine !=3D EM_NONE) { + if (env) { + env->e_machine =3D args.e_machine; + env->e_flags =3D args.e_flags; + } + if (e_flags) + *e_flags =3D 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 =3D args.e_flags; + *e_flags =3D EF_HOST; =20 - return args.e_machine =3D=3D EM_NONE ? EM_HOST : args.e_machine; + return EM_HOST; } --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 18:20:40 2026 Received: from mail-dy1-f202.google.com (mail-dy1-f202.google.com [74.125.82.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6130364EA6 for ; Tue, 3 Feb 2026 18:27:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143250; cv=none; b=LboUeq3YTbBMG8Q3WqH/XT647kOjR4SwCBrNO46xeJ68J1+Ao2ENPMqLTRrvp882zIDPBVFUzZEs7xLjXW2VJQNDX2KZ0suOkUG7lnYRBumnqIGVpo75eJYXZKnomjJj0gy0g7mzFMf7EwFezIjcjrnLu5/EnGlT0L817q8AOtc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770143250; c=relaxed/simple; bh=cxW5E6PS3j+YMSlMxPs0pg15R3kh9Gvwggyb8H61pds=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=R9T+HLJo0rfq8KQBljbRwZhOZI1vBm90q84VpkPlIP/NoNEepLHZF+gYi/w5ORZGlTl2BZUxrdZhQteOJ0+yCR03M0tlF7carQ/gBA/j+DMWLsgJufDqPqyCDSBm/JTmPO8H7gGM0yKx2rT+bhfNZUOwTkzj9ERDdJxzzbt2HvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=YfGSdv+B; arc=none smtp.client-ip=74.125.82.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="YfGSdv+B" Received: by mail-dy1-f202.google.com with SMTP id 5a478bee46e88-2b75222e9easo13362364eec.1 for ; Tue, 03 Feb 2026 10:27:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1770143248; x=1770748048; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=b4Lo69Fl4f1ujd/UcQ8IKUv7cnjD0QPa0txh8j6kiRg=; b=YfGSdv+BN4DBtmXLM8k4V06gkFUY76dDOp5BnxFmc9Tc6ZQVhYZoAN/gnkw+SBN7Zl X5aH0sg1YgEYj8KWTbHy70vLSv3OmYCbpZ+/Uwq/I7Sb0CQxjHinURfOf05NV8GzaBnd 63/fppLu0s6Titvg2Rlx8tCFzxjpJgq31yj+JGW0gOT1wK2Bo+kkK7NceKS2g1l2uABh kXI1neNKu9MrTxqDkNxWa2bqheI0WhlAZwl8WSPYEdAUCeErbGyLT68+IBnen9/rg+4g SLAvUKL9R0dP1E5U3BpJdrTST/UIln74TtAZGaTp9kZ2Dp1v2V4MbTCH2E7zKAdqDECE qk/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770143248; x=1770748048; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=b4Lo69Fl4f1ujd/UcQ8IKUv7cnjD0QPa0txh8j6kiRg=; b=ktHhn0rurpSD32pP5MXNuYHfzt/s+rvCdiBBPoBsv0CI0sga8qQpIyQKiOhtdUCR+L S/1MC/N0wxXQeWZDgoI+olYlaI54HhXtnSZJmViAq0ALb8nXRAD0qPHBMHm0nLywbpvP B/tg1x7/QjnuVxViSXmdxUE7i6iEDQztjZkGEyVevjk5fGz/Y5Fj843ADxEVJrhvrP6T rkPgV+xwRxWa7du3eoE18TDylgpC7eYm277W+F326lo/GjGBp+AdNzd0uhgBLCcsAD4e NwrhlKH6mQw9Z3sWSQ9ypmyjdr+3u736GVbye8YfN8EFrEHAvL/Hb9AusqN8TLZr4Hzu PwVA== X-Forwarded-Encrypted: i=1; AJvYcCVlpy40e3IsE56ibbTK5oEX5l+X90WapxPcdAbZPLn5vuW+T6tsSmTpd6JaEPCN2rvO/5jeL0T6wiqFADk=@vger.kernel.org X-Gm-Message-State: AOJu0YzhUnJTkrQxwUDYUbRKY58C0k0V0w/QWCjQ50upOER3b5tjRsCx EZSPpZWWY/oa6BowpwD+RDXME+uhq3bGbDWBwzQEEhgEtL/J8tXYVnTOG1cG7ZsMpgUJGuBkueJ aFeHKdSufwg== X-Received: from dybmd11.prod.google.com ([2002:a05:7301:180b:b0:2a4:6ffc:87c9]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:a287:b0:2b7:f522:9964 with SMTP id 5a478bee46e88-2b83296f2f4mr186503eec.7.1770143247875; Tue, 03 Feb 2026 10:27:27 -0800 (PST) Date: Tue, 3 Feb 2026 10:26:40 -0800 In-Reply-To: <20260203182640.3911987-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260203182640.3911987-1-irogers@google.com> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog Message-ID: <20260203182640.3911987-6-irogers@google.com> Subject: [PATCH v3 5/5] perf thread: Don't require machine to compute the e_machine From: Ian Rogers To: acme@kernel.org Cc: aditya.b1@linux.ibm.com, adrian.hunter@intel.com, ajones@ventanamicro.com, ak@linux.intel.com, alex@ghiti.fr, alexander.shishkin@linux.intel.com, anup@brainfault.org, aou@eecs.berkeley.edu, ashelat@redhat.com, atrajeev@linux.ibm.com, blakejones@google.com, ctshao@google.com, dapeng1.mi@linux.intel.com, dvyukov@google.com, howardchu95@gmail.com, irogers@google.com, james.clark@linaro.org, john.g.garry@oracle.com, jolsa@kernel.org, leo.yan@linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-riscv@lists.infradead.org, mingo@redhat.com, namhyung@kernel.org, palmer@dabbelt.com, peterz@infradead.org, pjw@kernel.org, shimin.guo@skydio.com, swapnil.sapkal@amd.com, thomas.falcon@intel.com, will@kernel.org, ysk@kzalloc.com, zhouquan@iscas.ac.cn Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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_sampl= e *sample, PyObject *callchain) { PyObject *dict, *dict_sample, *brstack, *brstacksym; - struct machine *machine; uint16_t e_machine =3D EM_HOST; uint32_t e_flags =3D EF_HOST; =20 @@ -926,10 +925,9 @@ static PyObject *get_perf_sample_dict(struct perf_samp= le *sample, PyLong_FromUnsignedLongLong(sample->cyc_cnt)); } =20 - if (al->thread) { - machine =3D maps__machine(thread__maps(al->thread)); - e_machine =3D thread__e_machine(al->thread, machine, &e_flags); - } + if (al->thread) + e_machine =3D thread__e_machine(al->thread, /*machine=3D*/NULL, &e_flags= ); + if (set_regs_in_dict(dict, sample, evsel, e_machine, e_flags)) Py_FatalError("Failed to setting regs in dict"); =20 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 =3D _args; - struct machine *machine =3D maps__machine(thread__maps(thread)); =20 - args->e_machine =3D thread__e_machine(thread, machine, &args->e_flags); + args->e_machine =3D thread__e_machine(thread, /*machine=3D*/NULL, &args->= e_flags); return args->e_machine !=3D EM_NONE ? 1 : 0; } =20 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, stru= ct machine *machine, uint3 return e_machine; } =20 + if (machine =3D=3D NULL) { + struct maps *maps =3D thread__maps(thread); + + machine =3D maps__machine(maps); + } tid =3D thread__tid(thread); pid =3D thread__pid(thread); if (pid !=3D tid) { --=20 2.53.0.rc2.204.g2597b5adb4-goog