diff options
-rw-r--r-- | arch/powerpc/include/asm/disassemble.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_booke.h | 7 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/kvm.h | 21 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 26 |
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 | ||
80 | static 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 | ||
31 | static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) | 36 | static 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) | ||
272 | struct kvm_debug_exit_arch { | 282 | struct 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 |
31 | static int dbell2prio(ulong param) | 32 | static 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 | ||
86 | static 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 | |||
85 | int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | 106 | int 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 | } |