![]() |
|
|||
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 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |