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

Commit b092b50c authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan
Browse files

drivers: rmnet_shs: Fix invalid mask on vnd creation



For a time after a vnd is created, the shs internal map_mask is updated
to an invalid state. If this happens during data transfer it could cause
invalid cpu states.

This fix will cause the map_mask to only take into acount already initialized
vnd rps values.

Fixes the following-

Unable to handle kernel write to read-only memory at virtual address ffffff99a0b5484c
pc : rmnet_shs_flush_lock_table+0x264/0x688 [rmnet_shs]
lr : rmnet_shs_flush_lock_table+0x238/0x688 [rmnet_shs]
Call trace:
 rmnet_shs_flush_lock_table+0x264/0x688 [rmnet_shs]
 rmnet_shs_chain_to_skb_list+0x320/0x340 [rmnet_shs]
 rmnet_shs_assign+0x980/0x1290 [rmnet_shs]
 rmnet_deliver_skb+0x240/0x410
 rmnet_frag_deliver+0x618/0x778
 rmnet_perf_core_flush_curr_pkt+0x12c/0x148 [rmnet_perf]
 rmnet_perf_tcp_opt_ingress+0x88/0x268 [rmnet_perf]
 rmnet_perf_opt_ingress+0x348/0x398 [rmnet_perf]
 rmnet_perf_core_desc_entry+0x128/0x180 [rmnet_perf]
 rmnet_frag_ingress_handler+0x3a8/0x578
 rmnet_rx_handler+0x230/0x400
 __netif_receive_skb_core+0x518/0xd60
 process_backlog+0x1d4/0x438
 net_rx_action+0x124/0x5b8
 __do_softirq+0x2f8/0x5d8
 irq_exit+0xec/0x110
 handle_IPI+0x1b8/0x2f8
 gic_handle_irq+0x10c/0x1d0
 el0_irq_naked+0x50/0x5c

Change-Id: I4c10ebb83140eb14ee3b643d057e3de29dfa851b
Acked-by: default avatarRaul Martinez <mraul@qti.qualcomm.com>
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent c9350693
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1875,20 +1875,31 @@ void rmnet_shs_update_cfg_mask(void)
{
	/* Start with most avaible mask all eps could share*/
	u8 mask = UPDATE_MASK;
	u8 rps_enabled = 0;
	struct rmnet_shs_wq_ep_s *ep;

	list_for_each_entry(ep, &rmnet_shs_wq_ep_tbl, ep_list_id) {

		if (!ep->is_ep_active)
			continue;
		/* Bitwise and to get common mask  VNDs with different mask
		 * will have UNDEFINED behavior
		/* Bitwise and to get common mask from non-null masks.
		 * VNDs with different mask  will have UNDEFINED behavior
		 */
		if (ep->rps_config_msk) {
			mask &= ep->rps_config_msk;
			rps_enabled = 1;
		}
	}

	if (!rps_enabled) {
		rmnet_shs_cfg.map_mask = 0;
		rmnet_shs_cfg.map_len = 0;
		return;
        } else if (rmnet_shs_cfg.map_mask != mask) {
		rmnet_shs_cfg.map_mask = mask;
		rmnet_shs_cfg.map_len = rmnet_shs_get_mask_len(mask);
	}
}

void rmnet_shs_wq_update_stats(void)
{