Commit 6f38efca authored by Kamal Heib's avatar Kamal Heib Committed by Jason Gunthorpe
Browse files

RDMA/core: Allocate the pkey cache only if the pkey_tbl_len is set

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: default avatarKamal Heib <kamalheib1@gmail.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 90efc8b2
Loading
Loading
Loading
Loading
+29 −16
Original line number Original line Diff line number Diff line
@@ -1054,7 +1054,7 @@ int ib_get_cached_pkey(struct ib_device *device,


	cache = device->port_data[port_num].cache.pkey;
	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;
		ret = -EINVAL;
	else
	else
		*pkey = cache->table[index];
		*pkey = cache->table[index];
@@ -1099,6 +1099,10 @@ int ib_find_cached_pkey(struct ib_device *device,
	read_lock_irqsave(&device->cache_lock, flags);
	read_lock_irqsave(&device->cache_lock, flags);


	cache = device->port_data[port_num].cache.pkey;
	cache = device->port_data[port_num].cache.pkey;
	if (!cache) {
		ret = -EINVAL;
		goto err;
	}


	*index = -1;
	*index = -1;


@@ -1117,6 +1121,7 @@ int ib_find_cached_pkey(struct ib_device *device,
		ret = 0;
		ret = 0;
	}
	}


err:
	read_unlock_irqrestore(&device->cache_lock, flags);
	read_unlock_irqrestore(&device->cache_lock, flags);


	return ret;
	return ret;
@@ -1139,6 +1144,10 @@ int ib_find_exact_cached_pkey(struct ib_device *device,
	read_lock_irqsave(&device->cache_lock, flags);
	read_lock_irqsave(&device->cache_lock, flags);


	cache = device->port_data[port_num].cache.pkey;
	cache = device->port_data[port_num].cache.pkey;
	if (!cache) {
		ret = -EINVAL;
		goto err;
	}


	*index = -1;
	*index = -1;


@@ -1149,6 +1158,7 @@ int ib_find_exact_cached_pkey(struct ib_device *device,
			break;
			break;
		}
		}


err:
	read_unlock_irqrestore(&device->cache_lock, flags);
	read_unlock_irqrestore(&device->cache_lock, flags);


	return ret;
	return ret;
@@ -1425,6 +1435,7 @@ ib_cache_update(struct ib_device *device, u8 port, bool enforce_security)
			goto err;
			goto err;
	}
	}


	if (tprops->pkey_tbl_len) {
		pkey_cache = kmalloc(struct_size(pkey_cache, table,
		pkey_cache = kmalloc(struct_size(pkey_cache, table,
						 tprops->pkey_tbl_len),
						 tprops->pkey_tbl_len),
				     GFP_KERNEL);
				     GFP_KERNEL);
@@ -1436,7 +1447,8 @@ ib_cache_update(struct ib_device *device, u8 port, bool enforce_security)
		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) {
		for (i = 0; i < pkey_cache->table_len; ++i) {
		ret = ib_query_pkey(device, port, i, pkey_cache->table + i);
			ret = ib_query_pkey(device, port, i,
					    pkey_cache->table + i);
			if (ret) {
			if (ret) {
				dev_warn(&device->dev,
				dev_warn(&device->dev,
					 "ib_query_pkey failed (%d) for index %d\n",
					 "ib_query_pkey failed (%d) for index %d\n",
@@ -1444,6 +1456,7 @@ ib_cache_update(struct ib_device *device, u8 port, bool enforce_security)
				goto err;
				goto err;
			}
			}
		}
		}
	}


	write_lock_irq(&device->cache_lock);
	write_lock_irq(&device->cache_lock);