summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_flt.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h1
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_rt.c11
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c18
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;
+}