msm:ipa: Fix to incorrect structure access
Accessing of incorrect structure pointer is causing memory out of bound access, fixed issue by accessing the correct structure pointer. Change-Id: I3c2f5f7a97cac854093ef670184d06db4231f5e1 Acked-by: Ashok Vuyyuru <avuyyuru@qti.qualcomm.com> Signed-off-by: Mohammed Javid <mjavid@codeaurora.org>
This commit is contained in:
parent
6f56b2a9c8
commit
8e5eb432c7
8 changed files with 170 additions and 71 deletions
|
@ -1027,7 +1027,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (rt_tbl->cookie != IPA_COOKIE) {
|
||||
if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
|
||||
IPAERR("RT table cookie is invalid\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1048,7 +1048,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
|
|||
}
|
||||
INIT_LIST_HEAD(&entry->link);
|
||||
entry->rule = *rule;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_FLT_COOKIE;
|
||||
entry->rt_tbl = rt_tbl;
|
||||
entry->tbl = tbl;
|
||||
if (add_rear) {
|
||||
|
@ -1067,13 +1067,19 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to add to tree\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
*rule_hdl = id;
|
||||
entry->id = id;
|
||||
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
|
||||
|
||||
return 0;
|
||||
|
||||
ipa_insert_failed:
|
||||
tbl->rule_cnt--;
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
list_del(&entry->link);
|
||||
kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
|
||||
error:
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -1089,7 +1095,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1121,7 +1127,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1142,7 +1148,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (rt_tbl->cookie != IPA_COOKIE) {
|
||||
if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
|
||||
IPAERR("RT table cookie is invalid\n");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -547,7 +547,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
{
|
||||
struct ipa_hdr_entry *hdr_entry;
|
||||
struct ipa_hdr_proc_ctx_entry *entry;
|
||||
struct ipa_hdr_proc_ctx_offset_entry *offset;
|
||||
struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
|
||||
u32 bin;
|
||||
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
|
||||
int id;
|
||||
|
@ -563,7 +563,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
}
|
||||
|
||||
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
|
||||
if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
|
||||
if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("hdr_hdl is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
entry->hdr = hdr_entry;
|
||||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt++;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_PROC_HDR_COOKIE;
|
||||
|
||||
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
|
||||
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
|
||||
|
@ -640,6 +640,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to alloc id\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
proc_ctx->proc_ctx_hdl = id;
|
||||
|
@ -647,6 +648,14 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
|
||||
return 0;
|
||||
|
||||
ipa_insert_failed:
|
||||
if (offset)
|
||||
list_move(&offset->link,
|
||||
&htbl->head_free_offset_list[offset->bin]);
|
||||
entry->offset_entry = NULL;
|
||||
list_del(&entry->link);
|
||||
htbl->proc_ctx_cnt--;
|
||||
|
||||
bad_len:
|
||||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt--;
|
||||
|
@ -659,7 +668,7 @@ bad_len:
|
|||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
||||
{
|
||||
struct ipa_hdr_entry *entry;
|
||||
struct ipa_hdr_offset_entry *offset;
|
||||
struct ipa_hdr_offset_entry *offset = NULL;
|
||||
u32 bin;
|
||||
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
|
||||
int id;
|
||||
|
@ -691,7 +700,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
entry->type = hdr->type;
|
||||
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
|
||||
entry->eth2_ofst = hdr->eth2_ofst;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_HDR_COOKIE;
|
||||
|
||||
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
|
||||
bin = IPA_HDR_BIN0;
|
||||
|
@ -780,6 +789,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
if (id < 0) {
|
||||
IPAERR("failed to alloc id\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
hdr->hdr_hdl = id;
|
||||
|
@ -804,10 +814,19 @@ fail_add_proc_ctx:
|
|||
entry->ref_cnt--;
|
||||
hdr->hdr_hdl = 0;
|
||||
ipa_id_remove(id);
|
||||
ipa_insert_failed:
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
|
||||
entry->hdr_len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
if (offset)
|
||||
list_move(&offset->link,
|
||||
&htbl->head_free_offset_list[offset->bin]);
|
||||
entry->offset_entry = NULL;
|
||||
}
|
||||
htbl->hdr_cnt--;
|
||||
list_del(&entry->link);
|
||||
dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
|
||||
entry->hdr_len, DMA_TO_DEVICE);
|
||||
|
||||
fail_dma_mapping:
|
||||
entry->is_hdr_proc_ctx = false;
|
||||
bad_hdr_len:
|
||||
|
@ -824,7 +843,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
|
|||
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
|
||||
|
||||
entry = ipa_id_find(proc_ctx_hdl);
|
||||
if (!entry || (entry->cookie != IPA_COOKIE)) {
|
||||
if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
|
||||
IPAERR("bad parm\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -875,7 +894,7 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE) {
|
||||
IPAERR("bad parm\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1444,7 +1463,7 @@ int ipa2_put_hdr(u32 hdr_hdl)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE) {
|
||||
IPAERR("invalid header entry\n");
|
||||
result = -EINVAL;
|
||||
goto bail;
|
||||
|
|
|
@ -37,7 +37,15 @@
|
|||
|
||||
#define DRV_NAME "ipa"
|
||||
#define NAT_DEV_NAME "ipaNatTable"
|
||||
|
||||
#define IPA_COOKIE 0x57831603
|
||||
#define IPA_RT_RULE_COOKIE 0x57831604
|
||||
#define IPA_RT_TBL_COOKIE 0x57831605
|
||||
#define IPA_FLT_COOKIE 0x57831606
|
||||
#define IPA_HDR_COOKIE 0x57831607
|
||||
#define IPA_PROC_HDR_COOKIE 0x57831608
|
||||
|
||||
|
||||
#define MTU_BYTE 1500
|
||||
|
||||
#define IPA_MAX_NUM_PIPES 0x14
|
||||
|
@ -223,8 +231,8 @@ struct ipa_smmu_cb_ctx {
|
|||
*/
|
||||
struct ipa_flt_entry {
|
||||
struct list_head link;
|
||||
struct ipa_flt_rule rule;
|
||||
u32 cookie;
|
||||
struct ipa_flt_rule rule;
|
||||
struct ipa_flt_tbl *tbl;
|
||||
struct ipa_rt_tbl *rt_tbl;
|
||||
u32 hw_len;
|
||||
|
@ -249,13 +257,13 @@ struct ipa_flt_entry {
|
|||
*/
|
||||
struct ipa_rt_tbl {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
struct list_head head_rt_rule_list;
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
u32 idx;
|
||||
u32 rule_cnt;
|
||||
u32 ref_cnt;
|
||||
struct ipa_rt_tbl_set *set;
|
||||
u32 cookie;
|
||||
bool in_sys;
|
||||
u32 sz;
|
||||
struct ipa_mem_buffer curr_mem;
|
||||
|
@ -286,6 +294,7 @@ struct ipa_rt_tbl {
|
|||
*/
|
||||
struct ipa_hdr_entry {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
u8 hdr[IPA_HDR_MAX_SIZE];
|
||||
u32 hdr_len;
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
|
@ -295,7 +304,6 @@ struct ipa_hdr_entry {
|
|||
dma_addr_t phys_base;
|
||||
struct ipa_hdr_proc_ctx_entry *proc_ctx;
|
||||
struct ipa_hdr_offset_entry *offset_entry;
|
||||
u32 cookie;
|
||||
u32 ref_cnt;
|
||||
int id;
|
||||
u8 is_eth2_ofst_valid;
|
||||
|
@ -368,10 +376,10 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
|
|||
*/
|
||||
struct ipa_hdr_proc_ctx_entry {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
enum ipa_hdr_proc_type type;
|
||||
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
|
||||
struct ipa_hdr_entry *hdr;
|
||||
u32 cookie;
|
||||
u32 ref_cnt;
|
||||
int id;
|
||||
bool user_deleted;
|
||||
|
@ -427,8 +435,8 @@ struct ipa_flt_tbl {
|
|||
*/
|
||||
struct ipa_rt_entry {
|
||||
struct list_head link;
|
||||
struct ipa_rt_rule rule;
|
||||
u32 cookie;
|
||||
struct ipa_rt_rule rule;
|
||||
struct ipa_rt_tbl *tbl;
|
||||
struct ipa_hdr_entry *hdr;
|
||||
struct ipa_hdr_proc_ctx_entry *proc_ctx;
|
||||
|
|
|
@ -909,7 +909,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
|
|||
INIT_LIST_HEAD(&entry->link);
|
||||
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
|
||||
entry->set = set;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_RT_TBL_COOKIE;
|
||||
entry->in_sys = (ip == IPA_IP_v4) ?
|
||||
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
|
||||
set->tbl_cnt++;
|
||||
|
@ -922,12 +922,16 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to add to tree\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
ipa_insert_failed:
|
||||
set->tbl_cnt--;
|
||||
list_del(&entry->link);
|
||||
fail_rt_idx_alloc:
|
||||
entry->cookie = 0;
|
||||
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
|
||||
|
@ -940,7 +944,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
|
|||
enum ipa_ip_type ip = IPA_IP_MAX;
|
||||
u32 id;
|
||||
|
||||
if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
|
||||
if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
|
||||
IPAERR("bad parms\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -954,8 +958,11 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
|
|||
ip = IPA_IP_v4;
|
||||
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
|
||||
ip = IPA_IP_v6;
|
||||
else
|
||||
else {
|
||||
WARN_ON(1);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
||||
if (!entry->in_sys) {
|
||||
list_del(&entry->link);
|
||||
|
@ -994,13 +1001,14 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
|
||||
if (rule->hdr_hdl) {
|
||||
hdr = ipa_id_find(rule->hdr_hdl);
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("rt rule does not point to valid hdr\n");
|
||||
goto error;
|
||||
}
|
||||
} else if (rule->hdr_proc_ctx_hdl) {
|
||||
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
|
||||
if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
|
||||
if ((proc_ctx == NULL) ||
|
||||
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
|
||||
IPAERR("rt rule does not point to valid proc ctx\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1008,7 +1016,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
|
||||
|
||||
tbl = __ipa_add_rt_tbl(ip, name);
|
||||
if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
|
||||
if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
|
||||
IPAERR("bad params\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1029,7 +1037,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
goto error;
|
||||
}
|
||||
INIT_LIST_HEAD(&entry->link);
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_RT_RULE_COOKIE;
|
||||
entry->rule = *rule;
|
||||
entry->tbl = tbl;
|
||||
entry->hdr = hdr;
|
||||
|
@ -1123,7 +1131,7 @@ int __ipa_del_rt_rule(u32 rule_hdl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_RT_RULE_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1358,7 +1366,7 @@ int ipa2_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
|
|||
}
|
||||
mutex_lock(&ipa_ctx->lock);
|
||||
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
|
||||
if (entry && entry->cookie == IPA_COOKIE) {
|
||||
if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
|
||||
if (entry->ref_cnt == U32_MAX) {
|
||||
IPAERR("fail: ref count crossed limit\n");
|
||||
goto ret;
|
||||
|
@ -1401,7 +1409,7 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
|
|||
goto ret;
|
||||
}
|
||||
|
||||
if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
|
||||
if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
|
||||
IPAERR("bad parms\n");
|
||||
result = -EINVAL;
|
||||
goto ret;
|
||||
|
@ -1411,8 +1419,11 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
|
|||
ip = IPA_IP_v4;
|
||||
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
|
||||
ip = IPA_IP_v6;
|
||||
else
|
||||
else {
|
||||
WARN_ON(1);
|
||||
result = -EINVAL;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
entry->ref_cnt--;
|
||||
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
|
||||
|
@ -1439,7 +1450,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
|
|||
|
||||
if (rtrule->rule.hdr_hdl) {
|
||||
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("rt rule does not point to valid hdr\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1451,7 +1462,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_RT_RULE_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -745,7 +745,7 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if ((*rt_tbl)->cookie != IPA_COOKIE) {
|
||||
if ((*rt_tbl)->cookie != IPA_RT_TBL_COOKIE) {
|
||||
IPAERR("RT table cookie is invalid\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -787,7 +787,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry,
|
|||
}
|
||||
INIT_LIST_HEAD(&((*entry)->link));
|
||||
(*entry)->rule = *rule;
|
||||
(*entry)->cookie = IPA_COOKIE;
|
||||
(*entry)->cookie = IPA_FLT_COOKIE;
|
||||
(*entry)->rt_tbl = rt_tbl;
|
||||
(*entry)->tbl = tbl;
|
||||
if (rule->rule_id) {
|
||||
|
@ -822,12 +822,18 @@ static int __ipa_finish_flt_rule_add(struct ipa3_flt_tbl *tbl,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to add to tree\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
*rule_hdl = id;
|
||||
entry->id = id;
|
||||
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
|
||||
|
||||
return 0;
|
||||
ipa_insert_failed:
|
||||
if (entry->rt_tbl)
|
||||
entry->rt_tbl->ref_cnt--;
|
||||
tbl->rule_cnt--;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
|
||||
|
@ -853,9 +859,16 @@ static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
|
|||
list_add(&entry->link, &tbl->head_flt_rule_list);
|
||||
}
|
||||
|
||||
__ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
|
||||
if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
|
||||
goto ipa_insert_failed;
|
||||
|
||||
return 0;
|
||||
ipa_insert_failed:
|
||||
list_del(&entry->link);
|
||||
/* if rule id was allocated from idr, remove it */
|
||||
if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
|
||||
idr_remove(&entry->tbl->rule_ids, entry->rule_id);
|
||||
kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
|
||||
|
||||
error:
|
||||
return -EPERM;
|
||||
|
@ -887,7 +900,8 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,
|
|||
|
||||
list_add(&entry->link, &((*add_after_entry)->link));
|
||||
|
||||
__ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
|
||||
if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
|
||||
goto ipa_insert_failed;
|
||||
|
||||
/*
|
||||
* prepare for next insertion
|
||||
|
@ -896,6 +910,13 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,
|
|||
|
||||
return 0;
|
||||
|
||||
ipa_insert_failed:
|
||||
list_del(&entry->link);
|
||||
/* if rule id was allocated from idr, remove it */
|
||||
if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
|
||||
idr_remove(&entry->tbl->rule_ids, entry->rule_id);
|
||||
kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
|
||||
|
||||
error:
|
||||
*add_after_entry = NULL;
|
||||
return -EPERM;
|
||||
|
@ -912,7 +933,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -949,7 +970,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_FLT_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -970,7 +991,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (rt_tbl->cookie != IPA_COOKIE) {
|
||||
if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
|
||||
IPAERR("RT table cookie is invalid\n");
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
IPAERR("hdr_hdl is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (hdr_entry->cookie != IPA_COOKIE) {
|
||||
if (hdr_entry->cookie != IPA_HDR_COOKIE) {
|
||||
IPAERR("Invalid header cookie %u\n", hdr_entry->cookie);
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
|
@ -359,7 +359,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
entry->hdr = hdr_entry;
|
||||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt++;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_HDR_COOKIE;
|
||||
|
||||
needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);
|
||||
|
||||
|
@ -417,6 +417,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to alloc id\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
proc_ctx->proc_ctx_hdl = id;
|
||||
|
@ -424,6 +425,14 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
|
|||
|
||||
return 0;
|
||||
|
||||
ipa_insert_failed:
|
||||
if (offset)
|
||||
list_move(&offset->link,
|
||||
&htbl->head_free_offset_list[offset->bin]);
|
||||
entry->offset_entry = NULL;
|
||||
list_del(&entry->link);
|
||||
htbl->proc_ctx_cnt--;
|
||||
|
||||
bad_len:
|
||||
if (add_ref_hdr)
|
||||
hdr_entry->ref_cnt--;
|
||||
|
@ -436,7 +445,7 @@ bad_len:
|
|||
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
||||
{
|
||||
struct ipa3_hdr_entry *entry;
|
||||
struct ipa_hdr_offset_entry *offset;
|
||||
struct ipa_hdr_offset_entry *offset = NULL;
|
||||
u32 bin;
|
||||
struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl;
|
||||
int id;
|
||||
|
@ -467,7 +476,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
entry->type = hdr->type;
|
||||
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
|
||||
entry->eth2_ofst = hdr->eth2_ofst;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_HDR_COOKIE;
|
||||
|
||||
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
|
||||
bin = IPA_HDR_BIN0;
|
||||
|
@ -546,6 +555,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
|
|||
if (id < 0) {
|
||||
IPAERR("failed to alloc id\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
hdr->hdr_hdl = id;
|
||||
|
@ -570,10 +580,19 @@ fail_add_proc_ctx:
|
|||
entry->ref_cnt--;
|
||||
hdr->hdr_hdl = 0;
|
||||
ipa3_id_remove(id);
|
||||
ipa_insert_failed:
|
||||
if (entry->is_hdr_proc_ctx) {
|
||||
dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
|
||||
entry->hdr_len, DMA_TO_DEVICE);
|
||||
} else {
|
||||
if (offset)
|
||||
list_move(&offset->link,
|
||||
&htbl->head_free_offset_list[offset->bin]);
|
||||
entry->offset_entry = NULL;
|
||||
}
|
||||
htbl->hdr_cnt--;
|
||||
list_del(&entry->link);
|
||||
dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
|
||||
entry->hdr_len, DMA_TO_DEVICE);
|
||||
|
||||
fail_dma_mapping:
|
||||
entry->is_hdr_proc_ctx = false;
|
||||
|
||||
|
@ -591,7 +610,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl,
|
|||
struct ipa3_hdr_proc_ctx_tbl *htbl = &ipa3_ctx->hdr_proc_ctx_tbl;
|
||||
|
||||
entry = ipa3_id_find(proc_ctx_hdl);
|
||||
if (!entry || (entry->cookie != IPA_COOKIE)) {
|
||||
if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("bad parm\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -642,7 +661,7 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE) {
|
||||
IPAERR("bad parm\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1188,7 +1207,7 @@ int ipa3_put_hdr(u32 hdr_hdl)
|
|||
goto bail;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_HDR_COOKIE) {
|
||||
IPAERR("invalid header entry\n");
|
||||
result = -EINVAL;
|
||||
goto bail;
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
#define DRV_NAME "ipa"
|
||||
#define NAT_DEV_NAME "ipaNatTable"
|
||||
#define IPA_COOKIE 0x57831603
|
||||
#define IPA_RT_RULE_COOKIE 0x57831604
|
||||
#define IPA_RT_TBL_COOKIE 0x57831605
|
||||
#define IPA_FLT_COOKIE 0x57831606
|
||||
#define IPA_HDR_COOKIE 0x57831607
|
||||
#define IPA_PROC_HDR_COOKIE 0x57831608
|
||||
|
||||
#define MTU_BYTE 1500
|
||||
|
||||
#define IPA_EP_NOT_ALLOCATED (-1)
|
||||
|
@ -217,8 +223,8 @@ struct ipa_smmu_cb_ctx {
|
|||
*/
|
||||
struct ipa3_flt_entry {
|
||||
struct list_head link;
|
||||
struct ipa_flt_rule rule;
|
||||
u32 cookie;
|
||||
struct ipa_flt_rule rule;
|
||||
struct ipa3_flt_tbl *tbl;
|
||||
struct ipa3_rt_tbl *rt_tbl;
|
||||
u32 hw_len;
|
||||
|
@ -246,13 +252,13 @@ struct ipa3_flt_entry {
|
|||
*/
|
||||
struct ipa3_rt_tbl {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
struct list_head head_rt_rule_list;
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
u32 idx;
|
||||
u32 rule_cnt;
|
||||
u32 ref_cnt;
|
||||
struct ipa3_rt_tbl_set *set;
|
||||
u32 cookie;
|
||||
bool in_sys[IPA_RULE_TYPE_MAX];
|
||||
u32 sz[IPA_RULE_TYPE_MAX];
|
||||
struct ipa_mem_buffer curr_mem[IPA_RULE_TYPE_MAX];
|
||||
|
@ -284,6 +290,7 @@ struct ipa3_rt_tbl {
|
|||
*/
|
||||
struct ipa3_hdr_entry {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
u8 hdr[IPA_HDR_MAX_SIZE];
|
||||
u32 hdr_len;
|
||||
char name[IPA_RESOURCE_NAME_MAX];
|
||||
|
@ -293,7 +300,6 @@ struct ipa3_hdr_entry {
|
|||
dma_addr_t phys_base;
|
||||
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
|
||||
struct ipa_hdr_offset_entry *offset_entry;
|
||||
u32 cookie;
|
||||
u32 ref_cnt;
|
||||
int id;
|
||||
u8 is_eth2_ofst_valid;
|
||||
|
@ -342,10 +348,10 @@ struct ipa3_hdr_proc_ctx_offset_entry {
|
|||
*/
|
||||
struct ipa3_hdr_proc_ctx_entry {
|
||||
struct list_head link;
|
||||
u32 cookie;
|
||||
enum ipa_hdr_proc_type type;
|
||||
struct ipa3_hdr_proc_ctx_offset_entry *offset_entry;
|
||||
struct ipa3_hdr_entry *hdr;
|
||||
u32 cookie;
|
||||
u32 ref_cnt;
|
||||
int id;
|
||||
bool user_deleted;
|
||||
|
@ -407,8 +413,8 @@ struct ipa3_flt_tbl {
|
|||
*/
|
||||
struct ipa3_rt_entry {
|
||||
struct list_head link;
|
||||
struct ipa_rt_rule rule;
|
||||
u32 cookie;
|
||||
struct ipa_rt_rule rule;
|
||||
struct ipa3_rt_tbl *tbl;
|
||||
struct ipa3_hdr_entry *hdr;
|
||||
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
|
||||
|
|
|
@ -796,7 +796,7 @@ static struct ipa3_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
|
|||
INIT_LIST_HEAD(&entry->link);
|
||||
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
|
||||
entry->set = set;
|
||||
entry->cookie = IPA_COOKIE;
|
||||
entry->cookie = IPA_RT_TBL_COOKIE;
|
||||
entry->in_sys[IPA_RULE_HASHABLE] = (ip == IPA_IP_v4) ?
|
||||
!ipa3_ctx->ip4_rt_tbl_hash_lcl :
|
||||
!ipa3_ctx->ip6_rt_tbl_hash_lcl;
|
||||
|
@ -814,12 +814,16 @@ static struct ipa3_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
|
|||
if (id < 0) {
|
||||
IPAERR("failed to add to tree\n");
|
||||
WARN_ON(1);
|
||||
goto ipa_insert_failed;
|
||||
}
|
||||
entry->id = id;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
ipa_insert_failed:
|
||||
set->tbl_cnt--;
|
||||
list_del(&entry->link);
|
||||
idr_destroy(&entry->rule_ids);
|
||||
fail_rt_idx_alloc:
|
||||
entry->cookie = 0;
|
||||
kmem_cache_free(ipa3_ctx->rt_tbl_cache, entry);
|
||||
|
@ -833,7 +837,7 @@ static int __ipa_del_rt_tbl(struct ipa3_rt_tbl *entry)
|
|||
u32 id;
|
||||
struct ipa3_rt_tbl_set *rset;
|
||||
|
||||
if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
|
||||
if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
|
||||
IPAERR("bad parms\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -847,8 +851,10 @@ static int __ipa_del_rt_tbl(struct ipa3_rt_tbl *entry)
|
|||
ip = IPA_IP_v4;
|
||||
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
|
||||
ip = IPA_IP_v6;
|
||||
else
|
||||
else {
|
||||
WARN_ON(1);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
rset = &ipa3_ctx->reap_rt_tbl_set[ip];
|
||||
|
||||
|
@ -885,14 +891,14 @@ static int __ipa_rt_validate_hndls(const struct ipa_rt_rule *rule,
|
|||
|
||||
if (rule->hdr_hdl) {
|
||||
*hdr = ipa3_id_find(rule->hdr_hdl);
|
||||
if ((*hdr == NULL) || ((*hdr)->cookie != IPA_COOKIE)) {
|
||||
if ((*hdr == NULL) || ((*hdr)->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("rt rule does not point to valid hdr\n");
|
||||
return -EPERM;
|
||||
}
|
||||
} else if (rule->hdr_proc_ctx_hdl) {
|
||||
*proc_ctx = ipa3_id_find(rule->hdr_proc_ctx_hdl);
|
||||
if ((*proc_ctx == NULL) ||
|
||||
((*proc_ctx)->cookie != IPA_COOKIE)) {
|
||||
((*proc_ctx)->cookie != IPA_PROC_HDR_COOKIE)) {
|
||||
|
||||
IPAERR("rt rule does not point to valid proc ctx\n");
|
||||
return -EPERM;
|
||||
|
@ -915,7 +921,7 @@ static int __ipa_create_rt_entry(struct ipa3_rt_entry **entry,
|
|||
goto error;
|
||||
}
|
||||
INIT_LIST_HEAD(&(*entry)->link);
|
||||
(*(entry))->cookie = IPA_COOKIE;
|
||||
(*(entry))->cookie = IPA_RT_RULE_COOKIE;
|
||||
(*(entry))->rule = *rule;
|
||||
(*(entry))->tbl = tbl;
|
||||
(*(entry))->hdr = hdr;
|
||||
|
@ -983,7 +989,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
|
|||
|
||||
|
||||
tbl = __ipa_add_rt_tbl(ip, name);
|
||||
if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
|
||||
if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
|
||||
IPAERR("failed adding rt tbl name = %s\n",
|
||||
name ? name : "");
|
||||
goto error;
|
||||
|
@ -1118,7 +1124,7 @@ int ipa3_add_rt_rule_after(struct ipa_ioc_add_rt_rule_after *rules)
|
|||
mutex_lock(&ipa3_ctx->lock);
|
||||
|
||||
tbl = __ipa3_find_rt_tbl(rules->ip, rules->rt_tbl_name);
|
||||
if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
|
||||
if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
|
||||
IPAERR("failed finding rt tbl name = %s\n",
|
||||
rules->rt_tbl_name ? rules->rt_tbl_name : "");
|
||||
ret = -EINVAL;
|
||||
|
@ -1202,7 +1208,7 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_RT_RULE_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1440,7 +1446,7 @@ int ipa3_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
|
|||
}
|
||||
mutex_lock(&ipa3_ctx->lock);
|
||||
entry = __ipa3_find_rt_tbl(lookup->ip, lookup->name);
|
||||
if (entry && entry->cookie == IPA_COOKIE) {
|
||||
if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
|
||||
if (entry->ref_cnt == U32_MAX) {
|
||||
IPAERR("fail: ref count crossed limit\n");
|
||||
goto ret;
|
||||
|
@ -1483,7 +1489,7 @@ int ipa3_put_rt_tbl(u32 rt_tbl_hdl)
|
|||
goto ret;
|
||||
}
|
||||
|
||||
if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
|
||||
if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
|
||||
IPAERR("bad parms\n");
|
||||
result = -EINVAL;
|
||||
goto ret;
|
||||
|
@ -1493,8 +1499,10 @@ int ipa3_put_rt_tbl(u32 rt_tbl_hdl)
|
|||
ip = IPA_IP_v4;
|
||||
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
|
||||
ip = IPA_IP_v6;
|
||||
else
|
||||
else {
|
||||
WARN_ON(1);
|
||||
goto ret;
|
||||
}
|
||||
|
||||
entry->ref_cnt--;
|
||||
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
|
||||
|
@ -1524,13 +1532,14 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
|
|||
|
||||
if (rtrule->rule.hdr_hdl) {
|
||||
hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
|
||||
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
|
||||
IPAERR("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_COOKIE)) {
|
||||
if ((proc_ctx == NULL) ||
|
||||
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
|
||||
IPAERR("rt rule does not point to valid proc ctx\n");
|
||||
goto error;
|
||||
}
|
||||
|
@ -1542,7 +1551,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (entry->cookie != IPA_COOKIE) {
|
||||
if (entry->cookie != IPA_RT_RULE_COOKIE) {
|
||||
IPAERR("bad params\n");
|
||||
goto error;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue