From 8e1741c658996a16bd096e077dae0da2460a997f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 10 Feb 2022 13:33:43 +0100
Subject: ALSA: memalloc: Fix dma_need_sync() checks

dma_need_sync() checks each DMA address.  Fix the incorrect usages
for non-contiguous and non-coherent page allocations.
Fortunately, there are no actual call sites that need manual syncs
yet.

Fixes: a25684a95646 ("ALSA: memalloc: Support for non-contiguous page allocation")
Fixes: 73325f60e2ed ("ALSA: memalloc: Support for non-coherent page allocation")
Cc: <stable@vger.kernel.org>
Reported-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Link: https://lore.kernel.org/r/20220210123344.8756-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/memalloc.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

(limited to 'sound/core/memalloc.c')

diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index d1fcd1d5adae..f98f694e3ce4 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -511,7 +511,8 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
 				      DEFAULT_GFP, 0);
 	if (!sgt)
 		return NULL;
-	dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir);
+	dmab->dev.need_sync = dma_need_sync(dmab->dev.dev,
+					    sg_dma_address(sgt->sgl));
 	p = dma_vmap_noncontiguous(dmab->dev.dev, size, sgt);
 	if (p)
 		dmab->private_data = sgt;
@@ -671,9 +672,13 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
  */
 static void *snd_dma_noncoherent_alloc(struct snd_dma_buffer *dmab, size_t size)
 {
-	dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir);
-	return dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr,
-				     dmab->dev.dir, DEFAULT_GFP);
+	void *p;
+
+	p = dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr,
+				  dmab->dev.dir, DEFAULT_GFP);
+	if (p)
+		dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->addr);
+	return p;
 }
 
 static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab)
-- 
cgit v1.2.3


From 3e16dc50d77dc3494275a241fac250c94bf45206 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Thu, 10 Feb 2022 13:33:44 +0100
Subject: ALSA: memalloc: invalidate SG pages before sync

It seems that calling invalidate_kernel_vmap_range() is more correct
to be called before dma_sync_*(), judging from the other thread:
  https://lore.kernel.org/all/20220111085958.GA22795@lst.de/
Although this won't matter much in practice, let's fix the call order
for consistency.

Fixes: a25684a95646 ("ALSA: memalloc: Support for non-contiguous page allocation")
Reported-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220210123344.8756-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/memalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'sound/core/memalloc.c')

diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index f98f694e3ce4..6fd763d4d15b 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -541,9 +541,9 @@ static void snd_dma_noncontig_sync(struct snd_dma_buffer *dmab,
 	if (mode == SNDRV_DMA_SYNC_CPU) {
 		if (dmab->dev.dir == DMA_TO_DEVICE)
 			return;
+		invalidate_kernel_vmap_range(dmab->area, dmab->bytes);
 		dma_sync_sgtable_for_cpu(dmab->dev.dev, dmab->private_data,
 					 dmab->dev.dir);
-		invalidate_kernel_vmap_range(dmab->area, dmab->bytes);
 	} else {
 		if (dmab->dev.dir == DMA_FROM_DEVICE)
 			return;
-- 
cgit v1.2.3