From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9DEE6CA5FAD for ; Tue, 29 Sep 2026 02:59:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=hOMETCPD6rhV8uZSv0/8O7XOYDjSnTdePZNVI177FQs=; b=k9VVLhh1o1z+Om/FFBfq7Fiejg sHrRHM4RotrvUDX7jJoujy7gyfjAT2/k87xqvJ2DUSkJ4CRESXoaC8e2AhPQElIDPeyiba9tkSJjv 9i3KJqUAqlFb+YNjCDXPZuMrXOvxO74V2uGrQHwpb9O9REh0xRzYatq7xy+f8VxBIBHEuTQG0eXj7 B6cwGDTu6VhSWmPTbYo+nQBMFqbsarpX006ep4efr1eR3gyiOERHUuH8a0NrazSr7t1JYTwioLynD qDx/idczGSgOpIGDk1nN1LKndchQzoy/eOy36k0bNK/6+vKxR4ZZdi9UMmWtWIGnuyXIvgqRZoRus DX+nrTPw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1xBO3f-00000002A5r-0enV; Tue, 29 Sep 2026 02:59:07 +0000 Received: from mail-dy2-x0f.google.com ([2607:f8b0:4864:36::f]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1xBO3c-00000002A4w-0dkM for ath12k@lists.infradead.org; Tue, 29 Sep 2026 02:59:05 +0000 Received: by mail-dy2-x0f.google.com with SMTP id 5a478bee46e88-33e62211987so3799085eec.2 for ; Mon, 28 Sep 2026 19:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trailofbits.com; s=google; t=1790650743; x=1791255543; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hOMETCPD6rhV8uZSv0/8O7XOYDjSnTdePZNVI177FQs=; b=XJ/Joz6sN9esbkk2WO2tUm06rP9JJdqxCko1atDqDhQv/6Mb9gozywBGS5wAlO/mGN 1rSF648hpQW0sIQwJnwBl/AX+XiR/ugCV5Hjg/BaNz8G35D6bivMIeREvPtQUKfWj0Pt cvOzw6lywGXkQrZtbjDSI38fWQpMfwijgRZ871xWMqmmA/BJVyWktFXLIpCjYN49uHy9 oXGaiezDr0r/ZFu2jqMoTM6gdreg0HpQ/as7UUpxMeeVPJGfLWC1dwKM34KgaL5Ajmhh RbWKYgCe+Qh4eIFKrbjkOhAPMo45G5XZSoD77o5Q6oehP57XeajSEJuLrgmsI1OyGN4l FcgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790650743; x=1791255543; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=hOMETCPD6rhV8uZSv0/8O7XOYDjSnTdePZNVI177FQs=; b=oiey25neDtKTTzD0hFGp4no2wo/kD8SVFCbuZrZPCyyfmwVfXU2xMlzdl1TUWNQVM0 6qkANQRcb5FAiuDDDmnDjIB8hC2hspNpjtVkx4/BrFgRGzBZ6AqcoX+364Lulgfi7vqo 7dI/ZWkK7N1Xt6y2PtnVDpdtFiWLQf70qwJ0fpBgV1wB3sM//c14FakL68TQsjZ6F7Kn qYI/ZazDg0aclSDIF+jXv0+bUKMp87v8uMDkjfk45QyHVRQBF4gJW0mnM0hQoMFP+Q5V fpfYVUa794gYSu8dFVgjQDk1141BGCaYVAAEap25LfAJnpMht+m/A99TLeaJzu3bKIFe oAlQ== X-Forwarded-Encrypted: i=1; AKwUvBx6n++0bzvkxCXhz4UrwRs3jMoXvqynukHqOPyatdE8DdsyhpLVd/7ANEF9Pi6UdnilMZdPf58=@lists.infradead.org X-Gm-Message-State: AFq9FYIRSjs0iXhzPlOfxosy3gdqSxq3G232xZIlXjjPurezbEZuylIj IEJ6tLuXorIS390mGK7suRxZBUbWmG2pEmgtin74NonnHSNizdVWsqTXGdHfV7KRV1M= X-Gm-Gg: AYBFou11Pg8R9ybwbQKwFsy31sqe1RyTdA9/5mWDu6O433mSw1bjdaqFw3i+MxTkcwn Uyd3jbL/EHE4USvvBP3f8op9B8QaHjnd2XuTvS6KMKmJGObJb2+iK4t6eXzp23IJES3xMVCSSnG tfD9cZULuU2akS3iyCtxeAY9aXji3Uh/yB2QX7OB7fzATkXU2p7xBRESfUCkNZAfpz2b+8+LNVy iRFy8jGwjjTAl4MFXSbA6OlYKfqgA8sO3PMIDxf2SCWRapd9XN0XsJ0kv7pSC89dEOeRiYwOG2P tivn3t4N7B459Sq7U6MWa6QXEINgzKjAOlhl6WyMs/1VPM86YN9+IbK3p7vCSYLk2ormx/bg7UA 12GhpVLs38YEuU+aFx4pJc84SV5EsPeUdEx7jvCD2DAEHIV2/VFBI9tMOATRJPiIfv9owhMFfF+ +Vk3dbLjHBDf7Fv3/5+AJ7zqScYYiIXo7ArfV+HRKNQDUr7Yi9cZ+cToJmofYzzD7xqoW/lStfK I8/jEZTOC/xZGx5AnJGyBlg7jsj6k/2LJrNrSjbFDeMPk2UcRfbxeccgwFQWgX5PRzpZvY= X-Received: by 2002:a05:693c:20c9:10b0:343:4ed7:6825 with SMTP id 5a478bee46e88-3434ed76a39mr10306743eec.41.1790650743013; Mon, 28 Sep 2026 19:59:03 -0700 (PDT) Received: from localhost.localdomain ([2603:8001:5f01:8bab:3481:cbb6:f339:9e4e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-34571658054sm13111683eec.8.2026.09.28.19.59.01 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 28 Sep 2026 19:59:02 -0700 (PDT) From: Artem Dinaburg To: stable@vger.kernel.org Cc: Artem Dinaburg , Greg Kroah-Hartman , Sasha Levin , Baochen Qiang , Kalle Valo , Jeff Johnson , ath12k@lists.infradead.org, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, quic_jjohnson@quicinc.com, Kalle Valo Subject: [PATCH 6.6.y 1/2] wifi: ath12k: fix kernel crash during resume Date: Mon, 28 Sep 2026 22:58:53 -0400 Message-ID: <20260929025856.85683-2-artem@trailofbits.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260929025856.85683-1-artem@trailofbits.com> References: <20260929025856.85683-1-artem@trailofbits.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260928_195904_199891_E65E456F X-CRM114-Status: GOOD ( 25.34 ) X-BeenThere: ath12k@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "ath12k" Errors-To: ath12k-bounces+ath12k=archiver.kernel.org@lists.infradead.org From: Baochen Qiang [ Upstream commit 303c017821d88ebad887814114d4e5966d320b28 ] Currently during resume, QMI target memory is not properly handled, resulting in kernel crash in case DMA remap is not supported: BUG: Bad page state in process kworker/u16:54 pfn:36e80 page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x36e80 page dumped because: nonzero _refcount Call Trace: bad_page free_page_is_bad_report __free_pages_ok __free_pages dma_direct_free dma_free_attrs ath12k_qmi_free_target_mem_chunk ath12k_qmi_msg_mem_request_cb The reason is: Once ath12k module is loaded, firmware sends memory request to host. In case DMA remap not supported, ath12k refuses the first request due to failure in allocating with large segment size: ath12k_pci 0000:04:00.0: qmi firmware request memory request ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 7077888 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 8454144 ath12k_pci 0000:04:00.0: qmi dma allocation failed (7077888 B type 1), will try later with small size ath12k_pci 0000:04:00.0: qmi delays mem_request 2 ath12k_pci 0000:04:00.0: qmi firmware request memory request Later firmware comes back with more but small segments and allocation succeeds: ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 262144 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 524288 ath12k_pci 0000:04:00.0: qmi mem seg type 4 size 65536 ath12k_pci 0000:04:00.0: qmi mem seg type 1 size 524288 Now ath12k is working. If suspend is triggered, firmware will be reloaded during resume. As same as before, firmware requests two large segments at first. In ath12k_qmi_msg_mem_request_cb() segment count and size are assigned: ab->qmi.mem_seg_count == 2 ab->qmi.target_mem[0].size == 7077888 ab->qmi.target_mem[1].size == 8454144 Then allocation failed like before and ath12k_qmi_free_target_mem_chunk() is called to free all allocated segments. Note the first segment is skipped because its v.addr is cleared due to allocation failure: chunk->v.addr = dma_alloc_coherent() Also note that this leaks that segment because it has not been freed. While freeing the second segment, a size of 8454144 is passed to dma_free_coherent(). However remember that this segment is allocated at the first time firmware is loaded, before suspend. So its real size is 524288, much smaller than 8454144. As a result kernel found we are freeing some memory which is in use and thus crashed. So one possible fix would be to free those segments during suspend. This works because with them freed, ath12k_qmi_free_target_mem_chunk() does nothing: all segment addresses are NULL so dma_free_coherent() is not called. But note that ath11k has similar logic but never hits this issue. Reviewing code there shows the luck comes from QMI memory reuse logic. So the decision is to port it to ath12k. Like in ath11k, the crash is avoided by adding prev_size to target_mem_chunk structure and caching real segment size in it, then prev_size instead of current size is passed to dma_free_coherent(), no unexpected memory is freed now. Also reuse m3 buffer. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0-03427-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.15378.4 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 [ Backport to 6.6.y: carried target-memory reuse and prev_size tracking; the target already retains core resources and reuses M3, whose size check follows in patch 2. ] Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://msgid.link/20240419034034.2842-1-quic_bqiang@quicinc.com Assisted-by: LLM Signed-off-by: Artem Dinaburg --- Hi Greg, Sasha, and wifi ath12k maintainers, I am working through the small CVE backports still missing from 6.6.y. This one addresses CVE-2024-40979. It tracks the actual target-memory allocation sizes across firmware resume requests. The fix is already present in 6.12.y, 6.18.y, and 7.2.y, but not in 6.6.y. The target-specific adjustment is recorded in the bracketed note above. Could you please queue it for 6.6.y? CVE: CVE-2024-40979 Upstream: 303c017821d88ebad887814114d4e5966d320b28 AI assistance: An LLM helped identify, adapt, and validate this backport; I reviewed the resulting code and validation evidence. Thanks, Artem Dinaburg drivers/net/wireless/ath/ath12k/qmi.c | 20 +++++++++++++++++++- drivers/net/wireless/ath/ath12k/qmi.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index c49f585cc39656..7a9868dbab02d7 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2152,8 +2152,9 @@ static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab) for (i = 0; i < ab->qmi.mem_seg_count; i++) { if (!ab->qmi.target_mem[i].v.addr) continue; + dma_free_coherent(ab->dev, - ab->qmi.target_mem[i].size, + ab->qmi.target_mem[i].prev_size, ab->qmi.target_mem[i].v.addr, ab->qmi.target_mem[i].paddr); ab->qmi.target_mem[i].v.addr = NULL; @@ -2179,6 +2180,19 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) case M3_DUMP_REGION_TYPE: case PAGEABLE_MEM_REGION_TYPE: case CALDB_MEM_REGION_TYPE: + /* Firmware reloads in recovery/resume. Reuse an + * unchanged allocation rather than allocating it again. + */ + if (chunk->v.addr) { + if (chunk->prev_type == chunk->type && + chunk->prev_size == chunk->size) + goto this_chunk_done; + + dma_free_coherent(ab->dev, chunk->prev_size, + chunk->v.addr, chunk->paddr); + chunk->v.addr = NULL; + } + chunk->v.addr = dma_alloc_coherent(ab->dev, chunk->size, &chunk->paddr, @@ -2197,6 +2211,10 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) chunk->type, chunk->size); return -ENOMEM; } + + chunk->prev_type = chunk->type; + chunk->prev_size = chunk->size; +this_chunk_done: break; default: ath12k_warn(ab, "memory type %u not supported\n", diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h index 4c1ba3196a403d..a996c6d57aa7b8 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.h +++ b/drivers/net/wireless/ath/ath12k/qmi.h @@ -97,6 +97,8 @@ struct ath12k_qmi_event_msg { struct target_mem_chunk { u32 size; u32 type; + u32 prev_size; + u32 prev_type; dma_addr_t paddr; union { void __iomem *ioaddr; -- 2.39.5