Skip to content

Commit 8576b65

Browse files
committed
zephyr: userspace: sof_dma: allow circular SG lists
Allow a non-null pointer at the end of the DMA transfer block list, if and only if it points to the first entry in the block list. The SOF DAI module sets the DMA transfers blocks like this and this change is required to use DAI module from user-space. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent d845f84 commit 8576b65

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

zephyr/syscall/sof_dma.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,28 @@ static inline void z_vrfy_sof_dma_release_channel(struct sof_dma *dma,
109109
*/
110110
static inline struct dma_block_config *deep_copy_dma_blk_cfg_list(struct dma_config *cfg)
111111
{
112-
struct dma_block_config *kern_cfg =
113-
rmalloc(0, sizeof(*kern_cfg) * cfg->block_count);
112+
struct dma_block_config *kern_cfg;
114113
struct dma_block_config *kern_prev = NULL, *kern_next, *user_next;
115114
int i = 0;
116115

116+
if (!cfg->block_count)
117+
return NULL;
118+
119+
kern_cfg = rmalloc(0, sizeof(*kern_cfg) * cfg->block_count);
117120
if (!kern_cfg)
118121
return NULL;
119122

120123
for (user_next = cfg->head_block, kern_next = kern_cfg;
121124
user_next;
122-
user_next = user_next->next_block, kern_next++) {
123-
if (++i > cfg->block_count)
124-
goto err;
125+
user_next = user_next->next_block, kern_next++, i++) {
126+
if (i == cfg->block_count) {
127+
/* last block can point to first one */
128+
if (user_next != cfg->head_block)
129+
goto err;
130+
131+
kern_prev->next_block = kern_cfg;
132+
break;
133+
}
125134

126135
if (k_usermode_from_copy(kern_next, user_next, sizeof(*kern_next)))
127136
goto err;

0 commit comments

Comments
 (0)