Skip to content

Commit c9e46ca

Browse files
jhovoldGeorgi Djakov
authored andcommitted
interconnect: exynos: fix registration race
The current interconnect provider registration interface is inherently racy as nodes are not added until the after adding the provider. This can specifically cause racing DT lookups to trigger a NULL-pointer deference when either a NULL pointer or not fully initialised node is returned from exynos_generic_icc_xlate(). Switch to using the new API where the provider is not registered until after it has been fully initialised. Fixes: 2f95b9d ("interconnect: Add generic interconnect driver for Exynos SoCs") Cc: [email protected] # 5.11 Cc: Sylwester Nawrocki <[email protected]> Reviewed-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Georgi Djakov <[email protected]>
1 parent 3aab264 commit c9e46ca

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

drivers/interconnect/samsung/exynos.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ static int exynos_generic_icc_remove(struct platform_device *pdev)
9898
struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
9999
struct icc_node *parent_node, *node = priv->node;
100100

101+
icc_provider_deregister(&priv->provider);
102+
101103
parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
102104
if (parent_node && !IS_ERR(parent_node))
103105
icc_link_destroy(node, parent_node);
104106

105107
icc_nodes_remove(&priv->provider);
106-
icc_provider_del(&priv->provider);
107108

108109
return 0;
109110
}
@@ -132,15 +133,11 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
132133
provider->inter_set = true;
133134
provider->data = priv;
134135

135-
ret = icc_provider_add(provider);
136-
if (ret < 0)
137-
return ret;
136+
icc_provider_init(provider);
138137

139138
icc_node = icc_node_create(pdev->id);
140-
if (IS_ERR(icc_node)) {
141-
ret = PTR_ERR(icc_node);
142-
goto err_prov_del;
143-
}
139+
if (IS_ERR(icc_node))
140+
return PTR_ERR(icc_node);
144141

145142
priv->node = icc_node;
146143
icc_node->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
@@ -171,14 +168,17 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
171168
goto err_pmqos_del;
172169
}
173170

171+
ret = icc_provider_register(provider);
172+
if (ret < 0)
173+
goto err_pmqos_del;
174+
174175
return 0;
175176

176177
err_pmqos_del:
177178
dev_pm_qos_remove_request(&priv->qos_req);
178179
err_node_del:
179180
icc_nodes_remove(provider);
180-
err_prov_del:
181-
icc_provider_del(provider);
181+
182182
return ret;
183183
}
184184

0 commit comments

Comments
 (0)