Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 789d6ef4 authored by Ghanim Fodi's avatar Ghanim Fodi
Browse files

msm: ipa: Protect the access to LAN CONS client notification call-back



When a packet is received on LAN_CONS pipe, IPA driver will notify the
source EP driver with a packet received event notification.
This is done via calling the source EP notification call-back.
There could be a race condition with calling the call-back and nullifing
it by other execution thread. For example, on EP disconnect. Spin lock
is being used to protect this access.

CRs-Fixed: 857971
Change-Id: I7b142c791e11507c18a5b346bbf22623ac57cbad
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent 23ed8497
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -2176,6 +2176,15 @@ static int ipa_setup_apps_pipes(void)
	} else {
		WARN_ON(1);
	}

	/**
	 * ipa_lan_rx_cb() intended to notify the source EP about packet
	 * being received on the LAN_CONS via calling the source EP call-back.
	 * There could be a race condition with calling this call-back. Other
	 * thread may nullify it - e.g. on EP disconnect.
	 * This lock intended to protect the access to the source EP call-back
	 */
	spin_lock_init(&ipa_ctx->lan_rx_clnt_notify_lock);
	if (ipa_setup_sys_pipe(&sys_in, &ipa_ctx->clnt_hdl_data_in)) {
		IPAERR(":setup sys pipe failed.\n");
		result = -EPERM;
+2 −0
Original line number Diff line number Diff line
@@ -539,7 +539,9 @@ int ipa_disconnect(u32 clnt_hdl)

	ipa_delete_dflt_flt_rules(clnt_hdl);

	spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock);
	memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context));
	spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock);

	ipa_dec_client_disable_clks();

+3 −0
Original line number Diff line number Diff line
@@ -2259,11 +2259,13 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys)
		src_pipe = WLAN_PROD_TX_EP;

	ep = &ipa_ctx->ep[src_pipe];
	spin_lock(&ipa_ctx->lan_rx_clnt_notify_lock);
	if (unlikely(src_pipe >= ipa_ctx->ipa_num_pipes ||
		!ep->valid || !ep->client_notify)) {
		IPAERR("drop pipe=%d ep_valid=%d client_notify=%p\n",
		  src_pipe, ep->valid, ep->client_notify);
		dev_kfree_skb_any(rx_skb);
		spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock);
		return 0;
	}

@@ -2282,6 +2284,7 @@ static int ipa_rx_pyld_hdlr(struct sk_buff *rx_skb, struct ipa_sys_context *sys)
	skb_pull(rx_skb, pull_len);
	ep->client_notify(ep->priv, IPA_RECEIVE,
			(unsigned long)(rx_skb));
	spin_unlock(&ipa_ctx->lan_rx_clnt_notify_lock);
	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -1106,6 +1106,7 @@ struct ipa_sps_pm {
 * @tag_process_before_gating: indicates whether to start tag process before
 *  gating IPA clocks
 * @sps_pm: sps power management related information
 * @lan_rx_clnt_notify_lock: protects LAN_CONS packet receive notification CB
 * @pipe_mem_pool: pipe memory pool
 * @dma_pool: special purpose DMA pool
 * @ipa_active_clients: structure for reference counting connected IPA clients
@@ -1184,6 +1185,7 @@ struct ipa_context {
	u32 clnt_hdl_cmd;
	u32 clnt_hdl_data_in;
	u32 clnt_hdl_data_out;
	spinlock_t lan_rx_clnt_notify_lock;
	u8 a5_pipe_index;
	struct list_head intf_list;
	struct list_head msg_list;