From: Dapeng Mi Date: Fri, 19 Sep 2025 02:16:58 +0000 (+0800) Subject: perf tools kvm: Use "cycles" to sample guest for "kvm record" on Intel X-Git-Tag: v6.18-rc1~35^2~37 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c1afca106e16fbbf9508b3770e6ab1c2f7993ea1;p=thirdparty%2Flinux.git perf tools kvm: Use "cycles" to sample guest for "kvm record" on Intel After KVM supports PEBS for guest on Intel platforms (https://lore.kernel.org/all/20220411101946.20262-1-likexu@tencent.com/), host loses the capability to sample guest with PEBS since all PEBS related MSRs are switched to guest value after vm-entry, like IA32_DS_AREA MSR is switched to guest GVA at vm-entry. This would lead to "perf kvm record" fails to sample guest on Intel platforms since "cycles:P" event is used to sample guest by default as below case shows. sudo perf kvm record -a ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.787 MB perf.data.guest ] So to ensure guest record can be sampled successfully, use "cycles" instead of "cycles:P" to sample guest record by default on Intel platforms. With this patch, the guest record can be sampled successfully. sudo perf kvm record -a ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.783 MB perf.data.guest (23 samples) ] Fixes: cf8e55fe50df0c02 ("KVM: x86/pmu: Expose CPUIDs feature bits PDCM, DS, DTES64") Reported-by: Kevin Tian Signed-off-by: Dapeng Mi Acked-by: Namhyung Kim Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Kan Liang Cc: Like Xu Cc: Paolo Bonzini Cc: Peter Zijlstra Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c index 424716518b75..bff36f9345ea 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/arch/x86/util/kvm-stat.c @@ -3,9 +3,11 @@ #include #include "../../../util/kvm-stat.h" #include "../../../util/evsel.h" +#include "../../../util/env.h" #include #include #include +#include define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS); define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS); @@ -211,3 +213,52 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) return 0; } + +/* + * After KVM supports PEBS for guest on Intel platforms + * (https://lore.kernel.org/all/20220411101946.20262-1-likexu@tencent.com/), + * host loses the capability to sample guest with PEBS since all PEBS related + * MSRs are switched to guest value after vm-entry, like IA32_DS_AREA MSR is + * switched to guest GVA at vm-entry. This would lead to "perf kvm record" + * fails to sample guest on Intel platforms since "cycles:P" event is used to + * sample guest by default. + * + * So, to avoid this issue explicitly use "cycles" instead of "cycles:P" event + * by default to sample guest on Intel platforms. + */ +int kvm_add_default_arch_event(int *argc, const char **argv) +{ + const char **tmp; + bool event = false; + int ret = 0, i, j = *argc; + + const struct option event_options[] = { + OPT_BOOLEAN('e', "event", &event, NULL), + OPT_BOOLEAN(0, "pfm-events", &event, NULL), + OPT_END() + }; + + if (!x86__is_intel_cpu()) + return 0; + + tmp = calloc(j + 1, sizeof(char *)); + if (!tmp) + return -ENOMEM; + + for (i = 0; i < j; i++) + tmp[i] = argv[i]; + + parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN); + if (!event) { + argv[j++] = STRDUP_FAIL_EXIT("-e"); + argv[j++] = STRDUP_FAIL_EXIT("cycles"); + *argc += 2; + } + + free(tmp); + return 0; + +EXIT: + free(tmp); + return ret; +} diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index d297a7b2c088..c0d62add4996 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1636,16 +1636,6 @@ exit: return ret; } -#define STRDUP_FAIL_EXIT(s) \ - ({ char *_p; \ - _p = strdup(s); \ - if (!_p) { \ - ret = -ENOMEM; \ - goto EXIT; \ - } \ - _p; \ - }) - int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused) { return 0; diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index 4249542544bb..53db3d56108b 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -190,5 +190,15 @@ static inline struct kvm_info *kvm_info__new(void) #define kvm_info__zput(ki) do { } while (0) #endif /* HAVE_KVM_STAT_SUPPORT */ +#define STRDUP_FAIL_EXIT(s) \ + ({ char *_p; \ + _p = strdup(s); \ + if (!_p) { \ + ret = -ENOMEM; \ + goto EXIT; \ + } \ + _p; \ + }) + extern int kvm_add_default_arch_event(int *argc, const char **argv); #endif /* __PERF_KVM_STAT_H */