KVM: x86/svm/pmu: Rewrite get_gp_pmc_amd() for more counters scalability
authorLike Xu <likexu@tencent.com>
Wed, 31 Aug 2022 08:53:28 +0000 (16:53 +0800)
committerSean Christopherson <seanjc@google.com>
Wed, 28 Sep 2022 19:47:23 +0000 (12:47 -0700)
commitea5cbc9ff839091a86558d4e2c082225b13e0055
tree3f0fb7379e5467a5e84de637a7250b56ceb2590d
parent5c6a67f4f265f84e1b8582f82562dda2a53f52d1
KVM: x86/svm/pmu: Rewrite get_gp_pmc_amd() for more counters scalability

If the number of AMD gp counters continues to grow, the code will
be very clumsy and the switch-case design of inline get_gp_pmc_amd()
will also bloat the kernel text size.

The target code is taught to manage two groups of MSRs, each
representing a different version of the AMD PMU counter MSRs.
The MSR addresses of each group are contiguous, with no holes,
and there is no intersection between two sets of addresses,
but they are discrete in functionality by design like this:

[Group A : All counter MSRs are tightly bound to all event select MSRs ]

  MSR_K7_EVNTSEL0 0xc0010000
  MSR_K7_EVNTSELi 0xc0010000 + i
  ...
  MSR_K7_EVNTSEL3 0xc0010003
  MSR_K7_PERFCTR0 0xc0010004
  MSR_K7_PERFCTRi 0xc0010004 + i
  ...
  MSR_K7_PERFCTR3 0xc0010007

[Group B : The counter MSRs are interleaved with the event select MSRs ]

  MSR_F15H_PERF_CTL0 0xc0010200
  MSR_F15H_PERF_CTR0 (0xc0010200 + 1)
  ...
  MSR_F15H_PERF_CTLi (0xc0010200 + 2 * i)
  MSR_F15H_PERF_CTRi (0xc0010200 + 2 * i + 1)
  ...
  MSR_F15H_PERF_CTL5 (0xc0010200 + 2 * 5)
  MSR_F15H_PERF_CTR5 (0xc0010200 + 2 * 5 + 1)

Rewrite get_gp_pmc_amd() in this way: first determine which group of
registers is accessed, then determine if it matches its requested type,
applying different scaling ratios respectively, and finally get pmc_idx
to pass into amd_pmc_idx_to_pmc().

Signed-off-by: Like Xu <likexu@tencent.com>
Link: https://lore.kernel.org/r/20220831085328.45489-8-likexu@tencent.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/pmu.c