aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/disassemble.h4
-rw-r--r--arch/powerpc/include/asm/kvm_booke.h7
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h21
-rw-r--r--arch/powerpc/kvm/booke.c2
-rw-r--r--arch/powerpc/kvm/e500_emulate.c26
5 files changed, 54 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/disassemble.h b/arch/powerpc/include/asm/disassemble.h
index 9b198d1b3b2b..856f8deb557a 100644
--- a/arch/powerpc/include/asm/disassemble.h
+++ b/arch/powerpc/include/asm/disassemble.h
@@ -77,4 +77,8 @@ static inline unsigned int get_d(u32 inst)
77 return inst & 0xffff; 77 return inst & 0xffff;
78} 78}
79 79
80static inline unsigned int get_oc(u32 inst)
81{
82 return (inst >> 11) & 0x7fff;
83}
80#endif /* __ASM_PPC_DISASSEMBLE_H__ */ 84#endif /* __ASM_PPC_DISASSEMBLE_H__ */
diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h
index d3c1eb34c986..dd8f61510dfd 100644
--- a/arch/powerpc/include/asm/kvm_booke.h
+++ b/arch/powerpc/include/asm/kvm_booke.h
@@ -26,7 +26,12 @@
26/* LPIDs we support with this build -- runtime limit may be lower */ 26/* LPIDs we support with this build -- runtime limit may be lower */
27#define KVMPPC_NR_LPIDS 64 27#define KVMPPC_NR_LPIDS 64
28 28
29#define KVMPPC_INST_EHPRIV 0x7c00021c 29#define KVMPPC_INST_EHPRIV 0x7c00021c
30#define EHPRIV_OC_SHIFT 11
31/* "ehpriv 1" : ehpriv with OC = 1 is used for debug emulation */
32#define EHPRIV_OC_DEBUG 1
33#define KVMPPC_INST_EHPRIV_DEBUG (KVMPPC_INST_EHPRIV | \
34 (EHPRIV_OC_DEBUG << EHPRIV_OC_SHIFT))
30 35
31static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) 36static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
32{ 37{
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index e420d46d363f..482bba56e499 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -269,7 +269,24 @@ struct kvm_fpu {
269 __u64 fpr[32]; 269 __u64 fpr[32];
270}; 270};
271 271
272/*
273 * Defines for h/w breakpoint, watchpoint (read, write or both) and
274 * software breakpoint.
275 * These are used as "type" in KVM_SET_GUEST_DEBUG ioctl and "status"
276 * for KVM_DEBUG_EXIT.
277 */
278#define KVMPPC_DEBUG_NONE 0x0
279#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1)
280#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2)
281#define KVMPPC_DEBUG_WATCH_READ (1UL << 3)
272struct kvm_debug_exit_arch { 282struct kvm_debug_exit_arch {
283 __u64 address;
284 /*
285 * exiting to userspace because of h/w breakpoint, watchpoint
286 * (read, write or both) and software breakpoint.
287 */
288 __u32 status;
289 __u32 reserved;
273}; 290};
274 291
275/* for KVM_SET_GUEST_DEBUG */ 292/* for KVM_SET_GUEST_DEBUG */
@@ -281,10 +298,6 @@ struct kvm_guest_debug_arch {
281 * Type denotes h/w breakpoint, read watchpoint, write 298 * Type denotes h/w breakpoint, read watchpoint, write
282 * watchpoint or watchpoint (both read and write). 299 * watchpoint or watchpoint (both read and write).
283 */ 300 */
284#define KVMPPC_DEBUG_NONE 0x0
285#define KVMPPC_DEBUG_BREAKPOINT (1UL << 1)
286#define KVMPPC_DEBUG_WATCH_WRITE (1UL << 2)
287#define KVMPPC_DEBUG_WATCH_READ (1UL << 3)
288 __u32 type; 301 __u32 type;
289 __u32 reserved; 302 __u32 reserved;
290 } bp[16]; 303 } bp[16];
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 65fa7754b194..1d6edf00e0e5 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -1477,7 +1477,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
1477 val = get_reg_val(reg->id, vcpu->arch.tsr); 1477 val = get_reg_val(reg->id, vcpu->arch.tsr);
1478 break; 1478 break;
1479 case KVM_REG_PPC_DEBUG_INST: 1479 case KVM_REG_PPC_DEBUG_INST:
1480 val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV); 1480 val = get_reg_val(reg->id, KVMPPC_INST_EHPRIV_DEBUG);
1481 break; 1481 break;
1482 case KVM_REG_PPC_VRSAVE: 1482 case KVM_REG_PPC_VRSAVE:
1483 val = get_reg_val(reg->id, vcpu->arch.vrsave); 1483 val = get_reg_val(reg->id, vcpu->arch.vrsave);
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index b10a01243abd..6163a0318d2a 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -26,6 +26,7 @@
26#define XOP_TLBRE 946 26#define XOP_TLBRE 946
27#define XOP_TLBWE 978 27#define XOP_TLBWE 978
28#define XOP_TLBILX 18 28#define XOP_TLBILX 18
29#define XOP_EHPRIV 270
29 30
30#ifdef CONFIG_KVM_E500MC 31#ifdef CONFIG_KVM_E500MC
31static int dbell2prio(ulong param) 32static int dbell2prio(ulong param)
@@ -82,6 +83,26 @@ static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
82} 83}
83#endif 84#endif
84 85
86static int kvmppc_e500_emul_ehpriv(struct kvm_run *run, struct kvm_vcpu *vcpu,
87 unsigned int inst, int *advance)
88{
89 int emulated = EMULATE_DONE;
90
91 switch (get_oc(inst)) {
92 case EHPRIV_OC_DEBUG:
93 run->exit_reason = KVM_EXIT_DEBUG;
94 run->debug.arch.address = vcpu->arch.pc;
95 run->debug.arch.status = 0;
96 kvmppc_account_exit(vcpu, DEBUG_EXITS);
97 emulated = EMULATE_EXIT_USER;
98 *advance = 0;
99 break;
100 default:
101 emulated = EMULATE_FAIL;
102 }
103 return emulated;
104}
105
85int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 106int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
86 unsigned int inst, int *advance) 107 unsigned int inst, int *advance)
87{ 108{
@@ -130,6 +151,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
130 emulated = kvmppc_e500_emul_tlbivax(vcpu, ea); 151 emulated = kvmppc_e500_emul_tlbivax(vcpu, ea);
131 break; 152 break;
132 153
154 case XOP_EHPRIV:
155 emulated = kvmppc_e500_emul_ehpriv(run, vcpu, inst,
156 advance);
157 break;
158
133 default: 159 default:
134 emulated = EMULATE_FAIL; 160 emulated = EMULATE_FAIL;
135 } 161 }