Commit d15697de authored by Alexey Khoroshilov's avatar Alexey Khoroshilov Committed by Kalle Valo

adm80211: add checks for dma mapping errors

The driver does not check if mapping dma memory succeed.
The patch adds the checks and failure handling.

Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: default avatarAlexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent e54a8c4b
...@@ -413,6 +413,13 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) ...@@ -413,6 +413,13 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
skb_tail_pointer(newskb), skb_tail_pointer(newskb),
RX_PKT_SIZE, RX_PKT_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(priv->pdev,
priv->rx_buffers[entry].mapping)) {
priv->rx_buffers[entry].skb = NULL;
dev_kfree_skb(newskb);
skb = NULL;
/* TODO: update rx dropped stats */
}
} else { } else {
skb = NULL; skb = NULL;
/* TODO: update rx dropped stats */ /* TODO: update rx dropped stats */
...@@ -1450,6 +1457,12 @@ static int adm8211_init_rings(struct ieee80211_hw *dev) ...@@ -1450,6 +1457,12 @@ static int adm8211_init_rings(struct ieee80211_hw *dev)
skb_tail_pointer(rx_info->skb), skb_tail_pointer(rx_info->skb),
RX_PKT_SIZE, RX_PKT_SIZE,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(priv->pdev, rx_info->mapping)) {
dev_kfree_skb(rx_info->skb);
rx_info->skb = NULL;
break;
}
desc->buffer1 = cpu_to_le32(rx_info->mapping); desc->buffer1 = cpu_to_le32(rx_info->mapping);
desc->status = cpu_to_le32(RDES0_STATUS_OWN | RDES0_STATUS_SQL); desc->status = cpu_to_le32(RDES0_STATUS_OWN | RDES0_STATUS_SQL);
} }
...@@ -1613,7 +1626,7 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int ...@@ -1613,7 +1626,7 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int
} }
/* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */ /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */
static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, static int adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
u16 plcp_signal, u16 plcp_signal,
size_t hdrlen) size_t hdrlen)
{ {
...@@ -1625,6 +1638,8 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1625,6 +1638,8 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
mapping = pci_map_single(priv->pdev, skb->data, skb->len, mapping = pci_map_single(priv->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
if (pci_dma_mapping_error(priv->pdev, mapping))
return -ENOMEM;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -1657,6 +1672,8 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1657,6 +1672,8 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
/* Trigger transmit poll */ /* Trigger transmit poll */
ADM8211_CSR_WRITE(TDR, 0); ADM8211_CSR_WRITE(TDR, 0);
return 0;
} }
/* Put adm8211_tx_hdr on skb and transmit */ /* Put adm8211_tx_hdr on skb and transmit */
...@@ -1710,7 +1727,10 @@ static void adm8211_tx(struct ieee80211_hw *dev, ...@@ -1710,7 +1727,10 @@ static void adm8211_tx(struct ieee80211_hw *dev,
txhdr->retry_limit = info->control.rates[0].count; txhdr->retry_limit = info->control.rates[0].count;
adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); if (adm8211_tx_raw(dev, skb, plcp_signal, hdrlen)) {
/* Drop packet */
ieee80211_free_txskb(dev, skb);
}
} }
static int adm8211_alloc_rings(struct ieee80211_hw *dev) static int adm8211_alloc_rings(struct ieee80211_hw *dev)
......
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