During IPA driver processing context delete, a delete to
the referenced header is being done. The header deletion
will also commit the changes to H/W which includes the
processing context commit. This resulted into committing
an invalid process context as it is still in the processing
context list, but points to deleted header.
The fix is to not commit the changes when deleting the header
but only when deleting the processing context.
Change-Id: I9d3c5eec717da0b072144a1027e4582e73aaa6d9
CRs-fixed:
1044710
Signed-off-by: Ghanim Fodi <gfodi@codeaurora.org>
return 0;
bad_len:
- hdr_entry->ref_cnt--;
+ if (add_ref_hdr)
+ hdr_entry->ref_cnt--;
entry->cookie = 0;
kmem_cache_free(ipa_ctx->hdr_proc_ctx_cache, entry);
return -EPERM;
}
if (release_hdr)
- __ipa_release_hdr(entry->hdr->id);
+ __ipa_del_hdr(entry->hdr->id);
/* move the offset entry to appropriate free list */
list_move(&entry->offset_entry->link,
&ipa_ctx->hdr_tbl.head_hdr_entry_list, link) {
/* do not remove the default header */
- if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME))
+ if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) {
+ if (entry->is_hdr_proc_ctx) {
+ mutex_unlock(&ipa_ctx->lock);
+ WARN_ON(1);
+ IPAERR("default header is proc ctx\n");
+ return -EFAULT;
+ }
continue;
+ }
if (ipa_id_find(entry->id) == NULL) {
- WARN_ON(1);
mutex_unlock(&ipa_ctx->lock);
+ WARN_ON(1);
return -EFAULT;
}
if (entry->is_hdr_proc_ctx) {
link) {
if (ipa_id_find(ctx_entry->id) == NULL) {
- WARN_ON(1);
mutex_unlock(&ipa_ctx->lock);
+ WARN_ON(1);
return -EFAULT;
}
list_del(&ctx_entry->link);
goto bail;
}
- if (entry == NULL || entry->cookie != IPA_COOKIE) {
- IPAERR("bad params\n");
+ if (entry->cookie != IPA_COOKIE) {
+ IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
}
* @is_partial: flag indicating if header table entry is partial
* @is_hdr_proc_ctx: false - hdr entry resides in hdr table,
* true - hdr entry resides in DDR and pointed to by proc ctx
- * @phys_base: physical address of entry in SRAM when is_hdr_proc_ctx is true,
+ * @phys_base: physical address of entry in DDR when is_hdr_proc_ctx is true,
* else 0
* @proc_ctx: processing context header
* @offset_entry: entry's offset
return 0;
ipa_insert_failed:
+ if (entry->hdr)
+ entry->hdr->ref_cnt--;
+ else if (entry->proc_ctx)
+ entry->proc_ctx->ref_cnt--;
list_del(&entry->link);
kmem_cache_free(ipa_ctx->rt_rule_cache, entry);
error:
return 0;
bad_len:
- hdr_entry->ref_cnt--;
+ if (add_ref_hdr)
+ hdr_entry->ref_cnt--;
entry->cookie = 0;
kmem_cache_free(ipa3_ctx->hdr_proc_ctx_cache, entry);
return -EPERM;
}
if (release_hdr)
- __ipa3_release_hdr(entry->hdr->id);
+ __ipa3_del_hdr(entry->hdr->id);
/* move the offset entry to appropriate free list */
list_move(&entry->offset_entry->link,
&ipa3_ctx->hdr_tbl.head_hdr_entry_list, link) {
/* do not remove the default header */
- if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME))
+ if (!strcmp(entry->name, IPA_LAN_RX_HDR_NAME)) {
+ if (entry->is_hdr_proc_ctx) {
+ IPAERR("default header is proc ctx\n");
+ mutex_unlock(&ipa3_ctx->lock);
+ WARN_ON(1);
+ return -EFAULT;
+ }
continue;
+ }
if (ipa3_id_find(entry->id) == NULL) {
- WARN_ON(1);
mutex_unlock(&ipa3_ctx->lock);
+ WARN_ON(1);
return -EFAULT;
}
if (entry->is_hdr_proc_ctx) {
link) {
if (ipa3_id_find(ctx_entry->id) == NULL) {
- WARN_ON(1);
mutex_unlock(&ipa3_ctx->lock);
+ WARN_ON(1);
return -EFAULT;
}
list_del(&ctx_entry->link);
goto bail;
}
- if (entry == NULL || entry->cookie != IPA_COOKIE) {
- IPAERR("bad params\n");
+ if (entry->cookie != IPA_COOKIE) {
+ IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
}
* @is_partial: flag indicating if header table entry is partial
* @is_hdr_proc_ctx: false - hdr entry resides in hdr table,
* true - hdr entry resides in DDR and pointed to by proc ctx
- * @phys_base: physical address of entry in SRAM when is_hdr_proc_ctx is true,
+ * @phys_base: physical address of entry in DDR when is_hdr_proc_ctx is true,
* else 0
* @proc_ctx: processing context header
* @offset_entry: entry's offset
return 0;
ipa_insert_failed:
+ if (entry->hdr)
+ entry->hdr->ref_cnt--;
+ else if (entry->proc_ctx)
+ entry->proc_ctx->ref_cnt--;
idr_remove(&tbl->rule_ids, entry->rule_id);
list_del(&entry->link);
kmem_cache_free(ipa3_ctx->rt_rule_cache, entry);
(!phys_base && !hdr_base_addr) ||
!hdr_base_addr ||
((is_hdr_proc_ctx == false) && !offset_entry)) {
- IPAHAL_ERR("failed on validating params");
+ IPAHAL_ERR(
+ "invalid input: hdr_len:%u phys_base:%pad hdr_base_addr:%u is_hdr_proc_ctx:%d offset_entry:%pK\n"
+ , hdr_len, &phys_base, hdr_base_addr
+ , is_hdr_proc_ctx, offset_entry);
return -EINVAL;
}