KVM: PPC: Tell guest about pending interrupts
authorAlexander Graf <agraf@suse.de>
Thu, 29 Jul 2010 12:47:51 +0000 (14:47 +0200)
committerAvi Kivity <avi@redhat.com>
Sun, 24 Oct 2010 08:50:46 +0000 (10:50 +0200)
When the guest turns on interrupts again, it needs to know if we have an
interrupt pending for it. Because if so, it should rather get out of guest
context and get the interrupt.

So we introduce a new field in the shared page that we use to tell the guest
that there's a pending interrupt lying around.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/include/asm/kvm_para.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/booke.c

index 5be00c9533d22a87a08c501e870cbb8c7ecfde19..0653b0d238b4b146b3c633fe6a934e3c8abc9ef2 100644 (file)
@@ -37,6 +37,7 @@ struct kvm_vcpu_arch_shared {
        __u64 dar;
        __u64 msr;
        __u32 dsisr;
+       __u32 int_pending;      /* Tells the guest if we have an interrupt */
 };
 
 #define KVM_SC_MAGIC_R0                0x4b564d21 /* "KVM!" */
index d6227ff0ceae7e8e8a75dbcee7d636ed6c8260f4..06229fec5c9f901111fcb9ea54daf708fe8e313e 100644 (file)
@@ -337,6 +337,7 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
 void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
 {
        unsigned long *pending = &vcpu->arch.pending_exceptions;
+       unsigned long old_pending = vcpu->arch.pending_exceptions;
        unsigned int priority;
 
 #ifdef EXIT_DEBUG
@@ -356,6 +357,12 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
                                         BITS_PER_BYTE * sizeof(*pending),
                                         priority + 1);
        }
+
+       /* Tell the guest about our interrupt status */
+       if (*pending)
+               vcpu->arch.shared->int_pending = 1;
+       else if (old_pending)
+               vcpu->arch.shared->int_pending = 0;
 }
 
 void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
index 104d0ee8c8aa6302add6770a82f8d0a1175ed9c0..c604277011a64cda2c4a26e1638dadfd5f30976e 100644 (file)
@@ -224,6 +224,7 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
 void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
 {
        unsigned long *pending = &vcpu->arch.pending_exceptions;
+       unsigned long old_pending = vcpu->arch.pending_exceptions;
        unsigned int priority;
 
        priority = __ffs(*pending);
@@ -235,6 +236,12 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
                                         BITS_PER_BYTE * sizeof(*pending),
                                         priority + 1);
        }
+
+       /* Tell the guest about our interrupt status */
+       if (*pending)
+               vcpu->arch.shared->int_pending = 1;
+       else if (old_pending)
+               vcpu->arch.shared->int_pending = 0;
 }
 
 /**