[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