Re: [PATCH] kvm: nVMX: flush TLB when decoded insn != VM-exit reason

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Aug 13, 2020 at 03:44:08PM -0500, Oliver Upton wrote:
> On Thu, Aug 13, 2020 at 12:03 PM Sean Christopherson
> > > +      *
> > > +      * Rather than synthesizing a VM-exit into L1 for every possible
> > > +      * instruction just flush the TLB, resume L2, and let hardware generate
> > > +      * the appropriate VM-exit.
> > > +      */
> > > +     vmx_flush_tlb_gva(vcpu, kvm_rip_read(vcpu));
> >
> > This is wrong, it should flush kvm_get_linear_rip(vcpu).
> >
> 
> I do not believe that the aim of this patch will work anymore, since:
> 
> 1dbf5d68af6f ("KVM: VMX: Add guest physical address check in EPT
> violation and misconfig")
> 
> Since it is possible to get into the emulator on any instruction that
> induces an EPT violation, we'd wind up looping when we believe the
> instruction needs to exit to L1 (TLB flush, resume guest, hit the same
> EPT violation. Rinse, wash, repeat).

kvm_get_linear_rip() doesn't walk any page tables, it simply accounts for a
non-zero CS.base when !64-bit mode.  If we really wanted to, this could use
the emulation context's cached _eip, but I don't see any value in that since
both GUEST_CS_* and GUEST_RIP will already be cached by KVM.

unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu)
{
        if (is_64_bit_mode(vcpu))
                return kvm_rip_read(vcpu);
        return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) +
                     kvm_rip_read(vcpu));
}



> 
> > > +     return X86EMUL_RETRY_INSTR;
> > >  }
> > >
> > >  #ifdef CONFIG_X86_64
> > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > > index 00c88c2f34e4..2ab47485100f 100644
> > > --- a/arch/x86/kvm/x86.c
> > > +++ b/arch/x86/kvm/x86.c
> > > @@ -6967,7 +6967,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
> > >
> > >       r = x86_emulate_insn(ctxt);
> > >
> > > -     if (r == EMULATION_INTERCEPTED)
> > > +     if (r == EMULATION_INTERCEPTED || r == EMULATION_RETRY_INSTR)
> > >               return 1;
> > >
> > >       if (r == EMULATION_FAILED) {
> > > --
> > > 2.27.0.290.gba653c62da-goog
> > >



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux