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 | |
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>
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 21 |
2 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d46e791de129..502fff123e29 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -362,8 +362,8 @@ struct kvm_vcpu_arch { | |||
362 | u64 *mce_banks; | 362 | u64 *mce_banks; |
363 | 363 | ||
364 | /* used for guest single stepping over the given code position */ | 364 | /* used for guest single stepping over the given code position */ |
365 | u16 singlestep_cs; | ||
366 | unsigned long singlestep_rip; | 365 | unsigned long singlestep_rip; |
366 | |||
367 | /* fields used by HYPER-V emulation */ | 367 | /* fields used by HYPER-V emulation */ |
368 | u64 hv_vapic; | 368 | u64 hv_vapic; |
369 | }; | 369 | }; |
@@ -820,4 +820,6 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | |||
820 | void kvm_define_shared_msr(unsigned index, u32 msr); | 820 | void kvm_define_shared_msr(unsigned index, u32 msr); |
821 | void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); | 821 | void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); |
822 | 822 | ||
823 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); | ||
824 | |||
823 | #endif /* _ASM_X86_KVM_HOST_H */ | 825 | #endif /* _ASM_X86_KVM_HOST_H */ |
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 | } |