summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/i8259.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2008-07-26 22:01:00 +0200
committerAvi Kivity <avi@qumranet.com>2008-10-15 10:15:16 +0200
commitf52447261bc8c21dfd4635196e32d2da1352f589 (patch)
treea0de6cefa7fbfdd07285bd60c4f61e4e2f2d4ed6 /arch/x86/kvm/i8259.c
parentKVM: Add irq ack notifier list (diff)
downloadlinux-f52447261bc8c21dfd4635196e32d2da1352f589.tar.xz
linux-f52447261bc8c21dfd4635196e32d2da1352f589.zip
KVM: irq ack notification
Based on a patch from: Ben-Ami Yassour <benami@il.ibm.com> which was based on a patch from: Amit Shah <amit.shah@qumranet.com> Notify IRQ acking on PIC/APIC emulation. The previous patch missed two things: - Edge triggered interrupts on IOAPIC - PIC reset with IRR/ISR set should be equivalent to ack (LAPIC probably needs something similar). Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> CC: Amit Shah <amit.shah@qumranet.com> CC: Ben-Ami Yassour <benami@il.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/i8259.c')
-rw-r--r--arch/x86/kvm/i8259.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 55e179ad98ef..de704995b819 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -159,9 +159,10 @@ static inline void pic_intack(struct kvm_kpic_state *s, int irq)
s->irr &= ~(1 << irq);
}
-int kvm_pic_read_irq(struct kvm_pic *s)
+int kvm_pic_read_irq(struct kvm *kvm)
{
int irq, irq2, intno;
+ struct kvm_pic *s = pic_irqchip(kvm);
irq = pic_get_irq(&s->pics[0]);
if (irq >= 0) {
@@ -187,12 +188,21 @@ int kvm_pic_read_irq(struct kvm_pic *s)
intno = s->pics[0].irq_base + irq;
}
pic_update_irq(s);
+ kvm_notify_acked_irq(kvm, irq);
return intno;
}
void kvm_pic_reset(struct kvm_kpic_state *s)
{
+ int irq;
+ struct kvm *kvm = s->pics_state->irq_request_opaque;
+
+ for (irq = 0; irq < PIC_NUM_PINS; irq++) {
+ if (!(s->imr & (1 << irq)) && (s->irr & (1 << irq) ||
+ s->isr & (1 << irq)))
+ kvm_notify_acked_irq(kvm, irq);
+ }
s->last_irr = 0;
s->irr = 0;
s->imr = 0;