| 5993e10b | 22-Jul-2026 |
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> |
bus: mhi: ep: Flush async transfers before notifying disconnect in mhi_ep_abort_transfer()
mhi_ep_abort_transfer() notifies the client drivers about the channel disconnect using -ENOTCONN and only t
bus: mhi: ep: Flush async transfers before notifying disconnect in mhi_ep_abort_transfer()
mhi_ep_abort_transfer() notifies the client drivers about the channel disconnect using -ENOTCONN and only then flushes the ring workqueue to drain the in-flight transfers. But the async DMA transfers issued by the ring workers can still complete after the notification. And the completion handlers trigger the client xfer_cb() as long as it is set.
So a transfer completing during the flush can deliver a success callback to the client even after it has been notified about the disconnect. This can lead to UAF (Use-After-Free) issues as the client can free its per-transfer resources in response to the -ENOTCONN notification and the trailing success callback would then reference the freed resources.
So to fix this issue, disable all the channels first to prevent new transfers and then drain both the ring workqueue and the in-flight async transfers before notifying the disconnect. The completion and queue paths bail out once the channel state is not MHI_CH_STATE_RUNNING, so disabling the channels upfront makes sure that no new transfer sneaks in during the drain and all the pending completions are delivered while xfer_cb() is still valid.
Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
show more ...
|
| 7cc5ddce | 22-Jul-2026 |
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> |
bus: mhi: ep: Add mhi_cntrl->flush_async() callback to flush the async read/write
MHI EP stack makes use of the MHI controller drivers like MHI EPF to do read/write to the host memory. And that driv
bus: mhi: ep: Add mhi_cntrl->flush_async() callback to flush the async read/write
MHI EP stack makes use of the MHI controller drivers like MHI EPF to do read/write to the host memory. And that driver is free to use mechanisms like DMA to offload the read/write operations.
So if DMA is used for offload, then there is no guarantee that those DMA operations would be completed by the time mhi_ep_remove() gets called. This can lead to UAF (Use-After-Free) issues as the DMA callback can trigger xfer_cb() even after mhi_ep_remove() has returned.
So to fix this issue, introduce the mhi_cntrl->flush_async() callback and call it in mhi_ep_remove() to drain all the in-flight async transfers before disconnecting the channels.
The completion handlers keep triggering xfer_cb() as long as it is set. So flushing the transfers after notifying the client about the disconnect (-ENOTCONN) would still let a success callback slip through afterwards and lead to the same UAF. So disable the channels first to prevent new transfers, then flush the in-flight transfers so that their completions are delivered while xfer_cb() is still valid and only then notify the disconnect and clear xfer_cb().
Fixes: 2547beb00ddb ("bus: mhi: ep: Add support for async DMA read operation") Fixes: ee08acb58fe4 ("bus: mhi: ep: Add support for async DMA write operation") Reviewed-by: Frank Li <Frank.Li@nxp.com> Cc: stable+noautosel@kernel.org # Needs dmaengine driver fix as well Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
show more ...
|
| 519ddf19 | 02-Mar-2026 |
Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> |
bus: mhi: ep: Protect mhi_ep_handle_syserr() in the error path
All the callers of mhi_ep_handle_syserr() except mhi_ep_process_cmd_ring() are holding the 'state_lock' to avoid the race in setting th
bus: mhi: ep: Protect mhi_ep_handle_syserr() in the error path
All the callers of mhi_ep_handle_syserr() except mhi_ep_process_cmd_ring() are holding the 'state_lock' to avoid the race in setting the MHI state. So do the same in mhi_ep_process_cmd_ring() for sanity.
Fixes: e827569062a8 ("bus: mhi: ep: Add support for processing command rings") Cc: stable@vger.kernel.org # 5.18 Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> Link: https://patch.msgid.link/20260302085612.18725-1-manivannan.sadhasivam@oss.qualcomm.com
show more ...
|
| ce3e534e | 14-Apr-2026 |
Sumit Kumar <sumit.kumar@oss.qualcomm.com> |
bus: mhi: ep: Add missing state_lock protection for mhi_state access
The mhi_cntrl->mhi_state field should be protected by state_lock to ensure atomic state transitions. However, mhi_ep_power_up() a
bus: mhi: ep: Add missing state_lock protection for mhi_state access
The mhi_cntrl->mhi_state field should be protected by state_lock to ensure atomic state transitions. However, mhi_ep_power_up() access mhi_state without holding this lock, which can race with concurrent state transitions and lead to state corruption.
Add proper state_lock protection around mhi_state access.
Fixes: fb3a26b7e8af ("bus: mhi: ep: Add support for powering up the MHI endpoint stack") Fixes: f7d0806bdb1b3 ("bus: mhi: ep: Add support for handling SYS_ERR condition") Signed-off-by: Sumit Kumar <sumit.kumar@oss.qualcomm.com> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> Link: https://patch.msgid.link/20260414-reset_worker_deadlock-v2-2-42fd682b45db@oss.qualcomm.com
show more ...
|
| 9e24bdfe | 06-Nov-2025 |
Marco Crivellari <marco.crivellari@suse.com> |
bus: mhi: ep: add WQ_PERCPU to alloc_workqueue users
Currently if a user enqueue a work item using schedule_delayed_work() the used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use WORK
bus: mhi: ep: add WQ_PERCPU to alloc_workqueue users
Currently if a user enqueue a work item using schedule_delayed_work() the used wq is "system_wq" (per-cpu wq) while queue_delayed_work() use WORK_CPU_UNBOUND (used when a cpu is not specified). The same applies to schedule_work() that is using system_wq and queue_work(), that makes use again of WORK_CPU_UNBOUND. This lack of consistency cannot be addressed without refactoring the API.
alloc_workqueue() treats all queues as per-CPU by default, while unbound workqueues must opt-in via WQ_UNBOUND.
This default is suboptimal: most workloads benefit from unbound queues, allowing the scheduler to place worker threads where they’re needed and reducing noise when CPUs are isolated.
This continues the effort to refactor workqueue APIs, which began with the introduction of new workqueues and a new alloc_workqueue flag in:
commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq") commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
This change adds a new WQ_PERCPU flag to explicitly request alloc_workqueue() to be per-cpu when WQ_UNBOUND has not been specified.
With the introduction of the WQ_PERCPU flag (equivalent to !WQ_UNBOUND), any alloc_workqueue() caller that doesn’t explicitly specify WQ_UNBOUND must now use WQ_PERCPU.
Once migration is complete, WQ_UNBOUND can be removed and unbound will become the implicit default.
Suggested-by: Tejun Heo <tj@kernel.org> Signed-off-by: Marco Crivellari <marco.crivellari@suse.com> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> Link: https://patch.msgid.link/20251106162430.328701-1-marco.crivellari@suse.com
show more ...
|
| 309ab14f | 27-Nov-2023 |
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
bus: mhi: ep: Add checks for read/write callbacks while registering controllers
The MHI EP controller drivers has to support both sync and async read/write callbacks. Hence, add a check for it.
Sig
bus: mhi: ep: Add checks for read/write callbacks while registering controllers
The MHI EP controller drivers has to support both sync and async read/write callbacks. Hence, add a check for it.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
show more ...
|
| 2547beb0 | 21-Aug-2023 |
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
bus: mhi: ep: Add support for async DMA read operation
As like the async DMA write operation, let's add support for async DMA read operation. In the async path, the data will be read from the transf
bus: mhi: ep: Add support for async DMA read operation
As like the async DMA write operation, let's add support for async DMA read operation. In the async path, the data will be read from the transfer ring continuously and when the controller driver notifies the stack using the completion callback (mhi_ep_read_completion), then the client driver will be notified with the read data and the completion event will be sent to the host for the respective ring element (if requested by the host).
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
show more ...
|