Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/rdmavt, hfi1, qib: Modify check_ah() to account for extended LIDs

rvt_check_ah() delegates lid verification to underlying
driver. Underlying driver uses different conditions to
check for dlid depending on whether the device supports
extended LIDs

Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Don Hiatt <don.hiatt@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Don Hiatt and committed by
Doug Ledford
13c19222 d295dbeb

+58 -27
-9
drivers/infiniband/hw/hfi1/common.h
··· 333 333 334 334 #define DEFAULT_P_KEY LIM_MGMT_P_KEY 335 335 336 - /** 337 - * 0xF8 - 4 bits of multicast range and 1 bit for collective range 338 - * Example: For 24 bit LID space, 339 - * Multicast range: 0xF00000 to 0xF7FFFF 340 - * Collective range: 0xF80000 to 0xFFFFFE 341 - */ 342 - #define HFI1_MCAST_NR 0x4 /* Number of top bits set */ 343 - #define HFI1_COLLECTIVE_NR 0x1 /* Number of bits after MCAST_NR */ 344 - 345 336 #define HFI1_PSM_IOC_BASE_SEQ 0x0 346 337 347 338 static inline __u64 rhf_to_cpu(const __le32 *rbuf)
+3 -2
drivers/infiniband/hw/hfi1/mad.c
··· 46 46 */ 47 47 48 48 #include <linux/net.h> 49 + #include <rdma/opa_addr.h> 49 50 #define OPA_NUM_PKEY_BLOCKS_PER_SMP (OPA_SMP_DR_DATA_SIZE \ 50 51 / (OPA_PARTITION_TABLE_BLK_SIZE * sizeof(u16))) 51 52 ··· 906 905 pi->buffer_units = cpu_to_be32(buffer_units); 907 906 908 907 pi->opa_cap_mask = cpu_to_be16(ibp->rvp.port_cap3_flags); 909 - pi->collectivemask_multicastmask = ((HFI1_COLLECTIVE_NR & 0x7) 910 - << 3 | (HFI1_MCAST_NR & 0x7)); 908 + pi->collectivemask_multicastmask = ((OPA_COLLECTIVE_NR & 0x7) 909 + << 3 | (OPA_MCAST_NR & 0x7)); 911 910 912 911 /* HFI supports a replay buffer 128 LTPs in size */ 913 912 pi->replay_depth.buffer = 0x80;
+5
drivers/infiniband/hw/hfi1/verbs.c
··· 53 53 #include <linux/rculist.h> 54 54 #include <linux/mm.h> 55 55 #include <linux/vmalloc.h> 56 + #include <rdma/opa_addr.h> 56 57 57 58 #include "hfi.h" 58 59 #include "common.h" ··· 1461 1460 struct hfi1_pportdata *ppd; 1462 1461 struct hfi1_devdata *dd; 1463 1462 u8 sc5; 1463 + 1464 + if (hfi1_check_mcast(rdma_ah_get_dlid(ah_attr)) && 1465 + !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) 1466 + return -EINVAL; 1464 1467 1465 1468 /* test the mapping for validity */ 1466 1469 ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr));
+9
drivers/infiniband/hw/qib/qib_verbs.c
··· 1341 1341 if (rdma_ah_get_sl(ah_attr) > 15) 1342 1342 return -EINVAL; 1343 1343 1344 + if (rdma_ah_get_dlid(ah_attr) == 0) 1345 + return -EINVAL; 1346 + if (rdma_ah_get_dlid(ah_attr) >= 1347 + be16_to_cpu(IB_MULTICAST_LID_BASE) && 1348 + rdma_ah_get_dlid(ah_attr) != 1349 + be16_to_cpu(IB_LID_PERMISSIVE) && 1350 + !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) 1351 + return -EINVAL; 1352 + 1344 1353 return 0; 1345 1354 } 1346 1355
-10
drivers/infiniband/sw/rdmavt/ah.c
··· 66 66 int port_num = rdma_ah_get_port_num(ah_attr); 67 67 struct ib_port_attr port_attr; 68 68 struct rvt_dev_info *rdi = ib_to_rvt(ibdev); 69 - enum rdma_link_layer link = rdma_port_get_link_layer(ibdev, port_num); 70 - u32 dlid = rdma_ah_get_dlid(ah_attr); 71 69 u8 ah_flags = rdma_ah_get_ah_flags(ah_attr); 72 70 u8 static_rate = rdma_ah_get_static_rate(ah_attr); 73 71 ··· 81 83 if ((ah_flags & IB_AH_GRH) && 82 84 rdma_ah_read_grh(ah_attr)->sgid_index >= port_attr.gid_tbl_len) 83 85 return -EINVAL; 84 - if (link != IB_LINK_LAYER_ETHERNET) { 85 - if (dlid == 0) 86 - return -EINVAL; 87 - if (dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE) && 88 - dlid != be16_to_cpu(IB_LID_PERMISSIVE) && 89 - !(ah_flags & IB_AH_GRH)) 90 - return -EINVAL; 91 - } 92 86 if (rdi->driver_f.check_ah) 93 87 return rdi->driver_f.check_ah(ibdev, ah_attr); 94 88 return 0;
+23 -6
drivers/infiniband/sw/rdmavt/qp.c
··· 52 52 #include <linux/slab.h> 53 53 #include <rdma/ib_verbs.h> 54 54 #include <rdma/ib_hdrs.h> 55 + #include <rdma/opa_addr.h> 55 56 #include "qp.h" 56 57 #include "vt.h" 57 58 #include "trace.h" ··· 1067 1066 int mig = 0; 1068 1067 int pmtu = 0; /* for gcc warning only */ 1069 1068 enum rdma_link_layer link; 1069 + int opa_ah; 1070 1070 1071 1071 link = rdma_port_get_link_layer(ibqp->device, qp->port_num); 1072 1072 ··· 1078 1076 cur_state = attr_mask & IB_QP_CUR_STATE ? 1079 1077 attr->cur_qp_state : qp->state; 1080 1078 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; 1079 + opa_ah = rdma_cap_opa_ah(ibqp->device, qp->port_num); 1081 1080 1082 1081 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, 1083 1082 attr_mask, link)) ··· 1089 1086 goto inval; 1090 1087 1091 1088 if (attr_mask & IB_QP_AV) { 1092 - if (rdma_ah_get_dlid(&attr->ah_attr) >= 1093 - be16_to_cpu(IB_MULTICAST_LID_BASE)) 1094 - goto inval; 1089 + if (opa_ah) { 1090 + if (rdma_ah_get_dlid(&attr->ah_attr) >= 1091 + opa_get_mcast_base(OPA_MCAST_NR)) 1092 + goto inval; 1093 + } else { 1094 + if (rdma_ah_get_dlid(&attr->ah_attr) >= 1095 + be16_to_cpu(IB_MULTICAST_LID_BASE)) 1096 + goto inval; 1097 + } 1098 + 1095 1099 if (rvt_check_ah(qp->ibqp.device, &attr->ah_attr)) 1096 1100 goto inval; 1097 1101 } 1098 1102 1099 1103 if (attr_mask & IB_QP_ALT_PATH) { 1100 - if (rdma_ah_get_dlid(&attr->alt_ah_attr) >= 1101 - be16_to_cpu(IB_MULTICAST_LID_BASE)) 1102 - goto inval; 1104 + if (opa_ah) { 1105 + if (rdma_ah_get_dlid(&attr->alt_ah_attr) >= 1106 + opa_get_mcast_base(OPA_MCAST_NR)) 1107 + goto inval; 1108 + } else { 1109 + if (rdma_ah_get_dlid(&attr->alt_ah_attr) >= 1110 + be16_to_cpu(IB_MULTICAST_LID_BASE)) 1111 + goto inval; 1112 + } 1113 + 1103 1114 if (rvt_check_ah(qp->ibqp.device, &attr->alt_ah_attr)) 1104 1115 goto inval; 1105 1116 if (attr->alt_pkey_index >= rvt_get_npkeys(rdi))
+18
include/rdma/opa_addr.h
··· 48 48 #ifndef OPA_ADDR_H 49 49 #define OPA_ADDR_H 50 50 51 + #include <rdma/opa_smi.h> 52 + 51 53 #define OPA_SPECIAL_OUI (0x00066AULL) 52 54 #define OPA_MAKE_ID(x) (cpu_to_be64(OPA_SPECIAL_OUI << 40 | (x))) 53 55 #define OPA_TO_IB_UCAST_LID(x) (((x) >= be16_to_cpu(IB_MULTICAST_LID_BASE)) \ 54 56 ? 0 : x) 57 + /** 58 + * 0xF8 - 4 bits of multicast range and 1 bit for collective range 59 + * Example: For 24 bit LID space, 60 + * Multicast range: 0xF00000 to 0xF7FFFF 61 + * Collective range: 0xF80000 to 0xFFFFFE 62 + */ 63 + #define OPA_MCAST_NR 0x4 /* Number of top bits set */ 64 + #define OPA_COLLECTIVE_NR 0x1 /* Number of bits after MCAST_NR */ 65 + 55 66 /** 56 67 * ib_is_opa_gid: Returns true if the top 24 bits of the gid 57 68 * contains the OPA_STL_OUI identifier. This identifies that ··· 106 95 else 107 96 return false; 108 97 } 98 + 99 + /* Get multicast lid base */ 100 + static inline u32 opa_get_mcast_base(u32 nr_top_bits) 101 + { 102 + return (be32_to_cpu(OPA_LID_PERMISSIVE) << (32 - nr_top_bits)); 103 + } 104 + 109 105 #endif /* OPA_ADDR_H */