diff options
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/mem.c')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/mem.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 0744455cd88b..cb43c2299ac0 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c | |||
@@ -50,6 +50,13 @@ static int inline_threshold = C4IW_INLINE_THRESHOLD; | |||
50 | module_param(inline_threshold, int, 0644); | 50 | module_param(inline_threshold, int, 0644); |
51 | MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); | 51 | MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); |
52 | 52 | ||
53 | static int mr_exceeds_hw_limits(struct c4iw_dev *dev, u64 length) | ||
54 | { | ||
55 | return (is_t4(dev->rdev.lldi.adapter_type) || | ||
56 | is_t5(dev->rdev.lldi.adapter_type)) && | ||
57 | length >= 8*1024*1024*1024ULL; | ||
58 | } | ||
59 | |||
53 | static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, | 60 | static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, |
54 | u32 len, dma_addr_t data, int wait) | 61 | u32 len, dma_addr_t data, int wait) |
55 | { | 62 | { |
@@ -369,9 +376,11 @@ static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php, | |||
369 | int ret; | 376 | int ret; |
370 | 377 | ||
371 | ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid, | 378 | ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid, |
372 | FW_RI_STAG_NSMR, mhp->attr.perms, | 379 | FW_RI_STAG_NSMR, mhp->attr.len ? |
380 | mhp->attr.perms : 0, | ||
373 | mhp->attr.mw_bind_enable, mhp->attr.zbva, | 381 | mhp->attr.mw_bind_enable, mhp->attr.zbva, |
374 | mhp->attr.va_fbo, mhp->attr.len, shift - 12, | 382 | mhp->attr.va_fbo, mhp->attr.len ? |
383 | mhp->attr.len : -1, shift - 12, | ||
375 | mhp->attr.pbl_size, mhp->attr.pbl_addr); | 384 | mhp->attr.pbl_size, mhp->attr.pbl_addr); |
376 | if (ret) | 385 | if (ret) |
377 | return ret; | 386 | return ret; |
@@ -536,6 +545,11 @@ int c4iw_reregister_phys_mem(struct ib_mr *mr, int mr_rereg_mask, | |||
536 | return ret; | 545 | return ret; |
537 | } | 546 | } |
538 | 547 | ||
548 | if (mr_exceeds_hw_limits(rhp, total_size)) { | ||
549 | kfree(page_list); | ||
550 | return -EINVAL; | ||
551 | } | ||
552 | |||
539 | ret = reregister_mem(rhp, php, &mh, shift, npages); | 553 | ret = reregister_mem(rhp, php, &mh, shift, npages); |
540 | kfree(page_list); | 554 | kfree(page_list); |
541 | if (ret) | 555 | if (ret) |
@@ -596,6 +610,12 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, | |||
596 | if (ret) | 610 | if (ret) |
597 | goto err; | 611 | goto err; |
598 | 612 | ||
613 | if (mr_exceeds_hw_limits(rhp, total_size)) { | ||
614 | kfree(page_list); | ||
615 | ret = -EINVAL; | ||
616 | goto err; | ||
617 | } | ||
618 | |||
599 | ret = alloc_pbl(mhp, npages); | 619 | ret = alloc_pbl(mhp, npages); |
600 | if (ret) { | 620 | if (ret) { |
601 | kfree(page_list); | 621 | kfree(page_list); |
@@ -699,6 +719,10 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
699 | 719 | ||
700 | php = to_c4iw_pd(pd); | 720 | php = to_c4iw_pd(pd); |
701 | rhp = php->rhp; | 721 | rhp = php->rhp; |
722 | |||
723 | if (mr_exceeds_hw_limits(rhp, length)) | ||
724 | return ERR_PTR(-EINVAL); | ||
725 | |||
702 | mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); | 726 | mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); |
703 | if (!mhp) | 727 | if (!mhp) |
704 | return ERR_PTR(-ENOMEM); | 728 | return ERR_PTR(-ENOMEM); |