diff options
author | Guenter Roeck <linux@roeck-us.net> | 2022-11-10 18:24:58 +0300 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2022-11-14 21:04:37 +0300 |
commit | 05eeee2b51b44c7ba5f1b8e5c41362020513f163 (patch) | |
tree | db5f9529216677a28b1fc3af6f49f2eb9f483891 /drivers/thermal/thermal_sysfs.c | |
parent | ea37bec51ff442546e4a57d5cca2de9cc64a9df3 (diff) | |
download | linux-05eeee2b51b44c7ba5f1b8e5c41362020513f163.tar.xz |
thermal/core: Protect sysfs accesses to thermal operations with thermal zone mutex
Protect access to thermal operations against thermal zone removal by
acquiring the thermal zone device mutex. After acquiring the mutex, check
if the thermal zone device is registered and abort the operation if not.
With this change, we can call __thermal_zone_device_update() instead of
thermal_zone_device_update() from trip_point_temp_store() and from
emul_temp_store(). Similar, we can call __thermal_zone_set_trips() instead
of thermal_zone_set_trips() from trip_point_hyst_store().
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/thermal/thermal_sysfs.c')
-rw-r--r-- | drivers/thermal/thermal_sysfs.c | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index febf9e76c440..d97f0bc0a26b 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -92,7 +92,14 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1) return -EINVAL; - result = tz->ops->get_trip_type(tz, trip, &type); + mutex_lock(&tz->lock); + + if (device_is_registered(dev)) + result = tz->ops->get_trip_type(tz, trip, &type); + else + result = -ENODEV; + + mutex_unlock(&tz->lock); if (result) return result; @@ -128,10 +135,17 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, if (kstrtoint(buf, 10, &temperature)) return -EINVAL; + mutex_lock(&tz->lock); + + if (!device_is_registered(dev)) { + ret = -ENODEV; + goto unlock; + } + if (tz->ops->set_trip_temp) { ret = tz->ops->set_trip_temp(tz, trip, temperature); if (ret) - return ret; + goto unlock; } if (tz->trips) @@ -140,16 +154,22 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, if (tz->ops->get_trip_hyst) { ret = tz->ops->get_trip_hyst(tz, trip, &hyst); if (ret) - return ret; + goto unlock; } ret = tz->ops->get_trip_type(tz, trip, &type); if (ret) - return ret; + goto unlock; thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst); - thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + +unlock: + mutex_unlock(&tz->lock); + + if (ret) + return ret; return count; } @@ -168,7 +188,14 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1) return -EINVAL; - ret = tz->ops->get_trip_temp(tz, trip, &temperature); + mutex_lock(&tz->lock); + + if (device_is_registered(dev)) + ret = tz->ops->get_trip_temp(tz, trip, &temperature); + else + ret = -ENODEV; + + mutex_unlock(&tz->lock); if (ret) return ret; @@ -193,6 +220,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, if (kstrtoint(buf, 10, &temperature)) return -EINVAL; + mutex_lock(&tz->lock); + + if (!device_is_registered(dev)) { + ret = -ENODEV; + goto unlock; + } + /* * We are not doing any check on the 'temperature' value * here. The driver implementing 'set_trip_hyst' has to @@ -201,7 +235,10 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, ret = tz->ops->set_trip_hyst(tz, trip, temperature); if (!ret) - thermal_zone_set_trips(tz); + __thermal_zone_set_trips(tz); + +unlock: + mutex_unlock(&tz->lock); return ret ? ret : count; } @@ -220,7 +257,14 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1) return -EINVAL; - ret = tz->ops->get_trip_hyst(tz, trip, &temperature); + mutex_lock(&tz->lock); + + if (device_is_registered(dev)) + ret = tz->ops->get_trip_hyst(tz, trip, &temperature); + else + ret = -ENODEV; + + mutex_unlock(&tz->lock); return ret ? ret : sprintf(buf, "%d\n", temperature); } @@ -269,16 +313,23 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, if (kstrtoint(buf, 10, &temperature)) return -EINVAL; - if (!tz->ops->set_emul_temp) { - mutex_lock(&tz->lock); + mutex_lock(&tz->lock); + + if (!device_is_registered(dev)) { + ret = -ENODEV; + goto unlock; + } + + if (!tz->ops->set_emul_temp) tz->emul_temperature = temperature; - mutex_unlock(&tz->lock); - } else { + else ret = tz->ops->set_emul_temp(tz, temperature); - } if (!ret) - thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + +unlock: + mutex_unlock(&tz->lock); return ret ? ret : count; } |