Skip to content

Commit 2de154f

Browse files
committed
KVM: x86/pmu: Provide "error" semantics for unsupported-but-known PMU MSRs
Provide "error" semantics (read zeros, drop writes) for userspace accesses to MSRs that are ultimately unsupported for whatever reason, but for which KVM told userspace to save and restore the MSR, i.e. for MSRs that KVM included in KVM_GET_MSR_INDEX_LIST. Previously, KVM special cased a few PMU MSRs that were problematic at one point or another. Extend the treatment to all PMU MSRs, e.g. to avoid spurious unsupported accesses. Note, the logic can also be used for non-PMU MSRs, but as of today only PMU MSRs can end up being unsupported after KVM told userspace to save and restore them. Link: https://lore.kernel.org/r/20230124234905.3774678-7-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent e33b6d7 commit 2de154f

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

arch/x86/kvm/x86.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3561,6 +3561,18 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
35613561
mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa));
35623562
}
35633563

3564+
static bool kvm_is_msr_to_save(u32 msr_index)
3565+
{
3566+
unsigned int i;
3567+
3568+
for (i = 0; i < num_msrs_to_save; i++) {
3569+
if (msrs_to_save[i] == msr_index)
3570+
return true;
3571+
}
3572+
3573+
return false;
3574+
}
3575+
35643576
int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
35653577
{
35663578
u32 msr = msr_info->index;
@@ -3876,20 +3888,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
38763888
vcpu->arch.guest_fpu.xfd_err = data;
38773889
break;
38783890
#endif
3879-
case MSR_IA32_PEBS_ENABLE:
3880-
case MSR_IA32_DS_AREA:
3881-
case MSR_PEBS_DATA_CFG:
3882-
case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
3891+
default:
38833892
if (kvm_pmu_is_valid_msr(vcpu, msr))
38843893
return kvm_pmu_set_msr(vcpu, msr_info);
3894+
38853895
/*
38863896
* Userspace is allowed to write '0' to MSRs that KVM reports
38873897
* as to-be-saved, even if an MSRs isn't fully supported.
38883898
*/
3889-
return !msr_info->host_initiated || data;
3890-
default:
3891-
if (kvm_pmu_is_valid_msr(vcpu, msr))
3892-
return kvm_pmu_set_msr(vcpu, msr_info);
3899+
if (msr_info->host_initiated && !data &&
3900+
kvm_is_msr_to_save(msr))
3901+
break;
3902+
38933903
return KVM_MSR_RET_INVALID;
38943904
}
38953905
return 0;
@@ -3979,20 +3989,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
39793989
case MSR_DRAM_ENERGY_STATUS: /* DRAM controller */
39803990
msr_info->data = 0;
39813991
break;
3982-
case MSR_IA32_PEBS_ENABLE:
3983-
case MSR_IA32_DS_AREA:
3984-
case MSR_PEBS_DATA_CFG:
3985-
case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
3986-
if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
3987-
return kvm_pmu_get_msr(vcpu, msr_info);
3988-
/*
3989-
* Userspace is allowed to read MSRs that KVM reports as
3990-
* to-be-saved, even if an MSR isn't fully supported.
3991-
*/
3992-
if (!msr_info->host_initiated)
3993-
return 1;
3994-
msr_info->data = 0;
3995-
break;
39963992
case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3:
39973993
case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3:
39983994
case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR1:
@@ -4248,6 +4244,17 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
42484244
default:
42494245
if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
42504246
return kvm_pmu_get_msr(vcpu, msr_info);
4247+
4248+
/*
4249+
* Userspace is allowed to read MSRs that KVM reports as
4250+
* to-be-saved, even if an MSR isn't fully supported.
4251+
*/
4252+
if (msr_info->host_initiated &&
4253+
kvm_is_msr_to_save(msr_info->index)) {
4254+
msr_info->data = 0;
4255+
break;
4256+
}
4257+
42514258
return KVM_MSR_RET_INVALID;
42524259
}
42534260
return 0;

0 commit comments

Comments
 (0)