kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>, Paul Durrant <paul@xen.org>,
	kvm@vger.kernel.org,  linux-kernel@vger.kernel.org,
	 syzbot+cdeaeec70992eca2d920@syzkaller.appspotmail.com,
	 Joao Martins <joao.m.martins@oracle.com>
Subject: Re: [PATCH 1/5] KVM: x86/xen: Restrict hypercall MSR to unofficial synthetic range
Date: Wed, 5 Feb 2025 07:06:58 -0800	[thread overview]
Message-ID: <Z6N-kn1-p6nIWHeP@google.com> (raw)
In-Reply-To: <43f702b383fb99d435f2cdb8ef35cc1449fe6c23.camel@infradead.org>

On Wed, Feb 05, 2025, David Woodhouse wrote:
> On Fri, 2025-01-31 at 17:13 -0800, Sean Christopherson wrote:
> > --- a/arch/x86/kvm/xen.c
> > +++ b/arch/x86/kvm/xen.c
> > @@ -1324,6 +1324,14 @@ 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 < 0x40000000 || xhc->msr > 0x4fffffff))
> > +		return -EINVAL;
> > +
> >  	mutex_lock(&kvm->arch.xen.xen_lock);
> >  
> >  	if (xhc->msr && !kvm->arch.xen_hvm_config.msr)
> 
> I'd prefer to see #defines for those magic values.

Can do.  Hmm, and since this would be visible to userspace, arguably the #defines
should go in arch/x86/include/uapi/asm/kvm.h

> Especially as there is a corresponding requirement that they never be set
> from host context (which is where the potential locking issues come in).
> Which train of thought leads me to ponder this as an alternative (or
> additional) solution:
> 
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3733,7 +3733,13 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>         u32 msr = msr_info->index;
>         u64 data = msr_info->data;
>  
> -       if (msr && msr == vcpu->kvm->arch.xen_hvm_config.msr)
> +       /*
> +        * Do not allow host-initiated writes to trigger the Xen hypercall
> +        * page setup; it could incur locking paths which are not expected
> +        * if userspace sets the MSR in an unusual location.

That's just as likely to break userspace.  Doing a save/restore on the MSR doesn't
make a whole lot of sense since it's effectively a "command" MSR, but IMO it's not
any less likely than userspace putting the MSR index outside of the synthetic range.

Side topic, upstream QEMU doesn't even appear to put the MSR at the Hyper-V
address.  It tells the guest that's where the MSR is located, but the config
passed to KVM still uses the default.

        /* Hypercall MSR base address */
        if (hyperv_enabled(cpu)) {
            c->ebx = XEN_HYPERCALL_MSR_HYPERV;
            kvm_xen_init(cs->kvm_state, c->ebx);
        } else {
            c->ebx = XEN_HYPERCALL_MSR;
        }

...

        /* hyperv_enabled() doesn't work yet. */
        uint32_t msr = XEN_HYPERCALL_MSR;
        ret = kvm_xen_init(s, msr);
        if (ret < 0) {
            return ret;
        }

Userspace breakage aside, disallowng host writes would fix the immediate issue,
and I think would mitigate all concerns with putting the host at risk.  But it's
not enough to actually make an overlapping MSR index work.  E.g. if the MSR is
passed through to the guest, the write will go through to the hardware MSR, unless
the WRMSR happens to be emulated.

I really don't want to broadly support redirecting any MSR, because to truly go
down that path we'd need to deal with x2APIC, EFER, and other MSRs that have
special treatment and meaning.

While KVM's stance is usually that a misconfigured vCPU model is userspace's
problem, in this case I don't see any value in letting userspace be stupid.  It
can't work generally, it creates unique ABI for KVM_SET_MSRS, and unless there's
a crazy use case I'm overlooking, there's no sane reason for userspace to put the
index in outside of the synthetic range (whereas defining seemingly nonsensical
CPUID feature bits is useful for testing purposes, implementing support in
userspace, etc).

  reply	other threads:[~2025-02-05 15:07 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-01  1:13 [PATCH 0/5] KVM: x86/xen: Restrict hypercall MSR index Sean Christopherson
2025-02-01  1:13 ` [PATCH 1/5] KVM: x86/xen: Restrict hypercall MSR to unofficial synthetic range Sean Christopherson
2025-02-03  9:09   ` Paul Durrant
2025-02-05  9:27   ` David Woodhouse
2025-02-05 15:06     ` Sean Christopherson [this message]
2025-02-05 15:26       ` David Woodhouse
2025-02-05 15:51         ` Sean Christopherson
2025-02-05 16:18           ` David Woodhouse
2025-02-05 17:15             ` David Woodhouse
2025-02-05 19:20               ` Sean Christopherson
2025-02-06 18:58                 ` David Woodhouse
2025-02-07 17:18                   ` Sean Christopherson
2025-02-06  9:18           ` David Woodhouse
2025-02-06 16:51   ` David Woodhouse
2025-02-01  1:13 ` [PATCH 2/5] KVM: x86/xen: Add an #ifdef'd helper to detect writes to Xen MSR Sean Christopherson
2025-02-03  9:09   ` Paul Durrant
2025-02-06 16:28   ` David Woodhouse
2025-02-01  1:13 ` [PATCH 3/5] KVM: x86/xen: Consult kvm_xen_enabled when checking for Xen MSR writes Sean Christopherson
2025-02-03  9:15   ` Paul Durrant
2025-02-06 16:29   ` David Woodhouse
2025-02-01  1:13 ` [PATCH 4/5] KVM: x86/xen: Bury xen_hvm_config behind CONFIG_KVM_XEN=y Sean Christopherson
2025-02-03  9:19   ` Paul Durrant
2025-02-06 16:30   ` David Woodhouse
2025-02-01  1:14 ` [PATCH 5/5] KVM: x86/xen: Move kvm_xen_hvm_config field into kvm_xen Sean Christopherson
2025-02-03  9:21   ` Paul Durrant
2025-02-06 16:32   ` David Woodhouse
2025-02-06 19:14 ` [PATCH] KVM: x86/xen: Only write Xen hypercall page for guest writes to MSR David Woodhouse
2025-02-15  0:50   ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Z6N-kn1-p6nIWHeP@google.com \
    --to=seanjc@google.com \
    --cc=dwmw2@infradead.org \
    --cc=joao.m.martins@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paul@xen.org \
    --cc=pbonzini@redhat.com \
    --cc=syzbot+cdeaeec70992eca2d920@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).