linux-stable/drivers/power
Krzysztof Kozlowski bdbe814454 power: charger-manager: Fix accessing invalidated power supply after fuel gauge unbind
The charger manager obtained reference to fuel gauge power supply in probe
with power_supply_get_by_name() for later usage. However if fuel gauge
driver was removed and re-added then this reference would point to old
power supply (from driver which was removed).

This lead to accessing old (and probably invalid) memory which could be
observed with:
$ echo "12-0036" > /sys/bus/i2c/drivers/max17042/unbind
$ echo "12-0036" > /sys/bus/i2c/drivers/max17042/bind
$ cat /sys/devices/virtual/power_supply/battery/capacity
[  240.480084] INFO: task cat:1393 blocked for more than 120 seconds.
[  240.484799]       Not tainted 3.17.0-next-20141007-00028-ge60b6dd79570 #203
[  240.491782] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  240.499589] cat             D c0469530     0  1393      1 0x00000000
[  240.505947] [<c0469530>] (__schedule) from [<c0469d3c>] (schedule_preempt_disabled+0x14/0x20)
[  240.514449] [<c0469d3c>] (schedule_preempt_disabled) from [<c046af08>] (mutex_lock_nested+0x1bc/0x458)
[  240.523736] [<c046af08>] (mutex_lock_nested) from [<c0287a98>] (regmap_read+0x30/0x60)
[  240.531647] [<c0287a98>] (regmap_read) from [<c032238c>] (max17042_get_property+0x2e8/0x350)
[  240.540055] [<c032238c>] (max17042_get_property) from [<c03247d8>] (charger_get_property+0x264/0x348)
[  240.549252] [<c03247d8>] (charger_get_property) from [<c0320764>] (power_supply_show_property+0x48/0x1e0)
[  240.558808] [<c0320764>] (power_supply_show_property) from [<c027308c>] (dev_attr_show+0x1c/0x48)
[  240.567664] [<c027308c>] (dev_attr_show) from [<c0141fb0>] (sysfs_kf_seq_show+0x84/0x104)
[  240.575814] [<c0141fb0>] (sysfs_kf_seq_show) from [<c0140b18>] (kernfs_seq_show+0x24/0x28)
[  240.584061] [<c0140b18>] (kernfs_seq_show) from [<c0104574>] (seq_read+0x1b0/0x484)
[  240.591702] [<c0104574>] (seq_read) from [<c00e1e24>] (vfs_read+0x88/0x144)
[  240.598640] [<c00e1e24>] (vfs_read) from [<c00e1f20>] (SyS_read+0x40/0x8c)
[  240.605507] [<c00e1f20>] (SyS_read) from [<c000e760>] (ret_fast_syscall+0x0/0x48)
[  240.612952] 4 locks held by cat/1393:
[  240.616589]  #0:  (&p->lock){+.+.+.}, at: [<c01043f4>] seq_read+0x30/0x484
[  240.623414]  #1:  (&of->mutex){+.+.+.}, at: [<c01417dc>] kernfs_seq_start+0x1c/0x8c
[  240.631086]  #2:  (s_active#31){++++.+}, at: [<c01417e4>] kernfs_seq_start+0x24/0x8c
[  240.638777]  #3:  (&map->mutex){+.+...}, at: [<c0287a98>] regmap_read+0x30/0x60

The charger-manager should get reference to fuel gauge power supply on
each use of get_property callback. The thermal zone 'tzd' field of
power supply should not be used because of the same reason.

Additionally this change solves also the issue with nested
thermal_zone_get_temp() calls and related false lockdep positive for
deadlock for thermal zone's mutex [1]. When fuel gauge is used as source of
temperature then the charger manager forwards its get_temp calls to fuel
gauge thermal zone. So actually different mutexes are used (one for
charger manager thermal zone and second for fuel gauge thermal zone) but
for lockdep this is one class of mutex.

The recursion is removed by retrieving temperature through power
supply's get_property().

In case external thermal zone is used ('cm-thermal-zone' property is
present in DTS) the recursion does not exist. Charger manager simply
exports POWER_SUPPLY_PROP_TEMP_AMBIENT property (instead of
POWER_SUPPLY_PROP_TEMP) thus no thermal zone is created for this power
supply.

[1] https://lkml.org/lkml/2014/10/6/309

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Cc: <stable@vger.kernel.org>
Fixes: 3bb3dbbd56 ("power_supply: Add initial Charger-Manager driver")
Signed-off-by: Sebastian Reichel <sre@kernel.org>
2014-10-28 03:30:20 +01:00
..
avs PM / AVS: SmartReflex: use devm_* API to initialize SmartReflex 2013-06-10 10:50:48 -07:00
reset power: reset: corrections for simple syscon reboot driver 2014-10-03 04:32:08 +02:00
88pm860x_battery.c 88pm860x_battery: Remove unnecessary platform_set_drvdata() 2013-06-06 17:12:37 -07:00
88pm860x_charger.c treewide: Fix typo in printk 2013-08-20 12:44:03 +02:00
ab8500_bmdata.c ab8500_bmdata: Export abx500_res_to_temp tables for hwmon 2013-04-16 17:38:10 -07:00
ab8500_btemp.c ab8500_bm: Remove unnecessary platform_set_drvdata() 2013-06-06 17:13:09 -07:00
ab8500_charger.c ab8500-charger: Remove redundant break 2013-10-25 15:36:23 -07:00
ab8500_fg.c power: ab8500_fg.c: use 64-bit time types 2014-10-15 10:37:05 +02:00
abx500_chargalg.c ab8500_bm: Remove unnecessary platform_set_drvdata() 2013-06-06 17:13:09 -07:00
apm_power.c
bq27x00_battery.c bq27x00_battery: Fix flag reading for bq27742 2014-10-01 04:10:50 +02:00
bq2415x_charger.c power: bq2415x_charger: Fix memory leak on DTS parsing error 2014-10-28 03:30:18 +01:00
bq24190_charger.c bq24190_charger: Workaround SS definition problem on i386 builds 2013-08-28 17:52:50 -07:00
bq24735-charger.c power_supply: Add support for bq24735 charger 2013-10-25 15:56:51 -07:00
charger-manager.c power: charger-manager: Fix accessing invalidated power supply after fuel gauge unbind 2014-10-28 03:30:20 +01:00
collie_battery.c power supply: collie_battery: Convert to use dev_pm_ops 2013-08-09 13:41:06 -07:00
da9030_battery.c da9030_battery: Use devm_kzalloc() 2013-03-31 23:25:51 -07:00
da9052-battery.c da9052-battery: Use devm_kzalloc() 2013-03-31 23:25:49 -07:00
ds2760_battery.c ds2760_battery: Use devm_kzalloc() 2013-03-31 23:25:47 -07:00
ds2780_battery.c ds2780_battery: Use devm_kzalloc() 2013-03-31 23:25:45 -07:00
ds2781_battery.c power: remove use of __devexit 2012-11-28 11:43:22 -08:00
ds2782_battery.c power: ds2782_battery: Typo in comment 2014-01-25 15:24:15 +04:00
generic-adc-battery.c generic-adc-battery: Fix checking if none of the channels are supported 2013-06-06 17:33:40 -07:00
goldfish_battery.c goldfish_battery: Use resource_size() 2013-03-31 23:39:40 -07:00
gpio-charger.c power: gpio-charger: do not use gpio value directly 2014-09-25 01:45:59 +02:00
intel_mid_battery.c power: Use platform_{get,set}_drvdata() 2013-06-06 17:30:46 -07:00
ipaq_micro_battery.c ipaq_micro_battery: fix sparse non static symbol warning 2014-07-28 15:36:29 +02:00
isp1704_charger.c isp1704_charger: remove useless check in isp1704_charger_probe() 2014-01-25 15:24:15 +04:00
jz4740-battery.c tree-wide: use reinit_completion instead of INIT_COMPLETION 2013-11-15 09:32:21 +09:00
Kconfig power: max14577: Fix circular config SYSFS dependency 2014-09-25 16:05:50 +02:00
lp8727_charger.c lp8727_charger: Support the device tree feature 2013-06-06 17:19:54 -07:00
lp8788-charger.c lp8788-charger: Use PAGE_SIZE for the sysfs read operation 2013-03-31 23:33:19 -07:00
Makefile power: add driver for battery reading on iPaq h3xxx 2014-07-24 16:20:17 +02:00
max8903_charger.c max8903_charger: Use devm_kzalloc() 2013-03-31 23:25:38 -07:00
max8925_power.c power: max8925: Use of_get_child_by_name 2014-09-25 01:37:13 +02:00
max8997_charger.c max8997_charger: Use devm_kzalloc() 2013-03-31 23:25:36 -07:00
max8998_charger.c max8998_charger: Use devm_kzalloc() 2013-03-31 23:25:34 -07:00
max14577_charger.c charger: max14577: Configure battery-dependent settings from DTS and sysfs 2014-09-24 15:25:49 +01:00
max17040_battery.c power: max17040: Add ID for MAX77836 Fuel Gauge block 2014-09-24 15:25:52 +01:00
max17042_battery.c max17042_battery: Add IRQF_ONESHOT flag to use default irq handler 2013-12-23 18:59:41 -08:00
olpc_battery.c Drivers: power: remove __dev* attributes. 2013-01-03 15:57:14 -08:00
pcf50633-charger.c power_supply: Replace strict_strtoul() with kstrtoul() 2013-06-06 17:35:38 -07:00
pda_power.c usb: power: pda_power: check against CONFIG_USB_PHY 2013-03-18 11:18:05 +02:00
pm2301_charger.c pm2301-charger: Remove unneeded NULL checks 2013-11-12 22:36:34 -08:00
pm2301_charger.h pm2301-charger: Removed unused code from PM2301 driver 2013-03-07 12:35:53 +08:00
pmu_battery.c
power_supply.h
power_supply_core.c power_supply: Add no_thermal property to prevent recursive get_temp calls 2014-10-28 03:30:19 +01:00
power_supply_leds.c power-supply: Avoid unnecessary 'goto' statements 2014-09-16 11:01:37 +02:00
power_supply_sysfs.c power-supply: Check for failures only when we can fail 2014-09-16 11:01:37 +02:00
rx51_battery.c rx51_battery: convert to iio consumer 2014-07-18 23:40:22 +02:00
s3c_adc_battery.c s3c-adc-battery: Fix possible NULL pointer dereference 2013-03-18 19:43:03 -07:00
sbs-battery.c sbs-battery: add min design voltage to sbs-battery 2014-09-06 20:57:43 +02:00
smb347-charger.c power: remove use of __devexit_p 2012-11-28 11:43:22 -08:00
test_power.c test_power: Fix a bug in setting module parameter values 2013-03-18 19:27:31 -07:00
tosa_battery.c power_supply: tosa_battery: Get rid of irq_to_gpio usage 2013-08-09 13:41:52 -07:00
tps65090-charger.c charger: tps65090: Allow charger module to be used when no irq 2014-07-18 23:40:23 +02:00
twl4030_charger.c power: twl4030_charger: detect battery presence prior to enabling charger 2014-07-23 13:58:33 +02:00
twl4030_madc_battery.c power: Add twl4030_madc battery driver. 2013-08-30 17:34:52 -07:00
wm97xx_battery.c power: remove use of __devexit 2012-11-28 11:43:22 -08:00
wm831x_backup.c wm831x_backup: Fix wrong kfree call for devdata->backup.name 2013-05-10 11:56:22 -07:00
wm831x_power.c power: remove use of __devexit 2012-11-28 11:43:22 -08:00
wm8350_power.c power: remove use of __devexit 2012-11-28 11:43:22 -08:00
z2_battery.c power: remove use of __devexit 2012-11-28 11:43:22 -08:00