This represents the following 3 patches (attached to bug 730765), but applied to the hardy kernel: http://lkml.org/lkml/2010/9/18/288 http://lkml.org/lkml/2010/9/18/282 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3588fe2e3f36543664beafedd3bb6dc3ffa896c5 Note that the third patch stacks over the change made in the first. diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c index 6d1da58..c8a19f0 100644 --- a/arch/x86/xen/events.c +++ b/arch/x86/xen/events.c @@ -258,7 +258,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) dynamic_irq_init(irq); set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, - handle_level_irq, "event"); + handle_fasteoi_irq, "event"); evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn); @@ -286,8 +286,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) goto out; dynamic_irq_init(irq); - set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, - handle_level_irq, "ipi"); + set_irq_chip_and_handler_name(irq, &xen_percpu_chip, + handle_percpu_irq, "ipi"); bind_ipi.vcpu = cpu; if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, @@ -331,8 +331,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) irq = find_unbound_irq(); dynamic_irq_init(irq); - set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, - handle_level_irq, "virq"); + set_irq_chip_and_handler_name(irq, &xen_percpu_chip, + handle_percpu_irq, "virq"); evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn); @@ -486,6 +486,9 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs) int port = (word_idx * BITS_PER_LONG) + bit_idx; int irq = evtchn_to_irq[port]; + mask_evtchn(port); + clear_evtchn(port); + if (irq != -1) { regs->orig_eax = ~irq; do_IRQ(regs); @@ -545,10 +548,10 @@ static void ack_dynirq(unsigned int irq) { int evtchn = evtchn_from_irq(irq); - move_native_irq(irq); + move_masked_irq(irq); if (VALID_EVTCHN(evtchn)) - clear_evtchn(evtchn); + unmask_evtchn(evtchn); } static int retrigger_dynirq(unsigned int irq) @@ -568,11 +571,22 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { .name = "xen-dyn", .mask = disable_dynirq, .unmask = enable_dynirq, - .ack = ack_dynirq, + .eoi = ack_dynirq, .set_affinity = set_affinity_irq, .retrigger = retrigger_dynirq, }; +static struct irq_chip xen_percpu_chip __read_mostly = { + .name = "xen-percpu", + + .disable = disable_dynirq, + .mask = disable_dynirq, + .unmask = enable_dynirq, + + .ack = ack_dynirq, +}; + + void __init xen_init_IRQ(void) { int i;