summary refs log tree commit diff
path: root/include/xen
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-05-19 18:40:49 +0100
committerDavid Vrabel <david.vrabel@citrix.com>2015-05-19 19:55:36 +0100
commit77bb3dfdc0d554befad58fdefbc41be5bc3ed38a (patch)
tree845e60544a5b07d4adc6beb6249997c909575c1c /include/xen
parentffb7dbed47da6ac4460b606a3feee295bbe4d9e2 (diff)
downloadlinux-77bb3dfdc0d554befad58fdefbc41be5bc3ed38a.tar.gz
xen/events: don't bind non-percpu VIRQs with percpu chip
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

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Cc: <stable@vger.kernel.org>
Diffstat (limited to 'include/xen')
-rw-r--r--include/xen/events.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/xen/events.h b/include/xen/events.h
index 5321cd9636e6..7d95fdf9cf3e 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -17,7 +17,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
 			      irq_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,