Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14de986a authored by Ralph Campbell's avatar Ralph Campbell Committed by Roland Dreier
Browse files

IB/ipath: Fix offset returned to ibv_modify_srq()



The wrong offset was being returned to libipathverbs so that when
ibv_modify_srq() calls mmap(), it always fails.

Signed-off-by: default avatarRalph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 8a278e6d
Loading
Loading
Loading
Loading
+25 −17
Original line number Original line Diff line number Diff line
@@ -211,11 +211,11 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
		     struct ib_udata *udata)
		     struct ib_udata *udata)
{
{
	struct ipath_srq *srq = to_isrq(ibsrq);
	struct ipath_srq *srq = to_isrq(ibsrq);
	struct ipath_rwq *wq;
	int ret = 0;
	int ret = 0;


	if (attr_mask & IB_SRQ_MAX_WR) {
	if (attr_mask & IB_SRQ_MAX_WR) {
		struct ipath_rwq *owq;
		struct ipath_rwq *owq;
		struct ipath_rwq *wq;
		struct ipath_rwqe *p;
		struct ipath_rwqe *p;
		u32 sz, size, n, head, tail;
		u32 sz, size, n, head, tail;


@@ -236,27 +236,20 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
			goto bail;
			goto bail;
		}
		}


		/*
		/* Check that we can write the offset to mmap. */
		 * Return the address of the RWQ as the offset to mmap.
		 * See ipath_mmap() for details.
		 */
		if (udata && udata->inlen >= sizeof(__u64)) {
		if (udata && udata->inlen >= sizeof(__u64)) {
			__u64 offset_addr;
			__u64 offset_addr;
			__u64 offset = (__u64) wq;
			__u64 offset = 0;


			ret = ib_copy_from_udata(&offset_addr, udata,
			ret = ib_copy_from_udata(&offset_addr, udata,
						 sizeof(offset_addr));
						 sizeof(offset_addr));
			if (ret) {
			if (ret)
				vfree(wq);
				goto bail_free;
				goto bail;
			}
			udata->outbuf = (void __user *) offset_addr;
			udata->outbuf = (void __user *) offset_addr;
			ret = ib_copy_to_udata(udata, &offset,
			ret = ib_copy_to_udata(udata, &offset,
					       sizeof(offset));
					       sizeof(offset));
			if (ret) {
			if (ret)
				vfree(wq);
				goto bail_free;
				goto bail;
			}
		}
		}


		spin_lock_irq(&srq->rq.lock);
		spin_lock_irq(&srq->rq.lock);
@@ -277,10 +270,8 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
		else
		else
			n -= tail;
			n -= tail;
		if (size <= n) {
		if (size <= n) {
			spin_unlock_irq(&srq->rq.lock);
			vfree(wq);
			ret = -EINVAL;
			ret = -EINVAL;
			goto bail;
			goto bail_unlock;
		}
		}
		n = 0;
		n = 0;
		p = wq->wq;
		p = wq->wq;
@@ -314,6 +305,18 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
			u32 s = sizeof(struct ipath_rwq) + size * sz;
			u32 s = sizeof(struct ipath_rwq) + size * sz;


			ipath_update_mmap_info(dev, ip, s, wq);
			ipath_update_mmap_info(dev, ip, s, wq);

			/*
			 * Return the offset to mmap.
			 * See ipath_mmap() for details.
			 */
			if (udata && udata->inlen >= sizeof(__u64)) {
				ret = ib_copy_to_udata(udata, &ip->offset,
						       sizeof(ip->offset));
				if (ret)
					goto bail;
			}

			spin_lock_irq(&dev->pending_lock);
			spin_lock_irq(&dev->pending_lock);
			if (list_empty(&ip->pending_mmaps))
			if (list_empty(&ip->pending_mmaps))
				list_add(&ip->pending_mmaps,
				list_add(&ip->pending_mmaps,
@@ -328,7 +331,12 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
			srq->limit = attr->srq_limit;
			srq->limit = attr->srq_limit;
		spin_unlock_irq(&srq->rq.lock);
		spin_unlock_irq(&srq->rq.lock);
	}
	}
	goto bail;


bail_unlock:
	spin_unlock_irq(&srq->rq.lock);
bail_free:
	vfree(wq);
bail:
bail:
	return ret;
	return ret;
}
}