@@ -93,36 +93,31 @@ u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
93
93
*
94
94
* 2. When the caller starts processing its mailbox queue in response to an
95
95
* interrupt, the structure ice_mbx_snapshot is expected to be cleared before
96
- * the algorithm can be run for the first time for that interrupt. This can be
97
- * done via ice_mbx_reset_snapshot().
96
+ * the algorithm can be run for the first time for that interrupt. This
97
+ * requires calling ice_mbx_reset_snapshot() as well as calling
98
+ * ice_mbx_reset_vf_info() for each VF tracking structure.
98
99
*
99
100
* 3. For every message read by the caller from the MBX Queue, the caller must
100
101
* call the detection algorithm's entry function ice_mbx_vf_state_handler().
101
102
* Before every call to ice_mbx_vf_state_handler() the struct ice_mbx_data is
102
103
* filled as it is required to be passed to the algorithm.
103
104
*
104
- * 4. Every time a message is read from the MBX queue, a VFId is received which
105
- * is passed to the state handler. The boolean output is_malvf of the state
106
- * handler ice_mbx_vf_state_handler() serves as an indicator to the caller
107
- * whether this VF is malicious or not.
105
+ * 4. Every time a message is read from the MBX queue, a tracking structure
106
+ * for the VF must be passed to the state handler. The boolean output
107
+ * report_malvf from ice_mbx_vf_state_handler() serves as an indicator to the
108
+ * caller whether it must report this VF as malicious or not.
108
109
*
109
110
* 5. When a VF is identified to be malicious, the caller can send a message
110
- * to the system administrator. The caller can invoke ice_mbx_report_malvf()
111
- * to help determine if a malicious VF is to be reported or not. This function
112
- * requires the caller to maintain a global bitmap to track all malicious VFs
113
- * and pass that to ice_mbx_report_malvf() along with the VFID which was identified
114
- * to be malicious by ice_mbx_vf_state_handler().
111
+ * to the system administrator.
115
112
*
116
- * 6. The global bitmap maintained by PF can be cleared completely if PF is in
117
- * reset or the bit corresponding to a VF can be cleared if that VF is in reset.
118
- * When a VF is shut down and brought back up, we assume that the new VF
119
- * brought up is not malicious and hence report it if found malicious.
113
+ * 6. The PF is responsible for maintaining the struct ice_mbx_vf_info
114
+ * structure for each VF. The PF should clear the VF tracking structure if the
115
+ * VF is reset. When a VF is shut down and brought back up, we will then
116
+ * assume that the new VF is not malicious and may report it again if we
117
+ * detect it again.
120
118
*
121
119
* 7. The function ice_mbx_reset_snapshot() is called to reset the information
122
120
* in ice_mbx_snapshot for every new mailbox interrupt handled.
123
- *
124
- * 8. The memory allocated for variables in ice_mbx_snapshot is de-allocated
125
- * when driver is unloaded.
126
121
*/
127
122
#define ICE_RQ_DATA_MASK (rq_data ) ((rq_data) & PF_MBX_ARQH_ARQH_M)
128
123
/* Using the highest value for an unsigned 16-bit value 0xFFFF to indicate that
@@ -132,26 +127,21 @@ u32 ice_conv_link_speed_to_virtchnl(bool adv_link_support, u16 link_speed)
132
127
133
128
/**
134
129
* ice_mbx_reset_snapshot - Reset mailbox snapshot structure
135
- * @snap: pointer to mailbox snapshot structure in the ice_hw struct
136
- *
137
- * Reset the mailbox snapshot structure and clear VF counter array.
130
+ * @snap: pointer to the mailbox snapshot
138
131
*/
139
132
static void ice_mbx_reset_snapshot (struct ice_mbx_snapshot * snap )
140
133
{
141
- u32 vfcntr_len ;
142
-
143
- if (!snap || !snap -> mbx_vf .vf_cntr )
144
- return ;
134
+ struct ice_mbx_vf_info * vf_info ;
145
135
146
- /* Clear VF counters. */
147
- vfcntr_len = snap -> mbx_vf .vfcntr_len ;
148
- if (vfcntr_len )
149
- memset (snap -> mbx_vf .vf_cntr , 0 ,
150
- (vfcntr_len * sizeof (* snap -> mbx_vf .vf_cntr )));
151
-
152
- /* Reset mailbox snapshot for a new capture. */
136
+ /* Clear mbx_buf in the mailbox snaphot structure and setting the
137
+ * mailbox snapshot state to a new capture.
138
+ */
153
139
memset (& snap -> mbx_buf , 0 , sizeof (snap -> mbx_buf ));
154
140
snap -> mbx_buf .state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT ;
141
+
142
+ /* Reset message counts for all VFs to zero */
143
+ list_for_each_entry (vf_info , & snap -> mbx_vf , list_entry )
144
+ vf_info -> msg_count = 0 ;
155
145
}
156
146
157
147
/**
@@ -195,7 +185,7 @@ ice_mbx_traverse(struct ice_hw *hw,
195
185
/**
196
186
* ice_mbx_detect_malvf - Detect malicious VF in snapshot
197
187
* @hw: pointer to the HW struct
198
- * @vf_id: relative virtual function ID
188
+ * @vf_info: mailbox tracking structure for a VF
199
189
* @new_state: new algorithm state
200
190
* @is_malvf: boolean output to indicate if VF is malicious
201
191
*
@@ -204,19 +194,14 @@ ice_mbx_traverse(struct ice_hw *hw,
204
194
* the permissible number of messages to send.
205
195
*/
206
196
static int
207
- ice_mbx_detect_malvf (struct ice_hw * hw , u16 vf_id ,
197
+ ice_mbx_detect_malvf (struct ice_hw * hw , struct ice_mbx_vf_info * vf_info ,
208
198
enum ice_mbx_snapshot_state * new_state ,
209
199
bool * is_malvf )
210
200
{
211
- struct ice_mbx_snapshot * snap = & hw -> mbx_snapshot ;
201
+ /* increment the message count for this VF */
202
+ vf_info -> msg_count ++ ;
212
203
213
- if (vf_id >= snap -> mbx_vf .vfcntr_len )
214
- return - EIO ;
215
-
216
- /* increment the message count in the VF array */
217
- snap -> mbx_vf .vf_cntr [vf_id ]++ ;
218
-
219
- if (snap -> mbx_vf .vf_cntr [vf_id ] >= ICE_ASYNC_VF_MSG_THRESHOLD )
204
+ if (vf_info -> msg_count >= ICE_ASYNC_VF_MSG_THRESHOLD )
220
205
* is_malvf = true;
221
206
222
207
/* continue to iterate through the mailbox snapshot */
@@ -229,7 +214,7 @@ ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,
229
214
* ice_mbx_vf_state_handler - Handle states of the overflow algorithm
230
215
* @hw: pointer to the HW struct
231
216
* @mbx_data: pointer to structure containing mailbox data
232
- * @vf_id: relative virtual function (VF) ID
217
+ * @vf_info: mailbox tracking structure for the VF in question
233
218
* @is_malvf: boolean output to indicate if VF is malicious
234
219
*
235
220
* The function serves as an entry point for the malicious VF
@@ -250,7 +235,8 @@ ice_mbx_detect_malvf(struct ice_hw *hw, u16 vf_id,
250
235
*/
251
236
int
252
237
ice_mbx_vf_state_handler (struct ice_hw * hw ,
253
- struct ice_mbx_data * mbx_data , u16 vf_id ,
238
+ struct ice_mbx_data * mbx_data ,
239
+ struct ice_mbx_vf_info * vf_info ,
254
240
bool * is_malvf )
255
241
{
256
242
struct ice_mbx_snapshot * snap = & hw -> mbx_snapshot ;
@@ -315,7 +301,8 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,
315
301
if (snap_buf -> num_pending_arq >=
316
302
mbx_data -> async_watermark_val ) {
317
303
new_state = ICE_MAL_VF_DETECT_STATE_DETECT ;
318
- status = ice_mbx_detect_malvf (hw , vf_id , & new_state , is_malvf );
304
+ status = ice_mbx_detect_malvf (hw , vf_info , & new_state ,
305
+ is_malvf );
319
306
} else {
320
307
new_state = ICE_MAL_VF_DETECT_STATE_TRAVERSE ;
321
308
ice_mbx_traverse (hw , & new_state );
@@ -329,7 +316,8 @@ ice_mbx_vf_state_handler(struct ice_hw *hw,
329
316
330
317
case ICE_MAL_VF_DETECT_STATE_DETECT :
331
318
new_state = ICE_MAL_VF_DETECT_STATE_DETECT ;
332
- status = ice_mbx_detect_malvf (hw , vf_id , & new_state , is_malvf );
319
+ status = ice_mbx_detect_malvf (hw , vf_info , & new_state ,
320
+ is_malvf );
333
321
break ;
334
322
335
323
default :
@@ -367,90 +355,49 @@ ice_mbx_report_malvf(struct ice_hw *hw, struct ice_mbx_vf_info *vf_info,
367
355
}
368
356
369
357
/**
370
- * ice_mbx_clear_malvf - Clear VF bitmap and counter for VF ID
371
- * @snap: pointer to the mailbox snapshot structure
372
- * @vf_id: relative virtual function ID of the malicious VF
373
- * @vf_info: mailbox tracking structure for this VF
358
+ * ice_mbx_clear_malvf - Clear VF mailbox info
359
+ * @vf_info: the mailbox tracking structure for a VF
374
360
*
375
- * In case of a VF reset, this function shall be called to clear the VF's
376
- * current mailbox tracking state.
377
- */
378
- void
379
- ice_mbx_clear_malvf (struct ice_mbx_snapshot * snap , u16 vf_id ,
380
- struct ice_mbx_vf_info * vf_info )
361
+ * In case of a VF reset, this function shall be called to clear the VF's
362
+ * current mailbox tracking state.
363
+ */
364
+ void ice_mbx_clear_malvf (struct ice_mbx_vf_info * vf_info )
381
365
{
382
- if (WARN_ON (!snap ))
383
- return ;
384
-
385
- /* Ensure VF ID value is not larger than bitmap or VF counter length */
386
- if (WARN_ON (vf_id >= snap -> mbx_vf .vfcntr_len ))
387
- return ;
388
-
389
366
vf_info -> malicious = 0 ;
390
-
391
- /* Clear the VF counter in the mailbox snapshot structure for that VF ID.
392
- * This is to ensure that if a VF is unloaded and a new one brought back
393
- * up with the same VF ID for a snapshot currently in traversal or detect
394
- * state the counter for that VF ID does not increment on top of existing
395
- * values in the mailbox overflow detection algorithm.
396
- */
397
- snap -> mbx_vf .vf_cntr [vf_id ] = 0 ;
367
+ vf_info -> msg_count = 0 ;
398
368
}
399
369
400
370
/**
401
371
* ice_mbx_init_vf_info - Initialize a new VF mailbox tracking info
402
372
* @hw: pointer to the hardware structure
403
373
* @vf_info: the mailbox tracking info structure for a VF
404
374
*
405
- * Initialize a VF mailbox tracking info structure.
375
+ * Initialize a VF mailbox tracking info structure and insert it into the
376
+ * snapshot list.
377
+ *
378
+ * If you remove the VF, you must also delete the associated VF info structure
379
+ * from the linked list.
406
380
*/
407
381
void ice_mbx_init_vf_info (struct ice_hw * hw , struct ice_mbx_vf_info * vf_info )
408
382
{
409
- vf_info -> malicious = 0 ;
383
+ struct ice_mbx_snapshot * snap = & hw -> mbx_snapshot ;
384
+
385
+ ice_mbx_clear_malvf (vf_info );
386
+ list_add (& vf_info -> list_entry , & snap -> mbx_vf );
410
387
}
411
388
412
389
/**
413
- * ice_mbx_init_snapshot - Initialize mailbox snapshot structure
390
+ * ice_mbx_init_snapshot - Initialize mailbox snapshot data
414
391
* @hw: pointer to the hardware structure
415
- * @vf_count: number of VFs allocated on a PF
416
- *
417
- * Clear the mailbox snapshot structure and allocate memory
418
- * for the VF counter array based on the number of VFs allocated
419
- * on that PF.
420
392
*
421
- * Assumption: This function will assume ice_get_caps() has already been
422
- * called to ensure that the vf_count can be compared against the number
423
- * of VFs supported as defined in the functional capabilities of the device.
393
+ * Clear the mailbox snapshot structure and initialize the VF mailbox list.
424
394
*/
425
- int ice_mbx_init_snapshot (struct ice_hw * hw , u16 vf_count )
395
+ void ice_mbx_init_snapshot (struct ice_hw * hw )
426
396
{
427
397
struct ice_mbx_snapshot * snap = & hw -> mbx_snapshot ;
428
398
429
- /* Ensure that the number of VFs allocated is non-zero and
430
- * is not greater than the number of supported VFs defined in
431
- * the functional capabilities of the PF.
432
- */
433
- if (!vf_count || vf_count > hw -> func_caps .num_allocd_vfs )
434
- return - EINVAL ;
435
-
436
- snap -> mbx_vf .vf_cntr = devm_kcalloc (ice_hw_to_dev (hw ), vf_count ,
437
- sizeof (* snap -> mbx_vf .vf_cntr ),
438
- GFP_KERNEL );
439
- if (!snap -> mbx_vf .vf_cntr )
440
- return - ENOMEM ;
441
-
442
- /* Setting the VF counter length to the number of allocated
443
- * VFs for given PF's functional capabilities.
444
- */
445
- snap -> mbx_vf .vfcntr_len = vf_count ;
446
-
447
- /* Clear mbx_buf in the mailbox snaphot structure and setting the
448
- * mailbox snapshot state to a new capture.
449
- */
450
- memset (& snap -> mbx_buf , 0 , sizeof (snap -> mbx_buf ));
451
- snap -> mbx_buf .state = ICE_MAL_VF_DETECT_STATE_NEW_SNAPSHOT ;
452
-
453
- return 0 ;
399
+ INIT_LIST_HEAD (& snap -> mbx_vf );
400
+ ice_mbx_reset_snapshot (snap );
454
401
}
455
402
456
403
/**
@@ -463,10 +410,6 @@ void ice_mbx_deinit_snapshot(struct ice_hw *hw)
463
410
{
464
411
struct ice_mbx_snapshot * snap = & hw -> mbx_snapshot ;
465
412
466
- /* Free VF counter array and reset VF counter length */
467
- devm_kfree (ice_hw_to_dev (hw ), snap -> mbx_vf .vf_cntr );
468
- snap -> mbx_vf .vfcntr_len = 0 ;
469
-
470
413
/* Clear mbx_buf in the mailbox snaphot structure */
471
414
memset (& snap -> mbx_buf , 0 , sizeof (snap -> mbx_buf ));
472
415
}
0 commit comments