diff options
author | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:01:13 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-17 00:01:13 -0400 |
commit | 19773539d6369c54fbb0c870de0c75417b0020d1 (patch) | |
tree | cf1f05517a3aa68fd13f2e2a18389316d0420379 /drivers/infiniband/hw/mthca | |
parent | f4f82994d1ea0cd01058a245985f1eb5e569e6d3 (diff) |
IB/mthca: Avoid integer overflow when dealing with profile size
mthca_make_profile() returns the size in bytes of the HCA context
layout it creates, or a negative value if an error occurs. However,
the return value is declared as u64 and the memfree initialization
path casts this value to int to test if it is negative. This makes it
think incorrectly than an error has occurred if the context size
happens to be bigger than 2GB, since this turns into a negative int.
Fix this by having mthca_make_profile() return an s64 and testing
for an error by checking whether this 64-bit value itself is negative.
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/mthca')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_profile.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_profile.h | 2 |
3 files changed, 10 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 3889ae859f51..9ebadd6e0cfb 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -276,6 +276,7 @@ static int mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim) | |||
276 | 276 | ||
277 | static int mthca_init_tavor(struct mthca_dev *mdev) | 277 | static int mthca_init_tavor(struct mthca_dev *mdev) |
278 | { | 278 | { |
279 | s64 size; | ||
279 | u8 status; | 280 | u8 status; |
280 | int err; | 281 | int err; |
281 | struct mthca_dev_lim dev_lim; | 282 | struct mthca_dev_lim dev_lim; |
@@ -328,9 +329,11 @@ static int mthca_init_tavor(struct mthca_dev *mdev) | |||
328 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) | 329 | if (mdev->mthca_flags & MTHCA_FLAG_SRQ) |
329 | profile.num_srq = dev_lim.max_srqs; | 330 | profile.num_srq = dev_lim.max_srqs; |
330 | 331 | ||
331 | err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); | 332 | size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); |
332 | if (err < 0) | 333 | if (size < 0) { |
334 | err = size; | ||
333 | goto err_disable; | 335 | goto err_disable; |
336 | } | ||
334 | 337 | ||
335 | err = mthca_INIT_HCA(mdev, &init_hca, &status); | 338 | err = mthca_INIT_HCA(mdev, &init_hca, &status); |
336 | if (err) { | 339 | if (err) { |
@@ -609,7 +612,7 @@ static int mthca_init_arbel(struct mthca_dev *mdev) | |||
609 | struct mthca_dev_lim dev_lim; | 612 | struct mthca_dev_lim dev_lim; |
610 | struct mthca_profile profile; | 613 | struct mthca_profile profile; |
611 | struct mthca_init_hca_param init_hca; | 614 | struct mthca_init_hca_param init_hca; |
612 | u64 icm_size; | 615 | s64 icm_size; |
613 | u8 status; | 616 | u8 status; |
614 | int err; | 617 | int err; |
615 | 618 | ||
@@ -657,7 +660,7 @@ static int mthca_init_arbel(struct mthca_dev *mdev) | |||
657 | profile.num_srq = dev_lim.max_srqs; | 660 | profile.num_srq = dev_lim.max_srqs; |
658 | 661 | ||
659 | icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); | 662 | icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca); |
660 | if ((int) icm_size < 0) { | 663 | if (icm_size < 0) { |
661 | err = icm_size; | 664 | err = icm_size; |
662 | goto err_stop_fw; | 665 | goto err_stop_fw; |
663 | } | 666 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c index 26bf86d1cfcd..605a8d57fac6 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.c +++ b/drivers/infiniband/hw/mthca/mthca_profile.c | |||
@@ -63,7 +63,7 @@ enum { | |||
63 | MTHCA_NUM_PDS = 1 << 15 | 63 | MTHCA_NUM_PDS = 1 << 15 |
64 | }; | 64 | }; |
65 | 65 | ||
66 | u64 mthca_make_profile(struct mthca_dev *dev, | 66 | s64 mthca_make_profile(struct mthca_dev *dev, |
67 | struct mthca_profile *request, | 67 | struct mthca_profile *request, |
68 | struct mthca_dev_lim *dev_lim, | 68 | struct mthca_dev_lim *dev_lim, |
69 | struct mthca_init_hca_param *init_hca) | 69 | struct mthca_init_hca_param *init_hca) |
@@ -77,7 +77,7 @@ u64 mthca_make_profile(struct mthca_dev *dev, | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | u64 mem_base, mem_avail; | 79 | u64 mem_base, mem_avail; |
80 | u64 total_size = 0; | 80 | s64 total_size = 0; |
81 | struct mthca_resource *profile; | 81 | struct mthca_resource *profile; |
82 | struct mthca_resource tmp; | 82 | struct mthca_resource tmp; |
83 | int i, j; | 83 | int i, j; |
diff --git a/drivers/infiniband/hw/mthca/mthca_profile.h b/drivers/infiniband/hw/mthca/mthca_profile.h index 94641808f97f..e76cb62d8e32 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.h +++ b/drivers/infiniband/hw/mthca/mthca_profile.h | |||
@@ -53,7 +53,7 @@ struct mthca_profile { | |||
53 | int fmr_reserved_mtts; | 53 | int fmr_reserved_mtts; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | u64 mthca_make_profile(struct mthca_dev *mdev, | 56 | s64 mthca_make_profile(struct mthca_dev *mdev, |
57 | struct mthca_profile *request, | 57 | struct mthca_profile *request, |
58 | struct mthca_dev_lim *dev_lim, | 58 | struct mthca_dev_lim *dev_lim, |
59 | struct mthca_init_hca_param *init_hca); | 59 | struct mthca_init_hca_param *init_hca); |