diff mbox series

[2/2,RFC] hwrng: fix khwrng registration

Message ID 20241024163121.246420-2-marex@denx.de (mailing list archive)
State Changes Requested
Delegated to: Herbert Xu
Headers show
Series [1/2,RFC] hwrng: fix khwrng lifecycle | expand

Commit Message

Marek Vasut Oct. 24, 2024, 4:30 p.m. UTC
If we have a register/unregister too fast, it can happen that the kthread
is not yet started when kthread_stop is called, and this seems to leave a
corrupted or uninitialized kthread struct. This is detected by the
WARN_ON at kernel/kthread.c:75 and later causes a page domain fault.

Wait for the kthread to start the same way as drivers/base/devtmpfs.c
does wait for kdevtmpfs thread to start using setup_done completion.

Signed-off-by: Marek Vasut <marex@denx.de>
---
This is a follow-up on second part of V2 of work by Luca Dariz:
https://lore.kernel.org/all/AM6PR06MB5400DAFE0551F1D468B728FBAB889@AM6PR06MB5400.eurprd06.prod.outlook.com/
---
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Harald Freudenberger <freude@linux.ibm.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Li Zhijian <lizhijian@fujitsu.com>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Olivia Mackall <olivia@selenic.com>
Cc: linux-crypto@vger.kernel.org
---
 drivers/char/hw_random/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 5be26f4e9d975..bb1f4ba602b1d 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -55,6 +55,7 @@  MODULE_PARM_DESC(default_quality,
 static void drop_current_rng(void);
 static int hwrng_init(struct hwrng *rng);
 static int hwrng_fillfn(void *unused);
+static DECLARE_COMPLETION(setup_done);
 
 static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size,
 			       int wait);
@@ -472,6 +473,7 @@  static int hwrng_fillfn(void *unused)
 	size_t entropy, entropy_credit = 0; /* in 1/1024 of a bit */
 	long rc;
 
+	complete(&setup_done);
 	while (!kthread_should_stop()) {
 		unsigned short quality;
 		struct hwrng *rng;
@@ -669,13 +671,15 @@  static int __init hwrng_modinit(void)
 	if (ret)
 		goto err_miscdev;
 
-	hwrng_fill = kthread_create(hwrng_fillfn, NULL, "hwrng");
+	hwrng_fill = kthread_run(hwrng_fillfn, NULL, "hwrng");
 	if (IS_ERR(hwrng_fill)) {
 		ret = PTR_ERR(hwrng_fill);
 		pr_err("hwrng_fill thread creation failed (%d)\n", ret);
 		goto err_kthread;
 	}
 
+	wait_for_completion(&setup_done);
+
 	ret = kthread_park(hwrng_fill);
 	if (ret)
 		goto err_park;