Message ID | 20200802132949.26788-1-baijiaju@tsinghua.edu.cn |
---|---|
State | New |
Headers | show |
Series | p54: avoid accessing the data mapped to streaming DMA | expand |
Jia-Ju Bai <baijiaju@tsinghua.edu.cn> wrote: > In p54p_tx(), skb->data is mapped to streaming DMA on line 337: > mapping = pci_map_single(..., skb->data, ...); > > Then skb->data is accessed on line 349: > desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; > > This access may cause data inconsistency between CPU cache and hardware. > > To fix this problem, ((struct p54_hdr *)skb->data)->req_id is stored in > a local variable before DMA mapping, and then the driver accesses this > local variable instead of skb->data. > > Cc: <stable@vger.kernel.org> > Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn> > Acked-by: Christian Lamparter <chunkeey@gmail.com> Patch applied to wireless-drivers-next.git, thanks. 478762855b5a p54: avoid accessing the data mapped to streaming DMA
diff --git a/drivers/net/wireless/intersil/p54/p54pci.c b/drivers/net/wireless/intersil/p54/p54pci.c index 80ad0b7eaef4..f8c6027cab6b 100644 --- a/drivers/net/wireless/intersil/p54/p54pci.c +++ b/drivers/net/wireless/intersil/p54/p54pci.c @@ -329,10 +329,12 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) struct p54p_desc *desc; dma_addr_t mapping; u32 idx, i; + __le32 device_addr; spin_lock_irqsave(&priv->lock, flags); idx = le32_to_cpu(ring_control->host_idx[1]); i = idx % ARRAY_SIZE(ring_control->tx_data); + device_addr = ((struct p54_hdr *)skb->data)->req_id; mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); @@ -346,7 +348,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) desc = &ring_control->tx_data[i]; desc->host_addr = cpu_to_le32(mapping); - desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; + desc->device_addr = device_addr; desc->len = cpu_to_le16(skb->len); desc->flags = 0;
In p54p_tx(), skb->data is mapped to streaming DMA on line 337: mapping = pci_map_single(..., skb->data, ...); Then skb->data is accessed on line 349: desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; This access may cause data inconsistency between CPU cache and hardware. To fix this problem, ((struct p54_hdr *)skb->data)->req_id is stored in a local variable before DMA mapping, and then the driver accesses this local variable instead of skb->data. Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn> --- drivers/net/wireless/intersil/p54/p54pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)