Patch "wcn36xx: add proper DMA memory barriers in rx path" has been added to the 5.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    wcn36xx: add proper DMA memory barriers in rx path

to the 5.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     wcn36xx-add-proper-dma-memory-barriers-in-rx-path.patch
and it can be found in the queue-5.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 516aae568e42eea7a56643c5dc73c49b75b4eb5f
Author: Benjamin Li <benl@xxxxxxxxxxxx>
Date:   Fri Oct 22 17:15:28 2021 -0700

    wcn36xx: add proper DMA memory barriers in rx path
    
    [ Upstream commit 9bfe38e064af5decba2ffce66a2958ab8b10eaa4 ]
    
    This is essentially exactly following the dma_wmb()/dma_rmb() usage
    instructions in Documentation/memory-barriers.txt.
    
    The theoretical races here are:
    
    1. DXE (the DMA Transfer Engine in the Wi-Fi subsystem) seeing the
    dxe->ctrl & WCN36xx_DXE_CTRL_VLD write before the dxe->dst_addr_l
    write, thus performing DMA into the wrong address.
    
    2. CPU reading dxe->dst_addr_l before DXE unsets dxe->ctrl &
    WCN36xx_DXE_CTRL_VLD. This should generally be harmless since DXE
    doesn't write dxe->dst_addr_l (no risk of freeing the wrong skb).
    
    Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware")
    Signed-off-by: Benjamin Li <benl@xxxxxxxxxxxx>
    Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20211023001528.3077822-1-benl@xxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 0e0bbcd11300b..aff04ef662663 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -606,6 +606,10 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
 	dxe = ctl->desc;
 
 	while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) {
+		/* do not read until we own DMA descriptor */
+		dma_rmb();
+
+		/* read/modify DMA descriptor */
 		skb = ctl->skb;
 		dma_addr = dxe->dst_addr_l;
 		ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC);
@@ -616,9 +620,15 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
 			dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE,
 					DMA_FROM_DEVICE);
 			wcn36xx_rx_skb(wcn, skb);
-		} /* else keep old skb not submitted and use it for rx DMA */
+		}
+		/* else keep old skb not submitted and reuse it for rx DMA
+		 * (dropping the packet that it contained)
+		 */
 
+		/* flush descriptor changes before re-marking as valid */
+		dma_wmb();
 		dxe->ctrl = ctrl;
+
 		ctl = ctl->next;
 		dxe = ctl->desc;
 	}



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux