ARM: 7887/1: Don't smp_cross_call() on UP devices in arch_irq_work_raise()
If we're running a kernel compiled with SMP_ON_UP=y and the
hardware only supports UP operation there isn't any
smp_cross_call function assigned. Unfortunately, we call
smp_cross_call() unconditionally in arch_irq_work_raise() and
crash the kernel on UP devices. Check to make sure we're running
on an SMP device before calling smp_cross_call() here.
Unable to handle kernel NULL pointer dereference at virtual address
00000000
pgd =
c0004000
[
00000000] *pgd=
00000000
Internal error: Oops:
80000005 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc6-00018-g8d45144-dirty #16
task:
de05b440 ti:
de05c000 task.ti:
de05c000
PC is at 0x0
LR is at arch_irq_work_raise+0x3c/0x48
pc : [<
00000000>] lr : [<
c0019590>] psr:
60000193
sp :
de05dd60 ip :
00000001 fp :
00000000
r10:
c085e2f0 r9 :
de05c000 r8 :
c07be0a4
r7 :
de05c000 r6 :
de05c000 r5 :
c07c5778 r4 :
c0824554
r3 :
00000000 r2 :
00000000 r1 :
00000006 r0 :
c0529a58
Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control:
10c5387d Table:
80004019 DAC:
00000017
Process swapper/0 (pid: 1, stack limit = 0xde05c248)
Stack: (0xde05dd60 to 0xde05e000)
dd60:
c07b9dbc c00cb2dc 00000001 c08242c0 c08242c0 60000113 c07be0a8 c00b0590
dd80:
de05c000 c085e2f0 c08242c0 c08242c0 c1414c28 c00b07cc de05b440 c1414c28
dda0:
c08242c0 c00b0af8 c0862bb0 c0862db0 c1414cd8 de05c028 c0824840 de05ddb8
ddc0:
00000000 00000009 00000001 00000024 c07be0a8 c07be0a4 de05c000 c085e2f0
dde0:
00000000 c004a4b0 00000010 de00d2dc 00000054 00000100 00000024 00000000
de00:
de05c028 0000000a ffff8ae7 00200040 00000016 de05c000 60000193 de05c000
de20:
00000054 00000000 00000000 00000000 00000000 c004a704 00000000 de05c008
de40:
c07ba254 c004aa1c c07c5778 c0014b70 fa200000 00000054 de05de80 c0861244
de60:
00000000 c0008634 de05b440 c051c778 20000113 ffffffff de05deb4 c051d0a4
de80:
00000001 00000001 00000000 de05b440 c082afac de057ac0 de057ac0 de0443c0
dea0:
00000000 00000000 00000000 00000000 c082afbc de05dec8 c009f2a0 c051c778
dec0:
20000113 ffffffff 00000000 c016edb0 00000000 000002b0 de057ac0 de057ac0
dee0:
00000000 c016ee40 c0875e50 de05df2e de057ac0 00000000 00000013 00000000
df00:
00000000 c016f054 de043600 de0443c0 c008eb38 de004ec0 c0875e50 c008eb44
df20:
00000012 00000000 00000000 3931f0f8 00000000 00000000 00000014 c0822e84
df40:
00000000 c008ed2c 00000000 00000000 00000000 c07b7490 c07b7490 c075ab3c
df60:
00000000 c00701ac 00000002 00000000 c0070160 dffadb73 7bf8edb4 00000000
df80:
c051092c 00000000 00000000 00000000 00000000 00000000 00000000 c0510934
dfa0:
de05aa40 00000000 c051092c c0013ce8 00000000 00000000 00000000 00000000
dfc0:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dfe0:
00000000 00000000 00000000 00000000 00000013 00000000 07efffe5 4dfac6f5
[<
c0019590>] (arch_irq_work_raise+0x3c/0x48) from [<
c00cb2dc>] (irq_work_queue+0xe4/0xf8)
[<
c00cb2dc>] (irq_work_queue+0xe4/0xf8) from [<
c00b0590>] (rcu_accelerate_cbs+0x1d4/0x1d8)
[<
c00b0590>] (rcu_accelerate_cbs+0x1d4/0x1d8) from [<
c00b07cc>] (rcu_start_gp+0x34/0x48)
[<
c00b07cc>] (rcu_start_gp+0x34/0x48) from [<
c00b0af8>] (rcu_process_callbacks+0x318/0x608)
[<
c00b0af8>] (rcu_process_callbacks+0x318/0x608) from [<
c004a4b0>] (__do_softirq+0x114/0x2a0)
[<
c004a4b0>] (__do_softirq+0x114/0x2a0) from [<
c004a704>] (do_softirq+0x6c/0x74)
[<
c004a704>] (do_softirq+0x6c/0x74) from [<
c004aa1c>] (irq_exit+0xac/0x100)
[<
c004aa1c>] (irq_exit+0xac/0x100) from [<
c0014b70>] (handle_IRQ+0x54/0xb4)
[<
c0014b70>] (handle_IRQ+0x54/0xb4) from [<
c0008634>] (omap3_intc_handle_irq+0x60/0x74)
[<
c0008634>] (omap3_intc_handle_irq+0x60/0x74) from [<
c051d0a4>] (__irq_svc+0x44/0x5c)
Exception stack(0xde05de80 to 0xde05dec8)
de80:
00000001 00000001 00000000 de05b440 c082afac de057ac0 de057ac0 de0443c0
dea0:
00000000 00000000 00000000 00000000 c082afbc de05dec8 c009f2a0 c051c778
dec0:
20000113 ffffffff
[<
c051d0a4>] (__irq_svc+0x44/0x5c) from [<
c051c778>] (_raw_spin_unlock_irq+0x28/0x2c)
[<
c051c778>] (_raw_spin_unlock_irq+0x28/0x2c) from [<
c016edb0>] (proc_alloc_inum+0x30/0xa8)
[<
c016edb0>] (proc_alloc_inum+0x30/0xa8) from [<
c016ee40>] (proc_register+0x18/0x130)
[<
c016ee40>] (proc_register+0x18/0x130) from [<
c016f054>] (proc_mkdir_data+0x44/0x6c)
[<
c016f054>] (proc_mkdir_data+0x44/0x6c) from [<
c008eb44>] (register_irq_proc+0x6c/0x128)
[<
c008eb44>] (register_irq_proc+0x6c/0x128) from [<
c008ed2c>] (init_irq_proc+0x74/0xb0)
[<
c008ed2c>] (init_irq_proc+0x74/0xb0) from [<
c075ab3c>] (kernel_init_freeable+0x84/0x1c8)
[<
c075ab3c>] (kernel_init_freeable+0x84/0x1c8) from [<
c0510934>] (kernel_init+0x8/0x150)
[<
c0510934>] (kernel_init+0x8/0x150) from [<
c0013ce8>] (ret_from_fork+0x14/0x2c)
Code: bad PC value
Fixes:
bf18525fd79 "ARM: 7872/1: Support arch_irq_work_raise() via self IPIs"
Reported-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>