Skip to content

Commit 64a5d7a

Browse files
committed
KVM: x86: Suppress failures on userspace access to advertised, unsupported MSRs
Extend KVM's suppression of failures due to a userspace access to an unsupported, but advertised as a "to save" MSR to all MSRs, not just those that happen to reach the default case statements in kvm_get_msr_common() and kvm_set_msr_common(). KVM's soon-to-be-established ABI is that if an MSR is advertised to userspace, then userspace is allowed to read the MSR, and write back the value that was read, i.e. why an MSR is unsupported doesn't change KVM's ABI. Practically speaking, this is very nearly a nop, as the only other paths that return KVM_MSR_RET_UNSUPPORTED are {svm,vmx}_get_feature_msr(), and it's unlikely, though not impossible, that userspace is using KVM_GET_MSRS on unsupported MSRs. The primary goal of moving the suppression to common code is to allow returning KVM_MSR_RET_UNSUPPORTED as appropriate throughout KVM, without having to manually handle the "is userspace accessing an advertised" waiver. I.e. this will allow formalizing KVM's ABI without incurring a high maintenance cost. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 3adef90 commit 64a5d7a

File tree

1 file changed

+9
-18
lines changed

1 file changed

+9
-18
lines changed

arch/x86/kvm/x86.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,15 @@ static __always_inline int kvm_do_msr_access(struct kvm_vcpu *vcpu, u32 msr,
512512
if (ret != KVM_MSR_RET_UNSUPPORTED)
513513
return ret;
514514

515+
/*
516+
* Userspace is allowed to read MSRs, and write '0' to MSRs, that KVM
517+
* reports as to-be-saved, even if an MSR isn't fully supported.
518+
* Simply check that @data is '0', which covers both the write '0' case
519+
* and all reads (in which case @data is zeroed on failure; see above).
520+
*/
521+
if (host_initiated && !*data && kvm_is_msr_to_save(msr))
522+
return 0;
523+
515524
if (!ignore_msrs) {
516525
kvm_debug_ratelimited("unhandled %s: 0x%x data 0x%llx\n",
517526
op, msr, *data);
@@ -4137,14 +4146,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
41374146
if (kvm_pmu_is_valid_msr(vcpu, msr))
41384147
return kvm_pmu_set_msr(vcpu, msr_info);
41394148

4140-
/*
4141-
* Userspace is allowed to write '0' to MSRs that KVM reports
4142-
* as to-be-saved, even if an MSRs isn't fully supported.
4143-
*/
4144-
if (msr_info->host_initiated && !data &&
4145-
kvm_is_msr_to_save(msr))
4146-
break;
4147-
41484149
return KVM_MSR_RET_UNSUPPORTED;
41494150
}
41504151
return 0;
@@ -4496,16 +4497,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
44964497
if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
44974498
return kvm_pmu_get_msr(vcpu, msr_info);
44984499

4499-
/*
4500-
* Userspace is allowed to read MSRs that KVM reports as
4501-
* to-be-saved, even if an MSR isn't fully supported.
4502-
*/
4503-
if (msr_info->host_initiated &&
4504-
kvm_is_msr_to_save(msr_info->index)) {
4505-
msr_info->data = 0;
4506-
break;
4507-
}
4508-
45094500
return KVM_MSR_RET_UNSUPPORTED;
45104501
}
45114502
return 0;

0 commit comments

Comments
 (0)