Re: [PATCH v8 6/8] KVM: x86: VMX: Prevent MSR passthrough when MSR access is denied

From: Sean Christopherson
Date: Mon Oct 05 2020 - 15:41:14 EST


On Thu, Oct 01, 2020 at 09:11:39PM -0400, Peter Xu wrote:
> Hi,
>
> I reported in the v13 cover letter of kvm dirty ring series that this patch
> seems to have been broken. Today I tried to reproduce with a simplest vm, and
> after a closer look...
>
> On Fri, Sep 25, 2020 at 04:34:20PM +0200, Alexander Graf wrote:
> > @@ -3764,15 +3859,14 @@ static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu)
> > return mode;
> > }
> >
> > -static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu,
> > - unsigned long *msr_bitmap, u8 mode)
> > +static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode)
> > {
> > int msr;
> >
> > - for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
> > - unsigned word = msr / BITS_PER_LONG;
> > - msr_bitmap[word] = (mode & MSR_BITMAP_MODE_X2APIC_APICV) ? 0 : ~0;
> > - msr_bitmap[word + (0x800 / sizeof(long))] = ~0;
> > + for (msr = 0x800; msr <= 0x8ff; msr++) {
> > + bool intercepted = !!(mode & MSR_BITMAP_MODE_X2APIC_APICV);
> > +
> > + vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_RW, intercepted);

Yeah, this is busted.

> > }
> >
> > if (mode & MSR_BITMAP_MODE_X2APIC) {
>
> ... I think we may want below change to be squashed:
>
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index d160aad59697..7d3f2815b04d 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -3781,9 +3781,10 @@ static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode)
> int msr;
>
> for (msr = 0x800; msr <= 0x8ff; msr++) {
> - bool intercepted = !!(mode & MSR_BITMAP_MODE_X2APIC_APICV);
> + bool apicv = mode & MSR_BITMAP_MODE_X2APIC_APICV;
>
> - vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_RW, intercepted);
> + vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_R, !apicv);
> + vmx_set_intercept_for_msr(vcpu, msr, MSR_TYPE_W, true);

I would prefer a full revert of sorts. Allowing userspace to intercept reads
to x2APIC MSRs when APICV is fully enabled for the guest simply can't work.
The LAPIC and thus virtual APIC is in-kernel and cannot be directly accessed
by userspace. I doubt it actually affects real world performance, but
resetting each MSR one-by-one bugs me.

Intercepting writes to TPR, EOI and SELF_IPI are somewhat plausible, but I
just don't see how intercepting reads when APICV is active is a sane setup.

I'll send a patch and we can go from there.

> }
>
> if (mode & MSR_BITMAP_MODE_X2APIC) {
>
> This fixes my problem the same as having this patch reverted.
>
> --
> Peter Xu
>