| From f2c3c1251760aa0fb553f98c6ff442d35100226b Mon Sep 17 00:00:00 2001 |
| From: Brett Creeley <brett.creeley@intel.com> |
| Date: Wed, 13 Nov 2019 11:28:17 -0800 |
| Subject: [PATCH] i40e: Fix virtchnl_queue_select bitmap validation |
| |
| commit d9d6a9aed3f66f8ce5fa3ca6ca26007d75032296 upstream. |
| |
| Currently in i40e_vc_disable_queues_msg() we are incorrectly |
| validating the virtchnl queue select bitmaps. The |
| virtchnl_queue_select rx_queues and tx_queue bitmap is being |
| compared against ICE_MAX_VF_QUEUES, but the problem is that |
| these bitmaps can have a value greater than I40E_MAX_VF_QUEUES. |
| Fix this by comparing the bitmaps against BIT(I40E_MAX_VF_QUEUES). |
| |
| Also, add the function i40e_vc_validate_vqs_bitmaps() that checks to see |
| if both virtchnl_queue_select bitmaps are empty along with checking that |
| the bitmaps only have valid bits set. This function can then be used in |
| both the queue enable and disable flows. |
| |
| Suggested-by: Arkady Gilinksky <arkady.gilinsky@harmonicinc.com> |
| Signed-off-by: Brett Creeley <brett.creeley@intel.com> |
| Tested-by: Andrew Bowers <andrewx.bowers@intel.com> |
| Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
| index 479bc60c8f71..a49da7261758 100644 |
| --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
| +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c |
| @@ -2307,6 +2307,22 @@ static int i40e_ctrl_vf_rx_rings(struct i40e_vsi *vsi, unsigned long q_map, |
| } |
| |
| /** |
| + * i40e_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTHCHNL |
| + * @vqs: virtchnl_queue_select structure containing bitmaps to validate |
| + * |
| + * Returns true if validation was successful, else false. |
| + */ |
| +static bool i40e_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs) |
| +{ |
| + if ((!vqs->rx_queues && !vqs->tx_queues) || |
| + vqs->rx_queues >= BIT(I40E_MAX_VF_QUEUES) || |
| + vqs->tx_queues >= BIT(I40E_MAX_VF_QUEUES)) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +/** |
| * i40e_vc_enable_queues_msg |
| * @vf: pointer to the VF info |
| * @msg: pointer to the msg buffer |
| @@ -2332,7 +2348,7 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg) |
| goto error_param; |
| } |
| |
| - if ((0 == vqs->rx_queues) && (0 == vqs->tx_queues)) { |
| + if (i40e_vc_validate_vqs_bitmaps(vqs)) { |
| aq_ret = I40E_ERR_PARAM; |
| goto error_param; |
| } |
| @@ -2389,9 +2405,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) |
| goto error_param; |
| } |
| |
| - if ((vqs->rx_queues == 0 && vqs->tx_queues == 0) || |
| - vqs->rx_queues > I40E_MAX_VF_QUEUES || |
| - vqs->tx_queues > I40E_MAX_VF_QUEUES) { |
| + if (i40e_vc_validate_vqs_bitmaps(vqs)) { |
| aq_ret = I40E_ERR_PARAM; |
| goto error_param; |
| } |
| -- |
| 2.7.4 |
| |