Skip to content

Commit

Permalink
firmware: arm_scmi: Fix locking in notifications
Browse files Browse the repository at this point in the history
When a protocol registers its events, the notification core takes care
to rescan the hashtable of pending event handlers and activate all the
possibly existent handlers referring to any of the events that are just
registered by the new protocol. When a pending handler becomes active
the core requests and enables the corresponding events in the SCMI
firmware.

If, for whatever reason, the enable fails, such invalid event handler
must be finally removed and freed. Let us ensure to use the
scmi_put_active_handler() helper which handles properly the needed
additional locking.

Failing to properly acquire all the needed mutexes exposes a race that
leads to the following splat being observed:

 WARNING: CPU: 0 PID: 388 at lib/refcount.c:28 refcount_warn_saturate+0xf8/0x148
 Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development
 	Platform, BIOS EDK II Jun 30 2020
 pstate: 40000005 (nZcv daif -PAN -UAO BTYPE=--)
 pc : refcount_warn_saturate+0xf8/0x148
 lr : refcount_warn_saturate+0xf8/0x148
 Call trace:
  refcount_warn_saturate+0xf8/0x148
  scmi_put_handler_unlocked.isra.10+0x204/0x208
  scmi_put_handler+0x50/0xa0
  scmi_unregister_notifier+0x1bc/0x240
  scmi_notify_tester_remove+0x4c/0x68 [dummy_scmi_consumer]
  scmi_dev_remove+0x54/0x68
  device_release_driver_internal+0x114/0x1e8
  driver_detach+0x58/0xe8
  bus_remove_driver+0x88/0xe0
  driver_unregister+0x38/0x68
  scmi_driver_unregister+0x1c/0x28
  scmi_drv_exit+0x1c/0xae0 [dummy_scmi_consumer]
  __arm64_sys_delete_module+0x1a4/0x268
  el0_svc_common.constprop.3+0x94/0x178
  do_el0_svc+0x2c/0x98
  el0_sync_handler+0x148/0x1a8
  el0_sync+0x158/0x180

Link: https://lore.kernel.org/r/[email protected]
Fixes: e7c215f ("firmware: arm_scmi: Add notification callbacks-registration")
Signed-off-by: Cristian Marussi <[email protected]>
Signed-off-by: Sudeep Holla <[email protected]>
  • Loading branch information
cris-ma authored and sudeep-holla committed Oct 14, 2020
1 parent 9724722 commit c7821c2
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions drivers/firmware/arm_scmi/notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,15 +1403,21 @@ static void scmi_protocols_late_init(struct work_struct *work)
"finalized PENDING handler - key:%X\n",
hndl->key);
ret = scmi_event_handler_enable_events(hndl);
if (ret) {
dev_dbg(ni->handle->dev,
"purging INVALID handler - key:%X\n",
hndl->key);
scmi_put_active_handler(ni, hndl);
}
} else {
ret = scmi_valid_pending_handler(ni, hndl);
}
if (ret) {
dev_dbg(ni->handle->dev,
"purging PENDING handler - key:%X\n",
hndl->key);
/* this hndl can be only a pending one */
scmi_put_handler_unlocked(ni, hndl);
if (ret) {
dev_dbg(ni->handle->dev,
"purging PENDING handler - key:%X\n",
hndl->key);
/* this hndl can be only a pending one */
scmi_put_handler_unlocked(ni, hndl);
}
}
}
mutex_unlock(&ni->pending_mtx);
Expand Down

0 comments on commit c7821c2

Please sign in to comment.