Skip to content

Commit 8b6ce25

Browse files
committed
Merge tag 'regulator-fix-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator fixes from Mark Brown: "The biggest set of fixes here is those from Michał Mirosław fixing some locking issues with coupled regulators that are triggered in cases where a coupled regulator is used by a device involved in fs_reclaim like eMMC storage. These are relatively serious for the affected systems, though the circumstances where they trigger are very rare" * tag 'regulator-fix-v5.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: regulator: pwm: Fix machine constraints application regulator: core: Fix slab-out-of-bounds in regulator_unlock_recursive() regulator: remove superfluous lock in regulator_resolve_coupling() regulator: cleanup regulator_ena_gpio_free() regulator: plug of_node leak in regulator_register()'s error path regulator: push allocation in set_consumer_device_supply() out of lock regulator: push allocations in create_regulator() outside of lock regulator: push allocation in regulator_ena_gpio_request() out of lock regulator: push allocation in regulator_init_coupling() outside of lock regulator: fix spelling mistake "Cant" -> "Can't" regulator: cros-ec-regulator: Add NULL test for devm_kmemdup call
2 parents 063d6a4 + 59ae97a commit 8b6ce25

File tree

4 files changed

+101
-85
lines changed

4 files changed

+101
-85
lines changed

drivers/regulator/core.c

Lines changed: 96 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -236,19 +236,22 @@ static bool regulator_supply_is_couple(struct regulator_dev *rdev)
236236
static void regulator_unlock_recursive(struct regulator_dev *rdev,
237237
unsigned int n_coupled)
238238
{
239-
struct regulator_dev *c_rdev;
240-
int i;
239+
struct regulator_dev *c_rdev, *supply_rdev;
240+
int i, supply_n_coupled;
241241

242242
for (i = n_coupled; i > 0; i--) {
243243
c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1];
244244

245245
if (!c_rdev)
246246
continue;
247247

248-
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev))
249-
regulator_unlock_recursive(
250-
c_rdev->supply->rdev,
251-
c_rdev->coupling_desc.n_coupled);
248+
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) {
249+
supply_rdev = c_rdev->supply->rdev;
250+
supply_n_coupled = supply_rdev->coupling_desc.n_coupled;
251+
252+
regulator_unlock_recursive(supply_rdev,
253+
supply_n_coupled);
254+
}
252255

253256
regulator_unlock(c_rdev);
254257
}
@@ -1461,7 +1464,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
14611464
const char *consumer_dev_name,
14621465
const char *supply)
14631466
{
1464-
struct regulator_map *node;
1467+
struct regulator_map *node, *new_node;
14651468
int has_dev;
14661469

14671470
if (supply == NULL)
@@ -1472,6 +1475,22 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
14721475
else
14731476
has_dev = 0;
14741477

1478+
new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1479+
if (new_node == NULL)
1480+
return -ENOMEM;
1481+
1482+
new_node->regulator = rdev;
1483+
new_node->supply = supply;
1484+
1485+
if (has_dev) {
1486+
new_node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
1487+
if (new_node->dev_name == NULL) {
1488+
kfree(new_node);
1489+
return -ENOMEM;
1490+
}
1491+
}
1492+
1493+
mutex_lock(&regulator_list_mutex);
14751494
list_for_each_entry(node, &regulator_map_list, list) {
14761495
if (node->dev_name && consumer_dev_name) {
14771496
if (strcmp(node->dev_name, consumer_dev_name) != 0)
@@ -1489,26 +1508,19 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
14891508
node->regulator->desc->name,
14901509
supply,
14911510
dev_name(&rdev->dev), rdev_get_name(rdev));
1492-
return -EBUSY;
1511+
goto fail;
14931512
}
14941513

1495-
node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
1496-
if (node == NULL)
1497-
return -ENOMEM;
1498-
1499-
node->regulator = rdev;
1500-
node->supply = supply;
1501-
1502-
if (has_dev) {
1503-
node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
1504-
if (node->dev_name == NULL) {
1505-
kfree(node);
1506-
return -ENOMEM;
1507-
}
1508-
}
1514+
list_add(&new_node->list, &regulator_map_list);
1515+
mutex_unlock(&regulator_list_mutex);
15091516

1510-
list_add(&node->list, &regulator_map_list);
15111517
return 0;
1518+
1519+
fail:
1520+
mutex_unlock(&regulator_list_mutex);
1521+
kfree(new_node->dev_name);
1522+
kfree(new_node);
1523+
return -EBUSY;
15121524
}
15131525

15141526
static void unset_regulator_supplies(struct regulator_dev *rdev)
@@ -1580,44 +1592,53 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
15801592
const char *supply_name)
15811593
{
15821594
struct regulator *regulator;
1583-
char buf[REG_STR_SIZE];
1584-
int err, size;
1595+
int err;
1596+
1597+
if (dev) {
1598+
char buf[REG_STR_SIZE];
1599+
int size;
1600+
1601+
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
1602+
dev->kobj.name, supply_name);
1603+
if (size >= REG_STR_SIZE)
1604+
return NULL;
1605+
1606+
supply_name = kstrdup(buf, GFP_KERNEL);
1607+
if (supply_name == NULL)
1608+
return NULL;
1609+
} else {
1610+
supply_name = kstrdup_const(supply_name, GFP_KERNEL);
1611+
if (supply_name == NULL)
1612+
return NULL;
1613+
}
15851614

15861615
regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
1587-
if (regulator == NULL)
1616+
if (regulator == NULL) {
1617+
kfree(supply_name);
15881618
return NULL;
1619+
}
15891620

1590-
regulator_lock(rdev);
15911621
regulator->rdev = rdev;
1622+
regulator->supply_name = supply_name;
1623+
1624+
regulator_lock(rdev);
15921625
list_add(&regulator->list, &rdev->consumer_list);
1626+
regulator_unlock(rdev);
15931627

15941628
if (dev) {
15951629
regulator->dev = dev;
15961630

15971631
/* Add a link to the device sysfs entry */
1598-
size = snprintf(buf, REG_STR_SIZE, "%s-%s",
1599-
dev->kobj.name, supply_name);
1600-
if (size >= REG_STR_SIZE)
1601-
goto overflow_err;
1602-
1603-
regulator->supply_name = kstrdup(buf, GFP_KERNEL);
1604-
if (regulator->supply_name == NULL)
1605-
goto overflow_err;
1606-
16071632
err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj,
1608-
buf);
1633+
supply_name);
16091634
if (err) {
16101635
rdev_dbg(rdev, "could not add device link %s err %d\n",
16111636
dev->kobj.name, err);
16121637
/* non-fatal */
16131638
}
1614-
} else {
1615-
regulator->supply_name = kstrdup_const(supply_name, GFP_KERNEL);
1616-
if (regulator->supply_name == NULL)
1617-
goto overflow_err;
16181639
}
16191640

1620-
regulator->debugfs = debugfs_create_dir(regulator->supply_name,
1641+
regulator->debugfs = debugfs_create_dir(supply_name,
16211642
rdev->debugfs);
16221643
if (!regulator->debugfs) {
16231644
rdev_dbg(rdev, "Failed to create debugfs directory\n");
@@ -1642,13 +1663,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
16421663
_regulator_is_enabled(rdev))
16431664
regulator->always_on = true;
16441665

1645-
regulator_unlock(rdev);
16461666
return regulator;
1647-
overflow_err:
1648-
list_del(&regulator->list);
1649-
kfree(regulator);
1650-
regulator_unlock(rdev);
1651-
return NULL;
16521667
}
16531668

16541669
static int _regulator_get_enable_time(struct regulator_dev *rdev)
@@ -2230,10 +2245,13 @@ EXPORT_SYMBOL_GPL(regulator_bulk_unregister_supply_alias);
22302245
static int regulator_ena_gpio_request(struct regulator_dev *rdev,
22312246
const struct regulator_config *config)
22322247
{
2233-
struct regulator_enable_gpio *pin;
2248+
struct regulator_enable_gpio *pin, *new_pin;
22342249
struct gpio_desc *gpiod;
22352250

22362251
gpiod = config->ena_gpiod;
2252+
new_pin = kzalloc(sizeof(*new_pin), GFP_KERNEL);
2253+
2254+
mutex_lock(&regulator_list_mutex);
22372255

22382256
list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
22392257
if (pin->gpiod == gpiod) {
@@ -2242,16 +2260,24 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
22422260
}
22432261
}
22442262

2245-
pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL);
2246-
if (pin == NULL)
2263+
if (new_pin == NULL) {
2264+
mutex_unlock(&regulator_list_mutex);
22472265
return -ENOMEM;
2266+
}
2267+
2268+
pin = new_pin;
2269+
new_pin = NULL;
22482270

22492271
pin->gpiod = gpiod;
22502272
list_add(&pin->list, &regulator_ena_gpio_list);
22512273

22522274
update_ena_gpio_to_rdev:
22532275
pin->request_count++;
22542276
rdev->ena_pin = pin;
2277+
2278+
mutex_unlock(&regulator_list_mutex);
2279+
kfree(new_pin);
2280+
22552281
return 0;
22562282
}
22572283

@@ -2264,19 +2290,19 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
22642290

22652291
/* Free the GPIO only in case of no use */
22662292
list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
2267-
if (pin->gpiod == rdev->ena_pin->gpiod) {
2268-
if (pin->request_count <= 1) {
2269-
pin->request_count = 0;
2270-
gpiod_put(pin->gpiod);
2271-
list_del(&pin->list);
2272-
kfree(pin);
2273-
rdev->ena_pin = NULL;
2274-
return;
2275-
} else {
2276-
pin->request_count--;
2277-
}
2278-
}
2293+
if (pin != rdev->ena_pin)
2294+
continue;
2295+
2296+
if (--pin->request_count)
2297+
break;
2298+
2299+
gpiod_put(pin->gpiod);
2300+
list_del(&pin->list);
2301+
kfree(pin);
2302+
break;
22792303
}
2304+
2305+
rdev->ena_pin = NULL;
22802306
}
22812307

22822308
/**
@@ -4949,13 +4975,9 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev)
49494975
return;
49504976
}
49514977

4952-
regulator_lock(c_rdev);
4953-
49544978
c_desc->coupled_rdevs[i] = c_rdev;
49554979
c_desc->n_resolved++;
49564980

4957-
regulator_unlock(c_rdev);
4958-
49594981
regulator_resolve_coupling(c_rdev);
49604982
}
49614983
}
@@ -5040,7 +5062,10 @@ static int regulator_init_coupling(struct regulator_dev *rdev)
50405062
if (!of_check_coupling_data(rdev))
50415063
return -EPERM;
50425064

5065+
mutex_lock(&regulator_list_mutex);
50435066
rdev->coupling_desc.coupler = regulator_find_coupler(rdev);
5067+
mutex_unlock(&regulator_list_mutex);
5068+
50445069
if (IS_ERR(rdev->coupling_desc.coupler)) {
50455070
err = PTR_ERR(rdev->coupling_desc.coupler);
50465071
rdev_err(rdev, "failed to get coupler: %d\n", err);
@@ -5141,16 +5166,16 @@ regulator_register(const struct regulator_desc *regulator_desc,
51415166
ret = -ENOMEM;
51425167
goto rinse;
51435168
}
5169+
device_initialize(&rdev->dev);
51445170

51455171
/*
51465172
* Duplicate the config so the driver could override it after
51475173
* parsing init data.
51485174
*/
51495175
config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL);
51505176
if (config == NULL) {
5151-
kfree(rdev);
51525177
ret = -ENOMEM;
5153-
goto rinse;
5178+
goto clean;
51545179
}
51555180

51565181
init_data = regulator_of_get_init_data(dev, regulator_desc, config,
@@ -5162,10 +5187,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
51625187
* from a gpio extender or something else.
51635188
*/
51645189
if (PTR_ERR(init_data) == -EPROBE_DEFER) {
5165-
kfree(config);
5166-
kfree(rdev);
51675190
ret = -EPROBE_DEFER;
5168-
goto rinse;
5191+
goto clean;
51695192
}
51705193

51715194
/*
@@ -5206,9 +5229,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
52065229
}
52075230

52085231
if (config->ena_gpiod) {
5209-
mutex_lock(&regulator_list_mutex);
52105232
ret = regulator_ena_gpio_request(rdev, config);
5211-
mutex_unlock(&regulator_list_mutex);
52125233
if (ret != 0) {
52135234
rdev_err(rdev, "Failed to request enable GPIO: %d\n",
52145235
ret);
@@ -5220,7 +5241,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
52205241
}
52215242

52225243
/* register with sysfs */
5223-
device_initialize(&rdev->dev);
52245244
rdev->dev.class = &regulator_class;
52255245
rdev->dev.parent = dev;
52265246
dev_set_name(&rdev->dev, "regulator.%lu",
@@ -5248,27 +5268,22 @@ regulator_register(const struct regulator_desc *regulator_desc,
52485268
if (ret < 0)
52495269
goto wash;
52505270

5251-
mutex_lock(&regulator_list_mutex);
52525271
ret = regulator_init_coupling(rdev);
5253-
mutex_unlock(&regulator_list_mutex);
52545272
if (ret < 0)
52555273
goto wash;
52565274

52575275
/* add consumers devices */
52585276
if (init_data) {
5259-
mutex_lock(&regulator_list_mutex);
52605277
for (i = 0; i < init_data->num_consumer_supplies; i++) {
52615278
ret = set_consumer_device_supply(rdev,
52625279
init_data->consumer_supplies[i].dev_name,
52635280
init_data->consumer_supplies[i].supply);
52645281
if (ret < 0) {
5265-
mutex_unlock(&regulator_list_mutex);
52665282
dev_err(dev, "Failed to set supply %s\n",
52675283
init_data->consumer_supplies[i].supply);
52685284
goto unset_supplies;
52695285
}
52705286
}
5271-
mutex_unlock(&regulator_list_mutex);
52725287
}
52735288

52745289
if (!rdev->desc->ops->get_voltage &&
@@ -5303,13 +5318,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
53035318
mutex_lock(&regulator_list_mutex);
53045319
regulator_ena_gpio_free(rdev);
53055320
mutex_unlock(&regulator_list_mutex);
5306-
put_device(&rdev->dev);
5307-
rdev = NULL;
53085321
clean:
53095322
if (dangling_of_gpiod)
53105323
gpiod_put(config->ena_gpiod);
5311-
kfree(rdev);
53125324
kfree(config);
5325+
put_device(&rdev->dev);
53135326
rinse:
53145327
if (dangling_cfg_gpiod)
53155328
gpiod_put(cfg->ena_gpiod);

drivers/regulator/cros-ec-regulator.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ static int cros_ec_regulator_init_info(struct device *dev,
170170
data->voltages_mV =
171171
devm_kmemdup(dev, resp.voltages_mv,
172172
sizeof(u16) * data->num_voltages, GFP_KERNEL);
173+
if (!data->voltages_mV)
174+
return -ENOMEM;
175+
173176
data->desc.n_voltages = data->num_voltages;
174177

175178
/* Make sure the returned name is always a valid string */

drivers/regulator/fixed.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
182182

183183
drvdata->enable_clock = devm_clk_get(dev, NULL);
184184
if (IS_ERR(drvdata->enable_clock)) {
185-
dev_err(dev, "Cant get enable-clock from devicetree\n");
185+
dev_err(dev, "Can't get enable-clock from devicetree\n");
186186
return -ENOENT;
187187
}
188188
} else {

0 commit comments

Comments
 (0)