[Intel-wired-lan] [PATCH S55 02/14] ice: Allow ignoring opcodes on specific VF

Jankowski, Konrad0 konrad0.jankowski at intel.com
Wed Apr 21 18:48:39 UTC 2021



> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces at osuosl.org> On Behalf Of
> Tony Nguyen
> Sent: wtorek, 2 marca 2021 19:12
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH S55 02/14] ice: Allow ignoring opcodes on
> specific VF
> 
> From: Michal Swiatkowski <michal.swiatkowski at intel.com>
> 
> Declare bitmap of allowed commands on VF. Initialize default opcodes list
> that should be always supported. Declare array of supported opcodes for
> each caps used in virtchnl code.
> 
> Change allowed bitmap by setting or clearing corresponding bit to allowlist
> (bit set) or denylist (bit clear).
> 
> Signed-off-by: Michal Swiatkowski <michal.swiatkowski at intel.com>
> Signed-off-by: Tony Nguyen <anthony.l.nguyen at intel.com>
> ---
>  drivers/net/ethernet/intel/ice/Makefile       |   2 +-
>  .../intel/ice/ice_virtchnl_allowlist.c        | 165 ++++++++++++++++++
>  .../intel/ice/ice_virtchnl_allowlist.h        |  13 ++
>  .../net/ethernet/intel/ice/ice_virtchnl_pf.c  |  18 ++
>  .../net/ethernet/intel/ice/ice_virtchnl_pf.h  |   1 +
>  include/linux/avf/virtchnl.h                  |   1 +
>  6 files changed, 199 insertions(+), 1 deletion(-)  create mode 100644
> drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c
>  create mode 100644 drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.h
> 
> diff --git a/drivers/net/ethernet/intel/ice/Makefile
> b/drivers/net/ethernet/intel/ice/Makefile
> index f391691e2c7e..dc24ce7d1c1e 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -26,7 +26,7 @@ ice-y := ice_main.o	\
>  	 ice_fw_update.o \
>  	 ice_lag.o	\
>  	 ice_ethtool.o
> -ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o ice_virtchnl_fdir.o
> +ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o
> +ice_virtchnl_allowlist.o ice_virtchnl_fdir.o
>  ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
>  ice-$(CONFIG_RFS_ACCEL) += ice_arfs.o
>  ice-$(CONFIG_XDP_SOCKETS) += ice_xsk.o
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c
> b/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c
> new file mode 100644
> index 000000000000..64b1314d4761
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.c
> @@ -0,0 +1,165 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2018-2021, Intel Corporation. */
> +
> +#include "ice_virtchnl_allowlist.h"
> +
> +/* Purpose of this file is to share functionality to allowlist or
> +denylist
> + * opcodes used in PF <-> VF communication. Group of opcodes:
> + * - default -> should be always allowed after creating VF,
> + *   default_allowlist_opcodes
> + * - opcodes needed by VF to work correctly, but not associated with caps -
> >
> + *   should be allowed after successful VF resources allocation,
> + *   working_allowlist_opcodes
> + * - opcodes needed by VF when caps are activated
> + *
> + * Caps that don't use new opcodes (no opcodes should be allowed):
> + * - VIRTCHNL_VF_OFFLOAD_RSS_AQ
> + * - VIRTCHNL_VF_OFFLOAD_RSS_REG
> + * - VIRTCHNL_VF_OFFLOAD_WB_ON_ITR
> + * - VIRTCHNL_VF_OFFLOAD_CRC
> + * - VIRTCHNL_VF_OFFLOAD_RX_POLLING
> + * - VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
> + * - VIRTCHNL_VF_OFFLOAD_ENCAP
> + * - VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM
> + * - VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM
> + * - VIRTCHNL_VF_OFFLOAD_USO
> + */
> +
> +/* default opcodes to communicate with VF */ static const u32
> +default_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_GET_VF_RESOURCES, VIRTCHNL_OP_VERSION,
> +VIRTCHNL_OP_RESET_VF, };
> +
> +/* opcodes supported after successful VIRTCHNL_OP_GET_VF_RESOURCES
> */
> +static const u32 working_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_CONFIG_TX_QUEUE,
> VIRTCHNL_OP_CONFIG_RX_QUEUE,
> +	VIRTCHNL_OP_CONFIG_VSI_QUEUES,
> VIRTCHNL_OP_CONFIG_IRQ_MAP,
> +	VIRTCHNL_OP_ENABLE_QUEUES, VIRTCHNL_OP_DISABLE_QUEUES,
> +	VIRTCHNL_OP_GET_STATS, VIRTCHNL_OP_EVENT, };
> +
> +/* VIRTCHNL_VF_OFFLOAD_L2 */
> +static const u32 l2_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_ADD_ETH_ADDR, VIRTCHNL_OP_DEL_ETH_ADDR,
> +	VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
> +};
> +
> +/* VIRTCHNL_VF_OFFLOAD_REQ_QUEUES */
> +static const u32 req_queues_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_REQUEST_QUEUES,
> +};
> +
> +/* VIRTCHNL_VF_OFFLOAD_VLAN */
> +static const u32 vlan_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_ADD_VLAN, VIRTCHNL_OP_DEL_VLAN,
> +	VIRTCHNL_OP_ENABLE_VLAN_STRIPPING,
> VIRTCHNL_OP_DISABLE_VLAN_STRIPPING,
> +};
> +
> +/* VIRTCHNL_VF_OFFLOAD_RSS_PF */
> +static const u32 rss_pf_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_CONFIG_RSS_KEY, VIRTCHNL_OP_CONFIG_RSS_LUT,
> +	VIRTCHNL_OP_GET_RSS_HENA_CAPS,
> VIRTCHNL_OP_SET_RSS_HENA, };
> +
> +/* VIRTCHNL_VF_OFFLOAD_FDIR_PF */
> +static const u32 fdir_pf_allowlist_opcodes[] = {
> +	VIRTCHNL_OP_ADD_FDIR_FILTER, VIRTCHNL_OP_DEL_FDIR_FILTER,
> };
> +
> +struct allowlist_opcode_info {
> +	const u32 *opcodes;
> +	size_t size;
> +};
> +
> +#define BIT_INDEX(caps) (HWEIGHT((caps) - 1)) #define
> ALLOW_ITEM(caps,
> +list) \
> +	[BIT_INDEX(caps)] = { \
> +		.opcodes = list, \
> +		.size = ARRAY_SIZE(list) \
> +	}
> +static const struct allowlist_opcode_info allowlist_opcodes[] = {
> +	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_L2, l2_allowlist_opcodes),
> +	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_REQ_QUEUES,
> req_queues_allowlist_opcodes),
> +	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_VLAN,
> vlan_allowlist_opcodes),
> +	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_RSS_PF,
> rss_pf_allowlist_opcodes),
> +	ALLOW_ITEM(VIRTCHNL_VF_OFFLOAD_FDIR_PF,
> fdir_pf_allowlist_opcodes), };
> +
> +/**
> + * ice_vc_opcode_is_allowed - check if this opcode is allowed on this
> +VF
> + * @vf: pointer to VF structure
> + * @opcode: virtchnl opcode
> + *
> + * Return true if message is allowed on this VF  */ bool
> +ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode) {
> +	if (opcode >= VIRTCHNL_OP_MAX)
> +		return false;
> +
> +	return test_bit(opcode, vf->opcodes_allowlist); }
> +
> +/**
> + * ice_vc_allowlist_opcodes - allowlist selected opcodes
> + * @vf: pointer to VF structure
> + * @opcodes: array of opocodes to allowlist
> + * @size: size of opcodes array
> + *
> + * Function should be called to allowlist opcodes on VF.
> + */
> +static void
> +ice_vc_allowlist_opcodes(struct ice_vf *vf, const u32 *opcodes, size_t
> +size) {
> +	unsigned int i;
> +
> +	for (i = 0; i < size; i++)
> +		set_bit(opcodes[i], vf->opcodes_allowlist); }
> +
> +/**
> + * ice_vc_clear_allowlist - clear all allowlist opcodes
> + * @vf: pointer to VF structure
> + */
> +static void ice_vc_clear_allowlist(struct ice_vf *vf) {
> +	bitmap_zero(vf->opcodes_allowlist, VIRTCHNL_OP_MAX); }
> +
> +/**
> + * ice_vc_set_default_allowlist - allowlist default opcodes for VF
> + * @vf: pointer to VF structure
> + */
> +void ice_vc_set_default_allowlist(struct ice_vf *vf) {
> +	ice_vc_clear_allowlist(vf);
> +	ice_vc_allowlist_opcodes(vf, default_allowlist_opcodes,
> +				 ARRAY_SIZE(default_allowlist_opcodes));
> +}
> +
> +/**
> + * ice_vc_set_working_allowlist - allowlist opcodes needed to by VF to
> +work
> + * @vf: pointer to VF structure
> + *
> + * Whitelist opcodes that aren't associated with specific caps, but
> + * are needed by VF to work.
> + */
> +void ice_vc_set_working_allowlist(struct ice_vf *vf) {
> +	ice_vc_allowlist_opcodes(vf, working_allowlist_opcodes,
> +				 ARRAY_SIZE(working_allowlist_opcodes));
> +}
> +
> +/**
> + * ice_vc_set_allowlist_based_on_caps - allowlist VF opcodes according
> +caps
> + * @vf: pointer to VF structure
> + */
> +void ice_vc_set_caps_allowlist(struct ice_vf *vf) {
> +	unsigned long caps = vf->driver_caps;
> +	unsigned int i;
> +
> +	for_each_set_bit(i, &caps, ARRAY_SIZE(allowlist_opcodes))
> +		ice_vc_allowlist_opcodes(vf, allowlist_opcodes[i].opcodes,
> +					 allowlist_opcodes[i].size);
> +}
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.h
> b/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.h
> new file mode 100644
> index 000000000000..c33bc6ac3f54
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_allowlist.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2018-2021, Intel Corporation. */
> +
> +#ifndef _ICE_VIRTCHNL_ALLOWLIST_H_
> +#define _ICE_VIRTCHNL_ALLOWLIST_H_
> +#include "ice.h"
> +
> +bool ice_vc_is_opcode_allowed(struct ice_vf *vf, u32 opcode);
> +
> +void ice_vc_set_default_allowlist(struct ice_vf *vf); void
> +ice_vc_set_working_allowlist(struct ice_vf *vf); void
> +ice_vc_set_caps_allowlist(struct ice_vf *vf); #endif
> diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> index 0da9c84ed30f..f09367eb242a 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
> @@ -5,6 +5,7 @@
>  #include "ice_base.h"
>  #include "ice_lib.h"
>  #include "ice_fltr.h"
> +#include "ice_virtchnl_allowlist.h"
> 
>  /**
>   * ice_validate_vf_id - helper to check if VF ID is valid @@ -1317,6 +1318,9
> @@ bool ice_reset_all_vfs(struct ice_pf *pf, bool is_vflr)
>  	ice_for_each_vf(pf, v) {
>  		vf = &pf->vf[v];
> 
> +		vf->driver_caps = 0;
> +		ice_vc_set_default_allowlist(vf);
> +
>  		ice_vf_fdir_exit(vf);
>  		/* clean VF control VSI when resetting VFs since it should be
>  		 * setup only when iAVF creates its first FDIR rule.
> @@ -1421,6 +1425,9 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
>  		usleep_range(10, 20);
>  	}
> 
> +	vf->driver_caps = 0;
> +	ice_vc_set_default_allowlist(vf);
> +
>  	/* Display a warning if VF didn't manage to reset in time, but need to
>  	 * continue on with the operation.
>  	 */
> @@ -1633,6 +1640,7 @@ static void ice_set_dflt_settings_vfs(struct ice_pf
> *pf)
>  		set_bit(ICE_VIRTCHNL_VF_CAP_L2, &vf->vf_caps);
>  		vf->spoofchk = true;
>  		vf->num_vf_qs = pf->num_qps_per_vf;
> +		ice_vc_set_default_allowlist(vf);
> 
>  		/* ctrl_vsi_idx will be set to a valid value only when iAVF
>  		 * creates its first fdir rule.
> @@ -2135,6 +2143,9 @@ static int ice_vc_get_vf_res_msg(struct ice_vf *vf,
> u8 *msg)
>  	/* match guest capabilities */
>  	vf->driver_caps = vfres->vf_cap_flags;
> 
> +	ice_vc_set_caps_allowlist(vf);
> +	ice_vc_set_working_allowlist(vf);
> +
>  	set_bit(ICE_VF_STATE_ACTIVE, vf->vf_states);
> 
>  err:
> @@ -3964,6 +3975,13 @@ void ice_vc_process_vf_msg(struct ice_pf *pf,
> struct ice_rq_event_info *event)
>  			err = -EINVAL;
>  	}
> 
> +	if (!ice_vc_is_opcode_allowed(vf, v_opcode)) {
> +		ice_vc_send_msg_to_vf(vf, v_opcode,
> +
> VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL,
> +				      0);
> +		return;
> +	}
> +
>  error_handler:
>  	if (err) {
>  		ice_vc_send_msg_to_vf(vf, v_opcode,
> VIRTCHNL_STATUS_ERR_PARAM, diff --git
> a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
> b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
> index 53391ac1f068..77ff0023f7be 100644
> --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
> +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
> @@ -110,6 +110,7 @@ struct ice_vf {
>  	u16 num_vf_qs;			/* num of queue configured
> per VF */
>  	struct ice_mdd_vf_events mdd_rx_events;
>  	struct ice_mdd_vf_events mdd_tx_events;
> +	DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX);
>  };
> 
>  #ifdef CONFIG_PCI_IOV
> diff --git a/include/linux/avf/virtchnl.h b/include/linux/avf/virtchnl.h index
> e3d5ecf7cf41..228b90ef3361 100644
> --- a/include/linux/avf/virtchnl.h
> +++ b/include/linux/avf/virtchnl.h
> @@ -139,6 +139,7 @@ enum virtchnl_ops {
>  	/* opcode 34 - 46 are reserved */
>  	VIRTCHNL_OP_ADD_FDIR_FILTER = 47,
>  	VIRTCHNL_OP_DEL_FDIR_FILTER = 48,
> +	VIRTCHNL_OP_MAX,
>  };
> 
>  /* These macros are used to generate compilation errors if a structure/union

Tested-by: Konrad Jankowski <konrad0.jankowski at intel.com>


More information about the Intel-wired-lan mailing list