IB/ipath: be more strict about testing the modify QP verb
authorBryan O'Sullivan <bos@pathscale.com>
Fri, 25 Aug 2006 18:24:41 +0000 (11:24 -0700)
committerRoland Dreier <rolandd@cisco.com>
Fri, 22 Sep 2006 22:22:36 +0000 (15:22 -0700)
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_verbs.h

index c0267cf..502d555 100644 (file)
@@ -455,11 +455,16 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                                attr_mask))
                goto inval;
 
-       if (attr_mask & IB_QP_AV)
+       if (attr_mask & IB_QP_AV) {
                if (attr->ah_attr.dlid == 0 ||
                    attr->ah_attr.dlid >= IPATH_MULTICAST_LID_BASE)
                        goto inval;
 
+               if ((attr->ah_attr.ah_flags & IB_AH_GRH) &&
+                   (attr->ah_attr.grh.sgid_index > 1))
+                       goto inval;
+       }
+
        if (attr_mask & IB_QP_PKEY_INDEX)
                if (attr->pkey_index >= ipath_get_npkeys(dev->dd))
                        goto inval;
@@ -468,6 +473,27 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                if (attr->min_rnr_timer > 31)
                        goto inval;
 
+       if (attr_mask & IB_QP_PORT)
+               if (attr->port_num == 0 ||
+                   attr->port_num > ibqp->device->phys_port_cnt)
+                       goto inval;
+
+       if (attr_mask & IB_QP_PATH_MTU)
+               if (attr->path_mtu > IB_MTU_4096)
+                       goto inval;
+
+       if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+               if (attr->max_dest_rd_atomic > 1)
+                       goto inval;
+
+       if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
+               if (attr->max_rd_atomic > 1)
+                       goto inval;
+
+       if (attr_mask & IB_QP_PATH_MIG_STATE)
+               if (attr->path_mig_state != IB_MIG_MIGRATED)
+                       goto inval;
+
        switch (new_state) {
        case IB_QPS_RESET:
                ipath_reset_qp(qp);
@@ -518,6 +544,9 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        if (attr_mask & IB_QP_MIN_RNR_TIMER)
                qp->r_min_rnr_timer = attr->min_rnr_timer;
 
+       if (attr_mask & IB_QP_TIMEOUT)
+               qp->timeout = attr->timeout;
+
        if (attr_mask & IB_QP_QKEY)
                qp->qkey = attr->qkey;
 
@@ -564,7 +593,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        attr->max_dest_rd_atomic = 1;
        attr->min_rnr_timer = qp->r_min_rnr_timer;
        attr->port_num = 1;
-       attr->timeout = 0;
+       attr->timeout = qp->timeout;
        attr->retry_cnt = qp->s_retry_cnt;
        attr->rnr_retry = qp->s_rnr_retry;
        attr->alt_port_num = 0;
index 9cc0dbf..f295609 100644 (file)
@@ -371,6 +371,7 @@ struct ipath_qp {
        u8 s_retry;             /* requester retry counter */
        u8 s_rnr_retry;         /* requester RNR retry counter */
        u8 s_pkey_index;        /* PKEY index to use */
+       u8 timeout;             /* Timeout for this QP */
        enum ib_mtu path_mtu;
        u32 remote_qpn;
        u32 qkey;               /* QKEY for this QP (for UD or RD) */