aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx4
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2012-08-13 04:15:07 -0400
committerRoland Dreier <roland@purestorage.com>2012-08-16 00:05:26 -0400
commit3de819e6b642fdd51904f5f4d2716d7466a2f7f5 (patch)
tree0f3fd1c557ef4dcb1bb93188c3b585ff4f0b0a44 /drivers/net/ethernet/mellanox/mlx4
parent89dd86db78e08b51bab29e168fd41b2fd943e6b6 (diff)
mlx4_core: Fix integer overflow issues around MTT table
Fix some issues around int variables used in data structures related to memory registration. Handle int overflow in mlx4_init_icm_table by using a u64 intermediate variable and changing struct mlx4_icm_table num_obj field to be u32. Change some more fields/variables to use u32 instead of int to prevent a case where the variable becomes negative when bit 31 is set. Also subtract log_mtts_per_seg from the exponent when computing num_mtt, since its added later on in that very same code area. This and the previous commit fixes some issues which actually prevent commit db5a7a65c058 ("mlx4_core: Scale size of MTT table with system RAM") from working. Now, when the number of MTTs is scaled with the size of the RAM we can map up to 8TB. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Jack Morgenstein <jackm@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx4')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/profile.c4
5 files changed, 13 insertions, 10 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index 88b7b3e75ab..daf41792366 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -358,13 +358,14 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
358} 358}
359 359
360int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, 360int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
361 u64 virt, int obj_size, int nobj, int reserved, 361 u64 virt, int obj_size, u32 nobj, int reserved,
362 int use_lowmem, int use_coherent) 362 int use_lowmem, int use_coherent)
363{ 363{
364 int obj_per_chunk; 364 int obj_per_chunk;
365 int num_icm; 365 int num_icm;
366 unsigned chunk_size; 366 unsigned chunk_size;
367 int i; 367 int i;
368 u64 size;
368 369
369 obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; 370 obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size;
370 num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; 371 num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk;
@@ -380,10 +381,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
380 table->coherent = use_coherent; 381 table->coherent = use_coherent;
381 mutex_init(&table->mutex); 382 mutex_init(&table->mutex);
382 383
384 size = (u64) nobj * obj_size;
383 for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { 385 for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) {
384 chunk_size = MLX4_TABLE_CHUNK_SIZE; 386 chunk_size = MLX4_TABLE_CHUNK_SIZE;
385 if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size) 387 if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size)
386 chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE); 388 chunk_size = PAGE_ALIGN(size -
389 i * MLX4_TABLE_CHUNK_SIZE);
387 390
388 table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, 391 table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT,
389 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | 392 (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
index 19e4efc0b34..a67744f5350 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.h
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
@@ -78,7 +78,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
78void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 78void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
79 int start, int end); 79 int start, int end);
80int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, 80int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
81 u64 virt, int obj_size, int nobj, int reserved, 81 u64 virt, int obj_size, u32 nobj, int reserved,
82 int use_lowmem, int use_coherent); 82 int use_lowmem, int use_coherent);
83void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); 83void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table);
84void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); 84void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 59ebc033963..4d9df8f2a12 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -249,7 +249,7 @@ struct mlx4_bitmap {
249struct mlx4_buddy { 249struct mlx4_buddy {
250 unsigned long **bits; 250 unsigned long **bits;
251 unsigned int *num_free; 251 unsigned int *num_free;
252 int max_order; 252 u32 max_order;
253 spinlock_t lock; 253 spinlock_t lock;
254}; 254};
255 255
@@ -258,7 +258,7 @@ struct mlx4_icm;
258struct mlx4_icm_table { 258struct mlx4_icm_table {
259 u64 virt; 259 u64 virt;
260 int num_icm; 260 int num_icm;
261 int num_obj; 261 u32 num_obj;
262 int obj_size; 262 int obj_size;
263 int lowmem; 263 int lowmem;
264 int coherent; 264 int coherent;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index d6a3a392a37..44b8e1ea1cd 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -678,7 +678,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
678 return err; 678 return err;
679 679
680 err = mlx4_buddy_init(&mr_table->mtt_buddy, 680 err = mlx4_buddy_init(&mr_table->mtt_buddy,
681 ilog2(dev->caps.num_mtts / 681 ilog2((u32)dev->caps.num_mtts /
682 (1 << log_mtts_per_seg))); 682 (1 << log_mtts_per_seg)));
683 if (err) 683 if (err)
684 goto err_buddy; 684 goto err_buddy;
@@ -688,7 +688,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev)
688 mlx4_alloc_mtt_range(dev, 688 mlx4_alloc_mtt_range(dev,
689 fls(dev->caps.reserved_mtts - 1)); 689 fls(dev->caps.reserved_mtts - 1));
690 if (priv->reserved_mtts < 0) { 690 if (priv->reserved_mtts < 0) {
691 mlx4_warn(dev, "MTT table of order %d is too small.\n", 691 mlx4_warn(dev, "MTT table of order %u is too small.\n",
692 mr_table->mtt_buddy.max_order); 692 mr_table->mtt_buddy.max_order);
693 err = -ENOMEM; 693 err = -ENOMEM;
694 goto err_reserve_mtts; 694 goto err_reserve_mtts;
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c
index 9ee4725363d..8e0c3cc2a1e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/profile.c
+++ b/drivers/net/ethernet/mellanox/mlx4/profile.c
@@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
76 u64 size; 76 u64 size;
77 u64 start; 77 u64 start;
78 int type; 78 int type;
79 int num; 79 u32 num;
80 int log_num; 80 int log_num;
81 }; 81 };
82 82
@@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev,
105 si_meminfo(&si); 105 si_meminfo(&si);
106 request->num_mtt = 106 request->num_mtt =
107 roundup_pow_of_two(max_t(unsigned, request->num_mtt, 107 roundup_pow_of_two(max_t(unsigned, request->num_mtt,
108 min(1UL << 31, 108 min(1UL << (31 - log_mtts_per_seg),
109 si.totalram >> (log_mtts_per_seg - 1)))); 109 si.totalram >> (log_mtts_per_seg - 1))));
110 110
111 profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; 111 profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz;