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 - 14:40:09 EST
On 10/30/2026 5:13 PM, Yosry Ahmed wrote:
>>> @@ -865,6 +867,7 @@ int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>> case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR:
>>> case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET:
>>> case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
>>> + case MSR_CORE_PERF_GLOBAL_STATUS_SET:
>>> msr_info->data = 0;
>>> break;
>>> default:
>>> @@ -931,6 +934,12 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>>> if (!msr_info->host_initiated)
>>> pmu->global_status &= ~data;
>>> break;
>>> + case MSR_CORE_PERF_GLOBAL_STATUS_SET:
>>> + if (data & pmu->global_status_rsvd)
>>> + return 1;
>>> + if (!msr_info->host_initiated)
>>> + pmu->global_status |= data;
>>> + break;
>>
>> According to Intel SDM Vol. 4, Table 2-2 ("IA-32 Architectural MSRs"),
>> IA32_PERF_GLOBAL_STATUS.CondChgd[bit 63] cannot be set by writing to
>> IA32_PERF_GLOBAL_STATUS_SET, because IA32_PERF_GLOBAL_STATUS_SET[bit 63] is
>> reserved. In other words, it is not possible to save/restore
>> IA32_PERF_GLOBAL_STATUS when bit 63 is set.
>>
>> Because bit 63 is clear in pmu->global_status_rsvd:
>>
>> 1. An intercepted guest WRMSR(MSR_CORE_PERF_GLOBAL_STATUS_SET, BIT_ULL(63))
>> succeeds instead of injecting #GP(0) and sets bit 63 in
>> pmu->global_status.
>> 2. When bit 63 is set in pmu->global_status (whether it was set by
>> kvm_pmu_set_msr() or by intel_mediated_pmu_put()), the next
>> intel_mediated_pmu_load() will try to write an illegal value to
>> MSR_CORE_PERF_GLOBAL_STATUS_SET. I don't think we get a #GP, because
>> every wrmsr is "safe" these days, but the write will be ignored.
>
> On SPR, it does produce a #GP that gets ignored (and logged) and the bit
> is not set. Interestingly, on CLX, the write goes through and the bit
> is set. Didn't check other CPUs.
Good catch! I tested a few more CPUs (DMR/CWF/SRF/GNR/NVL/LNL), and all
of them #GP on writes that set bit 63.
However, SKX, CLX, and ICX accept writes with bit 63 set and do not
generate #GP. On those systems, bit 63 also becomes visible when reading
back GLOBAL_STATUS. This behavior is documented in their errata:
SKX95/CLX89/ICX166. Bit 63 of IA32_PERF_GLOBAL_STATUS_SET MSR (391H) is
reserved. Due to this erratum, setting the bit will not result in #GP.
SKX:
https://cdrdv2-public.intel.com/336065/336065_Intel%20Xeon%20Processor%20Scalable%20Family%20Public%20Specification%20Update_rev17.pdf
CLX:
https://cdrdv2-public.intel.com/338848/338848_2nd%20Gen%20Intel%C2%AE%20Xeon%C2%AE%20Scalable%20Processors%20Specification%20Update_Rev028US.pdf
ICX:
https://cdrdv2-public.intel.com/637780/637780_3rd_Gen_Xeon_Scalable_Spec_Update_026US.pdf
Given that SKX95/CLX89/ICX166 document this behavior as an erratum,
while SPR and newer CPUs appear to follow the SDM and #GP, should KVM
continue to inject #GP for writes that set bit 63?
>> OTOH, what about PerfMon v4 bits 58 (GLOBAL_STATUS_LBRS_FROZEN), 59
>> (GLOBAL_STATUS_COUNTERS_FROZEN), and 61 (GLOBAL_STATUS_OVF_UNCORE)? Per
>> Intel SDM Vol. 4, Table 2-2, those bits are valid in
>> IA32_PERF_GLOBAL_STATUS, IA32_PERF_GLOBAL_STATUS_RESET, and
>> IA32_PERF_GLOBAL_STATUS_SET when CPUID.0AH:EAX[7:0] > 3.
>>
>> When those MSRs are passed through in mediated mode, the guest can set bits
>> 58, 59, or 61 in hardware via IA32_PERF_GLOBAL_STATUS_SET. Leaving those
>> bits set in pmu->global_status_rsvd for pmu->version >= 4 will break
>> KVM_SET_MSRS(MSR_CORE_PERF_GLOBAL_STATUS) as well as any intercepted guest
>> writes to GLOBAL_OVF_CTRL / GLOBAL_STATUS_SET.
>>
>> As I pointed out in patch 04/16, we can't pass through the PMU global
>> controls unless their reserved bits match hardware.
>
> I think there are two other relevant (but pre-existing) problems here:
>
> 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.
https://lore.kernel.org/kvm/20260821222002.54907-1-zide.chen@xxxxxxxxx/T/#m90394fda6d71ed0dd539a579abfb0c1df1e044fe
> (I think the PMI may also be lost as LVTPC points at the mediated vPMU
> vector)
>
> 2. On AMD, bit 58 and 59 have a similar problem. HW accepts those bits
> but they are reserved for the guest, so the guest can set them if
> GLOBAL_STATUS_SET is passed through, but userspace cannot restore them.
Right. That seems orthogonal to this series and could be addressed with
follow-up fixes.