diff options
-rw-r--r-- | arch/powerpc/include/asm/kvm_booke.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 19 | ||||
-rw-r--r-- | arch/powerpc/kvm/bookehv_interrupts.S | 4 |
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 | ||
39 | static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) | 37 | static 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), \ | |||
238 | kvm_handler BOOKE_INTERRUPT_ALIGNMENT, EX_PARAMS(GEN), \ | 238 | kvm_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) |
240 | kvm_handler BOOKE_INTERRUPT_PROGRAM, EX_PARAMS(GEN), \ | 240 | kvm_handler BOOKE_INTERRUPT_PROGRAM, EX_PARAMS(GEN), \ |
241 | SPRN_SRR0, SPRN_SRR1,NEED_ESR | 241 | SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU) |
242 | kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, EX_PARAMS(GEN), \ | 242 | kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, EX_PARAMS(GEN), \ |
243 | SPRN_SRR0, SPRN_SRR1, 0 | 243 | SPRN_SRR0, SPRN_SRR1, 0 |
244 | kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, EX_PARAMS(GEN), \ | 244 | kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, EX_PARAMS(GEN), \ |
@@ -348,7 +348,7 @@ kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR | |||
348 | kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 | 348 | kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0 |
349 | kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ | 349 | kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \ |
350 | SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR) | 350 | SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR) |
351 | kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, NEED_ESR | 351 | kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, (NEED_ESR | NEED_EMU) |
352 | kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 | 352 | kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 |
353 | kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0 | 353 | kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0 |
354 | kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 | 354 | kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 |