diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 5ba5c7c6fb81..83e65d8799e0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -2569,7 +2569,7 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) spin_lock_bh(&sys->spinlock); rx_pkt = list_first_entry(&sys->rcycl_list, struct ipa3_rx_pkt_wrapper, link); - list_del(&rx_pkt->link); + list_del_init(&rx_pkt->link); spin_unlock_bh(&sys->spinlock); ptr = skb_put(rx_pkt->data.skb, sys->rx_buff_sz); rx_pkt->data.dma_addr = dma_map_single(ipa3_ctx->pdev, @@ -2610,8 +2610,8 @@ static void ipa3_replenish_rx_cache_recycle(struct ipa3_sys_context *sys) goto done; fail_dma_mapping: spin_lock_bh(&sys->spinlock); + ipa3_skb_recycle(rx_pkt->data.skb); list_add_tail(&rx_pkt->link, &sys->rcycl_list); - INIT_LIST_HEAD(&rx_pkt->link); spin_unlock_bh(&sys->spinlock); fail_kmem_cache_alloc: if (rx_len_cached == 0) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index ab04374b3afe..1183d8e275c0 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include "ipa_i.h" @@ -90,6 +90,12 @@ static int ipa3_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, 0 : 1; } } + /* Check the pointer and header length to avoid dangerous overflow in HW */ + if (unlikely(!entry->hdr || !entry->hdr->offset_entry || + !entry->offset_entry || + entry->hdr->hdr_len == 0 || + entry->hdr->hdr_len > ipa_hdr_bin_sz[IPA_HDR_BIN_MAX - 1])) + return -EINVAL; ret = ipahal_cp_proc_ctx_to_hw_buff(entry->type, mem->base, entry->offset_entry->offset, @@ -747,7 +753,7 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) return 0; } - if (entry->is_hdr_proc_ctx) { + if (entry->is_hdr_proc_ctx || entry->proc_ctx) { dma_unmap_single(ipa3_ctx->pdev, entry->phys_base, entry->hdr_len, @@ -1078,6 +1084,7 @@ int ipa3_reset_hdr(bool user_only) if (ipa3_id_find(entry->id) == NULL) { mutex_unlock(&ipa3_ctx->lock); + IPAERR_RL("Invalid header ID\n"); WARN_ON_RATELIMIT_IPA(1); return -EFAULT; } @@ -1088,6 +1095,7 @@ int ipa3_reset_hdr(bool user_only) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); + entry->proc_ctx->hdr = NULL; entry->proc_ctx = NULL; } else { /* move the offset entry to free list */ @@ -1145,6 +1153,7 @@ int ipa3_reset_hdr(bool user_only) if (ipa3_id_find(ctx_entry->id) == NULL) { mutex_unlock(&ipa3_ctx->lock); + IPAERR_RL("Invalid proc header ID\n"); WARN_ON_RATELIMIT_IPA(1); return -EFAULT; } diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 07c9fc828d24..d14a04e22540 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -2965,6 +2965,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, } switch (code) { +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_BEFORE_DS_ENTRY: +#endif case SUBSYS_BEFORE_SHUTDOWN: IPAWANINFO("IPA received MPSS BEFORE_SHUTDOWN\n"); /*Stop netdev first to stop queueing pkts to Q6 */ @@ -2986,6 +2989,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_odl_pipe_cleanup(true); IPAWANINFO("IPA BEFORE_SHUTDOWN handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_AFTER_DS_ENTRY: +#endif case SUBSYS_AFTER_SHUTDOWN: IPAWANINFO("IPA Received MPSS AFTER_SHUTDOWN\n"); if (atomic_read(&rmnet_ipa3_ctx->is_ssr) && @@ -2997,6 +3003,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, IPAWANINFO("IPA AFTER_SHUTDOWN handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_BEFORE_DS_EXIT: +#endif case SUBSYS_BEFORE_POWERUP: IPAWANINFO("IPA received MPSS BEFORE_POWERUP\n"); if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) { @@ -3009,6 +3018,9 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this, ipa3_reset_freeze_vote(); IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n"); break; +#if IS_ENABLED(CONFIG_DEEPSLEEP) + case SUBSYS_AFTER_DS_EXIT: +#endif case SUBSYS_AFTER_POWERUP: IPAWANINFO("IPA received MPSS AFTER_POWERUP\n"); if (!atomic_read(&rmnet_ipa3_ctx->is_initialized) &&