From c682e51dbc9837f4aa61180775e9ca4f2a463adf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 9 Nov 2013 00:38:24 +0100 Subject: [PATCH] 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 : [] 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 [] (arch_irq_work_raise+0x3c/0x48) from [] (irq_work_queue+0xe4/0xf8) [] (irq_work_queue+0xe4/0xf8) from [] (rcu_accelerate_cbs+0x1d4/0x1d8) [] (rcu_accelerate_cbs+0x1d4/0x1d8) from [] (rcu_start_gp+0x34/0x48) [] (rcu_start_gp+0x34/0x48) from [] (rcu_process_callbacks+0x318/0x608) [] (rcu_process_callbacks+0x318/0x608) from [] (__do_softirq+0x114/0x2a0) [] (__do_softirq+0x114/0x2a0) from [] (do_softirq+0x6c/0x74) [] (do_softirq+0x6c/0x74) from [] (irq_exit+0xac/0x100) [] (irq_exit+0xac/0x100) from [] (handle_IRQ+0x54/0xb4) [] (handle_IRQ+0x54/0xb4) from [] (omap3_intc_handle_irq+0x60/0x74) [] (omap3_intc_handle_irq+0x60/0x74) from [] (__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 [] (__irq_svc+0x44/0x5c) from [] (_raw_spin_unlock_irq+0x28/0x2c) [] (_raw_spin_unlock_irq+0x28/0x2c) from [] (proc_alloc_inum+0x30/0xa8) [] (proc_alloc_inum+0x30/0xa8) from [] (proc_register+0x18/0x130) [] (proc_register+0x18/0x130) from [] (proc_mkdir_data+0x44/0x6c) [] (proc_mkdir_data+0x44/0x6c) from [] (register_irq_proc+0x6c/0x128) [] (register_irq_proc+0x6c/0x128) from [] (init_irq_proc+0x74/0xb0) [] (init_irq_proc+0x74/0xb0) from [] (kernel_init_freeable+0x84/0x1c8) [] (kernel_init_freeable+0x84/0x1c8) from [] (kernel_init+0x8/0x150) [] (kernel_init+0x8/0x150) from [] (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 Signed-off-by: Stephen Boyd Tested-by: Olof Johansson Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index bf9a0d6d91dc..e115cbb0d25a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -453,7 +453,8 @@ void arch_send_call_function_single_ipi(int cpu) #ifdef CONFIG_IRQ_WORK void arch_irq_work_raise(void) { - smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); + if (is_smp()) + smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif