diff options
author | Jan Stancek <jstancek@redhat.com> | 2015-12-08 13:57:51 -0500 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2015-12-09 14:13:06 -0500 |
commit | 27f972d3e00b50639deb4cc1392afaeb08d3cecc (patch) | |
tree | 7769a760fba417a4cee7a4091b3633908b25eef6 /drivers/char | |
parent | aa53685549a2cfb5f175b0c4a20bc9aa1e5a1b85 (diff) |
ipmi: move timer init to before irq is setup
We encountered a panic on boot in ipmi_si on a dell per320 due to an
uninitialized timer as follows.
static int smi_start_processing(void *send_info,
ipmi_smi_t intf)
{
/* Try to claim any interrupts. */
if (new_smi->irq_setup)
new_smi->irq_setup(new_smi);
--> IRQ arrives here and irq handler tries to modify uninitialized timer
which triggers BUG_ON(!timer->function) in __mod_timer().
Call Trace:
<IRQ>
[<ffffffffa0532617>] start_new_msg+0x47/0x80 [ipmi_si]
[<ffffffffa053269e>] start_check_enables+0x4e/0x60 [ipmi_si]
[<ffffffffa0532bd8>] smi_event_handler+0x1e8/0x640 [ipmi_si]
[<ffffffff810f5584>] ? __rcu_process_callbacks+0x54/0x350
[<ffffffffa053327c>] si_irq_handler+0x3c/0x60 [ipmi_si]
[<ffffffff810efaf0>] handle_IRQ_event+0x60/0x170
[<ffffffff810f245e>] handle_edge_irq+0xde/0x180
[<ffffffff8100fc59>] handle_irq+0x49/0xa0
[<ffffffff8154643c>] do_IRQ+0x6c/0xf0
[<ffffffff8100ba53>] ret_from_intr+0x0/0x11
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
The following patch fixes the problem.
To: Openipmi-developer@lists.sourceforge.net
To: Corey Minyard <minyard@acm.org>
CC: linux-kernel@vger.kernel.org
Signed-off-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Tony Camuso <tcamuso@redhat.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # Applies cleanly to 3.10-, needs small rework before
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 55fe9020459f..4cc72fa017c7 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1230,14 +1230,14 @@ static int smi_start_processing(void *send_info, | |||
1230 | 1230 | ||
1231 | new_smi->intf = intf; | 1231 | new_smi->intf = intf; |
1232 | 1232 | ||
1233 | /* Try to claim any interrupts. */ | ||
1234 | if (new_smi->irq_setup) | ||
1235 | new_smi->irq_setup(new_smi); | ||
1236 | |||
1237 | /* Set up the timer that drives the interface. */ | 1233 | /* Set up the timer that drives the interface. */ |
1238 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); | 1234 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); |
1239 | smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); | 1235 | smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); |
1240 | 1236 | ||
1237 | /* Try to claim any interrupts. */ | ||
1238 | if (new_smi->irq_setup) | ||
1239 | new_smi->irq_setup(new_smi); | ||
1240 | |||
1241 | /* | 1241 | /* |
1242 | * Check if the user forcefully enabled the daemon. | 1242 | * Check if the user forcefully enabled the daemon. |
1243 | */ | 1243 | */ |