Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2018, Intel Corporation. */
0003 
0004 #include "ice_common.h"
0005 #include "ice_vf_mbx.h"
0006 
0007 /**
0008  * ice_aq_send_msg_to_vf
0009  * @hw: pointer to the hardware structure
0010  * @vfid: VF ID to send msg
0011  * @v_opcode: opcodes for VF-PF communication
0012  * @v_retval: return error code
0013  * @msg: pointer to the msg buffer
0014  * @msglen: msg length
0015  * @cd: pointer to command details
0016  *
0017  * Send message to VF driver (0x0802) using mailbox
0018  * queue and asynchronously sending message via
0019  * ice_sq_send_cmd() function
0020  */
0021 int
0022 ice_aq_send_msg_to_vf(struct ice_hw *hw, u16 vfid, u32 v_opcode, u32 v_retval,
0023               u8 *msg, u16 msglen, struct ice_sq_cd *cd)
0024 {
0025     struct ice_aqc_pf_vf_msg *cmd;
0026     struct ice_aq_desc desc;
0027 
0028     ice_fill_dflt_direct_cmd_desc(&desc, ice_mbx_opc_send_msg_to_vf);
0029 
0030     cmd = &desc.params.virt;
0031     cmd->id = cpu_to_le32(vfid);
0032 
0033     desc.cookie_high = cpu_to_le32(v_opcode);
0034     desc.cookie_low = cpu_to_le32(v_retval);
0035 
0036     if (msglen)
0037         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
0038 
0039     return ice_sq_send_cmd(hw, &hw->mailboxq, &desc, msg, msglen, cd);
0040 }
0041 
0042 /**
0043  * ice_conv_link_speed_to_virtchnl
0044  * @adv_link_support: determines the format of the returned link speed
0045  * @link_speed: variable containing the link_speed to be converted
0046  *
0047  * Convert link speed supported by HW to link speed supported by virtchnl.
0048  * If adv_link_support is true, then return link speed in Mbps. Else return
0049  * link speed as a VIRTCHNL_LINK_SPEED_* casted to a u32. Note that the caller
0050  * needs to cast back to an enum virtchnl_link_speed in the case where
0051  * adv_link_support is false, but when adv_link_support is true the caller can
0052  * expect the speed in Mbps.
0053  */
0054 u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
0055 {
0056     u32 speed;
0057 
0058     if (adv_link_support)
0059         switch (link_speed) {
0060         case ICE_AQ_LINK_SPEED_10MB:
0061             speed = ICE_LINK_SPEED_10MBPS;
0062             break;
0063         case ICE_AQ_LINK_SPEED_100MB:
0064             speed = ICE_LINK_SPEED_100MBPS;
0065             break;
0066         case ICE_AQ_LINK_SPEED_1000MB:
0067             speed = ICE_LINK_SPEED_1000MBPS;
0068             break;
0069         case ICE_AQ_LINK_SPEED_2500MB:
0070             speed = ICE_LINK_SPEED_2500MBPS;
0071             break;
0072         case ICE_AQ_LINK_SPEED_5GB:
0073             speed = ICE_LINK_SPEED_5000MBPS;
0074             break;
0075         case ICE_AQ_LINK_SPEED_10GB:
0076             speed = ICE_LINK_SPEED_10000MBPS;
0077             break;
0078         case ICE_AQ_LINK_SPEED_20GB:
0079             speed = ICE_LINK_SPEED_20000MBPS;
0080             break;
0081         case ICE_AQ_LINK_SPEED_25GB:
0082             speed = ICE_LINK_SPEED_25000MBPS;
0083             break;
0084         case ICE_AQ_LINK_SPEED_40GB:
0085             speed = ICE_LINK_SPEED_40000MBPS;
0086             break;
0087         case ICE_AQ_LINK_SPEED_50GB:
0088             speed = ICE_LINK_SPEED_50000MBPS;
0089             break;
0090         case ICE_AQ_LINK_SPEED_100GB:
0091             speed = ICE_LINK_SPEED_100000MBPS;
0092             break;
0093         default:
0094             speed = ICE_LINK_SPEED_UNKNOWN;
0095             break;
0096         }
0097     else
0098         /* Virtchnl speeds are not defined for every speed supported in
0099          * the hardware. To maintain compatibility with older AVF
0100          * drivers, while reporting the speed the new speed values are
0101          * resolved to the closest known virtchnl speeds
0102          */
0103         switch (link_speed) {
0104         case ICE_AQ_LINK_SPEED_10MB:
0105         case ICE_AQ_LINK_SPEED_100MB:
0106             speed = (u32)VIRTCHNL_LINK_SPEED_100MB;
0107             break;
0108         case ICE_AQ_LINK_SPEED_1000MB:
0109         case ICE_AQ_LINK_SPEED_2500MB:
0110         case ICE_AQ_LINK_SPEED_5GB:
0111             speed = (u32)VIRTCHNL_LINK_SPEED_1GB;
0112             break;
0113         case ICE_AQ_LINK_SPEED_10GB:
0114             speed = (u32)VIRTCHNL_LINK_SPEED_10GB;
0115             break;
0116         case ICE_AQ_LINK_SPEED_20GB:
0117             speed = (u32)VIRTCHNL_LINK_SPEED_20GB;
0118             break;
0119         case ICE_AQ_LINK_SPEED_25GB:
0120             speed = (u32)VIRTCHNL_LINK_SPEED_25GB;
0121             break;
0122         case ICE_AQ_LINK_SPEED_40GB:
0123         case ICE_AQ_LINK_SPEED_50GB:
0124         case ICE_AQ_LINK_SPEED_100GB:
0125             speed = (u32)VIRTCHNL_LINK_SPEED_40GB;
0126             break;
0127         default:
0128             speed = (u32)VIRTCHNL_LINK_SPEED_UNKNOWN;
0129             break;
0130         }
0131 
0132     return speed;
0133 }
0134 
0135 /* The mailbox overflow detection algorithm helps to check if there
0136  * is a possibility of a malicious VF transmitting too many MBX messages to the
0137  * PF.
0138  * 1. The mailbox snapshot structure, ice_mbx_snapshot, is initialized during
0139  * driver initialization in ice_init_hw() using ice_mbx_init_snapshot().
0140  * The struct ice_mbx_snapshot helps to track and traverse a static window of
0141  * messages within the mailbox queue while looking for a malicious VF.
0142  *
0143  * 2. When the caller starts processing its mailbox queue in response to an
0144  * interrupt, the structure ice_mbx_snapshot is expected to be cleared before
0145  * the algorithm can be run for the first time for that interrupt. This can be
0146  * done via ice_mbx_reset_snapshot().
0147  *
0148  * 3. For every message read by the caller from the MBX Queue, the caller must
0149  * call the detection algorithm's entry function ice_mbx_vf_state_handler().
0150  * Before every call to ice_mbx_vf_state_handler() the struct ice_mbx_data is
0151  * filled as it is required to be passed to the algorithm.
0152  *
0153  * 4. Every time a message is read from the MBX queue, a VFId is received which
0154  * is passed to the state handler. The boolean output is_malvf of the state
0155  * handler ice_mbx_vf_state_handler() serves as an indicator to the caller
0156  * whether this VF is malicious or not.
0157  *
0158  * 5. When a VF is identified to be malicious, the caller can send a message
0159  * to the system administrator. The caller can invoke ice_mbx_report_malvf()
0160  * to help determine if a malicious VF is to be reported or not. This function
0161  * requires the caller to maintain a global bitmap to track all malicious VFs
0162  * and pass that to ice_mbx_report_malvf() along with the VFID which was identified
0163  * to be malicious by ice_mbx_vf_state_handler().
0164  *
0165  * 6. The global bitmap maintained by PF can be cleared completely if PF is in
0166  * reset or the bit corresponding to a VF can be cleared if that VF is in reset.
0167  * When a VF is shut down and brought back up, we assume that the new VF
0168  * brought up is not malicious and hence report it if found malicious.
0169  *
0170  * 7. The function ice_mbx_reset_snapshot() is called to reset the information
0171  * in ice_mbx_snapshot for every new mailbox interrupt handled.
0172  *
0173  * 8. The memory allocated for variables in ice_mbx_snapshot is de-allocated
0174  * when driver is unloaded.
0175  */
0176 #define ICE_RQ_DATA_MASK(rq_data) ((rq_data) & PF_MBX_ARQH_ARQH_M)
0177 /* Using the highest value for an unsigned 16-bit value 0xFFFF to indicate that
0178  * the max messages check must be ignored in the algorithm
0179  */
0180 #define ICE_IGNORE_MAX_MSG_CNT  0xFFFF
0181 
0182 /**
0183  * ice_mbx_traverse - Pass through mailbox snapshot
0184  * @hw: pointer to the HW struct
0185  * @new_state: new algorithm state
0186  *
0187  * Traversing the mailbox static snapshot without checking
0188  * for malicious VFs.
0189  */
0190 static void
0191 ice_mbx_traverse(struct ice_hw *hw,
0192          enum ice_mbx_snapshot_state *new_state)
0193 {
0194     struct ice_mbx_snap_buffer_data *snap_buf;
0195     u32 num_iterations;
0196 
0197     snap_buf = &hw->mbx_snapshot.mbx_buf;
0198 
0199     /* As mailbox buffer is circular, applying a mask
0200      * on the incremented iteration count.
0201      */
0202     num_iterations = ICE_RQ_DATA_MASK(++snap_buf->num_iterations);
0203 
0204     /* Checking either of the below conditions to exit snapshot traversal:
0205      * Condition-1: If the number of iterations in the mailbox is equal to
0206      * the mailbox head which would indicate that we have reached the end
0207      * of the static snapshot.
0208      * Condition-2: If the maximum messages serviced in the mailbox for a
0209      * given interrupt is the highest possible value then there is no need
0210      * to check if the number of messages processed is equal to it. If not
0211      * check if the number of messages processed is greater than or equal
0212      * to the maximum number of mailbox entries serviced in current work item.
0213      */
0214     if (num_iterations == snap_buf->head ||
0215         (snap_buf->max_num_msgs_mbx < ICE_IGNORE_MAX_MSG_CNT &&
0216          ++snap_buf->num_msg_proc >= snap_buf->max_num_msgs_mbx))
0217         *new_state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
0218 }
0219 
0220 /**
0221  * ice_mbx_detect_malvf - Detect malicious VF in snapshot
0222  * @hw: pointer to the HW struct
0223  * @vf_id: relative virtual function ID
0224  * @new_state: new algorithm state
0225  * @is_malvf: boolean output to indicate if VF is malicious
0226  *
0227  * This function tracks the number of asynchronous messages
0228  * sent per VF and marks the VF as malicious if it exceeds
0229  * the permissible number of messages to send.
0230  */
0231 static int
0232 ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,
0233              enum ice_mbx_snapshot_state *new_state,
0234              bool *is_malvf)
0235 {
0236     struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
0237 
0238     if (vf_id >= snap->mbx_vf.vfcntr_len)
0239         return -EIO;
0240 
0241     /* increment the message count in the VF array */
0242     snap->mbx_vf.vf_cntr[vf_id]++;
0243 
0244     if (snap->mbx_vf.vf_cntr[vf_id] >= ICE_ASYNC_VF_MSG_THRESHOLD)
0245         *is_malvf = true;
0246 
0247     /* continue to iterate through the mailbox snapshot */
0248     ice_mbx_traverse(hw, new_state);
0249 
0250     return 0;
0251 }
0252 
0253 /**
0254  * ice_mbx_reset_snapshot - Reset mailbox snapshot structure
0255  * @snap: pointer to mailbox snapshot structure in the ice_hw struct
0256  *
0257  * Reset the mailbox snapshot structure and clear VF counter array.
0258  */
0259 static void ice_mbx_reset_snapshot(struct ice_mbx_snapshot *snap)
0260 {
0261     u32 vfcntr_len;
0262 
0263     if (!snap || !snap->mbx_vf.vf_cntr)
0264         return;
0265 
0266     /* Clear VF counters. */
0267     vfcntr_len = snap->mbx_vf.vfcntr_len;
0268     if (vfcntr_len)
0269         memset(snap->mbx_vf.vf_cntr, 0,
0270                (vfcntr_len * sizeof(*snap->mbx_vf.vf_cntr)));
0271 
0272     /* Reset mailbox snapshot for a new capture. */
0273     memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
0274     snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
0275 }
0276 
0277 /**
0278  * ice_mbx_vf_state_handler - Handle states of the overflow algorithm
0279  * @hw: pointer to the HW struct
0280  * @mbx_data: pointer to structure containing mailbox data
0281  * @vf_id: relative virtual function (VF) ID
0282  * @is_malvf: boolean output to indicate if VF is malicious
0283  *
0284  * The function serves as an entry point for the malicious VF
0285  * detection algorithm by handling the different states and state
0286  * transitions of the algorithm:
0287  * New snapshot: This state is entered when creating a new static
0288  * snapshot. The data from any previous mailbox snapshot is
0289  * cleared and a new capture of the mailbox head and tail is
0290  * logged. This will be the new static snapshot to detect
0291  * asynchronous messages sent by VFs. On capturing the snapshot
0292  * and depending on whether the number of pending messages in that
0293  * snapshot exceed the watermark value, the state machine enters
0294  * traverse or detect states.
0295  * Traverse: If pending message count is below watermark then iterate
0296  * through the snapshot without any action on VF.
0297  * Detect: If pending message count exceeds watermark traverse
0298  * the static snapshot and look for a malicious VF.
0299  */
0300 int
0301 ice_mbx_vf_state_handler(struct ice_hw *hw,
0302              struct ice_mbx_data *mbx_data, u16 vf_id,
0303              bool *is_malvf)
0304 {
0305     struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
0306     struct ice_mbx_snap_buffer_data *snap_buf;
0307     struct ice_ctl_q_info *cq = &hw->mailboxq;
0308     enum ice_mbx_snapshot_state new_state;
0309     int status = 0;
0310 
0311     if (!is_malvf || !mbx_data)
0312         return -EINVAL;
0313 
0314     /* When entering the mailbox state machine assume that the VF
0315      * is not malicious until detected.
0316      */
0317     *is_malvf = false;
0318 
0319      /* Checking if max messages allowed to be processed while servicing current
0320       * interrupt is not less than the defined AVF message threshold.
0321       */
0322     if (mbx_data->max_num_msgs_mbx <= ICE_ASYNC_VF_MSG_THRESHOLD)
0323         return -EINVAL;
0324 
0325     /* The watermark value should not be lesser than the threshold limit
0326      * set for the number of asynchronous messages a VF can send to mailbox
0327      * nor should it be greater than the maximum number of messages in the
0328      * mailbox serviced in current interrupt.
0329      */
0330     if (mbx_data->async_watermark_val < ICE_ASYNC_VF_MSG_THRESHOLD ||
0331         mbx_data->async_watermark_val > mbx_data->max_num_msgs_mbx)
0332         return -EINVAL;
0333 
0334     new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
0335     snap_buf = &snap->mbx_buf;
0336 
0337     switch (snap_buf->state) {
0338     case ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT:
0339         /* Clear any previously held data in mailbox snapshot structure. */
0340         ice_mbx_reset_snapshot(snap);
0341 
0342         /* Collect the pending ARQ count, number of messages processed and
0343          * the maximum number of messages allowed to be processed from the
0344          * Mailbox for current interrupt.
0345          */
0346         snap_buf->num_pending_arq = mbx_data->num_pending_arq;
0347         snap_buf->num_msg_proc = mbx_data->num_msg_proc;
0348         snap_buf->max_num_msgs_mbx = mbx_data->max_num_msgs_mbx;
0349 
0350         /* Capture a new static snapshot of the mailbox by logging the
0351          * head and tail of snapshot and set num_iterations to the tail
0352          * value to mark the start of the iteration through the snapshot.
0353          */
0354         snap_buf->head = ICE_RQ_DATA_MASK(cq->rq.next_to_clean +
0355                           mbx_data->num_pending_arq);
0356         snap_buf->tail = ICE_RQ_DATA_MASK(cq->rq.next_to_clean - 1);
0357         snap_buf->num_iterations = snap_buf->tail;
0358 
0359         /* Pending ARQ messages returned by ice_clean_rq_elem
0360          * is the difference between the head and tail of the
0361          * mailbox queue. Comparing this value against the watermark
0362          * helps to check if we potentially have malicious VFs.
0363          */
0364         if (snap_buf->num_pending_arq >=
0365             mbx_data->async_watermark_val) {
0366             new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
0367             status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
0368         } else {
0369             new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
0370             ice_mbx_traverse(hw, &new_state);
0371         }
0372         break;
0373 
0374     case ICE_MAL_VF_DETECT_STATE_TRAVERSE:
0375         new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE;
0376         ice_mbx_traverse(hw, &new_state);
0377         break;
0378 
0379     case ICE_MAL_VF_DETECT_STATE_DETECT:
0380         new_state = ICE_MAL_VF_DETECT_STATE_DETECT;
0381         status = ice_mbx_detect_malvf(hw, vf_id, &new_state, is_malvf);
0382         break;
0383 
0384     default:
0385         new_state = ICE_MAL_VF_DETECT_STATE_INVALID;
0386         status = -EIO;
0387     }
0388 
0389     snap_buf->state = new_state;
0390 
0391     return status;
0392 }
0393 
0394 /**
0395  * ice_mbx_report_malvf - Track and note malicious VF
0396  * @hw: pointer to the HW struct
0397  * @all_malvfs: all malicious VFs tracked by PF
0398  * @bitmap_len: length of bitmap in bits
0399  * @vf_id: relative virtual function ID of the malicious VF
0400  * @report_malvf: boolean to indicate if malicious VF must be reported
0401  *
0402  * This function will update a bitmap that keeps track of the malicious
0403  * VFs attached to the PF. A malicious VF must be reported only once if
0404  * discovered between VF resets or loading so the function checks
0405  * the input vf_id against the bitmap to verify if the VF has been
0406  * detected in any previous mailbox iterations.
0407  */
0408 int
0409 ice_mbx_report_malvf(struct ice_hw *hw, unsigned long *all_malvfs,
0410              u16 bitmap_len, u16 vf_id, bool *report_malvf)
0411 {
0412     if (!all_malvfs || !report_malvf)
0413         return -EINVAL;
0414 
0415     *report_malvf = false;
0416 
0417     if (bitmap_len < hw->mbx_snapshot.mbx_vf.vfcntr_len)
0418         return -EINVAL;
0419 
0420     if (vf_id >= bitmap_len)
0421         return -EIO;
0422 
0423     /* If the vf_id is found in the bitmap set bit and boolean to true */
0424     if (!test_and_set_bit(vf_id, all_malvfs))
0425         *report_malvf = true;
0426 
0427     return 0;
0428 }
0429 
0430 /**
0431  * ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID
0432  * @snap: pointer to the mailbox snapshot structure
0433  * @all_malvfs: all malicious VFs tracked by PF
0434  * @bitmap_len: length of bitmap in bits
0435  * @vf_id: relative virtual function ID of the malicious VF
0436  *
0437  * In case of a VF reset, this function can be called to clear
0438  * the bit corresponding to the VF ID in the bitmap tracking all
0439  * malicious VFs attached to the PF. The function also clears the
0440  * VF counter array at the index of the VF ID. This is to ensure
0441  * that the new VF loaded is not considered malicious before going
0442  * through the overflow detection algorithm.
0443  */
0444 int
0445 ice_mbx_clear_malvf(struct ice_mbx_snapshot *snap, unsigned long *all_malvfs,
0446             u16 bitmap_len, u16 vf_id)
0447 {
0448     if (!snap || !all_malvfs)
0449         return -EINVAL;
0450 
0451     if (bitmap_len < snap->mbx_vf.vfcntr_len)
0452         return -EINVAL;
0453 
0454     /* Ensure VF ID value is not larger than bitmap or VF counter length */
0455     if (vf_id >= bitmap_len || vf_id >= snap->mbx_vf.vfcntr_len)
0456         return -EIO;
0457 
0458     /* Clear VF ID bit in the bitmap tracking malicious VFs attached to PF */
0459     clear_bit(vf_id, all_malvfs);
0460 
0461     /* Clear the VF counter in the mailbox snapshot structure for that VF ID.
0462      * This is to ensure that if a VF is unloaded and a new one brought back
0463      * up with the same VF ID for a snapshot currently in traversal or detect
0464      * state the counter for that VF ID does not increment on top of existing
0465      * values in the mailbox overflow detection algorithm.
0466      */
0467     snap->mbx_vf.vf_cntr[vf_id] = 0;
0468 
0469     return 0;
0470 }
0471 
0472 /**
0473  * ice_mbx_init_snapshot - Initialize mailbox snapshot structure
0474  * @hw: pointer to the hardware structure
0475  * @vf_count: number of VFs allocated on a PF
0476  *
0477  * Clear the mailbox snapshot structure and allocate memory
0478  * for the VF counter array based on the number of VFs allocated
0479  * on that PF.
0480  *
0481  * Assumption: This function will assume ice_get_caps() has already been
0482  * called to ensure that the vf_count can be compared against the number
0483  * of VFs supported as defined in the functional capabilities of the device.
0484  */
0485 int ice_mbx_init_snapshot(struct ice_hw *hw, u16 vf_count)
0486 {
0487     struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
0488 
0489     /* Ensure that the number of VFs allocated is non-zero and
0490      * is not greater than the number of supported VFs defined in
0491      * the functional capabilities of the PF.
0492      */
0493     if (!vf_count || vf_count > hw->func_caps.num_allocd_vfs)
0494         return -EINVAL;
0495 
0496     snap->mbx_vf.vf_cntr = devm_kcalloc(ice_hw_to_dev(hw), vf_count,
0497                         sizeof(*snap->mbx_vf.vf_cntr),
0498                         GFP_KERNEL);
0499     if (!snap->mbx_vf.vf_cntr)
0500         return -ENOMEM;
0501 
0502     /* Setting the VF counter length to the number of allocated
0503      * VFs for given PF's functional capabilities.
0504      */
0505     snap->mbx_vf.vfcntr_len = vf_count;
0506 
0507     /* Clear mbx_buf in the mailbox snaphot structure and setting the
0508      * mailbox snapshot state to a new capture.
0509      */
0510     memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
0511     snap->mbx_buf.state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT;
0512 
0513     return 0;
0514 }
0515 
0516 /**
0517  * ice_mbx_deinit_snapshot - Free mailbox snapshot structure
0518  * @hw: pointer to the hardware structure
0519  *
0520  * Clear the mailbox snapshot structure and free the VF counter array.
0521  */
0522 void ice_mbx_deinit_snapshot(struct ice_hw *hw)
0523 {
0524     struct ice_mbx_snapshot *snap = &hw->mbx_snapshot;
0525 
0526     /* Free VF counter array and reset VF counter length */
0527     devm_kfree(ice_hw_to_dev(hw), snap->mbx_vf.vf_cntr);
0528     snap->mbx_vf.vfcntr_len = 0;
0529 
0530     /* Clear mbx_buf in the mailbox snaphot structure */
0531     memset(&snap->mbx_buf, 0, sizeof(snap->mbx_buf));
0532 }