This patch allow userspace to inject debug interrupt to guest. Signed-off-by: Bharat Bhushan <Bharat.Bhushan@xxxxxxxxxxxxx> --- arch/powerpc/kvm/booke.c | 31 +++++++++++++++++++++++++++++-- arch/powerpc/kvm/e500mc.c | 10 +++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index bb25937..63ac38c 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -135,6 +135,11 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) #endif } +static int kvmppc_core_pending_debug(struct kvm_vcpu *vcpu) +{ + return test_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions); +} + static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { /* Synchronize guest's desire to get debug interrupts into shadow MSR */ @@ -143,8 +148,11 @@ static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) vcpu->arch.shadow_msr |= vcpu->arch.shared->msr & MSR_DE; #endif - /* Force enable debug interrupts when user space wants to debug */ - if (vcpu->guest_debug) { + /* + * Force enable debug interrupts when user space wants to debug + * and there is no debug interrupt pending for guest to handle. + */ + if (vcpu->guest_debug && !kvmppc_core_pending_debug(vcpu)) { #ifdef CONFIG_KVM_BOOKE_HV /* * Since there is no shadow MSR, sync MSR_DE into the guest @@ -264,6 +272,16 @@ static void kvmppc_core_dequeue_watchdog(struct kvm_vcpu *vcpu) clear_bit(BOOKE_IRQPRIO_WATCHDOG, &vcpu->arch.pending_exceptions); } +static void kvmppc_core_queue_debug(struct kvm_vcpu *vcpu) +{ + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DEBUG); +} + +static void kvmppc_core_dequeue_debug(struct kvm_vcpu *vcpu) +{ + clear_bit(BOOKE_IRQPRIO_DEBUG, &vcpu->arch.pending_exceptions); +} + static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1) { #ifdef CONFIG_KVM_BOOKE_HV @@ -1332,6 +1350,7 @@ static void get_sregs_base(struct kvm_vcpu *vcpu, sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); sregs->u.e.tb = tb; sregs->u.e.vrsave = vcpu->arch.vrsave; + sregs->u.e.dbsr = vcpu->arch.dbsr; } static int set_sregs_base(struct kvm_vcpu *vcpu, @@ -1356,6 +1375,14 @@ static int set_sregs_base(struct kvm_vcpu *vcpu, if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_TSR) kvmppc_set_tsr(vcpu, sregs->u.e.tsr); + if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DBSR) { + vcpu->arch.dbsr = sregs->u.e.dbsr; + if (vcpu->arch.dbsr) + kvmppc_core_queue_debug(vcpu); + else + kvmppc_core_dequeue_debug(vcpu); + } + return 0; } diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 17e4562..ea724f2 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -212,7 +212,7 @@ static int kvmppc_core_get_sregs_e500mc(struct kvm_vcpu *vcpu, struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM | - KVM_SREGS_E_PC; + KVM_SREGS_E_PC | KVM_SREGS_E_ED; sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL; sregs->u.e.impl.fsl.features = 0; @@ -220,6 +220,9 @@ static int kvmppc_core_get_sregs_e500mc(struct kvm_vcpu *vcpu, sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0; sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar; + sregs->u.e.dsrr0 = vcpu->arch.dsrr0; + sregs->u.e.dsrr1 = vcpu->arch.dsrr1; + kvmppc_get_sregs_e500_tlb(vcpu, sregs); sregs->u.e.ivor_high[3] = @@ -261,6 +264,11 @@ static int kvmppc_core_set_sregs_e500mc(struct kvm_vcpu *vcpu, sregs->u.e.ivor_high[5]; } + if (sregs->u.e.features & KVM_SREGS_E_ED) { + vcpu->arch.dsrr0 = sregs->u.e.dsrr0; + vcpu->arch.dsrr1 = sregs->u.e.dsrr1; + } + return kvmppc_set_sregs_ivor(vcpu, sregs); } -- 1.9.0 -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html