Skip to content

Commit 263d12b

Browse files
marcanjannau
authored andcommitted
macsmc: Fix race between backend and core on notifications
The core enables notifications (NTAP) before returning from the probe function, before the backend has a chance to set smc->core. This leads to a race if a notification arrives early. We already rely on the core setting the drvdata to itself, so move that ahead of NTAP=1 and drop smc->core entirely. That way it's safe for the backend notification callback to fire before the core probe function returns. Signed-off-by: Hector Martin <[email protected]>
1 parent 5e4858c commit 263d12b

File tree

3 files changed

+14
-17
lines changed

3 files changed

+14
-17
lines changed

drivers/platform/apple/smc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ struct apple_smc_backend_ops {
1919
int (*get_key_info)(void *cookie, smc_key key, struct apple_smc_key_info *info);
2020
};
2121

22-
struct apple_smc *apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops,
23-
void *cookie);
22+
int apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops, void *cookie);
2423
void *apple_smc_get_cookie(struct apple_smc *smc);
2524
int apple_smc_remove(struct apple_smc *smc);
2625
void apple_smc_event_received(struct apple_smc *smc, uint32_t event);

drivers/platform/apple/smc_core.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,15 +236,15 @@ void *apple_smc_get_cookie(struct apple_smc *smc)
236236
}
237237
EXPORT_SYMBOL(apple_smc_get_cookie);
238238

239-
struct apple_smc *apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops, void *cookie)
239+
int apple_smc_probe(struct device *dev, const struct apple_smc_backend_ops *ops, void *cookie)
240240
{
241241
struct apple_smc *smc;
242242
u32 count;
243243
int ret;
244244

245245
smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL);
246246
if (!smc)
247-
return ERR_PTR(-ENOMEM);
247+
return -ENOMEM;
248248

249249
smc->dev = dev;
250250
smc->be_cookie = cookie;
@@ -254,30 +254,30 @@ struct apple_smc *apple_smc_probe(struct device *dev, const struct apple_smc_bac
254254

255255
ret = apple_smc_read_u32(smc, SMC_KEY(#KEY), &count);
256256
if (ret)
257-
return ERR_PTR(dev_err_probe(dev, ret, "Failed to get key count"));
257+
return dev_err_probe(dev, ret, "Failed to get key count");
258258
smc->key_count = be32_to_cpu(count);
259259

260260
ret = apple_smc_get_key_by_index(smc, 0, &smc->first_key);
261261
if (ret)
262-
return ERR_PTR(dev_err_probe(dev, ret, "Failed to get first key"));
262+
return dev_err_probe(dev, ret, "Failed to get first key");
263263

264264
ret = apple_smc_get_key_by_index(smc, smc->key_count - 1, &smc->last_key);
265265
if (ret)
266-
return ERR_PTR(dev_err_probe(dev, ret, "Failed to get last key"));
266+
return dev_err_probe(dev, ret, "Failed to get last key");
267+
268+
dev_set_drvdata(dev, smc);
267269

268270
/* Enable notifications */
269271
apple_smc_write_flag(smc, SMC_KEY(NTAP), 1);
270272

271273
dev_info(dev, "Initialized (%d keys %p4ch..%p4ch)\n",
272274
smc->key_count, &smc->first_key, &smc->last_key);
273275

274-
dev_set_drvdata(dev, smc);
275-
276276
ret = mfd_add_devices(dev, -1, apple_smc_devs, ARRAY_SIZE(apple_smc_devs), NULL, 0, NULL);
277277
if (ret)
278-
return ERR_PTR(dev_err_probe(dev, ret, "Subdevice initialization failed"));
278+
return dev_err_probe(dev, ret, "Subdevice initialization failed");
279279

280-
return smc;
280+
return 0;
281281
}
282282
EXPORT_SYMBOL(apple_smc_probe);
283283

drivers/platform/apple/smc_rtkit.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040

4141
struct apple_smc_rtkit {
4242
struct device *dev;
43-
struct apple_smc *core;
4443
struct apple_rtkit *rtk;
4544

4645
struct completion init_done;
@@ -321,6 +320,7 @@ static bool apple_smc_rtkit_recv_early(void *cookie, u8 endpoint, u64 message)
321320
static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64 message)
322321
{
323322
struct apple_smc_rtkit *smc = cookie;
323+
struct apple_smc *core = dev_get_drvdata(smc->dev);
324324

325325
if (endpoint != SMC_ENDPOINT) {
326326
dev_err(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint);
@@ -332,7 +332,7 @@ static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64 message)
332332
return;
333333
}
334334

335-
apple_smc_event_received(smc->core, FIELD_GET(SMC_DATA, message));
335+
apple_smc_event_received(core, FIELD_GET(SMC_DATA, message));
336336
}
337337

338338
static const struct apple_rtkit_ops apple_smc_rtkit_ops = {
@@ -403,11 +403,9 @@ static int apple_smc_rtkit_probe(struct platform_device *pdev)
403403
goto cleanup;
404404
}
405405

406-
smc->core = apple_smc_probe(dev, &apple_smc_rtkit_be_ops, smc);
407-
if (IS_ERR(smc->core)) {
408-
ret = PTR_ERR(smc->core);
406+
ret = apple_smc_probe(dev, &apple_smc_rtkit_be_ops, smc);
407+
if (ret)
409408
goto cleanup;
410-
}
411409

412410
return 0;
413411

0 commit comments

Comments
 (0)