diff mbox

[2/2] KVM: SVM: Make stepping out of NMI handlers more robust

Message ID 20100217134916.GA14767@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gleb Natapov Feb. 17, 2010, 1:49 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 52f78dd..b85b200 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -109,6 +109,7 @@  struct vcpu_svm {
 	struct nested_state nested;
 
 	bool nmi_singlestep;
+	bool nmi_singlestep_tf;
 };
 
 /* enable NPT for AMD64 and X86 with PAE */
@@ -1221,9 +1222,14 @@  static int db_interception(struct vcpu_svm *svm)
 
 	if (svm->nmi_singlestep) {
 		svm->nmi_singlestep = false;
-		if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
+		if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
 			svm->vmcb->save.rflags &=
 				~(X86_EFLAGS_TF | X86_EFLAGS_RF);
+			if (svm->nmi_singlestep_tf) {
+				svm->vmcb->save.rflags |= X86_EFLAGS_TF;
+				kvm_queue_exception(&svm->vcpu, DB_VECTOR);
+			}
+		}
 		update_db_intercept(&svm->vcpu);
 	}
 
@@ -2586,6 +2592,7 @@  static void enable_nmi_window(struct kvm_vcpu *vcpu)
 	   possible problem (IRET or exception injection or interrupt
 	   shadow) */
 	svm->nmi_singlestep = true;
+	svm->nmi_singlestep_tf = (svm->vmcb->save.rflags | X86_EFLAGS_TF);
 	svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 	update_db_intercept(vcpu);
 }