IB/core, hfi1, rdmavt: patches for next 05/29/2017
Subsystems (3)
cover IB/core, hfi1, rdmavt: patches for next 05/29/2017
Hi Doug,
Here is the next set of patches for our drivers for 4.13. The first couple are clean up and general improvement patches. The last two are bug fixes. There is one core change in the mix here. It is to allow QP to transition from reset to error which according to the spec is supposed to be a valid transition.
Patches can can also be found in my GitHub repo at:
https://github.com/ddalessa/kernel/tree/for-4.13
---
Byczkowski, Jakub (1):
IB/hfi1: Modify handling of physical link state by Host Driver
Dennis Dalessandro (6):
IB/rdmavt: Remove duplicated functions IB/hfi1: Ensure dd->gi_mask can not be overflowed IB/hfi1: Fix spelling mistake in linkdown reason IB/hfi1: Use QPN mask to avoid overflow IB/hfi1: Remove subtraction of uninitialized value IB/hfi1,qib: Do not send QKey trap for UD qps
Neel Desai (1):
IB/hfi1: Add error checking for buffer overrun in OPA aggregate
Tadeusz Struk (1):
IB/core: Allow QP state transition from reset to error
drivers/infiniband/core/verbs.c | 1 drivers/infiniband/hw/hfi1/chip.c | 111 ++++++++---- drivers/infiniband/hw/hfi1/chip.h | 2 drivers/infiniband/hw/hfi1/driver.c | 9 + drivers/infiniband/hw/hfi1/hfi.h | 18 ++ drivers/infiniband/hw/hfi1/mad.c | 316 ++++++++++++++++++++------------- drivers/infiniband/hw/hfi1/ruc.c | 8 - drivers/infiniband/hw/hfi1/ud.c | 37 +--- drivers/infiniband/hw/hfi1/verbs.c | 2 drivers/infiniband/hw/hfi1/verbs.h | 4 drivers/infiniband/hw/qib/qib_mad.c | 13 + drivers/infiniband/hw/qib/qib_ruc.c | 20 +- drivers/infiniband/hw/qib/qib_ud.c | 43 +--- drivers/infiniband/hw/qib/qib_verbs.h | 4 drivers/infiniband/sw/rdmavt/qp.c | 37 +--- 15 files changed, 358 insertions(+), 267 deletions(-)
--
-Denny
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170530000314.534.72983.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
PATCH 1/9 IB/rdmavt: Remove duplicated functions
The free_qpn() function from the hfi1/qib driver which was the basis for rdmavt_free_qpn() function was accidentally left in the code. Remove it.
--- drivers/infiniband/sw/rdmavt/qp.c | 37 ++++++++++++++----------------------- 1 files changed, 14 insertions(+), 23 deletions(-)
drivers/infiniband/sw/rdmavt/qp.c +14 -23
@@ -422,15 +422,6 @@ static int alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,return ret; } -static void free_qpn (struct rvt_qpn_table *qpt,u32 qpn) -{ -struct rvt_qpn_map *map; - - map = qpt->map + qpn /RVT_BITS_PER_PAGE ; -if (map->page) -clear_bit (qpn &RVT_BITS_PER_PAGE_MASK , map->page); -} -/** * rvt_clear_mr_refs - Drop help mr refs * @qp: rvt qp data structure
@@ -646,6 +637,19 @@ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,lockdep_assert_held (&qp->s_lock); } +/** rvt_free_qpn - Free a qpn from the bit map +* @qpt: QP table +* @qpn: queue pair number to free +*/ +static void rvt_free_qpn (struct rvt_qpn_table *qpt,u32 qpn) +{ +struct rvt_qpn_map *map; + + map = qpt->map + qpn /RVT_BITS_PER_PAGE ; +if (map->page) +clear_bit (qpn &RVT_BITS_PER_PAGE_MASK , map->page); +} +/** * rvt_create_qp - create a queue pair for a device * @ibpd: the protection domain who's device we create the queue pair for
@@ -936,7 +940,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,kref_put (&qp->ip->ref, rvt_release_mmap_info); bail_qpn: -free_qpn (&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); +rvt_free_qpn (&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); bail_rq_wq:if (!qp->ip)
@@ -1325,19 +1329,6 @@ int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,return -EINVAL ; } -/** rvt_free_qpn - Free a qpn from the bit map -* @qpt: QP table -* @qpn: queue pair number to free -*/ -static void rvt_free_qpn (struct rvt_qpn_table *qpt,u32 qpn) -{ -struct rvt_qpn_map *map; - - map = qpt->map + qpn /RVT_BITS_PER_PAGE ; -if (map->page) -clear_bit (qpn &RVT_BITS_PER_PAGE_MASK , map->page); -} -/** * rvt_destroy_qp - destroy a queue pair * @ibqp: the queue pair to destroy
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/9 IB/hfi1: Ensure dd->gi_mask can not be overflowed
In reply to a message not in the archiveAs the code stands today the array access in remap_intr() is OK. To future proof the code though we should explicitly check to ensure the index value is not outside of the valid range. This is not a straight forward calculation so err on the side of caution.
--- drivers/infiniband/hw/hfi1/chip.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +6 -1
@@ -12832,7 +12832,12 @@ static void remap_intr(struct hfi1_devdata *dd, int isrc, int msix_intr)/* clear from the handled mask of the general interrupt */ m = isrc /64 ; n = isrc %64 ; - dd->gi_mask[m] &= ~((u64 )1 << n); +if (likely (m <CCE_NUM_INT_CSRS )) { + dd->gi_mask[m] &= ~((u64 )1 << n); + }else { +dd_dev_err (dd,"remap interrupt err\n" ); +return ; + }/* direct the chip source to the given MSI-X interrupt */ m = isrc /8 ;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/9 IB/hfi1: Fix spelling mistake in linkdown reason
In reply to a message not in the archiveSpell receive correctly in OPA_LINKDOWN_REASON_RCV_ERROR
--- drivers/infiniband/hw/hfi1/chip.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +1 -1
@@ -6906,7 +6906,7 @@ static void reset_neighbor_info(struct hfi1_pportdata *ppd)static const char *const link_down_reason_strs[] = { [OPA_LINKDOWN_REASON_NONE ] ="None" , - [OPA_LINKDOWN_REASON_RCV_ERROR_0 ] ="Recive error 0" , + [OPA_LINKDOWN_REASON_RCV_ERROR_0 ] ="Receive error 0" , [OPA_LINKDOWN_REASON_BAD_PKT_LEN ] ="Bad packet length" , [OPA_LINKDOWN_REASON_PKT_TOO_LONG ] ="Packet too long" , [OPA_LINKDOWN_REASON_PKT_TOO_SHORT ] ="Packet too short" ,
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/9 IB/hfi1: Use QPN mask to avoid overflow
In reply to a message not in the archiveEnsure we can't come up with an array size that is bigger than the array by applying the QPN mask before the divide in the free_qpn function.
--- drivers/infiniband/sw/rdmavt/qp.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/infiniband/sw/rdmavt/qp.c +1 -1
@@ -645,7 +645,7 @@ static void rvt_free_qpn(struct rvt_qpn_table *qpt, u32 qpn) {struct rvt_qpn_map *map; - map = qpt->map + qpn /RVT_BITS_PER_PAGE ; + map = qpt->map + (qpn &RVT_QPN_MASK ) /RVT_BITS_PER_PAGE ;if (map->page)clear_bit (qpn &RVT_BITS_PER_PAGE_MASK , map->page); }
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/9 IB/hfi1: Remove subtraction of uninitialized value
In reply to a message not in the archiveIn process_receive_packet the packet header field is used to calculate the length of the packet. However this is not necessarily setup. In fact only if the ECN prescan is enabled will the packet header be valid at this point.
The code works as is because we do not do anything with the packet length at this point in the packet processing. The length and header are setup correctly in hfi1_setup_ib_header which is called by the following sequence:
process_receive_packet()
-> rhf_receieve_function_map[]()
--> process_receive_ib()
---> hfi1_setup_9B_packet()
----> hfi1_setup_ib_header()
--- drivers/infiniband/hw/hfi1/driver.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/infiniband/hw/hfi1/driver.c +0 -1
@@ -703,7 +703,6 @@ static inline int process_rcv_packet(struct hfi1_packet *packet, int thread) packet->etype =rhf_rcv_type (packet->rhf); - packet->hlen = (u8 *)packet->rhf_addr - (u8 *)packet->hdr;/* total length */ packet->tlen =rhf_pkt_len (packet->rhf);/* in bytes */ /* retrieve eager buffer details */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/9 IB/hfi1: Add error checking for buffer overrun in OPA aggregate
In reply to a message not in the archiveFrom: Neel Desai <[email protected]>
Improve safety of code by checking the size of the data buffer and prevent buffer overrun
--- drivers/infiniband/hw/hfi1/mad.c | 296 ++++++++++++++++++++++++-------------- 1 files changed, 185 insertions(+), 111 deletions(-)
drivers/infiniband/hw/hfi1/mad.c +185 -111
@@ -59,6 +59,14 @@#define OPA_LINK_WIDTH_RESET_OLD 0x0fff#define OPA_LINK_WIDTH_RESET 0xffff +static int smp_length_check (u32 data_size,u32 request_len) +{ +if (unlikely (request_len < data_size)) +return -EINVAL ; + +return 0 ; +} +static int reply (struct ib_mad_hdr *smp) {/*
@@ -308,11 +316,11 @@ void hfi1_node_desc_chg(struct hfi1_ibport *ibp)static int __subn_get_opa_nodedesc (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev, -u8 port,u32 *resp_len) +u8 port,u32 *resp_len,u32 max_len) {struct opa_node_description *nd; -if (am) { +if (am ||smp_length_check (sizeof (*nd), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -329,7 +337,7 @@ static int __subn_get_opa_nodedesc(struct opa_smp *smp, u32 am,static int __subn_get_opa_nodeinfo (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct opa_node_info *ni;struct hfi1_devdata *dd =dd_from_ibdev (ibdev);
@@ -339,6 +347,7 @@ static int __subn_get_opa_nodeinfo(struct opa_smp *smp, u32 am, u8 *data,/* GUID 0 is illegal */ if (am || pidx >= dd->num_pports || ibdev->node_guid ==0 || +smp_length_check (sizeof (*ni), max_len) ||get_sguid (to_iport (ibdev, port),HFI1_PORT_GUID_INDEX ) ==0 ) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp);
@@ -520,7 +529,7 @@ void read_ltp_rtt(struct hfi1_devdata *dd)static int __subn_get_opa_portinfo (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {int i;struct hfi1_devdata *dd;
@@ -536,7 +545,7 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,u32 buffer_units;u64 tmp =0 ; -if (num_ports !=1 ) { +if (num_ports !=1 ||smp_length_check (sizeof (*pi), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -745,7 +754,7 @@ static int get_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)static int __subn_get_opa_pkeytable (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_devdata *dd =dd_from_ibdev (ibdev);u32 n_blocks_req =OPA_AM_NBLK (am);
@@ -768,6 +777,11 @@ static int __subn_get_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data, size = (n_blocks_req *OPA_PARTITION_TABLE_BLK_SIZE ) *sizeof (u16); +if (smp_length_check (size, max_len)) { + smp->status |=IB_SMP_INVALID_FIELD ; +return reply ((struct ib_mad_hdr *)smp); + } +if (start_block + n_blocks_req > n_blocks_avail || n_blocks_req >OPA_NUM_PKEY_BLOCKS_PER_SMP ) { pr_warn("OPA Get PKey AM Invalid : s 0x%x; req 0x%x; "
@@ -1071,7 +1085,7 @@ static int set_port_states(struct hfi1_pportdata *ppd, struct opa_smp *smp,*/ static int __subn_set_opa_portinfo (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct opa_port_info *pi = (struct opa_port_info *)data;struct ib_event event;
@@ -1092,7 +1106,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,int ret, i, invalid =0 , call_set_mtu =0 ;int call_link_downgrade_policy =0 ; -if (num_ports !=1 ) { +if (num_ports !=1 || +smp_length_check (sizeof (*pi), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1343,7 +1358,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,if (ret)return ret; - ret =__subn_get_opa_portinfo (smp, am, data, ibdev, port, resp_len); + ret =__subn_get_opa_portinfo (smp, am, data, ibdev, port, resp_len, + max_len);/* restore re-reg bit per o14-12.2.1 */ pi->clientrereg_subnettimeout |= clientrereg;
@@ -1360,7 +1376,8 @@ static int __subn_set_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data,return ret; get_only: -return __subn_get_opa_portinfo (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_portinfo (smp, am, data, ibdev, port, resp_len, + max_len); }/**
@@ -1421,7 +1438,7 @@ static int set_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)static int __subn_set_opa_pkeytable (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_devdata *dd =dd_from_ibdev (ibdev);u32 n_blocks_sent =OPA_AM_NBLK (am);
@@ -1431,6 +1448,7 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,int i;u16 n_blocks_avail;unsigned npkeys =hfi1_get_npkeys (dd); +u32 size =0 ;if (n_blocks_sent ==0 ) { pr_warn("OPA Get PKey AM Invalid : P = %d; B = 0x%x; N = 0x%x\n",
@@ -1441,6 +1459,13 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data, n_blocks_avail = (u16)(npkeys /OPA_PARTITION_TABLE_BLK_SIZE ) +1 ; + size =sizeof (u16) * (n_blocks_sent *OPA_PARTITION_TABLE_BLK_SIZE ); + +if (smp_length_check (size, max_len)) { + smp->status |=IB_SMP_INVALID_FIELD ; +return reply ((struct ib_mad_hdr *)smp); + } +if (start_block + n_blocks_sent > n_blocks_avail || n_blocks_sent >OPA_NUM_PKEY_BLOCKS_PER_SMP ) { pr_warn("OPA Set PKey AM Invalid : s 0x%x; req 0x%x; avail 0x%x; blk/smp 0x%lx\n",
@@ -1458,7 +1483,8 @@ static int __subn_set_opa_pkeytable(struct opa_smp *smp, u32 am, u8 *data,return reply ((struct ib_mad_hdr *)smp); } -return __subn_get_opa_pkeytable (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_pkeytable (smp, am, data, ibdev, port, resp_len, + max_len); }#define ILLEGAL_VL 12
@@ -1519,14 +1545,14 @@ static int get_sc2vlt_tables(struct hfi1_devdata *dd, void *data)static int __subn_get_opa_sl_to_sc (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_ibport *ibp =to_iport (ibdev, port);u8 *p = data;size_t size =ARRAY_SIZE (ibp->sl_to_sc);/* == 32 */ unsigned i; -if (am) { +if (am ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1542,14 +1568,15 @@ static int __subn_get_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_sl_to_sc (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_ibport *ibp =to_iport (ibdev, port);u8 *p = data; +size_t size =ARRAY_SIZE (ibp->sl_to_sc);int i;u8 sc; -if (am) { +if (am ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1564,19 +1591,20 @@ static int __subn_set_opa_sl_to_sc(struct opa_smp *smp, u32 am, u8 *data, } } -return __subn_get_opa_sl_to_sc (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_sl_to_sc (smp, am, data, ibdev, port, resp_len, + max_len); }static int __subn_get_opa_sc_to_sl (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_ibport *ibp =to_iport (ibdev, port);u8 *p = data;size_t size =ARRAY_SIZE (ibp->sc_to_sl);/* == 32 */ unsigned i; -if (am) { +if (am ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1592,13 +1620,14 @@ static int __subn_get_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_sc_to_sl (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_ibport *ibp =to_iport (ibdev, port); +size_t size =ARRAY_SIZE (ibp->sc_to_sl);u8 *p = data;int i; -if (am) { +if (am ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1606,19 +1635,20 @@ static int __subn_set_opa_sc_to_sl(struct opa_smp *smp, u32 am, u8 *data,for (i =0 ; i <ARRAY_SIZE (ibp->sc_to_sl); i++) ibp->sc_to_sl[i] = *p++; -return __subn_get_opa_sc_to_sl (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_sc_to_sl (smp, am, data, ibdev, port, resp_len, + max_len); }static int __subn_get_opa_sc_to_vlt (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 n_blocks =OPA_AM_NBLK (am);struct hfi1_devdata *dd =dd_from_ibdev (ibdev);void *vp = (void *)data;size_t size =4 *sizeof (u64); -if (n_blocks !=1 ) { +if (n_blocks !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1633,7 +1663,7 @@ static int __subn_get_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_sc_to_vlt (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 n_blocks =OPA_AM_NBLK (am);int async_update =OPA_AM_ASYNC (am);
@@ -1641,8 +1671,15 @@ static int __subn_set_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,void *vp = (void *)data;struct hfi1_pportdata *ppd;int lstate; +/* +* set_sc2vlt_tables writes the information contained in *data +* to four 64-bit registers SendSC2VLt[0-3]. We need to make +* sure *max_len is not greater than the total size of the four +* SendSC2VLt[0-3] registers. +*/ +size_t size =4 *sizeof (u64); -if (n_blocks !=1 || async_update) { +if (n_blocks !=1 || async_update ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1662,27 +1699,28 @@ static int __subn_set_opa_sc_to_vlt(struct opa_smp *smp, u32 am, u8 *data,set_sc2vlt_tables (dd, vp); -return __subn_get_opa_sc_to_vlt (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_sc_to_vlt (smp, am, data, ibdev, port, resp_len, + max_len); }static int __subn_get_opa_sc_to_vlnt (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 n_blocks =OPA_AM_NPORT (am);struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct hfi1_pportdata *ppd;void *vp = (void *)data; -int size; +int size =sizeof (struct sc2vlnt ); -if (n_blocks !=1 ) { +if (n_blocks !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); } ppd = dd->pport + (port -1 ); - size =fm_get_table (ppd,FM_TBL_SC2VLNT , vp); +fm_get_table (ppd,FM_TBL_SC2VLNT , vp);if (resp_len) *resp_len += size;
@@ -1692,15 +1730,16 @@ static int __subn_get_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_sc_to_vlnt (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 n_blocks =OPA_AM_NPORT (am);struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct hfi1_pportdata *ppd;void *vp = (void *)data;int lstate; +int size =sizeof (struct sc2vlnt ); -if (n_blocks !=1 ) { +if (n_blocks !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1718,12 +1757,12 @@ static int __subn_set_opa_sc_to_vlnt(struct opa_smp *smp, u32 am, u8 *data,fm_set_table (ppd,FM_TBL_SC2VLNT , vp);return __subn_get_opa_sc_to_vlnt (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len); }static int __subn_get_opa_psi (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 nports =OPA_AM_NPORT (am);u32 start_of_sm_config =OPA_AM_START_SM_CFG (am);
@@ -1732,7 +1771,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,struct hfi1_pportdata *ppd;struct opa_port_state_info *psi = (struct opa_port_state_info *)data; -if (nports !=1 ) { +if (nports !=1 ||smp_length_check (sizeof (*psi), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1765,7 +1804,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_psi (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {u32 nports =OPA_AM_NPORT (am);u32 start_of_sm_config =OPA_AM_START_SM_CFG (am);
@@ -1776,7 +1815,7 @@ static int __subn_set_opa_psi(struct opa_smp *smp, u32 am, u8 *data,struct opa_port_state_info *psi = (struct opa_port_state_info *)data;int ret, invalid =0 ; -if (nports !=1 ) { +if (nports !=1 ||smp_length_check (sizeof (*psi), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1806,19 +1845,21 @@ static int __subn_set_opa_psi(struct opa_smp *smp, u32 am, u8 *data,if (invalid) smp->status |=IB_SMP_INVALID_FIELD ; -return __subn_get_opa_psi (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_psi (smp, am, data, ibdev, port, resp_len, + max_len); }static int __subn_get_opa_cable_info (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_devdata *dd =dd_from_ibdev (ibdev);u32 addr =OPA_AM_CI_ADDR (am);u32 len =OPA_AM_CI_LEN (am) +1 ;int ret; -if (dd->pport->port_type !=PORT_TYPE_QSFP ) { +if (dd->pport->port_type !=PORT_TYPE_QSFP || +smp_length_check (len, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1861,21 +1902,22 @@ static int __subn_get_opa_cable_info(struct opa_smp *smp, u32 am, u8 *data, }static int __subn_get_opa_bct (struct opa_smp *smp,u32 am,u8 *data, -struct ib_device *ibdev,u8 port,u32 *resp_len) +struct ib_device *ibdev,u8 port,u32 *resp_len, +u32 max_len) {u32 num_ports =OPA_AM_NPORT (am);struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct hfi1_pportdata *ppd;struct buffer_control *p = (struct buffer_control *)data; -int size; +int size =sizeof (struct buffer_control ); -if (num_ports !=1 ) { +if (num_ports !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); } ppd = dd->pport + (port -1 ); - size =fm_get_table (ppd,FM_TBL_BUFFER_CONTROL , p); +fm_get_table (ppd,FM_TBL_BUFFER_CONTROL , p);trace_bct_get (dd, p);if (resp_len) *resp_len += size;
@@ -1884,14 +1926,15 @@ static int __subn_get_opa_bct(struct opa_smp *smp, u32 am, u8 *data, }static int __subn_set_opa_bct (struct opa_smp *smp,u32 am,u8 *data, -struct ib_device *ibdev,u8 port,u32 *resp_len) +struct ib_device *ibdev,u8 port,u32 *resp_len, +u32 max_len) {u32 num_ports =OPA_AM_NPORT (am);struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct hfi1_pportdata *ppd;struct buffer_control *p = (struct buffer_control *)data; -if (num_ports !=1 ) { +if (num_ports !=1 ||smp_length_check (sizeof (*p), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1902,41 +1945,43 @@ static int __subn_set_opa_bct(struct opa_smp *smp, u32 am, u8 *data,return reply ((struct ib_mad_hdr *)smp); } -return __subn_get_opa_bct (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_bct (smp, am, data, ibdev, port, resp_len, + max_len); }static int __subn_get_opa_vl_arb (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_pportdata *ppd =ppd_from_ibp (to_iport (ibdev, port));u32 num_ports =OPA_AM_NPORT (am);u8 section = (am &0x00ff0000 ) >>16 ;u8 *p = data; -int size =0 ; +int size =256 ; -if (num_ports !=1 ) { +if (num_ports !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }switch (section) {case OPA_VLARB_LOW_ELEMENTS : - size =fm_get_table (ppd,FM_TBL_VL_LOW_ARB , p); +fm_get_table (ppd,FM_TBL_VL_LOW_ARB , p);break ;case OPA_VLARB_HIGH_ELEMENTS : - size =fm_get_table (ppd,FM_TBL_VL_HIGH_ARB , p); +fm_get_table (ppd,FM_TBL_VL_HIGH_ARB , p);break ;case OPA_VLARB_PREEMPT_ELEMENTS : - size =fm_get_table (ppd,FM_TBL_VL_PREEMPT_ELEMS , p); +fm_get_table (ppd,FM_TBL_VL_PREEMPT_ELEMS , p);break ;case OPA_VLARB_PREEMPT_MATRIX : - size =fm_get_table (ppd,FM_TBL_VL_PREEMPT_MATRIX , p); +fm_get_table (ppd,FM_TBL_VL_PREEMPT_MATRIX , p);break ;default :pr_warn ("OPA SubnGet(VL Arb) AM Invalid : 0x%x\n" ,be32_to_cpu (smp->attr_mod)); smp->status |=IB_SMP_INVALID_FIELD ; + size =0 ;break ; }
@@ -1948,14 +1993,15 @@ static int __subn_get_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_vl_arb (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_pportdata *ppd =ppd_from_ibp (to_iport (ibdev, port));u32 num_ports =OPA_AM_NPORT (am);u8 section = (am &0x00ff0000 ) >>16 ;u8 *p = data; +int size =256 ; -if (num_ports !=1 ) { +if (num_ports !=1 ||smp_length_check (size, max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -1983,7 +2029,8 @@ static int __subn_set_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data,break ; } -return __subn_get_opa_vl_arb (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_vl_arb (smp, am, data, ibdev, port, resp_len, + max_len); }struct opa_pma_mad {
@@ -3279,13 +3326,18 @@ struct opa_congestion_info_attr {static int __subn_get_opa_cong_info (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct opa_congestion_info_attr *p = (struct opa_congestion_info_attr *)data;struct hfi1_ibport *ibp =to_iport (ibdev, port);struct hfi1_pportdata *ppd =ppd_from_ibp (ibp); +if (smp_length_check (sizeof (*p), max_len)) { + smp->status |=IB_SMP_INVALID_FIELD ; +return reply ((struct ib_mad_hdr *)smp); + } + p->congestion_info =0 ; p->control_table_cap = ppd->cc_max_table_entries; p->congestion_log_length =OPA_CONG_LOG_ELEMS ;
@@ -3298,7 +3350,7 @@ static int __subn_get_opa_cong_info(struct opa_smp *smp, u32 am, u8 *data,static int __subn_get_opa_cong_setting (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev, -u8 port,u32 *resp_len) +u8 port,u32 *resp_len,u32 max_len) {int i; struct opa_congestion_setting_attr *p =
@@ -3308,6 +3360,11 @@ static int __subn_get_opa_cong_setting(struct opa_smp *smp, u32 am,struct opa_congestion_setting_entry_shadow *entries;struct cc_state *cc_state; +if (smp_length_check (sizeof (*p), max_len)) { + smp->status |=IB_SMP_INVALID_FIELD ; +return reply ((struct ib_mad_hdr *)smp); + } +rcu_read_lock (); cc_state =get_cc_state (ppd);
@@ -3382,7 +3439,7 @@ static void apply_cc_state(struct hfi1_pportdata *ppd)static int __subn_set_opa_cong_setting (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct opa_congestion_setting_attr *p = (struct opa_congestion_setting_attr *)data;
@@ -3391,6 +3448,11 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,struct opa_congestion_setting_entry_shadow *entries;int i; +if (smp_length_check (sizeof (*p), max_len)) { + smp->status |=IB_SMP_INVALID_FIELD ; +return reply ((struct ib_mad_hdr *)smp); + } +/* * Save details from packet into the ppd. Hold the cc_state_lock so * our information is consistent with anyone trying to apply the state.
@@ -3412,12 +3474,12 @@ static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,apply_cc_state (ppd);return __subn_get_opa_cong_setting (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len); }static int __subn_get_opa_hfi1_cong_log (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev, -u8 port,u32 *resp_len) +u8 port,u32 *resp_len,u32 max_len) {struct hfi1_ibport *ibp =to_iport (ibdev, port);struct hfi1_pportdata *ppd =ppd_from_ibp (ibp);
@@ -3425,7 +3487,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,s64 ts;int i; -if (am !=0 ) { +if (am ||smp_length_check (sizeof (*cong_log), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -3483,7 +3545,7 @@ static int __subn_get_opa_hfi1_cong_log(struct opa_smp *smp, u32 am,static int __subn_get_opa_cc_table (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct ib_cc_table_attr *cc_table_attr = (struct ib_cc_table_attr *)data;
@@ -3495,9 +3557,10 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,int i, j;u32 sentry, eentry;struct cc_state *cc_state; +u32 size =sizeof (u16) * (IB_CCT_ENTRIES * n_blocks +1 );/* sanity check n_blocks, start_block */ -if (n_blocks ==0 || +if (n_blocks ==0 ||smp_length_check (size, max_len) || start_block + n_blocks > ppd->cc_max_table_entries) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp);
@@ -3527,14 +3590,14 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,rcu_read_unlock ();if (resp_len) - *resp_len +=sizeof (u16) * (IB_CCT_ENTRIES * n_blocks +1 ); + *resp_len += size;return reply ((struct ib_mad_hdr *)smp); }static int __subn_set_opa_cc_table (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct ib_cc_table_attr *p = (struct ib_cc_table_attr *)data;struct hfi1_ibport *ibp =to_iport (ibdev, port);
@@ -3545,9 +3608,10 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,int i, j;u32 sentry, eentry;u16 ccti_limit; +u32 size =sizeof (u16) * (IB_CCT_ENTRIES * n_blocks +1 );/* sanity check n_blocks, start_block */ -if (n_blocks ==0 || +if (n_blocks ==0 ||smp_length_check (size, max_len) || start_block + n_blocks > ppd->cc_max_table_entries) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp);
@@ -3578,7 +3642,8 @@ static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,/* now apply the information */ apply_cc_state (ppd); -return __subn_get_opa_cc_table (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_cc_table (smp, am, data, ibdev, port, resp_len, + max_len); }struct opa_led_info {
@@ -3591,7 +3656,7 @@ struct opa_led_info {static int __subn_get_opa_led_info (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct hfi1_pportdata *ppd = dd->pport;
@@ -3599,7 +3664,7 @@ static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,u32 nport =OPA_AM_NPORT (am);u32 is_beaconing_active; -if (nport !=1 ) { +if (nport !=1 ||smp_length_check (sizeof (*p), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -3621,14 +3686,14 @@ static int __subn_get_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,static int __subn_set_opa_led_info (struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {struct hfi1_devdata *dd =dd_from_ibdev (ibdev);struct opa_led_info *p = (struct opa_led_info *)data;u32 nport =OPA_AM_NPORT (am);int on = !!(be32_to_cpu (p->rsvd_led_mask) &OPA_LED_MASK ); -if (nport !=1 ) { +if (nport !=1 ||smp_length_check (sizeof (*p), max_len)) { smp->status |=IB_SMP_INVALID_FIELD ;return reply ((struct ib_mad_hdr *)smp); }
@@ -3638,12 +3703,13 @@ static int __subn_set_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,else shutdown_led_override (dd->pport); -return __subn_get_opa_led_info (smp, am, data, ibdev, port, resp_len); +return __subn_get_opa_led_info (smp, am, data, ibdev, port, resp_len, + max_len); }static int subn_get_opa_sma (__be16 attr_id,struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {int ret;struct hfi1_ibport *ibp =to_iport (ibdev, port);
@@ -3651,71 +3717,71 @@ static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,switch (attr_id) {case IB_SMP_ATTR_NODE_DESC : ret =__subn_get_opa_nodedesc (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_NODE_INFO : ret =__subn_get_opa_nodeinfo (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_PORT_INFO : ret =__subn_get_opa_portinfo (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_PKEY_TABLE : ret =__subn_get_opa_pkeytable (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SL_TO_SC_MAP : ret =__subn_get_opa_sl_to_sc (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_SL_MAP : ret =__subn_get_opa_sc_to_sl (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_VLT_MAP : ret =__subn_get_opa_sc_to_vlt (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_VLNT_MAP : ret =__subn_get_opa_sc_to_vlnt (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_PORT_STATE_INFO : ret =__subn_get_opa_psi (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_BUFFER_CONTROL_TABLE : ret =__subn_get_opa_bct (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_CABLE_INFO : ret =__subn_get_opa_cable_info (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_VL_ARB_TABLE : ret =__subn_get_opa_vl_arb (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_CONGESTION_INFO : ret =__subn_get_opa_cong_info (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_HFI_CONGESTION_SETTING : ret =__subn_get_opa_cong_setting (smp, am, data, ibdev, - port, resp_len); + port, resp_len, max_len);break ;case OPA_ATTRIB_ID_HFI_CONGESTION_LOG : ret =__subn_get_opa_hfi1_cong_log (smp, am, data, ibdev, - port, resp_len); + port, resp_len, max_len);break ;case OPA_ATTRIB_ID_CONGESTION_CONTROL_TABLE : ret =__subn_get_opa_cc_table (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_LED_INFO : ret =__subn_get_opa_led_info (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_SM_INFO :if (ibp->rvp.port_cap_flags &IB_PORT_SM_DISABLED )
@@ -3733,7 +3799,7 @@ static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,static int subn_set_opa_sma (__be16 attr_id,struct opa_smp *smp,u32 am,u8 *data,struct ib_device *ibdev,u8 port, -u32 *resp_len) +u32 *resp_len,u32 max_len) {int ret;struct hfi1_ibport *ibp =to_iport (ibdev, port);
@@ -3741,51 +3807,51 @@ static int subn_set_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am,switch (attr_id) {case IB_SMP_ATTR_PORT_INFO : ret =__subn_set_opa_portinfo (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_PKEY_TABLE : ret =__subn_set_opa_pkeytable (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SL_TO_SC_MAP : ret =__subn_set_opa_sl_to_sc (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_SL_MAP : ret =__subn_set_opa_sc_to_sl (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_VLT_MAP : ret =__subn_set_opa_sc_to_vlt (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_SC_TO_VLNT_MAP : ret =__subn_set_opa_sc_to_vlnt (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_PORT_STATE_INFO : ret =__subn_set_opa_psi (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_BUFFER_CONTROL_TABLE : ret =__subn_set_opa_bct (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_VL_ARB_TABLE : ret =__subn_set_opa_vl_arb (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case OPA_ATTRIB_ID_HFI_CONGESTION_SETTING : ret =__subn_set_opa_cong_setting (smp, am, data, ibdev, - port, resp_len); + port, resp_len, max_len);break ;case OPA_ATTRIB_ID_CONGESTION_CONTROL_TABLE : ret =__subn_set_opa_cc_table (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_LED_INFO : ret =__subn_set_opa_led_info (smp, am, data, ibdev, port, - resp_len); + resp_len, max_len);break ;case IB_SMP_ATTR_SM_INFO :if (ibp->rvp.port_cap_flags &IB_PORT_SM_DISABLED )
@@ -3841,7 +3907,10 @@ static int subn_get_opa_aggregate(struct opa_smp *smp,memset (next_smp +sizeof (*agg),0 , agg_data_len); (void )subn_get_opa_sma (agg->attr_id, smp, am, agg->data, - ibdev, port,NULL ); + ibdev, port,NULL , (u32 )agg_data_len); + +if (smp->status &IB_SMP_INVALID_FIELD ) +break ;if (smp->status & ~IB_SMP_DIRECTION ) {set_aggr_error (agg);return reply ((struct ib_mad_hdr *)smp);
@@ -3884,7 +3953,9 @@ static int subn_set_opa_aggregate(struct opa_smp *smp, } (void )subn_set_opa_sma (agg->attr_id, smp, am, agg->data, - ibdev, port,NULL ); + ibdev, port,NULL , (u32 )agg_data_len); +if (smp->status &IB_SMP_INVALID_FIELD ) +break ;if (smp->status & ~IB_SMP_DIRECTION ) {set_aggr_error (agg);return reply ((struct ib_mad_hdr *)smp);
@@ -3994,12 +4065,13 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,struct opa_smp *smp = (struct opa_smp *)out_mad;struct hfi1_ibport *ibp =to_iport (ibdev, port);u8 *data; -u32 am; +u32 am, data_size;__be16 attr_id;int ret; *out_mad = *in_mad; data =opa_get_smp_data (smp); + data_size = (u32 )opa_get_smp_data_size (smp); am =be32_to_cpu (smp->attr_mod); attr_id = smp->attr_id;
@@ -4043,7 +4115,8 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,default :clear_opa_smp_data (smp); ret =subn_get_opa_sma (attr_id, smp, am, data, - ibdev, port, resp_len); + ibdev, port, resp_len, + data_size);break ;case OPA_ATTRIB_ID_AGGREGATE : ret = subn_get_opa_aggregate(smp, ibdev, port,
@@ -4055,7 +4128,8 @@ static int process_subn_opa(struct ib_device *ibdev, int mad_flags,switch (attr_id) {default : ret =subn_set_opa_sma (attr_id, smp, am, data, - ibdev, port, resp_len); + ibdev, port, resp_len, + data_size);break ;case OPA_ATTRIB_ID_AGGREGATE : ret = subn_set_opa_aggregate(smp, ibdev, port,
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/9 IB/core: Allow QP state transition from reset to error
In reply to a message not in the archiveFrom: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is in IB_QPS_RESET state and the stack is trying to transition it to IB_QPS_ERR state in ipoib_ib_dev_stop().
According to the IB spec, Table 91 - "QP State Transition Properties" it looks like the transition from reset to error is valid:
Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.
This patch allows the transition and quiets the message.
--- drivers/infiniband/core/verbs.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/infiniband/core/verbs.c +1 -0
@@ -872,6 +872,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { [IB_QPS_RESET] = { [IB_QPS_RESET] = { .valid = 1 }, + [IB_QPS_ERR] = { .valid = 1 }, [IB_QPS_INIT] = { .valid = 1, .req_param = {
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): 20170530002032.534.25061.stgit-9QXIwq+3FY+1XWohqUldA0EOCMrvLtNR@public.gmane.org
Leon Romanovsky
Reviewed-byRe: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 16 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties" it looks like the transition from reset to error is valid:
Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.
Quoted 6 lines
This patch allows the transition and quiets the message.
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]>---
Thanks,
A message that is not in the archive (sent off-list or not yet received): 20170530054609.GG17751-U/[email protected]
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 19 lines · Leon Romanovsky
Quoted 18 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties" it looks like the transition from reset to error is valid:
Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 7 lines
Quoted 4 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]>---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context State Diagram - transition to error from reset is not valid.
The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."
I'll send revert patch along with proper fix.
Thanks
A message that is not in the archive (sent off-list or not yet received): 20170723073905.GE3259-U/[email protected]
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 33 lines · Leon Romanovsky
Quoted 19 lines · Leon Romanovsky
Quoted 18 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties" it looks like the transition from reset to error is valid:
Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 7 lines
Quoted 4 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]>---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
Quoted 7 lines
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context State Diagram - transition to error from reset is not valid.
The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."I'll send revert patch along with proper fix.
Ahh, it wasn't pushed to kernel.org, so no need to revert and you can simply drop it.
Thanks
Quoted 2 lines
Thanks
A message that is not in the archive (sent off-list or not yet received): 20170723074153.GF3259-U/[email protected]
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 44 lines · Leon Romanovsky
Quoted 43 lines · Leon Romanovsky
Quoted 23 lines · Leon Romanovsky
Quoted 21 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties"
it looks like the transition from reset to error is valid:Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in
process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 8 lines
Quoted 5 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]Quoted 1 line
---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context
State Diagram - transition to error from reset is not valid.
Quoted 8 lines
Quoted 5 lines
The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."I'll send revert patch along with proper fix.
Ahh, it wasn't pushed to kernel.org, so no need to revert and you can simply drop it.
It *is* on kernel.org, and has already been pulled by Linus:
commit ebc9ca43e1d52a85c72fc2d343f353386ed6c188
Author: Tadeusz Struk <[email protected]> Date: Mon May 29 17:20:53 2017 -0700
IB/core: Allow QP state transition from reset to error
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is in IB_QPS_RESET state and the stack is trying to transition it to IB_QPS_ERR state inipoib_ib_dev_stop().
According to the IB spec, Table 91 - "QP State Transition
Properties"
it looks like the transition from reset to error is valid:
Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.
This patch allows the transition and quiets the message.
Signature · 8 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 49 lines · Doug Ledford
Quoted 48 lines · Leon Romanovsky
Quoted 47 lines · Leon Romanovsky
Quoted 23 lines · Leon Romanovsky
Quoted 21 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties"
it looks like the transition from reset to error is valid:Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in
process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 8 lines
Quoted 5 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]Quoted 1 line
---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context
State Diagram - transition to error from reset is not valid.The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
I'll send revert patch along with proper fix.
Ahh, it wasn't pushed to kernel.org, so no need to revert and you can simply drop it.
It *is* on kernel.org, and has already been pulled by Linus:
Thanks, I updated the trees and got it.
Also I prepared revert and patch and will send once it will finish our regression runs.
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=b287b76e89503ef1d403cc5cc8bd74b035d25bfa
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=5dc78ad1904db597bdb4427f3ead437aae86f54c
BTW, when will you post for-4.14 branch so we will be able to base our submission queue for the -next?
Thanks
Quoted 36 lines
commit
ebc9ca43e1d52a85c72fc2d343f353386ed6c188Author: Tadeusz Struk <[email protected]> Date: Mon May 29 17:20:53 2017 -0700IB/core: Allow QP state transition from reset to error
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition
Properties"
it looks like the transition from reset to error is valid:Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in process are completed in error, when possible.This patch allows the transition and quiets the message.
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]>Signed-off-by Doug Ledford <[email protected]>--
Doug Ledford <[email protected]>GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
A message that is not in the archive (sent off-list or not yet received): 20170723130445.GG3259-U/[email protected]
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 57 lines · Leon Romanovsky
Quoted 49 lines · Doug Ledford
Quoted 48 lines · Leon Romanovsky
Quoted 47 lines · Leon Romanovsky
Quoted 23 lines · Leon Romanovsky
Quoted 21 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties"
it looks like the transition from reset to error is valid:Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in
process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 8 lines
Quoted 5 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]Quoted 1 line
---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context
State Diagram - transition to error from reset is not valid.The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."Quoted 6 lines
Quoted 4 lines
Quoted 1 line
I'll send revert patch along with proper fix.
Ahh, it wasn't pushed to kernel.org, so no need to revert and you can simply drop it.
It *is* on kernel.org, and has already been pulled by Linus:
Quoted 8 lines
Thanks, I updated the trees and got it.
Also I prepared revert and patch and will send once it will finish our regression runs.
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=b287b76e89503ef1d403cc5cc8bd74b035d25bfa
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=5dc78ad1904db597bdb4427f3ead437aae86f54cBTW, when will you post for-4.14 branch so we will be able to base our submission queue for the -next?
Tomorrow. I wanted to base it on 4.13-rc2 so it would get all of the fixes that went in this week.
Signature · 3 lines
Doug Ledford <[email protected]> GPG Key ID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
A message that is not in the archive (sent off-list or not yet received): 10f7f884-8e65-b563-bdd8-7c2735906d14-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Re: [PATCH for-next 7/9] IB/core: Allow QP state transition from reset to error
Quoted 64 lines · Doug Ledford
Quoted 63 lines · Leon Romanovsky
Quoted 49 lines · Doug Ledford
Quoted 48 lines · Leon Romanovsky
Quoted 47 lines · Leon Romanovsky
Quoted 23 lines · Leon Romanovsky
Quoted 21 lines · Dennis Dalessandro
From: Tadeusz Struk <[email protected]>
Playing with IP-O-IB interface can trigger a warning message:
"ib0: Failed to modify QP to ERROR state" to be logged. This happens when the QP is inIB_QPS_RESETstate and the stack is trying to transition it toIB_QPS_ERRstate inipoib_ib_dev_stop().According to the IB spec, Table 91 - "QP State Transition Properties"
it looks like the transition from reset to error is valid:Transition: Any State to Error
Required Attributes: None
Optional Attributes: None allowed
Actions: Queue processing is stopped. Work Requests pending or in
process are completed in error, when possible.This patch allows the transition and quiets the message.
Quoted 8 lines
Quoted 5 lines
Reviewed-by Dennis Dalessandro <[email protected]>Signed-off-by Tadeusz Struk <[email protected]>Signed-off-by Dennis Dalessandro <[email protected]Quoted 1 line
---
Thanks,
Doug,
After digging more with Erez's help, it looks like the sentence "it looks like the transition from reset to error is valid:" is not correct.
According to the InfiniBandTM Architecture Release 1.3, Figure 126 QP/EE Context
State Diagram - transition to error from reset is not valid.The quote from the spec:
"An error can be forced from any state, except Reset, with the Modify QP/EE Verb."Quoted 6 lines
Quoted 4 lines
Quoted 1 line
I'll send revert patch along with proper fix.
Ahh, it wasn't pushed to kernel.org, so no need to revert and you can simply drop it.
It *is* on kernel.org, and has already been pulled by Linus:
Thanks, I updated the trees and got it.
Also I prepared revert and patch and will send once it will finish our regression runs.
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=b287b76e89503ef1d403cc5cc8bd74b035d25bfa
https://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git/commit/?h=rdma-rc&id=5dc78ad1904db597bdb4427f3ead437aae86f54c
Quoted 5 lines
Quoted 2 lines
BTW, when will you post for-4.14 branch so we will be able to base our submission queue for the -next?
Tomorrow. I wanted to base it on 4.13-rc2 so it would get all of the fixes that went in this week.
Thanks
Quoted 7 lines
--
Doug Ledford <[email protected]>GPG Key ID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
PATCH 8/9 IB/hfi1: Modify handling of physical link state by Host Driver
In reply to a message not in the archiveFrom: Byczkowski, Jakub <[email protected]>
Ensure states returned to the Fabric Manager are consistent with the OPA specification by caching the physical state along with the logical state.
--- drivers/infiniband/hw/hfi1/chip.c | 102 ++++++++++++++++++++++++----------- drivers/infiniband/hw/hfi1/chip.h | 2 - drivers/infiniband/hw/hfi1/driver.c | 8 ++- drivers/infiniband/hw/hfi1/hfi.h | 18 ++++++ drivers/infiniband/hw/hfi1/mad.c | 6 +- drivers/infiniband/hw/hfi1/verbs.c | 2 - 6 files changed, 97 insertions(+), 41 deletions(-)
drivers/infiniband/hw/hfi1/chip.c +70 -32
@@ -1066,6 +1066,8 @@ static int do_8051_command(struct hfi1_devdata *dd, u32 type, u64 in_data,static int wait_logical_linkstate (struct hfi1_pportdata *ppd,u32 state,int msecs); +static int wait_physical_linkstate (struct hfi1_pportdata *ppd,u32 state, +int msecs);static void read_planned_down_reason_code (struct hfi1_devdata *dd,u8 *pdrrc);static void read_link_down_reason (struct hfi1_devdata *dd,u8 *ldr);static void handle_temp_err (struct hfi1_devdata *dd);
@@ -10028,28 +10030,6 @@ static void set_lidlmc(struct hfi1_pportdata *ppd)sdma_update_lmc (dd, mask, ppd->lid); } -static int wait_phy_linkstate (struct hfi1_devdata *dd,u32 state,u32 msecs) -{ -unsigned long timeout; -u32 curr_state; - - timeout = jiffies +msecs_to_jiffies (msecs); -while (1 ) { - curr_state =read_physical_state (dd); -if (curr_state == state) -break ; -if (time_after (jiffies, timeout)) { -dd_dev_err (dd, -"timeout waiting for phy link state 0x%x, current state is 0x%x\n" , - state, curr_state); -return -ETIMEDOUT ; - } -usleep_range (1950 ,2050 );/* sleep 2ms-ish */ - } - -return 0 ; -} -static const char *state_completed_string (u32 completed) {static const char *const state_completed[] = {
@@ -10283,7 +10263,7 @@ static int goto_offline(struct hfi1_pportdata *ppd, u8 rem_reason)if (do_wait) {/* it can take a while for the link to go down */ - ret =wait_phy_linkstate (dd,PLS_OFFLINE ,10000 ); + ret =wait_physical_linkstate (ppd,PLS_OFFLINE ,10000 );if (ret <0 )return ret; }
@@ -10536,6 +10516,19 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state) goto unexpected; } +/* +* Wait for Link_Up physical state. +* Physical and Logical states should already be +* be transitioned to LinkUp and LinkInit respectively. +*/ + ret =wait_physical_linkstate (ppd,PLS_LINKUP ,1000 ); +if (ret) { +dd_dev_err (dd, +"%s: physical state did not change to LINK-UP\n" , + __func__); +break ; + } + ret =wait_logical_linkstate (ppd,IB_PORT_INIT ,1000 );if (ret) { dd_dev_err(dd,
@@ -10649,6 +10642,8 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)*/ if (ret)goto_offline (ppd,0 ); +else +cache_physical_state (ppd);break ;case HLS_DN_DISABLE :/* link is disabled */
@@ -10673,6 +10668,13 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state) ret = -EINVAL ;break ; } + ret =wait_physical_linkstate (ppd,PLS_DISABLED ,10000 ); +if (ret) { +dd_dev_err (dd, +"%s: physical state did not change to DISABLED\n" , + __func__); +break ; + }dc_shutdown (dd); } ppd->host_link_state =HLS_DN_DISABLE ;
@@ -10690,6 +10692,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)if (ppd->host_link_state !=HLS_DN_POLL ) goto unexpected; ppd->host_link_state =HLS_VERIFY_CAP ; +cache_physical_state (ppd);break ;case HLS_GOING_UP :if (ppd->host_link_state !=HLS_VERIFY_CAP )
@@ -12663,21 +12666,56 @@ static int wait_logical_linkstate(struct hfi1_pportdata *ppd, u32 state,return -ETIMEDOUT ; } -u8 hfi1_ibphys_portstate (struct hfi1_pportdata *ppd) +/* +* Read the physical hardware link state and set the driver's cached value +* of it. +*/ +void cache_physical_state (struct hfi1_pportdata *ppd) { -u32 pstate; +u32 read_pstate;u32 ib_pstate; - pstate =read_physical_state (ppd->dd); - ib_pstate =chip_to_opa_pstate (ppd->dd, pstate); -if (ppd->last_pstate != ib_pstate) { + read_pstate =read_physical_state (ppd->dd); + ib_pstate =chip_to_opa_pstate (ppd->dd, read_pstate); +/* check if OPA pstate changed */ +if (chip_to_opa_pstate (ppd->dd, ppd->pstate) != ib_pstate) {dd_dev_info (ppd->dd,"%s: physical state changed to %s (0x%x), phy 0x%x\n" , __func__,opa_pstate_name (ib_pstate), ib_pstate, - pstate); - ppd->last_pstate = ib_pstate; + read_pstate); + } + ppd->pstate = read_pstate; +} + +/* +* wait_physical_linkstate - wait for an physical link state change to occur +* @ppd: port device +* @state: the state to wait for +* @msecs: the number of milliseconds to wait +* +* Wait up to msecs milliseconds for physical link state change to occur. +* Returns 0 if state reached, otherwise -ETIMEDOUT. +*/ +static int wait_physical_linkstate (struct hfi1_pportdata *ppd,u32 state, +int msecs) +{ +unsigned long timeout; + + timeout = jiffies +msecs_to_jiffies (msecs); +while (1 ) { +cache_physical_state (ppd); +if (ppd->pstate == state) +break ; +if (time_after (jiffies, timeout)) { +dd_dev_err (ppd->dd, +"timeout waiting for phy link state 0x%x, current state is 0x%x\n" , + state, ppd->pstate); +return -ETIMEDOUT ; + } +usleep_range (1950 ,2050 );/* sleep 2ms-ish */ } -return ib_pstate; + +return 0 ; }#define CLEAR_STATIC_RATE_CONTROL_SMASK (r) \
@@ -14781,7 +14819,7 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,/* start in offline */ ppd->host_link_state =HLS_DN_OFFLINE ;init_vl_arb_caches (ppd); - ppd->last_pstate =0xff ;/* invalid value */ + ppd->pstate =PLS_OFFLINE ; } dd->link_default =HLS_DN_POLL ;
drivers/infiniband/hw/hfi1/chip.h +1 -1
@@ -744,6 +744,7 @@ void update_usrhead(struct hfi1_ctxtdata *rcd, u32 hd, u32 updegr, u32 egrhd,u32 read_physical_state (struct hfi1_devdata *dd);u32 chip_to_opa_pstate (struct hfi1_devdata *dd,u32 chip_pstate);u32 get_logical_state (struct hfi1_pportdata *ppd); +void cache_physical_state (struct hfi1_pportdata *ppd);const char *opa_lstate_name (u32 lstate);const char *opa_pstate_name (u32 pstate);u32 driver_physical_state (struct hfi1_pportdata *ppd);
@@ -1354,7 +1355,6 @@ void hfi1_put_tid(struct hfi1_devdata *dd, u32 index,void hfi1_rcvctrl (struct hfi1_devdata *dd,unsigned int op,int ctxt);u32 hfi1_read_cntrs (struct hfi1_devdata *dd,char **namep,u64 **cntrp);u32 hfi1_read_portcntrs (struct hfi1_pportdata *ppd,char **namep,u64 **cntrp); -u8 hfi1_ibphys_portstate (struct hfi1_pportdata *ppd);int hfi1_get_ib_cfg (struct hfi1_pportdata *ppd,int which);int hfi1_set_ib_cfg (struct hfi1_pportdata *ppd,int which,u32 val);int hfi1_set_ctxt_jkey (struct hfi1_devdata *dd,unsigned ctxt,u16 jkey);
drivers/infiniband/hw/hfi1/driver.c +5 -3
@@ -906,10 +906,12 @@ static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd, sc =hfi1_9B_get_sc5 (hdr, packet->rhf); }if (sc !=SC15_PACKET ) { -int hwstate =read_logical_state (dd); +int hwstate =driver_lstate (rcd->ppd); -if (hwstate !=LSTATE_ACTIVE ) { -dd_dev_info (dd,"Unexpected link state %d\n" , hwstate); +if (hwstate !=IB_PORT_ACTIVE ) { +dd_dev_info (dd, +"Unexpected link state %s\n" , +opa_lstate_name (hwstate));return 0 ; }
drivers/infiniband/hw/hfi1/hfi.h +17 -1
@@ -663,7 +663,7 @@ struct hfi1_pportdata {u8 link_enabled;/* link enabled? */ u8 linkinit_reason;u8 local_tx_rate;/* rate given to 8051 firmware */ -u8 last_pstate;/* info only */ +u8 pstate;/* info only */ u8 qsfp_retry_count;/* placeholders for IB MAD packet settings */
@@ -1330,6 +1330,22 @@ static inline u32 driver_lstate(struct hfi1_pportdata *ppd)return ppd->lstate; } +/* return the driver's idea of the physical OPA port state */ +static inline u32 driver_pstate (struct hfi1_pportdata *ppd) +{ +/* +* The driver does some processing from the time the physical +* link state is at LINKUP to the time the SM can be notified +* as such. Return IB_PORTPHYSSTATE_TRAINING until the software +* state is ready. +*/ +if (ppd->pstate ==PLS_LINKUP && + !(ppd->host_link_state &HLS_UP )) +return IB_PORTPHYSSTATE_TRAINING ; +else +return chip_to_opa_pstate (ppd->dd, ppd->pstate); +} +void receive_interrupt_work (struct work_struct *work);/* extract service channel from header and rhf */
drivers/infiniband/hw/hfi1/mad.c +3 -3
@@ -113,7 +113,7 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)return ;/* o14-3.2.1 */ -if (ppd_from_ibp (ibp)->lstate !=IB_PORT_ACTIVE ) +if (driver_lstate (ppd_from_ibp (ibp)) !=IB_PORT_ACTIVE )return ;/* o14-2 */
@@ -615,7 +615,7 @@ static int __subn_get_opa_portinfo(struct opa_smp *smp, u32 am, u8 *data, ppd->offline_disabled_reason; pi->port_states.portphysstate_portstate = - (hfi1_ibphys_portstate (ppd) <<4 ) | state; + (driver_pstate (ppd) <<4 ) | state; pi->mkeyprotect_lmc = (ibp->rvp.mkeyprot <<6 ) | ppd->lmc;
@@ -1791,7 +1791,7 @@ static int __subn_get_opa_psi(struct opa_smp *smp, u32 am, u8 *data, ppd->offline_disabled_reason; psi->port_states.portphysstate_portstate = - (hfi1_ibphys_portstate (ppd) <<4 ) | (lstate &0xf ); + (driver_pstate (ppd) <<4 ) | (lstate &0xf ); psi->link_width_downgrade_tx_active =cpu_to_be16 (ppd->link_width_downgrade_tx_active); psi->link_width_downgrade_rx_active =
drivers/infiniband/hw/hfi1/verbs.c +1 -1
@@ -1354,7 +1354,7 @@ static int query_port(struct rvt_dev_info *rdi, u8 port_num, props->lmc = ppd->lmc;/* OPA logical states match IB logical states */ props->state =driver_lstate (ppd); - props->phys_state =hfi1_ibphys_portstate (ppd); + props->phys_state =driver_pstate (ppd); props->gid_tbl_len =HFI1_GUIDS_PER_PORT ; props->active_width = (u8 )opa_width_to_ib (ppd->link_width_active);/* see rate_show() in ib core/sysfs.c */
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/9 IB/hfi1,qib: Do not send QKey trap for UD qps
In reply to a message not in the archiveAccording to IBTA spec a QKey violation should not result in a bad qkey trap being triggered for UD queue pairs. Also since it is a silent error we do not increment the q_key violation or the dropped packet counters.
--- drivers/infiniband/hw/hfi1/mad.c | 14 ++++------- drivers/infiniband/hw/hfi1/ruc.c | 8 +++--- drivers/infiniband/hw/hfi1/ud.c | 37 +++++++++------------------- drivers/infiniband/hw/hfi1/verbs.h | 4 ++- drivers/infiniband/hw/qib/qib_mad.c | 13 ++++------ drivers/infiniband/hw/qib/qib_ruc.c | 20 ++++++++------- drivers/infiniband/hw/qib/qib_ud.c | 43 +++++++++++---------------------- drivers/infiniband/hw/qib/qib_verbs.h | 4 ++- 8 files changed, 54 insertions(+), 89 deletions(-)
drivers/infiniband/hw/hfi1/mad.c +5 -9
@@ -180,10 +180,10 @@ static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len) }/* -* Send a bad [PQ]_Key trap (ch. 14.3.8). +* Send a bad P_Key trap (ch. 14.3.8). */ -void hfi1_bad_pqkey (struct hfi1_ibport *ibp,__be16 trap_num,u32 key,u32 sl, -u32 qp1,u32 qp2,u16 lid1,u16 lid2) +void hfi1_bad_pkey (struct hfi1_ibport *ibp,u32 key,u32 sl, +u32 qp1,u32 qp2,u16 lid1,u16 lid2) {struct opa_mad_notice_attr data;u32 lid =ppd_from_ibp (ibp)->lid;
@@ -191,17 +191,13 @@ void hfi1_bad_pqkey(struct hfi1_ibport *ibp, __be16 trap_num, u32 key, u32 sl,u32 _lid2 = lid2;memset (&data,0 ,sizeof (data)); - -if (trap_num ==OPA_TRAP_BAD_P_KEY ) - ibp->rvp.pkey_violations++; -else - ibp->rvp.qkey_violations++; ibp->rvp.n_pkt_drops++; + ibp->rvp.pkey_violations++;/* Send violation trap */ data.generic_type =IB_NOTICE_TYPE_SECURITY ; data.prod_type_lsb =IB_NOTICE_PROD_CA ; - data.trap_num = trap_num; + data.trap_num =OPA_TRAP_BAD_P_KEY ; data.issuer_lid =cpu_to_be32 (lid); data.ntc_257_258.lid1 =cpu_to_be32 (_lid1); data.ntc_257_258.lid2 =cpu_to_be32 (_lid2);
drivers/infiniband/hw/hfi1/ruc.c +4 -4
@@ -254,8 +254,8 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet) }if (unlikely (rcv_pkey_check (ppd_from_ibp (ibp), (u16 )bth0, sc5, slid))) { -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_P_KEY , (u16 )bth0, sl, -0 , qp->ibqp.qp_num, slid, dlid); +hfi1_bad_pkey (ibp, (u16 )bth0, sl, +0 , qp->ibqp.qp_num, slid, dlid);return 1 ; }/* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
@@ -290,8 +290,8 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet) }if (unlikely (rcv_pkey_check (ppd_from_ibp (ibp), (u16 )bth0, sc5, slid))) { -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_P_KEY , (u16 )bth0, sl, -0 , qp->ibqp.qp_num, slid, dlid); +hfi1_bad_pkey (ibp, (u16 )bth0, sl, +0 , qp->ibqp.qp_num, slid, dlid);return 1 ; }/* Validate the SLID. See Ch. 9.6.1.5 */
drivers/infiniband/hw/hfi1/ud.c +12 -25
@@ -110,10 +110,10 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe) ((1 << ppd->lmc) - 1));if (unlikely (ingress_pkey_check (ppd, pkey, sc5, qp->s_pkey_index, slid))) { -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_P_KEY , pkey, -rdma_ah_get_sl (ah_attr), - sqp->ibqp.qp_num, qp->ibqp.qp_num, - slid,rdma_ah_get_dlid (ah_attr)); +hfi1_bad_pkey (ibp, pkey, +rdma_ah_get_sl (ah_attr), + sqp->ibqp.qp_num, qp->ibqp.qp_num, + slid,rdma_ah_get_dlid (ah_attr)); goto drop; } }
@@ -128,18 +128,8 @@ static void ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe) qkey = (int )swqe->ud_wr.remote_qkey <0 ? sqp->qkey : swqe->ud_wr.remote_qkey; -if (unlikely (qkey != qp->qkey)) { -u16 lid; - - lid = ppd->lid | (rdma_ah_get_path_bits (ah_attr) & - ((1 << ppd->lmc) -1 )); -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_Q_KEY , qkey, -rdma_ah_get_sl (ah_attr), - sqp->ibqp.qp_num, qp->ibqp.qp_num, - lid, -rdma_ah_get_dlid (ah_attr)); - goto drop; - } +if (unlikely (qkey != qp->qkey)) + goto drop;/* silently drop per IBTA spec */ }/*
@@ -722,10 +712,10 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)* for invalid pkeys is optional according to * IB spec (release 1.3, section 10.9.4) */ -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_P_KEY , - pkey, sl, - src_qp, qp->ibqp.qp_num, - slid, dlid); +hfi1_bad_pkey (ibp, + pkey, sl, + src_qp, qp->ibqp.qp_num, + slid, dlid);return ; } }else {
@@ -734,12 +724,9 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)if (mgmt_pkey_idx <0 ) goto drop; } -if (unlikely (qkey != qp->qkey)) { -hfi1_bad_pqkey (ibp,OPA_TRAP_BAD_Q_KEY , qkey, sl, - src_qp, qp->ibqp.qp_num, - slid, dlid); +if (unlikely (qkey != qp->qkey))/* Silent drop */ return ; - } +/* Drop invalid MAD packets (see 13.5.3.1). */ if (unlikely (qp->ibqp.qp_num ==1 && (tlen >2048 || (sc5 ==0xF ))))
drivers/infiniband/hw/hfi1/verbs.h +2 -2
@@ -236,8 +236,8 @@ static inline int hfi1_send_ok(struct rvt_qp *qp)/* * This must be called with s_lock held. */ -void hfi1_bad_pqkey (struct hfi1_ibport *ibp,__be16 trap_num,u32 key,u32 sl, -u32 qp1,u32 qp2,u16 lid1,u16 lid2); +void hfi1_bad_pkey (struct hfi1_ibport *ibp,u32 key,u32 sl, +u32 qp1,u32 qp2,u16 lid1,u16 lid2);void hfi1_cap_mask_chg (struct rvt_dev_info *rdi,u8 port_num);void hfi1_sys_guid_chg (struct hfi1_ibport *ibp);void hfi1_node_desc_chg (struct hfi1_ibport *ibp);
drivers/infiniband/hw/qib/qib_mad.c +5 -8
@@ -134,24 +134,21 @@ static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len) }/* -* Send a bad [PQ]_Key trap (ch. 14.3.8). +* Send a bad P_Key trap (ch. 14.3.8). */ -void qib_bad_pqkey (struct qib_ibport *ibp,__be16 trap_num,u32 key,u32 sl, -u32 qp1,u32 qp2,__be16 lid1,__be16 lid2) +void qib_bad_pkey (struct qib_ibport *ibp,u32 key,u32 sl, +u32 qp1,u32 qp2,__be16 lid1,__be16 lid2) {struct ib_mad_notice_attr data; -if (trap_num ==IB_NOTICE_TRAP_BAD_PKEY ) - ibp->rvp.pkey_violations++; -else - ibp->rvp.qkey_violations++; ibp->rvp.n_pkt_drops++; + ibp->rvp.pkey_violations++;/* Send violation trap */ data.generic_type =IB_NOTICE_TYPE_SECURITY ; data.prod_type_msb =0 ; data.prod_type_lsb =IB_NOTICE_PROD_CA ; - data.trap_num = trap_num; + data.trap_num =IB_NOTICE_TRAP_BAD_PKEY ; data.issuer_lid =cpu_to_be16 (ppd_from_ibp (ibp)->lid); data.toggle_count =0 ;memset (&data.details,0 ,sizeof (data.details));
drivers/infiniband/hw/qib/qib_ruc.c +10 -10
@@ -256,11 +256,11 @@ int qib_ruc_check_hdr(struct qib_ibport *ibp, struct ib_header *hdr, }if (!qib_pkey_ok ((u16 )bth0,qib_get_pkey (ibp, qp->s_alt_pkey_index))) { -qib_bad_pqkey (ibp,IB_NOTICE_TRAP_BAD_PKEY , - (u16 )bth0, - (be16_to_cpu (hdr->lrh[0 ]) >>4 ) &0xF , -0 , qp->ibqp.qp_num, - hdr->lrh[3 ], hdr->lrh[1 ]); +qib_bad_pkey (ibp, + (u16 )bth0, + (be16_to_cpu (hdr->lrh[0 ]) >>4 ) &0xF , +0 , qp->ibqp.qp_num, + hdr->lrh[3 ], hdr->lrh[1 ]); goto err; }/* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */
@@ -295,11 +295,11 @@ int qib_ruc_check_hdr(struct qib_ibport *ibp, struct ib_header *hdr, }if (!qib_pkey_ok ((u16 )bth0,qib_get_pkey (ibp, qp->s_pkey_index))) { -qib_bad_pqkey (ibp,IB_NOTICE_TRAP_BAD_PKEY , - (u16 )bth0, - (be16_to_cpu (hdr->lrh[0 ]) >>4 ) &0xF , -0 , qp->ibqp.qp_num, - hdr->lrh[3 ], hdr->lrh[1 ]); +qib_bad_pkey (ibp, + (u16 )bth0, + (be16_to_cpu (hdr->lrh[0 ]) >>4 ) &0xF , +0 , qp->ibqp.qp_num, + hdr->lrh[3 ], hdr->lrh[1 ]); goto err; }/* Validate the SLID. See Ch. 9.6.1.5 */
drivers/infiniband/hw/qib/qib_ud.c +14 -29
73 lines not on this page · raw message
drivers/infiniband/hw/qib/qib_verbs.h +2 -2
@@ -241,8 +241,8 @@ static inline int qib_pkey_ok(u16 pkey1, u16 pkey2)return p1 && p1 == p2 && ((__s16 )pkey1 <0 || (__s16 )pkey2 <0 ); } -void qib_bad_pqkey (struct qib_ibport *ibp,__be16 trap_num,u32 key,u32 sl, -u32 qp1,u32 qp2,__be16 lid1,__be16 lid2); +void qib_bad_pkey (struct qib_ibport *ibp,u32 key,u32 sl, +u32 qp1,u32 qp2,__be16 lid1,__be16 lid2);void qib_cap_mask_chg (struct rvt_dev_info *rdi,u8 port_num);void qib_sys_guid_chg (struct qib_ibport *ibp);void qib_node_desc_chg (struct qib_ibport *ibp);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 11 lines · Dennis Dalessandro
Hi Doug,
Here is the next set of patches for our drivers for 4.13. The first couple are
clean up and general improvement patches. The last two are bug fixes. There is
one core change in the mix here. It is to allow QP to transition from reset to
error which according to the spec is supposed to be a valid transition.
Quoted 2 lines
Patches can can also be found in my GitHub repo at:
https://github.com/ddalessa/kernel/tree/for-4.13
Hi Denny,
Series applied.
Signature · 8 lines
Doug Ledford <[email protected]> GPG KeyID: B826A3330E572FDD Key fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html