mbox series

[v2,00/10] KVM: x86: Clean up MSR access/failure handling

Message ID 20240802181935.292540-1-seanjc@google.com (mailing list archive)
Headers show
Series KVM: x86: Clean up MSR access/failure handling | expand

Message

Sean Christopherson Aug. 2, 2024, 6:19 p.m. UTC
Rework KVM's MSR access handling, and more specific the handling of failures,
to begin the march towards removing host_initiated exemptions for CPUID
checks, e.g. to eventually turn code like this:

		if (!msr_info->host_initiated &&
		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
			return 1;

into

		if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
			return KVM_MSR_RET_UNSUPPORTED;

For all intents and purposes, KVM already requires setting guest CPUID before
setting MSRs, as there are multiple MSR flows that simply cannot work if CPUID
isn't in place.

But because KVM's ABI is that userspace is allowed to save/restore MSRs that
are advertised to usersepace regardless of the vCPU CPUID model, KVM has ended
up with code like the above where KVM unconditionally allows host accesses.

The idea here is to funnel all MSR accesses through a single helper so that
KVM can make the "host_initiated" exception in a single location based on
KVM_MSR_RET_UNSUPPORTED, i.e. so that KVM doesn't need one-off checks for every
MSR, which is especially problematic for CET where a Venn diagram is needed to
map CET MSR existence to CPUID feature bits.

This series doesn't actually remove the existing host_initiated checks.  I
*really* wanted to do that here, but removing all the existing checks is
non-trivial and has a high chance of subtly breaking userspace.  I still want
to eventually get there, but it needs to be a slower, more thoughtful process.

For now, the goal is to allow new features to omit the host_initiated checks
without creating a weird userspace ABI, e.g to simplify the aforementioned CET
support.

v2:
 - Rebase (really the only reason I posted v2).
 - Collect reviews. [Weijiang]

v1:
 - https://lore.kernel.org/all/20240425181422.3250947-1-seanjc@google.com

Sean Christopherson (10):
  KVM: SVM: Disallow guest from changing userspace's MSR_AMD64_DE_CFG
    value
  KVM: x86: Move MSR_TYPE_{R,W,RW} values from VMX to x86, as enums
  KVM: x86: Rename KVM_MSR_RET_INVALID to KVM_MSR_RET_UNSUPPORTED
  KVM: x86: Refactor kvm_x86_ops.get_msr_feature() to avoid
    kvm_msr_entry
  KVM: x86: Rename get_msr_feature() APIs to get_feature_msr()
  KVM: x86: Refactor kvm_get_feature_msr() to avoid struct kvm_msr_entry
  KVM: x86: Funnel all fancy MSR return value handling into a common
    helper
  KVM: x86: Hoist x86.c's global msr_* variables up above
    kvm_do_msr_access()
  KVM: x86: Suppress failures on userspace access to advertised,
    unsupported MSRs
  KVM: x86: Suppress userspace access failures on unsupported,
    "emulated" MSRs

 arch/x86/include/asm/kvm-x86-ops.h |   2 +-
 arch/x86/include/asm/kvm_host.h    |   2 +-
 arch/x86/kvm/svm/svm.c             |  29 +-
 arch/x86/kvm/vmx/main.c            |   2 +-
 arch/x86/kvm/vmx/vmx.c             |   8 +-
 arch/x86/kvm/vmx/vmx.h             |   4 -
 arch/x86/kvm/vmx/x86_ops.h         |   2 +-
 arch/x86/kvm/x86.c                 | 513 ++++++++++++++---------------
 arch/x86/kvm/x86.h                 |  21 +-
 9 files changed, 294 insertions(+), 289 deletions(-)


base-commit: 332d2c1d713e232e163386c35a3ba0c1b90df83f

Comments

Sean Christopherson Aug. 23, 2024, 11:47 p.m. UTC | #1
On Fri, 02 Aug 2024 11:19:25 -0700, Sean Christopherson wrote:
> Rework KVM's MSR access handling, and more specific the handling of failures,
> to begin the march towards removing host_initiated exemptions for CPUID
> checks, e.g. to eventually turn code like this:
> 
> 		if (!msr_info->host_initiated &&
> 		    !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
> 			return 1;
> 
> [...]

Applied to kvm-x86 misc, thanks!

[01/10] KVM: SVM: Disallow guest from changing userspace's MSR_AMD64_DE_CFG value
        https://github.com/kvm-x86/linux/commit/74a0e79df68a
[02/10] KVM: x86: Move MSR_TYPE_{R,W,RW} values from VMX to x86, as enums
        https://github.com/kvm-x86/linux/commit/b58b808cbe93
[03/10] KVM: x86: Rename KVM_MSR_RET_INVALID to KVM_MSR_RET_UNSUPPORTED
        https://github.com/kvm-x86/linux/commit/aaecae7b6a2b
[04/10] KVM: x86: Refactor kvm_x86_ops.get_msr_feature() to avoid kvm_msr_entry
        https://github.com/kvm-x86/linux/commit/74c6c98a598a
[05/10] KVM: x86: Rename get_msr_feature() APIs to get_feature_msr()
        https://github.com/kvm-x86/linux/commit/b848f24bd74a
[06/10] KVM: x86: Refactor kvm_get_feature_msr() to avoid struct kvm_msr_entry
        https://github.com/kvm-x86/linux/commit/7075f1636150
[07/10] KVM: x86: Funnel all fancy MSR return value handling into a common helper
        https://github.com/kvm-x86/linux/commit/1cec2034980a
[08/10] KVM: x86: Hoist x86.c's global msr_* variables up above kvm_do_msr_access()
        https://github.com/kvm-x86/linux/commit/3adef9034596
[09/10] KVM: x86: Suppress failures on userspace access to advertised, unsupported MSRs
        https://github.com/kvm-x86/linux/commit/64a5d7a1091f
[10/10] KVM: x86: Suppress userspace access failures on unsupported, "emulated" MSRs
        https://github.com/kvm-x86/linux/commit/44dd0f5732b4

--
https://github.com/kvm-x86/linux/tree/next