Skip to content

Commit

Permalink
net: ena: Add validation for completion descriptors consistency
Browse files Browse the repository at this point in the history
Validate that `first` flag is set only for the first
descriptor in multi-buffer packets.
In case of an invalid descriptor, a reset will occur.
A new reset reason for RX data corruption has been added.

Signed-off-by: Shahar Itzko <itzko@amazon.com>
Signed-off-by: David Arinzon <darinzon@amazon.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240512134637.25299-4-darinzon@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
David Arinzon authored and Jakub Kicinski committed May 13, 2024
1 parent 48673ef commit b37b98a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
37 changes: 27 additions & 10 deletions drivers/net/ethernet/amazon/ena/ena_eth_com.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,42 +229,55 @@ static struct ena_eth_io_rx_cdesc_base *
idx * io_cq->cdesc_entry_size_in_bytes);
}

static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
u16 *first_cdesc_idx)
static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
u16 *first_cdesc_idx,
u16 *num_descs)
{
u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
struct ena_eth_io_rx_cdesc_base *cdesc;
u16 count = 0, head_masked;
u32 last = 0;

do {
u32 status;

cdesc = ena_com_get_next_rx_cdesc(io_cq);
if (!cdesc)
break;
status = READ_ONCE(cdesc->status);

ena_com_cq_inc_head(io_cq);
if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);

netdev_err(dev->net_device,
"First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
count, io_cq->qid, cdesc->req_id);
return -EFAULT;
}
count++;
last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
} while (!last);

if (last) {
*first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
count += io_cq->cur_rx_pkt_cdesc_count;

head_masked = io_cq->head & (io_cq->q_depth - 1);

*num_descs = count;
io_cq->cur_rx_pkt_cdesc_count = 0;
io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;

netdev_dbg(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
"ENA q_id: %d packets were completed. first desc idx %u descs# %d\n",
io_cq->qid, *first_cdesc_idx, count);
} else {
io_cq->cur_rx_pkt_cdesc_count += count;
count = 0;
io_cq->cur_rx_pkt_cdesc_count = count;
*num_descs = 0;
}

return count;
return 0;
}

static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
Expand Down Expand Up @@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
u16 cdesc_idx = 0;
u16 nb_hw_desc;
u16 i = 0;
int rc;

WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");

nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
if (unlikely(rc != 0))
return -EFAULT;

if (nb_hw_desc == 0) {
ena_rx_ctx->descs = nb_hw_desc;
return 0;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/amazon/ena/ena_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
if (rc == -ENOSPC) {
ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
} else if (rc == -EFAULT) {
ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
} else {
ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
&rx_ring->syncp);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/amazon/ena/ena_regs_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types {
ENA_REGS_RESET_GENERIC = 13,
ENA_REGS_RESET_MISS_INTERRUPT = 14,
ENA_REGS_RESET_SUSPECTED_POLL_STARVATION = 15,
ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED = 16,
};

/* ena_registers offsets */
Expand Down

0 comments on commit b37b98a

Please sign in to comment.