From nobody Sat Feb 7 08:02:49 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 0A6E025771 for ; Wed, 28 Jan 2026 07:41:09 +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=1769586072; cv=none; b=VLrJeynoYtoPCBUoR1lUk9yc1V7TuJS/AyxDQpxOAtSNzBISmWxOjWy1fBZwl9am7kltAt2B4Q7xI2+gwLUmV0trYoI9kn/HoQSGWapy4J/cmCA5ZWjMZXZWGKvIaqYtLkQcQmbDpWnyVsuGXgjyTSWv+5pMLMhkMceNAJqSKTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769586072; c=relaxed/simple; bh=ZYZ3ts2lEXpoAv2DKF+vERbCqS03n0zKhJZN6rN/scE=; h=Date:Mime-Version:Message-ID:Subject:From:To:Content-Type; b=Q6PaQNcSVStQq/ZqIJdmBdBDBbW6aSLJIeE/098P/SP8X0GLKZvSuo4rD98SxUefZabusGFd55js0cq0/Zcej/zGYX7KS7ZcNPsAhP2nB5ycWXWUe9jpUDgntwT2iFVmNO3Brmp7WAmDRkBKhLzSBLCklWG6hLehxJLqP1VuYQU= 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=ZLRHC7Fb; 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="ZLRHC7Fb" Received: by mail-dl1-f74.google.com with SMTP id a92af1059eb24-1233b91de6bso11198964c88.1 for ; Tue, 27 Jan 2026 23:41:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1769586069; x=1770190869; darn=vger.kernel.org; h=to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=X1yac3VhavJ/iSNuoTf4tOpLzxqJ/EDuq8aVrMeVv+k=; b=ZLRHC7FbS6ECRGCNG+1od8orlgrt5ldvyDF7EhAnODdqs0kJq1a83k/YNPckE9LfIV 08Nmh6MVycWAG9wSLcj/aRY8v6ZiMgKMq4AyZxqnYUExqae4vl3n8IYfqf+sl5VhAnZE cJUfdy/EKcX08cYQzOjsZDvV9jABh7Q9R52wZjnqKVwUrXq7d9QDp/wnSSNK8agg/ga1 71PlCfHbbrca+7lvhLXSEtLr7BkExO2gjmdtSvq9YDx3wAi/U9WIIksn/eb83cIjqBHF 7Qb81PTMgMh1Z8joc8opdMRm4tcu+yeg7Oef7mVdF7mXJ1gYLPFQLYSSTNNpp8TVSqp1 ehYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769586069; x=1770190869; h=to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=X1yac3VhavJ/iSNuoTf4tOpLzxqJ/EDuq8aVrMeVv+k=; b=Gl28W3DCkG9UwK0pMEuoMaH/K3qFVqSZsC7zEaPm86wuOIS4pGCu1gdQVm1AqZf22b 2oDJVtUAKEitOZIUu27fefQmnxxHvfKQPhuogOkyVwfD2KUrdnJwC0112KLP1l6yS08j hqZEpaozA8qmTsS8fTuyQfXcRg/4YXM30vJYuZCYVqBYkYIcEhnw2IkLfF7q++EDeZTV F2EMiRaEk3uVYhRAdGgafaSmxX7gGWbLI3ylrYMie4KP20A7zMHubK+fghv20S2ZwBJM PM2Vr5MZosne7XVWKdME+px93saB0ssxxnKJX1hFKaQbf4ibD+7kuVA1JCLAxy99pDHn e4jg== X-Forwarded-Encrypted: i=1; AJvYcCWPM1dYidhUS6A6zVWCQ/WKZhQBkNpuwU+kPzS5WdDeh1uVNXzDDAaHfLkiTzSwSWVsZV4NmrQa9+8Kd4Y=@vger.kernel.org X-Gm-Message-State: AOJu0YxVC3C+31mtvMijkZb1suW3ahs630lXd0gFkvvTmER8/eM+qq87 NcdwW/OC5+v7K0rpw5uzN8589YDeA3rG+nqEhu7ZXaxDMEKm2YgKLYmIQ9ljb+/rh8Z4zHPI8UX lm/KbuMfGXw== X-Received: from dlnn5.prod.google.com ([2002:a05:7022:6185:b0:11f:30f6:ea10]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:fa3:b0:123:35cb:96e3 with SMTP id a92af1059eb24-124a00e4d53mr2943505c88.46.1769586069175; Tue, 27 Jan 2026 23:41:09 -0800 (PST) Date: Tue, 27 Jan 2026 23:41:05 -0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260128074106.788156-1-irogers@google.com> Subject: [PATCH v1] perf kvm stat: Remove use of the arch directory From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Leo Yan , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti , Shimin Guo , Yunseong Kim , Athira Rajeev , Anup Patel , Quan Zhou , Andrew Jones , Dapeng Mi , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-riscv@lists.infradead.org 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. When the ELF machine can be determined from a header feature (ie EM_HOST at the time of the record) then this can change. 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 +- .../kvm-stat-arch}/arm64_exception_types.h | 0 .../kvm-stat-arch}/book3s_hcalls.h | 0 .../kvm-stat-arch}/book3s_hv_exits.h | 0 .../kvm-stat-arch/kvm-stat-arm64.c} | 43 ++-- .../kvm-stat-arch/kvm-stat-loongarch.c} | 48 ++-- .../kvm-stat-arch/kvm-stat-powerpc.c} | 61 ++--- .../kvm-stat-arch/kvm-stat-riscv.c} | 42 ++-- .../kvm-stat-arch/kvm-stat-s390.c} | 38 ++-- .../kvm-stat-arch/kvm-stat-x86.c} | 44 ++-- .../kvm-stat-arch}/riscv_trap_types.h | 2 +- tools/perf/util/kvm-stat.c | 209 +++++++++++++++++- tools/perf/util/kvm-stat.h | 68 ++++-- 27 files changed, 434 insertions(+), 178 deletions(-) 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/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..2073bfd82b67 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,11 +18,6 @@ define_exit_reasons_table(sie_sigp_order_codes, sigp_ord= er_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) @@ -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..a54cd4496df9 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,11 +111,9 @@ 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) - void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); @@ -130,11 +126,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 +138,49 @@ int setup_kvm_events_tp(struct perf_kvm_stat *kvm); /* * arch specific callbacks and data structures */ -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid); +int setup_kvm_events_tp(struct perf_kvm_stat *kvm); +int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm); =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; +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); =20 static inline struct kvm_info *kvm_info__get(struct kvm_info *ki) { @@ -186,11 +214,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 +224,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.52.0.457.g6b5491de43-goog