* [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read
@ 2026-06-23 6:07 Pengpeng Hou
2026-07-01 7:31 ` Jain, Harsh (AECG-SSW)
2026-07-05 8:40 ` Herbert Xu
0 siblings, 2 replies; 3+ messages in thread
From: Pengpeng Hou @ 2026-06-23 6:07 UTC (permalink / raw)
To: Mounika Botcha, Harsh Jain, Olivia Mackall, Herbert Xu,
Michal Simek, linux-crypto, linux-arm-kernel, linux-kernel
Cc: Pengpeng Hou
xtrng_readblock32() polls for 16-byte chunks but returns the number of
bytes read even when the first poll times out. Its caller then treats a
zero return as a short successful read, and partial reads for full
32-byte blocks can make the tail copy use a fixed block offset rather
than the amount already produced.
Return the poll error when no data has been read, preserve partial
positive returns after some data is available, stop the generator on all
collection exits, and append tail bytes at the current output count.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/char/hw_random/xilinx-trng.c | 32 +++++++++++++++++++++-------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/char/hw_random/xilinx-trng.c b/drivers/char/hw_random/xilinx-trng.c
index f615d5adddde..4a1a168bb46a 100644
--- a/drivers/char/hw_random/xilinx-trng.c
+++ b/drivers/char/hw_random/xilinx-trng.c
@@ -87,8 +87,8 @@ static void xtrng_softreset(struct xilinx_rng *rng)
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSRST_MASK, 0);
}
-/* Return no. of bytes read */
-static size_t xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32, bool wait)
+/* Return no. of bytes read or a negative error before any data is read. */
+static int xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32, bool wait)
{
int read = 0, ret;
int timeout = 1;
@@ -103,8 +103,11 @@ static size_t xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks3
ret = readl_poll_timeout(rng_base + TRNG_STATUS_OFFSET, val,
(val & TRNG_STATUS_QCNT_MASK) ==
TRNG_STATUS_QCNT_16_BYTES, !!wait, timeout);
- if (ret)
+ if (ret) {
+ if (!read)
+ return ret;
break;
+ }
for (idx = 0; idx < TRNG_READ_4_WORD; idx++) {
*(buf + read) = cpu_to_be32(ioread32(rng_base + TRNG_CORE_OUTPUT_OFFSET));
@@ -119,27 +122,40 @@ static int xtrng_collect_random_data(struct xilinx_rng *rng, u8 *rand_gen_buf,
{
u8 randbuf[TRNG_SEC_STRENGTH_BYTES];
int byteleft, blocks, count = 0;
+ int full_blocks_bytes;
int ret;
byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1);
blocks = no_of_random_bytes >> TRNG_SEC_STRENGTH_SHIFT;
+ full_blocks_bytes = blocks * TRNG_SEC_STRENGTH_BYTES;
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET, TRNG_CTRL_PRNGSTART_MASK,
TRNG_CTRL_PRNGSTART_MASK);
if (blocks) {
ret = xtrng_readblock32(rng->rng_base, (__be32 *)rand_gen_buf, blocks, wait);
- if (!ret)
- return 0;
+ if (ret <= 0) {
+ count = ret;
+ goto out_stop;
+ }
count += ret;
+ if (ret < full_blocks_bytes)
+ goto out_stop;
}
if (byteleft) {
ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait);
+ if (ret < 0) {
+ if (!count)
+ count = ret;
+ goto out_stop;
+ }
if (!ret)
- return count;
- memcpy(rand_gen_buf + (blocks * TRNG_SEC_STRENGTH_BYTES), randbuf, byteleft);
- count += byteleft;
+ goto out_stop;
+ ret = min(ret, no_of_random_bytes - count);
+ memcpy(rand_gen_buf + count, randbuf, ret);
+ count += ret;
}
+out_stop:
xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
TRNG_CTRL_PRNGMODE_MASK | TRNG_CTRL_PRNGSTART_MASK, 0U);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read
2026-06-23 6:07 [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read Pengpeng Hou
@ 2026-07-01 7:31 ` Jain, Harsh (AECG-SSW)
2026-07-05 8:40 ` Herbert Xu
1 sibling, 0 replies; 3+ messages in thread
From: Jain, Harsh (AECG-SSW) @ 2026-07-01 7:31 UTC (permalink / raw)
To: Pengpeng Hou, Botcha, Mounika, Olivia Mackall, Herbert Xu,
Simek, Michal, linux-crypto@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: Pandey, Radhey Shyam, Savitala, Sarat Chand
AMD General
Reviewed-by : Harsh Jain <h.jain@amd.com>
> -----Original Message-----
> From: Pengpeng Hou <pengpeng@iscas.ac.cn>
> Sent: Tuesday, June 23, 2026 11:37 AM
> To: Botcha, Mounika <Mounika.Botcha@amd.com>; Jain, Harsh (AECG-SSW)
> <h.jain@amd.com>; Olivia Mackall <olivia@selenic.com>; Herbert Xu
> <herbert@gondor.apana.org.au>; Simek, Michal <michal.simek@amd.com>; linux-
> crypto@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org
> Cc: Pengpeng Hou <pengpeng@iscas.ac.cn>
> Subject: [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read
>
>
> xtrng_readblock32() polls for 16-byte chunks but returns the number of
> bytes read even when the first poll times out. Its caller then treats a
> zero return as a short successful read, and partial reads for full
> 32-byte blocks can make the tail copy use a fixed block offset rather
> than the amount already produced.
>
> Return the poll error when no data has been read, preserve partial
> positive returns after some data is available, stop the generator on all
> collection exits, and append tail bytes at the current output count.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> drivers/char/hw_random/xilinx-trng.c | 32 +++++++++++++++++++++-------
> 1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/char/hw_random/xilinx-trng.c b/drivers/char/hw_random/xilinx-
> trng.c
> index f615d5adddde..4a1a168bb46a 100644
> --- a/drivers/char/hw_random/xilinx-trng.c
> +++ b/drivers/char/hw_random/xilinx-trng.c
> @@ -87,8 +87,8 @@ static void xtrng_softreset(struct xilinx_rng *rng)
> xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
> TRNG_CTRL_PRNGSRST_MASK, 0);
> }
>
> -/* Return no. of bytes read */
> -static size_t xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int
> blocks32, bool wait)
> +/* Return no. of bytes read or a negative error before any data is read. */
> +static int xtrng_readblock32(void __iomem *rng_base, __be32 *buf, int blocks32,
> bool wait)
> {
> int read = 0, ret;
> int timeout = 1;
> @@ -103,8 +103,11 @@ static size_t xtrng_readblock32(void __iomem *rng_base,
> __be32 *buf, int blocks3
> ret = readl_poll_timeout(rng_base + TRNG_STATUS_OFFSET, val,
> (val & TRNG_STATUS_QCNT_MASK) ==
> TRNG_STATUS_QCNT_16_BYTES, !!wait, timeout);
> - if (ret)
> + if (ret) {
> + if (!read)
> + return ret;
> break;
> + }
>
> for (idx = 0; idx < TRNG_READ_4_WORD; idx++) {
> *(buf + read) = cpu_to_be32(ioread32(rng_base +
> TRNG_CORE_OUTPUT_OFFSET));
> @@ -119,27 +122,40 @@ static int xtrng_collect_random_data(struct xilinx_rng
> *rng, u8 *rand_gen_buf,
> {
> u8 randbuf[TRNG_SEC_STRENGTH_BYTES];
> int byteleft, blocks, count = 0;
> + int full_blocks_bytes;
> int ret;
>
> byteleft = no_of_random_bytes & (TRNG_SEC_STRENGTH_BYTES - 1);
> blocks = no_of_random_bytes >> TRNG_SEC_STRENGTH_SHIFT;
> + full_blocks_bytes = blocks * TRNG_SEC_STRENGTH_BYTES;
> xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
> TRNG_CTRL_PRNGSTART_MASK,
> TRNG_CTRL_PRNGSTART_MASK);
> if (blocks) {
> ret = xtrng_readblock32(rng->rng_base, (__be32 *)rand_gen_buf, blocks,
> wait);
> - if (!ret)
> - return 0;
> + if (ret <= 0) {
> + count = ret;
> + goto out_stop;
> + }
> count += ret;
> + if (ret < full_blocks_bytes)
> + goto out_stop;
> }
>
> if (byteleft) {
> ret = xtrng_readblock32(rng->rng_base, (__be32 *)randbuf, 1, wait);
> + if (ret < 0) {
> + if (!count)
> + count = ret;
> + goto out_stop;
> + }
> if (!ret)
> - return count;
> - memcpy(rand_gen_buf + (blocks * TRNG_SEC_STRENGTH_BYTES),
> randbuf, byteleft);
> - count += byteleft;
> + goto out_stop;
> + ret = min(ret, no_of_random_bytes - count);
> + memcpy(rand_gen_buf + count, randbuf, ret);
> + count += ret;
> }
>
> +out_stop:
> xtrng_readwrite32(rng->rng_base + TRNG_CTRL_OFFSET,
> TRNG_CTRL_PRNGMODE_MASK |
> TRNG_CTRL_PRNGSTART_MASK, 0U);
>
> --
> 2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read
2026-06-23 6:07 [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read Pengpeng Hou
2026-07-01 7:31 ` Jain, Harsh (AECG-SSW)
@ 2026-07-05 8:40 ` Herbert Xu
1 sibling, 0 replies; 3+ messages in thread
From: Herbert Xu @ 2026-07-05 8:40 UTC (permalink / raw)
To: Pengpeng Hou
Cc: Mounika Botcha, Harsh Jain, Olivia Mackall, Michal Simek,
linux-crypto, linux-arm-kernel, linux-kernel
On Tue, Jun 23, 2026 at 02:07:27PM +0800, Pengpeng Hou wrote:
> xtrng_readblock32() polls for 16-byte chunks but returns the number of
> bytes read even when the first poll times out. Its caller then treats a
> zero return as a short successful read, and partial reads for full
> 32-byte blocks can make the tail copy use a fixed block offset rather
> than the amount already produced.
>
> Return the poll error when no data has been read, preserve partial
> positive returns after some data is available, stop the generator on all
> collection exits, and append tail bytes at the current output count.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> drivers/char/hw_random/xilinx-trng.c | 32 +++++++++++++++++++++-------
> 1 file changed, 24 insertions(+), 8 deletions(-)
Patch applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-05 8:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-23 6:07 [PATCH] hwrng: xilinx-trng: propagate timeout before any data is read Pengpeng Hou
2026-07-01 7:31 ` Jain, Harsh (AECG-SSW)
2026-07-05 8:40 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox