From: Like Xu <likexu@xxxxxxxxxxx> Updated test cases to cover KVM enabling code for AMD Guest PerfMonV2. The Intel-specific PMU helpers were added to check for AMD cpuid, and some of the same semantics of MSRs were assigned during the initialization phase. The vast majority of pmu test cases are reused seamlessly. On some x86 machines (AMD only), even with retired events, the same workload is measured repeatedly and the number of events collected is erratic, which essentially reflects the details of hardware implementation, and from a software perspective, the type of event is an unprecise event, which brings a tolerance check in the counter overflow testcases. Signed-off-by: Like Xu <likexu@xxxxxxxxxxx> --- lib/x86/msr.h | 5 +++++ lib/x86/pmu.c | 9 ++++++++- lib/x86/pmu.h | 6 +++++- lib/x86/processor.h | 2 +- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/x86/msr.h b/lib/x86/msr.h index 6cf8f33..c9869be 100644 --- a/lib/x86/msr.h +++ b/lib/x86/msr.h @@ -426,6 +426,11 @@ #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 +/* AMD Performance Counter Global Status and Control MSRs */ +#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS 0xc0000300 +#define MSR_AMD64_PERF_CNTR_GLOBAL_CTL 0xc0000301 +#define MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR 0xc0000302 + /* Geode defined MSRs */ #define MSR_GEODE_BUSCONT_CONF0 0x00001900 diff --git a/lib/x86/pmu.c b/lib/x86/pmu.c index 7fd2279..d4034cb 100644 --- a/lib/x86/pmu.c +++ b/lib/x86/pmu.c @@ -20,10 +20,17 @@ void pmu_init(void) } else { pmu.msr_gp_counter_base = MSR_F15H_PERF_CTR0; pmu.msr_gp_event_select_base = MSR_F15H_PERF_CTL0; - if (!has_amd_perfctr_core()) + if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) + pmu.nr_gp_counters = cpuid(0x80000022).b & 0xf; + else if (!has_amd_perfctr_core()) pmu.nr_gp_counters = AMD64_NUM_COUNTERS; else pmu.nr_gp_counters = AMD64_NUM_COUNTERS_CORE; + if (this_cpu_support_perf_status()) { + pmu.msr_global_status = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS; + pmu.msr_global_ctl = MSR_AMD64_PERF_CNTR_GLOBAL_CTL; + pmu.msr_global_status_clr = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR; + } } reset_all_counters(); } \ No newline at end of file diff --git a/lib/x86/pmu.h b/lib/x86/pmu.h index a4e00c5..8f5b5ac 100644 --- a/lib/x86/pmu.h +++ b/lib/x86/pmu.h @@ -115,8 +115,12 @@ static inline void write_gp_event_select(unsigned int i, u64 value) static inline u8 pmu_version(void) { - if (!is_intel()) + if (!is_intel()) { + /* Performance Monitoring Version 2 Supported */ + if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) + return 2; return 0; + } return cpuid_10.a & 0xff; } diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 64b36cf..7f884f7 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -266,7 +266,7 @@ static inline bool is_intel(void) #define X86_FEATURE_PAUSEFILTER (CPUID(0x8000000A, 0, EDX, 10)) #define X86_FEATURE_PFTHRESHOLD (CPUID(0x8000000A, 0, EDX, 12)) #define X86_FEATURE_VGIF (CPUID(0x8000000A, 0, EDX, 16)) - +#define X86_FEATURE_AMD_PMU_V2 (CPUID(0x80000022, 0, EAX, 0)) static inline bool this_cpu_has(u64 feature) { -- 2.38.1