Re: [PATCH v2 11/16] KVM: x86/pmu: Emulate the GLOBAL_STATUS_SET and GLOBAL_INUSE MSRs

From: Chen, Zide

Date: Mon Nov 02 2026 - 18:34:12 EST




On 11/2/2026 4:51 PM, Yosry Ahmed wrote:
> On Mon, Nov 2, 2026 at 2:48 PM Chen, Zide <zide.chen@xxxxxxxxx> wrote:
>>
>>
>>
>> On 11/2/2026 4:25 PM, Jim Mattson wrote:
>>> On Mon, Nov 2, 2026 at 2:13 PM Chen, Zide <zide.chen@xxxxxxxxx> wrote:
>>>>
>>>>
>>>> On 11/2/2026 3:36 PM, Yosry Ahmed wrote:
>>>>>>>>> 1. GLOBAL_STATUS_TRACE_TOPAPMI_BIT can leak from the host into the
>>>>>>>>> guest. If a host PT PMI arrives while the guest context is loaded, bit
>>>>>>>>> 55 will be set for the guest, and the guest won't be able to clear it if
>>>>>>>>> OVF_CTRL is intercepted (it will #GP as it is reserved for the guest).
>>>>>>>>> Similarly, the value can't be restored through KVM_SET_MSRS.
>>>>>>>> I think mediated vPMU assumes that no host PMIs can be generated while
>>>>>>>> guest PMU state is loaded.
>>>>>>>>
>>>>>>>> If PT state can leak into the guest via bit 55, similar leakage can also
>>>>>>>> occur for other status bits, e.g. when the guest exposes fewer
>>>>>>>> general-purpose or fixed counters than the host.
>>>>>>>>
>>>>>>>> The scenario where both host and guest can be active simultaneously is
>>>>>>>> handled by the perfmon_mask case, where intel_mediated_pmu_{load,put}()
>>>>>>>> filter guest-owned status bits.
>>>>>>> Looking at the code:
>>>>>>>
>>>>>>> kvm_mediated_pmu_load() -> perf_load_guest_context() ->
>>>>>>> perf_ctx_disable() will iterate PMUs with for_each_epc() and disable
>>>>>>> them, which skips PMUs without PERF_PMU_CAP_MEDIATED_VPMU.
>>>>>>>
>>>>>>> Same for kvm_mediated_pmu_load() -> perf_load_guest_context()
>>>>>>> ->ctx_sched_out(), it also uses for_each_epc() to iterate PMUs and
>>>>>>> schedule them out.
>>>>>>>
>>>>>>> pt_init() does not set PERF_PMU_CAP_MEDIATED_VPMU on pt_pmu.pmu.capabilities
>>>>>>>
>>>>>>> Please correct me if I am wrong.
>>>>>> My apologies, this bug is indeed real because pt_pmu lacks the
>>>>>> PERF_PMU_CAP_MEDIATED_VPMU capability.
>>>>>>
>>>>>> Adding this capability to pt_pmu seems intuitive, but unlike
>>>>>>
>>>>>> the core PMU (which merely toggles enable bits),
>>>>>> Intel PT is an AUX-based PMU. Stopping and restarting it on every VM
>>>>>> transition is heavier, and I'm not sure whether it could introduce a
>>>>>> noticeable performance penalty.
>>>>>>
>>>>>> However, whether the solution is adding PERF_PMU_CAP_MEDIATED_VPMU or
>>>>>> some other mechanism to enforce mutual exclusion between pt_pmu and
>>>>>> mediated vPMU, we can address that in a separate patch.
>>>>>>
>>>>>> To immediately protect guest state and live migration in this series,
>>>>>> I'm thinking of adding the following defensive filter in
>>>>>> intel_mediated_pmu_put():
>>>>>>
>>>>>> + /*
>>>>>> + * Scrub bits that are not virtualized for the guest to prevent
>>>>>> + * possible host state from leaking into guest state and breaking
>>>>>> + * live migration.
>>>>>> + */
>>>>>> + pmu->global_status &= ~pmu->global_status_rsvd;
>>>>> This doesn't prevent the leakage, it just clears it on the guest->host
>>>>> switch. So it helps live migration but I am not sure if it's better or
>>>>> worse if the guest sees the bit unexpectedly appear AND then
>>>>> unexpectedly disappear.
>>>> Right, as long as the GLOBAL_STATUS is passthru, the leak can't be
>>>> prevented.
>>>>> We can clear it when the MSR is read by userspace, which should fix
>>>>> live migration, but the guest will still see the bit, and it will
>>>>> still disappear unexpectedly but only during live migration.
>>>>>
>>>>> The guest still won't be able to clear it when OVF_CTRL is intercepted.
>>>> GLOBAL_STATUS and OVF_CTRL share the same interception policy. If they
>>>> are passed through, the guest can see the bit and clear it; if both are
>>>> intercepted, then bit 55 can't leak to the guest.
>>>>
>>>> It's not perfect, but at least the guest won't observe bit 55 and then
>>>> get an unexpected #GP when attempting to clear it.
>>> I'm not sure what imperfect solution you are referring to, but Yosry's
>>> proposal that the bit gets cleared on a guest->host switch is a
>>> non-starter. MSR bits must not vanish unpredictably.
>
> I don't think I proposed this? :)
>
>>
>> Agree, then maybe Yosry's suggestion is what we can do for now: filter
>> out unsupported bits when the MSR is read by userspace.
>
> This I did propose, but I also noted that the MSR bit will still
> vanish unpredictable, just on save/restore instead of guest->host
> switch, which should be better.

Yes.
>>
>> diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
>> index 38c7a4fa1007..3849b3f5234a 100644
>> --- a/arch/x86/kvm/pmu.c
>> +++ b/arch/x86/kvm/pmu.c
>> @@ -862,6 +862,8 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct
>> msr_data *msr_info)
>> switch (msr) {
>> case MSR_CORE_PERF_GLOBAL_STATUS:
>> case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS:
>> + if (msr_info->host_initiated)
>> + pmu->global_status &= ~pmu->global_status_rsvd;
>>
>> The underlying issue still requires proper mutual exclusion between
>> Intel PT and mediated vPMU, which I think can be addressed separately.
>
> Or maybe handle the host PT while the guest is running? Not sure if
> that would be correct.

Since KVM switches APIC LVTPC in guest context, it seems difficult to
correctly handle host PT PMIs while the guest is running.

I guess Intel PT virtualization could be re-enabled sooner or later, and
addressing the exclusion issue would be a must at that point anyway.