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: Chaitanya Pratapa <cpratapa@codeaurora.org>
This commit is contained in:
Chaitanya Pratapa
2020-07-01 13:27:16 -07:00
parent b8079886fd
commit 68623da41c

View File

@@ -79,14 +79,16 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
if (entry->hdr) { if (entry->hdr) {
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl); 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"); IPAERR_RL("Header entry already deleted\n");
return -EPERM; return -EPERM;
} }
} else if (entry->proc_ctx) { } else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl); hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry || 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"); IPAERR_RL("Proc header entry already deleted\n");
return -EPERM; return -EPERM;
} }
@@ -1759,18 +1761,19 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl); 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) {
IPAERR_RL("Header entry already deleted\n"); IPAERR_RL("Header entry already deleted\n");
return -EINVAL; entry->hdr = NULL;
} }
} else if (entry->proc_ctx) { } else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl); hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry || if (!hdr_proc_entry ||
hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) { hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
IPAERR_RL("Proc header entry already deleted\n"); 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); __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_check_idr_if_freed(entry->proc_ctx)))
@@ -1947,16 +1950,14 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
if (!user_only || if (!user_only ||
rule->ipacm_installed) { rule->ipacm_installed) {
list_del(&rule->link);
if (rule->hdr) { if (rule->hdr) {
hdr_entry = ipa3_id_find( hdr_entry = ipa3_id_find(
rule->rule.hdr_hdl); rule->rule.hdr_hdl);
if (!hdr_entry || if (!hdr_entry ||
hdr_entry->cookie != IPA_HDR_COOKIE) { hdr_entry->cookie != IPA_HDR_COOKIE) {
mutex_unlock(&ipa3_ctx->lock);
IPAERR_RL( IPAERR_RL(
"Header already deleted\n"); "Header already deleted\n");
return -EINVAL; rule->hdr = NULL;
} }
} else if (rule->proc_ctx) { } else if (rule->proc_ctx) {
hdr_proc_entry = hdr_proc_entry =
@@ -1965,15 +1966,16 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
if (!hdr_proc_entry || if (!hdr_proc_entry ||
hdr_proc_entry->cookie != hdr_proc_entry->cookie !=
IPA_PROC_HDR_COOKIE) { IPA_PROC_HDR_COOKIE) {
mutex_unlock(&ipa3_ctx->lock);
IPAERR_RL( IPAERR_RL(
"Proc entry already deleted\n"); "Proc entry already deleted\n");
return -EINVAL; rule->proc_ctx = NULL;
} }
} }
tbl->rule_cnt--; tbl->rule_cnt--;
list_del(&rule->link);
if (rule->hdr && if (rule->hdr &&
(!ipa3_check_idr_if_freed(rule->hdr))) (!ipa3_check_idr_if_freed(
rule->hdr)))
__ipa3_release_hdr(rule->hdr->id); __ipa3_release_hdr(rule->hdr->id);
else if (rule->proc_ctx && else if (rule->proc_ctx &&
(!ipa3_check_idr_if_freed( (!ipa3_check_idr_if_freed(
@@ -2150,20 +2152,8 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy_i *rtrule)
struct ipa3_hdr_entry *hdr_entry; struct ipa3_hdr_entry *hdr_entry;
struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry; struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
if (rtrule->rule.hdr_hdl) { if (__ipa_rt_validate_hndls(&rtrule->rule, &hdr, &proc_ctx))
hdr = ipa3_id_find(rtrule->rule.hdr_hdl); goto error;
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;
}
}
entry = ipa3_id_find(rtrule->rt_rule_hdl); entry = ipa3_id_find(rtrule->rt_rule_hdl);
if (entry == NULL) { if (entry == NULL) {
@@ -2187,14 +2177,16 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy_i *rtrule)
if (entry->hdr) { if (entry->hdr) {
hdr_entry = ipa3_id_find(entry->rule.hdr_hdl); 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"); IPAERR_RL("Header entry already deleted\n");
return -EPERM; return -EPERM;
} }
} else if (entry->proc_ctx) { } else if (entry->proc_ctx) {
hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl); hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
if (!hdr_proc_entry || 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"); IPAERR_RL("Proc header entry already deleted\n");
return -EPERM; return -EPERM;
} }
@@ -2202,7 +2194,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy_i *rtrule)
if (entry->hdr) if (entry->hdr)
entry->hdr->ref_cnt--; entry->hdr->ref_cnt--;
if (entry->proc_ctx) else if (entry->proc_ctx)
entry->proc_ctx->ref_cnt--; entry->proc_ctx->ref_cnt--;
entry->rule = rtrule->rule; entry->rule = rtrule->rule;