Skip to content

Commit 15fd256

Browse files
Gilad Ben-Yossefherbertx
authored andcommitted
crypto: ccree - fix PM race condition
The PM code was racy, possibly causing the driver to submit requests to a powered down device. Fix the race and while at it simplify the PM code. Signed-off-by: Gilad Ben-Yossef <[email protected]> Fixes: 1358c13 ("crypto: ccree - fix resume race condition on init") Cc: [email protected] # v4.20 Signed-off-by: Herbert Xu <[email protected]>
1 parent 5c83e8e commit 15fd256

File tree

4 files changed

+7
-80
lines changed

4 files changed

+7
-80
lines changed

drivers/crypto/ccree/cc_driver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct cc_drvdata {
160160
int std_bodies;
161161
bool sec_disabled;
162162
u32 comp_mask;
163+
bool pm_on;
163164
};
164165

165166
struct cc_crypto_alg {

drivers/crypto/ccree/cc_pm.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,8 @@ const struct dev_pm_ops ccree_pm = {
2222
int cc_pm_suspend(struct device *dev)
2323
{
2424
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
25-
int rc;
2625

2726
dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
28-
rc = cc_suspend_req_queue(drvdata);
29-
if (rc) {
30-
dev_err(dev, "cc_suspend_req_queue (%x)\n", rc);
31-
return rc;
32-
}
3327
fini_cc_regs(drvdata);
3428
cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE);
3529
cc_clk_off(drvdata);
@@ -63,13 +57,6 @@ int cc_pm_resume(struct device *dev)
6357
/* check if tee fips error occurred during power down */
6458
cc_tee_handle_fips_error(drvdata);
6559

66-
rc = cc_resume_req_queue(drvdata);
67-
if (rc) {
68-
dev_err(dev, "cc_resume_req_queue (%x)\n", rc);
69-
return rc;
70-
}
71-
72-
/* must be after the queue resuming as it uses the HW queue*/
7360
cc_init_hash_sram(drvdata);
7461

7562
return 0;
@@ -80,10 +67,8 @@ int cc_pm_get(struct device *dev)
8067
int rc = 0;
8168
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
8269

83-
if (cc_req_queue_suspended(drvdata))
70+
if (drvdata->pm_on)
8471
rc = pm_runtime_get_sync(dev);
85-
else
86-
pm_runtime_get_noresume(dev);
8772

8873
return (rc == 1 ? 0 : rc);
8974
}
@@ -93,14 +78,11 @@ int cc_pm_put_suspend(struct device *dev)
9378
int rc = 0;
9479
struct cc_drvdata *drvdata = dev_get_drvdata(dev);
9580

96-
if (!cc_req_queue_suspended(drvdata)) {
81+
if (drvdata->pm_on) {
9782
pm_runtime_mark_last_busy(dev);
9883
rc = pm_runtime_put_autosuspend(dev);
99-
} else {
100-
/* Something wrong happens*/
101-
dev_err(dev, "request to suspend already suspended queue");
102-
rc = -EBUSY;
10384
}
85+
10486
return rc;
10587
}
10688

@@ -117,17 +99,19 @@ int cc_pm_init(struct cc_drvdata *drvdata)
11799
/* must be before the enabling to avoid redundant suspending */
118100
pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT);
119101
pm_runtime_use_autosuspend(dev);
120-
/* activate the PM module */
102+
/* set us as active - note we won't do PM ops until cc_pm_go()! */
121103
return pm_runtime_set_active(dev);
122104
}
123105

124106
/* enable the PM module*/
125107
void cc_pm_go(struct cc_drvdata *drvdata)
126108
{
127109
pm_runtime_enable(drvdata_to_dev(drvdata));
110+
drvdata->pm_on = true;
128111
}
129112

130113
void cc_pm_fini(struct cc_drvdata *drvdata)
131114
{
132115
pm_runtime_disable(drvdata_to_dev(drvdata));
116+
drvdata->pm_on = false;
133117
}

drivers/crypto/ccree/cc_request_mgr.c

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ struct cc_req_mgr_handle {
4141
#else
4242
struct tasklet_struct comptask;
4343
#endif
44-
bool is_runtime_suspended;
4544
};
4645

4746
struct cc_bl_item {
@@ -664,52 +663,3 @@ static void comp_handler(unsigned long devarg)
664663
cc_proc_backlog(drvdata);
665664
dev_dbg(dev, "Comp. handler done.\n");
666665
}
667-
668-
/*
669-
* resume the queue configuration - no need to take the lock as this happens
670-
* inside the spin lock protection
671-
*/
672-
#if defined(CONFIG_PM)
673-
int cc_resume_req_queue(struct cc_drvdata *drvdata)
674-
{
675-
struct cc_req_mgr_handle *request_mgr_handle =
676-
drvdata->request_mgr_handle;
677-
678-
spin_lock_bh(&request_mgr_handle->hw_lock);
679-
request_mgr_handle->is_runtime_suspended = false;
680-
spin_unlock_bh(&request_mgr_handle->hw_lock);
681-
682-
return 0;
683-
}
684-
685-
/*
686-
* suspend the queue configuration. Since it is used for the runtime suspend
687-
* only verify that the queue can be suspended.
688-
*/
689-
int cc_suspend_req_queue(struct cc_drvdata *drvdata)
690-
{
691-
struct cc_req_mgr_handle *request_mgr_handle =
692-
drvdata->request_mgr_handle;
693-
694-
/* lock the send_request */
695-
spin_lock_bh(&request_mgr_handle->hw_lock);
696-
if (request_mgr_handle->req_queue_head !=
697-
request_mgr_handle->req_queue_tail) {
698-
spin_unlock_bh(&request_mgr_handle->hw_lock);
699-
return -EBUSY;
700-
}
701-
request_mgr_handle->is_runtime_suspended = true;
702-
spin_unlock_bh(&request_mgr_handle->hw_lock);
703-
704-
return 0;
705-
}
706-
707-
bool cc_req_queue_suspended(struct cc_drvdata *drvdata)
708-
{
709-
struct cc_req_mgr_handle *request_mgr_handle =
710-
drvdata->request_mgr_handle;
711-
712-
return request_mgr_handle->is_runtime_suspended;
713-
}
714-
715-
#endif

drivers/crypto/ccree/cc_request_mgr.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,4 @@ void complete_request(struct cc_drvdata *drvdata);
4040

4141
void cc_req_mgr_fini(struct cc_drvdata *drvdata);
4242

43-
#if defined(CONFIG_PM)
44-
int cc_resume_req_queue(struct cc_drvdata *drvdata);
45-
46-
int cc_suspend_req_queue(struct cc_drvdata *drvdata);
47-
48-
bool cc_req_queue_suspended(struct cc_drvdata *drvdata);
49-
#endif
50-
5143
#endif /*__REQUEST_MGR_H__*/

0 commit comments

Comments
 (0)