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>
        u64 vsid_next;
        u64 vsid_max;
        int context_id;
+       ulong prog_flags; /* flags to inject when giving a 700 trap */
 };
 
 #define CONTEXT_HOST           0
 
 
 extern void kvmppc_core_deliver_interrupts(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_dequeue_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
 
 #define   SRR1_WAKEMT          0x00280000 /* mtctrl */
 #define   SRR1_WAKEDEC         0x00180000 /* Decrementer 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_HSRR1     0x13B   /* Save/Restore Register 1 */
 
 
 }
 
 
-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);
 }
 
 {
        int deliver = 1;
        int vec = 0;
+       ulong flags = 0ULL;
 
        switch (priority) {
        case BOOK3S_IRQPRIO_DECREMENTER:
                break;
        case BOOK3S_IRQPRIO_PROGRAM:
                vec = BOOK3S_INTERRUPT_PROGRAM;
+               flags = to_book3s(vcpu)->prog_flags;
                break;
        case BOOK3S_IRQPRIO_VSX:
                vec = BOOK3S_INTERRUPT_VSX;
 #endif
 
        if (deliver)
-               kvmppc_inject_interrupt(vcpu, vec, 0ULL);
+               kvmppc_inject_interrupt(vcpu, vec, flags);
 
        return deliver;
 }
 
        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);
 }
 
 
 #else
                vcpu->arch.esr |= ESR_PTR;
 #endif
-               kvmppc_core_queue_program(vcpu);
+               kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
                advance = 0;
                break;