From: Jan Kiszka <jan.kiszka@siemens.com>
To: Avi Kivity <avi@redhat.com>
Cc: kvm@vger.kernel.org, "Yang, Sheng" <sheng.yang@intel.com>
Subject: [PATCH] KVM: VMX: Allow single-stepping when interruptible
Date: Thu, 11 Dec 2008 20:15:41 +0100 [thread overview]
Message-ID: <494166DD.1050105@siemens.com> (raw)
In-Reply-To: <493B9FD2.4080304@redhat.com>
Avi Kivity wrote:
> Jan Kiszka wrote:
>> When single-stepping, we have to ensure that the INT1 can make it
>> through even if the guest itself is uninterruptible due to MOV SS or
>> STI. VMENTRY will fail otherwise.
>>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>
>> arch/x86/kvm/vmx.c | 10 ++++++++--
>> 1 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 3a422dc..8e83102 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -1010,6 +1010,7 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu,
>> enum kvm_reg reg)
>> static int set_guest_debug(struct kvm_vcpu *vcpu, struct
>> kvm_guest_debug *dbg)
>> {
>> int old_debug = vcpu->guest_debug;
>> + u32 interruptibility;
>> unsigned long flags;
>>
>> vcpu->guest_debug = dbg->control;
>> @@ -1017,9 +1018,14 @@ static int set_guest_debug(struct kvm_vcpu
>> *vcpu, struct kvm_guest_debug *dbg)
>> vcpu->guest_debug = 0;
>>
>> flags = vmcs_readl(GUEST_RFLAGS);
>> - if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
>> + if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
>> flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
>> - else if (old_debug & KVM_GUESTDBG_SINGLESTEP)
>> + /* We must be interruptible when single-stepping */
>> + interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
>> + if (interruptibility & 3)
>> + vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
>> + interruptibility & ~3);
>>
>
> Could just write unconditionally - it's not like the write has any
> effect on speed. vmcs_clear_bits() will do it cleanly.
>
> But I'm worried about correctness. Suppose we're singlestepping a sti;
> hlt sequence. While we'll clear interruptibility, probably receive the
> debug trap (since that's a high priority exception), but then inject the
> interrupt before the hlt, hanging the guest. So we probably need to
> restore interruptibility on exit.
>
There was some issue with the original patch, but I think I have a safe
version now that also works as good as the old one. Please see below,
including comments. I'm still open to further concerns or better
approaches. Sheng, maybe you can provide some more details on how one is
supposed to handle this hairy case with VMX.
> This looks like a good candidate for a test case.
>
This will be more complicated as I'm currently able to handle: kvmctl
would have to be extended to interact with the guest debug interface of
kvm, setting appropriate breakpoints and handling the callbacks.
Jan
----------->
When single-stepping over STI and MOV SS, we must clear the
corresponding interruptibility bits in the guest state. Otherwise
vmentry fails as it then expects bit 14 (BS) in pending debug exceptions
being set, but that's not correct for the guest debugging case.
Note that clearing those bits is safe as we check for interruptibility
based on the original state and do not inject interrupts or NMIs if
guest interruptibility was blocked.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
arch/x86/kvm/vmx.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ec37635..26f732c 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2477,6 +2477,11 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
{
vmx_update_window_states(vcpu);
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_STI |
+ GUEST_INTR_STATE_MOV_SS);
+
if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
if (vcpu->arch.interrupt.pending) {
enable_nmi_window(vcpu);
@@ -3263,6 +3268,11 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
vmx_update_window_states(vcpu);
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_STI |
+ GUEST_INTR_STATE_MOV_SS);
+
if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
if (vcpu->arch.interrupt.pending) {
enable_nmi_window(vcpu);
prev parent reply other threads:[~2008-12-11 19:17 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-27 11:43 [PATCH 0/5] KVM: Improved guest debugging / debug register emulation Jan Kiszka
2008-11-27 11:43 ` [PATCH 5/5] KVM: x86: Wire-up hardware breakpoints for guest debugging Jan Kiszka
2008-11-27 11:43 ` [PATCH 4/5] KVM: x86: Virtualize debug registers Jan Kiszka
2008-11-27 11:43 ` [PATCH 2/5] KVM: New guest debug interface Jan Kiszka
2008-12-07 9:55 ` Avi Kivity
2008-12-08 9:13 ` Jan Kiszka
2008-12-08 9:34 ` Avi Kivity
2008-12-08 9:42 ` Jan Kiszka
2008-12-08 13:47 ` Jan Kiszka
2008-12-08 14:57 ` Avi Kivity
2008-12-08 15:17 ` Jan Kiszka
2008-12-10 8:48 ` Avi Kivity
2008-11-27 11:43 ` [PATCH 1/5] VMX: Support for injecting software exceptions Jan Kiszka
2008-11-27 11:43 ` [PATCH 3/5] KVM: VMX: Ensure interruptibility when single-stepping Jan Kiszka
2008-12-07 10:05 ` Avi Kivity
2008-12-08 9:17 ` Jan Kiszka
2008-12-11 19:15 ` Jan Kiszka [this message]
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=494166DD.1050105@siemens.com \
--to=jan.kiszka@siemens.com \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=sheng.yang@intel.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).