]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RDMA/core: Allocate the pkey cache only if the pkey_tbl_len is set
authorKamal Heib <kamalheib1@gmail.com>
Tue, 14 Jul 2020 18:34:09 +0000 (21:34 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 20 Jul 2020 19:18:16 +0000 (16:18 -0300)
Allocate the pkey cache only if the pkey_tbl_len is set by the provider,
also add checks to avoid accessing the pkey cache when it not initialized.

Link: https://lore.kernel.org/r/20200714183414.61069-3-kamalheib1@gmail.com
Signed-off-by: Kamal Heib <kamalheib1@gmail.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/core/cache.c

index a670209bbce6064135b499d567095f64caf47e01..ffad73bb40ff1dba53f65555c5e1fb1f3647a2c1 100644 (file)
@@ -1054,7 +1054,7 @@ int ib_get_cached_pkey(struct ib_device *device,
 
        cache = device->port_data[port_num].cache.pkey;
 
-       if (index < 0 || index >= cache->table_len)
+       if (!cache || index < 0 || index >= cache->table_len)
                ret = -EINVAL;
        else
                *pkey = cache->table[index];
@@ -1099,6 +1099,10 @@ int ib_find_cached_pkey(struct ib_device *device,
        read_lock_irqsave(&device->cache_lock, flags);
 
        cache = device->port_data[port_num].cache.pkey;
+       if (!cache) {
+               ret = -EINVAL;
+               goto err;
+       }
 
        *index = -1;
 
@@ -1117,6 +1121,7 @@ int ib_find_cached_pkey(struct ib_device *device,
                ret = 0;
        }
 
+err:
        read_unlock_irqrestore(&device->cache_lock, flags);
 
        return ret;
@@ -1139,6 +1144,10 @@ int ib_find_exact_cached_pkey(struct ib_device *device,
        read_lock_irqsave(&device->cache_lock, flags);
 
        cache = device->port_data[port_num].cache.pkey;
+       if (!cache) {
+               ret = -EINVAL;
+               goto err;
+       }
 
        *index = -1;
 
@@ -1149,6 +1158,7 @@ int ib_find_exact_cached_pkey(struct ib_device *device,
                        break;
                }
 
+err:
        read_unlock_irqrestore(&device->cache_lock, flags);
 
        return ret;
@@ -1425,23 +1435,26 @@ ib_cache_update(struct ib_device *device, u8 port, bool enforce_security)
                        goto err;
        }
 
-       pkey_cache = kmalloc(struct_size(pkey_cache, table,
-                                        tprops->pkey_tbl_len),
-                            GFP_KERNEL);
-       if (!pkey_cache) {
-               ret = -ENOMEM;
-               goto err;
-       }
+       if (tprops->pkey_tbl_len) {
+               pkey_cache = kmalloc(struct_size(pkey_cache, table,
+                                                tprops->pkey_tbl_len),
+                                    GFP_KERNEL);
+               if (!pkey_cache) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
 
-       pkey_cache->table_len = tprops->pkey_tbl_len;
+               pkey_cache->table_len = tprops->pkey_tbl_len;
 
-       for (i = 0; i < pkey_cache->table_len; ++i) {
-               ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
-               if (ret) {
-                       dev_warn(&device->dev,
-                                "ib_query_pkey failed (%d) for index %d\n",
-                                ret, i);
-                       goto err;
+               for (i = 0; i < pkey_cache->table_len; ++i) {
+                       ret = ib_query_pkey(device, port, i,
+                                           pkey_cache->table + i);
+                       if (ret) {
+                               dev_warn(&device->dev,
+                                        "ib_query_pkey failed (%d) for index %d\n",
+                                        ret, i);
+                               goto err;
+                       }
                }
        }