| From 746285cf81dc19502ab238249d75f5990bd2d231 Mon Sep 17 00:00:00 2001 |
| From: Alexander Wetzel <alexander@wetzel-home.de> |
| Date: Fri, 22 Apr 2022 16:52:28 +0200 |
| Subject: rtl818x: Prevent using not initialized queues |
| |
| From: Alexander Wetzel <alexander@wetzel-home.de> |
| |
| commit 746285cf81dc19502ab238249d75f5990bd2d231 upstream. |
| |
| Using not existing queues can panic the kernel with rtl8180/rtl8185 cards. |
| Ignore the skb priority for those cards, they only have one tx queue. Pierre |
| Asselin (pa@panix.com) reported the kernel crash in the Gentoo forum: |
| |
| https://forums.gentoo.org/viewtopic-t-1147832-postdays-0-postorder-asc-start-25.html |
| |
| He also confirmed that this patch fixes the issue. In summary this happened: |
| |
| After updating wpa_supplicant from 2.9 to 2.10 the kernel crashed with a |
| "divide error: 0000" when connecting to an AP. Control port tx now tries to |
| use IEEE80211_AC_VO for the priority, which wpa_supplicants starts to use in |
| 2.10. |
| |
| Since only the rtl8187se part of the driver supports QoS, the priority |
| of the skb is set to IEEE80211_AC_BE (2) by mac80211 for rtl8180/rtl8185 |
| cards. |
| |
| rtl8180 is then unconditionally reading out the priority and finally crashes on |
| drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c line 544 without this |
| patch: |
| idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries |
| |
| "ring->entries" is zero for rtl8180/rtl8185 cards, tx_ring[2] never got |
| initialized. |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: pa@panix.com |
| Tested-by: pa@panix.com |
| Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> |
| Signed-off-by: Kalle Valo <kvalo@kernel.org> |
| Link: https://lore.kernel.org/r/20220422145228.7567-1-alexander@wetzel-home.de |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c |
| +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c |
| @@ -460,8 +460,10 @@ static void rtl8180_tx(struct ieee80211_ |
| struct rtl8180_priv *priv = dev->priv; |
| struct rtl8180_tx_ring *ring; |
| struct rtl8180_tx_desc *entry; |
| + unsigned int prio = 0; |
| unsigned long flags; |
| - unsigned int idx, prio, hw_prio; |
| + unsigned int idx, hw_prio; |
| + |
| dma_addr_t mapping; |
| u32 tx_flags; |
| u8 rc_flags; |
| @@ -470,7 +472,9 @@ static void rtl8180_tx(struct ieee80211_ |
| /* do arithmetic and then convert to le16 */ |
| u16 frame_duration = 0; |
| |
| - prio = skb_get_queue_mapping(skb); |
| + /* rtl8180/rtl8185 only has one useable tx queue */ |
| + if (dev->queues > IEEE80211_AC_BK) |
| + prio = skb_get_queue_mapping(skb); |
| ring = &priv->tx_ring[prio]; |
| |
| mapping = pci_map_single(priv->pdev, skb->data, |