Commit 5c178481 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: x86/xen: Restrict hypercall MSR to unofficial synthetic range



Reject userspace attempts to set the Xen hypercall page MSR to an index
outside of the "standard" virtualization range [0x40000000, 0x4fffffff],
as KVM is not equipped to handle collisions with real MSRs, e.g. KVM
doesn't update MSR interception, conflicts with VMCS/VMCB fields, special
case writes in KVM, etc.

While the MSR index isn't strictly ABI, i.e. can theoretically float to
any value, in practice no known VMM sets the MSR index to anything other
than 0x40000000 or 0x40000200.

Cc: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: default avatarPaul Durrant <paul@xen.org>
Link: https://lore.kernel.org/r/20250215011437.1203084-2-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 3617c0ee
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,10 @@ blobs in userspace. When the guest writes the MSR, kvm copies one
page of a blob (32- or 64-bit, depending on the vcpu mode) to guest
memory.

The MSR index must be in the range [0x40000000, 0x4fffffff], i.e. must reside
in the range that is unofficially reserved for use by hypervisors.  The min/max
values are enumerated via KVM_XEN_MSR_MIN_INDEX and KVM_XEN_MSR_MAX_INDEX.

::

  struct kvm_xen_hvm_config {
+3 −0
Original line number Diff line number Diff line
@@ -559,6 +559,9 @@ struct kvm_x86_mce {
#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE	(1 << 7)
#define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA	(1 << 8)

#define KVM_XEN_MSR_MIN_INDEX			0x40000000u
#define KVM_XEN_MSR_MAX_INDEX			0x4fffffffu

struct kvm_xen_hvm_config {
	__u32 flags;
	__u32 msr;
+9 −0
Original line number Diff line number Diff line
@@ -1324,6 +1324,15 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc)
	     xhc->blob_size_32 || xhc->blob_size_64))
		return -EINVAL;

	/*
	 * Restrict the MSR to the range that is unofficially reserved for
	 * synthetic, virtualization-defined MSRs, e.g. to prevent confusing
	 * KVM by colliding with a real MSR that requires special handling.
	 */
	if (xhc->msr &&
	    (xhc->msr < KVM_XEN_MSR_MIN_INDEX || xhc->msr > KVM_XEN_MSR_MAX_INDEX))
		return -EINVAL;

	mutex_lock(&kvm->arch.xen.xen_lock);

	if (xhc->msr && !kvm->arch.xen_hvm_config.msr)