* [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race
@ 2023-05-31 13:44 Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 02/17] power: supply: sc27xx: " Sasha Levin
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Sasha Levin @ 2023-05-31 13:44 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Hans de Goede, Linus Walleij, Sebastian Reichel, Sasha Levin, sre,
linux-pm
From: Hans de Goede <hdegoede@redhat.com>
[ Upstream commit a5299ce4e96f3e8930e9c051b28d8093ada87b08 ]
ab8500_btemp_external_power_changed() dereferences di->btemp_psy,
which gets sets in ab8500_btemp_probe() like this:
di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc,
&psy_cfg);
As soon as devm_power_supply_register() has called device_add()
the external_power_changed callback can get called. So there is a window
where ab8500_btemp_external_power_changed() may get called while
di->btemp_psy has not been set yet leading to a NULL pointer dereference.
Fixing this is easy. The external_power_changed callback gets passed
the power_supply which will eventually get stored in di->btemp_psy,
so ab8500_btemp_external_power_changed() can simply directly use
the passed in psy argument which is always valid.
And the same applies to ab8500_fg_external_power_changed().
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/ab8500_btemp.c | 6 ++----
drivers/power/supply/ab8500_fg.c | 6 ++----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
index c8a22df650364..1f5cf4d7552be 100644
--- a/drivers/power/supply/ab8500_btemp.c
+++ b/drivers/power/supply/ab8500_btemp.c
@@ -919,10 +919,8 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
*/
static void ab8500_btemp_external_power_changed(struct power_supply *psy)
{
- struct ab8500_btemp *di = power_supply_get_drvdata(psy);
-
- class_for_each_device(power_supply_class, NULL,
- di->btemp_psy, ab8500_btemp_get_ext_psy_data);
+ class_for_each_device(power_supply_class, NULL, psy,
+ ab8500_btemp_get_ext_psy_data);
}
/* ab8500 btemp driver interrupts and their respective isr */
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index 4c229e6fb750a..75df20b2fe0e4 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -2380,10 +2380,8 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
*/
static void ab8500_fg_external_power_changed(struct power_supply *psy)
{
- struct ab8500_fg *di = power_supply_get_drvdata(psy);
-
- class_for_each_device(power_supply_class, NULL,
- di->fg_psy, ab8500_fg_get_ext_psy_data);
+ class_for_each_device(power_supply_class, NULL, psy,
+ ab8500_fg_get_ext_psy_data);
}
/**
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH AUTOSEL 5.4 02/17] power: supply: sc27xx: Fix external_power_changed race
2023-05-31 13:44 [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race Sasha Levin
@ 2023-05-31 13:44 ` Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 03/17] power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule() Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-05-31 13:44 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Hans de Goede, Orson Zhai, Chunyan Zhang, Baolin Wang,
Sebastian Reichel, Sasha Levin, sre, linux-pm
From: Hans de Goede <hdegoede@redhat.com>
[ Upstream commit 4d5c129d6c8993fe96e9ae712141eedcb9ca68c2 ]
sc27xx_fgu_external_power_changed() dereferences data->battery,
which gets sets in ab8500_btemp_probe() like this:
data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc,
&fgu_cfg);
As soon as devm_power_supply_register() has called device_add()
the external_power_changed callback can get called. So there is a window
where sc27xx_fgu_external_power_changed() may get called while
data->battery has not been set yet leading to a NULL pointer dereference.
Fixing this is easy. The external_power_changed callback gets passed
the power_supply which will eventually get stored in data->battery,
so sc27xx_fgu_external_power_changed() can simply directly use
the passed in psy argument which is always valid.
After this change sc27xx_fgu_external_power_changed() is reduced to just
"power_supply_changed(psy);" and it has the same prototype. While at it
simply replace it with making the external_power_changed callback
directly point to power_supply_changed.
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/sc27xx_fuel_gauge.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index 5e5bcdbf2e695..557b02d408134 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -634,13 +634,6 @@ static int sc27xx_fgu_set_property(struct power_supply *psy,
return ret;
}
-static void sc27xx_fgu_external_power_changed(struct power_supply *psy)
-{
- struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
-
- power_supply_changed(data->battery);
-}
-
static int sc27xx_fgu_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
@@ -671,7 +664,7 @@ static const struct power_supply_desc sc27xx_fgu_desc = {
.num_properties = ARRAY_SIZE(sc27xx_fgu_props),
.get_property = sc27xx_fgu_get_property,
.set_property = sc27xx_fgu_set_property,
- .external_power_changed = sc27xx_fgu_external_power_changed,
+ .external_power_changed = power_supply_changed,
.property_is_writeable = sc27xx_fgu_property_is_writeable,
};
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH AUTOSEL 5.4 03/17] power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule()
2023-05-31 13:44 [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 02/17] power: supply: sc27xx: " Sasha Levin
@ 2023-05-31 13:44 ` Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 05/17] power: supply: Ratelimit no data debug output Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 09/17] power: supply: Fix logic checking if system is running from battery Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-05-31 13:44 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Hans de Goede, Sebastian Reichel, Sasha Levin, sre, linux-pm
From: Hans de Goede <hdegoede@redhat.com>
[ Upstream commit 59dddea9879713423c7b2ade43c423bb71e0d216 ]
Use mod_delayed_work() instead of separate cancel_delayed_work_sync() +
schedule_delayed_work() calls.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/bq27xxx_battery.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index b1a37aa388800..f30f80f0a7c6e 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -886,10 +886,8 @@ static int poll_interval_param_set(const char *val, const struct kernel_param *k
return ret;
mutex_lock(&bq27xxx_list_lock);
- list_for_each_entry(di, &bq27xxx_battery_devices, list) {
- cancel_delayed_work_sync(&di->work);
- schedule_delayed_work(&di->work, 0);
- }
+ list_for_each_entry(di, &bq27xxx_battery_devices, list)
+ mod_delayed_work(system_wq, &di->work, 0);
mutex_unlock(&bq27xxx_list_lock);
return ret;
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH AUTOSEL 5.4 05/17] power: supply: Ratelimit no data debug output
2023-05-31 13:44 [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 02/17] power: supply: sc27xx: " Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 03/17] power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule() Sasha Levin
@ 2023-05-31 13:44 ` Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 09/17] power: supply: Fix logic checking if system is running from battery Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-05-31 13:44 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Marek Vasut, Hans de Goede, Sebastian Reichel, Sasha Levin, sre,
linux-pm
From: Marek Vasut <marex@denx.de>
[ Upstream commit 155c45a25679f571c2ae57d10db843a9dfc63430 ]
Reduce the amount of output this dev_dbg() statement emits into logs,
otherwise if system software polls the sysfs entry for data and keeps
getting -ENODATA, it could end up filling the logs up.
This does in fact make systemd journald choke, since during boot the
sysfs power supply entries are polled and if journald starts at the
same time, the journal is just being repeatedly filled up, and the
system stops on trying to start journald without booting any further.
Signed-off-by: Marek Vasut <marex@denx.de>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/power_supply_sysfs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index f37ad4eae60b9..d6c47ea27010c 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -127,7 +127,8 @@ static ssize_t power_supply_show_property(struct device *dev,
if (ret < 0) {
if (ret == -ENODATA)
- dev_dbg(dev, "driver has no data for `%s' property\n",
+ dev_dbg_ratelimited(dev,
+ "driver has no data for `%s' property\n",
attr->attr.name);
else if (ret != -ENODEV && ret != -EAGAIN)
dev_err_ratelimited(dev,
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH AUTOSEL 5.4 09/17] power: supply: Fix logic checking if system is running from battery
2023-05-31 13:44 [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race Sasha Levin
` (2 preceding siblings ...)
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 05/17] power: supply: Ratelimit no data debug output Sasha Levin
@ 2023-05-31 13:44 ` Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-05-31 13:44 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Mario Limonciello, Evan Quan, Lijo Lazar, Sebastian Reichel,
Sasha Levin, sre, linux-pm
From: Mario Limonciello <mario.limonciello@amd.com>
[ Upstream commit 95339f40a8b652b5b1773def31e63fc53c26378a ]
The logic used for power_supply_is_system_supplied() counts all power
supplies and assumes that the system is running from AC if there is
either a non-battery power-supply reporting to be online or if no
power-supplies exist at all.
The second rule is for desktop systems, that don't have any
battery/charger devices. These systems will incorrectly report to be
powered from battery once a device scope power-supply is registered
(e.g. a HID device), since these power-supplies increase the counter.
Apart from HID devices, recent dGPUs provide UCSI power supplies on a
desktop systems. The dGPU by default doesn't have anything plugged in so
it's 'offline'. This makes power_supply_is_system_supplied() return 0
with a count of 1 meaning all drivers that use this get a wrong judgement.
To fix this case adjust the logic to also examine the scope of the power
supply. If the power supply is deemed a device power supply, then don't
count it.
Cc: Evan Quan <Evan.Quan@amd.com>
Suggested-by: Lijo Lazar <Lijo.Lazar@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/power_supply_core.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index fd24254d90142..4a490ac4e4ed3 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -347,6 +347,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
struct power_supply *psy = dev_get_drvdata(dev);
unsigned int *count = data;
+ if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret))
+ if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
+ return 0;
+
(*count)++;
if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY)
if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE,
@@ -365,8 +369,8 @@ int power_supply_is_system_supplied(void)
__power_supply_is_system_supplied);
/*
- * If no power class device was found at all, most probably we are
- * running on a desktop system, so assume we are on mains power.
+ * If no system scope power class device was found at all, most probably we
+ * are running on a desktop system, so assume we are on mains power.
*/
if (count == 0)
return 1;
--
2.39.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-05-31 13:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-31 13:44 [PATCH AUTOSEL 5.4 01/17] power: supply: ab8500: Fix external_power_changed race Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 02/17] power: supply: sc27xx: " Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 03/17] power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule() Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 05/17] power: supply: Ratelimit no data debug output Sasha Levin
2023-05-31 13:44 ` [PATCH AUTOSEL 5.4 09/17] power: supply: Fix logic checking if system is running from battery Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).