To make sure that the array index isn't used in the code with
negative value, we stop using the for loop integer iterator
outside of it.
>From now on use members count to swap the last QP with removed one.
Fix also the second occurrence of this flow in mlx4_qp_detach_common().
In mlx4_qp_detach_common() use members_count instead of
loop iterator outside of the for loop.
Signed-off-by: Dotan Barak <dotanb@dev.mellanox.co.il>
Reviewed-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
u32 members_count;
bool found;
bool back_to_list = false;
u32 members_count;
bool found;
bool back_to_list = false;
int err;
if (port < 1 || port > dev->caps.num_ports)
int err;
if (port < 1 || port > dev->caps.num_ports)
list_del(&dqp->list);
kfree(dqp);
} else {
list_del(&dqp->list);
kfree(dqp);
} else {
err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
if (err)
goto out_mailbox;
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
err = mlx4_READ_ENTRY(dev, entry->index, mailbox);
if (err)
goto out_mailbox;
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- for (loc = -1, i = 0; i < members_count; ++i)
- if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn)
+ for (i = 0; i < members_count; ++i)
+ if ((be32_to_cpu(mgm->qp[i]) &
+ MGM_QPN_MASK) == qpn) {
+ break;
+ }
+
+ if (loc < 0) {
+ mlx4_err(dev, "QP %06x wasn't found in entry %d\n",
+ qpn, entry->index);
+ err = -EINVAL;
+ goto out_mailbox;
+ }
+ /* copy the last QP in this MGM over removed QP */
+ mgm->qp[loc] = mgm->qp[members_count - 1];
+ mgm->qp[members_count - 1] = 0;
mgm->members_count = cpu_to_be32(--members_count |
(MLX4_PROT_ETH << 30));
mgm->members_count = cpu_to_be32(--members_count |
(MLX4_PROT_ETH << 30));
- mgm->qp[loc] = mgm->qp[i - 1];
- mgm->qp[i - 1] = 0;
err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
if (err)
err = mlx4_WRITE_ENTRY(dev, entry->index, mailbox);
if (err)
struct mlx4_mgm *mgm;
u32 members_count;
int prev, index;
struct mlx4_mgm *mgm;
u32 members_count;
int prev, index;
int err;
u8 port = gid[5];
bool removed_entry = false;
int err;
u8 port = gid[5];
bool removed_entry = false;
goto out;
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
goto out;
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
- for (loc = -1, i = 0; i < members_count; ++i)
- if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
+ for (i = 0; i < members_count; ++i)
+ if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) {
if (loc == -1) {
mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
if (loc == -1) {
mlx4_err(dev, "QP %06x not found in MGM\n", qp->qpn);
+ /* copy the last QP in this MGM over removed QP */
+ mgm->qp[loc] = mgm->qp[members_count - 1];
+ mgm->qp[members_count - 1] = 0;
mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
mgm->members_count = cpu_to_be32(--members_count | (u32) prot << 30);
- mgm->qp[loc] = mgm->qp[i - 1];
- mgm->qp[i - 1] = 0;
if (prot == MLX4_PROT_ETH)
removed_entry = can_remove_steering_entry(dev, port, steer,
index, qp->qpn);
if (prot == MLX4_PROT_ETH)
removed_entry = can_remove_steering_entry(dev, port, steer,
index, qp->qpn);
- if (i != 1 && (prot != MLX4_PROT_ETH || !removed_entry)) {
+ if (members_count && (prot != MLX4_PROT_ETH || !removed_entry)) {
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
goto out;
}
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
goto out;
}