aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/x86.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 89313187d7f7..05afd1ac5563 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4971,6 +4971,41 @@ static int kvm_vcpu_check_hw_bp(unsigned long addr, u32 type, u32 dr7,
4971 return dr6; 4971 return dr6;
4972} 4972}
4973 4973
4974static void kvm_vcpu_check_singlestep(struct kvm_vcpu *vcpu, int *r)
4975{
4976 struct kvm_run *kvm_run = vcpu->run;
4977
4978 /*
4979 * Use the "raw" value to see if TF was passed to the processor.
4980 * Note that the new value of the flags has not been saved yet.
4981 *
4982 * This is correct even for TF set by the guest, because "the
4983 * processor will not generate this exception after the instruction
4984 * that sets the TF flag".
4985 */
4986 unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
4987
4988 if (unlikely(rflags & X86_EFLAGS_TF)) {
4989 if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
4990 kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1;
4991 kvm_run->debug.arch.pc = vcpu->arch.singlestep_rip;
4992 kvm_run->debug.arch.exception = DB_VECTOR;
4993 kvm_run->exit_reason = KVM_EXIT_DEBUG;
4994 *r = EMULATE_USER_EXIT;
4995 } else {
4996 vcpu->arch.emulate_ctxt.eflags &= ~X86_EFLAGS_TF;
4997 /*
4998 * "Certain debug exceptions may clear bit 0-3. The
4999 * remaining contents of the DR6 register are never
5000 * cleared by the processor".
5001 */
5002 vcpu->arch.dr6 &= ~15;
5003 vcpu->arch.dr6 |= DR6_BS;
5004 kvm_queue_exception(vcpu, DB_VECTOR);
5005 }
5006 }
5007}
5008
4974static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) 5009static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r)
4975{ 5010{
4976 struct kvm_run *kvm_run = vcpu->run; 5011 struct kvm_run *kvm_run = vcpu->run;
@@ -5117,10 +5152,12 @@ restart:
5117 5152
5118 if (writeback) { 5153 if (writeback) {
5119 toggle_interruptibility(vcpu, ctxt->interruptibility); 5154 toggle_interruptibility(vcpu, ctxt->interruptibility);
5120 kvm_set_rflags(vcpu, ctxt->eflags);
5121 kvm_make_request(KVM_REQ_EVENT, vcpu); 5155 kvm_make_request(KVM_REQ_EVENT, vcpu);
5122 vcpu->arch.emulate_regs_need_sync_to_vcpu = false; 5156 vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
5123 kvm_rip_write(vcpu, ctxt->eip); 5157 kvm_rip_write(vcpu, ctxt->eip);
5158 if (r == EMULATE_DONE)
5159 kvm_vcpu_check_singlestep(vcpu, &r);
5160 kvm_set_rflags(vcpu, ctxt->eflags);
5124 } else 5161 } else
5125 vcpu->arch.emulate_regs_need_sync_to_vcpu = true; 5162 vcpu->arch.emulate_regs_need_sync_to_vcpu = true;
5126 5163