diff options
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_flt.c | 8 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_rt.c | 11 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 18 |
4 files changed, 31 insertions, 7 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c index 9afdfdb9292a..060b40a3acc6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -51,7 +51,7 @@ static int ipa3_generate_flt_hw_rule(enum ipa_ip_type ip, memset(&gen_params, 0, sizeof(gen_params)); gen_params.ipt = ip; - if (entry->rt_tbl) + if (entry->rt_tbl && (!ipa3_check_idr_if_freed(entry->rt_tbl))) gen_params.rt_tbl_idx = entry->rt_tbl->idx; else gen_params.rt_tbl_idx = entry->rule.rt_tbl_idx; @@ -1402,7 +1402,9 @@ int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only) entry->ipacm_installed) { 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--; /* if rule id was allocated from idr, remove */ rule_id = entry->rule_id; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 4d6bc6fc859e..7691aa93d544 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -2125,5 +2125,6 @@ struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); struct device *ipa3_get_pdev(void); int ipa3_allocate_dma_task_for_gsi(void); +bool ipa3_check_idr_if_freed(void *ptr); void ipa3_free_dma_task_for_gsi(void); #endif /* _IPA3_I_H_ */ diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c index 659d38e90108..5413e62a75d8 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c @@ -94,6 +94,7 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip, struct ipa3_hdr_proc_ctx_entry *proc_ctx; proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx; if ((proc_ctx == NULL) || + ipa3_check_idr_if_freed(proc_ctx) || (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) { gen_params.hdr_type = IPAHAL_RT_RULE_HDR_NONE; gen_params.hdr_ofst = 0; @@ -731,7 +732,8 @@ struct ipa3_rt_tbl *__ipa3_find_rt_tbl(enum ipa_ip_type ip, const char *name) set = &ipa3_ctx->rt_tbl_set[ip]; list_for_each_entry(entry, &set->head_rt_tbl_list, link) { - if (!strcmp(name, entry->name)) + if (!ipa3_check_idr_if_freed(entry) && + !strcmp(name, entry->name)) return entry; } @@ -1366,7 +1368,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl) if (entry->hdr) __ipa3_release_hdr(entry->hdr->id); - else if (entry->proc_ctx) + else if (entry->proc_ctx && + (!ipa3_check_idr_if_freed(entry->proc_ctx))) __ipa3_release_hdr_proc_ctx(entry->proc_ctx->id); list_del(&entry->link); entry->tbl->rule_cnt--; @@ -1567,7 +1570,9 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only) tbl->rule_cnt--; if (rule->hdr) __ipa3_release_hdr(rule->hdr->id); - else if (rule->proc_ctx) + else if (rule->proc_ctx && + (!ipa3_check_idr_if_freed( + rule->proc_ctx))) __ipa3_release_hdr_proc_ctx( rule->proc_ctx->id); rule->cookie = 0; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index f4bce295311c..a00fcaeb8d8f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, 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 @@ -3865,3 +3865,19 @@ struct device *ipa3_get_pdev(void) return ipa3_ctx->pdev; } + +bool ipa3_check_idr_if_freed(void *ptr) +{ + int id; + void *iter_ptr; + + spin_lock(&ipa3_ctx->idr_lock); + idr_for_each_entry(&ipa3_ctx->ipa_idr, iter_ptr, id) { + if ((uintptr_t)ptr == (uintptr_t)iter_ptr) { + spin_unlock(&ipa3_ctx->idr_lock); + return false; + } + } + spin_unlock(&ipa3_ctx->idr_lock); + return true; +} |
