2023-06-12 08:54:51

by Meenakshi Aggarwal

[permalink] [raw]
Subject: [PATCH] crypto: caam - optimize RNG sample size

From: Meenakshi Aggarwal <[email protected]>

TRNG "sample size" (the total number of entropy samples that will be taken
during entropy generation) default / POR value is very conservatively
set to 2500.

Let's set it to 512, the same as the caam driver in U-boot
(drivers/crypto/fsl_caam.c) does.

This solves the issue of RNG performance dropping after a suspend/resume
cycle on parts where caam loses power, since the initial U-boot setttings
are lost and kernel does not restore them when resuming.

Note: when changing the sample size, the self-test parameters need to be
updated accordingly.

Signed-off-by: Horia Geantă <[email protected]>
Signed-off-by: Meenakshi Aggarwal <[email protected]>
---
drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
drivers/crypto/caam/regs.h | 14 ++++++++--
2 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 62dd069942e4..b06bb64c6c23 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -352,7 +352,7 @@ static void kick_trng(struct device *dev, int ent_delay)
struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
struct caam_ctrl __iomem *ctrl;
struct rng4tst __iomem *r4tst;
- u32 val;
+ u32 val, rtsdctl;

ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
r4tst = &ctrl->r4tst[0];
@@ -368,26 +368,38 @@ static void kick_trng(struct device *dev, int ent_delay)
* Performance-wise, it does not make sense to
* set the delay to a value that is lower
* than the last one that worked (i.e. the state handles
- * were instantiated properly. Thus, instead of wasting
- * time trying to set the values controlling the sample
- * frequency, the function simply returns.
+ * were instantiated properly).
*/
- val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
- >> RTSDCTL_ENT_DLY_SHIFT;
- if (ent_delay <= val)
- goto start_rng;
-
- val = rd_reg32(&r4tst->rtsdctl);
- val = (val & ~RTSDCTL_ENT_DLY_MASK) |
- (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
- wr_reg32(&r4tst->rtsdctl, val);
- /* min. freq. count, equal to 1/4 of the entropy sample length */
- wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
- /* max. freq. count, equal to 16 times the entropy sample length */
- wr_reg32(&r4tst->rtfrqmax, ent_delay << 4);
- /* read the control register */
- val = rd_reg32(&r4tst->rtmctl);
-start_rng:
+ rtsdctl = rd_reg32(&r4tst->rtsdctl);
+ val = (rtsdctl & RTSDCTL_ENT_DLY_MASK) >> RTSDCTL_ENT_DLY_SHIFT;
+ if (ent_delay > val) {
+ val = ent_delay;
+ /* min. freq. count, equal to 1/4 of the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmin, val >> 2);
+ /* max. freq. count, equal to 16 times the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmax, val << 4);
+ }
+
+ wr_reg32(&r4tst->rtsdctl, (val << RTSDCTL_ENT_DLY_SHIFT) |
+ RTSDCTL_SAMP_SIZE_VAL);
+
+ /*
+ * To avoid reprogramming the self-test parameters over and over again,
+ * use RTSDCTL[SAMP_SIZE] as an indicator.
+ */
+ if ((rtsdctl & RTSDCTL_SAMP_SIZE_MASK) != RTSDCTL_SAMP_SIZE_VAL) {
+ wr_reg32(&r4tst->rtscmisc, (2 << 16) | 32);
+ wr_reg32(&r4tst->rtpkrrng, 570);
+ wr_reg32(&r4tst->rtpkrmax, 1600);
+ wr_reg32(&r4tst->rtscml, (122 << 16) | 317);
+ wr_reg32(&r4tst->rtscrl[0], (80 << 16) | 107);
+ wr_reg32(&r4tst->rtscrl[1], (57 << 16) | 62);
+ wr_reg32(&r4tst->rtscrl[2], (39 << 16) | 39);
+ wr_reg32(&r4tst->rtscrl[3], (27 << 16) | 26);
+ wr_reg32(&r4tst->rtscrl[4], (19 << 16) | 18);
+ wr_reg32(&r4tst->rtscrl[5], (18 << 16) | 17);
+ }
+
/*
* select raw sampling in both entropy shifter
* and statistical checker; ; put RNG4 into run mode
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 66928f8a0c4b..189e74c21f0c 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -3,7 +3,7 @@
* CAAM hardware register-level view
*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
+ * Copyright 2018, 2023 NXP
*/

#ifndef REGS_H
@@ -523,6 +523,8 @@ struct rng4tst {
#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
#define RTSDCTL_ENT_DLY_MIN 3200
#define RTSDCTL_ENT_DLY_MAX 12800
+#define RTSDCTL_SAMP_SIZE_MASK 0xffff
+#define RTSDCTL_SAMP_SIZE_VAL 512
u32 rtsdctl; /* seed control register */
union {
u32 rtsblim; /* PRGM=1: sparse bit limit register */
@@ -534,7 +536,15 @@ struct rng4tst {
u32 rtfrqmax; /* PRGM=1: freq. count max. limit register */
u32 rtfrqcnt; /* PRGM=0: freq. count register */
};
- u32 rsvd1[40];
+ union {
+ u32 rtscmc; /* statistical check run monobit count */
+ u32 rtscml; /* statistical check run monobit limit */
+ };
+ union {
+ u32 rtscrc[6]; /* statistical check run length count */
+ u32 rtscrl[6]; /* statistical check run length limit */
+ };
+ u32 rsvd1[33];
#define RDSTA_SKVT 0x80000000
#define RDSTA_SKVN 0x40000000
#define RDSTA_PR0 BIT(4)
--
2.25.1



2023-06-15 12:16:17

by Gaurav Jain

[permalink] [raw]
Subject: RE: [PATCH] crypto: caam - optimize RNG sample size

Reviewed-by: Gaurav Jain <[email protected]>

> -----Original Message-----
> From: Meenakshi Aggarwal <[email protected]>
> Sent: Monday, June 12, 2023 2:01 PM
> To: Horia Geanta <[email protected]>; Varun Sethi <[email protected]>;
> Pankaj Gupta <[email protected]>; Gaurav Jain <[email protected]>;
> [email protected]; [email protected]; linux-
> [email protected]; [email protected]
> Cc: Meenakshi Aggarwal <[email protected]>
> Subject: [PATCH] crypto: caam - optimize RNG sample size
>
> From: Meenakshi Aggarwal <[email protected]>
>
> TRNG "sample size" (the total number of entropy samples that will be taken
> during entropy generation) default / POR value is very conservatively set to 2500.
>
> Let's set it to 512, the same as the caam driver in U-boot
> (drivers/crypto/fsl_caam.c) does.
>
> This solves the issue of RNG performance dropping after a suspend/resume
> cycle on parts where caam loses power, since the initial U-boot setttings are lost
> and kernel does not restore them when resuming.
>
> Note: when changing the sample size, the self-test parameters need to be
> updated accordingly.
>
> Signed-off-by: Horia Geantă <[email protected]>
> Signed-off-by: Meenakshi Aggarwal <[email protected]>
> ---
> drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
> drivers/crypto/caam/regs.h | 14 ++++++++--
> 2 files changed, 44 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index
> 62dd069942e4..b06bb64c6c23 100644
> --- a/drivers/crypto/caam/ctrl.c
> +++ b/drivers/crypto/caam/ctrl.c
> @@ -352,7 +352,7 @@ static void kick_trng(struct device *dev, int ent_delay)
> struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
> struct caam_ctrl __iomem *ctrl;
> struct rng4tst __iomem *r4tst;
> - u32 val;
> + u32 val, rtsdctl;
>
> ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
> r4tst = &ctrl->r4tst[0];
> @@ -368,26 +368,38 @@ static void kick_trng(struct device *dev, int ent_delay)
> * Performance-wise, it does not make sense to
> * set the delay to a value that is lower
> * than the last one that worked (i.e. the state handles
> - * were instantiated properly. Thus, instead of wasting
> - * time trying to set the values controlling the sample
> - * frequency, the function simply returns.
> + * were instantiated properly).
> */
> - val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
> - >> RTSDCTL_ENT_DLY_SHIFT;
> - if (ent_delay <= val)
> - goto start_rng;
> -
> - val = rd_reg32(&r4tst->rtsdctl);
> - val = (val & ~RTSDCTL_ENT_DLY_MASK) |
> - (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
> - wr_reg32(&r4tst->rtsdctl, val);
> - /* min. freq. count, equal to 1/4 of the entropy sample length */
> - wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
> - /* max. freq. count, equal to 16 times the entropy sample length */
> - wr_reg32(&r4tst->rtfrqmax, ent_delay << 4);
> - /* read the control register */
> - val = rd_reg32(&r4tst->rtmctl);
> -start_rng:
> + rtsdctl = rd_reg32(&r4tst->rtsdctl);
> + val = (rtsdctl & RTSDCTL_ENT_DLY_MASK) >> RTSDCTL_ENT_DLY_SHIFT;
> + if (ent_delay > val) {
> + val = ent_delay;
> + /* min. freq. count, equal to 1/4 of the entropy sample length
> */
> + wr_reg32(&r4tst->rtfrqmin, val >> 2);
> + /* max. freq. count, equal to 16 times the entropy sample
> length */
> + wr_reg32(&r4tst->rtfrqmax, val << 4);
> + }
> +
> + wr_reg32(&r4tst->rtsdctl, (val << RTSDCTL_ENT_DLY_SHIFT) |
> + RTSDCTL_SAMP_SIZE_VAL);
> +
> + /*
> + * To avoid reprogramming the self-test parameters over and over again,
> + * use RTSDCTL[SAMP_SIZE] as an indicator.
> + */
> + if ((rtsdctl & RTSDCTL_SAMP_SIZE_MASK) != RTSDCTL_SAMP_SIZE_VAL)
> {
> + wr_reg32(&r4tst->rtscmisc, (2 << 16) | 32);
> + wr_reg32(&r4tst->rtpkrrng, 570);
> + wr_reg32(&r4tst->rtpkrmax, 1600);
> + wr_reg32(&r4tst->rtscml, (122 << 16) | 317);
> + wr_reg32(&r4tst->rtscrl[0], (80 << 16) | 107);
> + wr_reg32(&r4tst->rtscrl[1], (57 << 16) | 62);
> + wr_reg32(&r4tst->rtscrl[2], (39 << 16) | 39);
> + wr_reg32(&r4tst->rtscrl[3], (27 << 16) | 26);
> + wr_reg32(&r4tst->rtscrl[4], (19 << 16) | 18);
> + wr_reg32(&r4tst->rtscrl[5], (18 << 16) | 17);
> + }
> +
> /*
> * select raw sampling in both entropy shifter
> * and statistical checker; ; put RNG4 into run mode diff --git
> a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index
> 66928f8a0c4b..189e74c21f0c 100644
> --- a/drivers/crypto/caam/regs.h
> +++ b/drivers/crypto/caam/regs.h
> @@ -3,7 +3,7 @@
> * CAAM hardware register-level view
> *
> * Copyright 2008-2011 Freescale Semiconductor, Inc.
> - * Copyright 2018 NXP
> + * Copyright 2018, 2023 NXP
> */
>
> #ifndef REGS_H
> @@ -523,6 +523,8 @@ struct rng4tst {
> #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
> #define RTSDCTL_ENT_DLY_MIN 3200 #define RTSDCTL_ENT_DLY_MAX 12800
> +#define RTSDCTL_SAMP_SIZE_MASK 0xffff
> +#define RTSDCTL_SAMP_SIZE_VAL 512
> u32 rtsdctl; /* seed control register */
> union {
> u32 rtsblim; /* PRGM=1: sparse bit limit register */
> @@ -534,7 +536,15 @@ struct rng4tst {
> u32 rtfrqmax; /* PRGM=1: freq. count max. limit register */
> u32 rtfrqcnt; /* PRGM=0: freq. count register */
> };
> - u32 rsvd1[40];
> + union {
> + u32 rtscmc; /* statistical check run monobit count */
> + u32 rtscml; /* statistical check run monobit limit */
> + };
> + union {
> + u32 rtscrc[6]; /* statistical check run length count */
> + u32 rtscrl[6]; /* statistical check run length limit */
> + };
> + u32 rsvd1[33];
> #define RDSTA_SKVT 0x80000000
> #define RDSTA_SKVN 0x40000000
> #define RDSTA_PR0 BIT(4)
> --
> 2.25.1

2023-06-23 08:33:39

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH] crypto: caam - optimize RNG sample size

On Mon, Jun 12, 2023 at 10:30:42AM +0200, [email protected] wrote:
> From: Meenakshi Aggarwal <[email protected]>
>
> TRNG "sample size" (the total number of entropy samples that will be taken
> during entropy generation) default / POR value is very conservatively
> set to 2500.
>
> Let's set it to 512, the same as the caam driver in U-boot
> (drivers/crypto/fsl_caam.c) does.
>
> This solves the issue of RNG performance dropping after a suspend/resume
> cycle on parts where caam loses power, since the initial U-boot setttings
> are lost and kernel does not restore them when resuming.
>
> Note: when changing the sample size, the self-test parameters need to be
> updated accordingly.
>
> Signed-off-by: Horia Geantă <[email protected]>
> Signed-off-by: Meenakshi Aggarwal <[email protected]>
> ---
> drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
> drivers/crypto/caam/regs.h | 14 ++++++++--
> 2 files changed, 44 insertions(+), 22 deletions(-)

Patch applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt