Skip to content

Commit d1aae06

Browse files
committed
clk: starfive: Avoid casting iomem pointers
Let's use a wrapper struct for the auxiliary_device made in jh7110_reset_controller_register() so that we can stop casting iomem pointers. The casts trip up tools like sparse, and make for some awkward casts that are largely unnecessary. While we're here, change the allocation from devm and actually free the auxiliary_device memory in the release function. This avoids any use after free problems where the parent device driver is unbound from the device but the auxiliuary_device is still in use accessing devm freed memory. Cc: Tommaso Merciai <tomm.merciai@gmail.com> Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com> Cc: Hal Feng <hal.feng@starfivetech.com> Cc: Conor Dooley <conor.dooley@microchip.com> Cc: Xingyu Wu <xingyu.wu@starfivetech.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Fixes: edab720 ("clk: starfive: Add StarFive JH7110 system clock driver") Signed-off-by: Stephen Boyd <sboyd@kernel.org> Link: https://lore.kernel.org/r/20230413205528.4044216-1-sboyd@kernel.org
1 parent 601e5d4 commit d1aae06

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

drivers/clk/starfive/clk-starfive-jh7110-sys.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include <linux/init.h>
1212
#include <linux/io.h>
1313
#include <linux/platform_device.h>
14+
#include <linux/slab.h>
15+
16+
#include <soc/starfive/reset-starfive-jh71x0.h>
1417

1518
#include <dt-bindings/clock/starfive,jh7110-crg.h>
1619

@@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev(void *_adev)
335338
struct auxiliary_device *adev = _adev;
336339

337340
auxiliary_device_delete(adev);
341+
auxiliary_device_uninit(adev);
338342
}
339343

340344
static void jh7110_reset_adev_release(struct device *dev)
341345
{
342346
struct auxiliary_device *adev = to_auxiliary_dev(dev);
347+
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
343348

344-
auxiliary_device_uninit(adev);
349+
kfree(rdev);
345350
}
346351

347352
int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
348353
const char *adev_name,
349354
u32 adev_id)
350355
{
356+
struct jh71x0_reset_adev *rdev;
351357
struct auxiliary_device *adev;
352358
int ret;
353359

354-
adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
355-
if (!adev)
360+
rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
361+
if (!rdev)
356362
return -ENOMEM;
357363

364+
rdev->base = priv->base;
365+
366+
adev = &rdev->adev;
358367
adev->name = adev_name;
359368
adev->dev.parent = priv->dev;
360369
adev->dev.release = jh7110_reset_adev_release;

drivers/reset/starfive/reset-starfive-jh7110.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include <linux/auxiliary_bus.h>
99

10+
#include <soc/starfive/reset-starfive-jh71x0.h>
11+
1012
#include "reset-starfive-jh71x0.h"
1113

1214
#include <dt-bindings/reset/starfive,jh7110-crg.h>
@@ -33,14 +35,15 @@ static int jh7110_reset_probe(struct auxiliary_device *adev,
3335
const struct auxiliary_device_id *id)
3436
{
3537
struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
36-
void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
38+
struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
39+
void __iomem *base = rdev->base;
3740

3841
if (!info || !base)
3942
return -ENODEV;
4043

4144
return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
42-
*base + info->assert_offset,
43-
*base + info->status_offset,
45+
base + info->assert_offset,
46+
base + info->status_offset,
4447
NULL,
4548
info->nr_resets,
4649
NULL);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __SOC_STARFIVE_RESET_JH71X0_H
3+
#define __SOC_STARFIVE_RESET_JH71X0_H
4+
5+
#include <linux/auxiliary_bus.h>
6+
#include <linux/compiler_types.h>
7+
#include <linux/container_of.h>
8+
9+
struct jh71x0_reset_adev {
10+
void __iomem *base;
11+
struct auxiliary_device adev;
12+
};
13+
14+
#define to_jh71x0_reset_adev(_adev) \
15+
container_of((_adev), struct jh71x0_reset_adev, adev)
16+
17+
#endif

0 commit comments

Comments
 (0)