From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>, Joerg Roedel <joro@8bytes.org>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Nadav Amit <nadav.amit@gmail.com>,
Andy Lutomirski <luto@kernel.org>
Subject: Re: [PATCH] KVM: x86: Don't update RIP or do single-step on faulting emulation
Date: Tue, 27 Aug 2019 20:35:49 +0200 [thread overview]
Message-ID: <20190827183549.GC65641@flask> (raw)
In-Reply-To: <20190823205544.24052-1-sean.j.christopherson@intel.com>
2019-08-23 13:55-0700, Sean Christopherson:
> Don't advance RIP or inject a single-step #DB if emulation signals a
> fault. This logic applies to all state updates that are conditional on
> clean retirement of the emulation instruction, e.g. updating RFLAGS was
> previously handled by commit 38827dbd3fb85 ("KVM: x86: Do not update
> EFLAGS on faulting emulation").
>
> Not advancing RIP is likely a nop, i.e. ctxt->eip isn't updated with
> ctxt->_eip until emulation "retires" anyways. Skipping #DB injection
> fixes a bug reported by Andy Lutomirski where a #UD on SYSCALL due to
> invalid state with RFLAGS.RF=1 would loop indefinitely due to emulation
> overwriting the #UD with #DB and thus restarting the bad SYSCALL over
> and over.
>
> Cc: Nadav Amit <nadav.amit@gmail.com>
> Cc: stable@vger.kernel.org
> Reported-by: Andy Lutomirski <luto@kernel.org>
> Fixes: 663f4c61b803 ("KVM: x86: handle singlestep during emulation")
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> ---
>
> Note, this has minor conflict with my recent series to cleanup the
> emulator return flows[*]. The end result should look something like:
>
> if (!ctxt->have_exception ||
> exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
> kvm_rip_write(vcpu, ctxt->eip);
> if (r && ctxt->tf)
> r = kvm_vcpu_do_singlestep(vcpu);
> __kvm_set_rflags(vcpu, ctxt->eflags);
> }
>
> [*] https://lkml.kernel.org/r/20190823010709.24879-1-sean.j.christopherson@intel.com
>
> arch/x86/kvm/x86.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index b4cfd786d0b6..d2962671c3d3 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6611,12 +6611,13 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
> unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
> toggle_interruptibility(vcpu, ctxt->interruptibility);
> vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
> - kvm_rip_write(vcpu, ctxt->eip);
> - if (r == EMULATE_DONE && ctxt->tf)
> - kvm_vcpu_do_singlestep(vcpu, &r);
> if (!ctxt->have_exception ||
> - exception_type(ctxt->exception.vector) == EXCPT_TRAP)
> + exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
Hm, EXCPT_TRAP is either #OF, #BP, or another #DB, none of which we want
to override. The first two disable TF and the last one is the same as
its fault variant must take other path, so it works out in the end...
I've fixed the RF in commit message when applying, thanks.
---
We still seem to have at least a minor problem with single stepping:
SDM, Interrupt 1—Debug Exception (#DB):
The following items detail the treatment of debug exceptions on the
instruction boundary following execution of the MOV or the POP
instruction that loads the SS register:
• If EFLAGS.TF is 1, no single-step trap is generated.
I think a check for KVM_X86_SHADOW_INT_MOV_SS in
kvm_vcpu_do_singlestep() is missing.
next prev parent reply other threads:[~2019-08-27 18:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-23 20:55 [PATCH] KVM: x86: Don't update RIP or do single-step on faulting emulation Sean Christopherson
2019-08-23 21:42 ` Nadav Amit
2019-08-23 22:46 ` Andy Lutomirski
2019-08-26 14:06 ` Sean Christopherson
2019-08-27 18:35 ` Radim Krčmář [this message]
2019-08-27 19:12 ` Jim Mattson
2019-08-27 19:49 ` 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=20190827183549.GC65641@flask \
--to=rkrcmar@redhat.com \
--cc=jmattson@google.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=nadav.amit@gmail.com \
--cc=pbonzini@redhat.com \
--cc=sean.j.christopherson@intel.com \
--cc=vkuznets@redhat.com \
--cc=wanpengli@tencent.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