Skip to content

Commit 0b37a83

Browse files
geertuEduardo Valentin
authored and
Eduardo Valentin
committed
thermal: rcar: Fix race condition between init and interrupt
As soon as the interrupt has been enabled by devm_request_irq(), the interrupt routine may be called, depending on the current status of the hardware. However, at that point rcar_thermal_common hasn't been initialized complely yet. E.g. rcar_thermal_common.base is still NULL, causing a NULL pointer dereference: Unable to handle kernel NULL pointer dereference at virtual address 0000000c pgd = c0004000 [0000000c] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.19.0-rc7-ape6evm-04564-gb6e46cb7cbe82389 #30 Hardware name: Generic R8A73A4 (Flattened Device Tree) task: ee8953c0 ti: ee896000 task.ti: ee896000 PC is at rcar_thermal_irq+0x1c/0xf0 LR is at _raw_spin_lock_irqsave+0x48/0x54 Postpone the call to devm_request_irq() until all initialization has been done to fix this. Signed-off-by: Geert Uytterhoeven <[email protected]> Acked-by: Kuninori Morimoto <[email protected]> Signed-off-by: Eduardo Valentin <[email protected]>
1 parent 12ca718 commit 0b37a83

File tree

1 file changed

+9
-13
lines changed

1 file changed

+9
-13
lines changed

drivers/thermal/rcar_thermal.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -387,21 +387,9 @@ static int rcar_thermal_probe(struct platform_device *pdev)
387387

388388
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
389389
if (irq) {
390-
int ret;
391-
392390
/*
393391
* platform has IRQ support.
394392
* Then, driver uses common registers
395-
*/
396-
397-
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
398-
dev_name(dev), common);
399-
if (ret) {
400-
dev_err(dev, "irq request failed\n ");
401-
return ret;
402-
}
403-
404-
/*
405393
* rcar_has_irq_support() will be enabled
406394
*/
407395
res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
@@ -456,8 +444,16 @@ static int rcar_thermal_probe(struct platform_device *pdev)
456444
}
457445

458446
/* enable temperature comparation */
459-
if (irq)
447+
if (irq) {
448+
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
449+
dev_name(dev), common);
450+
if (ret) {
451+
dev_err(dev, "irq request failed\n ");
452+
goto error_unregister;
453+
}
454+
460455
rcar_thermal_common_write(common, ENR, enr_bits);
456+
}
461457

462458
platform_set_drvdata(pdev, common);
463459

0 commit comments

Comments
 (0)