diff options
-rw-r--r-- | arch/x86/kvm/x86.c | 39 |
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 | ||
4974 | static 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 | |||
4974 | static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r) | 5009 | static 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 | ||