On 9/7/2022 9:41 AM, Jim Mattson wrote:
On Tue, Sep 6, 2022 at 8:59 PM Like Xu <like.xu.linux@xxxxxxxxx> wrote:
[...]
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 75dcf7a72605..08a29ab096d2 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -1094,7 +1094,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
entry->edx = 0;
break;
case 0x80000000:
- entry->eax = min(entry->eax, 0x80000021);
+ entry->eax = min(entry->eax, 0x80000022);
/*
* Serializing LFENCE is reported in a multitude of ways, and
* NullSegClearsBase is not reported in CPUID on Zen2; help
@@ -1203,6 +1203,25 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
if (!static_cpu_has_bug(X86_BUG_NULL_SEG))
entry->eax |= BIT(6);
break;
+ /* AMD Extended Performance Monitoring and Debug */
+ case 0x80000022: {
+ union cpuid_0x80000022_eax eax;
+ union cpuid_0x80000022_ebx ebx;
+
+ entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+ if (!enable_pmu)
+ break;
+
+ if (kvm_pmu_cap.version > 1) {
+ /* AMD PerfMon is only supported up to V2 in the KVM. */
+ eax.split.perfmon_v2 = 1;
+ ebx.split.num_core_pmc = min(kvm_pmu_cap.num_counters_gp,
+ KVM_AMD_PMC_MAX_GENERIC);
Note that the number of core PMCs has to be at least 6 if
guest_cpuid_has(vcpu, X86_FEATURE_PERFCTR_CORE). I suppose this leaf
could claim fewer, but the first 6 PMCs must work, per the v1 PMU
spec. That is, software that knows about PERFCTR_CORE, but not about
PMU v2, can rightfully expect 6 PMCs.
I thought the NumCorePmc number would only make sense if
CPUID.80000022.eax.perfmon_v2
bit was present, but considering that the user space is perfectly fine with just
configuring the
NumCorePmc number without setting perfmon_v2 bit at all, so how about:
CPUID.80000022H might only make sense if X86_FEATURE_PERFCTR_CORE is
present. It's hard to know in the absence of documentation.
Whenever this happens, we may always leave the definition of behavior to the
hypervisor.
I disagree. If CPUID.0H reports "AuthenticAMD," then AMD is the sole
authority on behavior.
I understand that official documentation is not out yet. However, for Zen 4
models, it is expected that both the PerfMonV2 bit of CPUID.80000022H EAX and
the PerfCtrExtCore bit of CPUID.80000001H ECX will be set.
/* AMD Extended Performance Monitoring and Debug */
case 0x80000022: {
union cpuid_0x80000022_eax eax;
union cpuid_0x80000022_ebx ebx;
bool perfctr_core;
entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
if (!enable_pmu)
break;
perfctr_core = kvm_cpu_cap_has(X86_FEATURE_PERFCTR_CORE);
if (!perfctr_core)
ebx.split.num_core_pmc = AMD64_NUM_COUNTERS;
if (kvm_pmu_cap.version > 1) {
/* AMD PerfMon is only supported up to V2 in the KVM. */
eax.split.perfmon_v2 = 1;
ebx.split.num_core_pmc = min(kvm_pmu_cap.num_counters_gp,
KVM_AMD_PMC_MAX_GENERIC);
}
if (perfctr_core) {
ebx.split.num_core_pmc = max(ebx.split.num_core_pmc,
AMD64_NUM_COUNTERS_CORE);
}
This still isn't quite right. All AMD CPUs must support a minimum of 4 PMCs.
K7 at least. I could not confirm that all antique AMD CPUs have 4 counters w/o
perfctr_core.
The APM says, "All implementations support the base set of four
performance counter / event-select pairs." That is unequivocal.
That is true. The same can be inferred from amd_core_pmu_init() in
arch/x86/events/amd/core.c. If PERFCTR_CORE is not detected, it assumes
that the four legacy counters are always available.
- Sandipan