Commit 25a8a02d authored by Alexander Graf's avatar Alexander Graf Committed by Marcelo Tosatti

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: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 021ec9c6
...@@ -91,6 +91,7 @@ struct kvmppc_vcpu_book3s { ...@@ -91,6 +91,7 @@ struct kvmppc_vcpu_book3s {
u64 vsid_next; u64 vsid_next;
u64 vsid_max; u64 vsid_max;
int context_id; int context_id;
ulong prog_flags; /* flags to inject when giving a 700 trap */
}; };
#define CONTEXT_HOST 0 #define CONTEXT_HOST 0
......
...@@ -80,7 +80,7 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); ...@@ -80,7 +80,7 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu); extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu); extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu); extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
......
...@@ -426,6 +426,10 @@ ...@@ -426,6 +426,10 @@
#define SRR1_WAKEMT 0x00280000 /* mtctrl */ #define SRR1_WAKEMT 0x00280000 /* mtctrl */
#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ #define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
#define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */ #define SRR1_WAKETHERM 0x00100000 /* Thermal management interrupt */
#define SRR1_PROGFPE 0x00100000 /* Floating Point Enabled */
#define SRR1_PROGPRIV 0x00040000 /* Privileged instruction */
#define SRR1_PROGTRAP 0x00020000 /* Trap */
#define SRR1_PROGADDR 0x00010000 /* SRR0 contains subsequent addr */
#define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ #define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */
#define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ #define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */
......
...@@ -168,8 +168,9 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) ...@@ -168,8 +168,9 @@ void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
} }
void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
{ {
to_book3s(vcpu)->prog_flags = flags;
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM); kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_PROGRAM);
} }
...@@ -198,6 +199,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) ...@@ -198,6 +199,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
{ {
int deliver = 1; int deliver = 1;
int vec = 0; int vec = 0;
ulong flags = 0ULL;
switch (priority) { switch (priority) {
case BOOK3S_IRQPRIO_DECREMENTER: case BOOK3S_IRQPRIO_DECREMENTER:
...@@ -231,6 +233,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) ...@@ -231,6 +233,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
break; break;
case BOOK3S_IRQPRIO_PROGRAM: case BOOK3S_IRQPRIO_PROGRAM:
vec = BOOK3S_INTERRUPT_PROGRAM; vec = BOOK3S_INTERRUPT_PROGRAM;
flags = to_book3s(vcpu)->prog_flags;
break; break;
case BOOK3S_IRQPRIO_VSX: case BOOK3S_IRQPRIO_VSX:
vec = BOOK3S_INTERRUPT_VSX; vec = BOOK3S_INTERRUPT_VSX;
...@@ -261,7 +264,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) ...@@ -261,7 +264,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
#endif #endif
if (deliver) if (deliver)
kvmppc_inject_interrupt(vcpu, vec, 0ULL); kvmppc_inject_interrupt(vcpu, vec, flags);
return deliver; return deliver;
} }
......
...@@ -82,8 +82,9 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu, ...@@ -82,8 +82,9 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
set_bit(priority, &vcpu->arch.pending_exceptions); set_bit(priority, &vcpu->arch.pending_exceptions);
} }
void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags)
{ {
/* BookE does flags in ESR, so ignore those we get here */
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
} }
......
...@@ -154,7 +154,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) ...@@ -154,7 +154,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
#else #else
vcpu->arch.esr |= ESR_PTR; vcpu->arch.esr |= ESR_PTR;
#endif #endif
kvmppc_core_queue_program(vcpu); kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
advance = 0; advance = 0;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment