diff options
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 40 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 47 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 1 |
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 | ||
2371 | static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev, | 2371 | static 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 | } |
2539 | EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state); | 2552 | EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state); |
2553 | |||
2554 | int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port) | ||
2555 | { | ||
2556 | return 0; | ||
2557 | } | ||
2558 | EXPORT_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); | |||
1234 | int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port); | 1234 | int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port); |
1235 | 1235 | ||
1236 | int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port); | 1236 | int mlx4_config_vxlan_port(struct mlx4_dev *dev, __be16 udp_port); |
1237 | int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port); | ||
1237 | #endif /* MLX4_DEVICE_H */ | 1238 | #endif /* MLX4_DEVICE_H */ |