Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/dledford/rdma

Pull rdma fixes from Doug Ledford:
 "Final set of -rc fixes for 4.6.

  I've collected up a number of patches that are all pretty small with
  the exception of only a couple.  The hfi1 driver has a number of
  important patches, and it is what really drives the line count of this
  pull request up.  These are all small and I've got this kernel built
  and running in the test lab (I have most of the hardware, I think nes
  is the only thing in this patch set that I can't say I've personally
  tested and have up and running).

  Summary:

   - A number of collected fixes for oopses, memory corruptions,
     deadlocks, etc.  All of these fixes are small (many only 5-10
     lines), obvious, and tested.

   - Fix for the security issue related to the use of write for
     bi-directional communications"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
  RDMA/nes: don't leak skb if carrier down
  IB/security: Restrict use of the write() interface
  IB/hfi1: Use kernel default llseek for ui device
  IB/hfi1: Don't attempt to free resources if initialization failed
  IB/hfi1: Fix missing lock/unlock in verbs drain callback
  IB/rdmavt: Fix send scheduling
  IB/hfi1: Prevent unpinning of wrong pages
  IB/hfi1: Fix deadlock caused by locking with wrong scope
  IB/hfi1: Prevent NULL pointer deferences in caching code
  MAINTAINERS: Update iser/isert maintainer contact info
  IB/mlx5: Expose correct max_sge_rd limit
  RDMA/iw_cxgb4: Fix bar2 virt addr calculation for T4 chips
  iw_cxgb4: handle draining an idle qp
  iw_cxgb3: initialize ibdev.iwcm->ifname for port mapping
  iw_cxgb4: initialize ibdev.iwcm->ifname for port mapping
  IB/core: Don't drain non-existent rq queue-pair
  IB/core: Fix oops in ib_cache_gid_set_default_gid
  • Loading branch information
torvalds committed Apr 30, 2016
2 parents 1d003af + 4c8bb95 commit 925d96a
Show file tree
Hide file tree
Showing 23 changed files with 173 additions and 102 deletions.
4 changes: 2 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6027,7 +6027,7 @@ F: include/scsi/*iscsi*

ISCSI EXTENSIONS FOR RDMA (ISER) INITIATOR
M: Or Gerlitz <[email protected]>
M: Sagi Grimberg <[email protected]>
M: Sagi Grimberg <[email protected]>
M: Roi Dayan <[email protected]>
L: [email protected]
S: Supported
Expand All @@ -6037,7 +6037,7 @@ Q: http://patchwork.kernel.org/project/linux-rdma/list/
F: drivers/infiniband/ulp/iser/

ISCSI EXTENSIONS FOR RDMA (ISER) TARGET
M: Sagi Grimberg <[email protected]>
M: Sagi Grimberg <[email protected]>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
L: [email protected]
L: [email protected]
Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,8 @@ void ib_cache_gid_set_default_gid(struct ib_device *ib_dev, u8 port,
NULL);

/* Coudn't find default GID location */
WARN_ON(ix < 0);
if (WARN_ON(ix < 0))
goto release;

zattr_type.gid_type = gid_type;

Expand Down
4 changes: 4 additions & 0 deletions drivers/infiniband/core/ucm.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#include <asm/uaccess.h>

#include <rdma/ib.h>
#include <rdma/ib_cm.h>
#include <rdma/ib_user_cm.h>
#include <rdma/ib_marshall.h>
Expand Down Expand Up @@ -1103,6 +1104,9 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,
struct ib_ucm_cmd_hdr hdr;
ssize_t result;

if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
return -EACCES;

if (len < sizeof(hdr))
return -EINVAL;

Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/core/ucma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,9 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf,
struct rdma_ucm_cmd_hdr hdr;
ssize_t ret;

if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
return -EACCES;

if (len < sizeof(hdr))
return -EINVAL;

Expand Down
5 changes: 5 additions & 0 deletions drivers/infiniband/core/uverbs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

#include <asm/uaccess.h>

#include <rdma/ib.h>

#include "uverbs.h"

MODULE_AUTHOR("Roland Dreier");
Expand Down Expand Up @@ -709,6 +711,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
int srcu_key;
ssize_t ret;

if (WARN_ON_ONCE(!ib_safe_file_access(filp)))
return -EACCES;

if (count < sizeof hdr)
return -EINVAL;

Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1860,6 +1860,7 @@ EXPORT_SYMBOL(ib_drain_rq);
void ib_drain_qp(struct ib_qp *qp)
{
ib_drain_sq(qp);
ib_drain_rq(qp);
if (!qp->srq)
ib_drain_rq(qp);
}
EXPORT_SYMBOL(ib_drain_qp);
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/cxgb3/iwch_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,8 @@ int iwch_register_device(struct iwch_dev *dev)
dev->ibdev.iwcm->add_ref = iwch_qp_add_ref;
dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref;
dev->ibdev.iwcm->get_qp = iwch_get_qp;
memcpy(dev->ibdev.iwcm->ifname, dev->rdev.t3cdev_p->lldev->name,
sizeof(dev->ibdev.iwcm->ifname));

ret = ib_register_device(&dev->ibdev, NULL);
if (ret)
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
cq->bar2_va = c4iw_bar2_addrs(rdev, cq->cqid, T4_BAR2_QTYPE_INGRESS,
&cq->bar2_qid,
user ? &cq->bar2_pa : NULL);
if (user && !cq->bar2_va) {
if (user && !cq->bar2_pa) {
pr_warn(MOD "%s: cqid %u not in BAR2 range.\n",
pci_name(rdev->lldi.pdev), cq->cqid);
ret = -EINVAL;
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/cxgb4/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ int c4iw_register_device(struct c4iw_dev *dev)
dev->ibdev.iwcm->add_ref = c4iw_qp_add_ref;
dev->ibdev.iwcm->rem_ref = c4iw_qp_rem_ref;
dev->ibdev.iwcm->get_qp = c4iw_get_qp;
memcpy(dev->ibdev.iwcm->ifname, dev->rdev.lldi.ports[0]->name,
sizeof(dev->ibdev.iwcm->ifname));

ret = ib_register_device(&dev->ibdev, NULL);
if (ret)
Expand Down
24 changes: 21 additions & 3 deletions drivers/infiniband/hw/cxgb4/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ void __iomem *c4iw_bar2_addrs(struct c4iw_rdev *rdev, unsigned int qid,

if (pbar2_pa)
*pbar2_pa = (rdev->bar2_pa + bar2_qoffset) & PAGE_MASK;

if (is_t4(rdev->lldi.adapter_type))
return NULL;

return rdev->bar2_kva + bar2_qoffset;
}

Expand Down Expand Up @@ -270,7 +274,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
/*
* User mode must have bar2 access.
*/
if (user && (!wq->sq.bar2_va || !wq->rq.bar2_va)) {
if (user && (!wq->sq.bar2_pa || !wq->rq.bar2_pa)) {
pr_warn(MOD "%s: sqid %u or rqid %u not in BAR2 range.\n",
pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid);
goto free_dma;
Expand Down Expand Up @@ -1895,13 +1899,27 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
void c4iw_drain_sq(struct ib_qp *ibqp)
{
struct c4iw_qp *qp = to_c4iw_qp(ibqp);
unsigned long flag;
bool need_to_wait;

wait_for_completion(&qp->sq_drained);
spin_lock_irqsave(&qp->lock, flag);
need_to_wait = !t4_sq_empty(&qp->wq);
spin_unlock_irqrestore(&qp->lock, flag);

if (need_to_wait)
wait_for_completion(&qp->sq_drained);
}

void c4iw_drain_rq(struct ib_qp *ibqp)
{
struct c4iw_qp *qp = to_c4iw_qp(ibqp);
unsigned long flag;
bool need_to_wait;

spin_lock_irqsave(&qp->lock, flag);
need_to_wait = !t4_rq_empty(&qp->wq);
spin_unlock_irqrestore(&qp->lock, flag);

wait_for_completion(&qp->rq_drained);
if (need_to_wait)
wait_for_completion(&qp->rq_drained);
}
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
sizeof(struct mlx5_wqe_ctrl_seg)) /
sizeof(struct mlx5_wqe_data_seg);
props->max_sge = min(max_rq_sg, max_sq_sg);
props->max_sge_rd = props->max_sge;
props->max_sge_rd = MLX5_MAX_SGE_RD;
props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq);
props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1;
props->max_mr = 1 << MLX5_CAP_GEN(mdev, log_max_mkey);
Expand Down
3 changes: 0 additions & 3 deletions drivers/infiniband/hw/nes/nes_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
* skb_shinfo(skb)->nr_frags, skb_is_gso(skb));
*/

if (!netif_carrier_ok(netdev))
return NETDEV_TX_OK;

if (netif_queue_stopped(netdev))
return NETDEV_TX_BUSY;

Expand Down
5 changes: 5 additions & 0 deletions drivers/infiniband/hw/qib/qib_file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include <linux/export.h>
#include <linux/uio.h>

#include <rdma/ib.h>

#include "qib.h"
#include "qib_common.h"
#include "qib_user_sdma.h"
Expand Down Expand Up @@ -2067,6 +2069,9 @@ static ssize_t qib_write(struct file *fp, const char __user *data,
ssize_t ret = 0;
void *dest;

if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
return -EACCES;

if (count < sizeof(cmd.type)) {
ret = -EINVAL;
goto bail;
Expand Down
4 changes: 2 additions & 2 deletions drivers/infiniband/sw/rdmavt/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1637,9 +1637,9 @@ int rvt_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
spin_unlock_irqrestore(&qp->s_hlock, flags);
if (nreq) {
if (call_send)
rdi->driver_f.schedule_send_no_lock(qp);
else
rdi->driver_f.do_send(qp);
else
rdi->driver_f.schedule_send_no_lock(qp);
}
return err;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/rdma/hfi1/TODO
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ July, 2015
- Remove unneeded file entries in sysfs
- Remove software processing of IB protocol and place in library for use
by qib, ipath (if still present), hfi1, and eventually soft-roce

- Replace incorrect uAPI
91 changes: 35 additions & 56 deletions drivers/staging/rdma/hfi1/file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#include <linux/vmalloc.h>
#include <linux/io.h>

#include <rdma/ib.h>

#include "hfi.h"
#include "pio.h"
#include "device.h"
Expand Down Expand Up @@ -190,6 +192,10 @@ static ssize_t hfi1_file_write(struct file *fp, const char __user *data,
int uctxt_required = 1;
int must_be_root = 0;

/* FIXME: This interface cannot continue out of staging */
if (WARN_ON_ONCE(!ib_safe_file_access(fp)))
return -EACCES;

if (count < sizeof(cmd)) {
ret = -EINVAL;
goto bail;
Expand Down Expand Up @@ -791,15 +797,16 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
spin_unlock_irqrestore(&dd->uctxt_lock, flags);

dd->rcd[uctxt->ctxt] = NULL;

hfi1_user_exp_rcv_free(fdata);
hfi1_clear_ctxt_pkey(dd, uctxt->ctxt);

uctxt->rcvwait_to = 0;
uctxt->piowait_to = 0;
uctxt->rcvnowait = 0;
uctxt->pionowait = 0;
uctxt->event_flags = 0;

hfi1_user_exp_rcv_free(fdata);
hfi1_clear_ctxt_pkey(dd, uctxt->ctxt);

hfi1_stats.sps_ctxts--;
if (++dd->freectxts == dd->num_user_contexts)
aspm_enable_all(dd);
Expand Down Expand Up @@ -1127,27 +1134,13 @@ static int setup_subctxt(struct hfi1_ctxtdata *uctxt)

static int user_init(struct file *fp)
{
int ret;
unsigned int rcvctrl_ops = 0;
struct hfi1_filedata *fd = fp->private_data;
struct hfi1_ctxtdata *uctxt = fd->uctxt;

/* make sure that the context has already been setup */
if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags)) {
ret = -EFAULT;
goto done;
}

/*
* Subctxts don't need to initialize anything since master
* has done it.
*/
if (fd->subctxt) {
ret = wait_event_interruptible(uctxt->wait, !test_bit(
HFI1_CTXT_MASTER_UNINIT,
&uctxt->event_flags));
goto expected;
}
if (!test_bit(HFI1_CTXT_SETUP_DONE, &uctxt->event_flags))
return -EFAULT;

/* initialize poll variables... */
uctxt->urgent = 0;
Expand Down Expand Up @@ -1202,19 +1195,7 @@ static int user_init(struct file *fp)
wake_up(&uctxt->wait);
}

expected:
/*
* Expected receive has to be setup for all processes (including
* shared contexts). However, it has to be done after the master
* context has been fully configured as it depends on the
* eager/expected split of the RcvArray entries.
* Setting it up here ensures that the subcontexts will be waiting
* (due to the above wait_event_interruptible() until the master
* is setup.
*/
ret = hfi1_user_exp_rcv_init(fp);
done:
return ret;
return 0;
}

static int get_ctxt_info(struct file *fp, void __user *ubase, __u32 len)
Expand Down Expand Up @@ -1261,7 +1242,7 @@ static int setup_ctxt(struct file *fp)
int ret = 0;

/*
* Context should be set up only once (including allocation and
* Context should be set up only once, including allocation and
* programming of eager buffers. This is done if context sharing
* is not requested or by the master process.
*/
Expand All @@ -1282,8 +1263,27 @@ static int setup_ctxt(struct file *fp)
if (ret)
goto done;
}
} else {
ret = wait_event_interruptible(uctxt->wait, !test_bit(
HFI1_CTXT_MASTER_UNINIT,
&uctxt->event_flags));
if (ret)
goto done;
}

ret = hfi1_user_sdma_alloc_queues(uctxt, fp);
if (ret)
goto done;
/*
* Expected receive has to be setup for all processes (including
* shared contexts). However, it has to be done after the master
* context has been fully configured as it depends on the
* eager/expected split of the RcvArray entries.
* Setting it up here ensures that the subcontexts will be waiting
* (due to the above wait_event_interruptible() until the master
* is setup.
*/
ret = hfi1_user_exp_rcv_init(fp);
if (ret)
goto done;

Expand Down Expand Up @@ -1565,29 +1565,8 @@ static loff_t ui_lseek(struct file *filp, loff_t offset, int whence)
{
struct hfi1_devdata *dd = filp->private_data;

switch (whence) {
case SEEK_SET:
break;
case SEEK_CUR:
offset += filp->f_pos;
break;
case SEEK_END:
offset = ((dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE) -
offset;
break;
default:
return -EINVAL;
}

if (offset < 0)
return -EINVAL;

if (offset >= (dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE)
return -EINVAL;

filp->f_pos = offset;

return filp->f_pos;
return fixed_size_llseek(filp, offset, whence,
(dd->kregend - dd->kregbase) + DC8051_DATA_MEM_SIZE);
}

/* NOTE: assumes unsigned long is 8 bytes */
Expand Down
Loading

0 comments on commit 925d96a

Please sign in to comment.