]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: fix reusing m3 memory
authorBaochen Qiang <baochen.qiang@oss.qualcomm.com>
Wed, 29 Oct 2025 02:07:14 +0000 (10:07 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 30 Oct 2025 21:55:07 +0000 (14:55 -0700)
During firmware recovery or suspend/resume, m3 memory could be reused if
the size of the new m3 binary is equal to or less than that of the
existing memory. There will be issues for the latter case, since
m3_mem->size will be updated with a smaller value and this value is
eventually used in the free path, where the original total size should be
used instead.

To fix it, add a new member in m3_mem_region structure to track the original
memory size and use it in free path.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3

Fixes: 05090ae82f44 ("wifi: ath12k: check M3 buffer size as well whey trying to reuse it")
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20251029-ath12k-fix-m3-reuse-v1-1-69225bacfc5d@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/qmi.c
drivers/net/wireless/ath/ath12k/qmi.h

index 36325e62aa2423fcc091d6d447700d6598a16317..8de9aee2498ec55e2065f655993d929ddf696e82 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
 #include <linux/elf.h>
@@ -3114,9 +3114,10 @@ static void ath12k_qmi_m3_free(struct ath12k_base *ab)
        if (!m3_mem->vaddr)
                return;
 
-       dma_free_coherent(ab->dev, m3_mem->size,
+       dma_free_coherent(ab->dev, m3_mem->total_size,
                          m3_mem->vaddr, m3_mem->paddr);
        m3_mem->vaddr = NULL;
+       m3_mem->total_size = 0;
        m3_mem->size = 0;
 }
 
@@ -3152,7 +3153,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
 
        /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
        if (m3_mem->vaddr) {
-               if (m3_mem->size >= m3_len)
+               if (m3_mem->total_size >= m3_len)
                        goto skip_m3_alloc;
 
                /* Old buffer is too small, free and reallocate */
@@ -3164,11 +3165,13 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab)
                                           GFP_KERNEL);
        if (!m3_mem->vaddr) {
                ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
-                          fw->size);
+                          m3_len);
                ret = -ENOMEM;
                goto out;
        }
 
+       m3_mem->total_size = m3_len;
+
 skip_m3_alloc:
        memcpy(m3_mem->vaddr, m3_data, m3_len);
        m3_mem->size = m3_len;
index 4767d9a2e309e48e4a9939296ec99513536af953..7a88268aa1e9e99a13034003cf2ca7d21ccb7573 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 
 #ifndef ATH12K_QMI_H
@@ -120,6 +120,9 @@ struct target_info {
 };
 
 struct m3_mem_region {
+       /* total memory allocated */
+       u32 total_size;
+       /* actual memory being used */
        u32 size;
        dma_addr_t paddr;
        void *vaddr;