ice: track malicious VFs in new ice_mbx_vf_info structure
authorJacob Keller <jacob.e.keller@intel.com>
Wed, 22 Feb 2023 17:09:09 +0000 (09:09 -0800)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 13 Mar 2023 17:32:32 +0000 (10:32 -0700)
Currently the PF tracks malicious VFs in a malvfs bitmap which is used by
the ice_mbx_clear_malvf and ice_mbx_report_malvf functions. This bitmap is
used to ensure that we only report a VF as malicious once rather than
continuously spamming the event log.

This mechanism of storage for the malicious indication works well enough
for SR-IOV. However, it will not work with Scalable IOV. This is because
Scalable IOV VFs can be allocated dynamically and might change VF ID when
their underlying VSI changes.

To support this, the mailbox overflow logic will need to be refactored.
First, introduce a new ice_mbx_vf_info structure which will be used to
store data about a VF. Embed this structure in the struct ice_vf, and
ensure it gets initialized when a new VF is created.

For now this only stores the malicious indicator bit. Pass a pointer to the
VF's mbx_info structure instead of using a bitmap to keep track of these
bits.

A future change will extend this structure and the rest of the logic
associated with the overflow detection.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Marek Szlosek <marek.szlosek@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_type.h
drivers/net/ethernet/intel/ice/ice_vf_lib.c
drivers/net/ethernet/intel/ice/ice_vf_lib.h
drivers/net/ethernet/intel/ice/ice_vf_mbx.c
drivers/net/ethernet/intel/ice/ice_vf_mbx.h

index 7107c27..44b9427 100644 (file)
@@ -204,8 +204,8 @@ void ice_free_vfs(struct ice_pf *pf)
                }
 
                /* clear malicious info since the VF is getting released */
-               ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs,
-                                   ICE_MAX_SRIOV_VFS, vf->vf_id);
+               ice_mbx_clear_malvf(&hw->mbx_snapshot, vf->vf_id,
+                                   &vf->mbx_info);
 
                mutex_unlock(&vf->cfg_lock);
        }
@@ -1828,8 +1828,7 @@ ice_is_malicious_vf(struct ice_pf *pf, struct ice_rq_event_info *event,
                /* if the VF is malicious and we haven't let the user
                 * know about it, then let them know now
                 */
-               status = ice_mbx_report_malvf(&pf->hw, pf->vfs.malvfs,
-                                             ICE_MAX_SRIOV_VFS, vf_id,
+               status = ice_mbx_report_malvf(&pf->hw, &vf->mbx_info,
                                              &report_vf);
                if (status)
                        dev_dbg(dev, "Error reporting malicious VF\n");
index e3f622c..d243a0c 100644 (file)
@@ -794,6 +794,13 @@ struct ice_mbx_vf_counter {
        u32 vfcntr_len;
 };
 
+/* Structure used to track a single VF's messages on the mailbox:
+ * 1. malicious: whether this VF has been detected as malicious before
+ */
+struct ice_mbx_vf_info {
+       u8 malicious : 1;
+};
+
 /* Structure to hold data relevant to the captured static snapshot
  * of the PF-VF mailbox.
  */
index 116b435..69e89e9 100644 (file)
@@ -496,8 +496,8 @@ void ice_reset_all_vfs(struct ice_pf *pf)
 
        /* clear all malicious info if the VFs are getting reset */
        ice_for_each_vf(pf, bkt, vf)
-               ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs,
-                                   ICE_MAX_SRIOV_VFS, vf->vf_id);
+               ice_mbx_clear_malvf(&hw->mbx_snapshot, vf->vf_id,
+                                   &vf->mbx_info);
 
        /* If VFs have been disabled, there is no need to reset */
        if (test_and_set_bit(ICE_VF_DIS, pf->state)) {
@@ -703,8 +703,7 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
        ice_eswitch_replay_vf_mac_rule(vf);
 
        /* if the VF has been reset allow it to come up again */
-       ice_mbx_clear_malvf(&hw->mbx_snapshot, pf->vfs.malvfs,
-                           ICE_MAX_SRIOV_VFS, vf->vf_id);
+       ice_mbx_clear_malvf(&hw->mbx_snapshot, vf->vf_id, &vf->mbx_info);
 
 out_unlock:
        if (flags & ICE_VF_RESET_LOCK)
@@ -760,6 +759,9 @@ void ice_initialize_vf_entry(struct ice_vf *vf)
        ice_vf_ctrl_invalidate_vsi(vf);
        ice_vf_fdir_init(vf);
 
+       /* Initialize mailbox info for this VF */
+       ice_mbx_init_vf_info(&pf->hw, &vf->mbx_info);
+
        mutex_init(&vf->cfg_lock);
 }
 
index ef30f05..e3cda6f 100644 (file)
@@ -74,7 +74,6 @@ struct ice_vfs {
        u16 num_qps_per;                /* number of queue pairs per VF */
        u16 num_msix_per;               /* number of MSI-X vectors per VF */
        unsigned long last_printed_mdd_jiffies; /* MDD message rate limit */
-       DECLARE_BITMAP(malvfs, ICE_MAX_SRIOV_VFS); /* malicious VF indicator */
 };
 
 /* VF information structure */
@@ -105,6 +104,7 @@ struct ice_vf {
        DECLARE_BITMAP(rxq_ena, ICE_MAX_RSS_QS_PER_VF);
        struct ice_vlan port_vlan_info; /* Port VLAN ID, QoS, and TPID */
        struct virtchnl_vlan_caps vlan_v2_caps;
+       struct ice_mbx_vf_info mbx_info;
        u8 pf_set_mac:1;                /* VF MAC address set by VMM admin */
        u8 trusted:1;
        u8 spoofchk:1;
index 9f6acfe..2e769bd 100644 (file)
@@ -345,35 +345,23 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,
 /**
  * ice_mbx_report_malvf - Track and note malicious VF
  * @hw: pointer to the HW struct
- * @all_malvfs: all malicious VFs tracked by PF
- * @bitmap_len: length of bitmap in bits
- * @vf_id: relative virtual function ID of the malicious VF
+ * @vf_info: the mailbox tracking info structure for a VF
  * @report_malvf: boolean to indicate if malicious VF must be reported
  *
- * This function will update a bitmap that keeps track of the malicious
- * VFs attached to the PF. A malicious VF must be reported only once if
- * discovered between VF resets or loading so the function checks
- * the input vf_id against the bitmap to verify if the VF has been
- * detected in any previous mailbox iterations.
+ * This function updates the malicious indicator bit in the VF mailbox
+ * tracking structure. A malicious VF must be reported only once if discovered
+ * between VF resets or loading so the function first checks if the VF has
+ * already been detected in any previous mailbox iterations.
  */
 int
-ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
-                    u16 bitmap_len, u16 vf_id, bool *report_malvf)
+ice_mbx_report_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
+                    bool *report_malvf)
 {
-       if (!all_malvfs || !report_malvf)
-               return -EINVAL;
-
-       *report_malvf = false;
-
-       if (bitmap_len < hw->mbx_snapshot.mbx_vf.vfcntr_len)
+       if (!report_malvf)
                return -EINVAL;
 
-       if (vf_id >= bitmap_len)
-               return -EIO;
-
-       /* If the vf_id is found in the bitmap set bit and boolean to true */
-       if (!test_and_set_bit(vf_id, all_malvfs))
-               *report_malvf = true;
+       *report_malvf = !vf_info->malicious;
+       vf_info->malicious = 1;
 
        return 0;
 }
@@ -381,33 +369,24 @@ ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
 /**
  * ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID
  * @snap: pointer to the mailbox snapshot structure
- * @all_malvfs: all malicious VFs tracked by PF
- * @bitmap_len: length of bitmap in bits
  * @vf_id: relative virtual function ID of the malicious VF
+ * @vf_info: mailbox tracking structure for this VF
  *
- * In case of a VF reset, this function can be called to clear
- * the bit corresponding to the VF ID in the bitmap tracking all
- * malicious VFs attached to the PF. The function also clears the
- * VF counter array at the index of the VF ID. This is to ensure
- * that the new VF loaded is not considered malicious before going
- * through the overflow detection algorithm.
- */
+* In case of a VF reset, this function shall be called to clear the VF's
+* current mailbox tracking state.
+*/
 void
-ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
-                   u16 bitmap_len, u16 vf_id)
+ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, u16 vf_id,
+                   struct ice_mbx_vf_info *vf_info)
 {
-       if (WARN_ON(!snap || !all_malvfs))
-               return;
-
-       if (WARN_ON(bitmap_len < snap->mbx_vf.vfcntr_len))
+       if (WARN_ON(!snap))
                return;
 
        /* Ensure VF ID value is not larger than bitmap or VF counter length */
-       if (WARN_ON(vf_id >= bitmap_len || vf_id >= snap->mbx_vf.vfcntr_len))
+       if (WARN_ON(vf_id >= snap->mbx_vf.vfcntr_len))
                return;
 
-       /* Clear VF ID bit in the bitmap tracking malicious VFs attached to PF */
-       clear_bit(vf_id, all_malvfs);
+       vf_info->malicious = 0;
 
        /* Clear the VF counter in the mailbox snapshot structure for that VF ID.
         * This is to ensure that if a VF is unloaded and a new one brought back
@@ -419,6 +398,18 @@ ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
 }
 
 /**
+ * ice_mbx_init_vf_info - Initialize a new VF mailbox tracking info
+ * @hw: pointer to the hardware structure
+ * @vf_info: the mailbox tracking info structure for a VF
+ *
+ * Initialize a VF mailbox tracking info structure.
+ */
+void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info)
+{
+       vf_info->malicious = 0;
+}
+
+/**
  * ice_mbx_init_snapshot - Initialize mailbox snapshot structure
  * @hw: pointer to the hardware structure
  * @vf_count: number of VFs allocated on a PF
index be593b9..2613cba 100644 (file)
@@ -23,13 +23,14 @@ int
 ice_mbx_vf_state_handler(struct ice_hw *hw, struct ice_mbx_data *mbx_data,
                         u16 vf_id, bool *is_mal_vf);
 void
-ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
-                   u16 bitmap_len, u16 vf_id);
+ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, u16 vf_id,
+                   struct ice_mbx_vf_info *vf_info);
+void ice_mbx_init_vf_info(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info);
 int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count);
 void ice_mbx_deinit_snapshot(struct ice_hw *hw);
 int
-ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
-                    u16 bitmap_len, u16 vf_id, bool *report_malvf);
+ice_mbx_report_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
+                    bool *report_malvf);
 #else /* CONFIG_PCI_IOV */
 static inline int
 ice_aq_send_msg_to_vf(struct ice_hw __always_unused *hw,