Skip to content

Commit 3075a39

Browse files
Sanman Pradhangroeck
authored andcommitted
hwmon: (pmbus/isl68137) Add mutex protection for AVS enable sysfs attributes
The custom avs0_enable and avs1_enable sysfs attributes access PMBus registers through the exported API helpers (pmbus_read_byte_data, pmbus_read_word_data, pmbus_write_word_data, pmbus_update_byte_data) without holding the PMBus update_lock mutex. These exported helpers do not acquire the mutex internally, unlike the core's internal callers which hold the lock before invoking them. The store callback is especially vulnerable: it performs a multi-step read-modify-write sequence (read VOUT_COMMAND, write VOUT_COMMAND, then update OPERATION) where concurrent access from another thread could interleave and corrupt the register state. Add pmbus_lock_interruptible()/pmbus_unlock() around both the show and store callbacks to serialize PMBus register access with the rest of the driver. Fixes: 038a9c3 ("hwmon: (pmbus/isl68137) Add driver for Intersil ISL68137 PWM Controller") Cc: [email protected] Signed-off-by: Sanman Pradhan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent f7e775c commit 3075a39

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

drivers/hwmon/pmbus/isl68137.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@ static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
9696
int page,
9797
char *buf)
9898
{
99-
int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
99+
int val;
100+
101+
val = pmbus_lock_interruptible(client);
102+
if (val)
103+
return val;
104+
105+
val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
106+
107+
pmbus_unlock(client);
100108

101109
if (val < 0)
102110
return val;
@@ -118,6 +126,10 @@ static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
118126

119127
op_val = result ? ISL68137_VOUT_AVS : 0;
120128

129+
rc = pmbus_lock_interruptible(client);
130+
if (rc)
131+
return rc;
132+
121133
/*
122134
* Writes to VOUT setpoint over AVSBus will persist after the VRM is
123135
* switched to PMBus control. Switching back to AVSBus control
@@ -129,17 +141,20 @@ static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
129141
rc = pmbus_read_word_data(client, page, 0xff,
130142
PMBUS_VOUT_COMMAND);
131143
if (rc < 0)
132-
return rc;
144+
goto unlock;
133145

134146
rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND,
135147
rc);
136148
if (rc < 0)
137-
return rc;
149+
goto unlock;
138150
}
139151

140152
rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
141153
ISL68137_VOUT_AVS, op_val);
142154

155+
unlock:
156+
pmbus_unlock(client);
157+
143158
return (rc < 0) ? rc : count;
144159
}
145160

0 commit comments

Comments
 (0)