aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-01-07 20:58:07 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2010-03-01 10:35:49 -0500
commit25a8a02d26a71c28e26417a3520c653c2d40af6b (patch)
tree9d8126991a73f8e33bca3230115bd5ef53c67eb4
parent021ec9c69f8b7b20f46296cc76cc4cb341b25191 (diff)
KVM: PPC: Emulate trap SRR1 flags properly
Book3S needs some flags in SRR1 to get to know details about an interrupt. One such example is the trap instruction. It tells the guest kernel that a program interrupt is due to a trap using a bit in SRR1. This patch implements above behavior, making WARN_ON behave like WARN_ON. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h1
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/include/asm/reg.h4
-rw-r--r--arch/powerpc/kvm/book3s.c7
-rw-r--r--arch/powerpc/kvm/booke.c3
-rw-r--r--arch/powerpc/kvm/emulate.c2
6 files changed, 14 insertions, 5 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index c91be0ff0232..79ab8faf18e7 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -91,6 +91,7 @@ struct kvmppc_vcpu_book3s {
91 u64 vsid_next; 91 u64 vsid_next;
92 u64 vsid_max; 92 u64 vsid_max;
93 int context_id; 93 int context_id;
94 ulong prog_flags; /* flags to inject when giving a 700 trap */
94}; 95};
95 96
96#define CONTEXT_HOST 0 97#define CONTEXT_HOST 0
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 89c5d79c3479..09816da9e950 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -80,7 +80,7 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
80 80
81extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu); 81extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
82extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu); 82extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
83extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu); 83extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
84extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); 84extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
85extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); 85extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
86extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 86extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index bc8dd53f718a..5572e86223f4 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -426,6 +426,10 @@
426#define SRR1_WAKEMT 0x00280000 /* mtctrl */ 426#define SRR1_WAKEMT 0x00280000 /* mtctrl */
427#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ 427#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
428#define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */ 428#define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */
429#define SRR1_PROGFPE 0x00100000 /* Floating Point Enabled */
430#define SRR1_PROGPRIV 0x00040000 /* Privileged instruction */
431#define SRR1_PROGTRAP 0x00020000 /* Trap */
432#define SRR1_PROGADDR 0x00010000 /* SRR0 contains subsequent addr */
429#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ 433#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */
430#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ 434#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */
431 435
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 13173922b678..66b5924e1748 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -168,8 +168,9 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
168} 168}
169 169
170 170
171void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) 171void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
172{ 172{
173 to_book3s(vcpu)->prog_flags = flags;
173 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM); 174 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
174} 175}
175 176
@@ -198,6 +199,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
198{ 199{
199 int deliver = 1; 200 int deliver = 1;
200 int vec = 0; 201 int vec = 0;
202 ulong flags = 0ULL;
201 203
202 switch (priority) { 204 switch (priority) {
203 case BOOK3S_IRQPRIO_DECREMENTER: 205 case BOOK3S_IRQPRIO_DECREMENTER:
@@ -231,6 +233,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
231 break; 233 break;
232 case BOOK3S_IRQPRIO_PROGRAM: 234 case BOOK3S_IRQPRIO_PROGRAM:
233 vec = BOOK3S_INTERRUPT_PROGRAM; 235 vec = BOOK3S_INTERRUPT_PROGRAM;
236 flags = to_book3s(vcpu)->prog_flags;
234 break; 237 break;
235 case BOOK3S_IRQPRIO_VSX: 238 case BOOK3S_IRQPRIO_VSX:
236 vec = BOOK3S_INTERRUPT_VSX; 239 vec = BOOK3S_INTERRUPT_VSX;
@@ -261,7 +264,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
261#endif 264#endif
262 265
263 if (deliver) 266 if (deliver)
264 kvmppc_inject_interrupt(vcpu, vec, 0ULL); 267 kvmppc_inject_interrupt(vcpu, vec, flags);
265 268
266 return deliver; 269 return deliver;
267} 270}
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 338baf9f6b28..e283e44e9f16 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -82,8 +82,9 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
82 set_bit(priority, &vcpu->arch.pending_exceptions); 82 set_bit(priority, &vcpu->arch.pending_exceptions);
83} 83}
84 84
85void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) 85void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
86{ 86{
87 /* BookE does flags in ESR, so ignore those we get here */
87 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); 88 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
88} 89}
89 90
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 04e317c1bbee..8b0ba0b69c2a 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -154,7 +154,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
154#else 154#else
155 vcpu->arch.esr |= ESR_PTR; 155 vcpu->arch.esr |= ESR_PTR;
156#endif 156#endif
157 kvmppc_core_queue_program(vcpu); 157 kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
158 advance = 0; 158 advance = 0;
159 break; 159 break;
160 160