aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c40
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c47
-rw-r--r--include/linux/mlx4/device.h1
4 files changed, 66 insertions, 38 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index fd36ec672632..287ad0564acd 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -478,10 +478,6 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
478 if (!tun_ctx || tun_ctx->state != DEMUX_PV_STATE_ACTIVE) 478 if (!tun_ctx || tun_ctx->state != DEMUX_PV_STATE_ACTIVE)
479 return -EAGAIN; 479 return -EAGAIN;
480 480
481 /* QP0 forwarding only for Dom0 */
482 if (!dest_qpt && (mlx4_master_func_num(dev->dev) != slave))
483 return -EINVAL;
484
485 if (!dest_qpt) 481 if (!dest_qpt)
486 tun_qp = &tun_ctx->qp[0]; 482 tun_qp = &tun_ctx->qp[0];
487 else 483 else
@@ -667,6 +663,21 @@ static int mlx4_ib_demux_mad(struct ib_device *ibdev, u8 port,
667 } 663 }
668 /* Class-specific handling */ 664 /* Class-specific handling */
669 switch (mad->mad_hdr.mgmt_class) { 665 switch (mad->mad_hdr.mgmt_class) {
666 case IB_MGMT_CLASS_SUBN_LID_ROUTED:
667 case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
668 /* 255 indicates the dom0 */
669 if (slave != 255 && slave != mlx4_master_func_num(dev->dev)) {
670 if (!mlx4_vf_smi_enabled(dev->dev, slave, port))
671 return -EPERM;
672 /* for a VF. drop unsolicited MADs */
673 if (!(mad->mad_hdr.method & IB_MGMT_METHOD_RESP)) {
674 mlx4_ib_warn(ibdev, "demux QP0. rejecting unsolicited mad for slave %d class 0x%x, method 0x%x\n",
675 slave, mad->mad_hdr.mgmt_class,
676 mad->mad_hdr.method);
677 return -EINVAL;
678 }
679 }
680 break;
670 case IB_MGMT_CLASS_SUBN_ADM: 681 case IB_MGMT_CLASS_SUBN_ADM:
671 if (mlx4_ib_demux_sa_handler(ibdev, port, slave, 682 if (mlx4_ib_demux_sa_handler(ibdev, port, slave,
672 (struct ib_sa_mad *) mad)) 683 (struct ib_sa_mad *) mad))
@@ -1165,10 +1176,6 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
1165 if (!sqp_ctx || sqp_ctx->state != DEMUX_PV_STATE_ACTIVE) 1176 if (!sqp_ctx || sqp_ctx->state != DEMUX_PV_STATE_ACTIVE)
1166 return -EAGAIN; 1177 return -EAGAIN;
1167 1178
1168 /* QP0 forwarding only for Dom0 */
1169 if (dest_qpt == IB_QPT_SMI && (mlx4_master_func_num(dev->dev) != slave))
1170 return -EINVAL;
1171
1172 if (dest_qpt == IB_QPT_SMI) { 1179 if (dest_qpt == IB_QPT_SMI) {
1173 src_qpnum = 0; 1180 src_qpnum = 0;
1174 sqp = &sqp_ctx->qp[0]; 1181 sqp = &sqp_ctx->qp[0];
@@ -1285,11 +1292,6 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc
1285 "belongs to another slave\n", wc->src_qp); 1292 "belongs to another slave\n", wc->src_qp);
1286 return; 1293 return;
1287 } 1294 }
1288 if (slave != mlx4_master_func_num(dev->dev) && !(wc->src_qp & 0x2)) {
1289 mlx4_ib_warn(ctx->ib_dev, "can't multiplex bad sqp:%d: "
1290 "non-master trying to send QP0 packets\n", wc->src_qp);
1291 return;
1292 }
1293 1295
1294 /* Map transaction ID */ 1296 /* Map transaction ID */
1295 ib_dma_sync_single_for_cpu(ctx->ib_dev, tun_qp->ring[wr_ix].map, 1297 ib_dma_sync_single_for_cpu(ctx->ib_dev, tun_qp->ring[wr_ix].map,
@@ -1317,6 +1319,12 @@ static void mlx4_ib_multiplex_mad(struct mlx4_ib_demux_pv_ctx *ctx, struct ib_wc
1317 1319
1318 /* Class-specific handling */ 1320 /* Class-specific handling */
1319 switch (tunnel->mad.mad_hdr.mgmt_class) { 1321 switch (tunnel->mad.mad_hdr.mgmt_class) {
1322 case IB_MGMT_CLASS_SUBN_LID_ROUTED:
1323 case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
1324 if (slave != mlx4_master_func_num(dev->dev) &&
1325 !mlx4_vf_smi_enabled(dev->dev, slave, ctx->port))
1326 return;
1327 break;
1320 case IB_MGMT_CLASS_SUBN_ADM: 1328 case IB_MGMT_CLASS_SUBN_ADM:
1321 if (mlx4_ib_multiplex_sa_handler(ctx->ib_dev, ctx->port, slave, 1329 if (mlx4_ib_multiplex_sa_handler(ctx->ib_dev, ctx->port, slave,
1322 (struct ib_sa_mad *) &tunnel->mad)) 1330 (struct ib_sa_mad *) &tunnel->mad))
@@ -1749,9 +1757,9 @@ static int create_pv_resources(struct ib_device *ibdev, int slave, int port,
1749 return -EEXIST; 1757 return -EEXIST;
1750 1758
1751 ctx->state = DEMUX_PV_STATE_STARTING; 1759 ctx->state = DEMUX_PV_STATE_STARTING;
1752 /* have QP0 only on port owner, and only if link layer is IB */ 1760 /* have QP0 only if link layer is IB */
1753 if (ctx->slave == mlx4_master_func_num(to_mdev(ctx->ib_dev)->dev) && 1761 if (rdma_port_get_link_layer(ibdev, ctx->port) ==
1754 rdma_port_get_link_layer(ibdev, ctx->port) == IB_LINK_LAYER_INFINIBAND) 1762 IB_LINK_LAYER_INFINIBAND)
1755 ctx->has_smi = 1; 1763 ctx->has_smi = 1;
1756 1764
1757 if (ctx->has_smi) { 1765 if (ctx->has_smi) {
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 41308af4163c..2e8c58806e2f 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -2370,7 +2370,8 @@ static void set_datagram_seg(struct mlx4_wqe_datagram_seg *dseg,
2370 2370
2371static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev, 2371static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev,
2372 struct mlx4_wqe_datagram_seg *dseg, 2372 struct mlx4_wqe_datagram_seg *dseg,
2373 struct ib_send_wr *wr, enum ib_qp_type qpt) 2373 struct ib_send_wr *wr,
2374 enum mlx4_ib_qp_type qpt)
2374{ 2375{
2375 union mlx4_ext_av *av = &to_mah(wr->wr.ud.ah)->av; 2376 union mlx4_ext_av *av = &to_mah(wr->wr.ud.ah)->av;
2376 struct mlx4_av sqp_av = {0}; 2377 struct mlx4_av sqp_av = {0};
@@ -2383,8 +2384,10 @@ static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev,
2383 cpu_to_be32(0xf0000000); 2384 cpu_to_be32(0xf0000000);
2384 2385
2385 memcpy(dseg->av, &sqp_av, sizeof (struct mlx4_av)); 2386 memcpy(dseg->av, &sqp_av, sizeof (struct mlx4_av));
2386 /* This function used only for sending on QP1 proxies */ 2387 if (qpt == MLX4_IB_QPT_PROXY_GSI)
2387 dseg->dqpn = cpu_to_be32(dev->dev->caps.qp1_tunnel[port - 1]); 2388 dseg->dqpn = cpu_to_be32(dev->dev->caps.qp1_tunnel[port - 1]);
2389 else
2390 dseg->dqpn = cpu_to_be32(dev->dev->caps.qp0_tunnel[port - 1]);
2388 /* Use QKEY from the QP context, which is set by master */ 2391 /* Use QKEY from the QP context, which is set by master */
2389 dseg->qkey = cpu_to_be32(IB_QP_SET_QKEY); 2392 dseg->qkey = cpu_to_be32(IB_QP_SET_QKEY);
2390} 2393}
@@ -2700,16 +2703,13 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
2700 size += seglen / 16; 2703 size += seglen / 16;
2701 break; 2704 break;
2702 case MLX4_IB_QPT_PROXY_SMI: 2705 case MLX4_IB_QPT_PROXY_SMI:
2703 /* don't allow QP0 sends on guests */
2704 err = -ENOSYS;
2705 *bad_wr = wr;
2706 goto out;
2707 case MLX4_IB_QPT_PROXY_GSI: 2706 case MLX4_IB_QPT_PROXY_GSI:
2708 /* If we are tunneling special qps, this is a UD qp. 2707 /* If we are tunneling special qps, this is a UD qp.
2709 * In this case we first add a UD segment targeting 2708 * In this case we first add a UD segment targeting
2710 * the tunnel qp, and then add a header with address 2709 * the tunnel qp, and then add a header with address
2711 * information */ 2710 * information */
2712 set_tunnel_datagram_seg(to_mdev(ibqp->device), wqe, wr, ibqp->qp_type); 2711 set_tunnel_datagram_seg(to_mdev(ibqp->device), wqe, wr,
2712 qp->mlx4_ib_qp_type);
2713 wqe += sizeof (struct mlx4_wqe_datagram_seg); 2713 wqe += sizeof (struct mlx4_wqe_datagram_seg);
2714 size += sizeof (struct mlx4_wqe_datagram_seg) / 16; 2714 size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
2715 build_tunnel_header(wr, wqe, &seglen); 2715 build_tunnel_header(wr, wqe, &seglen);
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 78099eab7673..b0e48d426fce 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -705,20 +705,28 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
705 struct ib_smp *smp = inbox->buf; 705 struct ib_smp *smp = inbox->buf;
706 u32 index; 706 u32 index;
707 u8 port; 707 u8 port;
708 u8 opcode_modifier;
708 u16 *table; 709 u16 *table;
709 int err; 710 int err;
710 int vidx, pidx; 711 int vidx, pidx;
712 int network_view;
711 struct mlx4_priv *priv = mlx4_priv(dev); 713 struct mlx4_priv *priv = mlx4_priv(dev);
712 struct ib_smp *outsmp = outbox->buf; 714 struct ib_smp *outsmp = outbox->buf;
713 __be16 *outtab = (__be16 *)(outsmp->data); 715 __be16 *outtab = (__be16 *)(outsmp->data);
714 __be32 slave_cap_mask; 716 __be32 slave_cap_mask;
715 __be64 slave_node_guid; 717 __be64 slave_node_guid;
718
716 port = vhcr->in_modifier; 719 port = vhcr->in_modifier;
717 720
721 /* network-view bit is for driver use only, and should not be passed to FW */
722 opcode_modifier = vhcr->op_modifier & ~0x8; /* clear netw view bit */
723 network_view = !!(vhcr->op_modifier & 0x8);
724
718 if (smp->base_version == 1 && 725 if (smp->base_version == 1 &&
719 smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED && 726 smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED &&
720 smp->class_version == 1) { 727 smp->class_version == 1) {
721 if (smp->method == IB_MGMT_METHOD_GET) { 728 /* host view is paravirtualized */
729 if (!network_view && smp->method == IB_MGMT_METHOD_GET) {
722 if (smp->attr_id == IB_SMP_ATTR_PKEY_TABLE) { 730 if (smp->attr_id == IB_SMP_ATTR_PKEY_TABLE) {
723 index = be32_to_cpu(smp->attr_mod); 731 index = be32_to_cpu(smp->attr_mod);
724 if (port < 1 || port > dev->caps.num_ports) 732 if (port < 1 || port > dev->caps.num_ports)
@@ -743,7 +751,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
743 /*get the slave specific caps:*/ 751 /*get the slave specific caps:*/
744 /*do the command */ 752 /*do the command */
745 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 753 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma,
746 vhcr->in_modifier, vhcr->op_modifier, 754 vhcr->in_modifier, opcode_modifier,
747 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 755 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
748 /* modify the response for slaves */ 756 /* modify the response for slaves */
749 if (!err && slave != mlx4_master_func_num(dev)) { 757 if (!err && slave != mlx4_master_func_num(dev)) {
@@ -760,7 +768,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
760 smp->attr_mod = cpu_to_be32(slave / 8); 768 smp->attr_mod = cpu_to_be32(slave / 8);
761 /* execute cmd */ 769 /* execute cmd */
762 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 770 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma,
763 vhcr->in_modifier, vhcr->op_modifier, 771 vhcr->in_modifier, opcode_modifier,
764 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 772 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
765 if (!err) { 773 if (!err) {
766 /* if needed, move slave gid to index 0 */ 774 /* if needed, move slave gid to index 0 */
@@ -774,7 +782,7 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
774 } 782 }
775 if (smp->attr_id == IB_SMP_ATTR_NODE_INFO) { 783 if (smp->attr_id == IB_SMP_ATTR_NODE_INFO) {
776 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma, 784 err = mlx4_cmd_box(dev, inbox->dma, outbox->dma,
777 vhcr->in_modifier, vhcr->op_modifier, 785 vhcr->in_modifier, opcode_modifier,
778 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 786 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
779 if (!err) { 787 if (!err) {
780 slave_node_guid = mlx4_get_slave_node_guid(dev, slave); 788 slave_node_guid = mlx4_get_slave_node_guid(dev, slave);
@@ -784,19 +792,24 @@ static int mlx4_MAD_IFC_wrapper(struct mlx4_dev *dev, int slave,
784 } 792 }
785 } 793 }
786 } 794 }
795
796 /* Non-privileged VFs are only allowed "host" view LID-routed 'Get' MADs.
797 * These are the MADs used by ib verbs (such as ib_query_gids).
798 */
787 if (slave != mlx4_master_func_num(dev) && 799 if (slave != mlx4_master_func_num(dev) &&
788 ((smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) || 800 !mlx4_vf_smi_enabled(dev, slave, port)) {
789 (smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED && 801 if (!(smp->mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED &&
790 smp->method == IB_MGMT_METHOD_SET))) { 802 smp->method == IB_MGMT_METHOD_GET) || network_view) {
791 mlx4_err(dev, "slave %d is trying to execute a Subnet MGMT MAD, " 803 mlx4_err(dev, "Unprivileged slave %d is trying to execute a Subnet MGMT MAD, class 0x%x, method 0x%x, view=%s for attr 0x%x. Rejecting\n",
792 "class 0x%x, method 0x%x for attr 0x%x. Rejecting\n", 804 slave, smp->method, smp->mgmt_class,
793 slave, smp->method, smp->mgmt_class, 805 network_view ? "Network" : "Host",
794 be16_to_cpu(smp->attr_id)); 806 be16_to_cpu(smp->attr_id));
795 return -EPERM; 807 return -EPERM;
808 }
796 } 809 }
797 /*default:*/ 810
798 return mlx4_cmd_box(dev, inbox->dma, outbox->dma, 811 return mlx4_cmd_box(dev, inbox->dma, outbox->dma,
799 vhcr->in_modifier, vhcr->op_modifier, 812 vhcr->in_modifier, opcode_modifier,
800 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE); 813 vhcr->op, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
801} 814}
802 815
@@ -2537,3 +2550,9 @@ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_stat
2537 return 0; 2550 return 0;
2538} 2551}
2539EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state); 2552EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
2553
2554int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
2555{
2556 return 0;
2557}
2558EXPORT_SYMBOL_GPL(mlx4_vf_smi_enabled);
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index ba87bd21295a..83612faa819c 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1234,4 +1234,5 @@ int mlx4_phys_to_slave_port(struct mlx4_dev *dev, int slave, int port);
1234int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port); 1234int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port);
1235 1235
1236int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port); 1236int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port);
1237int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port);
1237#endif /* MLX4_DEVICE_H */ 1238#endif /* MLX4_DEVICE_H */