All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: Takashi Iwai <tiwai@suse.com>
Cc: Sasha Levin <sashal@kernel.org>, Jaroslav Kysela <perex@perex.cz>,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] ALSA: memalloc: Free the new pages when WC DMA mapping fails
Date: Wed, 28 Oct 2026 10:44:41 -0400	[thread overview]
Message-ID: <20261028144441.992127-1-sashal@kernel.org> (raw)

snd_dma_wc_alloc() keeps the newly allocated pages in a local variable,
and snd_dma_alloc_dir_pages() stores them in dmab->area only after
->alloc() returns.  If dma_map_single() fails, the error path passes
dmab->area to do_free_pages() instead, and that is still NULL at this
point for the usual callers.

The pages are then leaked with their write-combining attribute still
set, set_memory_wb() warns about the zero address, and for buffers
larger than a page free_pages_exact() goes on to free the struct pages
of the bogus addresses 4096, 8192 and so on.  With CONFIG_DEBUG_VM that
hits the VM_BUG_ON() in free_pages():

  kernel BUG at mm/page_alloc.c:5600!
  RIP: 0010:free_pages_exact+0xcb/0xd0
  Call Trace:
   snd_dma_wc_alloc+0x14f/0x160 [snd_pcm]
   snd_dma_alloc_dir_pages+0x4f/0x80 [snd_pcm]

This was reproduced on an x86 guest without swiotlb by allocating
SNDRV_DMA_TYPE_DEV_WC buffers for a device with a 24-bit streaming DMA
mask, so that dma_map_single() fails.

Free the pages that were just allocated.

Fixes: c880a5146642 ("ALSA: memalloc: Use proper DMA mapping API for x86 WC buffer allocations")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/core/memalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 5bc7e586b430f..3118bb14231ce 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -506,7 +506,7 @@ static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
 		return NULL;
 	dmab->addr = dma_map_single(dmab->dev.dev, p, size, DMA_BIDIRECTIONAL);
 	if (dma_mapping_error(dmab->dev.dev, dmab->addr)) {
-		do_free_pages(dmab->area, size, true);
+		do_free_pages(p, size, true);
 		return NULL;
 	}
 	return p;
-- 
2.53.0


                 reply	other threads:[~2026-10-28 14:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028144441.992127-1-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.