mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-17 18:36:00 +00:00
ASoC: Intel: Skylake: Fix IPC rx_list corruption
In SKL+ platforms, all IPC commands are serialised, i.e. the driver sends a new IPC to DSP, only after receiving a reply from the firmware for the current IPC. Hence it seems apparent that there is only a single modifier of the IPC RX List. However, during an IPC timeout case in a multithreaded environment, there is a possibility of the list element being deleted two times if not properly protected. So, use spin lock save/restore to prevent rx_list corruption. Signed-off-by: Pardha Saradhi K <pardha.saradhi.kesapragada@intel.com> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
ab1b732d53
commit
5cd1f5c321
@ -413,8 +413,11 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
|
|||||||
u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
|
u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
|
||||||
u64 *ipc_header = (u64 *)(&header);
|
u64 *ipc_header = (u64 *)(&header);
|
||||||
struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
|
struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
|
||||||
msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
|
msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
|
||||||
|
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
dev_dbg(ipc->dev, "ipc: rx list is empty\n");
|
dev_dbg(ipc->dev, "ipc: rx list is empty\n");
|
||||||
return;
|
return;
|
||||||
@ -456,8 +459,10 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
|
||||||
list_del(&msg->list);
|
list_del(&msg->list);
|
||||||
sst_ipc_tx_msg_reply_complete(ipc, msg);
|
sst_ipc_tx_msg_reply_complete(ipc, msg);
|
||||||
|
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
|
irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user