aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_booke.h2
-rw-r--r--arch/powerpc/kvm/booke.c19
-rw-r--r--arch/powerpc/kvm/bookehv_interrupts.S4
3 files changed, 20 insertions, 5 deletions
diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h
index 630134d17f5d..3286f0d6a86c 100644
--- a/arch/powerpc/include/asm/kvm_booke.h
+++ b/arch/powerpc/include/asm/kvm_booke.h
@@ -33,8 +33,6 @@
33#define EHPRIV_OC_SHIFT 11 33#define EHPRIV_OC_SHIFT 11
34/* "ehpriv 1" : ehpriv with OC = 1 is used for debug emulation */ 34/* "ehpriv 1" : ehpriv with OC = 1 is used for debug emulation */
35#define EHPRIV_OC_DEBUG 1 35#define EHPRIV_OC_DEBUG 1
36#define KVMPPC_INST_EHPRIV_DEBUG (KVMPPC_INST_EHPRIV | \
37 (EHPRIV_OC_DEBUG << EHPRIV_OC_SHIFT))
38 36
39static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) 37static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
40{ 38{
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 97ec5b7fce9c..ed5b0dd58726 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -994,6 +994,11 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
994 case BOOKE_INTERRUPT_HV_PRIV: 994 case BOOKE_INTERRUPT_HV_PRIV:
995 emulated = kvmppc_get_last_inst(vcpu, false, &last_inst); 995 emulated = kvmppc_get_last_inst(vcpu, false, &last_inst);
996 break; 996 break;
997 case BOOKE_INTERRUPT_PROGRAM:
998 /* SW breakpoints arrive as illegal instructions on HV */
999 if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
1000 emulated = kvmppc_get_last_inst(vcpu, false, &last_inst);
1001 break;
997 default: 1002 default:
998 break; 1003 break;
999 } 1004 }
@@ -1071,6 +1076,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
1071 break; 1076 break;
1072 1077
1073 case BOOKE_INTERRUPT_PROGRAM: 1078 case BOOKE_INTERRUPT_PROGRAM:
1079 if ((vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) &&
1080 (last_inst == KVMPPC_INST_SW_BREAKPOINT)) {
1081 /*
1082 * We are here because of an SW breakpoint instr,
1083 * so lets return to host to handle.
1084 */
1085 r = kvmppc_handle_debug(run, vcpu);
1086 run->exit_reason = KVM_EXIT_DEBUG;
1087 kvmppc_account_exit(vcpu, DEBUG_EXITS);
1088 break;
1089 }
1090
1074 if (vcpu->arch.shared->msr & (MSR_PR | MSR_GS)) { 1091 if (vcpu->arch.shared->msr & (MSR_PR | MSR_GS)) {
1075 /* 1092 /*
1076 * Program traps generated by user-level software must 1093 * Program traps generated by user-level software must
@@ -1647,7 +1664,7 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
1647 *val = get_reg_val(id, vcpu->arch.tsr); 1664 *val = get_reg_val(id, vcpu->arch.tsr);
1648 break; 1665 break;
1649 case KVM_REG_PPC_DEBUG_INST: 1666 case KVM_REG_PPC_DEBUG_INST:
1650 *val = get_reg_val(id, KVMPPC_INST_EHPRIV_DEBUG); 1667 *val = get_reg_val(id, KVMPPC_INST_SW_BREAKPOINT);
1651 break; 1668 break;
1652 case KVM_REG_PPC_VRSAVE: 1669 case KVM_REG_PPC_VRSAVE:
1653 *val = get_reg_val(id, vcpu->arch.vrsave); 1670 *val = get_reg_val(id, vcpu->arch.vrsave);
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
index c8e4da55cb43..81bd8a07aa51 100644
--- a/arch/powerpc/kvm/bookehv_interrupts.S
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -238,7 +238,7 @@ kvm_handler BOOKE_INTERRUPT_EXTERNAL, EX_PARAMS(GEN), \
238kvm_handler BOOKE_INTERRUPT_ALIGNMENT, EX_PARAMS(GEN), \ 238kvm_handler BOOKE_INTERRUPT_ALIGNMENT, EX_PARAMS(GEN), \
239 SPRN_SRR0, SPRN_SRR1,(NEED_DEAR | NEED_ESR) 239 SPRN_SRR0, SPRN_SRR1,(NEED_DEAR | NEED_ESR)
240kvm_handler BOOKE_INTERRUPT_PROGRAM, EX_PARAMS(GEN), \ 240kvm_handler BOOKE_INTERRUPT_PROGRAM, EX_PARAMS(GEN), \
241 SPRN_SRR0, SPRN_SRR1,NEED_ESR 241 SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU)
242kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, EX_PARAMS(GEN), \ 242kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, EX_PARAMS(GEN), \
243 SPRN_SRR0, SPRN_SRR1, 0 243 SPRN_SRR0, SPRN_SRR1, 0
244kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, EX_PARAMS(GEN), \ 244kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, EX_PARAMS(GEN), \
@@ -348,7 +348,7 @@ kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR
348kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 348kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0
349kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ 349kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \
350 SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR) 350 SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR)
351kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, NEED_ESR 351kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU)
352kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 352kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
353kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0 353kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
354kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 354kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0