| From 4a2bbdfd03b50a288a38f01f2b0c060e7793e4a3 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 20 Aug 2018 08:12:29 -0700 |
| Subject: i40evf: Validate the number of queues a PF sends |
| |
| From: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com> |
| |
| [ Upstream commit 3c818910911c93bb5099c6637ec350f90c0e71fc ] |
| |
| A PF can send any number of queues to the VF and the VF may not |
| be able to support that many. Check to see that the number of |
| queues is less than or equal to the max number of queues the |
| VF can have. |
| |
| Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com> |
| Tested-by: Andrew Bowers <andrewx.bowers@intel.com> |
| Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../ethernet/intel/i40evf/i40evf_virtchnl.c | 32 +++++++++++++++++++ |
| 1 file changed, 32 insertions(+) |
| |
| diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c |
| index 565677de5ba37..94dabc9d89f73 100644 |
| --- a/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c |
| +++ b/drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c |
| @@ -153,6 +153,32 @@ int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter) |
| NULL, 0); |
| } |
| |
| +/** |
| + * i40evf_validate_num_queues |
| + * @adapter: adapter structure |
| + * |
| + * Validate that the number of queues the PF has sent in |
| + * VIRTCHNL_OP_GET_VF_RESOURCES is not larger than the VF can handle. |
| + **/ |
| +static void i40evf_validate_num_queues(struct i40evf_adapter *adapter) |
| +{ |
| + if (adapter->vf_res->num_queue_pairs > I40EVF_MAX_REQ_QUEUES) { |
| + struct virtchnl_vsi_resource *vsi_res; |
| + int i; |
| + |
| + dev_info(&adapter->pdev->dev, "Received %d queues, but can only have a max of %d\n", |
| + adapter->vf_res->num_queue_pairs, |
| + I40EVF_MAX_REQ_QUEUES); |
| + dev_info(&adapter->pdev->dev, "Fixing by reducing queues to %d\n", |
| + I40EVF_MAX_REQ_QUEUES); |
| + adapter->vf_res->num_queue_pairs = I40EVF_MAX_REQ_QUEUES; |
| + for (i = 0; i < adapter->vf_res->num_vsis; i++) { |
| + vsi_res = &adapter->vf_res->vsi_res[i]; |
| + vsi_res->num_queue_pairs = I40EVF_MAX_REQ_QUEUES; |
| + } |
| + } |
| +} |
| + |
| /** |
| * i40evf_get_vf_config |
| * @adapter: private adapter structure |
| @@ -195,6 +221,11 @@ int i40evf_get_vf_config(struct i40evf_adapter *adapter) |
| err = (i40e_status)le32_to_cpu(event.desc.cookie_low); |
| memcpy(adapter->vf_res, event.msg_buf, min(event.msg_len, len)); |
| |
| + /* some PFs send more queues than we should have so validate that |
| + * we aren't getting too many queues |
| + */ |
| + if (!err) |
| + i40evf_validate_num_queues(adapter); |
| i40e_vf_parse_hw_config(hw, adapter->vf_res); |
| out_alloc: |
| kfree(event.msg_buf); |
| @@ -1329,6 +1360,7 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, |
| I40E_MAX_VF_VSI * |
| sizeof(struct virtchnl_vsi_resource); |
| memcpy(adapter->vf_res, msg, min(msglen, len)); |
| + i40evf_validate_num_queues(adapter); |
| i40e_vf_parse_hw_config(&adapter->hw, adapter->vf_res); |
| /* restore current mac address */ |
| ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr); |
| -- |
| 2.20.1 |
| |