Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mei: bus: call mei_cl_read_start under device lock

Ensure that mei_cl_read_start is called under the device lock
also in the bus layer. The function updates global ctrl_wr_list
which should be locked.

Cc: <stable@vger.kernel.org> #4.4+
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
bc46b45a bedffda8

+12 -3
+12 -3
drivers/misc/mei/bus.c
··· 220 220 static void mei_cl_bus_event_work(struct work_struct *work) 221 221 { 222 222 struct mei_cl_device *cldev; 223 + struct mei_device *bus; 223 224 224 225 cldev = container_of(work, struct mei_cl_device, event_work); 226 + 227 + bus = cldev->bus; 225 228 226 229 if (cldev->event_cb) 227 230 cldev->event_cb(cldev, cldev->events, cldev->event_context); ··· 232 229 cldev->events = 0; 233 230 234 231 /* Prepare for the next read */ 235 - if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) 232 + if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { 233 + mutex_lock(&bus->device_lock); 236 234 mei_cl_read_start(cldev->cl, 0, NULL); 235 + mutex_unlock(&bus->device_lock); 236 + } 237 237 } 238 238 239 239 /** ··· 310 304 unsigned long events_mask, 311 305 mei_cldev_event_cb_t event_cb, void *context) 312 306 { 307 + struct mei_device *bus = cldev->bus; 313 308 int ret; 314 309 315 310 if (cldev->event_cb) ··· 323 316 INIT_WORK(&cldev->event_work, mei_cl_bus_event_work); 324 317 325 318 if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { 319 + mutex_lock(&bus->device_lock); 326 320 ret = mei_cl_read_start(cldev->cl, 0, NULL); 321 + mutex_unlock(&bus->device_lock); 327 322 if (ret && ret != -EBUSY) 328 323 return ret; 329 324 } 330 325 331 326 if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) { 332 - mutex_lock(&cldev->cl->dev->device_lock); 327 + mutex_lock(&bus->device_lock); 333 328 ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0); 334 - mutex_unlock(&cldev->cl->dev->device_lock); 329 + mutex_unlock(&bus->device_lock); 335 330 if (ret) 336 331 return ret; 337 332 }