From: Shai Brandes <shaib...@amazon.com> Adding a check of the MBZ (Must Be Zero) fields in the incoming tx and rx completion descriptors in order to identify corrupted descriptors.
Signed-off-by: Shai Brandes <shaib...@amazon.com> Reviewed-by: Amit Bernstein <amitb...@amazon.com> --- drivers/net/ena/hal/ena_eth_com.c | 13 +++++++++++-- drivers/net/ena/hal/ena_eth_com.h | 14 +++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/net/ena/hal/ena_eth_com.c b/drivers/net/ena/hal/ena_eth_com.c index dc2935a53e..988fa013a7 100644 --- a/drivers/net/ena/hal/ena_eth_com.c +++ b/drivers/net/ena/hal/ena_eth_com.c @@ -237,6 +237,7 @@ static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, u16 *first_cdesc_idx, u16 *num_descs) { + struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq); u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked; struct ena_eth_io_rx_cdesc_base *cdesc; u32 last = 0; @@ -252,13 +253,21 @@ static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, 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); - ena_trc_err(dev, "First bit is on in descriptor #%d on q_id: %d, req_id: %u\n", count, io_cq->qid, cdesc->req_id); return ENA_COM_FAULT; } + + if (unlikely((status & (ENA_ETH_IO_RX_CDESC_BASE_MBZ7_MASK | + ENA_ETH_IO_RX_CDESC_BASE_MBZ17_MASK)) && + ena_com_get_cap(dev, ENA_ADMIN_CDESC_MBZ))) { + ena_trc_err(dev, + "Corrupted RX descriptor #%d on q_id: %d, req_id: %u\n", + count, io_cq->qid, cdesc->req_id); + return ENA_COM_FAULT; + } + count++; last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; diff --git a/drivers/net/ena/hal/ena_eth_com.h b/drivers/net/ena/hal/ena_eth_com.h index 6a7c17f84f..2fac10e678 100644 --- a/drivers/net/ena/hal/ena_eth_com.h +++ b/drivers/net/ena/hal/ena_eth_com.h @@ -204,9 +204,11 @@ static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq) static inline int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id) { + struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq); u8 expected_phase, cdesc_phase; struct ena_eth_io_tx_cdesc *cdesc; u16 masked_head; + u8 flags; masked_head = io_cq->head & (io_cq->q_depth - 1); expected_phase = io_cq->phase; @@ -215,14 +217,24 @@ static inline int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, ((uintptr_t)io_cq->cdesc_addr.virt_addr + (masked_head * io_cq->cdesc_entry_size_in_bytes)); + flags = READ_ONCE8(cdesc->flags); + /* When the current completion descriptor phase isn't the same as the * expected, it mean that the device still didn't update * this completion. */ - cdesc_phase = READ_ONCE8(cdesc->flags) & ENA_ETH_IO_TX_CDESC_PHASE_MASK; + cdesc_phase = flags & ENA_ETH_IO_TX_CDESC_PHASE_MASK; if (cdesc_phase != expected_phase) return ENA_COM_TRY_AGAIN; + if (unlikely((flags & ENA_ETH_IO_TX_CDESC_MBZ6_MASK) && + ena_com_get_cap(dev, ENA_ADMIN_CDESC_MBZ))) { + ena_trc_err(dev, + "Corrupted TX descriptor on q_id: %d, req_id: %u\n", + io_cq->qid, cdesc->req_id); + return ENA_COM_FAULT; + } + dma_rmb(); *req_id = READ_ONCE16(cdesc->req_id); -- 2.17.1