Skip to content

Commit

Permalink
crypto: ccree - fix resume race condition on init
Browse files Browse the repository at this point in the history
We were enabling autosuspend, which is using data set by the
hash module, prior to the hash module being inited, casuing
a crash on resume as part of the startup sequence if the race
was lost.

This was never a real problem because the PM infra was using low
res timers so we were always winning the race, until commit 8234f67
("PM-runtime: Switch autosuspend over to using hrtimers") changed that :-)

Fix this by seperating the PM setup and enablement and doing the
latter only at the end of the init sequence.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: stable@kernel.org # v4.20
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Gilad Ben-Yossef authored and Herbert Xu committed Feb 8, 2019
1 parent 356690d commit 1358c13
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
7 changes: 4 additions & 3 deletions drivers/crypto/ccree/cc_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static int init_cc_resources(struct platform_device *plat_dev)
rc = cc_ivgen_init(new_drvdata);
if (rc) {
dev_err(dev, "cc_ivgen_init failed\n");
goto post_power_mgr_err;
goto post_buf_mgr_err;
}

/* Allocate crypto algs */
Expand All @@ -403,6 +403,9 @@ static int init_cc_resources(struct platform_device *plat_dev)
goto post_hash_err;
}

/* All set, we can allow autosuspend */
cc_pm_go(new_drvdata);

/* If we got here and FIPS mode is enabled
* it means all FIPS test passed, so let TEE
* know we're good.
Expand All @@ -417,8 +420,6 @@ static int init_cc_resources(struct platform_device *plat_dev)
cc_cipher_free(new_drvdata);
post_ivgen_err:
cc_ivgen_fini(new_drvdata);
post_power_mgr_err:
cc_pm_fini(new_drvdata);
post_buf_mgr_err:
cc_buffer_mgr_fini(new_drvdata);
post_req_mgr_err:
Expand Down
13 changes: 6 additions & 7 deletions drivers/crypto/ccree/cc_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,19 @@ int cc_pm_put_suspend(struct device *dev)

int cc_pm_init(struct cc_drvdata *drvdata)
{
int rc = 0;
struct device *dev = drvdata_to_dev(drvdata);

/* must be before the enabling to avoid resdundent suspending */
pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(dev);
/* activate the PM module */
rc = pm_runtime_set_active(dev);
if (rc)
return rc;
/* enable the PM module*/
pm_runtime_enable(dev);
return pm_runtime_set_active(dev);
}

return rc;
/* enable the PM module*/
void cc_pm_go(struct cc_drvdata *drvdata)
{
pm_runtime_enable(drvdata_to_dev(drvdata));
}

void cc_pm_fini(struct cc_drvdata *drvdata)
Expand Down
3 changes: 3 additions & 0 deletions drivers/crypto/ccree/cc_pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
extern const struct dev_pm_ops ccree_pm;

int cc_pm_init(struct cc_drvdata *drvdata);
void cc_pm_go(struct cc_drvdata *drvdata);
void cc_pm_fini(struct cc_drvdata *drvdata);
int cc_pm_suspend(struct device *dev);
int cc_pm_resume(struct device *dev);
Expand All @@ -29,6 +30,8 @@ static inline int cc_pm_init(struct cc_drvdata *drvdata)
return 0;
}

static void cc_pm_go(struct cc_drvdata *drvdata) {}

static inline void cc_pm_fini(struct cc_drvdata *drvdata) {}

static inline int cc_pm_suspend(struct device *dev)
Expand Down

0 comments on commit 1358c13

Please sign in to comment.