KVM: VMX: Allow single-stepping when uninterruptible
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 15 Dec 2008 12:52:10 +0000 (13:52 +0100)
committerAvi Kivity <avi@redhat.com>
Tue, 24 Mar 2009 09:02:49 +0000 (11:02 +0200)
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>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/vmx.c

index f55690ddb3acf31b5cdd15072ec3e7f5e75fd0a5..c776868ffe41feb1c86a75bd74918bf06bf9347c 100644 (file)
@@ -2478,6 +2478,11 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
 {
        vmx_update_window_states(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);
        if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
                if (vcpu->arch.interrupt.pending) {
                        enable_nmi_window(vcpu);
@@ -3244,6 +3249,11 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
 
        vmx_update_window_states(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);
        if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
                if (vcpu->arch.interrupt.pending) {
                        enable_nmi_window(vcpu);