Skip to content

Commit b37b98a

Browse files
davidarinzonkuba-moo
authored andcommitted
net: ena: Add validation for completion descriptors consistency
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 <[email protected]> Signed-off-by: David Arinzon <[email protected]> Reviewed-by: Simon Horman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 48673ef commit b37b98a

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

drivers/net/ethernet/amazon/ena/ena_eth_com.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -229,42 +229,55 @@ static struct ena_eth_io_rx_cdesc_base *
229229
idx * io_cq->cdesc_entry_size_in_bytes);
230230
}
231231

232-
static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
233-
u16 *first_cdesc_idx)
232+
static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
233+
u16 *first_cdesc_idx,
234+
u16 *num_descs)
234235
{
236+
u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
235237
struct ena_eth_io_rx_cdesc_base *cdesc;
236-
u16 count = 0, head_masked;
237238
u32 last = 0;
238239

239240
do {
241+
u32 status;
242+
240243
cdesc = ena_com_get_next_rx_cdesc(io_cq);
241244
if (!cdesc)
242245
break;
246+
status = READ_ONCE(cdesc->status);
243247

244248
ena_com_cq_inc_head(io_cq);
249+
if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
250+
ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
251+
struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);
252+
253+
netdev_err(dev->net_device,
254+
"First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
255+
count, io_cq->qid, cdesc->req_id);
256+
return -EFAULT;
257+
}
245258
count++;
246-
last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
247-
ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
259+
last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
260+
ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
248261
} while (!last);
249262

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

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

268+
*num_descs = count;
256269
io_cq->cur_rx_pkt_cdesc_count = 0;
257270
io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
258271

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

267-
return count;
280+
return 0;
268281
}
269282

270283
static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
@@ -539,10 +552,14 @@ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
539552
u16 cdesc_idx = 0;
540553
u16 nb_hw_desc;
541554
u16 i = 0;
555+
int rc;
542556

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

545-
nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
559+
rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
560+
if (unlikely(rc != 0))
561+
return -EFAULT;
562+
546563
if (nb_hw_desc == 0) {
547564
ena_rx_ctx->descs = nb_hw_desc;
548565
return 0;

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,8 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
13471347
if (rc == -ENOSPC) {
13481348
ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
13491349
ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
1350+
} else if (rc == -EFAULT) {
1351+
ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
13501352
} else {
13511353
ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
13521354
&rx_ring->syncp);

drivers/net/ethernet/amazon/ena/ena_regs_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum ena_regs_reset_reason_types {
2222
ENA_REGS_RESET_GENERIC = 13,
2323
ENA_REGS_RESET_MISS_INTERRUPT = 14,
2424
ENA_REGS_RESET_SUSPECTED_POLL_STARVATION = 15,
25+
ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED = 16,
2526
};
2627

2728
/* ena_registers offsets */

0 commit comments

Comments
 (0)