[PATCH] hwrng: xilinx-trng: propagate timeout before any data is read
Jain, Harsh (AECG-SSW)
h.jain at amd.com
Wed Jul 1 00:31:29 PDT 2026
AMD General
Reviewed-by : Harsh Jain <h.jain at amd.com>
> -----Original Message-----
> From: Pengpeng Hou <pengpeng at iscas.ac.cn>
> Sent: Tuesday, June 23, 2026 11:37 AM
> To: Botcha, Mounika <Mounika.Botcha at amd.com>; Jain, Harsh (AECG-SSW)
> <h.jain at amd.com>; Olivia Mackall <olivia at selenic.com>; Herbert Xu
> <herbert at gondor.apana.org.au>; Simek, Michal <michal.simek at amd.com>; linux-
> crypto at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org
> Cc: Pengpeng Hou <pengpeng at 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 at 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)
More information about the linux-arm-kernel
mailing list