KVM: x86: Refactor guest debug IOCTL handling
PATCH 1/2 KVM: x86: Refactor guest debug IOCTL handling
Much of so far vendor-specific code for setting up guest debug can actually be handled by the generic code. This also fixes a minor deficit in the SVM part /wrt processing KVM_GUESTDBG_ENABLE.
Signed-off-by Jan Kiszka <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 4 ++-- arch/x86/kvm/svm.c | 14 ++------------ arch/x86/kvm/vmx.c | 18 +----------------- arch/x86/kvm/x86.c | 28 +++++++++++++++++++++------- 4 files changed, 26 insertions(+), 38 deletions(-)
arch/x86/include/asm/kvm_host.h +2 -2
@@ -475,8 +475,8 @@ struct kvm_x86_ops {void (*vcpu_load)(struct kvm_vcpu *vcpu,int cpu);void (*vcpu_put)(struct kvm_vcpu *vcpu); -int (*set_guest_debug)(struct kvm_vcpu *vcpu, -struct kvm_guest_debug *dbg); +void (*set_guest_debug)(struct kvm_vcpu *vcpu, +struct kvm_guest_debug *dbg);int (*get_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 *pdata);int (*set_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 data);u64 (*get_segment_base)(struct kvm_vcpu *vcpu,int seg);
arch/x86/kvm/svm.c +2 -12
@@ -1065,26 +1065,16 @@ static void update_db_intercept(struct kvm_vcpu *vcpu) vcpu->guest_debug =0 ; } -static int svm_guest_debug (struct kvm_vcpu *vcpu,struct kvm_guest_debug *dbg) +static void svm_guest_debug (struct kvm_vcpu *vcpu,struct kvm_guest_debug *dbg) { -int old_debug = vcpu->guest_debug;struct vcpu_svm *svm =to_svm (vcpu); - vcpu->guest_debug = dbg->control; - -update_db_intercept (vcpu); -if (vcpu->guest_debug &KVM_GUESTDBG_USE_HW_BP ) svm->vmcb->save.dr7 = dbg->arch.debugreg[7 ];else svm->vmcb->save.dr7 = vcpu->arch.dr7; -if (vcpu->guest_debug &KVM_GUESTDBG_SINGLESTEP ) - svm->vmcb->save.rflags |=X86_EFLAGS_TF |X86_EFLAGS_RF ; -else if (old_debug &KVM_GUESTDBG_SINGLESTEP ) - svm->vmcb->save.rflags &= ~(X86_EFLAGS_TF |X86_EFLAGS_RF ); - -return 0 ; +update_db_intercept (vcpu); }static void load_host_msrs (struct kvm_vcpu *vcpu)
arch/x86/kvm/vmx.c +1 -17
@@ -1096,30 +1096,14 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) } } -static int set_guest_debug (struct kvm_vcpu *vcpu,struct kvm_guest_debug *dbg) +static void set_guest_debug (struct kvm_vcpu *vcpu,struct kvm_guest_debug *dbg) { -int old_debug = vcpu->guest_debug; -unsigned long flags; - - vcpu->guest_debug = dbg->control; -if (!(vcpu->guest_debug &KVM_GUESTDBG_ENABLE )) - vcpu->guest_debug =0 ; -if (vcpu->guest_debug &KVM_GUESTDBG_USE_HW_BP )vmcs_writel (GUEST_DR7 , dbg->arch.debugreg[7 ]);else vmcs_writel (GUEST_DR7 , vcpu->arch.dr7); - flags =vmcs_readl (GUEST_RFLAGS ); -if (vcpu->guest_debug &KVM_GUESTDBG_SINGLESTEP ) - flags |=X86_EFLAGS_TF |X86_EFLAGS_RF ; -else if (old_debug &KVM_GUESTDBG_SINGLESTEP ) - flags &= ~(X86_EFLAGS_TF |X86_EFLAGS_RF ); -vmcs_writel (GUEST_RFLAGS , flags); -update_exception_bitmap (vcpu); - -return 0 ; }static __init int cpu_has_kvm_support (void )
arch/x86/kvm/x86.c +21 -7
@@ -4470,12 +4470,19 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,int kvm_arch_vcpu_ioctl_set_guest_debug (struct kvm_vcpu *vcpu,struct kvm_guest_debug *dbg) { -int i, r; +unsigned long rflags; +int old_debug; +int i;vcpu_load (vcpu); -if ((dbg->control & (KVM_GUESTDBG_ENABLE |KVM_GUESTDBG_USE_HW_BP )) == - (KVM_GUESTDBG_ENABLE |KVM_GUESTDBG_USE_HW_BP )) { + old_debug = vcpu->guest_debug; + + vcpu->guest_debug = dbg->control; +if (!(vcpu->guest_debug &KVM_GUESTDBG_ENABLE )) + vcpu->guest_debug =0 ; + +if (vcpu->guest_debug &KVM_GUESTDBG_USE_HW_BP ) {for (i =0 ; i <KVM_NR_DB_REGS ; ++i) vcpu->arch.eff_db[i] = dbg->arch.debugreg[i]; vcpu->arch.switch_db_regs =
@@ -4486,16 +4493,23 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, vcpu->arch.switch_db_regs = (vcpu->arch.dr7 &DR7_BP_EN_MASK ); } - r = kvm_x86_ops->set_guest_debug (vcpu, dbg); + rflags = kvm_x86_ops->get_rflags (vcpu); +if (vcpu->guest_debug &KVM_GUESTDBG_SINGLESTEP ) + rflags |=X86_EFLAGS_TF |X86_EFLAGS_RF ; +else if (old_debug &KVM_GUESTDBG_SINGLESTEP ) + rflags &= ~(X86_EFLAGS_TF |X86_EFLAGS_RF ); + kvm_x86_ops->set_rflags (vcpu, rflags); -if (dbg->control &KVM_GUESTDBG_INJECT_DB ) + kvm_x86_ops->set_guest_debug (vcpu, dbg); + +if (vcpu->guest_debug &KVM_GUESTDBG_INJECT_DB )kvm_queue_exception (vcpu,DB_VECTOR ); -else if (dbg->control &KVM_GUESTDBG_INJECT_BP ) +else if (vcpu->guest_debug &KVM_GUESTDBG_INJECT_BP )kvm_queue_exception (vcpu,BP_VECTOR );vcpu_put (vcpu); -return r; +return 0 ; }/*