diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index 4636aef29300..bb61c78e5c29 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2797,8 +2797,8 @@ static const char *ath12k_qmi_get_mem_reg_name(int mem_type) static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab) { struct device_node *np = ab->dev->of_node; + size_t avail_rmem_size, offset = 0; struct target_mem_chunk *chunk; - size_t avail_rmem_size; struct resource res; const char *rname; int i, idx, ret; @@ -2832,9 +2832,20 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab) goto out; avail_rmem_size = resource_size(&res); - if (chunk->type == BDF_MEM_REGION_TYPE) { - avail_rmem_size -= ab->hw_params->bdf_addr_offset; - res.start += ab->hw_params->bdf_addr_offset; + if (chunk->type == BDF_MEM_REGION_TYPE || + chunk->type == HOST_DDR_REGION_TYPE) { + if (ab->hw_params->bdf_addr_offset > avail_rmem_size || + offset > avail_rmem_size - ab->hw_params->bdf_addr_offset) { + ath12k_err(ab, "qmi mem offset overflow: bdf_offset=%u offset=%zu size=%zu\n", + ab->hw_params->bdf_addr_offset, offset, + avail_rmem_size); + ret = -EINVAL; + goto out; + } + + avail_rmem_size -= ab->hw_params->bdf_addr_offset + offset; + res.start += ab->hw_params->bdf_addr_offset + offset; + offset += chunk->size; } if (avail_rmem_size < chunk->size) {