Skip to content

Commit e4f949e

Browse files
ipylypivmartinkpetersen
authored andcommitted
scsi: pm80xx: Set phy->enable_completion only when we wait for it
pm8001_phy_control() populates the enable_completion pointer with a stack address, sends a PHY_LINK_RESET / PHY_HARD_RESET, waits 300 ms, and returns. The problem arises when a phy control response comes late. After 300 ms the pm8001_phy_control() function returns and the passed enable_completion stack address is no longer valid. Late phy control response invokes complete() on a dangling enable_completion pointer which leads to a kernel crash. Signed-off-by: Igor Pylypiv <[email protected]> Signed-off-by: Terrence Adams <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Jack Wang <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 7cbff57 commit e4f949e

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/scsi/pm8001/pm8001_sas.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
166166
unsigned long flags;
167167
pm8001_ha = sas_phy->ha->lldd_ha;
168168
phy = &pm8001_ha->phy[phy_id];
169-
pm8001_ha->phy[phy_id].enable_completion = &completion;
170169

171170
if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) {
172171
/*
@@ -190,6 +189,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
190189
rates->maximum_linkrate;
191190
}
192191
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
192+
pm8001_ha->phy[phy_id].enable_completion = &completion;
193193
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
194194
wait_for_completion(&completion);
195195
}
@@ -198,6 +198,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
198198
break;
199199
case PHY_FUNC_HARD_RESET:
200200
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
201+
pm8001_ha->phy[phy_id].enable_completion = &completion;
201202
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
202203
wait_for_completion(&completion);
203204
}
@@ -206,6 +207,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
206207
break;
207208
case PHY_FUNC_LINK_RESET:
208209
if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) {
210+
pm8001_ha->phy[phy_id].enable_completion = &completion;
209211
PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id);
210212
wait_for_completion(&completion);
211213
}

0 commit comments

Comments
 (0)