aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/cxgb4/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/mem.c')
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c28
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;
50module_param(inline_threshold, int, 0644); 50module_param(inline_threshold, int, 0644);
51MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)"); 51MODULE_PARM_DESC(inline_threshold, "inline vs dsgl threshold (default=128)");
52 52
53static 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
53static int _c4iw_write_mem_dma_aligned(struct c4iw_rdev *rdev, u32 addr, 60static 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);