diff mbox series

[net-next] i40e: fix VF queue mapping collision with PF queue 0

Message ID 178946707899.849053.3626754711268331752@bigrain
State Under Review
Delegated to: Anthony Nguyen
Headers show
Series [net-next] i40e: fix VF queue mapping collision with PF queue 0 | expand

Commit Message

Tian Run Sept. 15, 2026, 10:11 a.m. UTC
i40e_vsi_setup() limits the queue pairs of an SRIOV VSI to
pf->num_lan_msix and fills info.queue_mapping[] only for that many
entries, leaving the rest zeroed. i40e_vc_get_pf_queue_id() resolves
such an entry to absolute queue 0, which belongs to the PF itself.

i40e_config_vsi_tx_queue() then overwrites the PF's queue 0 context
with the VF's ring and re-programs QTX_CTL(0) into VF mode. The PF's
next transmit on queue 0 wedges the queue: the device stops it,
reports a Malicious Driver Detection event without a valid event ID,
sets both PF_MDET_TX and VP_MDET_TX and the PF enters a NETDEV
WATCHDOG / reset loop.

alloc_queue_pairs is set to pf->num_vf_qps, so GET_VF_RESOURCES
advertises the full count and a VF with more online CPUs than the
PF's num_lan_msix (e.g. a 4-CPU guest on a 3-CPU host) configures
the extra queue pair and hits the unprogrammed mapping entry.

Clamp alloc_queue_pairs by num_lan_msix like i40e_vsi_setup() does,
so the VF is only offered queue pairs whose mapping was programmed.

Fixes: 1563f2d2e012 ("i40e: Do not allow use more TC queue pairs than MSI-X vectors exist")
Signed-off-by: Tian Run <15503232150@163.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Romanowski, Rafal Oct. 6, 2026, 8:04 a.m. UTC | #1
> -----Original Message-----
> From: Tian Run <15503232150@163.com>
> Sent: Tuesday, September 15, 2026 12:11 PM
> To: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org
> Cc: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> David S.Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; linux-
> kernel@vger.kernel.org
> Subject: [PATCH net-next] i40e: fix VF queue mapping collision with PF queue 0
> 
> i40e_vsi_setup() limits the queue pairs of an SRIOV VSI to
> pf->num_lan_msix and fills info.queue_mapping[] only for that many
> entries, leaving the rest zeroed. i40e_vc_get_pf_queue_id() resolves such an
> entry to absolute queue 0, which belongs to the PF itself.
> 
> i40e_config_vsi_tx_queue() then overwrites the PF's queue 0 context with the
> VF's ring and re-programs QTX_CTL(0) into VF mode. The PF's next transmit on
> queue 0 wedges the queue: the device stops it, reports a Malicious Driver
> Detection event without a valid event ID, sets both PF_MDET_TX and
> VP_MDET_TX and the PF enters a NETDEV WATCHDOG / reset loop.
> 
> alloc_queue_pairs is set to pf->num_vf_qps, so GET_VF_RESOURCES advertises
> the full count and a VF with more online CPUs than the PF's num_lan_msix (e.g. a
> 4-CPU guest on a 3-CPU host) configures the extra queue pair and hits the
> unprogrammed mapping entry.
> 
> Clamp alloc_queue_pairs by num_lan_msix like i40e_vsi_setup() does, so the VF
> is only offered queue pairs whose mapping was programmed.
> 
> Fixes: 1563f2d2e012 ("i40e: Do not allow use more TC queue pairs than MSI-X
> vectors exist")
> Signed-off-by: Tian Run <15503232150@163.com>
> ---
>  drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index abbc71e81..2934862da 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -11443,6 +11443,12 @@ static int i40e_set_num_rings_in_vsi(struct
> i40e_vsi *vsi)
> 
>  	case I40E_VSI_SRIOV:
>  		vsi->alloc_queue_pairs = pf->num_vf_qps;
> +		/* i40e_vsi_setup() limits queue pairs to num_lan_msix;
> +		 * keep alloc_queue_pairs consistent with that limit.
> +		 */
> +		if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
> +			vsi->alloc_queue_pairs =
> +				min_t(u16, pf->num_vf_qps, pf-
> >num_lan_msix);
>  		if (!vsi->num_tx_desc)
>  			vsi->num_tx_desc =
> ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
> 
> I40E_REQ_DESCRIPTOR_MULTIPLE);
> --
> 2.43.0


Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Romanowski, Rafal Oct. 6, 2026, 8:11 a.m. UTC | #2
> -----Original Message-----
> From: Tian Run <15503232150@163.com>
> Sent: Tuesday, September 15, 2026 12:11 PM
> To: intel-wired-lan@lists.osuosl.org; netdev@vger.kernel.org
> Cc: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Andrew Lunn <andrew+netdev@lunn.ch>;
> David S.Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; linux-
> kernel@vger.kernel.org
> Subject: [PATCH net-next] i40e: fix VF queue mapping collision with PF queue 0
> 
> i40e_vsi_setup() limits the queue pairs of an SRIOV VSI to
> pf->num_lan_msix and fills info.queue_mapping[] only for that many
> entries, leaving the rest zeroed. i40e_vc_get_pf_queue_id() resolves such an
> entry to absolute queue 0, which belongs to the PF itself.
> 
> i40e_config_vsi_tx_queue() then overwrites the PF's queue 0 context with the
> VF's ring and re-programs QTX_CTL(0) into VF mode. The PF's next transmit on
> queue 0 wedges the queue: the device stops it, reports a Malicious Driver
> Detection event without a valid event ID, sets both PF_MDET_TX and
> VP_MDET_TX and the PF enters a NETDEV WATCHDOG / reset loop.
> 
> alloc_queue_pairs is set to pf->num_vf_qps, so GET_VF_RESOURCES advertises
> the full count and a VF with more online CPUs than the PF's num_lan_msix (e.g. a
> 4-CPU guest on a 3-CPU host) configures the extra queue pair and hits the
> unprogrammed mapping entry.
> 
> Clamp alloc_queue_pairs by num_lan_msix like i40e_vsi_setup() does, so the VF
> is only offered queue pairs whose mapping was programmed.
> 
> Fixes: 1563f2d2e012 ("i40e: Do not allow use more TC queue pairs than MSI-X
> vectors exist")
> Signed-off-by: Tian Run <15503232150@163.com>
> ---
>  drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c
> b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index abbc71e81..2934862da 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -11443,6 +11443,12 @@ static int i40e_set_num_rings_in_vsi(struct
> i40e_vsi *vsi)
> 
>  	case I40E_VSI_SRIOV:
>  		vsi->alloc_queue_pairs = pf->num_vf_qps;
> +		/* i40e_vsi_setup() limits queue pairs to num_lan_msix;
> +		 * keep alloc_queue_pairs consistent with that limit.
> +		 */
> +		if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
> +			vsi->alloc_queue_pairs =
> +				min_t(u16, pf->num_vf_qps, pf-
> >num_lan_msix);
>  		if (!vsi->num_tx_desc)
>  			vsi->num_tx_desc =
> ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
> 
> I40E_REQ_DESCRIPTOR_MULTIPLE);
> --
> 2.43.0


Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index abbc71e81..2934862da 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -11443,6 +11443,12 @@  static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
 
 	case I40E_VSI_SRIOV:
 		vsi->alloc_queue_pairs = pf->num_vf_qps;
+		/* i40e_vsi_setup() limits queue pairs to num_lan_msix;
+		 * keep alloc_queue_pairs consistent with that limit.
+		 */
+		if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
+			vsi->alloc_queue_pairs =
+				min_t(u16, pf->num_vf_qps, pf->num_lan_msix);
 		if (!vsi->num_tx_desc)
 			vsi->num_tx_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
 						 I40E_REQ_DESCRIPTOR_MULTIPLE);