diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-07-31 03:43:19 +0200 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-07-31 06:42:37 +0200 |
commit | cf44819c98db11163f58f08b822d626c7a8f5188 (patch) | |
tree | 68af0f6580a73753e5c43bc51ba46a87aaa1a18b /drivers/hwmon/amc6821.c | |
parent | hwmon: (lm78) Fix overflow problems seen when writing large temperature limits (diff) | |
download | linux-cf44819c98db11163f58f08b822d626c7a8f5188.tar.xz linux-cf44819c98db11163f58f08b822d626c7a8f5188.zip |
hwmon: (amc6821) Fix possible race condition bug
Ensure mutex lock protects the read-modify-write period to prevent possible
race condition bug.
In additional, update data->valid should also be protected by the mutex lock.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon/amc6821.c')
-rw-r--r-- | drivers/hwmon/amc6821.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c index 9f2be3dd28f3..8a67ec6279a4 100644 --- a/drivers/hwmon/amc6821.c +++ b/drivers/hwmon/amc6821.c @@ -360,11 +360,13 @@ static ssize_t set_pwm1_enable( if (config) return config; + mutex_lock(&data->update_lock); config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); if (config < 0) { dev_err(&client->dev, "Error reading configuration register, aborting.\n"); - return config; + count = config; + goto unlock; } switch (val) { @@ -381,14 +383,15 @@ static ssize_t set_pwm1_enable( config |= AMC6821_CONF1_FDRC1; break; default: - return -EINVAL; + count = -EINVAL; + goto unlock; } - mutex_lock(&data->update_lock); if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) { dev_err(&client->dev, "Configuration register write error, aborting.\n"); count = -EIO; } +unlock: mutex_unlock(&data->update_lock); return count; } @@ -493,8 +496,9 @@ static ssize_t set_temp_auto_point_temp( return -EINVAL; } - data->valid = 0; mutex_lock(&data->update_lock); + data->valid = 0; + switch (ix) { case 0: ptemp[0] = clamp_val(val / 1000, 0, @@ -658,13 +662,14 @@ static ssize_t set_fan1_div( if (config) return config; + mutex_lock(&data->update_lock); config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); if (config < 0) { dev_err(&client->dev, "Error reading configuration register, aborting.\n"); - return config; + count = config; + goto EXIT; } - mutex_lock(&data->update_lock); switch (val) { case 2: config &= ~AMC6821_CONF4_PSPR; |