i40e/i40evf: don't trust VF to reset itself
When using 'ethtool -L' on a VF to change number of requested queues from PF, we shouldn't trust the VF to reset itself after making the request. Doing it that way opens the door for a potentially malicious VF to do nasty things to the PF which should never be the case. This makes it such that after VF makes a successful request, PF will then reset the VF to institute required changes. Only if the request fails will PF send a message back to VF letting it know the request was unsuccessful. Testing-hints: There should be no real functional changes. This is simply hardening against a potentially malicious VF. Signed-off-by: Alan Brady <alan.brady@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Родитель
8fdb69dd38
Коммит
17a9422de7
|
@ -2045,8 +2045,9 @@ error_param:
|
||||||
* @msglen: msg length
|
* @msglen: msg length
|
||||||
*
|
*
|
||||||
* VFs get a default number of queues but can use this message to request a
|
* VFs get a default number of queues but can use this message to request a
|
||||||
* different number. Will respond with either the number requested or the
|
* different number. If the request is successful, PF will reset the VF and
|
||||||
* maximum we can support.
|
* return 0. If unsuccessful, PF will send message informing VF of number of
|
||||||
|
* available queues and return result of sending VF a message.
|
||||||
**/
|
**/
|
||||||
static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
|
static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
|
||||||
{
|
{
|
||||||
|
@ -2077,7 +2078,11 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg, int msglen)
|
||||||
pf->queues_left);
|
pf->queues_left);
|
||||||
vfres->num_queue_pairs = pf->queues_left + cur_pairs;
|
vfres->num_queue_pairs = pf->queues_left + cur_pairs;
|
||||||
} else {
|
} else {
|
||||||
|
/* successful request */
|
||||||
vf->num_req_queues = req_pairs;
|
vf->num_req_queues = req_pairs;
|
||||||
|
i40e_vc_notify_vf_reset(vf);
|
||||||
|
i40e_reset_vf(vf, false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,
|
return i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_REQUEST_QUEUES, 0,
|
||||||
|
|
|
@ -407,6 +407,7 @@ int i40evf_request_queues(struct i40evf_adapter *adapter, int num)
|
||||||
vfres.num_queue_pairs = num;
|
vfres.num_queue_pairs = num;
|
||||||
|
|
||||||
adapter->current_op = VIRTCHNL_OP_REQUEST_QUEUES;
|
adapter->current_op = VIRTCHNL_OP_REQUEST_QUEUES;
|
||||||
|
adapter->flags |= I40EVF_FLAG_REINIT_ITR_NEEDED;
|
||||||
return i40evf_send_pf_msg(adapter, VIRTCHNL_OP_REQUEST_QUEUES,
|
return i40evf_send_pf_msg(adapter, VIRTCHNL_OP_REQUEST_QUEUES,
|
||||||
(u8 *)&vfres, sizeof(vfres));
|
(u8 *)&vfres, sizeof(vfres));
|
||||||
}
|
}
|
||||||
|
@ -1098,15 +1099,13 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
|
||||||
case VIRTCHNL_OP_REQUEST_QUEUES: {
|
case VIRTCHNL_OP_REQUEST_QUEUES: {
|
||||||
struct virtchnl_vf_res_request *vfres =
|
struct virtchnl_vf_res_request *vfres =
|
||||||
(struct virtchnl_vf_res_request *)msg;
|
(struct virtchnl_vf_res_request *)msg;
|
||||||
if (vfres->num_queue_pairs == adapter->num_req_queues) {
|
if (vfres->num_queue_pairs != adapter->num_req_queues) {
|
||||||
adapter->flags |= I40EVF_FLAG_REINIT_ITR_NEEDED;
|
|
||||||
i40evf_schedule_reset(adapter);
|
|
||||||
} else {
|
|
||||||
dev_info(&adapter->pdev->dev,
|
dev_info(&adapter->pdev->dev,
|
||||||
"Requested %d queues, PF can support %d\n",
|
"Requested %d queues, PF can support %d\n",
|
||||||
adapter->num_req_queues,
|
adapter->num_req_queues,
|
||||||
vfres->num_queue_pairs);
|
vfres->num_queue_pairs);
|
||||||
adapter->num_req_queues = 0;
|
adapter->num_req_queues = 0;
|
||||||
|
adapter->flags &= ~I40EVF_FLAG_REINIT_ITR_NEEDED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -333,8 +333,8 @@ struct virtchnl_vsi_queue_config_info {
|
||||||
* additional queues must be negotiated. This is a best effort request as it
|
* additional queues must be negotiated. This is a best effort request as it
|
||||||
* is possible the PF does not have enough queues left to support the request.
|
* is possible the PF does not have enough queues left to support the request.
|
||||||
* If the PF cannot support the number requested it will respond with the
|
* If the PF cannot support the number requested it will respond with the
|
||||||
* maximum number it is able to support; otherwise it will respond with the
|
* maximum number it is able to support. If the request is successful, PF will
|
||||||
* number requested.
|
* then reset the VF to institute required changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* VF resource request */
|
/* VF resource request */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче