diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2010-02-23 11:47:55 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-04-25 06:00:40 -0400 |
commit | f92653eeb496fe8624ac4b0d628c916a06a3d25c (patch) | |
tree | 114da40a81c70bc10efca3b633be98b7d4d70c73 /arch/x86/kvm/x86.c | |
parent | 116a4752c82f767a59c27b2630a8474b936a776a (diff) |
KVM: x86: Add kvm_is_linear_rip
Based on Gleb's suggestion: Add a helper kvm_is_linear_rip that matches
a given linear RIP against the current one. Use this for guest
single-stepping, more users will follow.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index efeeabd84ecd..f2f246ae4a4c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -5376,11 +5376,9 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
5376 | vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); | 5376 | vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); |
5377 | } | 5377 | } |
5378 | 5378 | ||
5379 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | 5379 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |
5380 | vcpu->arch.singlestep_cs = | 5380 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) + |
5381 | get_segment_selector(vcpu, VCPU_SREG_CS); | 5381 | get_segment_base(vcpu, VCPU_SREG_CS); |
5382 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu); | ||
5383 | } | ||
5384 | 5382 | ||
5385 | /* | 5383 | /* |
5386 | * Trigger an rflags update that will inject or remove the trace | 5384 | * Trigger an rflags update that will inject or remove the trace |
@@ -5871,6 +5869,15 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
5871 | return kvm_x86_ops->interrupt_allowed(vcpu); | 5869 | return kvm_x86_ops->interrupt_allowed(vcpu); |
5872 | } | 5870 | } |
5873 | 5871 | ||
5872 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) | ||
5873 | { | ||
5874 | unsigned long current_rip = kvm_rip_read(vcpu) + | ||
5875 | get_segment_base(vcpu, VCPU_SREG_CS); | ||
5876 | |||
5877 | return current_rip == linear_rip; | ||
5878 | } | ||
5879 | EXPORT_SYMBOL_GPL(kvm_is_linear_rip); | ||
5880 | |||
5874 | unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) | 5881 | unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) |
5875 | { | 5882 | { |
5876 | unsigned long rflags; | 5883 | unsigned long rflags; |
@@ -5885,9 +5892,7 @@ EXPORT_SYMBOL_GPL(kvm_get_rflags); | |||
5885 | void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 5892 | void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
5886 | { | 5893 | { |
5887 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && | 5894 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && |
5888 | vcpu->arch.singlestep_cs == | 5895 | kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip)) |
5889 | get_segment_selector(vcpu, VCPU_SREG_CS) && | ||
5890 | vcpu->arch.singlestep_rip == kvm_rip_read(vcpu)) | ||
5891 | rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; | 5896 | rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; |
5892 | kvm_x86_ops->set_rflags(vcpu, rflags); | 5897 | kvm_x86_ops->set_rflags(vcpu, rflags); |
5893 | } | 5898 | } |