bus: mhi: ep: Do not allocate event ring element on stack
[ Upstream commit 987fdb5a43a66764808371b54e6047834170d565 ]
It is possible that the host controller driver would use DMA framework to
write the event ring element. So avoid allocating event ring element on the
stack as DMA cannot work on vmalloc memory.
Cc: stable@vger.kernel.org
Fixes: 961aeb6892
("bus: mhi: ep: Add support for sending events to the host")
Link: https://lore.kernel.org/r/20230901073502.69385-1-manivannan.sadhasivam@linaro.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
512fc4d735
commit
ea3357c6cf
@ -71,45 +71,77 @@ static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx,
|
||||
static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
|
||||
struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code)
|
||||
{
|
||||
struct mhi_ring_element event = {};
|
||||
struct mhi_ring_element *event;
|
||||
int ret;
|
||||
|
||||
event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre));
|
||||
event.dword[0] = MHI_TRE_EV_DWORD0(code, len);
|
||||
event.dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
|
||||
event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
|
||||
if (!event)
|
||||
return -ENOMEM;
|
||||
|
||||
return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event, MHI_TRE_DATA_GET_BEI(tre));
|
||||
event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre));
|
||||
event->dword[0] = MHI_TRE_EV_DWORD0(code, len);
|
||||
event->dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
|
||||
|
||||
ret = mhi_ep_send_event(mhi_cntrl, ring->er_index, event, MHI_TRE_DATA_GET_BEI(tre));
|
||||
kfree(event);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state)
|
||||
{
|
||||
struct mhi_ring_element event = {};
|
||||
struct mhi_ring_element *event;
|
||||
int ret;
|
||||
|
||||
event.dword[0] = MHI_SC_EV_DWORD0(state);
|
||||
event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
|
||||
event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
|
||||
if (!event)
|
||||
return -ENOMEM;
|
||||
|
||||
return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
|
||||
event->dword[0] = MHI_SC_EV_DWORD0(state);
|
||||
event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
|
||||
|
||||
ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
|
||||
kfree(event);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env)
|
||||
{
|
||||
struct mhi_ring_element event = {};
|
||||
struct mhi_ring_element *event;
|
||||
int ret;
|
||||
|
||||
event.dword[0] = MHI_EE_EV_DWORD0(exec_env);
|
||||
event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
|
||||
event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
|
||||
if (!event)
|
||||
return -ENOMEM;
|
||||
|
||||
return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
|
||||
event->dword[0] = MHI_EE_EV_DWORD0(exec_env);
|
||||
event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
|
||||
|
||||
ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
|
||||
kfree(event);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code)
|
||||
{
|
||||
struct mhi_ep_ring *ring = &mhi_cntrl->mhi_cmd->ring;
|
||||
struct mhi_ring_element event = {};
|
||||
struct mhi_ring_element *event;
|
||||
int ret;
|
||||
|
||||
event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element));
|
||||
event.dword[0] = MHI_CC_EV_DWORD0(code);
|
||||
event.dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
|
||||
event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
|
||||
if (!event)
|
||||
return -ENOMEM;
|
||||
|
||||
return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
|
||||
event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element));
|
||||
event->dword[0] = MHI_CC_EV_DWORD0(code);
|
||||
event->dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
|
||||
|
||||
ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
|
||||
kfree(event);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_element *el)
|
||||
|
Loading…
Reference in New Issue
Block a user