From: Sasha Levin Date: Thu, 1 Apr 2021 17:31:25 +0000 (-0400) Subject: Fixes for 5.11 X-Git-Tag: v4.4.265~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e4f7799b5b7367679b93ffb3144324b3509826d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.11 Signed-off-by: Sasha Levin --- diff --git a/queue-5.11/appletalk-fix-skb-allocation-size-in-loopback-case.patch b/queue-5.11/appletalk-fix-skb-allocation-size-in-loopback-case.patch new file mode 100644 index 00000000000..0239b36206d --- /dev/null +++ b/queue-5.11/appletalk-fix-skb-allocation-size-in-loopback-case.patch @@ -0,0 +1,99 @@ +From fad73685db33abef39bd5e7036a0d9e8a23e4552 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 21:27:54 -0800 +Subject: appletalk: Fix skb allocation size in loopback case + +From: Doug Brown + +[ Upstream commit 39935dccb21c60f9bbf1bb72d22ab6fd14ae7705 ] + +If a DDP broadcast packet is sent out to a non-gateway target, it is +also looped back. There is a potential for the loopback device to have a +longer hardware header length than the original target route's device, +which can result in the skb not being created with enough room for the +loopback device's hardware header. This patch fixes the issue by +determining that a loopback will be necessary prior to allocating the +skb, and if so, ensuring the skb has enough room. + +This was discovered while testing a new driver that creates a LocalTalk +network interface (LTALK_HLEN = 1). It caused an skb_under_panic. + +Signed-off-by: Doug Brown +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/appletalk/ddp.c | 33 +++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c +index ca1a0d07a087..ebda397fa95a 100644 +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -1577,8 +1577,8 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + struct sk_buff *skb; + struct net_device *dev; + struct ddpehdr *ddp; +- int size; +- struct atalk_route *rt; ++ int size, hard_header_len; ++ struct atalk_route *rt, *rt_lo = NULL; + int err; + + if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) +@@ -1641,7 +1641,22 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", + sk, size, dev->name); + +- size += dev->hard_header_len; ++ hard_header_len = dev->hard_header_len; ++ /* Leave room for loopback hardware header if necessary */ ++ if (usat->sat_addr.s_node == ATADDR_BCAST && ++ (dev->flags & IFF_LOOPBACK || !(rt->flags & RTF_GATEWAY))) { ++ struct atalk_addr at_lo; ++ ++ at_lo.s_node = 0; ++ at_lo.s_net = 0; ++ ++ rt_lo = atrtr_find(&at_lo); ++ ++ if (rt_lo && rt_lo->dev->hard_header_len > hard_header_len) ++ hard_header_len = rt_lo->dev->hard_header_len; ++ } ++ ++ size += hard_header_len; + release_sock(sk); + skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); + lock_sock(sk); +@@ -1649,7 +1664,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + goto out; + + skb_reserve(skb, ddp_dl->header_length); +- skb_reserve(skb, dev->hard_header_len); ++ skb_reserve(skb, hard_header_len); + skb->dev = dev; + + SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); +@@ -1700,18 +1715,12 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + /* loop back */ + skb_orphan(skb); + if (ddp->deh_dnode == ATADDR_BCAST) { +- struct atalk_addr at_lo; +- +- at_lo.s_node = 0; +- at_lo.s_net = 0; +- +- rt = atrtr_find(&at_lo); +- if (!rt) { ++ if (!rt_lo) { + kfree_skb(skb); + err = -ENETUNREACH; + goto out; + } +- dev = rt->dev; ++ dev = rt_lo->dev; + skb->dev = dev; + } + ddp_dl->request(ddp_dl, skb, dev->dev_addr); +-- +2.30.1 + diff --git a/queue-5.11/ath10k-hold-rcu-lock-when-calling-ieee80211_find_sta.patch b/queue-5.11/ath10k-hold-rcu-lock-when-calling-ieee80211_find_sta.patch new file mode 100644 index 00000000000..b9e32c09c47 --- /dev/null +++ b/queue-5.11/ath10k-hold-rcu-lock-when-calling-ieee80211_find_sta.patch @@ -0,0 +1,61 @@ +From 214539e5f084fda2da740061472bd1fd6b11fb2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Feb 2021 14:21:07 -0700 +Subject: ath10k: hold RCU lock when calling ieee80211_find_sta_by_ifaddr() + +From: Shuah Khan + +[ Upstream commit 09078368d516918666a0122f2533dc73676d3d7e ] + +ieee80211_find_sta_by_ifaddr() must be called under the RCU lock and +the resulting pointer is only valid under RCU lock as well. + +Fix ath10k_wmi_tlv_op_pull_peer_stats_info() to hold RCU lock before it +calls ieee80211_find_sta_by_ifaddr() and release it when the resulting +pointer is no longer needed. + +This problem was found while reviewing code to debug RCU warn from +ath10k_wmi_tlv_parse_peer_stats_info(). + +Link: https://lore.kernel.org/linux-wireless/7230c9e5-2632-b77e-c4f9-10eca557a5bb@linuxfoundation.org/ +Signed-off-by: Shuah Khan +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20210210212107.40373-1-skhan@linuxfoundation.org +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/wmi-tlv.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +index e6135795719a..e7072fc4f487 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +@@ -576,13 +576,13 @@ static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) + case WMI_TDLS_TEARDOWN_REASON_TX: + case WMI_TDLS_TEARDOWN_REASON_RSSI: + case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: ++ rcu_read_lock(); + station = ieee80211_find_sta_by_ifaddr(ar->hw, + ev->peer_macaddr.addr, + NULL); + if (!station) { + ath10k_warn(ar, "did not find station from tdls peer event"); +- kfree(tb); +- return; ++ goto exit; + } + arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); + ieee80211_tdls_oper_request( +@@ -593,6 +593,9 @@ static void ath10k_wmi_event_tdls_peer(struct ath10k *ar, struct sk_buff *skb) + ); + break; + } ++ ++exit: ++ rcu_read_unlock(); + kfree(tb); + } + +-- +2.30.1 + diff --git a/queue-5.11/ath11k-add-ieee80211_unregister_hw-to-avoid-kernel-c.patch b/queue-5.11/ath11k-add-ieee80211_unregister_hw-to-avoid-kernel-c.patch new file mode 100644 index 00000000000..50cb755b02c --- /dev/null +++ b/queue-5.11/ath11k-add-ieee80211_unregister_hw-to-avoid-kernel-c.patch @@ -0,0 +1,162 @@ +From 733c94800e0c580fdb62ba56639dc1af0aef1aea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Jan 2021 18:26:00 +0200 +Subject: ath11k: add ieee80211_unregister_hw to avoid kernel crash caused by + NULL pointer + +From: Wen Gong + +[ Upstream commit 0d96968315d7ffbd70d608b29e9bea084210b96d ] + +When function return fail to __ath11k_mac_register after success called +ieee80211_register_hw, then it set wiphy->dev.parent to NULL by +SET_IEEE80211_DEV(ar->hw, NULL) in end of __ath11k_mac_register, then +cfg80211_get_drvinfo will be called by below call stack, but the +wiphy->dev.parent is NULL, so kernel crash. + +Call stack to cfg80211_get_drvinfo: +NetworkManager 826 [001] 6696.731371: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) + ffffffffc107d8f1 cfg80211_get_drvinfo+0x1 (/lib/modules/5.10.0-rc1-wt-ath+/kernel/net/wireless-back/cfg80211.ko) + ffffffff9d8fc529 ethtool_get_drvinfo+0x99 (vmlinux) + ffffffff9d90080e dev_ethtool+0x1dbe (vmlinux) + ffffffff9d8b88f7 dev_ioctl+0xb7 (vmlinux) + ffffffff9d8668de sock_do_ioctl+0xae (vmlinux) + ffffffff9d866d60 sock_ioctl+0x350 (vmlinux) + ffffffff9d2ca30e __x64_sys_ioctl+0x8e (vmlinux) + ffffffff9da0dda3 do_syscall_64+0x33 (vmlinux) + ffffffff9dc0008c entry_SYSCALL_64_after_hwframe+0x44 (vmlinux) + 7feb5f673007 __GI___ioctl+0x7 (/lib/x86_64-linux-gnu/libc-2.23.so) + 0 [unknown] ([unknown]) + +Code of cfg80211_get_drvinfo, the pdev which is wiphy->dev.parent is +NULL when kernel crash: +void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct device *pdev = wiphy_dev(wdev->wiphy); + + if (pdev->driver) +.... + +kernel crash log: +[ 973.619550] ath11k_pci 0000:05:00.0: failed to perform regd update : -16 +[ 973.619555] ath11k_pci 0000:05:00.0: ath11k regd update failed: -16 +[ 973.619566] ath11k_pci 0000:05:00.0: failed register the radio with mac80211: -16 +[ 973.619618] ath11k_pci 0000:05:00.0: failed to create pdev core: -16 +[ 973.636035] BUG: kernel NULL pointer dereference, address: 0000000000000068 +[ 973.636046] #PF: supervisor read access in kernel mode +[ 973.636050] #PF: error_code(0x0000) - not-present page +[ 973.636054] PGD 800000012452e067 P4D 800000012452e067 PUD 12452d067 PMD 0 +[ 973.636064] Oops: 0000 [#1] SMP PTI +[ 973.636072] CPU: 3 PID: 848 Comm: NetworkManager Kdump: loaded Tainted: G W OE 5.10.0-rc1-wt-ath+ #24 +[ 973.636076] Hardware name: LENOVO 418065C/418065C, BIOS 83ET63WW (1.33 ) 07/29/2011 +[ 973.636161] RIP: 0010:cfg80211_get_drvinfo+0x25/0xd0 [cfg80211] +[ 973.636169] Code: e9 c9 fe ff ff 66 66 66 66 90 55 53 ba 20 00 00 00 48 8b af 08 03 00 00 48 89 f3 48 8d 7e 04 48 8b 45 00 48 8b 80 90 01 00 00 <48> 8b 40 68 48 85 c0 0f 84 8d 00 00 00 48 8b 30 e8 a6 cc 72 c7 48 +[ 973.636174] RSP: 0018:ffffaafb4040bbe0 EFLAGS: 00010286 +[ 973.636180] RAX: 0000000000000000 RBX: ffffaafb4040bbfc RCX: 0000000000000000 +[ 973.636184] RDX: 0000000000000020 RSI: ffffaafb4040bbfc RDI: ffffaafb4040bc00 +[ 973.636188] RBP: ffff8a84c9568950 R08: 722d302e30312e35 R09: 74612d74772d3163 +[ 973.636192] R10: 3163722d302e3031 R11: 2b6874612d74772d R12: ffffaafb4040bbfc +[ 973.636196] R13: 00007ffe453707c0 R14: ffff8a84c9568000 R15: 0000000000000000 +[ 973.636202] FS: 00007fd3d179b940(0000) GS:ffff8a84fa2c0000(0000) knlGS:0000000000000000 +[ 973.636206] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 973.636211] CR2: 0000000000000068 CR3: 00000001153b6002 CR4: 00000000000606e0 +[ 973.636215] Call Trace: +[ 973.636234] ethtool_get_drvinfo+0x99/0x1f0 +[ 973.636246] dev_ethtool+0x1dbe/0x2be0 +[ 973.636256] ? mntput_no_expire+0x35/0x220 +[ 973.636264] ? inet_ioctl+0x1ce/0x200 +[ 973.636274] ? tomoyo_path_number_perm+0x68/0x1d0 +[ 973.636282] ? kmem_cache_alloc+0x3cb/0x430 +[ 973.636290] ? dev_ioctl+0xb7/0x570 +[ 973.636295] dev_ioctl+0xb7/0x570 +[ 973.636307] sock_do_ioctl+0xae/0x150 +[ 973.636315] ? sock_ioctl+0x350/0x3c0 +[ 973.636319] sock_ioctl+0x350/0x3c0 +[ 973.636332] ? __x64_sys_ioctl+0x8e/0xd0 +[ 973.636339] ? dlci_ioctl_set+0x30/0x30 +[ 973.636346] __x64_sys_ioctl+0x8e/0xd0 +[ 973.636359] do_syscall_64+0x33/0x80 +[ 973.636368] entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Sequence of function call when wlan load for success case when function +__ath11k_mac_register return 0: + +kworker/u16:3-e 2922 [001] 6696.729734: probe:ieee80211_register_hw: (ffffffffc116ae60) +kworker/u16:3-e 2922 [001] 6696.730210: probe:ieee80211_if_add: (ffffffffc1185cc0) +NetworkManager 826 [001] 6696.731345: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +NetworkManager 826 [001] 6696.731371: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) +NetworkManager 826 [001] 6696.731639: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +NetworkManager 826 [001] 6696.731653: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) +NetworkManager 826 [001] 6696.732866: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +NetworkManager 826 [001] 6696.732893: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) +systemd-udevd 3850 [003] 6696.737199: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +systemd-udevd 3850 [003] 6696.737226: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) +NetworkManager 826 [000] 6696.759950: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +NetworkManager 826 [000] 6696.759967: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) +NetworkManager 826 [000] 6696.760057: probe:ethtool_get_drvinfo: (ffffffff9d8fc490) +NetworkManager 826 [000] 6696.760062: probe:cfg80211_get_drvinfo: (ffffffffc107d8f0) + +After apply this patch, kernel crash gone, and below is the test case's +sequence of function call and log when wlan load with fail by function +ath11k_regd_update, and __ath11k_mac_register return fail: + +kworker/u16:5-e 192 [001] 215.174388: probe:ieee80211_register_hw: (ffffffffc1131e60) +kworker/u16:5-e 192 [000] 215.174973: probe:ieee80211_if_add: (ffffffffc114ccc0) +NetworkManager 846 [001] 215.175857: probe:ethtool_get_drvinfo: (ffffffff928fc490) +kworker/u16:5-e 192 [000] 215.175867: probe:ieee80211_unregister_hw: (ffffffffc1131970) +NetworkManager 846 [001] 215.175880: probe:cfg80211_get_drvinfo: (ffffffffc107f8f0) +NetworkManager 846 [001] 215.176105: probe:ethtool_get_drvinfo: (ffffffff928fc490) +NetworkManager 846 [001] 215.176118: probe:cfg80211_get_drvinfo: (ffffffffc107f8f0) +[ 215.175859] ath11k_pci 0000:05:00.0: ath11k regd update failed: -16 +NetworkManager 846 [001] 215.196420: probe:ethtool_get_drvinfo: (ffffffff928fc490) +NetworkManager 846 [001] 215.196430: probe:cfg80211_get_drvinfo: (ffffffffc107f8f0) +[ 215.258598] ath11k_pci 0000:05:00.0: failed register the radio with mac80211: -16 +[ 215.258613] ath11k_pci 0000:05:00.0: failed to create pdev core: -16 + +When ath11k_regd_update or ath11k_debugfs_register return fail, function +ieee80211_unregister_hw of mac80211 will be called, then it will wait +untill cfg80211_get_drvinfo finished, the wiphy->dev.parent is not NULL +at this moment, after that, it set wiphy->dev.parent to NULL by +SET_IEEE80211_DEV(ar->hw, NULL) in end of __ath11k_mac_register, so +not happen kernel crash. + +Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 +Signed-off-by: Wen Gong +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/1608607824-16067-1-git-send-email-wgong@codeaurora.org +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 54bdef33f3f8..55ecf7f43735 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6361,17 +6361,20 @@ static int __ath11k_mac_register(struct ath11k *ar) + ret = ath11k_regd_update(ar, true); + if (ret) { + ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret); +- goto err_free_if_combs; ++ goto err_unregister_hw; + } + + ret = ath11k_debugfs_register(ar); + if (ret) { + ath11k_err(ar->ab, "debugfs registration failed: %d\n", ret); +- goto err_free_if_combs; ++ goto err_unregister_hw; + } + + return 0; + ++err_unregister_hw: ++ ieee80211_unregister_hw(ar->hw); ++ + err_free_if_combs: + kfree(ar->hw->wiphy->iface_combinations[0].limits); + kfree(ar->hw->wiphy->iface_combinations); +-- +2.30.1 + diff --git a/queue-5.11/brcmfmac-clear-eap-association-status-bits-on-linkdo.patch b/queue-5.11/brcmfmac-clear-eap-association-status-bits-on-linkdo.patch new file mode 100644 index 00000000000..7f49ddc1c4f --- /dev/null +++ b/queue-5.11/brcmfmac-clear-eap-association-status-bits-on-linkdo.patch @@ -0,0 +1,63 @@ +From dcacafa1aa239356d1e9732c4c4f1e7938eae38d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Dec 2020 11:51:59 +0100 +Subject: brcmfmac: clear EAP/association status bits on linkdown events + +From: Luca Pesce + +[ Upstream commit e862a3e4088070de352fdafe9bd9e3ae0a95a33c ] + +This ensure that previous association attempts do not leave stale statuses +on subsequent attempts. + +This fixes the WARN_ON(!cr->bss)) from __cfg80211_connect_result() when +connecting to an AP after a previous connection failure (e.g. where EAP fails +due to incorrect psk but association succeeded). In some scenarios, indeed, +brcmf_is_linkup() was reporting a link up event too early due to stale +BRCMF_VIF_STATUS_ASSOC_SUCCESS bit, thus reporting to cfg80211 a connection +result with a zeroed bssid (vif->profile.bssid is still empty), causing the +WARN_ON due to the call to cfg80211_get_bss() with the empty bssid. + +Signed-off-by: Luca Pesce +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/1608807119-21785-1-git-send-email-luca.pesce@vimar.com +Signed-off-by: Sasha Levin +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index 0ee421f30aa2..23e6422c2251 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5611,7 +5611,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif, + return false; + } + +-static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) ++static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif, ++ const struct brcmf_event_msg *e) + { + u32 event = e->event_code; + u16 flags = e->flags; +@@ -5620,6 +5621,8 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) + (event == BRCMF_E_DISASSOC_IND) || + ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) { + brcmf_dbg(CONN, "Processing link down\n"); ++ clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state); ++ clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state); + return true; + } + return false; +@@ -6067,7 +6070,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, + } else + brcmf_bss_connect_done(cfg, ndev, e, true); + brcmf_net_setcarrier(ifp, true); +- } else if (brcmf_is_linkdown(e)) { ++ } else if (brcmf_is_linkdown(ifp->vif, e)) { + brcmf_dbg(CONN, "Linkdown\n"); + if (!brcmf_is_ibssmode(ifp->vif) && + test_bit(BRCMF_VIF_STATUS_CONNECTED, +-- +2.30.1 + diff --git a/queue-5.11/can-dev-move-driver-related-infrastructure-into-sepa.patch b/queue-5.11/can-dev-move-driver-related-infrastructure-into-sepa.patch new file mode 100644 index 00000000000..a0365f02cae --- /dev/null +++ b/queue-5.11/can-dev-move-driver-related-infrastructure-into-sepa.patch @@ -0,0 +1,68 @@ +From 93cb57e919bcd1a71c19c50175521ddccf9449e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Jan 2021 15:19:17 +0100 +Subject: can: dev: move driver related infrastructure into separate subdir + +From: Marc Kleine-Budde + +[ Upstream commit 3e77f70e734584e0ad1038e459ed3fd2400f873a ] + +This patch moves the CAN driver related infrastructure into a separate subdir. +It will be split into more files in the coming patches. + +Reviewed-by: Vincent Mailhol +Link: https://lore.kernel.org/r/20210111141930.693847-3-mkl@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/Makefile | 7 +------ + drivers/net/can/dev/Makefile | 7 +++++++ + drivers/net/can/{ => dev}/dev.c | 0 + drivers/net/can/{ => dev}/rx-offload.c | 0 + 4 files changed, 8 insertions(+), 6 deletions(-) + create mode 100644 drivers/net/can/dev/Makefile + rename drivers/net/can/{ => dev}/dev.c (100%) + rename drivers/net/can/{ => dev}/rx-offload.c (100%) + +diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile +index 22164300122d..a2b4463d8480 100644 +--- a/drivers/net/can/Makefile ++++ b/drivers/net/can/Makefile +@@ -7,12 +7,7 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o + obj-$(CONFIG_CAN_VXCAN) += vxcan.o + obj-$(CONFIG_CAN_SLCAN) += slcan.o + +-obj-$(CONFIG_CAN_DEV) += can-dev.o +-can-dev-y += dev.o +-can-dev-y += rx-offload.o +- +-can-dev-$(CONFIG_CAN_LEDS) += led.o +- ++obj-y += dev/ + obj-y += rcar/ + obj-y += spi/ + obj-y += usb/ +diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile +new file mode 100644 +index 000000000000..cba92e6bcf6f +--- /dev/null ++++ b/drivers/net/can/dev/Makefile +@@ -0,0 +1,7 @@ ++# SPDX-License-Identifier: GPL-2.0 ++ ++obj-$(CONFIG_CAN_DEV) += can-dev.o ++can-dev-y += dev.o ++can-dev-y += rx-offload.o ++ ++can-dev-$(CONFIG_CAN_LEDS) += led.o +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev/dev.c +similarity index 100% +rename from drivers/net/can/dev.c +rename to drivers/net/can/dev/dev.c +diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/dev/rx-offload.c +similarity index 100% +rename from drivers/net/can/rx-offload.c +rename to drivers/net/can/dev/rx-offload.c +-- +2.30.1 + diff --git a/queue-5.11/can-tcan4x5x-fix-max-register-value.patch b/queue-5.11/can-tcan4x5x-fix-max-register-value.patch new file mode 100644 index 00000000000..afb4bad68ed --- /dev/null +++ b/queue-5.11/can-tcan4x5x-fix-max-register-value.patch @@ -0,0 +1,34 @@ +From 07232ce96181e32b4805de33d8f6a9f950bdb3f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Mar 2021 19:13:21 -0400 +Subject: can: tcan4x5x: fix max register value + +[ Upstream commit 6e1caaf8ed22eb700cc47ec353816eee33186c1c ] + +This patch fixes the max register value for the regmap. + +Reviewed-by: Dan Murphy +Tested-by: Sean Nyekjaer +Link: https://lore.kernel.org/r/20201215231746.1132907-12-mkl@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/m_can/tcan4x5x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c +index 4920de09ffb7..aeac3ce7bfc8 100644 +--- a/drivers/net/can/m_can/tcan4x5x.c ++++ b/drivers/net/can/m_can/tcan4x5x.c +@@ -88,7 +88,7 @@ + + #define TCAN4X5X_MRAM_START 0x8000 + #define TCAN4X5X_MCAN_OFFSET 0x1000 +-#define TCAN4X5X_MAX_REGISTER 0x8fff ++#define TCAN4X5X_MAX_REGISTER 0x8ffc + + #define TCAN4X5X_CLEAR_ALL_INT 0xffffffff + #define TCAN4X5X_SET_ALL_INT 0xffffffff +-- +2.30.1 + diff --git a/queue-5.11/flow_dissector-fix-ttl-and-tos-dissection-on-ipv4-fr.patch b/queue-5.11/flow_dissector-fix-ttl-and-tos-dissection-on-ipv4-fr.patch new file mode 100644 index 00000000000..2af4052c172 --- /dev/null +++ b/queue-5.11/flow_dissector-fix-ttl-and-tos-dissection-on-ipv4-fr.patch @@ -0,0 +1,114 @@ +From 4e3d686cbb682339f238b0b63745a1ac9ea41598 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Feb 2021 16:12:25 +0100 +Subject: flow_dissector: fix TTL and TOS dissection on IPv4 fragments + +From: Davide Caratti + +[ Upstream commit d2126838050ccd1dadf310ffb78b2204f3b032b9 ] + +the following command: + + # tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ + $tcflags dst_ip 192.0.2.2 ip_ttl 63 action drop + +doesn't drop all IPv4 packets that match the configured TTL / destination +address. In particular, if "fragment offset" or "more fragments" have non +zero value in the IPv4 header, setting of FLOW_DISSECTOR_KEY_IP is simply +ignored. Fix this dissecting IPv4 TTL and TOS before fragment info; while +at it, add a selftest for tc flower's match on 'ip_ttl' that verifies the +correct behavior. + +Fixes: 518d8a2e9bad ("net/flow_dissector: add support for dissection of misc ip header fields") +Reported-by: Shuang Li +Signed-off-by: Davide Caratti +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 6 +-- + .../selftests/net/forwarding/tc_flower.sh | 38 ++++++++++++++++++- + 2 files changed, 40 insertions(+), 4 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 7a06d4301617..180be5102efc 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1050,6 +1050,9 @@ proto_again: + key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; + } + ++ __skb_flow_dissect_ipv4(skb, flow_dissector, ++ target_container, data, iph); ++ + if (ip_is_fragment(iph)) { + key_control->flags |= FLOW_DIS_IS_FRAGMENT; + +@@ -1066,9 +1069,6 @@ proto_again: + } + } + +- __skb_flow_dissect_ipv4(skb, flow_dissector, +- target_container, data, iph); +- + break; + } + case htons(ETH_P_IPV6): { +diff --git a/tools/testing/selftests/net/forwarding/tc_flower.sh b/tools/testing/selftests/net/forwarding/tc_flower.sh +index 058c746ee300..b11d8e6b5bc1 100755 +--- a/tools/testing/selftests/net/forwarding/tc_flower.sh ++++ b/tools/testing/selftests/net/forwarding/tc_flower.sh +@@ -3,7 +3,7 @@ + + ALL_TESTS="match_dst_mac_test match_src_mac_test match_dst_ip_test \ + match_src_ip_test match_ip_flags_test match_pcp_test match_vlan_test \ +- match_ip_tos_test match_indev_test" ++ match_ip_tos_test match_indev_test match_ip_ttl_test" + NUM_NETIFS=2 + source tc_common.sh + source lib.sh +@@ -310,6 +310,42 @@ match_ip_tos_test() + log_test "ip_tos match ($tcflags)" + } + ++match_ip_ttl_test() ++{ ++ RET=0 ++ ++ tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ ++ $tcflags dst_ip 192.0.2.2 ip_ttl 63 action drop ++ tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ ++ $tcflags dst_ip 192.0.2.2 action drop ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=63" -q ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=63,mf,frag=256" -q ++ ++ tc_check_packets "dev $h2 ingress" 102 1 ++ check_fail $? "Matched on the wrong filter (no check on ttl)" ++ ++ tc_check_packets "dev $h2 ingress" 101 2 ++ check_err $? "Did not match on correct filter (ttl=63)" ++ ++ $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ ++ -t ip "ttl=255" -q ++ ++ tc_check_packets "dev $h2 ingress" 101 3 ++ check_fail $? "Matched on a wrong filter (ttl=63)" ++ ++ tc_check_packets "dev $h2 ingress" 102 1 ++ check_err $? "Did not match on correct filter (no check on ttl)" ++ ++ tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower ++ tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower ++ ++ log_test "ip_ttl match ($tcflags)" ++} ++ + match_indev_test() + { + RET=0 +-- +2.30.1 + diff --git a/queue-5.11/iwlwifi-pcie-don-t-disable-interrupts-for-reg_lock.patch b/queue-5.11/iwlwifi-pcie-don-t-disable-interrupts-for-reg_lock.patch new file mode 100644 index 00000000000..a592462c583 --- /dev/null +++ b/queue-5.11/iwlwifi-pcie-don-t-disable-interrupts-for-reg_lock.patch @@ -0,0 +1,175 @@ +From b2a93368e6e56c68c916f0e5b959767a1c57e431 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Feb 2021 13:56:27 +0200 +Subject: iwlwifi: pcie: don't disable interrupts for reg_lock + +From: Johannes Berg + +[ Upstream commit 874020f8adce535cd318af1768ffe744251b6593 ] + +The only thing we do touching the device in hard interrupt context +is, at most, writing an interrupt ACK register, which isn't racing +in with anything protected by the reg_lock. + +Thus, avoid disabling interrupts here for potentially long periods +of time, particularly long periods have been observed with dumping +of firmware memory (leading to lockup warnings on some devices.) + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/iwlwifi.20210210135352.da916ab91298.I064c3e7823b616647293ed97da98edefb9ce9435@changeid +Signed-off-by: Luca Coelho +Signed-off-by: Sasha Levin +--- + .../net/wireless/intel/iwlwifi/pcie/trans.c | 11 +++++----- + .../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 5 ++--- + drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 22 ++++++++----------- + 3 files changed, 16 insertions(+), 22 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +index ab93a848a466..e71bc97cb40e 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +@@ -1972,7 +1972,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, + int ret; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + +- spin_lock_irqsave(&trans_pcie->reg_lock, *flags); ++ spin_lock_bh(&trans_pcie->reg_lock); + + if (trans_pcie->cmd_hold_nic_awake) + goto out; +@@ -2057,7 +2057,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, + } + + err: +- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + return false; + } + +@@ -2095,7 +2095,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, + * scheduled on different CPUs (after we drop reg_lock). + */ + out: +- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + } + + static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, +@@ -2296,11 +2296,10 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg, + u32 mask, u32 value) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); +- unsigned long flags; + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock_bh(&trans_pcie->reg_lock); + __iwl_trans_pcie_set_bits_mask(trans, reg, mask, value); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock_bh(&trans_pcie->reg_lock); + } + + static const char *get_csr_string(int cmd) +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +index 8757246a90d5..b9afd9b04042 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +@@ -31,7 +31,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, + struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id]; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; +- unsigned long flags; + void *dup_buf = NULL; + dma_addr_t phys_addr; + int i, cmd_pos, idx; +@@ -244,11 +243,11 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans, + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + /* Increment and update queue's write index */ + txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr); + iwl_txq_inc_wr_ptr(trans, txq); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + + out: + spin_unlock_bh(&txq->lock); +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +index 83f4964f3cb2..689f51968049 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -223,12 +223,10 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) + txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr); + + if (txq->read_ptr == txq->write_ptr) { +- unsigned long flags; +- +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + if (txq_id == trans->txqs.cmd.q_id) + iwl_pcie_clear_cmd_in_flight(trans); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + } + } + +@@ -679,7 +677,6 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) + { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_txq *txq = trans->txqs.txq[txq_id]; +- unsigned long flags; + int nfreed = 0; + u16 r; + +@@ -710,9 +707,10 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) + } + + if (txq->read_ptr == txq->write_ptr) { +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ /* BHs are also disabled due to txq->lock */ ++ spin_lock(&trans_pcie->reg_lock); + iwl_pcie_clear_cmd_in_flight(trans); +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); ++ spin_unlock(&trans_pcie->reg_lock); + } + + iwl_txq_progress(txq); +@@ -921,7 +919,6 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, + struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id]; + struct iwl_device_cmd *out_cmd; + struct iwl_cmd_meta *out_meta; +- unsigned long flags; + void *dup_buf = NULL; + dma_addr_t phys_addr; + int idx; +@@ -1164,20 +1161,19 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, + if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout); + +- spin_lock_irqsave(&trans_pcie->reg_lock, flags); ++ spin_lock(&trans_pcie->reg_lock); + ret = iwl_pcie_set_cmd_in_flight(trans, cmd); + if (ret < 0) { + idx = ret; +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); +- goto out; ++ goto unlock_reg; + } + + /* Increment and update queue's write index */ + txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr); + iwl_pcie_txq_inc_wr_ptr(trans, txq); + +- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); +- ++ unlock_reg: ++ spin_unlock(&trans_pcie->reg_lock); + out: + spin_unlock_bh(&txq->lock); + free_dup_buf: +-- +2.30.1 + diff --git a/queue-5.11/mptcp-add-a-missing-retransmission-timer-scheduling.patch b/queue-5.11/mptcp-add-a-missing-retransmission-timer-scheduling.patch new file mode 100644 index 00000000000..d32684eda22 --- /dev/null +++ b/queue-5.11/mptcp-add-a-missing-retransmission-timer-scheduling.patch @@ -0,0 +1,58 @@ +From 36231868643270ca82298c1d1d8302df75c2b66b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 15:30:42 -0800 +Subject: mptcp: add a missing retransmission timer scheduling + +From: Paolo Abeni + +[ Upstream commit d09d818ec2ed31bce94fdcfcc4700233e01f8498 ] + +Currently we do not schedule the MPTCP retransmission +timer after pushing the data when such action happens +in the subflow context. + +This may cause hang-up on active-backup scenarios, or +even when only single subflow msks are involved, if we lost +some peer's ack. + +Fixes: 6e628cd3a8f7 ("mptcp: use mptcp release_cb for delayed tasks") +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/options.c | 3 +-- + net/mptcp/protocol.c | 3 +++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/mptcp/options.c b/net/mptcp/options.c +index 37ef0bf098f6..9e86c601093f 100644 +--- a/net/mptcp/options.c ++++ b/net/mptcp/options.c +@@ -885,8 +885,7 @@ static void ack_update_msk(struct mptcp_sock *msk, + msk->wnd_end = new_wnd_end; + + /* this assumes mptcp_incoming_options() is invoked after tcp_ack() */ +- if (after64(msk->wnd_end, READ_ONCE(msk->snd_nxt)) && +- sk_stream_memory_free(ssk)) ++ if (after64(msk->wnd_end, READ_ONCE(msk->snd_nxt))) + __mptcp_check_push(sk, ssk); + + if (after64(new_snd_una, old_snd_una)) { +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 44b8868f0607..67483e561b37 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1568,6 +1568,9 @@ out: + mptcp_set_timeout(sk, ssk); + tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle, + info.size_goal); ++ if (!mptcp_timer_pending(sk)) ++ mptcp_reset_timer(sk); ++ + if (msk->snd_data_fin_enable && + msk->snd_nxt + 1 == msk->write_seq) + mptcp_schedule_work(sk); +-- +2.30.1 + diff --git a/queue-5.11/mptcp-deliver-ssk-errors-to-msk.patch b/queue-5.11/mptcp-deliver-ssk-errors-to-msk.patch new file mode 100644 index 00000000000..977d41e2cb5 --- /dev/null +++ b/queue-5.11/mptcp-deliver-ssk-errors-to-msk.patch @@ -0,0 +1,163 @@ +From 8e62c5e7d7af6f04cbe27ecab50c0efc4a27b943 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 15:30:37 -0800 +Subject: mptcp: deliver ssk errors to msk + +From: Paolo Abeni + +[ Upstream commit 15cc10453398c22f78f6c2b897119ecce5e5dd89 ] + +Currently all errors received on msk subflows are ignored. +We need to catch at least the errors on connect() and +on fallback sockets. + +Use a custom sk_error_report callback at subflow level, +and do the real action under the msk socket lock - via +the usual sock_owned_by_user()/release_callback() schema. + +Fixes: 6e628cd3a8f7 ("mptcp: use mptcp release_cb for delayed tasks") +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 7 +++++++ + net/mptcp/protocol.h | 4 ++++ + net/mptcp/subflow.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 54 insertions(+) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 7345df40385a..f588332eebb4 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2958,6 +2958,8 @@ static void mptcp_release_cb(struct sock *sk) + mptcp_push_pending(sk, 0); + spin_lock_bh(&sk->sk_lock.slock); + } ++ if (test_and_clear_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags)) ++ __mptcp_error_report(sk); + + /* clear any wmem reservation and errors */ + __mptcp_update_wmem(sk); +@@ -3354,6 +3356,11 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; + ++ /* This barrier is coupled with smp_wmb() in tcp_reset() */ ++ smp_rmb(); ++ if (sk->sk_err) ++ mask |= EPOLLERR; ++ + return mask; + } + +diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h +index c374345ad134..62288836d053 100644 +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -96,6 +96,7 @@ + #define MPTCP_WORK_CLOSE_SUBFLOW 5 + #define MPTCP_PUSH_PENDING 6 + #define MPTCP_CLEAN_UNA 7 ++#define MPTCP_ERROR_REPORT 8 + + static inline bool before64(__u64 seq1, __u64 seq2) + { +@@ -413,6 +414,7 @@ struct mptcp_subflow_context { + void (*tcp_data_ready)(struct sock *sk); + void (*tcp_state_change)(struct sock *sk); + void (*tcp_write_space)(struct sock *sk); ++ void (*tcp_error_report)(struct sock *sk); + + struct rcu_head rcu; + }; +@@ -478,6 +480,7 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk, + sk->sk_data_ready = ctx->tcp_data_ready; + sk->sk_state_change = ctx->tcp_state_change; + sk->sk_write_space = ctx->tcp_write_space; ++ sk->sk_error_report = ctx->tcp_error_report; + + inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops; + } +@@ -505,6 +508,7 @@ bool mptcp_finish_join(struct sock *sk); + bool mptcp_schedule_work(struct sock *sk); + void __mptcp_check_push(struct sock *sk, struct sock *ssk); + void __mptcp_data_acked(struct sock *sk); ++void __mptcp_error_report(struct sock *sk); + void mptcp_subflow_eof(struct sock *sk); + bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit); + void __mptcp_flush_join_list(struct mptcp_sock *msk); +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 96e040951cd4..6c0205816a5d 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -1054,6 +1054,46 @@ static void subflow_write_space(struct sock *ssk) + /* we take action in __mptcp_clean_una() */ + } + ++void __mptcp_error_report(struct sock *sk) ++{ ++ struct mptcp_subflow_context *subflow; ++ struct mptcp_sock *msk = mptcp_sk(sk); ++ ++ mptcp_for_each_subflow(msk, subflow) { ++ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); ++ int err = sock_error(ssk); ++ ++ if (!err) ++ continue; ++ ++ /* only propagate errors on fallen-back sockets or ++ * on MPC connect ++ */ ++ if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(msk)) ++ continue; ++ ++ inet_sk_state_store(sk, inet_sk_state_load(ssk)); ++ sk->sk_err = -err; ++ ++ /* This barrier is coupled with smp_rmb() in mptcp_poll() */ ++ smp_wmb(); ++ sk->sk_error_report(sk); ++ break; ++ } ++} ++ ++static void subflow_error_report(struct sock *ssk) ++{ ++ struct sock *sk = mptcp_subflow_ctx(ssk)->conn; ++ ++ mptcp_data_lock(sk); ++ if (!sock_owned_by_user(sk)) ++ __mptcp_error_report(sk); ++ else ++ set_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags); ++ mptcp_data_unlock(sk); ++} ++ + static struct inet_connection_sock_af_ops * + subflow_default_af_ops(struct sock *sk) + { +@@ -1367,9 +1407,11 @@ static int subflow_ulp_init(struct sock *sk) + ctx->tcp_data_ready = sk->sk_data_ready; + ctx->tcp_state_change = sk->sk_state_change; + ctx->tcp_write_space = sk->sk_write_space; ++ ctx->tcp_error_report = sk->sk_error_report; + sk->sk_data_ready = subflow_data_ready; + sk->sk_write_space = subflow_write_space; + sk->sk_state_change = subflow_state_change; ++ sk->sk_error_report = subflow_error_report; + out: + return err; + } +@@ -1422,6 +1464,7 @@ static void subflow_ulp_clone(const struct request_sock *req, + new_ctx->tcp_data_ready = old_ctx->tcp_data_ready; + new_ctx->tcp_state_change = old_ctx->tcp_state_change; + new_ctx->tcp_write_space = old_ctx->tcp_write_space; ++ new_ctx->tcp_error_report = old_ctx->tcp_error_report; + new_ctx->rel_write_seq = 1; + new_ctx->tcp_sock = newsk; + +-- +2.30.1 + diff --git a/queue-5.11/mptcp-fix-bit-mptcp_push_pending-tests.patch b/queue-5.11/mptcp-fix-bit-mptcp_push_pending-tests.patch new file mode 100644 index 00000000000..a90b2525350 --- /dev/null +++ b/queue-5.11/mptcp-fix-bit-mptcp_push_pending-tests.patch @@ -0,0 +1,46 @@ +From 1401d613606b3b1cb91af708ae9e131948c6fe16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Mar 2021 10:41:12 +0300 +Subject: mptcp: fix bit MPTCP_PUSH_PENDING tests + +From: Dan Carpenter + +[ Upstream commit 2e5de7e0c8d2caa860e133ef71fc94671cb8e0bf ] + +The MPTCP_PUSH_PENDING define is 6 and these tests should be testing if +BIT(6) is set. + +Fixes: c2e6048fa1cf ("mptcp: fix race in release_cb") +Signed-off-by: Dan Carpenter +Reviewed-by: Matthieu Baerts +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 7cbb544c6d02..5932b0ebecc3 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2947,7 +2947,7 @@ static void mptcp_release_cb(struct sock *sk) + for (;;) { + flags = 0; + if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) +- flags |= MPTCP_PUSH_PENDING; ++ flags |= BIT(MPTCP_PUSH_PENDING); + if (!flags) + break; + +@@ -2960,7 +2960,7 @@ static void mptcp_release_cb(struct sock *sk) + */ + + spin_unlock_bh(&sk->sk_lock.slock); +- if (flags & MPTCP_PUSH_PENDING) ++ if (flags & BIT(MPTCP_PUSH_PENDING)) + __mptcp_push_pending(sk, 0); + + cond_resched(); +-- +2.30.1 + diff --git a/queue-5.11/mptcp-fix-data_fin-processing-for-orphaned-sockets.patch b/queue-5.11/mptcp-fix-data_fin-processing-for-orphaned-sockets.patch new file mode 100644 index 00000000000..644e5c5d4ed --- /dev/null +++ b/queue-5.11/mptcp-fix-data_fin-processing-for-orphaned-sockets.patch @@ -0,0 +1,50 @@ +From e02a6d3ae0b6f42d8c642a6e4327d94a733d377e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Feb 2021 18:35:37 +0100 +Subject: mptcp: fix DATA_FIN processing for orphaned sockets + +From: Paolo Abeni + +[ Upstream commit 341c65242fe18aac8900e4291d472df9f7ba7bc7 ] + +Currently we move orphaned msk sockets directly from FIN_WAIT2 +state to CLOSE, with the rationale that incoming additional +data could be just dropped by the TCP stack/TW sockets. + +Anyhow we miss sending MPTCP-level ack on incoming DATA_FIN, +and that may hang the peers. + +Fixes: e16163b6e2b7 ("mptcp: refactor shutdown and close") +Reviewed-by: Mat Martineau +Signed-off-by: Paolo Abeni +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 67483e561b37..88f2d900a347 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -2292,13 +2292,12 @@ static void mptcp_worker(struct work_struct *work) + __mptcp_check_send_data_fin(sk); + mptcp_check_data_fin(sk); + +- /* if the msk data is completely acked, or the socket timedout, +- * there is no point in keeping around an orphaned sk ++ /* There is no point in keeping around an orphaned sk timedout or ++ * closed, but we need the msk around to reply to incoming DATA_FIN, ++ * even if it is orphaned and in FIN_WAIT2 state + */ + if (sock_flag(sk, SOCK_DEAD) && +- (mptcp_check_close_timeout(sk) || +- (state != sk->sk_state && +- ((1 << inet_sk_state_load(sk)) & (TCPF_CLOSE | TCPF_FIN_WAIT2))))) { ++ (mptcp_check_close_timeout(sk) || sk->sk_state == TCP_CLOSE)) { + inet_sk_state_store(sk, TCP_CLOSE); + __mptcp_destroy_sock(sk); + goto unlock; +-- +2.30.1 + diff --git a/queue-5.11/mptcp-fix-poll-after-shutdown.patch b/queue-5.11/mptcp-fix-poll-after-shutdown.patch new file mode 100644 index 00000000000..29ff1a35b42 --- /dev/null +++ b/queue-5.11/mptcp-fix-poll-after-shutdown.patch @@ -0,0 +1,49 @@ +From 9f1e6937cb15ad0fd5457b0fe84a0bd5df44f2ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 15:30:38 -0800 +Subject: mptcp: fix poll after shutdown + +From: Paolo Abeni + +[ Upstream commit dd913410b0a442a53d41a9817ed2208850858e99 ] + +The current mptcp_poll() implementation gives unexpected +results after shutdown(SEND_SHUTDOWN) and when the msk +status is TCP_CLOSE. + +Set the correct mask. + +Fixes: 8edf08649eed ("mptcp: rework poll+nospace handling") +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index f588332eebb4..44b8868f0607 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3320,7 +3320,7 @@ static __poll_t mptcp_check_writeable(struct mptcp_sock *msk) + struct sock *sk = (struct sock *)msk; + + if (unlikely(sk->sk_shutdown & SEND_SHUTDOWN)) +- return 0; ++ return EPOLLOUT | EPOLLWRNORM; + + if (sk_stream_is_writeable(sk)) + return EPOLLOUT | EPOLLWRNORM; +@@ -3353,6 +3353,8 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, + mask |= mptcp_check_readable(msk); + mask |= mptcp_check_writeable(msk); + } ++ if (sk->sk_shutdown == SHUTDOWN_MASK || state == TCP_CLOSE) ++ mask |= EPOLLHUP; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; + +-- +2.30.1 + diff --git a/queue-5.11/mptcp-fix-race-in-release_cb.patch b/queue-5.11/mptcp-fix-race-in-release_cb.patch new file mode 100644 index 00000000000..eb6296c293e --- /dev/null +++ b/queue-5.11/mptcp-fix-race-in-release_cb.patch @@ -0,0 +1,107 @@ +From 7cf10a80ed9df700a10e6c72e9df1a066762605d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Mar 2021 13:32:14 -0800 +Subject: mptcp: fix race in release_cb + +From: Paolo Abeni + +[ Upstream commit c2e6048fa1cf2228063aec299f93ac6eb256b457 ] + +If we receive a MPTCP_PUSH_PENDING even from a subflow when +mptcp_release_cb() is serving the previous one, the latter +will be delayed up to the next release_sock(msk). + +Address the issue implementing a test/serve loop for such +event. + +Additionally rename the push helper to __mptcp_push_pending() +to be more consistent with the existing code. + +Fixes: 6e628cd3a8f7 ("mptcp: use mptcp release_cb for delayed tasks") +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 33 +++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index c3299a4568a0..7cbb544c6d02 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1442,7 +1442,7 @@ static void mptcp_push_release(struct sock *sk, struct sock *ssk, + release_sock(ssk); + } + +-static void mptcp_push_pending(struct sock *sk, unsigned int flags) ++static void __mptcp_push_pending(struct sock *sk, unsigned int flags) + { + struct sock *prev_ssk = NULL, *ssk = NULL; + struct mptcp_sock *msk = mptcp_sk(sk); +@@ -1681,14 +1681,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + + wait_for_memory: + set_bit(MPTCP_NOSPACE, &msk->flags); +- mptcp_push_pending(sk, msg->msg_flags); ++ __mptcp_push_pending(sk, msg->msg_flags); + ret = sk_stream_wait_memory(sk, &timeo); + if (ret) + goto out; + } + + if (copied) +- mptcp_push_pending(sk, msg->msg_flags); ++ __mptcp_push_pending(sk, msg->msg_flags); + + out: + release_sock(sk); +@@ -2944,13 +2944,14 @@ static void mptcp_release_cb(struct sock *sk) + { + unsigned long flags, nflags; + +- /* push_pending may touch wmem_reserved, do it before the later +- * cleanup +- */ +- if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags)) +- __mptcp_clean_una(sk); +- if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) { +- /* mptcp_push_pending() acquires the subflow socket lock ++ for (;;) { ++ flags = 0; ++ if (test_and_clear_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags)) ++ flags |= MPTCP_PUSH_PENDING; ++ if (!flags) ++ break; ++ ++ /* the following actions acquire the subflow socket lock + * + * 1) can't be invoked in atomic scope + * 2) must avoid ABBA deadlock with msk socket spinlock: the RX +@@ -2959,13 +2960,21 @@ static void mptcp_release_cb(struct sock *sk) + */ + + spin_unlock_bh(&sk->sk_lock.slock); +- mptcp_push_pending(sk, 0); ++ if (flags & MPTCP_PUSH_PENDING) ++ __mptcp_push_pending(sk, 0); ++ ++ cond_resched(); + spin_lock_bh(&sk->sk_lock.slock); + } ++ ++ if (test_and_clear_bit(MPTCP_CLEAN_UNA, &mptcp_sk(sk)->flags)) ++ __mptcp_clean_una(sk); + if (test_and_clear_bit(MPTCP_ERROR_REPORT, &mptcp_sk(sk)->flags)) + __mptcp_error_report(sk); + +- /* clear any wmem reservation and errors */ ++ /* push_pending may touch wmem_reserved, ensure we do the cleanup ++ * later ++ */ + __mptcp_update_wmem(sk); + __mptcp_update_rmem(sk); + +-- +2.30.1 + diff --git a/queue-5.11/mptcp-init-mptcp-request-socket-earlier.patch b/queue-5.11/mptcp-init-mptcp-request-socket-earlier.patch new file mode 100644 index 00000000000..53e10b735f8 --- /dev/null +++ b/queue-5.11/mptcp-init-mptcp-request-socket-earlier.patch @@ -0,0 +1,137 @@ +From 9449893a066c86d516b03abc590c558ef3976552 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 15:30:40 -0800 +Subject: mptcp: init mptcp request socket earlier + +From: Paolo Abeni + +[ Upstream commit d8b59efa64060d17b7b61f97d891de2d9f2bd9f0 ] + +The mptcp subflow route_req() callback performs the subflow +req initialization after the route_req() check. If the latter +fails, mptcp-specific bits of the current request sockets +are left uninitialized. + +The above causes bad things at req socket disposal time, when +the mptcp resources are cleared. + +This change addresses the issue by splitting subflow_init_req() +into the actual initialization and the mptcp-specific checks. +The initialization is moved before any possibly failing check. + +Reported-by: Christoph Paasch +Fixes: 7ea851d19b23 ("tcp: merge 'init_req' and 'route_req' functions") +Signed-off-by: Paolo Abeni +Signed-off-by: Mat Martineau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/subflow.c | 40 ++++++++++++++++------------------------ + 1 file changed, 16 insertions(+), 24 deletions(-) + +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 6c0205816a5d..f97f29df4505 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -92,7 +92,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req, + return msk; + } + +-static int __subflow_init_req(struct request_sock *req, const struct sock *sk_listener) ++static void subflow_init_req(struct request_sock *req, const struct sock *sk_listener) + { + struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); + +@@ -100,16 +100,6 @@ static int __subflow_init_req(struct request_sock *req, const struct sock *sk_li + subflow_req->mp_join = 0; + subflow_req->msk = NULL; + mptcp_token_init_request(req); +- +-#ifdef CONFIG_TCP_MD5SIG +- /* no MPTCP if MD5SIG is enabled on this socket or we may run out of +- * TCP option space. +- */ +- if (rcu_access_pointer(tcp_sk(sk_listener)->md5sig_info)) +- return -EINVAL; +-#endif +- +- return 0; + } + + /* Init mptcp request socket. +@@ -117,20 +107,23 @@ static int __subflow_init_req(struct request_sock *req, const struct sock *sk_li + * Returns an error code if a JOIN has failed and a TCP reset + * should be sent. + */ +-static int subflow_init_req(struct request_sock *req, +- const struct sock *sk_listener, +- struct sk_buff *skb) ++static int subflow_check_req(struct request_sock *req, ++ const struct sock *sk_listener, ++ struct sk_buff *skb) + { + struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk_listener); + struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req); + struct mptcp_options_received mp_opt; +- int ret; + + pr_debug("subflow_req=%p, listener=%p", subflow_req, listener); + +- ret = __subflow_init_req(req, sk_listener); +- if (ret) +- return 0; ++#ifdef CONFIG_TCP_MD5SIG ++ /* no MPTCP if MD5SIG is enabled on this socket or we may run out of ++ * TCP option space. ++ */ ++ if (rcu_access_pointer(tcp_sk(sk_listener)->md5sig_info)) ++ return -EINVAL; ++#endif + + mptcp_get_options(skb, &mp_opt); + +@@ -205,10 +198,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req, + struct mptcp_options_received mp_opt; + int err; + +- err = __subflow_init_req(req, sk_listener); +- if (err) +- return err; +- ++ subflow_init_req(req, sk_listener); + mptcp_get_options(skb, &mp_opt); + + if (mp_opt.mp_capable && mp_opt.mp_join) +@@ -248,12 +238,13 @@ static struct dst_entry *subflow_v4_route_req(const struct sock *sk, + int err; + + tcp_rsk(req)->is_mptcp = 1; ++ subflow_init_req(req, sk); + + dst = tcp_request_sock_ipv4_ops.route_req(sk, skb, fl, req); + if (!dst) + return NULL; + +- err = subflow_init_req(req, sk, skb); ++ err = subflow_check_req(req, sk, skb); + if (err == 0) + return dst; + +@@ -273,12 +264,13 @@ static struct dst_entry *subflow_v6_route_req(const struct sock *sk, + int err; + + tcp_rsk(req)->is_mptcp = 1; ++ subflow_init_req(req, sk); + + dst = tcp_request_sock_ipv6_ops.route_req(sk, skb, fl, req); + if (!dst) + return NULL; + +- err = subflow_init_req(req, sk, skb); ++ err = subflow_check_req(req, sk, skb); + if (err == 0) + return dst; + +-- +2.30.1 + diff --git a/queue-5.11/mptcp-provide-subflow-aware-release-function.patch b/queue-5.11/mptcp-provide-subflow-aware-release-function.patch new file mode 100644 index 00000000000..d13265e5df4 --- /dev/null +++ b/queue-5.11/mptcp-provide-subflow-aware-release-function.patch @@ -0,0 +1,119 @@ +From fcf0bc8efd5299a07ea390a6073cde1709eb5a64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Feb 2021 18:35:39 +0100 +Subject: mptcp: provide subflow aware release function + +From: Florian Westphal + +[ Upstream commit ad98dd37051e14fa8c785609430d907fcfd518ba ] + +mptcp re-used inet(6)_release, so the subflow sockets are ignored. +Need to invoke ip(v6)_mc_drop_socket function to ensure mcast join +resources get free'd. + +Fixes: 717e79c867ca5 ("mptcp: Add setsockopt()/getsockopt() socket operations") +Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/110 +Acked-by: Paolo Abeni +Signed-off-by: Florian Westphal +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 53 insertions(+), 2 deletions(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 88f2d900a347..c3299a4568a0 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ + #include + #if IS_ENABLED(CONFIG_MPTCP_IPV6) + #include ++#include + #endif + #include + #include +@@ -3368,10 +3370,34 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, + return mask; + } + ++static int mptcp_release(struct socket *sock) ++{ ++ struct mptcp_subflow_context *subflow; ++ struct sock *sk = sock->sk; ++ struct mptcp_sock *msk; ++ ++ if (!sk) ++ return 0; ++ ++ lock_sock(sk); ++ ++ msk = mptcp_sk(sk); ++ ++ mptcp_for_each_subflow(msk, subflow) { ++ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); ++ ++ ip_mc_drop_socket(ssk); ++ } ++ ++ release_sock(sk); ++ ++ return inet_release(sock); ++} ++ + static const struct proto_ops mptcp_stream_ops = { + .family = PF_INET, + .owner = THIS_MODULE, +- .release = inet_release, ++ .release = mptcp_release, + .bind = mptcp_bind, + .connect = mptcp_stream_connect, + .socketpair = sock_no_socketpair, +@@ -3418,10 +3444,35 @@ void __init mptcp_proto_init(void) + } + + #if IS_ENABLED(CONFIG_MPTCP_IPV6) ++static int mptcp6_release(struct socket *sock) ++{ ++ struct mptcp_subflow_context *subflow; ++ struct mptcp_sock *msk; ++ struct sock *sk = sock->sk; ++ ++ if (!sk) ++ return 0; ++ ++ lock_sock(sk); ++ ++ msk = mptcp_sk(sk); ++ ++ mptcp_for_each_subflow(msk, subflow) { ++ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); ++ ++ ip_mc_drop_socket(ssk); ++ ipv6_sock_mc_close(ssk); ++ ipv6_sock_ac_close(ssk); ++ } ++ ++ release_sock(sk); ++ return inet6_release(sock); ++} ++ + static const struct proto_ops mptcp_v6_stream_ops = { + .family = PF_INET6, + .owner = THIS_MODULE, +- .release = inet6_release, ++ .release = mptcp6_release, + .bind = mptcp_bind, + .connect = mptcp_stream_connect, + .socketpair = sock_no_socketpair, +-- +2.30.1 + diff --git a/queue-5.11/net-9p-advance-iov-on-empty-read.patch b/queue-5.11/net-9p-advance-iov-on-empty-read.patch new file mode 100644 index 00000000000..61fb49ff74b --- /dev/null +++ b/queue-5.11/net-9p-advance-iov-on-empty-read.patch @@ -0,0 +1,74 @@ +From 46838091498c3a9d0a517f117826d9e801284e5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Mar 2021 17:19:32 +0800 +Subject: net: 9p: advance iov on empty read + +From: Jisheng Zhang + +[ Upstream commit d65614a01d24704b016635abf5cc028a54e45a62 ] + +I met below warning when cating a small size(about 80bytes) txt file +on 9pfs(msize=2097152 is passed to 9p mount option), the reason is we +miss iov_iter_advance() if the read count is 0 for zerocopy case, so +we didn't truncate the pipe, then iov_iter_pipe() thinks the pipe is +full. Fix it by removing the exception for 0 to ensure to call +iov_iter_advance() even on empty read for zerocopy case. + +[ 8.279568] WARNING: CPU: 0 PID: 39 at lib/iov_iter.c:1203 iov_iter_pipe+0x31/0x40 +[ 8.280028] Modules linked in: +[ 8.280561] CPU: 0 PID: 39 Comm: cat Not tainted 5.11.0+ #6 +[ 8.281260] RIP: 0010:iov_iter_pipe+0x31/0x40 +[ 8.281974] Code: 2b 42 54 39 42 5c 76 22 c7 07 20 00 00 00 48 89 57 18 8b 42 50 48 c7 47 08 b +[ 8.283169] RSP: 0018:ffff888000cbbd80 EFLAGS: 00000246 +[ 8.283512] RAX: 0000000000000010 RBX: ffff888000117d00 RCX: 0000000000000000 +[ 8.283876] RDX: ffff88800031d600 RSI: 0000000000000000 RDI: ffff888000cbbd90 +[ 8.284244] RBP: ffff888000cbbe38 R08: 0000000000000000 R09: ffff8880008d2058 +[ 8.284605] R10: 0000000000000002 R11: ffff888000375510 R12: 0000000000000050 +[ 8.284964] R13: ffff888000cbbe80 R14: 0000000000000050 R15: ffff88800031d600 +[ 8.285439] FS: 00007f24fd8af600(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000 +[ 8.285844] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 8.286150] CR2: 00007f24fd7d7b90 CR3: 0000000000c97000 CR4: 00000000000406b0 +[ 8.286710] Call Trace: +[ 8.288279] generic_file_splice_read+0x31/0x1a0 +[ 8.289273] ? do_splice_to+0x2f/0x90 +[ 8.289511] splice_direct_to_actor+0xcc/0x220 +[ 8.289788] ? pipe_to_sendpage+0xa0/0xa0 +[ 8.290052] do_splice_direct+0x8b/0xd0 +[ 8.290314] do_sendfile+0x1ad/0x470 +[ 8.290576] do_syscall_64+0x2d/0x40 +[ 8.290818] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 8.291409] RIP: 0033:0x7f24fd7dca0a +[ 8.292511] Code: c3 0f 1f 80 00 00 00 00 4c 89 d2 4c 89 c6 e9 bd fd ff ff 0f 1f 44 00 00 31 8 +[ 8.293360] RSP: 002b:00007ffc20932818 EFLAGS: 00000206 ORIG_RAX: 0000000000000028 +[ 8.293800] RAX: ffffffffffffffda RBX: 0000000001000000 RCX: 00007f24fd7dca0a +[ 8.294153] RDX: 0000000000000000 RSI: 0000000000000003 RDI: 0000000000000001 +[ 8.294504] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 +[ 8.294867] R10: 0000000001000000 R11: 0000000000000206 R12: 0000000000000003 +[ 8.295217] R13: 0000000000000001 R14: 0000000000000001 R15: 0000000000000000 +[ 8.295782] ---[ end trace 63317af81b3ca24b ]--- + +Signed-off-by: Jisheng Zhang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/9p/client.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/net/9p/client.c b/net/9p/client.c +index 4f62f299da0c..0a9019da18f3 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -1623,10 +1623,6 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, + } + + p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count); +- if (!count) { +- p9_tag_remove(clnt, req); +- return 0; +- } + + if (non_zc) { + int n = copy_to_iter(dataptr, count, to); +-- +2.30.1 + diff --git a/queue-5.11/net-bonding-fix-error-return-code-of-bond_neigh_init.patch b/queue-5.11/net-bonding-fix-error-return-code-of-bond_neigh_init.patch new file mode 100644 index 00000000000..46b0676b3d1 --- /dev/null +++ b/queue-5.11/net-bonding-fix-error-return-code-of-bond_neigh_init.patch @@ -0,0 +1,47 @@ +From 9f147e1f5a783de142638e64a4e2fba236a5ef6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Mar 2021 19:11:02 -0800 +Subject: net: bonding: fix error return code of bond_neigh_init() + +From: Jia-Ju Bai + +[ Upstream commit 2055a99da8a253a357bdfd359b3338ef3375a26c ] + +When slave is NULL or slave_ops->ndo_neigh_setup is NULL, no error +return code of bond_neigh_init() is assigned. +To fix this bug, ret is assigned with -EINVAL in these cases. + +Fixes: 9e99bfefdbce ("bonding: fix bond_neigh_init()") +Reported-by: TOTE Robot +Signed-off-by: Jia-Ju Bai +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 5fe5232cc3f3..fba6b6d1b430 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3917,11 +3917,15 @@ static int bond_neigh_init(struct neighbour *n) + + rcu_read_lock(); + slave = bond_first_slave_rcu(bond); +- if (!slave) ++ if (!slave) { ++ ret = -EINVAL; + goto out; ++ } + slave_ops = slave->dev->netdev_ops; +- if (!slave_ops->ndo_neigh_setup) ++ if (!slave_ops->ndo_neigh_setup) { ++ ret = -EINVAL; + goto out; ++ } + + /* TODO: find another way [1] to implement this. + * Passing a zeroed structure is fragile, +-- +2.30.1 + diff --git a/queue-5.11/net-ethernet-aquantia-handle-error-cleanup-of-start-.patch b/queue-5.11/net-ethernet-aquantia-handle-error-cleanup-of-start-.patch new file mode 100644 index 00000000000..9ab118968f8 --- /dev/null +++ b/queue-5.11/net-ethernet-aquantia-handle-error-cleanup-of-start-.patch @@ -0,0 +1,50 @@ +From 6d380cc2591514de3725a7c41e9347f209b67508 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Feb 2021 05:17:57 +0000 +Subject: net: ethernet: aquantia: Handle error cleanup of start on open + +From: Nathan Rossi + +[ Upstream commit 8a28af7a3e85ddf358f8c41e401a33002f7a9587 ] + +The aq_nic_start function can fail in a variety of cases which leaves +the device in broken state. + +An example case where the start function fails is the +request_threaded_irq which can be interrupted, resulting in a EINTR +result. This can be manually triggered by bringing the link up (e.g. ip +link set up) and triggering a SIGINT on the initiating process (e.g. +Ctrl+C). This would put the device into a half configured state. +Subsequently bringing the link up again would cause the napi_enable to +BUG. + +In order to correctly clean up the failed attempt to start a device call +aq_nic_stop. + +Signed-off-by: Nathan Rossi +Reviewed-by: Igor Russkikh +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/aquantia/atlantic/aq_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c +index 8f70a3909929..4af0cd9530de 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c +@@ -71,8 +71,10 @@ static int aq_ndev_open(struct net_device *ndev) + goto err_exit; + + err = aq_nic_start(aq_nic); +- if (err < 0) ++ if (err < 0) { ++ aq_nic_stop(aq_nic); + goto err_exit; ++ } + + err_exit: + if (err < 0) +-- +2.30.1 + diff --git a/queue-5.11/net-introduce-can-specific-pointer-in-the-struct-net.patch b/queue-5.11/net-introduce-can-specific-pointer-in-the-struct-net.patch new file mode 100644 index 00000000000..3355416258f --- /dev/null +++ b/queue-5.11/net-introduce-can-specific-pointer-in-the-struct-net.patch @@ -0,0 +1,456 @@ +From 75671ccb4f7f77867c58fe711166cf4090aa4411 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Feb 2021 08:01:26 +0100 +Subject: net: introduce CAN specific pointer in the struct net_device + +From: Oleksij Rempel + +[ Upstream commit 4e096a18867a5a989b510f6999d9c6b6622e8f7b ] + +Since 20dd3850bcf8 ("can: Speed up CAN frame receiption by using +ml_priv") the CAN framework uses per device specific data in the AF_CAN +protocol. For this purpose the struct net_device->ml_priv is used. Later +the ml_priv usage in CAN was extended for other users, one of them being +CAN_J1939. + +Later in the kernel ml_priv was converted to an union, used by other +drivers. E.g. the tun driver started storing it's stats pointer. + +Since tun devices can claim to be a CAN device, CAN specific protocols +will wrongly interpret this pointer, which will cause system crashes. +Mostly this issue is visible in the CAN_J1939 stack. + +To fix this issue, we request a dedicated CAN pointer within the +net_device struct. + +Reported-by: syzbot+5138c4dd15a0401bec7b@syzkaller.appspotmail.com +Fixes: 20dd3850bcf8 ("can: Speed up CAN frame receiption by using ml_priv") +Fixes: ffd956eef69b ("can: introduce CAN midlayer private and allocate it automatically") +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Fixes: 497a5757ce4e ("tun: switch to net core provided statistics counters") +Signed-off-by: Oleksij Rempel +Link: https://lore.kernel.org/r/20210223070127.4538-1-o.rempel@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/can/dev/dev.c | 4 +++- + drivers/net/can/slcan.c | 4 +++- + drivers/net/can/vcan.c | 2 +- + drivers/net/can/vxcan.c | 6 +++++- + include/linux/can/can-ml.h | 12 ++++++++++++ + include/linux/netdevice.h | 34 +++++++++++++++++++++++++++++++++- + net/can/af_can.c | 34 ++-------------------------------- + net/can/j1939/main.c | 22 ++++++++-------------- + net/can/j1939/socket.c | 13 ++++--------- + net/can/proc.c | 19 +++++++++++++------ + 10 files changed, 84 insertions(+), 66 deletions(-) + +diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c +index 2a4f12c3c28b..a665afaeccd1 100644 +--- a/drivers/net/can/dev/dev.c ++++ b/drivers/net/can/dev/dev.c +@@ -747,6 +747,7 @@ EXPORT_SYMBOL_GPL(alloc_can_err_skb); + struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, + unsigned int txqs, unsigned int rxqs) + { ++ struct can_ml_priv *can_ml; + struct net_device *dev; + struct can_priv *priv; + int size; +@@ -778,7 +779,8 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, + priv = netdev_priv(dev); + priv->dev = dev; + +- dev->ml_priv = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN); ++ can_ml = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); + + if (echo_skb_max) { + priv->echo_skb_max = echo_skb_max; +diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c +index a1bd1be09548..30c8d53c9745 100644 +--- a/drivers/net/can/slcan.c ++++ b/drivers/net/can/slcan.c +@@ -516,6 +516,7 @@ static struct slcan *slc_alloc(void) + int i; + char name[IFNAMSIZ]; + struct net_device *dev = NULL; ++ struct can_ml_priv *can_ml; + struct slcan *sl; + int size; + +@@ -538,7 +539,8 @@ static struct slcan *slc_alloc(void) + + dev->base_addr = i; + sl = netdev_priv(dev); +- dev->ml_priv = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); ++ can_ml = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); + + /* Initialize channel control data */ + sl->magic = SLCAN_MAGIC; +diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c +index 39ca14b0585d..067705e2850b 100644 +--- a/drivers/net/can/vcan.c ++++ b/drivers/net/can/vcan.c +@@ -153,7 +153,7 @@ static void vcan_setup(struct net_device *dev) + dev->addr_len = 0; + dev->tx_queue_len = 0; + dev->flags = IFF_NOARP; +- dev->ml_priv = netdev_priv(dev); ++ can_set_ml_priv(dev, netdev_priv(dev)); + + /* set flags according to driver capabilities */ + if (echo) +diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c +index f9a524c5f6d6..8861a7d875e7 100644 +--- a/drivers/net/can/vxcan.c ++++ b/drivers/net/can/vxcan.c +@@ -141,6 +141,8 @@ static const struct net_device_ops vxcan_netdev_ops = { + + static void vxcan_setup(struct net_device *dev) + { ++ struct can_ml_priv *can_ml; ++ + dev->type = ARPHRD_CAN; + dev->mtu = CANFD_MTU; + dev->hard_header_len = 0; +@@ -149,7 +151,9 @@ static void vxcan_setup(struct net_device *dev) + dev->flags = (IFF_NOARP|IFF_ECHO); + dev->netdev_ops = &vxcan_netdev_ops; + dev->needs_free_netdev = true; +- dev->ml_priv = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); ++ ++ can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); ++ can_set_ml_priv(dev, can_ml); + } + + /* forward declaration for rtnl_create_link() */ +diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h +index 2f5d731ae251..8afa92d15a66 100644 +--- a/include/linux/can/can-ml.h ++++ b/include/linux/can/can-ml.h +@@ -44,6 +44,7 @@ + + #include + #include ++#include + + #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) + #define CAN_EFF_RCV_HASH_BITS 10 +@@ -65,4 +66,15 @@ struct can_ml_priv { + #endif + }; + ++static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev) ++{ ++ return netdev_get_ml_priv(dev, ML_PRIV_CAN); ++} ++ ++static inline void can_set_ml_priv(struct net_device *dev, ++ struct can_ml_priv *ml_priv) ++{ ++ netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN); ++} ++ + #endif /* CAN_ML_H */ +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index fb79ac497794..688c7477ec0a 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1607,6 +1607,12 @@ enum netdev_priv_flags { + #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER + #define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK + ++/* Specifies the type of the struct net_device::ml_priv pointer */ ++enum netdev_ml_priv_type { ++ ML_PRIV_NONE, ++ ML_PRIV_CAN, ++}; ++ + /** + * struct net_device - The DEVICE structure. + * +@@ -1802,6 +1808,7 @@ enum netdev_priv_flags { + * @nd_net: Network namespace this network device is inside + * + * @ml_priv: Mid-layer private ++ * @ml_priv_type: Mid-layer private type + * @lstats: Loopback statistics + * @tstats: Tunnel statistics + * @dstats: Dummy statistics +@@ -2114,8 +2121,10 @@ struct net_device { + possible_net_t nd_net; + + /* mid-layer private */ ++ void *ml_priv; ++ enum netdev_ml_priv_type ml_priv_type; ++ + union { +- void *ml_priv; + struct pcpu_lstats __percpu *lstats; + struct pcpu_sw_netstats __percpu *tstats; + struct pcpu_dstats __percpu *dstats; +@@ -2305,6 +2314,29 @@ static inline void netdev_reset_rx_headroom(struct net_device *dev) + netdev_set_rx_headroom(dev, -1); + } + ++static inline void *netdev_get_ml_priv(struct net_device *dev, ++ enum netdev_ml_priv_type type) ++{ ++ if (dev->ml_priv_type != type) ++ return NULL; ++ ++ return dev->ml_priv; ++} ++ ++static inline void netdev_set_ml_priv(struct net_device *dev, ++ void *ml_priv, ++ enum netdev_ml_priv_type type) ++{ ++ WARN(dev->ml_priv_type && dev->ml_priv_type != type, ++ "Overwriting already set ml_priv_type (%u) with different ml_priv_type (%u)!\n", ++ dev->ml_priv_type, type); ++ WARN(!dev->ml_priv_type && dev->ml_priv, ++ "Overwriting already set ml_priv and ml_priv_type is ML_PRIV_NONE!\n"); ++ ++ dev->ml_priv = ml_priv; ++ dev->ml_priv_type = type; ++} ++ + /* + * Net namespace inlines + */ +diff --git a/net/can/af_can.c b/net/can/af_can.c +index 837bb8af0ec3..cce2af10eb3e 100644 +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -304,8 +304,8 @@ static struct can_dev_rcv_lists *can_dev_rcv_lists_find(struct net *net, + struct net_device *dev) + { + if (dev) { +- struct can_ml_priv *ml_priv = dev->ml_priv; +- return &ml_priv->dev_rcv_lists; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ return &can_ml->dev_rcv_lists; + } else { + return net->can.rx_alldev_list; + } +@@ -790,25 +790,6 @@ void can_proto_unregister(const struct can_proto *cp) + } + EXPORT_SYMBOL(can_proto_unregister); + +-/* af_can notifier to create/remove CAN netdevice specific structs */ +-static int can_notifier(struct notifier_block *nb, unsigned long msg, +- void *ptr) +-{ +- struct net_device *dev = netdev_notifier_info_to_dev(ptr); +- +- if (dev->type != ARPHRD_CAN) +- return NOTIFY_DONE; +- +- switch (msg) { +- case NETDEV_REGISTER: +- WARN(!dev->ml_priv, +- "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n"); +- break; +- } +- +- return NOTIFY_DONE; +-} +- + static int can_pernet_init(struct net *net) + { + spin_lock_init(&net->can.rcvlists_lock); +@@ -876,11 +857,6 @@ static const struct net_proto_family can_family_ops = { + .owner = THIS_MODULE, + }; + +-/* notifier block for netdevice event */ +-static struct notifier_block can_netdev_notifier __read_mostly = { +- .notifier_call = can_notifier, +-}; +- + static struct pernet_operations can_pernet_ops __read_mostly = { + .init = can_pernet_init, + .exit = can_pernet_exit, +@@ -911,17 +887,12 @@ static __init int can_init(void) + err = sock_register(&can_family_ops); + if (err) + goto out_sock; +- err = register_netdevice_notifier(&can_netdev_notifier); +- if (err) +- goto out_notifier; + + dev_add_pack(&can_packet); + dev_add_pack(&canfd_packet); + + return 0; + +-out_notifier: +- sock_unregister(PF_CAN); + out_sock: + unregister_pernet_subsys(&can_pernet_ops); + out_pernet: +@@ -935,7 +906,6 @@ static __exit void can_exit(void) + /* protocol unregister */ + dev_remove_pack(&canfd_packet); + dev_remove_pack(&can_packet); +- unregister_netdevice_notifier(&can_netdev_notifier); + sock_unregister(PF_CAN); + + unregister_pernet_subsys(&can_pernet_ops); +diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c +index bb914d8b4216..da3a7a7bcff2 100644 +--- a/net/can/j1939/main.c ++++ b/net/can/j1939/main.c +@@ -140,9 +140,9 @@ static struct j1939_priv *j1939_priv_create(struct net_device *ndev) + static inline void j1939_priv_set(struct net_device *ndev, + struct j1939_priv *priv) + { +- struct can_ml_priv *can_ml_priv = ndev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + +- can_ml_priv->j1939_priv = priv; ++ can_ml->j1939_priv = priv; + } + + static void __j1939_priv_release(struct kref *kref) +@@ -211,12 +211,9 @@ static void __j1939_rx_release(struct kref *kref) + /* get pointer to priv without increasing ref counter */ + static inline struct j1939_priv *j1939_ndev_to_priv(struct net_device *ndev) + { +- struct can_ml_priv *can_ml_priv = ndev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + +- if (!can_ml_priv) +- return NULL; +- +- return can_ml_priv->j1939_priv; ++ return can_ml->j1939_priv; + } + + static struct j1939_priv *j1939_priv_get_by_ndev_locked(struct net_device *ndev) +@@ -225,9 +222,6 @@ static struct j1939_priv *j1939_priv_get_by_ndev_locked(struct net_device *ndev) + + lockdep_assert_held(&j1939_netdev_lock); + +- if (ndev->type != ARPHRD_CAN) +- return NULL; +- + priv = j1939_ndev_to_priv(ndev); + if (priv) + j1939_priv_get(priv); +@@ -348,15 +342,16 @@ static int j1939_netdev_notify(struct notifier_block *nb, + unsigned long msg, void *data) + { + struct net_device *ndev = netdev_notifier_info_to_dev(data); ++ struct can_ml_priv *can_ml = can_get_ml_priv(ndev); + struct j1939_priv *priv; + ++ if (!can_ml) ++ goto notify_done; ++ + priv = j1939_priv_get_by_ndev(ndev); + if (!priv) + goto notify_done; + +- if (ndev->type != ARPHRD_CAN) +- goto notify_put; +- + switch (msg) { + case NETDEV_DOWN: + j1939_cancel_active_session(priv, NULL); +@@ -365,7 +360,6 @@ static int j1939_netdev_notify(struct notifier_block *nb, + break; + } + +-notify_put: + j1939_priv_put(priv); + + notify_done: +diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c +index f23966526a88..56aa66147d5a 100644 +--- a/net/can/j1939/socket.c ++++ b/net/can/j1939/socket.c +@@ -12,6 +12,7 @@ + + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + ++#include + #include + #include + #include +@@ -453,6 +454,7 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) + j1939_jsk_del(priv, jsk); + j1939_local_ecu_put(priv, jsk->addr.src_name, jsk->addr.sa); + } else { ++ struct can_ml_priv *can_ml; + struct net_device *ndev; + + ndev = dev_get_by_index(net, addr->can_ifindex); +@@ -461,15 +463,8 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) + goto out_release_sock; + } + +- if (ndev->type != ARPHRD_CAN) { +- dev_put(ndev); +- ret = -ENODEV; +- goto out_release_sock; +- } +- +- if (!ndev->ml_priv) { +- netdev_warn_once(ndev, +- "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n"); ++ can_ml = can_get_ml_priv(ndev); ++ if (!can_ml) { + dev_put(ndev); + ret = -ENODEV; + goto out_release_sock; +diff --git a/net/can/proc.c b/net/can/proc.c +index 5ea8695f507e..b15760b5c1cc 100644 +--- a/net/can/proc.c ++++ b/net/can/proc.c +@@ -322,8 +322,11 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v) + + /* receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) +- can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) ++ can_rcvlist_proc_show_one(m, idx, dev, ++ &can_ml->dev_rcv_lists); + } + + rcu_read_unlock(); +@@ -375,8 +378,10 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v) + + /* sff receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) { +- dev_rcv_lists = dev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) { ++ dev_rcv_lists = &can_ml->dev_rcv_lists; + can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_sff, + ARRAY_SIZE(dev_rcv_lists->rx_sff)); + } +@@ -406,8 +411,10 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v) + + /* eff receive list for registered CAN devices */ + for_each_netdev_rcu(net, dev) { +- if (dev->type == ARPHRD_CAN && dev->ml_priv) { +- dev_rcv_lists = dev->ml_priv; ++ struct can_ml_priv *can_ml = can_get_ml_priv(dev); ++ ++ if (can_ml) { ++ dev_rcv_lists = &can_ml->dev_rcv_lists; + can_rcvlist_proc_show_array(m, dev, dev_rcv_lists->rx_eff, + ARRAY_SIZE(dev_rcv_lists->rx_eff)); + } +-- +2.30.1 + diff --git a/queue-5.11/net-ipa-fix-register-write-command-validation.patch b/queue-5.11/net-ipa-fix-register-write-command-validation.patch new file mode 100644 index 00000000000..6c89f3c5575 --- /dev/null +++ b/queue-5.11/net-ipa-fix-register-write-command-validation.patch @@ -0,0 +1,102 @@ +From 0f9778f94b64165b688527fbc23445d0e4c6f69c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Feb 2021 08:34:00 -0600 +Subject: net: ipa: fix register write command validation + +From: Alex Elder + +[ Upstream commit 2d65ed76924bc772d3974b0894d870b1aa63b34a ] + +In ipa_cmd_register_write_valid() we verify that values we will +supply to a REGISTER_WRITE IPA immediate command will fit in +the fields that need to hold them. This patch fixes some issues +in that function and ipa_cmd_register_write_offset_valid(). + +The dev_err() call in ipa_cmd_register_write_offset_valid() has +some printf format errors: + - The name of the register (corresponding to the string format + specifier) was not supplied. + - The IPA base offset and offset need to be supplied separately to + match the other format specifiers. +Also make the ~0 constant used there to compute the maximum +supported offset value explicitly unsigned. + +There are two other issues in ipa_cmd_register_write_valid(): + - There's no need to check the hash flush register for platforms + (like IPA v4.2) that do not support hashed tables + - The highest possible endpoint number, whose status register + offset is computed, is COUNT - 1, not COUNT. + +Fix these problems, and add some additional commentary. + +Signed-off-by: Alex Elder +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ipa/ipa_cmd.c | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ipa/ipa_cmd.c b/drivers/net/ipa/ipa_cmd.c +index 002e51448510..eb65a11e33ea 100644 +--- a/drivers/net/ipa/ipa_cmd.c ++++ b/drivers/net/ipa/ipa_cmd.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + + /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +- * Copyright (C) 2019-2020 Linaro Ltd. ++ * Copyright (C) 2019-2021 Linaro Ltd. + */ + + #include +@@ -244,11 +244,15 @@ static bool ipa_cmd_register_write_offset_valid(struct ipa *ipa, + if (ipa->version != IPA_VERSION_3_5_1) + bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK); + BUILD_BUG_ON(bit_count > 32); +- offset_max = ~0 >> (32 - bit_count); ++ offset_max = ~0U >> (32 - bit_count); + ++ /* Make sure the offset can be represented by the field(s) ++ * that holds it. Also make sure the offset is not outside ++ * the overall IPA memory range. ++ */ + if (offset > offset_max || ipa->mem_offset > offset_max - offset) { + dev_err(dev, "%s offset too large 0x%04x + 0x%04x > 0x%04x)\n", +- ipa->mem_offset + offset, offset_max); ++ name, ipa->mem_offset, offset, offset_max); + return false; + } + +@@ -261,12 +265,24 @@ static bool ipa_cmd_register_write_valid(struct ipa *ipa) + const char *name; + u32 offset; + +- offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version); +- name = "filter/route hash flush"; +- if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) +- return false; ++ /* If hashed tables are supported, ensure the hash flush register ++ * offset will fit in a register write IPA immediate command. ++ */ ++ if (ipa->version != IPA_VERSION_4_2) { ++ offset = ipa_reg_filt_rout_hash_flush_offset(ipa->version); ++ name = "filter/route hash flush"; ++ if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) ++ return false; ++ } + +- offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT); ++ /* Each endpoint can have a status endpoint associated with it, ++ * and this is recorded in an endpoint register. If the modem ++ * crashes, we reset the status endpoint for all modem endpoints ++ * using a register write IPA immediate command. Make sure the ++ * worst case (highest endpoint number) offset of that endpoint ++ * fits in the register write command field(s) that must hold it. ++ */ ++ offset = IPA_REG_ENDP_STATUS_N_OFFSET(IPA_ENDPOINT_COUNT - 1); + name = "maximal endpoint status"; + if (!ipa_cmd_register_write_offset_valid(ipa, name, offset)) + return false; +-- +2.30.1 + diff --git a/queue-5.11/net-ipa-remove-two-unused-register-definitions.patch b/queue-5.11/net-ipa-remove-two-unused-register-definitions.patch new file mode 100644 index 00000000000..3ede189b400 --- /dev/null +++ b/queue-5.11/net-ipa-remove-two-unused-register-definitions.patch @@ -0,0 +1,45 @@ +From 17d05c00bb0bafc8323081eb42cc41ee80ac1137 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Feb 2021 16:10:57 -0600 +Subject: net: ipa: remove two unused register definitions + +From: Alex Elder + +[ Upstream commit d5bc5015eb9d64cbd14e467db1a56db1472d0d6c ] + +We do not support inter-EE channel or event ring commands. Inter-EE +interrupts are disabled (and never re-enabled) for all channels and +event rings, so we have no need for the GSI registers that clear +those interrupt conditions. So remove their definitions. + +Signed-off-by: Alex Elder +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ipa/gsi_reg.h | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h +index 0e138bbd8205..299456e70f28 100644 +--- a/drivers/net/ipa/gsi_reg.h ++++ b/drivers/net/ipa/gsi_reg.h +@@ -59,16 +59,6 @@ + #define GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(ee) \ + (0x0000c01c + 0x1000 * (ee)) + +-#define GSI_INTER_EE_SRC_CH_IRQ_CLR_OFFSET \ +- GSI_INTER_EE_N_SRC_CH_IRQ_CLR_OFFSET(GSI_EE_AP) +-#define GSI_INTER_EE_N_SRC_CH_IRQ_CLR_OFFSET(ee) \ +- (0x0000c028 + 0x1000 * (ee)) +- +-#define GSI_INTER_EE_SRC_EV_CH_IRQ_CLR_OFFSET \ +- GSI_INTER_EE_N_SRC_EV_CH_IRQ_CLR_OFFSET(GSI_EE_AP) +-#define GSI_INTER_EE_N_SRC_EV_CH_IRQ_CLR_OFFSET(ee) \ +- (0x0000c02c + 0x1000 * (ee)) +- + #define GSI_CH_C_CNTXT_0_OFFSET(ch) \ + GSI_EE_N_CH_C_CNTXT_0_OFFSET((ch), GSI_EE_AP) + #define GSI_EE_N_CH_C_CNTXT_0_OFFSET(ch, ee) \ +-- +2.30.1 + diff --git a/queue-5.11/net-ipa-use-a-separate-pointer-for-adjusted-gsi-memo.patch b/queue-5.11/net-ipa-use-a-separate-pointer-for-adjusted-gsi-memo.patch new file mode 100644 index 00000000000..5f093764f2b --- /dev/null +++ b/queue-5.11/net-ipa-use-a-separate-pointer-for-adjusted-gsi-memo.patch @@ -0,0 +1,198 @@ +From c3899b93aa92b8d0a10b2a00564d0178e863d476 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Feb 2021 08:33:58 -0600 +Subject: net: ipa: use a separate pointer for adjusted GSI memory + +From: Alex Elder + +[ Upstream commit 571b1e7e58ad30b3a842254aea50d2e83b2396e1 ] + +This patch actually fixes a bug, though it doesn't affect the two +platforms supported currently. The fix implements GSI memory +pointers a bit differently. + +For IPA version 4.5 and above, the address space for almost all GSI +registers is adjusted downward by a fixed amount. This is currently +handled by adjusting the I/O virtual address pointer after it has +been mapped. The bug is that the pointer is not "de-adjusted" as it +should be when it's unmapped. + +This patch fixes that error, but it does so by maintaining one "raw" +pointer for the mapped memory range. This is assigned when the +memory is mapped and used to unmap the memory. This pointer is also +used to access the two registers that do *not* sit in the "adjusted" +memory space. + +Rather than adjusting *that* pointer, we maintain a separate pointer +that's an adjusted copy of the "raw" pointer, and that is used for +most GSI register accesses. + +Signed-off-by: Alex Elder +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ipa/gsi.c | 28 ++++++++++++---------------- + drivers/net/ipa/gsi.h | 5 +++-- + drivers/net/ipa/gsi_reg.h | 21 +++++++++++++-------- + 3 files changed, 28 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c +index b77f5fef7aec..febfac75dd6a 100644 +--- a/drivers/net/ipa/gsi.c ++++ b/drivers/net/ipa/gsi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + + /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +- * Copyright (C) 2018-2020 Linaro Ltd. ++ * Copyright (C) 2018-2021 Linaro Ltd. + */ + + #include +@@ -195,8 +195,6 @@ static void gsi_irq_type_disable(struct gsi *gsi, enum gsi_irq_type_id type_id) + /* Turn off all GSI interrupts initially */ + static void gsi_irq_setup(struct gsi *gsi) + { +- u32 adjust; +- + /* Disable all interrupt types */ + gsi_irq_type_update(gsi, 0); + +@@ -206,10 +204,9 @@ static void gsi_irq_setup(struct gsi *gsi) + iowrite32(0, gsi->virt + GSI_CNTXT_GLOB_IRQ_EN_OFFSET); + iowrite32(0, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET); + +- /* Reverse the offset adjustment for inter-EE register offsets */ +- adjust = gsi->version < IPA_VERSION_4_5 ? 0 : GSI_EE_REG_ADJUST; +- iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_CH_IRQ_OFFSET); +- iowrite32(0, gsi->virt + adjust + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET); ++ /* The inter-EE registers are in the non-adjusted address range */ ++ iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_CH_IRQ_OFFSET); ++ iowrite32(0, gsi->virt_raw + GSI_INTER_EE_SRC_EV_CH_IRQ_OFFSET); + + iowrite32(0, gsi->virt + GSI_CNTXT_GSI_IRQ_EN_OFFSET); + } +@@ -2115,9 +2112,8 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, + gsi->dev = dev; + gsi->version = version; + +- /* The GSI layer performs NAPI on all endpoints. NAPI requires a +- * network device structure, but the GSI layer does not have one, +- * so we must create a dummy network device for this purpose. ++ /* GSI uses NAPI on all channels. Create a dummy network device ++ * for the channel NAPI contexts to be associated with. + */ + init_dummy_netdev(&gsi->dummy_dev); + +@@ -2142,13 +2138,13 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, + return -EINVAL; + } + +- gsi->virt = ioremap(res->start, size); +- if (!gsi->virt) { ++ gsi->virt_raw = ioremap(res->start, size); ++ if (!gsi->virt_raw) { + dev_err(dev, "unable to remap \"gsi\" memory\n"); + return -ENOMEM; + } +- /* Adjust register range pointer downward for newer IPA versions */ +- gsi->virt -= adjust; ++ /* Most registers are accessed using an adjusted register range */ ++ gsi->virt = gsi->virt_raw - adjust; + + init_completion(&gsi->completion); + +@@ -2167,7 +2163,7 @@ int gsi_init(struct gsi *gsi, struct platform_device *pdev, + err_irq_exit: + gsi_irq_exit(gsi); + err_iounmap: +- iounmap(gsi->virt); ++ iounmap(gsi->virt_raw); + + return ret; + } +@@ -2178,7 +2174,7 @@ void gsi_exit(struct gsi *gsi) + mutex_destroy(&gsi->mutex); + gsi_channel_exit(gsi); + gsi_irq_exit(gsi); +- iounmap(gsi->virt); ++ iounmap(gsi->virt_raw); + } + + /* The maximum number of outstanding TREs on a channel. This limits +diff --git a/drivers/net/ipa/gsi.h b/drivers/net/ipa/gsi.h +index 96c9aed397aa..696c9825834a 100644 +--- a/drivers/net/ipa/gsi.h ++++ b/drivers/net/ipa/gsi.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + + /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +- * Copyright (C) 2018-2020 Linaro Ltd. ++ * Copyright (C) 2018-2021 Linaro Ltd. + */ + #ifndef _GSI_H_ + #define _GSI_H_ +@@ -150,7 +150,8 @@ struct gsi { + struct device *dev; /* Same as IPA device */ + enum ipa_version version; + struct net_device dummy_dev; /* needed for NAPI */ +- void __iomem *virt; ++ void __iomem *virt_raw; /* I/O mapped address range */ ++ void __iomem *virt; /* Adjusted for most registers */ + u32 irq; + u32 channel_count; + u32 evt_ring_count; +diff --git a/drivers/net/ipa/gsi_reg.h b/drivers/net/ipa/gsi_reg.h +index 299456e70f28..1622d8cf8dea 100644 +--- a/drivers/net/ipa/gsi_reg.h ++++ b/drivers/net/ipa/gsi_reg.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + + /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +- * Copyright (C) 2018-2020 Linaro Ltd. ++ * Copyright (C) 2018-2021 Linaro Ltd. + */ + #ifndef _GSI_REG_H_ + #define _GSI_REG_H_ +@@ -38,17 +38,21 @@ + * (though the actual limit is hardware-dependent). + */ + +-/* GSI EE registers as a group are shifted downward by a fixed +- * constant amount for IPA versions 4.5 and beyond. This applies +- * to all GSI registers we use *except* the ones that disable +- * inter-EE interrupts for channels and event channels. ++/* GSI EE registers as a group are shifted downward by a fixed constant amount ++ * for IPA versions 4.5 and beyond. This applies to all GSI registers we use ++ * *except* the ones that disable inter-EE interrupts for channels and event ++ * channels. + * +- * We handle this by adjusting the pointer to the mapped GSI memory +- * region downward. Then in the one place we use them (gsi_irq_setup()) +- * we undo that adjustment for the inter-EE interrupt registers. ++ * The "raw" (not adjusted) GSI register range is mapped, and a pointer to ++ * the mapped range is held in gsi->virt_raw. The inter-EE interrupt ++ * registers are accessed using that pointer. ++ * ++ * Most registers are accessed using gsi->virt, which is a copy of the "raw" ++ * pointer, adjusted downward by the fixed amount. + */ + #define GSI_EE_REG_ADJUST 0x0000d000 /* IPA v4.5+ */ + ++/* The two inter-EE IRQ register offsets are relative to gsi->virt_raw */ + #define GSI_INTER_EE_SRC_CH_IRQ_OFFSET \ + GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(GSI_EE_AP) + #define GSI_INTER_EE_N_SRC_CH_IRQ_OFFSET(ee) \ +@@ -59,6 +63,7 @@ + #define GSI_INTER_EE_N_SRC_EV_CH_IRQ_OFFSET(ee) \ + (0x0000c01c + 0x1000 * (ee)) + ++/* All other register offsets are relative to gsi->virt */ + #define GSI_CH_C_CNTXT_0_OFFSET(ch) \ + GSI_EE_N_CH_C_CNTXT_0_OFFSET((ch), GSI_EE_AP) + #define GSI_EE_N_CH_C_CNTXT_0_OFFSET(ch, ee) \ +-- +2.30.1 + diff --git a/queue-5.11/net-mvpp2-fix-interrupt-mask-unmask-skip-condition.patch b/queue-5.11/net-mvpp2-fix-interrupt-mask-unmask-skip-condition.patch new file mode 100644 index 00000000000..f320d539c62 --- /dev/null +++ b/queue-5.11/net-mvpp2-fix-interrupt-mask-unmask-skip-condition.patch @@ -0,0 +1,48 @@ +From cc725cfc843f5655ef14da635379d5c171646333 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Mar 2021 19:11:09 -0400 +Subject: net: mvpp2: fix interrupt mask/unmask skip condition + +[ Upstream commit 7867299cde34e9c2d2c676f2a384a9d5853b914d ] + +The condition should be skipped if CPU ID equal to nthreads. +The patch doesn't fix any actual issue since +nthreads = min_t(unsigned int, num_present_cpus(), MVPP2_MAX_THREADS). +On all current Armada platforms, the number of CPU's is +less than MVPP2_MAX_THREADS. + +Fixes: e531f76757eb ("net: mvpp2: handle cases where more CPUs are available than s/w threads") +Reported-by: Russell King +Signed-off-by: Stefan Chulski +Reviewed-by: Russell King +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +index 358119d98358..e6f9b5345b70 100644 +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +@@ -1153,7 +1153,7 @@ static void mvpp2_interrupts_unmask(void *arg) + u32 val; + + /* If the thread isn't used, don't do anything */ +- if (smp_processor_id() > port->priv->nthreads) ++ if (smp_processor_id() >= port->priv->nthreads) + return; + + val = MVPP2_CAUSE_MISC_SUM_MASK | +@@ -2287,7 +2287,7 @@ static void mvpp2_txq_sent_counter_clear(void *arg) + int queue; + + /* If the thread isn't used, don't do anything */ +- if (smp_processor_id() > port->priv->nthreads) ++ if (smp_processor_id() >= port->priv->nthreads) + return; + + for (queue = 0; queue < port->ntxqs; queue++) { +-- +2.30.1 + diff --git a/queue-5.11/net-wan-lmc-unregister-device-when-no-matching-devic.patch b/queue-5.11/net-wan-lmc-unregister-device-when-no-matching-devic.patch new file mode 100644 index 00000000000..c0bec5857a7 --- /dev/null +++ b/queue-5.11/net-wan-lmc-unregister-device-when-no-matching-devic.patch @@ -0,0 +1,96 @@ +From 77782bdf5143f7c4cc8318a3fc8d1bc67d907056 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Feb 2021 14:17:56 -0500 +Subject: net: wan/lmc: unregister device when no matching device is found + +From: Tong Zhang + +[ Upstream commit 62e69bc419772638369eff8ff81340bde8aceb61 ] + +lmc set sc->lmc_media pointer when there is a matching device. +However, when no matching device is found, this pointer is NULL +and the following dereference will result in a null-ptr-deref. + +To fix this issue, unregister the hdlc device and return an error. + +[ 4.569359] BUG: KASAN: null-ptr-deref in lmc_init_one.cold+0x2b6/0x55d [lmc] +[ 4.569748] Read of size 8 at addr 0000000000000008 by task modprobe/95 +[ 4.570102] +[ 4.570187] CPU: 0 PID: 95 Comm: modprobe Not tainted 5.11.0-rc7 #94 +[ 4.570527] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-preb4 +[ 4.571125] Call Trace: +[ 4.571261] dump_stack+0x7d/0xa3 +[ 4.571445] kasan_report.cold+0x10c/0x10e +[ 4.571667] ? lmc_init_one.cold+0x2b6/0x55d [lmc] +[ 4.571932] lmc_init_one.cold+0x2b6/0x55d [lmc] +[ 4.572186] ? lmc_mii_readreg+0xa0/0xa0 [lmc] +[ 4.572432] local_pci_probe+0x6f/0xb0 +[ 4.572639] pci_device_probe+0x171/0x240 +[ 4.572857] ? pci_device_remove+0xe0/0xe0 +[ 4.573080] ? kernfs_create_link+0xb6/0x110 +[ 4.573315] ? sysfs_do_create_link_sd.isra.0+0x76/0xe0 +[ 4.573598] really_probe+0x161/0x420 +[ 4.573799] driver_probe_device+0x6d/0xd0 +[ 4.574022] device_driver_attach+0x82/0x90 +[ 4.574249] ? device_driver_attach+0x90/0x90 +[ 4.574485] __driver_attach+0x60/0x100 +[ 4.574694] ? device_driver_attach+0x90/0x90 +[ 4.574931] bus_for_each_dev+0xe1/0x140 +[ 4.575146] ? subsys_dev_iter_exit+0x10/0x10 +[ 4.575387] ? klist_node_init+0x61/0x80 +[ 4.575602] bus_add_driver+0x254/0x2a0 +[ 4.575812] driver_register+0xd3/0x150 +[ 4.576021] ? 0xffffffffc0018000 +[ 4.576202] do_one_initcall+0x84/0x250 +[ 4.576411] ? trace_event_raw_event_initcall_finish+0x150/0x150 +[ 4.576733] ? unpoison_range+0xf/0x30 +[ 4.576938] ? ____kasan_kmalloc.constprop.0+0x84/0xa0 +[ 4.577219] ? unpoison_range+0xf/0x30 +[ 4.577423] ? unpoison_range+0xf/0x30 +[ 4.577628] do_init_module+0xf8/0x350 +[ 4.577833] load_module+0x3fe6/0x4340 +[ 4.578038] ? vm_unmap_ram+0x1d0/0x1d0 +[ 4.578247] ? ____kasan_kmalloc.constprop.0+0x84/0xa0 +[ 4.578526] ? module_frob_arch_sections+0x20/0x20 +[ 4.578787] ? __do_sys_finit_module+0x108/0x170 +[ 4.579037] __do_sys_finit_module+0x108/0x170 +[ 4.579278] ? __ia32_sys_init_module+0x40/0x40 +[ 4.579523] ? file_open_root+0x200/0x200 +[ 4.579742] ? do_sys_open+0x85/0xe0 +[ 4.579938] ? filp_open+0x50/0x50 +[ 4.580125] ? exit_to_user_mode_prepare+0xfc/0x130 +[ 4.580390] do_syscall_64+0x33/0x40 +[ 4.580586] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 4.580859] RIP: 0033:0x7f1a724c3cf7 +[ 4.581054] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 48 891 +[ 4.582043] RSP: 002b:00007fff44941c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 +[ 4.582447] RAX: ffffffffffffffda RBX: 00000000012ada70 RCX: 00007f1a724c3cf7 +[ 4.582827] RDX: 0000000000000000 RSI: 00000000012ac9e0 RDI: 0000000000000003 +[ 4.583207] RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000001 +[ 4.583587] R10: 00007f1a72527300 R11: 0000000000000246 R12: 00000000012ac9e0 +[ 4.583968] R13: 0000000000000000 R14: 00000000012acc90 R15: 0000000000000001 +[ 4.584349] ================================================================== + +Signed-off-by: Tong Zhang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/wan/lmc/lmc_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c +index 93c7e8502845..ebb568f9bc66 100644 +--- a/drivers/net/wan/lmc/lmc_main.c ++++ b/drivers/net/wan/lmc/lmc_main.c +@@ -899,6 +899,8 @@ static int lmc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + break; + default: + printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name); ++ unregister_hdlc_device(dev); ++ return -EIO; + break; + } + +-- +2.30.1 + diff --git a/queue-5.11/netdevsim-dev-initialize-fib-module-after-debugfs.patch b/queue-5.11/netdevsim-dev-initialize-fib-module-after-debugfs.patch new file mode 100644 index 00000000000..b63bb3f433d --- /dev/null +++ b/queue-5.11/netdevsim-dev-initialize-fib-module-after-debugfs.patch @@ -0,0 +1,138 @@ +From 4d95d0daf3554e064e950868cfc1fa69e5772f55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Feb 2021 10:22:55 +0200 +Subject: netdevsim: dev: Initialize FIB module after debugfs + +From: Ido Schimmel + +[ Upstream commit f57ab5b75f7193e194c83616cd104f41c8350f68 ] + +Initialize the dummy FIB offload module after debugfs, so that the FIB +module could create its own directory there. + +Signed-off-by: Amit Cohen +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/netdevsim/dev.c | 40 +++++++++++++++++++------------------ + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c +index 816af1f55e2c..dbeb29fa16e8 100644 +--- a/drivers/net/netdevsim/dev.c ++++ b/drivers/net/netdevsim/dev.c +@@ -1012,23 +1012,25 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, + nsim_dev->fw_update_status = true; + nsim_dev->fw_update_overwrite_mask = 0; + +- nsim_dev->fib_data = nsim_fib_create(devlink, extack); +- if (IS_ERR(nsim_dev->fib_data)) +- return PTR_ERR(nsim_dev->fib_data); +- + nsim_devlink_param_load_driverinit_values(devlink); + + err = nsim_dev_dummy_region_init(nsim_dev, devlink); + if (err) +- goto err_fib_destroy; ++ return err; + + err = nsim_dev_traps_init(devlink); + if (err) + goto err_dummy_region_exit; + ++ nsim_dev->fib_data = nsim_fib_create(devlink, extack); ++ if (IS_ERR(nsim_dev->fib_data)) { ++ err = PTR_ERR(nsim_dev->fib_data); ++ goto err_traps_exit; ++ } ++ + err = nsim_dev_health_init(nsim_dev, devlink); + if (err) +- goto err_traps_exit; ++ goto err_fib_destroy; + + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + if (err) +@@ -1043,12 +1045,12 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, + + err_health_exit: + nsim_dev_health_exit(nsim_dev); ++err_fib_destroy: ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_traps_exit: + nsim_dev_traps_exit(devlink); + err_dummy_region_exit: + nsim_dev_dummy_region_exit(nsim_dev); +-err_fib_destroy: +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + return err; + } + +@@ -1080,15 +1082,9 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + if (err) + goto err_devlink_free; + +- nsim_dev->fib_data = nsim_fib_create(devlink, NULL); +- if (IS_ERR(nsim_dev->fib_data)) { +- err = PTR_ERR(nsim_dev->fib_data); +- goto err_resources_unregister; +- } +- + err = devlink_register(devlink, &nsim_bus_dev->dev); + if (err) +- goto err_fib_destroy; ++ goto err_resources_unregister; + + err = devlink_params_register(devlink, nsim_devlink_params, + ARRAY_SIZE(nsim_devlink_params)); +@@ -1108,9 +1104,15 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) + if (err) + goto err_traps_exit; + ++ nsim_dev->fib_data = nsim_fib_create(devlink, NULL); ++ if (IS_ERR(nsim_dev->fib_data)) { ++ err = PTR_ERR(nsim_dev->fib_data); ++ goto err_debugfs_exit; ++ } ++ + err = nsim_dev_health_init(nsim_dev, devlink); + if (err) +- goto err_debugfs_exit; ++ goto err_fib_destroy; + + err = nsim_bpf_dev_init(nsim_dev); + if (err) +@@ -1128,6 +1130,8 @@ err_bpf_dev_exit: + nsim_bpf_dev_exit(nsim_dev); + err_health_exit: + nsim_dev_health_exit(nsim_dev); ++err_fib_destroy: ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_debugfs_exit: + nsim_dev_debugfs_exit(nsim_dev); + err_traps_exit: +@@ -1139,8 +1143,6 @@ err_params_unregister: + ARRAY_SIZE(nsim_devlink_params)); + err_dl_unregister: + devlink_unregister(devlink); +-err_fib_destroy: +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + err_resources_unregister: + devlink_resources_unregister(devlink, NULL); + err_devlink_free: +@@ -1157,10 +1159,10 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) + debugfs_remove(nsim_dev->take_snapshot); + nsim_dev_port_del_all(nsim_dev); + nsim_dev_health_exit(nsim_dev); ++ nsim_fib_destroy(devlink, nsim_dev->fib_data); + nsim_dev_traps_exit(devlink); + nsim_dev_dummy_region_exit(nsim_dev); + mutex_destroy(&nsim_dev->port_list_lock); +- nsim_fib_destroy(devlink, nsim_dev->fib_data); + } + + void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev) +-- +2.30.1 + diff --git a/queue-5.11/rtw88-coex-8821c-correct-antenna-switch-function.patch b/queue-5.11/rtw88-coex-8821c-correct-antenna-switch-function.patch new file mode 100644 index 00000000000..7718aeb463b --- /dev/null +++ b/queue-5.11/rtw88-coex-8821c-correct-antenna-switch-function.patch @@ -0,0 +1,67 @@ +From 981878872b20ef21348441583fbcbdfc55536fdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Feb 2021 13:50:10 +0800 +Subject: rtw88: coex: 8821c: correct antenna switch function + +From: Guo-Feng Fan + +[ Upstream commit adba838af159914eb98fcd55bfd3a89c9a7d41a8 ] + +This patch fixes a defect that uses incorrect function to access +registers. Use 8 and 32 bit access function to access 8 and 32 bit long +data respectively. + +Signed-off-by: Guo-Feng Fan +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20210202055012.8296-2-pkshih@realtek.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +index fbfd85439d1f..88fb49486ee0 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -719,8 +719,8 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + regval = (!polarity_inverse ? 0x1 : 0x2); + } + +- rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, +- regval); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, ++ regval); + break; + case COEX_SWITCH_CTRL_BY_PTA: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); +@@ -730,8 +730,8 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + PTA_CTRL_PIN); + + regval = (!polarity_inverse ? 0x2 : 0x1); +- rtw_write8_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, +- regval); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, BIT_MASK_R_RFE_SEL_15, ++ regval); + break; + case COEX_SWITCH_CTRL_BY_ANTDIV: + rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); +@@ -757,11 +757,11 @@ static void rtw8821c_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, + } + + if (ctrl_type == COEX_SWITCH_CTRL_BY_BT) { +- rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); +- rtw_write32_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); ++ rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); ++ rtw_write8_clr(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } else { +- rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); +- rtw_write32_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); ++ rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE1); ++ rtw_write8_set(rtwdev, REG_CTRL_TYPE, BIT_CTRL_TYPE2); + } + } + +-- +2.30.1 + diff --git a/queue-5.11/series b/queue-5.11/series index cda809e84d3..b03ff83a58a 100644 --- a/queue-5.11/series +++ b/queue-5.11/series @@ -37,3 +37,30 @@ nouveau-skip-unvailable-ttm-page-entries.patch static_call-align-static_call_is_init-patching-condi.patch ext4-do-not-iput-inode-under-running-transaction-in-.patch io_uring-call-req_set_fail_links-on-short-send-msg-r.patch +net-mvpp2-fix-interrupt-mask-unmask-skip-condition.patch +mptcp-deliver-ssk-errors-to-msk.patch +mptcp-fix-poll-after-shutdown.patch +mptcp-init-mptcp-request-socket-earlier.patch +mptcp-add-a-missing-retransmission-timer-scheduling.patch +flow_dissector-fix-ttl-and-tos-dissection-on-ipv4-fr.patch +mptcp-fix-data_fin-processing-for-orphaned-sockets.patch +mptcp-provide-subflow-aware-release-function.patch +can-dev-move-driver-related-infrastructure-into-sepa.patch +net-introduce-can-specific-pointer-in-the-struct-net.patch +mptcp-fix-race-in-release_cb.patch +net-bonding-fix-error-return-code-of-bond_neigh_init.patch +mptcp-fix-bit-mptcp_push_pending-tests.patch +can-tcan4x5x-fix-max-register-value.patch +brcmfmac-clear-eap-association-status-bits-on-linkdo.patch +ath11k-add-ieee80211_unregister_hw-to-avoid-kernel-c.patch +rtw88-coex-8821c-correct-antenna-switch-function.patch +netdevsim-dev-initialize-fib-module-after-debugfs.patch +iwlwifi-pcie-don-t-disable-interrupts-for-reg_lock.patch +ath10k-hold-rcu-lock-when-calling-ieee80211_find_sta.patch +net-ethernet-aquantia-handle-error-cleanup-of-start-.patch +appletalk-fix-skb-allocation-size-in-loopback-case.patch +net-ipa-remove-two-unused-register-definitions.patch +net-ipa-use-a-separate-pointer-for-adjusted-gsi-memo.patch +net-ipa-fix-register-write-command-validation.patch +net-wan-lmc-unregister-device-when-no-matching-devic.patch +net-9p-advance-iov-on-empty-read.patch