[Intel-wired-lan] [next-queue PATCH] ixgbevf: Fix coexistence of malicious driver detection with XDP

Shannon Nelson shannon.nelson at oracle.com
Tue May 22 17:02:33 UTC 2018


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

> +	}
>   
>   	/* put descriptor type bits */
>   	cmd_type = IXGBE_ADVTXD_DTYP_DATA |
>   		   IXGBE_ADVTXD_DCMD_DEXT |
>   		   IXGBE_ADVTXD_DCMD_IFCS;
>   	cmd_type |= len | IXGBE_TXD_CMD;
> +
> +	tx_desc = IXGBEVF_TX_DESC(ring, i);
> +	tx_desc->read.buffer_addr = cpu_to_le64(dma);
> +
>   	tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
>   	tx_desc->read.olinfo_status =
>   			cpu_to_le32((len << IXGBE_ADVTXD_PAYLEN_SHIFT) |
> @@ -1688,6 +1709,7 @@ static void ixgbevf_configure_tx_ring(struct ixgbevf_adapter *adapter,
>   	       sizeof(struct ixgbevf_tx_buffer) * ring->count);
>   
>   	clear_bit(__IXGBEVF_HANG_CHECK_ARMED, &ring->state);
> +	clear_bit(__IXGBEVF_TX_XDP_RING_PRIMED, &ring->state);
>   
>   	IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(reg_idx), txdctl);
>   
> 
> _______________________________________________
> Intel-wired-lan mailing list
> Intel-wired-lan at osuosl.org
> https://lists.osuosl.org/mailman/listinfo/intel-wired-lan
> 


More information about the Intel-wired-lan mailing list