Re: [PATCH 16/23] KVM: x86/pmu: Handle FIXED_CTR_CTRL under PerfMon masking

From: Chen, Zide

Date: Thu Aug 27 2026 - 18:39:41 EST




On 8/26/2026 3:43 AM, Mi, Dapeng wrote:
>
> On 8/22/2026 6:19 AM, Zide Chen wrote:
>> PerfMon masking affects reads from and writes to this MSR. The effective
>> mask is defined as bits 4n+3:4n and bits 4n+35:4n+32 being set if and
>> only if bit 32+n of the PerfMon mask is set (for 0 <= n <= 7).
>>
>> KVM doesn't support some fixed-counter features, and
>> pmu->fixed_ctr_ctrl_rsvd is a subset of the effective mask above, so the
>> existing gating in intel_pmu_set_msr() is sufficient even under PerfMon
>> masking.
>>
>> Upon guest PMU context load, OR the guest-owned bits with whatever the
>> hardware currently holds for every fixed-counter index the guest does
>> not own, before writing the result to the MSR.
>>
>> During PMU context put, host-owned fixed counters may still be scheduled
>> for system-wide host events, so the host-owned bits should remain
>> unchanged.
>>
>> Signed-off-by: Zide Chen <zide.chen@xxxxxxxxx>
>> ---
>> arch/x86/kvm/vmx/pmu_intel.c | 40 +++++++++++++++++++++++++++++++++---
>> 1 file changed, 37 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
>> index 19ccc7cd319c..9236bfa15c41 100644
>> --- a/arch/x86/kvm/vmx/pmu_intel.c
>> +++ b/arch/x86/kvm/vmx/pmu_intel.c
>> @@ -920,6 +920,33 @@ static void intel_pmu_write_global_ctrl(u64 global_ctrl)
>> vmcs_write64(GUEST_IA32_PERF_GLOBAL_CTRL, global_ctrl);
>> }
>>
>> +static u64 intel_fixed_ctrl_host_bits(struct kvm_pmu *pmu)
>> +{
>> + unsigned long fixed_mask;
>> + u64 fixed_ctl;
>> + int i;
>> +
>> + if (!kvm_vcpu_has_perfmon_mask(pmu_to_vcpu(pmu)))
>> + return 0;
>> +
>> + fixed_mask = kvm_fixed_pmc_mask(pmu);
>> +
>> + rdmsrq(MSR_CORE_PERF_FIXED_CTR_CTRL, fixed_ctl);
>> +
>> + /*
>> + * Use the full per-counter nibbles (bits 4n+3:4n and 4n+35:4n+32) to
>> + * strip all bits belonging to guest-owned counters.
>> + *
>> + * pmu->fixed_ctr_ctrl_rsvd can't be used here since it can't gate bits
>> + * that are not supported by KVM.
>> + */
>> + kvm_for_each_fixed_counter(i, fixed_mask)
>> + fixed_ctl &= ~intel_fixed_bits_by_idx(i, GENMASK_ULL(3, 0) |
>> + GENMASK_ULL(35, 32));
>> +
>> + return fixed_ctl;
>> +}
>
> Strictly speaking, this should be a perf/x86/intel function and then
> exposed to KVM. Perf host side may also need this function.

The code is slightly different. For example, fc0 is bit 0 in
kvm_fixed_pmc_mask(), while it is bit 32 in the host case
(x86_pmu_current_partition_mask()).

It does not seem worthwhile to refactor the code for reuse for such a
small API.