Commit e9b797dc authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'mlx5-fixes-2023-12-13' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5 fixes 2023-12-13

This series provides bug fixes to mlx5 driver.

* tag 'mlx5-fixes-2023-12-13' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5e: Correct snprintf truncation handling for fw_version buffer used by representors
  net/mlx5e: Correct snprintf truncation handling for fw_version buffer
  net/mlx5e: Fix error codes in alloc_branch_attr()
  net/mlx5e: Fix error code in mlx5e_tc_action_miss_mapping_get()
  net/mlx5: Refactor mlx5_flow_destination->rep pointer to vport num
  net/mlx5: Fix fw tracer first block check
  net/mlx5e: XDP, Drop fragmented packets larger than MTU size
  net/mlx5e: Decrease num_block_tc when unblock tc offload
  net/mlx5e: Fix overrun reported by coverity
  net/mlx5e: fix a potential double-free in fs_udp_create_groups
  net/mlx5e: Fix a race in command alloc flow
  net/mlx5e: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list()
  net/mlx5e: fix double free of encap_header
  Revert "net/mlx5e: fix double free of encap_header"
  Revert "net/mlx5e: fix double free of encap_header in update funcs"
====================

Link: https://lore.kernel.org/r/20231214012505.42666-1-saeed@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2c1a4185 b13559b7
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -156,15 +156,18 @@ static u8 alloc_token(struct mlx5_cmd *cmd)
	return token;
}

static int cmd_alloc_index(struct mlx5_cmd *cmd)
static int cmd_alloc_index(struct mlx5_cmd *cmd, struct mlx5_cmd_work_ent *ent)
{
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&cmd->alloc_lock, flags);
	ret = find_first_bit(&cmd->vars.bitmask, cmd->vars.max_reg_cmds);
	if (ret < cmd->vars.max_reg_cmds)
	if (ret < cmd->vars.max_reg_cmds) {
		clear_bit(ret, &cmd->vars.bitmask);
		ent->idx = ret;
		cmd->ent_arr[ent->idx] = ent;
	}
	spin_unlock_irqrestore(&cmd->alloc_lock, flags);

	return ret < cmd->vars.max_reg_cmds ? ret : -ENOMEM;
@@ -979,7 +982,7 @@ static void cmd_work_handler(struct work_struct *work)
	sem = ent->page_queue ? &cmd->vars.pages_sem : &cmd->vars.sem;
	down(sem);
	if (!ent->page_queue) {
		alloc_ret = cmd_alloc_index(cmd);
		alloc_ret = cmd_alloc_index(cmd, ent);
		if (alloc_ret < 0) {
			mlx5_core_err_rl(dev, "failed to allocate command entry\n");
			if (ent->callback) {
@@ -994,15 +997,14 @@ static void cmd_work_handler(struct work_struct *work)
			up(sem);
			return;
		}
		ent->idx = alloc_ret;
	} else {
		ent->idx = cmd->vars.max_reg_cmds;
		spin_lock_irqsave(&cmd->alloc_lock, flags);
		clear_bit(ent->idx, &cmd->vars.bitmask);
		cmd->ent_arr[ent->idx] = ent;
		spin_unlock_irqrestore(&cmd->alloc_lock, flags);
	}

	cmd->ent_arr[ent->idx] = ent;
	lay = get_inst(cmd, ent->idx);
	ent->lay = lay;
	memset(lay, 0, sizeof(*lay));
+1 −1
Original line number Diff line number Diff line
@@ -718,7 +718,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work)

	while (block_timestamp > tracer->last_timestamp) {
		/* Check block override if it's not the first block */
		if (!tracer->last_timestamp) {
		if (tracer->last_timestamp) {
			u64 *ts_event;
			/* To avoid block override be the HW in case of buffer
			 * wraparound, the time stamp of the previous block
+1 −0
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ static int fs_udp_create_groups(struct mlx5e_flow_table *ft, enum fs_udp_type ty
	in = kvzalloc(inlen, GFP_KERNEL);
	if  (!in || !ft->g) {
		kfree(ft->g);
		ft->g = NULL;
		kvfree(in);
		return -ENOMEM;
	}
+3 −2
Original line number Diff line number Diff line
@@ -197,7 +197,7 @@ parse_mirred_encap(struct mlx5e_tc_act_parse_state *parse_state,
	}
	esw_attr->dests[esw_attr->out_count].flags |= MLX5_ESW_DEST_ENCAP;
	esw_attr->out_count++;
	/* attr->dests[].rep is resolved when we handle encap */
	/* attr->dests[].vport is resolved when we handle encap */

	return 0;
}
@@ -270,7 +270,8 @@ parse_mirred(struct mlx5e_tc_act_parse_state *parse_state,

	out_priv = netdev_priv(out_dev);
	rpriv = out_priv->ppriv;
	esw_attr->dests[esw_attr->out_count].rep = rpriv->rep;
	esw_attr->dests[esw_attr->out_count].vport_valid = true;
	esw_attr->dests[esw_attr->out_count].vport = rpriv->rep->vport;
	esw_attr->dests[esw_attr->out_count].mdev = out_priv->mdev;

	esw_attr->out_count++;
+28 −22
Original line number Diff line number Diff line
@@ -300,6 +300,10 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
	if (err)
		goto destroy_neigh_entry;

	e->encap_size = ipv4_encap_size;
	e->encap_header = encap_header;
	encap_header = NULL;

	if (!(nud_state & NUD_VALID)) {
		neigh_event_send(attr.n, NULL);
		/* the encap entry will be made valid on neigh update event
@@ -310,8 +314,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,

	memset(&reformat_params, 0, sizeof(reformat_params));
	reformat_params.type = e->reformat_type;
	reformat_params.size = ipv4_encap_size;
	reformat_params.data = encap_header;
	reformat_params.size = e->encap_size;
	reformat_params.data = e->encap_header;
	e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
						     MLX5_FLOW_NAMESPACE_FDB);
	if (IS_ERR(e->pkt_reformat)) {
@@ -319,8 +323,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
		goto destroy_neigh_entry;
	}

	e->encap_size = ipv4_encap_size;
	e->encap_header = encap_header;
	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev));
	mlx5e_route_lookup_ipv4_put(&attr);
@@ -403,18 +405,23 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv,
	if (err)
		goto free_encap;

	e->encap_size = ipv4_encap_size;
	kfree(e->encap_header);
	e->encap_header = encap_header;
	encap_header = NULL;

	if (!(nud_state & NUD_VALID)) {
		neigh_event_send(attr.n, NULL);
		/* the encap entry will be made valid on neigh update event
		 * and not used before that.
		 */
		goto free_encap;
		goto release_neigh;
	}

	memset(&reformat_params, 0, sizeof(reformat_params));
	reformat_params.type = e->reformat_type;
	reformat_params.size = ipv4_encap_size;
	reformat_params.data = encap_header;
	reformat_params.size = e->encap_size;
	reformat_params.data = e->encap_header;
	e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
						     MLX5_FLOW_NAMESPACE_FDB);
	if (IS_ERR(e->pkt_reformat)) {
@@ -422,10 +429,6 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv,
		goto free_encap;
	}

	e->encap_size = ipv4_encap_size;
	kfree(e->encap_header);
	e->encap_header = encap_header;

	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev));
	mlx5e_route_lookup_ipv4_put(&attr);
@@ -567,6 +570,10 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
	if (err)
		goto destroy_neigh_entry;

	e->encap_size = ipv6_encap_size;
	e->encap_header = encap_header;
	encap_header = NULL;

	if (!(nud_state & NUD_VALID)) {
		neigh_event_send(attr.n, NULL);
		/* the encap entry will be made valid on neigh update event
@@ -577,8 +584,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,

	memset(&reformat_params, 0, sizeof(reformat_params));
	reformat_params.type = e->reformat_type;
	reformat_params.size = ipv6_encap_size;
	reformat_params.data = encap_header;
	reformat_params.size = e->encap_size;
	reformat_params.data = e->encap_header;
	e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
						     MLX5_FLOW_NAMESPACE_FDB);
	if (IS_ERR(e->pkt_reformat)) {
@@ -586,8 +593,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
		goto destroy_neigh_entry;
	}

	e->encap_size = ipv6_encap_size;
	e->encap_header = encap_header;
	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev));
	mlx5e_route_lookup_ipv6_put(&attr);
@@ -669,18 +674,23 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv,
	if (err)
		goto free_encap;

	e->encap_size = ipv6_encap_size;
	kfree(e->encap_header);
	e->encap_header = encap_header;
	encap_header = NULL;

	if (!(nud_state & NUD_VALID)) {
		neigh_event_send(attr.n, NULL);
		/* the encap entry will be made valid on neigh update event
		 * and not used before that.
		 */
		goto free_encap;
		goto release_neigh;
	}

	memset(&reformat_params, 0, sizeof(reformat_params));
	reformat_params.type = e->reformat_type;
	reformat_params.size = ipv6_encap_size;
	reformat_params.data = encap_header;
	reformat_params.size = e->encap_size;
	reformat_params.data = e->encap_header;
	e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev, &reformat_params,
						     MLX5_FLOW_NAMESPACE_FDB);
	if (IS_ERR(e->pkt_reformat)) {
@@ -688,10 +698,6 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv,
		goto free_encap;
	}

	e->encap_size = ipv6_encap_size;
	kfree(e->encap_header);
	e->encap_header = encap_header;

	e->flags |= MLX5_ENCAP_ENTRY_VALID;
	mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev));
	mlx5e_route_lookup_ipv6_put(&attr);
Loading