[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <bd144177-94e6-49b2-8c9e-b5edbaa42aeb@amd.com>
Date: Fri, 3 Oct 2025 10:33:43 +0530
From: Sandipan Das <sandidas@....com>
To: Sean Christopherson <seanjc@...gle.com>
Cc: Marc Zyngier <maz@...nel.org>, Oliver Upton <oliver.upton@...ux.dev>,
Tianrui Zhao <zhaotianrui@...ngson.cn>, Bibo Mao <maobibo@...ngson.cn>,
Huacai Chen <chenhuacai@...nel.org>, Anup Patel <anup@...infault.org>,
Paul Walmsley <paul.walmsley@...ive.com>, Palmer Dabbelt
<palmer@...belt.com>, Albert Ou <aou@...s.berkeley.edu>,
Xin Li <xin@...or.com>, "H. Peter Anvin" <hpa@...or.com>,
Andy Lutomirski <luto@...nel.org>, Peter Zijlstra <peterz@...radead.org>,
Ingo Molnar <mingo@...hat.com>, Arnaldo Carvalho de Melo <acme@...nel.org>,
Namhyung Kim <namhyung@...nel.org>, Paolo Bonzini <pbonzini@...hat.com>,
linux-arm-kernel@...ts.infradead.org, kvmarm@...ts.linux.dev,
kvm@...r.kernel.org, loongarch@...ts.linux.dev,
kvm-riscv@...ts.infradead.org, linux-riscv@...ts.infradead.org,
linux-kernel@...r.kernel.org, linux-perf-users@...r.kernel.org,
Kan Liang <kan.liang@...ux.intel.com>, Yongwei Ma <yongwei.ma@...el.com>,
Mingwei Zhang <mizhang@...gle.com>,
Xiong Zhang <xiong.y.zhang@...ux.intel.com>,
Sandipan Das <sandipan.das@....com>, Dapeng Mi <dapeng1.mi@...ux.intel.com>
Subject: Re: [PATCH v5 32/44] KVM: x86/pmu: Disable interception of select PMU
MSRs for mediated vPMUs
On 10/1/2025 11:44 PM, Sean Christopherson wrote:
> On Fri, Sep 26, 2025, Sandipan Das wrote:
>> On 8/7/2025 1:26 AM, Sean Christopherson wrote:
>>> From: Dapeng Mi <dapeng1.mi@...ux.intel.com>
>>>
>>> For vCPUs with a mediated vPMU, disable interception of counter MSRs for
>>> PMCs that are exposed to the guest, and for GLOBAL_CTRL and related MSRs
>>> if they are fully supported according to the vCPU model, i.e. if the MSRs
>>> and all bits supported by hardware exist from the guest's point of view.
>>>
>>> Do NOT passthrough event selector or fixed counter control MSRs, so that
>>> KVM can enforce userspace-defined event filters, e.g. to prevent use of
>>> AnyThread events (which is unfortunately a setting in the fixed counter
>>> control MSR).
>>>
>>> Defer support for nested passthrough of mediated PMU MSRs to the future,
>>> as the logic for nested MSR interception is unfortunately vendor specific.
>
> ...
>
>>> #define MSR_AMD64_LBR_SELECT 0xc000010e
>>> diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
>>> index 4246e1d2cfcc..817ef852bdf9 100644
>>> --- a/arch/x86/kvm/pmu.c
>>> +++ b/arch/x86/kvm/pmu.c
>>> @@ -715,18 +715,14 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
>>> return 0;
>>> }
>>>
>>> -bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu)
>>> +bool kvm_need_perf_global_ctrl_intercept(struct kvm_vcpu *vcpu)
>>> {
>>> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>>>
>>> if (!kvm_vcpu_has_mediated_pmu(vcpu))
>>> return true;
>>>
>>> - /*
>>> - * VMware allows access to these Pseduo-PMCs even when read via RDPMC
>>> - * in Ring3 when CR4.PCE=0.
>>> - */
>>> - if (enable_vmware_backdoor)
>>> + if (!kvm_pmu_has_perf_global_ctrl(pmu))
>>> return true;
>>>
>>> /*
>>> @@ -735,7 +731,22 @@ bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu)
>>> * capabilities themselves may be a subset of hardware capabilities.
>>> */
>>> return pmu->nr_arch_gp_counters != kvm_host_pmu.num_counters_gp ||
>>> - pmu->nr_arch_fixed_counters != kvm_host_pmu.num_counters_fixed ||
>>> + pmu->nr_arch_fixed_counters != kvm_host_pmu.num_counters_fixed;
>>> +}
>>> +EXPORT_SYMBOL_GPL(kvm_need_perf_global_ctrl_intercept);
>>> +
>>> +bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu)
>>> +{
>>> + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>>> +
>>> + /*
>>> + * VMware allows access to these Pseduo-PMCs even when read via RDPMC
>>> + * in Ring3 when CR4.PCE=0.
>>> + */
>>> + if (enable_vmware_backdoor)
>>> + return true;
>>> +
>>> + return kvm_need_perf_global_ctrl_intercept(vcpu) ||
>>> pmu->counter_bitmask[KVM_PMC_GP] != (BIT_ULL(kvm_host_pmu.bit_width_gp) - 1) ||
>>> pmu->counter_bitmask[KVM_PMC_FIXED] != (BIT_ULL(kvm_host_pmu.bit_width_fixed) - 1);
>>> }
>>
>> There is a case for AMD processors where the global MSRs are absent in the guest
>> but the guest still uses the same number of counters as what is advertised by the
>> host capabilities. So RDPMC interception is not necessary for all cases where
>> global control is unavailable.o
>
> Hmm, I think Intel would be the same? Ah, no, because the host will have fixed
> counters, but the guest will not. However, that's not directly related to
> kvm_pmu_has_perf_global_ctrl(), so I think this would be correct?
>
> diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
> index 4414d070c4f9..4c5b2712ee4c 100644
> --- a/arch/x86/kvm/pmu.c
> +++ b/arch/x86/kvm/pmu.c
> @@ -744,16 +744,13 @@ int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
> return 0;
> }
>
> -bool kvm_need_perf_global_ctrl_intercept(struct kvm_vcpu *vcpu)
> +static bool kvm_need_pmc_intercept(struct kvm_vcpu *vcpu)
> {
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>
> if (!kvm_vcpu_has_mediated_pmu(vcpu))
> return true;
>
> - if (!kvm_pmu_has_perf_global_ctrl(pmu))
> - return true;
> -
> /*
> * Note! Check *host* PMU capabilities, not KVM's PMU capabilities, as
> * KVM's capabilities are constrained based on KVM support, i.e. KVM's
> @@ -762,6 +759,13 @@ bool kvm_need_perf_global_ctrl_intercept(struct kvm_vcpu *vcpu)
> return pmu->nr_arch_gp_counters != kvm_host_pmu.num_counters_gp ||
> pmu->nr_arch_fixed_counters != kvm_host_pmu.num_counters_fixed;
> }
> +
> +bool kvm_need_perf_global_ctrl_intercept(struct kvm_vcpu *vcpu)
> +{
> +
> + return kvm_need_pmc_intercept(vcpu) ||
> + !kvm_pmu_has_perf_global_ctrl(vcpu_to_pmu(vcpu));
> +}
> EXPORT_SYMBOL_GPL(kvm_need_perf_global_ctrl_intercept);
>
> bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu)
> @@ -775,7 +779,7 @@ bool kvm_need_rdpmc_intercept(struct kvm_vcpu *vcpu)
> if (enable_vmware_backdoor)
> return true;
>
> - return kvm_need_perf_global_ctrl_intercept(vcpu) ||
> + return kvm_need_pmc_intercept(vcpu) ||
> pmu->counter_bitmask[KVM_PMC_GP] != (BIT_ULL(kvm_host_pmu.bit_width_gp) - 1) ||
> pmu->counter_bitmask[KVM_PMC_FIXED] != (BIT_ULL(kvm_host_pmu.bit_width_fixed) - 1);
> }
This looks good. Thanks.
Powered by blists - more mailing lists