hwrng: bcm2835: fix oops when rng h/w is accessed during registration

Message ID 1397157730-31161-1-git-send-email-mporter@linaro.org
State New
Headers show

Commit Message

Matt Porter April 10, 2014, 7:22 p.m.
Commit "d9e7972 hwrng: add randomness to system from rng sources"
exposed a bug in the bcm2835-rng driver resulting in boot failure
on Raspberry Pi due to the following oops:

[   28.261523] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1]
[   28.271058]
[   28.275958] CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.0+ #11
[   28.285374] task: db480000 ti: db484000 task.ti: db484000
[   28.294279] PC is at bcm2835_rng_read+0x28/0x48
[   28.302276] LR is at hwrng_register+0x1a8/0x238
.
.
.

The RNG h/w is not completely initialized and enabled before
hwrng_register() is called and so the bcm2835_rng_read() fails.
Fix this by making the warmup/enable writes before registering
the RNG source with the hwrng core.

Signed-off-by: Matt Porter <mporter@linaro.org>
---
 drivers/char/hw_random/bcm2835-rng.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Herbert Xu April 11, 2014, 3:32 a.m. | #1
On Thu, Apr 10, 2014 at 03:22:10PM -0400, Matt Porter wrote:
> Commit "d9e7972 hwrng: add randomness to system from rng sources"
> exposed a bug in the bcm2835-rng driver resulting in boot failure
> on Raspberry Pi due to the following oops:
> 
> [   28.261523] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1]
> [   28.271058]
> [   28.275958] CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.0+ #11
> [   28.285374] task: db480000 ti: db484000 task.ti: db484000
> [   28.294279] PC is at bcm2835_rng_read+0x28/0x48
> [   28.302276] LR is at hwrng_register+0x1a8/0x238
> .
> .
> .
> 
> The RNG h/w is not completely initialized and enabled before
> hwrng_register() is called and so the bcm2835_rng_read() fails.
> Fix this by making the warmup/enable writes before registering
> the RNG source with the hwrng core.
> 
> Signed-off-by: Matt Porter <mporter@linaro.org>

Patch applied.  Thanks a lot!

Patch

diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
index 8c3b255..e900961 100644
--- a/drivers/char/hw_random/bcm2835-rng.c
+++ b/drivers/char/hw_random/bcm2835-rng.c
@@ -61,18 +61,18 @@  static int bcm2835_rng_probe(struct platform_device *pdev)
 	}
 	bcm2835_rng_ops.priv = (unsigned long)rng_base;
 
+	/* set warm-up count & enable */
+	__raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+	__raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+
 	/* register driver */
 	err = hwrng_register(&bcm2835_rng_ops);
 	if (err) {
 		dev_err(dev, "hwrng registration failed\n");
 		iounmap(rng_base);
-	} else {
+	} else
 		dev_info(dev, "hwrng registered\n");
 
-		/* set warm-up count & enable */
-		__raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
-		__raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
-	}
 	return err;
 }