Commit bca463e8 authored by Chin-Ran Lo's avatar Chin-Ran Lo Committed by John W. Linville

mwifiex: fix tx_info/rx_info overlap with PCIe dma_mapping

On PCIe Tx data path, network interface specific tx_info
parameters such as bss_num and bss_type are saved at
"skb->cb + sizeof(dma_addr_t)" (returned by MWIFIEX_SKB_TXCB).
Later mwifiex_map_pci_memory() called from
mwifiex_pcie_send_data() will memcpy
sizeof(struct mwifiex_dma_mapping) bytes to save PCIe DMA
address and length information at beginning of skb->cb.
This accidently overwrites bss_num and bss_type saved in skb->cb
previously because bss_num/bss_type and mwifiex_dma_mapping data
overlap.
Similarly, on PCIe Rx data path, rx_info parameters overlaps
with PCIe DMA address and length information too.

Fix it by defining mwifiex_cb structure and having
MWIFIEX_SKB_TXCB and MWIFIEX_SKB_RXCB return the correct address
of tx_info/rx_info using the structure members.

Also add a BUILD_BUG_ON to maks sure that mwifiex_cb structure
doesn't exceed the size of skb->cb.
Reviewed-by: default avatarAaron Durbin <adurbin@chromium.org>
Signed-off-by: default avatarChin-Ran Lo <crlo@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f15ec345
...@@ -50,7 +50,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, ...@@ -50,7 +50,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
return -1; return -1;
} }
mapping.len = size; mapping.len = size;
memcpy(skb->cb, &mapping, sizeof(mapping)); mwifiex_store_mapping(skb, &mapping);
return 0; return 0;
} }
...@@ -60,7 +60,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter, ...@@ -60,7 +60,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
struct mwifiex_dma_mapping mapping; struct mwifiex_dma_mapping mapping;
MWIFIEX_SKB_PACB(skb, &mapping); mwifiex_get_mapping(skb, &mapping);
pci_unmap_single(card->dev, mapping.addr, mapping.len, flags); pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
} }
......
...@@ -20,32 +20,55 @@ ...@@ -20,32 +20,55 @@
#ifndef _MWIFIEX_UTIL_H_ #ifndef _MWIFIEX_UTIL_H_
#define _MWIFIEX_UTIL_H_ #define _MWIFIEX_UTIL_H_
struct mwifiex_dma_mapping {
dma_addr_t addr;
size_t len;
};
struct mwifiex_cb {
struct mwifiex_dma_mapping dma_mapping;
union {
struct mwifiex_rxinfo rx_info;
struct mwifiex_txinfo tx_info;
};
};
static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
{ {
return (struct mwifiex_rxinfo *)(skb->cb + sizeof(dma_addr_t)); struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
BUILD_BUG_ON(sizeof(struct mwifiex_cb) > sizeof(skb->cb));
return &cb->rx_info;
} }
static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb) static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
{ {
return (struct mwifiex_txinfo *)(skb->cb + sizeof(dma_addr_t)); struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
return &cb->tx_info;
} }
struct mwifiex_dma_mapping { static inline void mwifiex_store_mapping(struct sk_buff *skb,
dma_addr_t addr; struct mwifiex_dma_mapping *mapping)
size_t len; {
}; struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
memcpy(&cb->dma_mapping, mapping, sizeof(*mapping));
}
static inline void MWIFIEX_SKB_PACB(struct sk_buff *skb, static inline void mwifiex_get_mapping(struct sk_buff *skb,
struct mwifiex_dma_mapping *mapping) struct mwifiex_dma_mapping *mapping)
{ {
memcpy(mapping, skb->cb, sizeof(*mapping)); struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
memcpy(mapping, &cb->dma_mapping, sizeof(*mapping));
} }
static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb) static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
{ {
struct mwifiex_dma_mapping mapping; struct mwifiex_dma_mapping mapping;
MWIFIEX_SKB_PACB(skb, &mapping); mwifiex_get_mapping(skb, &mapping);
return mapping.addr; return mapping.addr;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment