[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][HVM] Make sure that the interrupt which event channel events come in
# HG changeset patch # User Steven Smith <ssmith@xxxxxxxxxxxxx> # Node ID c620b16d4063a824b5536b76b90e45d2b0e647e5 # Parent 477a0084ff47ac99a8fdd0fdf21dca1cb69e7346 [XEN][HVM] Make sure that the interrupt which event channel events come in on is level triggered rather than edge triggered, since it's a PCI device. This is complicated by the possibility that another PCI device could be on the same interrupt; the workaround is to have two irr registers for the PIC and APIC, and have qemu and Xen generated interrupts go into different ones. This broke the alt_irq stuff. Fortunately, nobody uses that anymore, so I've removed it. Signed-off-by: Steven Smith <sos22@xxxxxxxxx> --- xen/arch/x86/hvm/i8259.c | 46 +++++++++++++++++++++++--------------- xen/arch/x86/hvm/svm/intr.c | 9 +------ xen/arch/x86/hvm/vioapic.c | 22 +++++++++++++++++- xen/arch/x86/hvm/vmx/io.c | 9 +------ xen/include/asm-x86/hvm/vioapic.h | 2 + xen/include/asm-x86/hvm/vpic.h | 8 ++---- 6 files changed, 59 insertions(+), 37 deletions(-) diff -r 477a0084ff47 -r c620b16d4063 xen/arch/x86/hvm/i8259.c --- a/xen/arch/x86/hvm/i8259.c Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/arch/x86/hvm/i8259.c Fri Sep 29 14:42:04 2006 +0100 @@ -86,7 +86,7 @@ static int pic_get_irq(PicState *s) ASSERT(spin_is_locked(&s->pics_state->lock)); - mask = s->irr & ~s->imr; + mask = (s->irr|s->irr_xen) & ~s->imr; priority = get_priority(s, mask); if (priority == 8) return -1; @@ -128,6 +128,32 @@ void pic_update_irq(struct hvm_virpic *s } } +void pic_set_xen_irq(void *opaque, int irq, int level) +{ + struct hvm_virpic *s = opaque; + unsigned long flags; + PicState *ps; + + spin_lock_irqsave(&s->lock, flags); + + hvm_vioapic_set_xen_irq(current->domain, irq, level); + + /* Set it on the 8259s */ + ps = &s->pics[irq >> 3]; + if (!(ps->elcr & (1 << (irq & 7)))) { + DPRINTK("edge-triggered override IRQ?\n"); + domain_crash(current->domain); + } + if (level) { + ps->irr_xen |= 1 << (irq & 7); + } else { + ps->irr_xen &= ~(1 << (irq & 7)); + } + + pic_update_irq(s); + spin_unlock_irqrestore(&s->lock, flags); +} + void pic_set_irq_new(void *opaque, int irq, int level) { struct hvm_virpic *s = opaque; @@ -136,9 +162,6 @@ void pic_set_irq_new(void *opaque, int i spin_lock_irqsave(&s->lock, flags); hvm_vioapic_set_irq(current->domain, irq, level); pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); - /* used for IOAPIC irqs */ - if (s->alt_irq_func) - s->alt_irq_func(s->alt_irq_opaque, irq, level); pic_update_irq(s); spin_unlock_irqrestore(&s->lock, flags); } @@ -371,6 +394,7 @@ static uint32_t pic_poll_read (PicState s->pics_state->pics[0].irr &= ~(1 << 2); } s->irr &= ~(1 << ret); + s->irr_xen &= ~(1 << ret); s->isr &= ~(1 << ret); if (addr1 >> 7 || ret != 2) pic_update_irq(s->pics_state); @@ -400,7 +424,7 @@ static uint32_t pic_ioport_read(void *op if (s->read_reg_select) ret = s->isr; else - ret = s->irr; + ret = s->irr | s->irr_xen; } else { ret = s->imr; } @@ -470,18 +494,6 @@ void pic_init(struct hvm_virpic *s, void spin_unlock_irqrestore(&s->lock, flags); s->irq_request = irq_request; s->irq_request_opaque = irq_request_opaque; -} - -void pic_set_alt_irq_func(struct hvm_virpic *s, - void (*alt_irq_func)(void *, int, int), - void *alt_irq_opaque) -{ - unsigned long flags; - - spin_lock_irqsave(&s->lock, flags); - s->alt_irq_func = alt_irq_func; - s->alt_irq_opaque = alt_irq_opaque; - spin_unlock_irqrestore(&s->lock, flags); } static int intercept_pic_io(ioreq_t *p) diff -r 477a0084ff47 -r c620b16d4063 xen/arch/x86/hvm/svm/intr.c --- a/xen/arch/x86/hvm/svm/intr.c Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/arch/x86/hvm/svm/intr.c Fri Sep 29 14:42:04 2006 +0100 @@ -122,13 +122,8 @@ asmlinkage void svm_intr_assist(void) } callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ]; - if ( callback_irq != 0 && - local_events_need_delivery() ) { - /*inject para-device call back irq*/ - v->vcpu_info->evtchn_upcall_mask = 1; - pic_set_irq(pic, callback_irq, 0); - pic_set_irq(pic, callback_irq, 1); - } + if ( callback_irq != 0) + pic_set_xen_irq(pic, callback_irq, local_events_need_delivery()); if ( cpu_has_pending_irq(v) ) intr_vector = cpu_get_interrupt(v, &intr_type); diff -r 477a0084ff47 -r c620b16d4063 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/arch/x86/hvm/vioapic.c Fri Sep 29 14:42:04 2006 +0100 @@ -479,7 +479,7 @@ static void ioapic_deliver(hvm_vioapic_t static int ioapic_get_highest_irq(hvm_vioapic_t *s) { - uint32_t irqs = s->irr & ~s->isr & ~s->imr; + uint32_t irqs = (s->irr | s->irr_xen) & ~s->isr & ~s->imr; return fls(irqs) - 1; } @@ -501,6 +501,7 @@ static void service_ioapic(hvm_vioapic_t } s->irr &= ~(1 << irqno); + s->irr_xen &= ~(1 << irqno); } } @@ -524,6 +525,25 @@ void hvm_vioapic_do_irqs_clear(struct do s->irr &= ~irqs; service_ioapic(s); +} + +void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level) +{ + hvm_vioapic_t *s = &d->arch.hvm_domain.vioapic; + + if (!hvm_apic_support(d) || !IOAPICEnabled(s) || + s->redirtbl[irq].RedirForm.mask) + return; + + if (s->redirtbl[irq].RedirForm.trigmod != IOAPIC_LEVEL_TRIGGER) { + DPRINTK("Forcing edge triggered APIC irq %d?\n", irq); + domain_crash(d); + } + + if (level) + s->irr_xen |= 1 << irq; + else + s->irr_xen &= ~(1 << irq); } void hvm_vioapic_set_irq(struct domain *d, int irq, int level) diff -r 477a0084ff47 -r c620b16d4063 xen/arch/x86/hvm/vmx/io.c --- a/xen/arch/x86/hvm/vmx/io.c Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/arch/x86/hvm/vmx/io.c Fri Sep 29 14:42:04 2006 +0100 @@ -92,13 +92,8 @@ asmlinkage void vmx_intr_assist(void) } callback_irq = v->domain->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ]; - if ( callback_irq != 0 && - local_events_need_delivery() ) { - /*inject para-device call back irq*/ - v->vcpu_info->evtchn_upcall_mask = 1; - pic_set_irq(pic, callback_irq, 0); - pic_set_irq(pic, callback_irq, 1); - } + if ( callback_irq != 0 ) + pic_set_xen_irq(pic, callback_irq, local_events_need_delivery()); has_ext_irq = cpu_has_pending_irq(v); diff -r 477a0084ff47 -r c620b16d4063 xen/include/asm-x86/hvm/vioapic.h --- a/xen/include/asm-x86/hvm/vioapic.h Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/include/asm-x86/hvm/vioapic.h Fri Sep 29 14:42:04 2006 +0100 @@ -88,6 +88,7 @@ typedef union RedirStatus typedef struct hvm_vioapic { uint32_t irr; + uint32_t irr_xen; /* interrupts forced on by the hypervisor. */ uint32_t isr; /* This is used for level trigger */ uint32_t imr; uint32_t ioregsel; @@ -105,6 +106,7 @@ hvm_vioapic_t *hvm_vioapic_init(struct d void hvm_vioapic_do_irqs_clear(struct domain *d, uint16_t irqs); void hvm_vioapic_do_irqs(struct domain *d, uint16_t irqs); +void hvm_vioapic_set_xen_irq(struct domain *d, int irq, int level); void hvm_vioapic_set_irq(struct domain *d, int irq, int level); int hvm_vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v); diff -r 477a0084ff47 -r c620b16d4063 xen/include/asm-x86/hvm/vpic.h --- a/xen/include/asm-x86/hvm/vpic.h Fri Sep 29 11:57:06 2006 +0100 +++ b/xen/include/asm-x86/hvm/vpic.h Fri Sep 29 14:42:04 2006 +0100 @@ -34,6 +34,8 @@ typedef struct PicState { typedef struct PicState { uint8_t last_irr; /* edge detection */ uint8_t irr; /* interrupt request register */ + uint8_t irr_xen; /* interrupts forced on by the hypervisor e.g. + the callback irq. */ uint8_t imr; /* interrupt mask register */ uint8_t isr; /* interrupt service register */ uint8_t priority_add; /* highest irq priority */ @@ -58,20 +60,16 @@ struct hvm_virpic { void (*irq_request)(void *opaque, int level); void *irq_request_opaque; /* IOAPIC callback support */ - void (*alt_irq_func)(void *opaque, int irq_num, int level); - void *alt_irq_opaque; spinlock_t lock; }; +void pic_set_xen_irq(void *opaque, int irq, int level); void pic_set_irq(struct hvm_virpic *s, int irq, int level); void pic_set_irq_new(void *opaque, int irq, int level); void pic_init(struct hvm_virpic *s, void (*irq_request)(void *, int), void *irq_request_opaque); -void pic_set_alt_irq_func(struct hvm_virpic *s, - void (*alt_irq_func)(void *, int, int), - void *alt_irq_opaque); int pic_read_irq(struct hvm_virpic *s); void pic_update_irq(struct hvm_virpic *s); /* Caller must hold s->lock */ uint32_t pic_intack_read(struct hvm_virpic *s); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |