Patch "xen/events: don't bind non-percpu VIRQs with percpu chip" has been added to the 3.14-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
xen/events: don't bind non-percpu VIRQs with percpu chip
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
77bb3dfdc0d554befad58fdefbc41be5bc3ed38aMon Sep 17 00:00:00 2001
From: David Vrabel <[email protected]>
Date: Tue, 19 May 2015 18:40:49 +0100
Subject: xen/events: don't bind non-percpu VIRQs with percpu chip
From: David Vrabel <[email protected]>
commit 77bb3dfdc0d554befad58fdefbc41be5bc3ed38a upstream.
A non-percpu VIRQ (e.g., VIRQ_CONSOLE) may be freed on a different VCPU than it is bound to. This can result in a race between handle_percpu_irq() and removing the action in __free_irq() because handle_percpu_irq() does not take desc->lock. The interrupt handler sees a NULL action and oopses.
Only use the percpu chip/handler for per-CPU VIRQs (like VIRQ_TIMER).
# cat /proc/interrupts | grep virq 40: 87246 0 xen-percpu-virq timer0 44: 0 0 xen-percpu-virq debug0 47: 0 20995 xen-percpu-virq timer1 51: 0 0 xen-percpu-virq debug1 69: 0 0 xen-dyn-virq xen-pcpu 74: 0 0 xen-dyn-virq mce 75: 29 0 xen-dyn-virq hvc_console
--- drivers/tty/hvc/hvc_xen.c | 2 +- drivers/xen/events/events_base.c | 12 ++++++++---- include/xen/events.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-)
drivers/tty/hvc/hvc_xen.c +1 -1
@@ -289,7 +289,7 @@ static int xen_initial_domain_console_inreturn -ENOMEM ; } - info->irq =bind_virq_to_irq (VIRQ_CONSOLE ,0 ); + info->irq =bind_virq_to_irq (VIRQ_CONSOLE ,0 , false); info->vtermno =HVC_COOKIE ;spin_lock (&xencons_lock);
drivers/xen/events/events_base.c +8 -4
@@ -973,7 +973,7 @@ unsigned xen_evtchn_nr_channels(void) }EXPORT_SYMBOL_GPL (xen_evtchn_nr_channels); -int bind_virq_to_irq (unsigned int virq,unsigned int cpu) +int bind_virq_to_irq (unsigned int virq,unsigned int cpu,bool percpu) {struct evtchn_bind_virq bind_virq;int evtchn, irq, ret;
@@ -987,8 +987,12 @@ int bind_virq_to_irq(unsigned int virq,if (irq <0 ) goto out; -irq_set_chip_and_handler_name (irq, &xen_percpu_chip, - handle_percpu_irq,"virq" ); +if (percpu) +irq_set_chip_and_handler_name (irq, &xen_percpu_chip, + handle_percpu_irq,"virq" ); +else +irq_set_chip_and_handler_name (irq, &xen_dynamic_chip, + handle_edge_irq,"virq" ); bind_virq.virq = virq; bind_virq.vcpu = cpu;
@@ -1078,7 +1082,7 @@ int bind_virq_to_irqhandler(unsigned int {int irq, retval; - irq =bind_virq_to_irq (virq, cpu); + irq =bind_virq_to_irq (virq, cpu, irqflags &IRQF_PERCPU );if (irq <0 )return irq; retval =request_irq (irq, handler, irqflags, devname, dev_id);
include/xen/events.h +1 -1
@@ -14,7 +14,7 @@ int bind_evtchn_to_irqhandler(unsigned iirq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id); -int bind_virq_to_irq (unsigned int virq,unsigned int cpu); +int bind_virq_to_irq (unsigned int virq,unsigned int cpu,bool percpu); int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, irq_handler_t handler, unsigned long irqflags, const char *devname,
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/xen-events-don-t-bind-non-percpu-virqs-with-percpu-chip.patch