aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2012-08-29 11:14:35 -0400
committerRoland Dreier <roland@purestorage.com>2012-09-13 20:52:02 -0400
commitdd03e73481564fe57655d37154f84a0af00cb449 (patch)
treebfccd072c4492919bd29c4c2cbf85847a1c21a12
parentfea7a08acb13524b47711625eebea40a0ede69a0 (diff)
mlx4_core: Fix integer overflows so 8TBs of memory registration works
This patch adds on the fixes done in commits 89dd86db78e0 ("mlx4_core: Allow large mlx4_buddy bitmaps") and 3de819e6b642 ("mlx4_core: Fix integer overflow issues around MTT table") so that memory registration of up to 8TB (log_num_mtt=31) finally works. It fixes integer overflows in a few mlx4_table_yyy routines in icm.c by using a u64 intermediate variable, and int/uint issues that caused table indexes to become nagive by setting some variables to be u32 instead of int. These problems cause crashes when a user attempted to register > 512GB of RAM. Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c30
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.h10
2 files changed, 23 insertions, 17 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index daf417923661..31d02649be41 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -227,9 +227,10 @@ int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev)
227 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 227 MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
228} 228}
229 229
230int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj) 230int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
231{ 231{
232 int i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size); 232 u32 i = (obj & (table->num_obj - 1)) /
233 (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
233 int ret = 0; 234 int ret = 0;
234 235
235 mutex_lock(&table->mutex); 236 mutex_lock(&table->mutex);
@@ -262,16 +263,18 @@ out:
262 return ret; 263 return ret;
263} 264}
264 265
265void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj) 266void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj)
266{ 267{
267 int i; 268 u32 i;
269 u64 offset;
268 270
269 i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size); 271 i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size);
270 272
271 mutex_lock(&table->mutex); 273 mutex_lock(&table->mutex);
272 274
273 if (--table->icm[i]->refcount == 0) { 275 if (--table->icm[i]->refcount == 0) {
274 mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE, 276 offset = (u64) i * MLX4_TABLE_CHUNK_SIZE;
277 mlx4_UNMAP_ICM(dev, table->virt + offset,
275 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); 278 MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE);
276 mlx4_free_icm(dev, table->icm[i], table->coherent); 279 mlx4_free_icm(dev, table->icm[i], table->coherent);
277 table->icm[i] = NULL; 280 table->icm[i] = NULL;
@@ -280,9 +283,11 @@ void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj)
280 mutex_unlock(&table->mutex); 283 mutex_unlock(&table->mutex);
281} 284}
282 285
283void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle) 286void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj,
287 dma_addr_t *dma_handle)
284{ 288{
285 int idx, offset, dma_offset, i; 289 int offset, dma_offset, i;
290 u64 idx;
286 struct mlx4_icm_chunk *chunk; 291 struct mlx4_icm_chunk *chunk;
287 struct mlx4_icm *icm; 292 struct mlx4_icm *icm;
288 struct page *page = NULL; 293 struct page *page = NULL;
@@ -292,7 +297,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
292 297
293 mutex_lock(&table->mutex); 298 mutex_lock(&table->mutex);
294 299
295 idx = (obj & (table->num_obj - 1)) * table->obj_size; 300 idx = (u64) (obj & (table->num_obj - 1)) * table->obj_size;
296 icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE]; 301 icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE];
297 dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE; 302 dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE;
298 303
@@ -326,10 +331,11 @@ out:
326} 331}
327 332
328int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 333int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
329 int start, int end) 334 u32 start, u32 end)
330{ 335{
331 int inc = MLX4_TABLE_CHUNK_SIZE / table->obj_size; 336 int inc = MLX4_TABLE_CHUNK_SIZE / table->obj_size;
332 int i, err; 337 int err;
338 u32 i;
333 339
334 for (i = start; i <= end; i += inc) { 340 for (i = start; i <= end; i += inc) {
335 err = mlx4_table_get(dev, table, i); 341 err = mlx4_table_get(dev, table, i);
@@ -349,9 +355,9 @@ fail:
349} 355}
350 356
351void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 357void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
352 int start, int end) 358 u32 start, u32 end)
353{ 359{
354 int i; 360 u32 i;
355 361
356 for (i = start; i <= end; i += MLX4_TABLE_CHUNK_SIZE / table->obj_size) 362 for (i = start; i <= end; i += MLX4_TABLE_CHUNK_SIZE / table->obj_size)
357 mlx4_table_put(dev, table, i); 363 mlx4_table_put(dev, table, i);
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h
index a67744f53506..dee67fa39107 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.h
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.h
@@ -71,17 +71,17 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
71 gfp_t gfp_mask, int coherent); 71 gfp_t gfp_mask, int coherent);
72void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent); 72void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
73 73
74int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 74int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
75void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); 75void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj);
76int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, 76int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
77 int start, int end); 77 u32 start, u32 end);
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 u32 start, u32 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, u32 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, u32 obj, dma_addr_t *dma_handle);
85 85
86static inline void mlx4_icm_first(struct mlx4_icm *icm, 86static inline void mlx4_icm_first(struct mlx4_icm *icm,
87 struct mlx4_icm_iter *iter) 87 struct mlx4_icm_iter *iter)