Commit cf44819c authored by Axel Lin's avatar Axel Lin Committed by Guenter Roeck

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: default avatarAxel Lin <axel.lin@ingics.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 1074d683
...@@ -360,11 +360,13 @@ static ssize_t set_pwm1_enable( ...@@ -360,11 +360,13 @@ static ssize_t set_pwm1_enable(
if (config) if (config)
return config; return config;
mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1); config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
if (config < 0) { if (config < 0) {
dev_err(&client->dev, dev_err(&client->dev,
"Error reading configuration register, aborting.\n"); "Error reading configuration register, aborting.\n");
return config; count = config;
goto unlock;
} }
switch (val) { switch (val) {
...@@ -381,14 +383,15 @@ static ssize_t set_pwm1_enable( ...@@ -381,14 +383,15 @@ static ssize_t set_pwm1_enable(
config |= AMC6821_CONF1_FDRC1; config |= AMC6821_CONF1_FDRC1;
break; break;
default: default:
return -EINVAL; count = -EINVAL;
goto unlock;
} }
mutex_lock(&data->update_lock);
if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) { if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
dev_err(&client->dev, dev_err(&client->dev,
"Configuration register write error, aborting.\n"); "Configuration register write error, aborting.\n");
count = -EIO; count = -EIO;
} }
unlock:
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return count;
} }
...@@ -493,8 +496,9 @@ static ssize_t set_temp_auto_point_temp( ...@@ -493,8 +496,9 @@ static ssize_t set_temp_auto_point_temp(
return -EINVAL; return -EINVAL;
} }
data->valid = 0;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->valid = 0;
switch (ix) { switch (ix) {
case 0: case 0:
ptemp[0] = clamp_val(val / 1000, 0, ptemp[0] = clamp_val(val / 1000, 0,
...@@ -658,13 +662,14 @@ static ssize_t set_fan1_div( ...@@ -658,13 +662,14 @@ static ssize_t set_fan1_div(
if (config) if (config)
return config; return config;
mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4); config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
if (config < 0) { if (config < 0) {
dev_err(&client->dev, dev_err(&client->dev,
"Error reading configuration register, aborting.\n"); "Error reading configuration register, aborting.\n");
return config; count = config;
goto EXIT;
} }
mutex_lock(&data->update_lock);
switch (val) { switch (val) {
case 2: case 2:
config &= ~AMC6821_CONF4_PSPR; config &= ~AMC6821_CONF4_PSPR;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment