VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46084

CVE-2026-46084

Description

In the Linux kernel, the following vulnerability has been resolved:

RDMA/mana_ib: Disable RX steering on RSS QP destroy

When an RSS QP is destroyed (e.g. DPDK exit), mana_ib_destroy_qp_rss() destroys the RX WQ objects but does not disable vPort RX steering in firmware. This leaves stale steering configuration that still points to the destroyed RX objects.

If traffic continues to arrive (e.g. peer VM is still transmitting) and the VF interface is subsequently brought up (mana_open), the firmware may deliver completions using stale CQ IDs from the old RX objects. These CQ IDs can be reused by the ethernet driver for new TX CQs, causing RX completions to land on TX CQs:

WARNING: mana_poll_tx_cq+0x1b8/0x220 [mana] (is_sq == false) WARNING: mana_gd_process_eq_events+0x209/0x290 (cq_table lookup fails)

Fix this by disabling vPort RX steering before destroying RX WQ objects. Note that mana_fence_rqs() cannot be used here because the fence completion is delivered on the CQ, which is polled by user-mode (e.g. DPDK) and not visible to the kernel driver.

Refactor the disable logic into a shared mana_disable_vport_rx() in mana_en, exported for use by mana_ib, replacing the duplicate code. The ethernet driver's mana_dealloc_queues() is also updated to call this common function.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In the Linux kernel, mana_ib fails to disable vPort RX steering when destroying an RSS QP, enabling stale CQ reuse and a crash.

Vulnerability

In the Linux kernel, the mana_ib driver's mana_ib_destroy_qp_rss() function destroys RX work queue (WQ) objects without first disabling vPort RX steering in firmware. This leaves stale steering configuration pointing to the destroyed RX objects. The bug affects all versions including the fix commit [1].

Exploitation

An attacker must arrange for traffic to continue arriving (e.g., from a peer VM) after the RSS QP is destroyed, and then have the VF interface brought up (mana_open). The firmware may deliver completions using stale completion queue (CQ) IDs from the old RX objects, which can be reused by the ethernet driver for new TX CQs. This causes RX completions to be processed on TX CQs, triggering warnings (mana_poll_tx_cq with is_sq == false) and a lookup failure in mana_gd_process_eq_events [1].

Impact

A local attacker with the ability to trigger RSS QP destruction (e.g., via DPDK exit) and subsequent network interface activation can cause a system crash or denial of service due to mismatched CQ processing. The vulnerability leads to kernel warnings and potentially an invalid CQ table lookup, which can halt the system [1].

Mitigation

The fix is included in Linux kernel commit 6a2d6273b6c3 (stable series). Users should update to a kernel version containing this commit. No workaround is provided in the available references [1].

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

10
3be5ed233de0

RDMA/mana_ib: Disable RX steering on RSS QP destroy

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLong LiMar 25, 2026Fixed in 7.0.4via kernel-cna
3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 82f84f7ad37a90..c8a7129bbad558 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -822,6 +822,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 09a53c97754550..6d87533924fa8f 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2889,6 +2889,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3273,10 +3280,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index a078af283bddbb..743bfa8ad8e368 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -568,6 +568,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
8ba804869382

RDMA/mana_ib: Disable RX steering on RSS QP destroy

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLong LiMar 25, 2026Fixed in 6.18.27via kernel-cna
3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 48c1f4977f218e..960878b53da851 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -823,6 +823,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 729133c1e5e4f9..abb207339992bb 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2766,6 +2766,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3150,10 +3157,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index 0921485565c051..857f45a3386cc7 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -554,6 +554,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
dbeb256e8dd8

RDMA/mana_ib: Disable RX steering on RSS QP destroy

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitLong LiMar 25, 2026Fixed in 7.1-rc1via kernel-cna
3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index f3bb1edc7f79ff..e6fc3cc10795ff 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -799,6 +799,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index dca62fb9a3a9ef..af2a35c0977367 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2882,6 +2882,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3266,10 +3273,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index a078af283bddbb..743bfa8ad8e368 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -568,6 +568,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
f1ccc4d500a0

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 48fef989318b49..84b8666af606c1 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -601,6 +601,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 969dd44303569d..e527139936dee4 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2392,6 +2392,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, NET_MANA);
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -2676,12 +2683,14 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err) {
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     		return err;
     	}
     
    +	mana_fence_rqs(apc);
    +
     	mana_destroy_vport(apc);
     
     	return 0;
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index ac9a4b0bd49bf2..ab10b0cc1dc2d5 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -473,6 +473,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
6a2d6273b6c3

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 4b3b5b274e8498..8009a339bf9ca7 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -449,6 +449,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mc->ports[qp->port - 1];
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index b56a337b1e212f..343f6e879af39e 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2380,6 +2380,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, NET_MANA);
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -2620,12 +2627,14 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err) {
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     		return err;
     	}
     
    +	mana_fence_rqs(apc);
    +
     	mana_destroy_vport(apc);
     
     	return 0;
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index 7892b79854f62e..d716771a7262c6 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -437,6 +437,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
dbeb256e8dd8

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index f3bb1edc7f79ff..e6fc3cc10795ff 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -799,6 +799,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index dca62fb9a3a9ef..af2a35c0977367 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2882,6 +2882,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3266,10 +3273,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index a078af283bddbb..743bfa8ad8e368 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -568,6 +568,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
3be5ed233de0

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 82f84f7ad37a90..c8a7129bbad558 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -822,6 +822,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 09a53c97754550..6d87533924fa8f 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2889,6 +2889,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3273,10 +3280,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index a078af283bddbb..743bfa8ad8e368 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -568,6 +568,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
8ba804869382

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 48c1f4977f218e..960878b53da851 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -823,6 +823,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 729133c1e5e4f9..abb207339992bb 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2766,6 +2766,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, "NET_MANA");
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -3150,10 +3157,12 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err && mana_en_need_log(apc, err))
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     
    +	mana_fence_rqs(apc);
    +
     	/* Even in err case, still need to cleanup the vPort */
     	mana_destroy_vport(apc);
     
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index 0921485565c051..857f45a3386cc7 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -554,6 +554,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
6a2d6273b6c3

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 4b3b5b274e8498..8009a339bf9ca7 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -449,6 +449,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mc->ports[qp->port - 1];
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index b56a337b1e212f..343f6e879af39e 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2380,6 +2380,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, NET_MANA);
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -2620,12 +2627,14 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err) {
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     		return err;
     	}
     
    +	mana_fence_rqs(apc);
    +
     	mana_destroy_vport(apc);
     
     	return 0;
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index 7892b79854f62e..d716771a7262c6 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -437,6 +437,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    
f1ccc4d500a0

RDMA/mana_ib: Disable RX steering on RSS QP destroy

3 files changed · +26 2
  • drivers/infiniband/hw/mana/qp.c+15 0 modified
    diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
    index 48fef989318b49..84b8666af606c1 100644
    --- a/drivers/infiniband/hw/mana/qp.c
    +++ b/drivers/infiniband/hw/mana/qp.c
    @@ -601,6 +601,21 @@ static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
     	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
     	mpc = netdev_priv(ndev);
     
    +	/* Disable vPort RX steering before destroying RX WQ objects.
    +	 * Otherwise firmware still routes traffic to the destroyed queues,
    +	 * which can cause bogus completions on reused CQ IDs when the
    +	 * ethernet driver later creates new queues on mana_open().
    +	 *
    +	 * Unlike the ethernet teardown path, mana_fence_rqs() cannot be
    +	 * used here because the fence completion CQE is delivered on the
    +	 * CQ which is polled by userspace (e.g. DPDK), so there is no way
    +	 * for the kernel to wait for fence completion.
    +	 *
    +	 * This is best effort — if it fails there is not much we can do,
    +	 * and mana_cfg_vport_steering() already logs the error.
    +	 */
    +	mana_disable_vport_rx(mpc);
    +
     	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
     		ibwq = ind_tbl->ind_tbl[i];
     		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
    
  • drivers/net/ethernet/microsoft/mana/mana_en.c+10 1 modified
    diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
    index 969dd44303569d..e527139936dee4 100644
    --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
    +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
    @@ -2392,6 +2392,13 @@ static void mana_rss_table_init(struct mana_port_context *apc)
     			ethtool_rxfh_indir_default(i, apc->num_queues);
     }
     
    +int mana_disable_vport_rx(struct mana_port_context *apc)
    +{
    +	return mana_cfg_vport_steering(apc, TRI_STATE_FALSE, false, false,
    +				       false);
    +}
    +EXPORT_SYMBOL_NS(mana_disable_vport_rx, NET_MANA);
    +
     int mana_config_rss(struct mana_port_context *apc, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab)
     {
    @@ -2676,12 +2683,14 @@ static int mana_dealloc_queues(struct net_device *ndev)
     	 */
     
     	apc->rss_state = TRI_STATE_FALSE;
    -	err = mana_config_rss(apc, TRI_STATE_FALSE, false, false);
    +	err = mana_disable_vport_rx(apc);
     	if (err) {
     		netdev_err(ndev, "Failed to disable vPort: %d\n", err);
     		return err;
     	}
     
    +	mana_fence_rqs(apc);
    +
     	mana_destroy_vport(apc);
     
     	return 0;
    
  • include/net/mana/mana.h+1 1 modified
    diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
    index ac9a4b0bd49bf2..ab10b0cc1dc2d5 100644
    --- a/include/net/mana/mana.h
    +++ b/include/net/mana/mana.h
    @@ -473,6 +473,7 @@ struct mana_port_context {
     netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
     int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
     		    bool update_hash, bool update_tab);
    +int mana_disable_vport_rx(struct mana_port_context *apc);
     
     int mana_alloc_queues(struct net_device *ndev);
     int mana_attach(struct net_device *ndev);
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing firmware vPort RX steering disable before destroying RX WQ objects in RSS QP teardown, leaving stale steering pointing to freed resources."

Attack vector

An attacker who can trigger destruction of an RSS QP (e.g., via DPDK exit) while a peer VM continues transmitting traffic leaves stale firmware steering pointing to destroyed RX objects. When the VF interface is subsequently brought up via `mana_open()`, the firmware may deliver completions using stale CQ IDs from the old RX objects. These CQ IDs can be reused by the ethernet driver for new TX CQs, causing RX completions to land on TX CQs and triggering kernel WARNINGs in `mana_poll_tx_cq` and `mana_gd_process_eq_events` [patch_id=2659833].

Affected code

The bug is in `mana_ib_destroy_qp_rss()` in `drivers/infiniband/hw/mana/qp.c`. The function destroys RX WQ objects without first disabling vPort RX steering in firmware. The fix also refactors the disable logic into a new shared function `mana_disable_vport_rx()` in `drivers/net/ethernet/microsoft/mana/mana_en.c`, exported via `include/net/mana/mana.h`, and updates `mana_dealloc_queues()` to call it as well [patch_id=2659833].

What the fix does

The patch adds a call to `mana_disable_vport_rx(mpc)` at the beginning of `mana_ib_destroy_qp_rss()`, before the loop that destroys RX WQ objects. This tells the firmware to stop routing traffic to the vPort, eliminating the stale steering configuration. A new shared function `mana_disable_vport_rx()` is introduced in `mana_en.c` that wraps `mana_cfg_vport_steering()` with `TRI_STATE_FALSE`, and is exported for use by the RDMA driver. The ethernet driver's `mana_dealloc_queues()` is also updated to call this common function and then `mana_fence_rqs()` after disabling RX, ensuring proper ordering [patch_id=2659833].

Preconditions

  • inputAn RSS QP must be destroyed (e.g., DPDK application exit) without disabling vPort RX steering
  • networkTraffic must continue to arrive at the VF (e.g., from a peer VM) after QP destruction
  • inputThe VF interface must be subsequently brought up via mana_open(), causing the ethernet driver to allocate new CQs that may reuse stale CQ IDs

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.