From: Horia GeantA <[email protected]>
RNG (re-)initialization will be needed on pm resume path,
thus refactor the corresponding code out of the probe callback.
Signed-off-by: Horia GeantA <[email protected]>
Signed-off-by: Leonard Crestez <[email protected]>
Signed-off-by: Dong Aisheng <[email protected]>
---
drivers/crypto/caam/ctrl.c | 199 ++++++++++++++++++-----------------
drivers/crypto/caam/intern.h | 1 +
2 files changed, 104 insertions(+), 96 deletions(-)
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 5a6cd63742a4..cf93cfb0eb99 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -342,13 +342,12 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
/*
* kick_trng - sets the various parameters for enabling the initialization
* of the RNG4 block in CAAM
- * @pdev - pointer to the platform device
+ * @dev - pointer to the controller device
* @ent_delay - Defines the length (in system clocks) of each entropy sample.
*/
-static void kick_trng(struct platform_device *pdev, int ent_delay)
+static void kick_trng(struct device *dev, int ent_delay)
{
- struct device *ctrldev = &pdev->dev;
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
struct caam_ctrl __iomem *ctrl;
struct rng4tst __iomem *r4tst;
u32 val;
@@ -589,6 +588,100 @@ static void caam_remove_debugfs(void *root)
debugfs_remove_recursive(root);
}
+static int caam_ctrl_rng_init(struct device *dev)
+{
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
+ int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ u8 rng_vid;
+
+ if (ctrlpriv->era < 10) {
+ struct caam_perfmon __iomem *perfmon;
+
+ perfmon = ctrlpriv->total_jobrs ?
+ (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon :
+ (struct caam_perfmon *)&ctrl->perfmon;
+
+ rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
+ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
+ } else {
+ struct version_regs __iomem *vreg;
+
+ vreg = ctrlpriv->total_jobrs ?
+ (struct version_regs *)&ctrlpriv->jr[0]->vreg :
+ (struct version_regs *)&ctrl->vreg;
+
+ rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
+ CHA_VER_VID_SHIFT;
+ }
+
+ /*
+ * If SEC has RNG version >= 4 and RNG state handle has not been
+ * already instantiated, do RNG instantiation
+ * In case of SoCs with Management Complex, RNG is managed by MC f/w.
+ */
+ if (!(ctrlpriv->mc_en && ctrlpriv->pr_support) && rng_vid >= 4) {
+ ctrlpriv->rng4_sh_init =
+ rd_reg32(&ctrl->r4tst[0].rdsta);
+ /*
+ * If the secure keys (TDKEK, JDKEK, TDSK), were already
+ * generated, signal this to the function that is instantiating
+ * the state handles. An error would occur if RNG4 attempts
+ * to regenerate these keys before the next POR.
+ */
+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+ ctrlpriv->rng4_sh_init &= RDSTA_MASK;
+ do {
+ int inst_handles =
+ rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_MASK;
+ /*
+ * If either SH were instantiated by somebody else
+ * (e.g. u-boot) then it is assumed that the entropy
+ * parameters are properly set and thus the function
+ * setting these (kick_trng(...)) is skipped.
+ * Also, if a handle was instantiated, do not change
+ * the TRNG parameters.
+ */
+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ dev_info(dev,
+ "Entropy delay = %u\n",
+ ent_delay);
+ kick_trng(dev, ent_delay);
+ ent_delay += 400;
+ }
+ /*
+ * if instantiate_rng(...) fails, the loop will rerun
+ * and the kick_trng(...) function will modify the
+ * upper and lower limits of the entropy sampling
+ * interval, leading to a successful initialization of
+ * the RNG.
+ */
+ ret = instantiate_rng(dev, inst_handles,
+ gen_sk);
+ if (ret == -EAGAIN)
+ /*
+ * if here, the loop will rerun,
+ * so don't hog the CPU
+ */
+ cpu_relax();
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
+ if (ret) {
+ dev_err(dev, "failed to instantiate RNG");
+ return ret;
+ }
+ /*
+ * Set handles initialized by this module as the complement of
+ * the already initialized ones
+ */
+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
+
+ /* Enable RDB bit so that RNG works faster */
+ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_FSL_MC_BUS
static bool check_version(struct fsl_mc_version *mc_version, u32 major,
u32 minor, u32 revision)
@@ -619,7 +712,7 @@ static bool needs_entropy_delay_adjustment(void)
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ int ret, ring;
u64 caam_id;
const struct soc_device_attribute *imx_soc_match;
struct device *dev;
@@ -629,10 +722,8 @@ static int caam_probe(struct platform_device *pdev)
struct caam_perfmon __iomem *perfmon;
struct dentry *dfs_root;
u32 scfgr, comp_params;
- u8 rng_vid;
int pg_size;
int BLOCK_OFFSET = 0;
- bool pr_support = false;
bool reg_access = true;
ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);
@@ -768,7 +859,8 @@ static int caam_probe(struct platform_device *pdev)
mc_version = fsl_mc_get_version();
if (mc_version)
- pr_support = check_version(mc_version, 10, 20, 0);
+ ctrlpriv->pr_support = check_version(mc_version, 10, 20,
+ 0);
else
return -EPROBE_DEFER;
}
@@ -858,9 +950,6 @@ static int caam_probe(struct platform_device *pdev)
return -ENOMEM;
}
- if (!reg_access)
- goto report_live;
-
comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ls);
ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB);
@@ -870,101 +959,19 @@ static int caam_probe(struct platform_device *pdev)
* check both here.
*/
if (ctrlpriv->era < 10) {
- rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
- CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
ctrlpriv->blob_present = ctrlpriv->blob_present &&
(rd_reg32(&ctrl->perfmon.cha_num_ls) & CHA_ID_LS_AES_MASK);
} else {
- struct version_regs __iomem *vreg;
-
- vreg = ring ? (struct version_regs *)&ctrlpriv->jr[0]->vreg :
- (struct version_regs *)&ctrl->vreg;
-
- rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
- CHA_VER_VID_SHIFT;
ctrlpriv->blob_present = ctrlpriv->blob_present &&
(rd_reg32(&ctrl->vreg.aesa) & CHA_VER_MISC_AES_NUM_MASK);
}
- /*
- * If SEC has RNG version >= 4 and RNG state handle has not been
- * already instantiated, do RNG instantiation
- * In case of SoCs with Management Complex, RNG is managed by MC f/w.
- */
- if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) {
- ctrlpriv->rng4_sh_init =
- rd_reg32(&ctrl->r4tst[0].rdsta);
- /*
- * If the secure keys (TDKEK, JDKEK, TDSK), were already
- * generated, signal this to the function that is instantiating
- * the state handles. An error would occur if RNG4 attempts
- * to regenerate these keys before the next POR.
- */
- gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
- ctrlpriv->rng4_sh_init &= RDSTA_MASK;
- do {
- int inst_handles =
- rd_reg32(&ctrl->r4tst[0].rdsta) &
- RDSTA_MASK;
- /*
- * If either SH were instantiated by somebody else
- * (e.g. u-boot) then it is assumed that the entropy
- * parameters are properly set and thus the function
- * setting these (kick_trng(...)) is skipped.
- * Also, if a handle was instantiated, do not change
- * the TRNG parameters.
- */
- if (needs_entropy_delay_adjustment())
- ent_delay = 12000;
- if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
- dev_info(dev,
- "Entropy delay = %u\n",
- ent_delay);
- kick_trng(pdev, ent_delay);
- ent_delay += 400;
- }
- /*
- * if instantiate_rng(...) fails, the loop will rerun
- * and the kick_trng(...) function will modify the
- * upper and lower limits of the entropy sampling
- * interval, leading to a successful initialization of
- * the RNG.
- */
- ret = instantiate_rng(dev, inst_handles,
- gen_sk);
- /*
- * Entropy delay is determined via TRNG characterization.
- * TRNG characterization is run across different voltages
- * and temperatures.
- * If worst case value for ent_dly is identified,
- * the loop can be skipped for that platform.
- */
- if (needs_entropy_delay_adjustment())
- break;
- if (ret == -EAGAIN)
- /*
- * if here, the loop will rerun,
- * so don't hog the CPU
- */
- cpu_relax();
- } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
- if (ret) {
- dev_err(dev, "failed to instantiate RNG");
+ if (reg_access) {
+ ret = caam_ctrl_rng_init(dev);
+ if (ret)
return ret;
- }
- /*
- * Set handles initialized by this module as the complement of
- * the already initialized ones
- */
- ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
-
- /* Enable RDB bit so that RNG works faster */
- clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
}
- /* NOTE: RTIC detection ought to go here, around Si time */
-
-report_live:
caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 |
(u64)rd_reg32(&perfmon->caam_id_ls);
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index efe2bc2f1103..a5048605cd67 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -95,6 +95,7 @@ struct caam_drv_private {
u8 blob_present; /* Nonzero if BLOB support present in device */
u8 mc_en; /* Nonzero if MC f/w is active */
u8 optee_en; /* Nonzero if OP-TEE f/w is active */
+ bool pr_support; /* RNG prediction resistance available */
int secvio_irq; /* Security violation interrupt number */
int virt_en; /* Virtualization enabled in CAAM */
int era; /* CAAM Era (internal HW revision) */
--
2.25.1
On Mon, Mar 20, 2023 at 08:38:48AM +0100, [email protected] wrote:
>
> @@ -619,7 +712,7 @@ static bool needs_entropy_delay_adjustment(void)
> /* Probe routine for CAAM top (controller) level */
> static int caam_probe(struct platform_device *pdev)
> {
> - int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
> + int ret, ring;
> u64 caam_id;
> const struct soc_device_attribute *imx_soc_match;
> struct device *dev;
> @@ -629,10 +722,8 @@ static int caam_probe(struct platform_device *pdev)
> struct caam_perfmon __iomem *perfmon;
> struct dentry *dfs_root;
> u32 scfgr, comp_params;
> - u8 rng_vid;
> int pg_size;
> int BLOCK_OFFSET = 0;
> - bool pr_support = false;
> bool reg_access = true;
This patch does not apply against cryptodev. There is no reg_access
in my tree.
Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Horia GeantA <[email protected]>
RNG (re-)initialization will be needed on pm resume path,
thus refactor the corresponding code out of the probe callback.
Signed-off-by: Horia GeantA <[email protected]>
Signed-off-by: Leonard Crestez <[email protected]>
Signed-off-by: Dong Aisheng <[email protected]>
Signed-off-by: Meenakshi Aggarwal <[email protected]>
---
changes in v2:
Rebased on "page 0" patches
NOTE: This patch depends on "page 0" patches, which are under
review on mailing list.
drivers/crypto/caam/ctrl.c | 201 ++++++++++++++++++-----------------
drivers/crypto/caam/intern.h | 1 +
2 files changed, 104 insertions(+), 98 deletions(-)
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 9c5a035e1b96..852d538cfc25 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -342,13 +342,12 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
/*
* kick_trng - sets the various parameters for enabling the initialization
* of the RNG4 block in CAAM
- * @pdev - pointer to the platform device
+ * @dev - pointer to the controller device
* @ent_delay - Defines the length (in system clocks) of each entropy sample.
*/
-static void kick_trng(struct platform_device *pdev, int ent_delay)
+static void kick_trng(struct device *dev, int ent_delay)
{
- struct device *ctrldev = &pdev->dev;
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
struct caam_ctrl __iomem *ctrl;
struct rng4tst __iomem *r4tst;
u32 val;
@@ -589,6 +588,100 @@ static void caam_remove_debugfs(void *root)
debugfs_remove_recursive(root);
}
+static int caam_ctrl_rng_init(struct device *dev)
+{
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
+ int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ u8 rng_vid;
+
+ if (ctrlpriv->era < 10) {
+ struct caam_perfmon __iomem *perfmon;
+
+ perfmon = ctrlpriv->total_jobrs ?
+ (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon :
+ (struct caam_perfmon *)&ctrl->perfmon;
+
+ rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
+ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
+ } else {
+ struct version_regs __iomem *vreg;
+
+ vreg = ctrlpriv->total_jobrs ?
+ (struct version_regs __iomem *)&ctrlpriv->jr[0]->vreg :
+ (struct version_regs __iomem *)&ctrl->vreg;
+
+ rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
+ CHA_VER_VID_SHIFT;
+ }
+
+ /*
+ * If SEC has RNG version >= 4 and RNG state handle has not been
+ * already instantiated, do RNG instantiation
+ * In case of SoCs with Management Complex, RNG is managed by MC f/w.
+ */
+ if (!(ctrlpriv->mc_en && ctrlpriv->pr_support) && rng_vid >= 4) {
+ ctrlpriv->rng4_sh_init =
+ rd_reg32(&ctrl->r4tst[0].rdsta);
+ /*
+ * If the secure keys (TDKEK, JDKEK, TDSK), were already
+ * generated, signal this to the function that is instantiating
+ * the state handles. An error would occur if RNG4 attempts
+ * to regenerate these keys before the next POR.
+ */
+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+ ctrlpriv->rng4_sh_init &= RDSTA_MASK;
+ do {
+ int inst_handles =
+ rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_MASK;
+ /*
+ * If either SH were instantiated by somebody else
+ * (e.g. u-boot) then it is assumed that the entropy
+ * parameters are properly set and thus the function
+ * setting these (kick_trng(...)) is skipped.
+ * Also, if a handle was instantiated, do not change
+ * the TRNG parameters.
+ */
+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ dev_info(dev,
+ "Entropy delay = %u\n",
+ ent_delay);
+ kick_trng(dev, ent_delay);
+ ent_delay += 400;
+ }
+ /*
+ * if instantiate_rng(...) fails, the loop will rerun
+ * and the kick_trng(...) function will modify the
+ * upper and lower limits of the entropy sampling
+ * interval, leading to a successful initialization of
+ * the RNG.
+ */
+ ret = instantiate_rng(dev, inst_handles,
+ gen_sk);
+ if (ret == -EAGAIN)
+ /*
+ * if here, the loop will rerun,
+ * so don't hog the CPU
+ */
+ cpu_relax();
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
+ if (ret) {
+ dev_err(dev, "failed to instantiate RNG");
+ return ret;
+ }
+ /*
+ * Set handles initialized by this module as the complement of
+ * the already initialized ones
+ */
+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
+
+ /* Enable RDB bit so that RNG works faster */
+ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_FSL_MC_BUS
static bool check_version(struct fsl_mc_version *mc_version, u32 major,
u32 minor, u32 revision)
@@ -609,17 +702,10 @@ static bool check_version(struct fsl_mc_version *mc_version, u32 major,
}
#endif
-static bool needs_entropy_delay_adjustment(void)
-{
- if (of_machine_is_compatible("fsl,imx6sx"))
- return true;
- return false;
-}
-
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ int ret, ring;
u64 caam_id;
const struct soc_device_attribute *imx_soc_match;
struct device *dev;
@@ -629,10 +715,8 @@ static int caam_probe(struct platform_device *pdev)
struct caam_perfmon __iomem *perfmon;
struct dentry *dfs_root;
u32 scfgr, comp_params;
- u8 rng_vid;
int pg_size;
int BLOCK_OFFSET = 0;
- bool pr_support = false;
bool reg_access = true;
ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);
@@ -768,7 +852,8 @@ static int caam_probe(struct platform_device *pdev)
mc_version = fsl_mc_get_version();
if (mc_version)
- pr_support = check_version(mc_version, 10, 20, 0);
+ ctrlpriv->pr_support = check_version(mc_version, 10, 20,
+ 0);
else
return -EPROBE_DEFER;
}
@@ -859,9 +944,6 @@ static int caam_probe(struct platform_device *pdev)
return -ENOMEM;
}
- if (!reg_access)
- goto report_live;
-
comp_params = rd_reg32(&perfmon->comp_parms_ls);
ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB);
@@ -871,8 +953,6 @@ static int caam_probe(struct platform_device *pdev)
* check both here.
*/
if (ctrlpriv->era < 10) {
- rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
- CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
ctrlpriv->blob_present = ctrlpriv->blob_present &&
(rd_reg32(&perfmon->cha_num_ls) & CHA_ID_LS_AES_MASK);
} else {
@@ -882,91 +962,16 @@ static int caam_probe(struct platform_device *pdev)
(struct version_regs __iomem *)&ctrlpriv->jr[0]->vreg :
(struct version_regs __iomem *)&ctrl->vreg;
- rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
- CHA_VER_VID_SHIFT;
ctrlpriv->blob_present = ctrlpriv->blob_present &&
(rd_reg32(&vreg->aesa) & CHA_VER_MISC_AES_NUM_MASK);
}
- /*
- * If SEC has RNG version >= 4 and RNG state handle has not been
- * already instantiated, do RNG instantiation
- * In case of SoCs with Management Complex, RNG is managed by MC f/w.
- */
- if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) {
- ctrlpriv->rng4_sh_init =
- rd_reg32(&ctrl->r4tst[0].rdsta);
- /*
- * If the secure keys (TDKEK, JDKEK, TDSK), were already
- * generated, signal this to the function that is instantiating
- * the state handles. An error would occur if RNG4 attempts
- * to regenerate these keys before the next POR.
- */
- gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
- ctrlpriv->rng4_sh_init &= RDSTA_MASK;
- do {
- int inst_handles =
- rd_reg32(&ctrl->r4tst[0].rdsta) &
- RDSTA_MASK;
- /*
- * If either SH were instantiated by somebody else
- * (e.g. u-boot) then it is assumed that the entropy
- * parameters are properly set and thus the function
- * setting these (kick_trng(...)) is skipped.
- * Also, if a handle was instantiated, do not change
- * the TRNG parameters.
- */
- if (needs_entropy_delay_adjustment())
- ent_delay = 12000;
- if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
- dev_info(dev,
- "Entropy delay = %u\n",
- ent_delay);
- kick_trng(pdev, ent_delay);
- ent_delay += 400;
- }
- /*
- * if instantiate_rng(...) fails, the loop will rerun
- * and the kick_trng(...) function will modify the
- * upper and lower limits of the entropy sampling
- * interval, leading to a successful initialization of
- * the RNG.
- */
- ret = instantiate_rng(dev, inst_handles,
- gen_sk);
- /*
- * Entropy delay is determined via TRNG characterization.
- * TRNG characterization is run across different voltages
- * and temperatures.
- * If worst case value for ent_dly is identified,
- * the loop can be skipped for that platform.
- */
- if (needs_entropy_delay_adjustment())
- break;
- if (ret == -EAGAIN)
- /*
- * if here, the loop will rerun,
- * so don't hog the CPU
- */
- cpu_relax();
- } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
- if (ret) {
- dev_err(dev, "failed to instantiate RNG");
+ if (reg_access) {
+ ret = caam_ctrl_rng_init(dev);
+ if (ret)
return ret;
- }
- /*
- * Set handles initialized by this module as the complement of
- * the already initialized ones
- */
- ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
-
- /* Enable RDB bit so that RNG works faster */
- clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
}
-report_live:
- /* NOTE: RTIC detection ought to go here, around Si time */
-
caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 |
(u64)rd_reg32(&perfmon->caam_id_ls);
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 86ed1b91c22d..b4f7bf77f487 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -95,6 +95,7 @@ struct caam_drv_private {
u8 blob_present; /* Nonzero if BLOB support present in device */
u8 mc_en; /* Nonzero if MC f/w is active */
u8 optee_en; /* Nonzero if OP-TEE f/w is active */
+ bool pr_support; /* RNG prediction resistance available */
int secvio_irq; /* Security violation interrupt number */
int virt_en; /* Virtualization enabled in CAAM */
int era; /* CAAM Era (internal HW revision) */
--
2.25.1
HI
> -----Original Message-----
> From: Meenakshi Aggarwal <[email protected]>
> Sent: Wednesday, April 5, 2023 4:03 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];
> [email protected]; Aisheng Dong <[email protected]>
> Cc: Meenakshi Aggarwal <[email protected]>
> Subject: [PATCH v2] crypto: caam - refactor RNG initialization
>
> From: Horia GeantA <[email protected]>
>
> RNG (re-)initialization will be needed on pm resume path, thus refactor the
> corresponding code out of the probe callback.
>
> Signed-off-by: Horia GeantA <[email protected]>
> Signed-off-by: Leonard Crestez <[email protected]>
> Signed-off-by: Dong Aisheng <[email protected]>
> Signed-off-by: Meenakshi Aggarwal <[email protected]>
> ---
> changes in v2:
> Rebased on "page 0" patches
>
> NOTE: This patch depends on "page 0" patches, which are under review on
> mailing list.
>
> drivers/crypto/caam/ctrl.c | 201 ++++++++++++++++++-----------------
> drivers/crypto/caam/intern.h | 1 +
> 2 files changed, 104 insertions(+), 98 deletions(-)
>
> diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index
> 9c5a035e1b96..852d538cfc25 100644
> --- a/drivers/crypto/caam/ctrl.c
> +++ b/drivers/crypto/caam/ctrl.c
> @@ -342,13 +342,12 @@ static int instantiate_rng(struct device *ctrldev, int
> state_handle_mask,
> /*
> * kick_trng - sets the various parameters for enabling the initialization
> * of the RNG4 block in CAAM
> - * @pdev - pointer to the platform device
> + * @dev - pointer to the controller device
> * @ent_delay - Defines the length (in system clocks) of each entropy sample.
> */
> -static void kick_trng(struct platform_device *pdev, int ent_delay)
> +static void kick_trng(struct device *dev, int ent_delay)
> {
> - struct device *ctrldev = &pdev->dev;
> - struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
> + struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
> struct caam_ctrl __iomem *ctrl;
> struct rng4tst __iomem *r4tst;
> u32 val;
> @@ -589,6 +588,100 @@ static void caam_remove_debugfs(void *root)
> debugfs_remove_recursive(root);
> }
>
> +static int caam_ctrl_rng_init(struct device *dev) {
> + struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
> + struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
> + int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
> + u8 rng_vid;
> +
> + if (ctrlpriv->era < 10) {
> + struct caam_perfmon __iomem *perfmon;
> +
> + perfmon = ctrlpriv->total_jobrs ?
> + (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon :
> + (struct caam_perfmon *)&ctrl->perfmon;
> +
> + rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
> + CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
> + } else {
> + struct version_regs __iomem *vreg;
> +
> + vreg = ctrlpriv->total_jobrs ?
> + (struct version_regs __iomem *)&ctrlpriv->jr[0]->vreg :
> + (struct version_regs __iomem *)&ctrl->vreg;
> +
> + rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
> + CHA_VER_VID_SHIFT;
> + }
> +
> + /*
> + * If SEC has RNG version >= 4 and RNG state handle has not been
> + * already instantiated, do RNG instantiation
> + * In case of SoCs with Management Complex, RNG is managed by MC
> f/w.
> + */
> + if (!(ctrlpriv->mc_en && ctrlpriv->pr_support) && rng_vid >= 4) {
> + ctrlpriv->rng4_sh_init =
> + rd_reg32(&ctrl->r4tst[0].rdsta);
> + /*
> + * If the secure keys (TDKEK, JDKEK, TDSK), were already
> + * generated, signal this to the function that is instantiating
> + * the state handles. An error would occur if RNG4 attempts
> + * to regenerate these keys before the next POR.
> + */
> + gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
> + ctrlpriv->rng4_sh_init &= RDSTA_MASK;
> + do {
> + int inst_handles =
> + rd_reg32(&ctrl->r4tst[0].rdsta) & RDSTA_MASK;
> + /*
> + * If either SH were instantiated by somebody else
> + * (e.g. u-boot) then it is assumed that the entropy
> + * parameters are properly set and thus the function
> + * setting these (kick_trng(...)) is skipped.
> + * Also, if a handle was instantiated, do not change
> + * the TRNG parameters.
> + */
> + if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
> + dev_info(dev,
> + "Entropy delay = %u\n",
> + ent_delay);
> + kick_trng(dev, ent_delay);
> + ent_delay += 400;
> + }
> + /*
> + * if instantiate_rng(...) fails, the loop will rerun
> + * and the kick_trng(...) function will modify the
> + * upper and lower limits of the entropy sampling
> + * interval, leading to a successful initialization of
> + * the RNG.
> + */
> + ret = instantiate_rng(dev, inst_handles,
> + gen_sk);
> + if (ret == -EAGAIN)
> + /*
> + * if here, the loop will rerun,
> + * so don't hog the CPU
> + */
> + cpu_relax();
> + } while ((ret == -EAGAIN) && (ent_delay <
> RTSDCTL_ENT_DLY_MAX));
> + if (ret) {
> + dev_err(dev, "failed to instantiate RNG");
> + return ret;
> + }
> + /*
> + * Set handles initialized by this module as the complement of
> + * the already initialized ones
> + */
> + ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
> +
> + /* Enable RDB bit so that RNG works faster */
> + clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
> + }
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_FSL_MC_BUS
> static bool check_version(struct fsl_mc_version *mc_version, u32 major,
> u32 minor, u32 revision)
> @@ -609,17 +702,10 @@ static bool check_version(struct fsl_mc_version
> *mc_version, u32 major, } #endif
>
> -static bool needs_entropy_delay_adjustment(void)
> -{
> - if (of_machine_is_compatible("fsl,imx6sx"))
> - return true;
> - return false;
> -}
This will break the RNG on i.MX6SX platform.
Please rework this.
Regards
Gaurav Jain
> -
> /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct
> platform_device *pdev) {
> - int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
> + int ret, ring;
> u64 caam_id;
> const struct soc_device_attribute *imx_soc_match;
> struct device *dev;
> @@ -629,10 +715,8 @@ static int caam_probe(struct platform_device *pdev)
> struct caam_perfmon __iomem *perfmon;
> struct dentry *dfs_root;
> u32 scfgr, comp_params;
> - u8 rng_vid;
> int pg_size;
> int BLOCK_OFFSET = 0;
> - bool pr_support = false;
> bool reg_access = true;
>
> ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL);
> @@ -768,7 +852,8 @@ static int caam_probe(struct platform_device *pdev)
>
> mc_version = fsl_mc_get_version();
> if (mc_version)
> - pr_support = check_version(mc_version, 10, 20, 0);
> + ctrlpriv->pr_support = check_version(mc_version, 10,
> 20,
> + 0);
> else
> return -EPROBE_DEFER;
> }
> @@ -859,9 +944,6 @@ static int caam_probe(struct platform_device *pdev)
> return -ENOMEM;
> }
>
> - if (!reg_access)
> - goto report_live;
> -
> comp_params = rd_reg32(&perfmon->comp_parms_ls);
> ctrlpriv->blob_present = !!(comp_params & CTPR_LS_BLOB);
>
> @@ -871,8 +953,6 @@ static int caam_probe(struct platform_device *pdev)
> * check both here.
> */
> if (ctrlpriv->era < 10) {
> - rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
> - CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
> ctrlpriv->blob_present = ctrlpriv->blob_present &&
> (rd_reg32(&perfmon->cha_num_ls) &
> CHA_ID_LS_AES_MASK);
> } else {
> @@ -882,91 +962,16 @@ static int caam_probe(struct platform_device *pdev)
> (struct version_regs __iomem *)&ctrlpriv->jr[0]->vreg :
> (struct version_regs __iomem *)&ctrl->vreg;
>
> - rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
> - CHA_VER_VID_SHIFT;
> ctrlpriv->blob_present = ctrlpriv->blob_present &&
> (rd_reg32(&vreg->aesa) &
> CHA_VER_MISC_AES_NUM_MASK);
> }
>
> - /*
> - * If SEC has RNG version >= 4 and RNG state handle has not been
> - * already instantiated, do RNG instantiation
> - * In case of SoCs with Management Complex, RNG is managed by MC
> f/w.
> - */
> - if (!(ctrlpriv->mc_en && pr_support) && rng_vid >= 4) {
> - ctrlpriv->rng4_sh_init =
> - rd_reg32(&ctrl->r4tst[0].rdsta);
> - /*
> - * If the secure keys (TDKEK, JDKEK, TDSK), were already
> - * generated, signal this to the function that is instantiating
> - * the state handles. An error would occur if RNG4 attempts
> - * to regenerate these keys before the next POR.
> - */
> - gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
> - ctrlpriv->rng4_sh_init &= RDSTA_MASK;
> - do {
> - int inst_handles =
> - rd_reg32(&ctrl->r4tst[0].rdsta) &
> - RDSTA_MASK;
> - /*
> - * If either SH were instantiated by somebody else
> - * (e.g. u-boot) then it is assumed that the entropy
> - * parameters are properly set and thus the function
> - * setting these (kick_trng(...)) is skipped.
> - * Also, if a handle was instantiated, do not change
> - * the TRNG parameters.
> - */
> - if (needs_entropy_delay_adjustment())
> - ent_delay = 12000;
> - if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
> - dev_info(dev,
> - "Entropy delay = %u\n",
> - ent_delay);
> - kick_trng(pdev, ent_delay);
> - ent_delay += 400;
> - }
> - /*
> - * if instantiate_rng(...) fails, the loop will rerun
> - * and the kick_trng(...) function will modify the
> - * upper and lower limits of the entropy sampling
> - * interval, leading to a successful initialization of
> - * the RNG.
> - */
> - ret = instantiate_rng(dev, inst_handles,
> - gen_sk);
> - /*
> - * Entropy delay is determined via TRNG
> characterization.
> - * TRNG characterization is run across different
> voltages
> - * and temperatures.
> - * If worst case value for ent_dly is identified,
> - * the loop can be skipped for that platform.
> - */
> - if (needs_entropy_delay_adjustment())
> - break;
> - if (ret == -EAGAIN)
> - /*
> - * if here, the loop will rerun,
> - * so don't hog the CPU
> - */
> - cpu_relax();
> - } while ((ret == -EAGAIN) && (ent_delay <
> RTSDCTL_ENT_DLY_MAX));
> - if (ret) {
> - dev_err(dev, "failed to instantiate RNG");
> + if (reg_access) {
> + ret = caam_ctrl_rng_init(dev);
> + if (ret)
> return ret;
> - }
> - /*
> - * Set handles initialized by this module as the complement of
> - * the already initialized ones
> - */
> - ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
> -
> - /* Enable RDB bit so that RNG works faster */
> - clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
> }
>
> -report_live:
> - /* NOTE: RTIC detection ought to go here, around Si time */
> -
> caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 |
> (u64)rd_reg32(&perfmon->caam_id_ls);
>
> diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index
> 86ed1b91c22d..b4f7bf77f487 100644
> --- a/drivers/crypto/caam/intern.h
> +++ b/drivers/crypto/caam/intern.h
> @@ -95,6 +95,7 @@ struct caam_drv_private {
> u8 blob_present; /* Nonzero if BLOB support present in device */
> u8 mc_en; /* Nonzero if MC f/w is active */
> u8 optee_en; /* Nonzero if OP-TEE f/w is active */
> + bool pr_support; /* RNG prediction resistance available */
> int secvio_irq; /* Security violation interrupt number */
> int virt_en; /* Virtualization enabled in CAAM */
> int era; /* CAAM Era (internal HW revision) */
> --
> 2.25.1