summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adisumarta <madisuma@codeaurora.org>2020-10-08 00:40:33 -0700
committerMichael Adisumarta <madisuma@codeaurora.org>2020-10-08 00:40:33 -0700
commit07726d60e69861459269ce085c7c1ad3bb21e965 (patch)
treebc4c20c22cf5fd7b76952f6ed6c5b21383b5d6c7
parentdce57d817758260a14181dece4a2c8b92887e6e9 (diff)
msm: ipa: Fix deleting the routing entries
Make changes to delete the route entry even when the hdr/proc_ctx handles are already freed. Otherwise the entry will be dangling. Change-Id: Icbab6b96fa137c5214b37ea33c6203c5a54273ac Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_rt.c48
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index bc63b3188276..f434f9a406e5 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -77,14 +77,16 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
if (entry->hdr) {
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
- if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE) ||
+ ipa3_check_idr_if_freed(entry->hdr)) {
IPAERR_RL("Header entry already deleted\n");
return -EPERM;
}
} else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry ||
- hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ (hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) ||
+ ipa3_check_idr_if_freed(entry->proc_ctx)) {
IPAERR_RL("Proc header entry already deleted\n");
return -EPERM;
}
@@ -1355,18 +1357,19 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
IPAERR_RL("Header entry already deleted\n");
- return -EINVAL;
+ entry->hdr = NULL;
}
} else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry ||
hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
IPAERR_RL("Proc header entry already deleted\n");
- return -EINVAL;
+ entry->proc_ctx = NULL;
}
}
- if (entry->hdr)
+ if (entry->hdr &&
+ (!ipa3_check_idr_if_freed(entry->hdr)))
__ipa3_release_hdr(entry->hdr->id);
else if (entry->proc_ctx &&
(!ipa3_check_idr_if_freed(entry->proc_ctx)))
@@ -1543,7 +1546,6 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
if (!user_only ||
rule->ipacm_installed) {
- list_del(&rule->link);
if (rule->hdr) {
hdr_entry = ipa3_id_find(
rule->rule.hdr_hdl);
@@ -1551,8 +1553,7 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
hdr_entry->cookie != IPA_HDR_COOKIE) {
IPAERR_RL(
"Header already deleted\n");
- mutex_unlock(&ipa3_ctx->lock);
- return -EINVAL;
+ rule->hdr = NULL;
}
} else if (rule->proc_ctx) {
hdr_proc_entry =
@@ -1563,12 +1564,13 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
IPA_PROC_HDR_COOKIE) {
IPAERR_RL(
"Proc entry already deleted\n");
- mutex_unlock(&ipa3_ctx->lock);
- return -EINVAL;
+ rule->hdr = NULL;
}
}
tbl->rule_cnt--;
- if (rule->hdr)
+ list_del(&rule->link);
+ if (rule->hdr &&
+ (!ipa3_check_idr_if_freed(rule->hdr)))
__ipa3_release_hdr(rule->hdr->id);
else if (rule->proc_ctx &&
(!ipa3_check_idr_if_freed(
@@ -1744,20 +1746,8 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
struct ipa3_hdr_entry *hdr_entry;
struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
- if (rtrule->rule.hdr_hdl) {
- hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
- IPAERR_RL("rt rule does not point to valid hdr\n");
- goto error;
- }
- } else if (rtrule->rule.hdr_proc_ctx_hdl) {
- proc_ctx = ipa3_id_find(rtrule->rule.hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) ||
- (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
- IPAERR_RL("rt rule does not point to valid proc ctx\n");
- goto error;
- }
- }
+ if (__ipa_rt_validate_hndls(&rtrule->rule, &hdr, &proc_ctx))
+ goto error;
entry = ipa3_id_find(rtrule->rt_rule_hdl);
if (entry == NULL) {
@@ -1780,14 +1770,16 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (entry->hdr) {
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
- if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE) ||
+ ipa3_check_idr_if_freed(entry->hdr)) {
IPAERR_RL("Header entry already deleted\n");
return -EPERM;
}
} else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry ||
- hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ (hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) ||
+ ipa3_check_idr_if_freed(entry->proc_ctx)) {
IPAERR_RL("Proc header entry already deleted\n");
return -EPERM;
}
@@ -1795,7 +1787,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (entry->hdr)
entry->hdr->ref_cnt--;
- if (entry->proc_ctx)
+ else if (entry->proc_ctx)
entry->proc_ctx->ref_cnt--;
entry->rule = rtrule->rule;