net/bnxt: fix out of bound access in bit handling
[dpdk.git] / drivers / net / bnxt / tf_core / tf_rm.c
index e0469b6..66a3358 100644 (file)
@@ -17,6 +17,9 @@
 #include "tfp.h"
 #include "tf_msg.h"
 
+/* Logging defines */
+#define TF_RM_DEBUG  0
+
 /**
  * Generic RM Element data type that an RM DB is build upon.
  */
@@ -106,7 +109,8 @@ tf_rm_count_hcapi_reservations(enum tf_dir dir,
        uint16_t cnt = 0;
 
        for (i = 0; i < count; i++) {
-               if (cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI &&
+               if ((cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI ||
+                    cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA) &&
                    reservations[i] > 0)
                        cnt++;
 
@@ -119,16 +123,11 @@ tf_rm_count_hcapi_reservations(enum tf_dir dir,
                    cfg[i].cfg_type == TF_RM_ELEM_CFG_NULL &&
                    reservations[i] > 0) {
                        TFP_DRV_LOG(ERR,
-                               "%s, %s, %s allocation not supported\n",
-                               tf_device_module_type_2_str(type),
-                               tf_dir_2_str(dir),
-                               tf_device_module_type_subtype_2_str(type, i));
-                       printf("%s, %s, %s allocation of %d not supported\n",
+                               "%s, %s, %s allocation of %d not supported\n",
                                tf_device_module_type_2_str(type),
                                tf_dir_2_str(dir),
-                              tf_device_module_type_subtype_2_str(type, i),
-                              reservations[i]);
-
+                               tf_device_module_type_subtype_2_str(type, i),
+                               reservations[i]);
                }
        }
 
@@ -390,7 +389,7 @@ tf_rm_create_db(struct tf *tfp,
        TF_CHECK_PARMS2(tfp, parms);
 
        /* Retrieve the session information */
-       rc = tf_session_get_session(tfp, &tfs);
+       rc = tf_session_get_session_internal(tfp, &tfs);
        if (rc)
                return rc;
 
@@ -467,7 +466,8 @@ tf_rm_create_db(struct tf *tfp,
        /* Build the request */
        for (i = 0, j = 0; i < parms->num_elements; i++) {
                /* Skip any non HCAPI cfg elements */
-               if (parms->cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI) {
+               if (parms->cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI ||
+                   parms->cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA) {
                        /* Only perform reservation for entries that
                         * has been requested
                         */
@@ -529,7 +529,8 @@ tf_rm_create_db(struct tf *tfp,
                /* Skip any non HCAPI types as we didn't include them
                 * in the reservation request.
                 */
-               if (parms->cfg[i].cfg_type != TF_RM_ELEM_CFG_HCAPI)
+               if (parms->cfg[i].cfg_type != TF_RM_ELEM_CFG_HCAPI &&
+                   parms->cfg[i].cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                        continue;
 
                /* If the element didn't request an allocation no need
@@ -546,34 +547,32 @@ tf_rm_create_db(struct tf *tfp,
                        db[i].alloc.entry.start = resv[j].start;
                        db[i].alloc.entry.stride = resv[j].stride;
 
-                       printf("Entry:%d Start:%d Stride:%d\n",
-                              i,
-                              resv[j].start,
-                              resv[j].stride);
-
-                       /* Create pool */
-                       pool_size = (BITALLOC_SIZEOF(resv[j].stride) /
-                                    sizeof(struct bitalloc));
-                       /* Alloc request, alignment already set */
-                       cparms.nitems = pool_size;
-                       cparms.size = sizeof(struct bitalloc);
-                       rc = tfp_calloc(&cparms);
-                       if (rc) {
-                               TFP_DRV_LOG(ERR,
-                                           "%s: Pool alloc failed, type:%d\n",
-                                           tf_dir_2_str(parms->dir),
-                                           db[i].cfg_type);
-                               goto fail;
-                       }
-                       db[i].pool = (struct bitalloc *)cparms.mem_va;
-
-                       rc = ba_init(db[i].pool, resv[j].stride);
-                       if (rc) {
-                               TFP_DRV_LOG(ERR,
-                                           "%s: Pool init failed, type:%d\n",
-                                           tf_dir_2_str(parms->dir),
-                                           db[i].cfg_type);
-                               goto fail;
+                       /* Only allocate BA pool if so requested */
+                       if (parms->cfg[i].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA) {
+                               /* Create pool */
+                               pool_size = (BITALLOC_SIZEOF(resv[j].stride) /
+                                            sizeof(struct bitalloc));
+                               /* Alloc request, alignment already set */
+                               cparms.nitems = pool_size;
+                               cparms.size = sizeof(struct bitalloc);
+                               rc = tfp_calloc(&cparms);
+                               if (rc) {
+                                       TFP_DRV_LOG(ERR,
+                                            "%s: Pool alloc failed, type:%d\n",
+                                            tf_dir_2_str(parms->dir),
+                                            db[i].cfg_type);
+                                       goto fail;
+                               }
+                               db[i].pool = (struct bitalloc *)cparms.mem_va;
+
+                               rc = ba_init(db[i].pool, resv[j].stride);
+                               if (rc) {
+                                       TFP_DRV_LOG(ERR,
+                                            "%s: Pool init failed, type:%d\n",
+                                            tf_dir_2_str(parms->dir),
+                                            db[i].cfg_type);
+                                       goto fail;
+                               }
                        }
                        j++;
                } else {
@@ -597,10 +596,12 @@ tf_rm_create_db(struct tf *tfp,
        rm_db->type = parms->type;
        *parms->rm_db = (void *)rm_db;
 
+#if (TF_RM_DEBUG == 1)
        printf("%s: type:%d num_entries:%d\n",
               tf_dir_2_str(parms->dir),
               parms->type,
               i);
+#endif /* (TF_RM_DEBUG == 1) */
 
        tfp_free((void *)req);
        tfp_free((void *)resv);
@@ -682,6 +683,9 @@ tf_rm_free_db(struct tf *tfp,
                                    tf_device_module_type_2_str(rm_db->type));
        }
 
+       /* No need to check for configuration type, even if we do not
+        * have a BA pool we just delete on a null ptr, no harm
+        */
        for (i = 0; i < rm_db->num_entries; i++)
                tfp_free((void *)rm_db->db[i].pool);
 
@@ -702,11 +706,12 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
        /* Bail out if not controlled by RM */
-       if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+       if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        /* Bail out if the pool is not valid, should never happen */
@@ -752,6 +757,8 @@ tf_rm_allocate(struct tf_rm_allocate_parms *parms)
        }
 
        *parms->index = index;
+       if (parms->base_index)
+               *parms->base_index = id;
 
        return rc;
 }
@@ -767,11 +774,12 @@ tf_rm_free(struct tf_rm_free_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
        /* Bail out if not controlled by RM */
-       if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+       if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        /* Bail out if the pool is not valid, should never happen */
@@ -813,11 +821,12 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
        /* Bail out if not controlled by RM */
-       if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+       if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        /* Bail out if the pool is not valid, should never happen */
@@ -840,6 +849,8 @@ tf_rm_is_allocated(struct tf_rm_is_allocated_parms *parms)
        if (rc)
                return rc;
 
+       if (parms->base_index)
+               *parms->base_index = adj_index;
        *parms->allocated = ba_inuse(rm_db->db[parms->db_index].pool,
                                     adj_index);
 
@@ -855,11 +866,13 @@ tf_rm_get_info(struct tf_rm_get_alloc_info_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
-       /* Bail out if not controlled by RM */
+       /* Bail out if not controlled by HCAPI */
        if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+           cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        memcpy(parms->info,
@@ -878,11 +891,13 @@ tf_rm_get_hcapi_type(struct tf_rm_get_hcapi_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
-       /* Bail out if not controlled by RM */
+       /* Bail out if not controlled by HCAPI */
        if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+           cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        *parms->hcapi_type = rm_db->db[parms->db_index].hcapi_type;
@@ -900,11 +915,12 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
        TF_CHECK_PARMS2(parms, parms->rm_db);
 
        rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
        cfg_type = rm_db->db[parms->db_index].cfg_type;
 
        /* Bail out if not controlled by RM */
-       if (cfg_type != TF_RM_ELEM_CFG_HCAPI &&
-           cfg_type != TF_RM_ELEM_CFG_PRIVATE)
+       if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
                return -ENOTSUP;
 
        /* Bail silently (no logging), if the pool is not valid there
@@ -920,3 +936,44 @@ tf_rm_get_inuse_count(struct tf_rm_get_inuse_count_parms *parms)
        return rc;
 
 }
+
+int
+tf_rm_check_indexes_in_range(struct tf_rm_check_indexes_in_range_parms *parms)
+{
+       struct tf_rm_new_db *rm_db;
+       enum tf_rm_elem_cfg_type cfg_type;
+       uint32_t base_index;
+       uint32_t stride;
+       int rc = 0;
+
+       TF_CHECK_PARMS2(parms, parms->rm_db);
+
+       rm_db = (struct tf_rm_new_db *)parms->rm_db;
+       if (!rm_db->db)
+               return -EINVAL;
+       cfg_type = rm_db->db[parms->db_index].cfg_type;
+
+       /* Bail out if not controlled by RM */
+       if (cfg_type != TF_RM_ELEM_CFG_HCAPI_BA)
+               return -ENOTSUP;
+
+       /* Bail out if the pool is not valid, should never happen */
+       if (rm_db->db[parms->db_index].pool == NULL) {
+               rc = -ENOTSUP;
+               TFP_DRV_LOG(ERR,
+                           "%s: Invalid pool for this type:%d, rc:%s\n",
+                           tf_dir_2_str(rm_db->dir),
+                           parms->db_index,
+                           strerror(-rc));
+               return rc;
+       }
+
+       base_index = rm_db->db[parms->db_index].alloc.entry.start;
+       stride = rm_db->db[parms->db_index].alloc.entry.stride;
+
+       if (parms->starting_index < base_index ||
+           parms->starting_index + parms->num_entries > base_index + stride)
+               return -EINVAL;
+
+       return rc;
+}