@@ -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);
}