[Intel-wired-lan] [next-queue PATCH] ixgbevf: Fix coexistence of malicious driver detection with XDP
Alexander Duyck
alexander.duyck at gmail.com
Tue May 22 17:13:46 UTC 2018
On Tue, May 22, 2018 at 10:02 AM, Shannon Nelson
<shannon.nelson at oracle.com> wrote:
> On 5/22/2018 8:44 AM, Alexander Duyck wrote:
>>
>> In the case of the VF driver it is supposed to provide a context
>> descriptor
>> that allows us to provide information about the header offsets inside of
>> the frame. However in the case of XDP we don't really have any of that
>> information since the data is minimally processed. As a result we were
>> seeing malicious driver detection (MDD) events being triggered when the PF
>> had that functionality enabled.
>>
>> To address this I have added a bit of new code that will "prime" the XDP
>> ring by providing one context descriptor that assumes the minimal setup of
>> an Ethernet frame which is an L2 header length of 14. With just that we
>> can
>> provide enough information to make the hardware happy so that we don't
>> trigger MDD events.
>>
>> Signed-off-by: Alexander Duyck <alexander.h.duyck at intel.com>
>> ---
>> drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 +
>> drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 36
>> +++++++++++++++++----
>> 2 files changed, 30 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
>> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
>> index 70c7568..56a1031 100644
>> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
>> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
>> @@ -76,6 +76,7 @@ enum ixgbevf_ring_state_t {
>> __IXGBEVF_TX_DETECT_HANG,
>> __IXGBEVF_HANG_CHECK_ARMED,
>> __IXGBEVF_TX_XDP_RING,
>> + __IXGBEVF_TX_XDP_RING_PRIMED,
>> };
>> #define ring_is_xdp(ring) \
>> diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>> index c298614..e2a8a03 100644
>> --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>> +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
>> @@ -991,24 +991,45 @@ static int ixgbevf_xmit_xdp_ring(struct ixgbevf_ring
>> *ring,
>> return IXGBEVF_XDP_CONSUMED;
>> /* record the location of the first descriptor for this packet */
>> - tx_buffer = &ring->tx_buffer_info[ring->next_to_use];
>> - tx_buffer->bytecount = len;
>> - tx_buffer->gso_segs = 1;
>> - tx_buffer->protocol = 0;
>> -
>> i = ring->next_to_use;
>> - tx_desc = IXGBEVF_TX_DESC(ring, i);
>> + tx_buffer = &ring->tx_buffer_info[i];
>> dma_unmap_len_set(tx_buffer, len, len);
>> dma_unmap_addr_set(tx_buffer, dma, dma);
>> tx_buffer->data = xdp->data;
>> - tx_desc->read.buffer_addr = cpu_to_le64(dma);
>> + tx_buffer->bytecount = len;
>> + tx_buffer->gso_segs = 1;
>> + tx_buffer->protocol = 0;
>> +
>> + /* Populate minimal context descriptor that will provide for the
>> + * fact that we are expected to process Ethernet frames.
>> + */
>> + if (!test_bit(__IXGBEVF_TX_XDP_RING_PRIMED, &ring->state)) {
>> + struct ixgbe_adv_tx_context_desc *context_desc;
>> +
>> + set_bit(__IXGBEVF_TX_XDP_RING_PRIMED, &ring->state);
>> +
>> + context_desc = IXGBEVF_TX_CTXTDESC(ring, 0);
>> + context_desc->vlan_macip_lens =
>> + cpu_to_le32(ETH_HLEN <<
>> IXGBE_ADVTXD_MACLEN_SHIFT);
>> + context_desc->seqnum_seed = 0;
>> + context_desc->type_tucmd_mlhl =
>> + cpu_to_le32(IXGBE_TXD_CMD_DEXT |
>> + IXGBE_ADVTXD_DTYP_CTXT);
>> + context_desc->mss_l4len_idx = 0;
>> +
>> + i = 1;
>
>
> This setting of i looks odd to me. If i is the index of the next Tx
> descriptor to be used, why are hard coding it to 1 here? If this bit of
> code is only run the first time after the ring has been configured, then
> next_to_use was 0, and the data is in tx_buffer_info[0], but now tx_desc[1]
> will be filled in? Or am I misreading this?
>
> sln
No, you are reading this correctly.
We populate tx_buffer_info[0], populate tx_desc[0] with the context
descriptor, and tx_desc[1] with the data descriptor. This only happens
for the first packet placed in the ring so we can just bump the
tx_desc reference directly to 1 in this case since we will always know
that next_to_use will be 0.
We actually do this kind of thing in the normal transmit path,
although there we reference the first tx_buffer_info structure via the
"first" pointer.
Thanks.
- Alex
More information about the Intel-wired-lan
mailing list