|
@@ -87,16 +87,14 @@ static int enforce_qp_pkey_security(u16 pkey,
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- if (qp_sec->qp == qp_sec->qp->real_qp) {
|
|
|
- list_for_each_entry(shared_qp_sec,
|
|
|
- &qp_sec->shared_qp_list,
|
|
|
- shared_qp_list) {
|
|
|
- ret = security_ib_pkey_access(shared_qp_sec->security,
|
|
|
- subnet_prefix,
|
|
|
- pkey);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
- }
|
|
|
+ list_for_each_entry(shared_qp_sec,
|
|
|
+ &qp_sec->shared_qp_list,
|
|
|
+ shared_qp_list) {
|
|
|
+ ret = security_ib_pkey_access(shared_qp_sec->security,
|
|
|
+ subnet_prefix,
|
|
|
+ pkey);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -560,15 +558,22 @@ int ib_security_modify_qp(struct ib_qp *qp,
|
|
|
int ret = 0;
|
|
|
struct ib_ports_pkeys *tmp_pps;
|
|
|
struct ib_ports_pkeys *new_pps;
|
|
|
- bool special_qp = (qp->qp_type == IB_QPT_SMI ||
|
|
|
- qp->qp_type == IB_QPT_GSI ||
|
|
|
- qp->qp_type >= IB_QPT_RESERVED1);
|
|
|
+ struct ib_qp *real_qp = qp->real_qp;
|
|
|
+ bool special_qp = (real_qp->qp_type == IB_QPT_SMI ||
|
|
|
+ real_qp->qp_type == IB_QPT_GSI ||
|
|
|
+ real_qp->qp_type >= IB_QPT_RESERVED1);
|
|
|
bool pps_change = ((qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) ||
|
|
|
(qp_attr_mask & IB_QP_ALT_PATH));
|
|
|
|
|
|
+ /* The port/pkey settings are maintained only for the real QP. Open
|
|
|
+ * handles on the real QP will be in the shared_qp_list. When
|
|
|
+ * enforcing security on the real QP all the shared QPs will be
|
|
|
+ * checked as well.
|
|
|
+ */
|
|
|
+
|
|
|
if (pps_change && !special_qp) {
|
|
|
- mutex_lock(&qp->qp_sec->mutex);
|
|
|
- new_pps = get_new_pps(qp,
|
|
|
+ mutex_lock(&real_qp->qp_sec->mutex);
|
|
|
+ new_pps = get_new_pps(real_qp,
|
|
|
qp_attr,
|
|
|
qp_attr_mask);
|
|
|
|
|
@@ -586,14 +591,14 @@ int ib_security_modify_qp(struct ib_qp *qp,
|
|
|
|
|
|
if (!ret)
|
|
|
ret = check_qp_port_pkey_settings(new_pps,
|
|
|
- qp->qp_sec);
|
|
|
+ real_qp->qp_sec);
|
|
|
}
|
|
|
|
|
|
if (!ret)
|
|
|
- ret = qp->device->modify_qp(qp->real_qp,
|
|
|
- qp_attr,
|
|
|
- qp_attr_mask,
|
|
|
- udata);
|
|
|
+ ret = real_qp->device->modify_qp(real_qp,
|
|
|
+ qp_attr,
|
|
|
+ qp_attr_mask,
|
|
|
+ udata);
|
|
|
|
|
|
if (pps_change && !special_qp) {
|
|
|
/* Clean up the lists and free the appropriate
|
|
@@ -602,8 +607,8 @@ int ib_security_modify_qp(struct ib_qp *qp,
|
|
|
if (ret) {
|
|
|
tmp_pps = new_pps;
|
|
|
} else {
|
|
|
- tmp_pps = qp->qp_sec->ports_pkeys;
|
|
|
- qp->qp_sec->ports_pkeys = new_pps;
|
|
|
+ tmp_pps = real_qp->qp_sec->ports_pkeys;
|
|
|
+ real_qp->qp_sec->ports_pkeys = new_pps;
|
|
|
}
|
|
|
|
|
|
if (tmp_pps) {
|
|
@@ -611,7 +616,7 @@ int ib_security_modify_qp(struct ib_qp *qp,
|
|
|
port_pkey_list_remove(&tmp_pps->alt);
|
|
|
}
|
|
|
kfree(tmp_pps);
|
|
|
- mutex_unlock(&qp->qp_sec->mutex);
|
|
|
+ mutex_unlock(&real_qp->qp_sec->mutex);
|
|
|
}
|
|
|
return ret;
|
|
|
}
|