diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index d9bd57f9b3b2..6663e79dc528 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1367,10 +1367,6 @@ int gsi_register_device(struct gsi_per_props *props, unsigned long *dev_hdl) gsi_writel(0, gsi_ctx->base + GSI_EE_n_ERROR_LOG_OFFS(gsi_ctx->per.ee)); - /* Reset to zero scratch_1 register*/ - gsi_writel(0, gsi_ctx->base + - GSI_EE_n_CNTXT_SCRATCH_1_OFFS(gsi_ctx->per.ee)); - if (running_emulation) { /* * Set up the emulator's interrupt controller... diff --git a/drivers/platform/msm/gsi/gsi_reg_v1.h b/drivers/platform/msm/gsi/gsi_reg_v1.h index ee3de12fa3f8..8d3052f4db34 100644 --- a/drivers/platform/msm/gsi/gsi_reg_v1.h +++ b/drivers/platform/msm/gsi/gsi_reg_v1.h @@ -1177,11 +1177,6 @@ #define GSI_EE_n_CNTXT_SCRATCH_0_SCRATCH_BMSK 0xffffffff #define GSI_EE_n_CNTXT_SCRATCH_0_SCRATCH_SHFT 0x0 -#define GSI_EE_n_CNTXT_SCRATCH_1_OFFS(n) \ - (GSI_GSI_REG_BASE_OFFS + 0x0001f404 + 0x4000 * (n)) -#define GSI_EE_n_CNTXT_SCRATCH_1_SCRATCH_BMSK 0xffffffff -#define GSI_EE_n_CNTXT_SCRATCH_1_SCRATCH_SHFT 0x0 - #define GSI_INTER_EE_n_SRC_GSI_CH_IRQ_OFFS(n) \ (GSI_GSI_REG_BASE_OFFS + 0x0000c018 + 0x1000 * (n)) #define GSI_INTER_EE_n_SRC_GSI_CH_IRQ_GSI_CH_BIT_MAP_BMSK 0xffffffff diff --git a/drivers/platform/msm/gsi/gsi_reg_v2.h b/drivers/platform/msm/gsi/gsi_reg_v2.h index 11ce1c435969..459c0ba7c42f 100644 --- a/drivers/platform/msm/gsi/gsi_reg_v2.h +++ b/drivers/platform/msm/gsi/gsi_reg_v2.h @@ -1180,11 +1180,6 @@ #define GSI_EE_n_CNTXT_SCRATCH_0_SCRATCH_BMSK 0xffffffff #define GSI_EE_n_CNTXT_SCRATCH_0_SCRATCH_SHFT 0x0 -#define GSI_EE_n_CNTXT_SCRATCH_1_OFFS(n) \ - (GSI_GSI_REG_BASE_OFFS + 0x00012404 + 0x4000 * (n)) -#define GSI_EE_n_CNTXT_SCRATCH_1_SCRATCH_BMSK 0xffffffff -#define GSI_EE_n_CNTXT_SCRATCH_1_SCRATCH_SHFT 0x0 - #define GSI_INTER_EE_n_SRC_GSI_CH_IRQ_OFFS(n) \ (GSI_GSI_REG_BASE_OFFS + 0x0000c018 + 0x1000 * (n)) #define GSI_INTER_EE_n_SRC_GSI_CH_IRQ_GSI_CH_BIT_MAP_BMSK 0xffffffff diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 7d6b5802dfb0..1f63f9b26f3e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -1005,6 +1005,7 @@ static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1043,6 +1044,24 @@ static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_add_rt_rule_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_add_rt_rule_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1082,6 +1101,8 @@ static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1097,6 +1118,7 @@ static int ipa3_ioctl_add_rt_rule_ext_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, @@ -1138,6 +1160,24 @@ static int ipa3_ioctl_add_rt_rule_ext_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_add_rt_rule_ext_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule_ext_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_add_rt_rule_ext_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1179,6 +1219,8 @@ static int ipa3_ioctl_add_rt_rule_ext_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1194,6 +1236,7 @@ static int ipa3_ioctl_add_rt_rule_after_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1234,6 +1277,23 @@ static int ipa3_ioctl_add_rt_rule_after_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_add_rt_rule_after_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule_after_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_add_rt_rule_after_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1273,6 +1333,8 @@ static int ipa3_ioctl_add_rt_rule_after_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1288,6 +1350,7 @@ static int ipa3_ioctl_mdfy_rt_rule_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1328,6 +1391,23 @@ static int ipa3_ioctl_mdfy_rt_rule_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_mdfy_rt_rule_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_mdfy_rt_rule_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1367,6 +1447,8 @@ static int ipa3_ioctl_mdfy_rt_rule_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1382,6 +1464,7 @@ static int ipa3_ioctl_add_flt_rule_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1421,6 +1504,23 @@ static int ipa3_ioctl_add_flt_rule_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_add_flt_rule_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_add_flt_rule_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1459,6 +1559,8 @@ static int ipa3_ioctl_add_flt_rule_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1474,6 +1576,7 @@ static int ipa3_ioctl_add_flt_rule_after_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1514,6 +1617,23 @@ static int ipa3_ioctl_add_flt_rule_after_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_add_flt_rule_after_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule_after_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_add_flt_rule_after_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1553,6 +1673,8 @@ static int ipa3_ioctl_add_flt_rule_after_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; @@ -1568,6 +1690,7 @@ static int ipa3_ioctl_mdfy_flt_rule_v2(unsigned long arg) u32 pyld_sz; u64 uptr = 0; u8 *param = NULL; + u8 *param2 = NULL; u8 *kptr = NULL; if (copy_from_user(header, (const void __user *)arg, @@ -1608,6 +1731,23 @@ static int ipa3_ioctl_mdfy_flt_rule_v2(unsigned long arg) retval = -EFAULT; goto free_param_kptr; } + + param2 = memdup_user((const void __user *)arg, + sizeof(struct ipa_ioc_mdfy_flt_rule_v2)); + if (IS_ERR(param2)) { + retval = -EFAULT; + goto free_param_kptr; + } + + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule_v2 *)param2)->num_rules + != pre_entry)) { + IPAERR_RL("current %d pre %d\n", + ((struct ipa_ioc_mdfy_flt_rule_v2 *)param2)-> + num_rules, pre_entry); + retval = -EFAULT; + goto free_param_kptr; + } /* alloc kernel pointer with actual payload size */ kptr = kzalloc(pyld_sz, GFP_KERNEL); if (!kptr) { @@ -1647,6 +1787,8 @@ static int ipa3_ioctl_mdfy_flt_rule_v2(unsigned long arg) free_param_kptr: if (!IS_ERR(param)) kfree(param); + if (!IS_ERR(param2)) + kfree(param2); kfree(kptr); return retval; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c index 4aeab4968f2a..f71b4346b186 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c @@ -1078,7 +1078,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl) list_del(&entry->link); entry->tbl->rule_cnt--; - if (entry->rt_tbl) + if (entry->rt_tbl && !ipa3_check_idr_if_freed(entry->rt_tbl)) entry->rt_tbl->ref_cnt--; IPADBG("del flt rule rule_cnt=%d rule_id=%d\n", entry->tbl->rule_cnt, entry->rule_id); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c index 4fd5ccc7604a..3ae0f9976cf8 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hw_stats.c @@ -1533,6 +1533,9 @@ int ipa_drop_stats_init(void) /* Always enable drop stats for USB DPL Pipe. */ pipe_bitmask |= IPA_CLIENT_BIT_32(IPA_CLIENT_USB_DPL_CONS); + /* Always enable drop stats for ODL DPL Pipe. */ + pipe_bitmask |= IPA_CLIENT_BIT_32(IPA_CLIENT_ODL_DPL_CONS); + /* Currently we have option to enable drop stats using debugfs. * To enable drop stats for a different pipe, first user needs * to query drop stats to get the current stats and enable. diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 4d00cf315deb..8ff6f6b28b6c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -2281,6 +2281,12 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 12, 4, 4, 4, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY} }, + [IPA_4_2][IPA_CLIENT_ODL_DPL_CONS] = { + true, IPA_v4_2_GROUP_UL_DL, + false, + IPA_DPS_HPS_SEQ_TYPE_INVALID, + QMB_MASTER_SELECT_DDR, + { 13, 10, 6, 6, IPA_EE_AP, GSI_ESCAPE_BUF_ONLY} }, [IPA_4_2][IPA_CLIENT_APPS_LAN_CONS] = { true, IPA_v4_2_GROUP_UL_DL, false, @@ -2305,12 +2311,6 @@ static const struct ipa_ep_configuration ipa3_ep_mapping IPA_DPS_HPS_SEQ_TYPE_INVALID, QMB_MASTER_SELECT_DDR, { 10, 2, 6, 6, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY} }, - [IPA_4_2][IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS] = { - true, IPA_v4_2_GROUP_UL_DL, - false, - IPA_DPS_HPS_SEQ_TYPE_INVALID, - QMB_MASTER_SELECT_DDR, - { 13, 4, 6, 6, IPA_EE_Q6, GSI_ESCAPE_BUF_ONLY} }, [IPA_4_2][IPA_CLIENT_ETHERNET_CONS] = { true, IPA_v4_2_GROUP_UL_DL, false, @@ -8784,6 +8784,8 @@ void ipa3_force_close_coal(void) int ipa3_suspend_apps_pipes(bool suspend) { int res; + struct ipa_ep_cfg_holb holb_cfg; + int odl_ep_idx; /* As per HPG first need start/stop coalescing channel * then default one. Coalescing client number was greater then @@ -8805,6 +8807,24 @@ int ipa3_suspend_apps_pipes(bool suspend) if (res == -EAGAIN) goto undo_odl_cons; + odl_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_ODL_DPL_CONS); + if (odl_ep_idx != IPA_EP_NOT_ALLOCATED && ipa3_ctx->ep[odl_ep_idx].valid) { + memset(&holb_cfg, 0, sizeof(holb_cfg)); + if (suspend) + holb_cfg.en = 0; + else + holb_cfg.en = 1; + + ipahal_write_reg_n_fields(IPA_ENDP_INIT_HOL_BLOCK_EN_n, + odl_ep_idx, &holb_cfg); + /* IPA4.5 issue requires HOLB_EN to be written twice */ + if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5 && holb_cfg.en) + ipahal_write_reg_n_fields( + IPA_ENDP_INIT_HOL_BLOCK_EN_n, + odl_ep_idx, &holb_cfg); + + } + res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_LOW_LAT_CONS, suspend); if (res == -EAGAIN)