diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2009-12-01 16:15:30 +0000 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2009-12-03 11:14:55 -0800 |
commit | fed5ea87e02aaf902ff38c65b4514233db03dc09 (patch) | |
tree | 0cd603bec4179e9bbe3e020f3b7ef447d3de6ee2 /drivers/xen/events.c | |
parent | f6eafe3665bcc374c66775d58312d1c06c55303f (diff) |
xen: don't leak IRQs over suspend/resume.
On resume irq_info[*].evtchn is reset to 0 since event channel mappings
are not preserved over suspend/resume. The other contents of irq_info
is preserved to allow rebind_evtchn_irq() to function.
However when a device resumes it will try to unbind from the
previous IRQ (e.g. blkfront goes blkfront_resume() -> blkif_free() ->
unbind_from_irqhandler() -> unbind_from_irq()). This will fail due to the
check for VALID_EVTCHN in unbind_from_irq() and the IRQ is leaked. The
device will then continue to resume and allocate a new IRQ, eventually
leading to find_unbound_irq() panic()ing.
Fix this by changing unbind_from_irq() to handle teardown of interrupts
which have type!=IRQT_UNBOUND but are not currently bound to a specific
event channel.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: Stable Kernel <stable@kernel.org>
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 2f57276e87a..ce602dd09bc 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -474,6 +474,9 @@ static void unbind_from_irq(unsigned int irq) bind_evtchn_to_cpu(evtchn, 0); evtchn_to_irq[evtchn] = -1; + } + + if (irq_info[irq].type != IRQT_UNBOUND) { irq_info[irq] = mk_unbound_info(); dynamic_irq_cleanup(irq); |