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> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- lib/x86/msr.h | 5 +++++ lib/x86/pmu.c | 14 +++++++++++++- lib/x86/processor.h | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/x86/msr.h b/lib/x86/msr.h index 6cf8f336..c9869be5 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 090e1115..af68f3a8 100644 --- a/lib/x86/pmu.c +++ b/lib/x86/pmu.c @@ -39,9 +39,15 @@ void pmu_init(void) pmu.msr_global_status_clr = MSR_CORE_PERF_GLOBAL_OVF_CTRL; } } else { + /* Performance Monitoring Version 2 Supported */ + if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) + pmu.version = 2; + pmu.msr_gp_counter_base = MSR_F15H_PERF_CTR0; pmu.msr_gp_event_select_base = MSR_F15H_PERF_CTL0; - if (!this_cpu_has(X86_FEATURE_PERFCTR_CORE)) + if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) + pmu.nr_gp_counters = cpuid(0x80000022).b & 0xf; + else if (!this_cpu_has(X86_FEATURE_PERFCTR_CORE)) pmu.nr_gp_counters = AMD64_NUM_COUNTERS; else pmu.nr_gp_counters = AMD64_NUM_COUNTERS_CORE; @@ -49,6 +55,12 @@ void pmu_init(void) pmu.gp_counter_width = PMC_DEFAULT_WIDTH; pmu.gp_counter_mask_length = pmu.nr_gp_counters; pmu.gp_counter_available = (1u << pmu.nr_gp_counters) - 1; + + if (this_cpu_has_perf_global_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; + } } pmu_reset_all_counters(); diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 681e1675..72bdc833 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.431.g37b22c650d-goog