From: Sasha Levin Date: Sat, 22 Jun 2024 23:36:21 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v6.1.96~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=136254e66588d427da7243df3a9b53391dc02551;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/cipso-fix-total-option-length-computation.patch b/queue-5.4/cipso-fix-total-option-length-computation.patch new file mode 100644 index 00000000000..52a057c0f00 --- /dev/null +++ b/queue-5.4/cipso-fix-total-option-length-computation.patch @@ -0,0 +1,52 @@ +From 83e41f47076ab253d523aefb231a6b84c7f509dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Jun 2024 18:07:52 +0200 +Subject: cipso: fix total option length computation + +From: Ondrej Mosnacek + +[ Upstream commit 9f36169912331fa035d7b73a91252d7c2512eb1a ] + +As evident from the definition of ip_options_get(), the IP option +IPOPT_END is used to pad the IP option data array, not IPOPT_NOP. Yet +the loop that walks the IP options to determine the total IP options +length in cipso_v4_delopt() doesn't take IPOPT_END into account. + +Fix it by recognizing the IPOPT_END value as the end of actual options. + +Fixes: 014ab19a69c3 ("selinux: Set socket NetLabel based on connection endpoint") +Signed-off-by: Ondrej Mosnacek +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/cipso_ipv4.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 42eaad5e515f8..39a6f0d34208e 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -2015,12 +2015,16 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) + * from there we can determine the new total option length */ + iter = 0; + optlen_new = 0; +- while (iter < opt->opt.optlen) +- if (opt->opt.__data[iter] != IPOPT_NOP) { ++ while (iter < opt->opt.optlen) { ++ if (opt->opt.__data[iter] == IPOPT_END) { ++ break; ++ } else if (opt->opt.__data[iter] == IPOPT_NOP) { ++ iter++; ++ } else { + iter += opt->opt.__data[iter + 1]; + optlen_new = iter; +- } else +- iter++; ++ } ++ } + hdr_delta = opt->opt.optlen; + opt->opt.optlen = (optlen_new + 3) & ~3; + hdr_delta -= opt->opt.optlen; +-- +2.43.0 + diff --git a/queue-5.4/ipv6-prevent-possible-null-deref-in-fib6_nh_init.patch b/queue-5.4/ipv6-prevent-possible-null-deref-in-fib6_nh_init.patch new file mode 100644 index 00000000000..f70d3f619d6 --- /dev/null +++ b/queue-5.4/ipv6-prevent-possible-null-deref-in-fib6_nh_init.patch @@ -0,0 +1,77 @@ +From 9315f0c8c179ab313601d53c56f3052183a4487b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 08:20:02 +0000 +Subject: ipv6: prevent possible NULL deref in fib6_nh_init() + +From: Eric Dumazet + +[ Upstream commit 2eab4543a2204092c3a7af81d7d6c506e59a03a6 ] + +syzbot reminds us that in6_dev_get() can return NULL. + +fib6_nh_init() + ip6_validate_gw( &idev ) + ip6_route_check_nh( idev ) + *idev = in6_dev_get(dev); // can be NULL + +Oops: general protection fault, probably for non-canonical address 0xdffffc00000000bc: 0000 [#1] PREEMPT SMP KASAN PTI +KASAN: null-ptr-deref in range [0x00000000000005e0-0x00000000000005e7] +CPU: 0 PID: 11237 Comm: syz-executor.3 Not tainted 6.10.0-rc2-syzkaller-00249-gbe27b8965297 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/07/2024 + RIP: 0010:fib6_nh_init+0x640/0x2160 net/ipv6/route.c:3606 +Code: 00 00 fc ff df 4c 8b 64 24 58 48 8b 44 24 28 4c 8b 74 24 30 48 89 c1 48 89 44 24 28 48 8d 98 e0 05 00 00 48 89 d8 48 c1 e8 03 <42> 0f b6 04 38 84 c0 0f 85 b3 17 00 00 8b 1b 31 ff 89 de e8 b8 8b +RSP: 0018:ffffc900032775a0 EFLAGS: 00010202 +RAX: 00000000000000bc RBX: 00000000000005e0 RCX: 0000000000000000 +RDX: 0000000000000010 RSI: ffffc90003277a54 RDI: ffff88802b3a08d8 +RBP: ffffc900032778b0 R08: 00000000000002fc R09: 0000000000000000 +R10: 00000000000002fc R11: 0000000000000000 R12: ffff88802b3a08b8 +R13: 1ffff9200064eec8 R14: ffffc90003277a00 R15: dffffc0000000000 +FS: 00007f940feb06c0(0000) GS:ffff8880b9400000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000000 CR3: 00000000245e8000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + ip6_route_info_create+0x99e/0x12b0 net/ipv6/route.c:3809 + ip6_route_add+0x28/0x160 net/ipv6/route.c:3853 + ipv6_route_ioctl+0x588/0x870 net/ipv6/route.c:4483 + inet6_ioctl+0x21a/0x280 net/ipv6/af_inet6.c:579 + sock_do_ioctl+0x158/0x460 net/socket.c:1222 + sock_ioctl+0x629/0x8e0 net/socket.c:1341 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:907 [inline] + __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:893 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f940f07cea9 + +Fixes: 428604fb118f ("ipv6: do not set routes if disable_ipv6 has been enabled") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Acked-by: Lorenzo Bianconi +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20240614082002.26407-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 08cdb38d41d86..f2ffec3db5cfb 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3506,7 +3506,7 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, + if (!dev) + goto out; + +- if (idev->cnf.disable_ipv6) { ++ if (!idev || idev->cnf.disable_ipv6) { + NL_SET_ERR_MSG(extack, "IPv6 is disabled on nexthop device"); + err = -EACCES; + goto out; +-- +2.43.0 + diff --git a/queue-5.4/ipv6-prevent-possible-null-dereference-in-rt6_probe.patch b/queue-5.4/ipv6-prevent-possible-null-dereference-in-rt6_probe.patch new file mode 100644 index 00000000000..7d617409893 --- /dev/null +++ b/queue-5.4/ipv6-prevent-possible-null-dereference-in-rt6_probe.patch @@ -0,0 +1,86 @@ +From 66d39efc1181401a838b7323ab4505efe0c5af7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Jun 2024 15:14:54 +0000 +Subject: ipv6: prevent possible NULL dereference in rt6_probe() + +From: Eric Dumazet + +[ Upstream commit b86762dbe19a62e785c189f313cda5b989931f37 ] + +syzbot caught a NULL dereference in rt6_probe() [1] + +Bail out if __in6_dev_get() returns NULL. + +[1] +Oops: general protection fault, probably for non-canonical address 0xdffffc00000000cb: 0000 [#1] PREEMPT SMP KASAN PTI +KASAN: null-ptr-deref in range [0x0000000000000658-0x000000000000065f] +CPU: 1 PID: 22444 Comm: syz-executor.0 Not tainted 6.10.0-rc2-syzkaller-00383-gb8481381d4e2 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024 + RIP: 0010:rt6_probe net/ipv6/route.c:656 [inline] + RIP: 0010:find_match+0x8c4/0xf50 net/ipv6/route.c:758 +Code: 14 fd f7 48 8b 85 38 ff ff ff 48 c7 45 b0 00 00 00 00 48 8d b8 5c 06 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 19 +RSP: 0018:ffffc900034af070 EFLAGS: 00010203 +RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc90004521000 +RDX: 00000000000000cb RSI: ffffffff8990d0cd RDI: 000000000000065c +RBP: ffffc900034af150 R08: 0000000000000005 R09: 0000000000000000 +R10: 0000000000000001 R11: 0000000000000002 R12: 000000000000000a +R13: 1ffff92000695e18 R14: ffff8880244a1d20 R15: 0000000000000000 +FS: 00007f4844a5a6c0(0000) GS:ffff8880b9300000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000001b31b27000 CR3: 000000002d42c000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + rt6_nh_find_match+0xfa/0x1a0 net/ipv6/route.c:784 + nexthop_for_each_fib6_nh+0x26d/0x4a0 net/ipv4/nexthop.c:1496 + __find_rr_leaf+0x6e7/0xe00 net/ipv6/route.c:825 + find_rr_leaf net/ipv6/route.c:853 [inline] + rt6_select net/ipv6/route.c:897 [inline] + fib6_table_lookup+0x57e/0xa30 net/ipv6/route.c:2195 + ip6_pol_route+0x1cd/0x1150 net/ipv6/route.c:2231 + pol_lookup_func include/net/ip6_fib.h:616 [inline] + fib6_rule_lookup+0x386/0x720 net/ipv6/fib6_rules.c:121 + ip6_route_output_flags_noref net/ipv6/route.c:2639 [inline] + ip6_route_output_flags+0x1d0/0x640 net/ipv6/route.c:2651 + ip6_dst_lookup_tail.constprop.0+0x961/0x1760 net/ipv6/ip6_output.c:1147 + ip6_dst_lookup_flow+0x99/0x1d0 net/ipv6/ip6_output.c:1250 + rawv6_sendmsg+0xdab/0x4340 net/ipv6/raw.c:898 + inet_sendmsg+0x119/0x140 net/ipv4/af_inet.c:853 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + sock_write_iter+0x4b8/0x5c0 net/socket.c:1160 + new_sync_write fs/read_write.c:497 [inline] + vfs_write+0x6b6/0x1140 fs/read_write.c:590 + ksys_write+0x1f8/0x260 fs/read_write.c:643 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: 52e1635631b3 ("[IPV6]: ROUTE: Add router_probe_interval sysctl.") +Signed-off-by: Eric Dumazet +Reviewed-by: Jason Xing +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20240615151454.166404-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index f2ffec3db5cfb..2e91a563139a8 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -649,6 +649,8 @@ static void rt6_probe(struct fib6_nh *fib6_nh) + rcu_read_lock_bh(); + last_probe = READ_ONCE(fib6_nh->last_probe); + idev = __in6_dev_get(dev); ++ if (!idev) ++ goto out; + neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); + if (neigh) { + if (neigh->nud_state & NUD_VALID) +-- +2.43.0 + diff --git a/queue-5.4/mips-bmips-bcm6358-make-sure-cbr-is-correctly-set.patch b/queue-5.4/mips-bmips-bcm6358-make-sure-cbr-is-correctly-set.patch new file mode 100644 index 00000000000..db8b4080991 --- /dev/null +++ b/queue-5.4/mips-bmips-bcm6358-make-sure-cbr-is-correctly-set.patch @@ -0,0 +1,45 @@ +From e00c92c28575fa3b7b2925b477c02d577ad54c40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Jun 2024 13:35:33 +0200 +Subject: mips: bmips: BCM6358: make sure CBR is correctly set + +From: Christian Marangi + +[ Upstream commit ce5cdd3b05216b704a704f466fb4c2dff3778caf ] + +It was discovered that some device have CBR address set to 0 causing +kernel panic when arch_sync_dma_for_cpu_all is called. + +This was notice in situation where the system is booted from TP1 and +BMIPS_GET_CBR() returns 0 instead of a valid address and +!!(read_c0_brcm_cmt_local() & (1 << 31)); not failing. + +The current check whether RAC flush should be disabled or not are not +enough hence lets check if CBR is a valid address or not. + +Fixes: ab327f8acdf8 ("mips: bmips: BCM6358: disable RAC flush for TP1") +Signed-off-by: Christian Marangi +Acked-by: Florian Fainelli +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/bmips/setup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c +index 36fbedcbd518d..4ef8842100b30 100644 +--- a/arch/mips/bmips/setup.c ++++ b/arch/mips/bmips/setup.c +@@ -110,7 +110,8 @@ static void bcm6358_quirks(void) + * RAC flush causes kernel panics on BCM6358 when booting from TP1 + * because the bootloader is not initializing it properly. + */ +- bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); ++ bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || ++ !!BMIPS_GET_CBR(); + } + + static void bcm6368_quirks(void) +-- +2.43.0 + diff --git a/queue-5.4/mips-routerboard-532-fix-vendor-retry-check-code.patch b/queue-5.4/mips-routerboard-532-fix-vendor-retry-check-code.patch new file mode 100644 index 00000000000..155afd64619 --- /dev/null +++ b/queue-5.4/mips-routerboard-532-fix-vendor-retry-check-code.patch @@ -0,0 +1,46 @@ +From f28ccc20217a4a5b1bb4ca94ea54be81e8fdbe7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 May 2024 15:07:00 +0300 +Subject: MIPS: Routerboard 532: Fix vendor retry check code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit ae9daffd9028f2500c9ac1517e46d4f2b57efb80 ] + +read_config_dword() contains strange condition checking ret for a +number of values. The ret variable, however, is always zero because +config_access() never returns anything else. Thus, the retry is always +taken until number of tries is exceeded. + +The code looks like it wants to check *val instead of ret to see if the +read gave an error response. + +Fixes: 73b4390fb234 ("[MIPS] Routerboard 532: Support for base system") +Signed-off-by: Ilpo Järvinen +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/pci/ops-rc32434.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c +index 874ed6df97683..34b9323bdabb0 100644 +--- a/arch/mips/pci/ops-rc32434.c ++++ b/arch/mips/pci/ops-rc32434.c +@@ -112,8 +112,8 @@ static int read_config_dword(struct pci_bus *bus, unsigned int devfn, + * gives them time to settle + */ + if (where == PCI_VENDOR_ID) { +- if (ret == 0xffffffff || ret == 0x00000000 || +- ret == 0x0000ffff || ret == 0xffff0000) { ++ if (*val == 0xffffffff || *val == 0x00000000 || ++ *val == 0x0000ffff || *val == 0xffff0000) { + if (delay > 4) + return 0; + delay *= 2; +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-add-pci11010-pci11414-device-ids.patch b/queue-5.4/net-lan743x-add-pci11010-pci11414-device-ids.patch new file mode 100644 index 00000000000..33b1decef21 --- /dev/null +++ b/queue-5.4/net-lan743x-add-pci11010-pci11414-device-ids.patch @@ -0,0 +1,65 @@ +From 38880b7913c75122ce831aea1e4d3a68412c3766 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Feb 2022 21:23:11 +0530 +Subject: net: lan743x: Add PCI11010 / PCI11414 device IDs + +From: Raju Lakkaraju + +[ Upstream commit bb4f6bffe33c8791549cb634d7b053aa5c3d1131 ] + +PCI11010/PCI11414 devices are enhancement of Ethernet LAN743x chip family. + +Signed-off-by: Raju Lakkaraju +Signed-off-by: David S. Miller +Stable-dep-of: 7725363936a8 ("net: lan743x: disable WOL upon resume to restore full data path operation") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 2 ++ + drivers/net/ethernet/microchip/lan743x_main.h | 11 +++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 083f7a051ca38..417fb4b8761dc 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -3051,6 +3051,8 @@ static const struct dev_pm_ops lan743x_pm_ops = { + static const struct pci_device_id lan743x_pcidev_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7430) }, + { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7431) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_A011) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_A041) }, + { 0, } + }; + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 1fbcef3910989..a8ff2bd12f63a 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -15,8 +15,13 @@ + #define ID_REV_ID_MASK_ (0xFFFF0000) + #define ID_REV_ID_LAN7430_ (0x74300000) + #define ID_REV_ID_LAN7431_ (0x74310000) +-#define ID_REV_IS_VALID_CHIP_ID_(id_rev) \ +- (((id_rev) & 0xFFF00000) == 0x74300000) ++#define ID_REV_ID_LAN743X_ (0x74300000) ++#define ID_REV_ID_A011_ (0xA0110000) // PCI11010 ++#define ID_REV_ID_A041_ (0xA0410000) // PCI11414 ++#define ID_REV_ID_A0X1_ (0xA0010000) ++#define ID_REV_IS_VALID_CHIP_ID_(id_rev) \ ++ ((((id_rev) & 0xFFF00000) == ID_REV_ID_LAN743X_) || \ ++ (((id_rev) & 0xFF0F0000) == ID_REV_ID_A0X1_)) + #define ID_REV_CHIP_REV_MASK_ (0x0000FFFF) + #define ID_REV_CHIP_REV_A0_ (0x00000000) + #define ID_REV_CHIP_REV_B0_ (0x00000010) +@@ -553,6 +558,8 @@ struct lan743x_adapter; + #define PCI_VENDOR_ID_SMSC PCI_VENDOR_ID_EFAR + #define PCI_DEVICE_ID_SMSC_LAN7430 (0x7430) + #define PCI_DEVICE_ID_SMSC_LAN7431 (0x7431) ++#define PCI_DEVICE_ID_SMSC_A011 (0xA011) ++#define PCI_DEVICE_ID_SMSC_A041 (0xA041) + + #define PCI_CONFIG_LENGTH (0x1000) + +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-add-support-for-4-tx-queues.patch b/queue-5.4/net-lan743x-add-support-for-4-tx-queues.patch new file mode 100644 index 00000000000..781e74441e6 --- /dev/null +++ b/queue-5.4/net-lan743x-add-support-for-4-tx-queues.patch @@ -0,0 +1,272 @@ +From f9dbac9e8c8d810b41afc60ed9556a17c6d74738 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Feb 2022 21:23:12 +0530 +Subject: net: lan743x: Add support for 4 Tx queues + +From: Raju Lakkaraju + +[ Upstream commit cf9aaea8e55b3f80488975a76fa4ca2ffaedcedd ] + +Add support for 4 Tx queues + +Signed-off-by: Raju Lakkaraju +Signed-off-by: David S. Miller +Stable-dep-of: 7725363936a8 ("net: lan743x: disable WOL upon resume to restore full data path operation") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 83 +++++++++++++++---- + drivers/net/ethernet/microchip/lan743x_main.h | 12 ++- + drivers/net/ethernet/microchip/lan743x_ptp.c | 8 +- + 3 files changed, 79 insertions(+), 24 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 417fb4b8761dc..d2a98d633e97a 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -15,6 +15,18 @@ + #include "lan743x_main.h" + #include "lan743x_ethtool.h" + ++static bool is_pci11x1x_chip(struct lan743x_adapter *adapter) ++{ ++ struct lan743x_csr *csr = &adapter->csr; ++ u32 id_rev = csr->id_rev; ++ ++ if (((id_rev & 0xFFFF0000) == ID_REV_ID_A011_) || ++ ((id_rev & 0xFFFF0000) == ID_REV_ID_A041_)) { ++ return true; ++ } ++ return false; ++} ++ + static void lan743x_pci_cleanup(struct lan743x_adapter *adapter) + { + pci_release_selected_regions(adapter->pdev, +@@ -263,7 +275,7 @@ static void lan743x_intr_shared_isr(void *context, u32 int_sts, u32 flags) + } + } + if (int_sts & INT_BIT_ALL_TX_) { +- for (channel = 0; channel < LAN743X_USED_TX_CHANNELS; ++ for (channel = 0; channel < adapter->used_tx_channels; + channel++) { + u32 int_bit = INT_BIT_DMA_TX_(channel); + +@@ -465,6 +477,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + { + struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT]; + struct lan743x_intr *intr = &adapter->intr; ++ unsigned int used_tx_channels; + u32 int_vec_en_auto_clr = 0; + u32 int_vec_map0 = 0; + u32 int_vec_map1 = 0; +@@ -479,9 +492,10 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT); + for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) + msix_entries[index].entry = index; ++ used_tx_channels = adapter->used_tx_channels; + ret = pci_enable_msix_range(adapter->pdev, + msix_entries, 1, +- 1 + LAN743X_USED_TX_CHANNELS + ++ 1 + used_tx_channels + + LAN743X_USED_RX_CHANNELS); + + if (ret > 0) { +@@ -586,8 +600,8 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + if (intr->number_of_vectors > 1) { + int number_of_tx_vectors = intr->number_of_vectors - 1; + +- if (number_of_tx_vectors > LAN743X_USED_TX_CHANNELS) +- number_of_tx_vectors = LAN743X_USED_TX_CHANNELS; ++ if (number_of_tx_vectors > used_tx_channels) ++ number_of_tx_vectors = used_tx_channels; + flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ | + LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C | + LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK | +@@ -625,9 +639,9 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + INT_VEC_EN_(vector)); + } + } +- if ((intr->number_of_vectors - LAN743X_USED_TX_CHANNELS) > 1) { ++ if ((intr->number_of_vectors - used_tx_channels) > 1) { + int number_of_rx_vectors = intr->number_of_vectors - +- LAN743X_USED_TX_CHANNELS - 1; ++ used_tx_channels - 1; + + if (number_of_rx_vectors > LAN743X_USED_RX_CHANNELS) + number_of_rx_vectors = LAN743X_USED_RX_CHANNELS; +@@ -2488,7 +2502,8 @@ static int lan743x_netdev_close(struct net_device *netdev) + struct lan743x_adapter *adapter = netdev_priv(netdev); + int index; + +- lan743x_tx_close(&adapter->tx[0]); ++ for (index = 0; index < adapter->used_tx_channels; index++) ++ lan743x_tx_close(&adapter->tx[index]); + + for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) + lan743x_rx_close(&adapter->rx[index]); +@@ -2534,12 +2549,19 @@ static int lan743x_netdev_open(struct net_device *netdev) + goto close_rx; + } + +- ret = lan743x_tx_open(&adapter->tx[0]); +- if (ret) +- goto close_rx; +- ++ for (index = 0; index < adapter->used_tx_channels; index++) { ++ ret = lan743x_tx_open(&adapter->tx[index]); ++ if (ret) ++ goto close_tx; ++ } + return 0; + ++close_tx: ++ for (index = 0; index < adapter->used_tx_channels; index++) { ++ if (adapter->tx[index].ring_cpu_ptr) ++ lan743x_tx_close(&adapter->tx[index]); ++ } ++ + close_rx: + for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) { + if (adapter->rx[index].ring_cpu_ptr) +@@ -2566,8 +2588,12 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb, + struct net_device *netdev) + { + struct lan743x_adapter *adapter = netdev_priv(netdev); ++ u8 ch = 0; ++ ++ if (adapter->is_pci11x1x) ++ ch = skb->queue_mapping % PCI11X1X_USED_TX_CHANNELS; + +- return lan743x_tx_xmit_frame(&adapter->tx[0], skb); ++ return lan743x_tx_xmit_frame(&adapter->tx[ch], skb); + } + + static int lan743x_netdev_ioctl(struct net_device *netdev, +@@ -2698,6 +2724,15 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, + int index; + int ret; + ++ adapter->is_pci11x1x = is_pci11x1x_chip(adapter); ++ if (adapter->is_pci11x1x) { ++ adapter->max_tx_channels = PCI11X1X_MAX_TX_CHANNELS; ++ adapter->used_tx_channels = PCI11X1X_USED_TX_CHANNELS; ++ } else { ++ adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS; ++ adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS; ++ } ++ + adapter->intr.irq = adapter->pdev->irq; + lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF); + +@@ -2728,10 +2763,13 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, + adapter->rx[index].channel_number = index; + } + +- tx = &adapter->tx[0]; +- tx->adapter = adapter; +- tx->channel_number = 0; +- spin_lock_init(&tx->ring_lock); ++ for (index = 0; index < adapter->used_tx_channels; index++) { ++ tx = &adapter->tx[index]; ++ tx->adapter = adapter; ++ tx->channel_number = index; ++ spin_lock_init(&tx->ring_lock); ++ } ++ + return 0; + } + +@@ -2783,8 +2821,17 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev, + struct net_device *netdev = NULL; + int ret = -ENODEV; + +- netdev = devm_alloc_etherdev(&pdev->dev, +- sizeof(struct lan743x_adapter)); ++ if (id->device == PCI_DEVICE_ID_SMSC_A011 || ++ id->device == PCI_DEVICE_ID_SMSC_A041) { ++ netdev = devm_alloc_etherdev_mqs(&pdev->dev, ++ sizeof(struct lan743x_adapter), ++ PCI11X1X_USED_TX_CHANNELS, ++ LAN743X_USED_RX_CHANNELS); ++ } else { ++ netdev = devm_alloc_etherdev(&pdev->dev, ++ sizeof(struct lan743x_adapter)); ++ } ++ + if (!netdev) + goto return_error; + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index a8ff2bd12f63a..9769ee004423d 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -540,10 +540,12 @@ + + #define LAN743X_MAX_RX_CHANNELS (4) + #define LAN743X_MAX_TX_CHANNELS (1) ++#define PCI11X1X_MAX_TX_CHANNELS (4) + struct lan743x_adapter; + + #define LAN743X_USED_RX_CHANNELS (4) + #define LAN743X_USED_TX_CHANNELS (1) ++#define PCI11X1X_USED_TX_CHANNELS (4) + #define LAN743X_INT_MOD (400) + + #if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS) +@@ -552,6 +554,9 @@ struct lan743x_adapter; + #if (LAN743X_USED_TX_CHANNELS > LAN743X_MAX_TX_CHANNELS) + #error Invalid LAN743X_USED_TX_CHANNELS + #endif ++#if (PCI11X1X_USED_TX_CHANNELS > PCI11X1X_MAX_TX_CHANNELS) ++#error Invalid PCI11X1X_USED_TX_CHANNELS ++#endif + + /* PCI */ + /* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */ +@@ -719,8 +724,11 @@ struct lan743x_adapter { + u8 mac_address[ETH_ALEN]; + + struct lan743x_phy phy; +- struct lan743x_tx tx[LAN743X_MAX_TX_CHANNELS]; +- struct lan743x_rx rx[LAN743X_MAX_RX_CHANNELS]; ++ struct lan743x_tx tx[PCI11X1X_USED_TX_CHANNELS]; ++ struct lan743x_rx rx[LAN743X_USED_RX_CHANNELS]; ++ bool is_pci11x1x; ++ u8 max_tx_channels; ++ u8 used_tx_channels; + + #define LAN743X_ADAPTER_FLAG_OTP BIT(0) + u32 flags; +diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c +index e8fe9a90fe4f9..d099d6c7cd07d 100644 +--- a/drivers/net/ethernet/microchip/lan743x_ptp.c ++++ b/drivers/net/ethernet/microchip/lan743x_ptp.c +@@ -1127,21 +1127,21 @@ int lan743x_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) + + switch (config.tx_type) { + case HWTSTAMP_TX_OFF: +- for (index = 0; index < LAN743X_MAX_TX_CHANNELS; +- index++) ++ for (index = 0; index < adapter->used_tx_channels; ++ index++) + lan743x_tx_set_timestamping_mode(&adapter->tx[index], + false, false); + lan743x_ptp_set_sync_ts_insert(adapter, false); + break; + case HWTSTAMP_TX_ON: +- for (index = 0; index < LAN743X_MAX_TX_CHANNELS; ++ for (index = 0; index < adapter->used_tx_channels; + index++) + lan743x_tx_set_timestamping_mode(&adapter->tx[index], + true, false); + lan743x_ptp_set_sync_ts_insert(adapter, false); + break; + case HWTSTAMP_TX_ONESTEP_SYNC: +- for (index = 0; index < LAN743X_MAX_TX_CHANNELS; ++ for (index = 0; index < adapter->used_tx_channels; + index++) + lan743x_tx_set_timestamping_mode(&adapter->tx[index], + true, true); +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-add-support-for-sgmii-interface.patch b/queue-5.4/net-lan743x-add-support-for-sgmii-interface.patch new file mode 100644 index 00000000000..7cfa73cc253 --- /dev/null +++ b/queue-5.4/net-lan743x-add-support-for-sgmii-interface.patch @@ -0,0 +1,146 @@ +From 9fd7960ea22db50aa7ea1cd62dc4a6b3fda187a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Feb 2022 21:23:14 +0530 +Subject: net: lan743x: Add support for SGMII interface + +From: Raju Lakkaraju + +[ Upstream commit a46d9d37c4f4fa16c3f1915a1b0a19c31fed5099 ] + +This change facilitates the selection between SGMII and (R)GIII +interfaces + +Signed-off-by: Raju Lakkaraju +Signed-off-by: David S. Miller +Stable-dep-of: 8c248cd83601 ("net: lan743x: Support WOL at both the PHY and MAC appropriately") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 48 +++++++++++++++++++ + drivers/net/ethernet/microchip/lan743x_main.h | 17 +++++++ + 2 files changed, 65 insertions(+) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 9f39afdfd415e..f77d3221072d9 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -15,6 +15,34 @@ + #include "lan743x_main.h" + #include "lan743x_ethtool.h" + ++static void pci11x1x_strap_get_status(struct lan743x_adapter *adapter) ++{ ++ u32 chip_rev; ++ u32 strap; ++ ++ strap = lan743x_csr_read(adapter, STRAP_READ); ++ if (strap & STRAP_READ_USE_SGMII_EN_) { ++ if (strap & STRAP_READ_SGMII_EN_) ++ adapter->is_sgmii_en = true; ++ else ++ adapter->is_sgmii_en = false; ++ netif_dbg(adapter, drv, adapter->netdev, ++ "STRAP_READ: 0x%08X\n", strap); ++ } else { ++ chip_rev = lan743x_csr_read(adapter, FPGA_REV); ++ if (chip_rev) { ++ if (chip_rev & FPGA_SGMII_OP) ++ adapter->is_sgmii_en = true; ++ else ++ adapter->is_sgmii_en = false; ++ netif_dbg(adapter, drv, adapter->netdev, ++ "FPGA_REV: 0x%08X\n", chip_rev); ++ } else { ++ adapter->is_sgmii_en = false; ++ } ++ } ++} ++ + static bool is_pci11x1x_chip(struct lan743x_adapter *adapter) + { + struct lan743x_csr *csr = &adapter->csr; +@@ -2741,6 +2769,7 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, + adapter->max_tx_channels = PCI11X1X_MAX_TX_CHANNELS; + adapter->used_tx_channels = PCI11X1X_USED_TX_CHANNELS; + adapter->max_vector_count = PCI11X1X_MAX_VECTOR_COUNT; ++ pci11x1x_strap_get_status(adapter); + } else { + adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS; + adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS; +@@ -2789,6 +2818,7 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, + + static int lan743x_mdiobus_init(struct lan743x_adapter *adapter) + { ++ u32 sgmii_ctl; + int ret; + + adapter->mdiobus = devm_mdiobus_alloc(&adapter->pdev->dev); +@@ -2798,6 +2828,24 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter) + } + + adapter->mdiobus->priv = (void *)adapter; ++ if (adapter->is_pci11x1x) { ++ if (adapter->is_sgmii_en) { ++ sgmii_ctl = lan743x_csr_read(adapter, SGMII_CTL); ++ sgmii_ctl |= SGMII_CTL_SGMII_ENABLE_; ++ sgmii_ctl &= ~SGMII_CTL_SGMII_POWER_DN_; ++ lan743x_csr_write(adapter, SGMII_CTL, sgmii_ctl); ++ netif_dbg(adapter, drv, adapter->netdev, ++ "SGMII operation\n"); ++ } else { ++ sgmii_ctl = lan743x_csr_read(adapter, SGMII_CTL); ++ sgmii_ctl &= ~SGMII_CTL_SGMII_ENABLE_; ++ sgmii_ctl |= SGMII_CTL_SGMII_POWER_DN_; ++ lan743x_csr_write(adapter, SGMII_CTL, sgmii_ctl); ++ netif_dbg(adapter, drv, adapter->netdev, ++ "(R)GMII operation\n"); ++ } ++ } ++ + adapter->mdiobus->read = lan743x_mdiobus_read; + adapter->mdiobus->write = lan743x_mdiobus_write; + adapter->mdiobus->name = "lan743x-mdiobus"; +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 52d787aed0d17..1825021c63f81 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -29,6 +29,17 @@ + #define FPGA_REV (0x04) + #define FPGA_REV_GET_MINOR_(fpga_rev) (((fpga_rev) >> 8) & 0x000000FF) + #define FPGA_REV_GET_MAJOR_(fpga_rev) ((fpga_rev) & 0x000000FF) ++#define FPGA_SGMII_OP BIT(24) ++ ++#define STRAP_READ (0x0C) ++#define STRAP_READ_USE_SGMII_EN_ BIT(22) ++#define STRAP_READ_SGMII_EN_ BIT(6) ++#define STRAP_READ_SGMII_REFCLK_ BIT(5) ++#define STRAP_READ_SGMII_2_5G_ BIT(4) ++#define STRAP_READ_BASE_X_ BIT(3) ++#define STRAP_READ_RGMII_TXC_DELAY_EN_ BIT(2) ++#define STRAP_READ_RGMII_RXC_DELAY_EN_ BIT(1) ++#define STRAP_READ_ADV_PM_DISABLE_ BIT(0) + + #define HW_CFG (0x010) + #define HW_CFG_RST_PROTECT_PCIE_ BIT(19) +@@ -246,6 +257,11 @@ + #define MAC_WUCSR2_IPV6_TCPSYN_RCD_ BIT(5) + #define MAC_WUCSR2_IPV4_TCPSYN_RCD_ BIT(4) + ++#define SGMII_CTL (0x728) ++#define SGMII_CTL_SGMII_ENABLE_ BIT(31) ++#define SGMII_CTL_LINK_STATUS_SOURCE_ BIT(8) ++#define SGMII_CTL_SGMII_POWER_DN_ BIT(1) ++ + #define INT_STS (0x780) + #define INT_BIT_DMA_RX_(channel) BIT(24 + (channel)) + #define INT_BIT_ALL_RX_ (0x0F000000) +@@ -763,6 +779,7 @@ struct lan743x_adapter { + struct lan743x_tx tx[PCI11X1X_USED_TX_CHANNELS]; + struct lan743x_rx rx[LAN743X_USED_RX_CHANNELS]; + bool is_pci11x1x; ++ bool is_sgmii_en; + u8 max_tx_channels; + u8 used_tx_channels; + u8 max_vector_count; +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-add-support-to-secure-on-wol.patch b/queue-5.4/net-lan743x-add-support-to-secure-on-wol.patch new file mode 100644 index 00000000000..ed937ea6db5 --- /dev/null +++ b/queue-5.4/net-lan743x-add-support-to-secure-on-wol.patch @@ -0,0 +1,180 @@ +From b8bbd8e71c54ce8b790c4ee74b9e0d09fb2509e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jun 2022 09:42:24 +0530 +Subject: net: lan743x: Add support to Secure-ON WOL + +From: Raju Lakkaraju + +[ Upstream commit 6b3768ac8e2b3e3594f6851a073f2a11cfb82719 ] + +Add support to Magic Packet Detection with Secure-ON for PCI11010/PCI11414 chips + +Signed-off-by: Raju Lakkaraju +Reviewed-by: Andrew Lunn +Signed-off-by: Jakub Kicinski +Stable-dep-of: 7725363936a8 ("net: lan743x: disable WOL upon resume to restore full data path operation") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/microchip/lan743x_ethtool.c | 12 ++++++++ + drivers/net/ethernet/microchip/lan743x_main.c | 29 +++++++++++++++++++ + drivers/net/ethernet/microchip/lan743x_main.h | 10 +++++++ + 3 files changed, 51 insertions(+) + +diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c +index eedec13460787..469a591cf9cd2 100644 +--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c ++++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c +@@ -787,7 +787,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev, + wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | + WAKE_MAGIC | WAKE_PHY | WAKE_ARP; + ++ if (adapter->is_pci11x1x) ++ wol->supported |= WAKE_MAGICSECURE; ++ + wol->wolopts |= adapter->wolopts; ++ if (adapter->wolopts & WAKE_MAGICSECURE) ++ memcpy(wol->sopass, adapter->sopass, sizeof(wol->sopass)); + } + + static int lan743x_ethtool_set_wol(struct net_device *netdev, +@@ -808,6 +813,13 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, + adapter->wolopts |= WAKE_PHY; + if (wol->wolopts & WAKE_ARP) + adapter->wolopts |= WAKE_ARP; ++ if (wol->wolopts & WAKE_MAGICSECURE && ++ wol->wolopts & WAKE_MAGIC) { ++ memcpy(adapter->sopass, wol->sopass, sizeof(wol->sopass)); ++ adapter->wolopts |= WAKE_MAGICSECURE; ++ } else { ++ memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX); ++ } + + device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts); + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index d2a98d633e97a..114dd5847c958 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -2940,6 +2940,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + const u8 ipv6_multicast[3] = { 0x33, 0x33 }; + const u8 arp_type[2] = { 0x08, 0x06 }; + int mask_index; ++ u32 sopass; + u32 pmtctl; + u32 wucsr; + u32 macrx; +@@ -3034,6 +3035,14 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + pmtctl |= PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_; + } + ++ if (adapter->wolopts & WAKE_MAGICSECURE) { ++ sopass = *(u32 *)adapter->sopass; ++ lan743x_csr_write(adapter, MAC_MP_SO_LO, sopass); ++ sopass = *(u16 *)&adapter->sopass[4]; ++ lan743x_csr_write(adapter, MAC_MP_SO_HI, sopass); ++ wucsr |= MAC_MP_SO_EN_; ++ } ++ + lan743x_csr_write(adapter, MAC_WUCSR, wucsr); + lan743x_csr_write(adapter, PMT_CTL, pmtctl); + lan743x_csr_write(adapter, MAC_RX, macrx); +@@ -3044,6 +3053,7 @@ static int lan743x_pm_suspend(struct device *dev) + struct pci_dev *pdev = to_pci_dev(dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct lan743x_adapter *adapter = netdev_priv(netdev); ++ u32 data; + + lan743x_pcidev_shutdown(pdev); + +@@ -3055,6 +3065,18 @@ static int lan743x_pm_suspend(struct device *dev) + if (adapter->wolopts) + lan743x_pm_set_wol(adapter); + ++ if (adapter->is_pci11x1x) { ++ /* Save HW_CFG to config again in PM resume */ ++ data = lan743x_csr_read(adapter, HW_CFG); ++ adapter->hw_cfg = data; ++ data |= (HW_CFG_RST_PROTECT_PCIE_ | ++ HW_CFG_D3_RESET_DIS_ | ++ HW_CFG_D3_VAUX_OVR_ | ++ HW_CFG_HOT_RESET_DIS_ | ++ HW_CFG_RST_PROTECT_); ++ lan743x_csr_write(adapter, HW_CFG, data); ++ } ++ + /* Host sets PME_En, put D3hot */ + return pci_prepare_to_sleep(pdev);; + } +@@ -3070,6 +3092,10 @@ static int lan743x_pm_resume(struct device *dev) + pci_restore_state(pdev); + pci_save_state(pdev); + ++ /* Restore HW_CFG that was saved during pm suspend */ ++ if (adapter->is_pci11x1x) ++ lan743x_csr_write(adapter, HW_CFG, adapter->hw_cfg); ++ + ret = lan743x_hardware_init(adapter, pdev); + if (ret) { + netif_err(adapter, probe, adapter->netdev, +@@ -3086,6 +3112,9 @@ static int lan743x_pm_resume(struct device *dev) + lan743x_netdev_open(netdev); + + netif_device_attach(netdev); ++ ret = lan743x_csr_read(adapter, MAC_WK_SRC); ++ netif_info(adapter, drv, adapter->netdev, ++ "Wakeup source : 0x%08X\n", ret); + + return 0; + } +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 9769ee004423d..5c8bcc5cecc8a 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -31,6 +31,11 @@ + #define FPGA_REV_GET_MAJOR_(fpga_rev) ((fpga_rev) & 0x000000FF) + + #define HW_CFG (0x010) ++#define HW_CFG_RST_PROTECT_PCIE_ BIT(19) ++#define HW_CFG_HOT_RESET_DIS_ BIT(15) ++#define HW_CFG_D3_VAUX_OVR_ BIT(14) ++#define HW_CFG_D3_RESET_DIS_ BIT(13) ++#define HW_CFG_RST_PROTECT_ BIT(12) + #define HW_CFG_RELOAD_TYPE_ALL_ (0x00000FC0) + #define HW_CFG_EE_OTP_RELOAD_ BIT(4) + #define HW_CFG_LRST_ BIT(1) +@@ -148,6 +153,7 @@ + #define MAC_EEE_TX_LPI_REQ_DLY_CNT (0x130) + + #define MAC_WUCSR (0x140) ++#define MAC_MP_SO_EN_ BIT(21) + #define MAC_WUCSR_RFE_WAKE_EN_ BIT(14) + #define MAC_WUCSR_PFDA_EN_ BIT(3) + #define MAC_WUCSR_WAKE_EN_ BIT(2) +@@ -155,6 +161,8 @@ + #define MAC_WUCSR_BCST_EN_ BIT(0) + + #define MAC_WK_SRC (0x144) ++#define MAC_MP_SO_HI (0x148) ++#define MAC_MP_SO_LO (0x14C) + + #define MAC_WUF_CFG0 (0x150) + #define MAC_NUM_OF_WUF_CFG (32) +@@ -713,6 +721,7 @@ struct lan743x_adapter { + int msg_enable; + #ifdef CONFIG_PM + u32 wolopts; ++ u8 sopass[SOPASS_MAX]; + #endif + struct pci_dev *pdev; + struct lan743x_csr csr; +@@ -732,6 +741,7 @@ struct lan743x_adapter { + + #define LAN743X_ADAPTER_FLAG_OTP BIT(0) + u32 flags; ++ u32 hw_cfg; + }; + + #define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel)) +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-disable-wol-upon-resume-to-restore-full-.patch b/queue-5.4/net-lan743x-disable-wol-upon-resume-to-restore-full-.patch new file mode 100644 index 00000000000..cf24284be27 --- /dev/null +++ b/queue-5.4/net-lan743x-disable-wol-upon-resume-to-restore-full-.patch @@ -0,0 +1,146 @@ +From 4c9084c176f54a24daf3c3d777e38897dd9d1c33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 22:41:55 +0530 +Subject: net: lan743x: disable WOL upon resume to restore full data path + operation + +From: Raju Lakkaraju + +[ Upstream commit 7725363936a88351b71495774c1e0e852ae4cdca ] + +When Wake-on-LAN (WoL) is active and the system is in suspend mode, triggering +a system event can wake the system from sleep, which may block the data path. +To restore normal data path functionality after waking, disable all wake-up +events. Furthermore, clear all Write 1 to Clear (W1C) status bits by writing +1's to them. + +Fixes: 4d94282afd95 ("lan743x: Add power management support") +Reviewed-by: Wojciech Drewek +Signed-off-by: Raju Lakkaraju +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 30 ++++++++++++++++--- + drivers/net/ethernet/microchip/lan743x_main.h | 24 +++++++++++++++ + 2 files changed, 50 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 114dd5847c958..b07033c2851e4 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -2951,7 +2951,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + + /* clear wake settings */ + pmtctl = lan743x_csr_read(adapter, PMT_CTL); +- pmtctl |= PMT_CTL_WUPS_MASK_; ++ pmtctl |= PMT_CTL_WUPS_MASK_ | PMT_CTL_RES_CLR_WKP_MASK_; + pmtctl &= ~(PMT_CTL_GPIO_WAKEUP_EN_ | PMT_CTL_EEE_WAKEUP_EN_ | + PMT_CTL_WOL_EN_ | PMT_CTL_MAC_D3_RX_CLK_OVR_ | + PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ | PMT_CTL_ETH_PHY_WAKE_EN_); +@@ -3086,6 +3086,7 @@ static int lan743x_pm_resume(struct device *dev) + struct pci_dev *pdev = to_pci_dev(dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct lan743x_adapter *adapter = netdev_priv(netdev); ++ u32 data; + int ret; + + pci_set_power_state(pdev, PCI_D0); +@@ -3104,6 +3105,30 @@ static int lan743x_pm_resume(struct device *dev) + return ret; + } + ++ ret = lan743x_csr_read(adapter, MAC_WK_SRC); ++ netif_dbg(adapter, drv, adapter->netdev, ++ "Wakeup source : 0x%08X\n", ret); ++ ++ /* Clear the wol configuration and status bits. Note that ++ * the status bits are "Write One to Clear (W1C)" ++ */ ++ data = MAC_WUCSR_EEE_TX_WAKE_ | MAC_WUCSR_EEE_RX_WAKE_ | ++ MAC_WUCSR_RFE_WAKE_FR_ | MAC_WUCSR_PFDA_FR_ | MAC_WUCSR_WUFR_ | ++ MAC_WUCSR_MPR_ | MAC_WUCSR_BCAST_FR_; ++ lan743x_csr_write(adapter, MAC_WUCSR, data); ++ ++ data = MAC_WUCSR2_NS_RCD_ | MAC_WUCSR2_ARP_RCD_ | ++ MAC_WUCSR2_IPV6_TCPSYN_RCD_ | MAC_WUCSR2_IPV4_TCPSYN_RCD_; ++ lan743x_csr_write(adapter, MAC_WUCSR2, data); ++ ++ data = MAC_WK_SRC_ETH_PHY_WK_ | MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ | ++ MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ | MAC_WK_SRC_EEE_TX_WK_ | ++ MAC_WK_SRC_EEE_RX_WK_ | MAC_WK_SRC_RFE_FR_WK_ | ++ MAC_WK_SRC_PFDA_FR_WK_ | MAC_WK_SRC_MP_FR_WK_ | ++ MAC_WK_SRC_BCAST_FR_WK_ | MAC_WK_SRC_WU_FR_WK_ | ++ MAC_WK_SRC_WK_FR_SAVED_; ++ lan743x_csr_write(adapter, MAC_WK_SRC, data); ++ + /* open netdev when netdev is at running state while resume. + * For instance, it is true when system wakesup after pm-suspend + * However, it is false when system wakes up after suspend GUI menu +@@ -3112,9 +3137,6 @@ static int lan743x_pm_resume(struct device *dev) + lan743x_netdev_open(netdev); + + netif_device_attach(netdev); +- ret = lan743x_csr_read(adapter, MAC_WK_SRC); +- netif_info(adapter, drv, adapter->netdev, +- "Wakeup source : 0x%08X\n", ret); + + return 0; + } +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 5c8bcc5cecc8a..fc33a05ff02d2 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -48,6 +48,7 @@ + #define PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ BIT(18) + #define PMT_CTL_GPIO_WAKEUP_EN_ BIT(15) + #define PMT_CTL_EEE_WAKEUP_EN_ BIT(13) ++#define PMT_CTL_RES_CLR_WKP_MASK_ GENMASK(9, 8) + #define PMT_CTL_READY_ BIT(7) + #define PMT_CTL_ETH_PHY_RST_ BIT(4) + #define PMT_CTL_WOL_EN_ BIT(3) +@@ -155,12 +156,31 @@ + #define MAC_WUCSR (0x140) + #define MAC_MP_SO_EN_ BIT(21) + #define MAC_WUCSR_RFE_WAKE_EN_ BIT(14) ++#define MAC_WUCSR_EEE_TX_WAKE_ BIT(13) ++#define MAC_WUCSR_EEE_RX_WAKE_ BIT(11) ++#define MAC_WUCSR_RFE_WAKE_FR_ BIT(9) ++#define MAC_WUCSR_PFDA_FR_ BIT(7) ++#define MAC_WUCSR_WUFR_ BIT(6) ++#define MAC_WUCSR_MPR_ BIT(5) ++#define MAC_WUCSR_BCAST_FR_ BIT(4) + #define MAC_WUCSR_PFDA_EN_ BIT(3) + #define MAC_WUCSR_WAKE_EN_ BIT(2) + #define MAC_WUCSR_MPEN_ BIT(1) + #define MAC_WUCSR_BCST_EN_ BIT(0) + + #define MAC_WK_SRC (0x144) ++#define MAC_WK_SRC_ETH_PHY_WK_ BIT(17) ++#define MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ BIT(16) ++#define MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ BIT(15) ++#define MAC_WK_SRC_EEE_TX_WK_ BIT(14) ++#define MAC_WK_SRC_EEE_RX_WK_ BIT(13) ++#define MAC_WK_SRC_RFE_FR_WK_ BIT(12) ++#define MAC_WK_SRC_PFDA_FR_WK_ BIT(11) ++#define MAC_WK_SRC_MP_FR_WK_ BIT(10) ++#define MAC_WK_SRC_BCAST_FR_WK_ BIT(9) ++#define MAC_WK_SRC_WU_FR_WK_ BIT(8) ++#define MAC_WK_SRC_WK_FR_SAVED_ BIT(7) ++ + #define MAC_MP_SO_HI (0x148) + #define MAC_MP_SO_LO (0x14C) + +@@ -221,6 +241,10 @@ + #define RFE_INDX(index) (0x580 + (index << 2)) + + #define MAC_WUCSR2 (0x600) ++#define MAC_WUCSR2_NS_RCD_ BIT(7) ++#define MAC_WUCSR2_ARP_RCD_ BIT(6) ++#define MAC_WUCSR2_IPV6_TCPSYN_RCD_ BIT(5) ++#define MAC_WUCSR2_IPV4_TCPSYN_RCD_ BIT(4) + + #define INT_STS (0x780) + #define INT_BIT_DMA_RX_(channel) BIT(24 + (channel)) +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-increase-msi-x-vectors-to-16-and-int-de-.patch b/queue-5.4/net-lan743x-increase-msi-x-vectors-to-16-and-int-de-.patch new file mode 100644 index 00000000000..ea30343be2f --- /dev/null +++ b/queue-5.4/net-lan743x-increase-msi-x-vectors-to-16-and-int-de-.patch @@ -0,0 +1,155 @@ +From cbb47a4861bfd582a36b15e0cf40f4ff7dac944a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Feb 2022 21:23:13 +0530 +Subject: net: lan743x: Increase MSI(x) vectors to 16 and Int de-assertion + timers to 10 + +From: Raju Lakkaraju + +[ Upstream commit ac16b6eb39d6023585bcbd220feca04f10cab9dd ] + +Increase MSI / MSI-X vectors supported from 8 to 16 and +Interrupt De-assertion timers from 8 to 10 + +Signed-off-by: Raju Lakkaraju +Signed-off-by: David S. Miller +Stable-dep-of: 8c248cd83601 ("net: lan743x: Support WOL at both the PHY and MAC appropriately") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 32 +++++++++++++------ + drivers/net/ethernet/microchip/lan743x_main.h | 6 +++- + 2 files changed, 28 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index b07033c2851e4..9f39afdfd415e 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -440,7 +440,7 @@ static u32 lan743x_intr_get_vector_flags(struct lan743x_adapter *adapter, + { + int index; + +- for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) { ++ for (index = 0; index < adapter->max_vector_count; index++) { + if (adapter->intr.vector_list[index].int_mask & int_mask) + return adapter->intr.vector_list[index].flags; + } +@@ -453,9 +453,12 @@ static void lan743x_intr_close(struct lan743x_adapter *adapter) + int index = 0; + + lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_MAS_); +- lan743x_csr_write(adapter, INT_VEC_EN_CLR, 0x000000FF); ++ if (adapter->is_pci11x1x) ++ lan743x_csr_write(adapter, INT_VEC_EN_CLR, 0x0000FFFF); ++ else ++ lan743x_csr_write(adapter, INT_VEC_EN_CLR, 0x000000FF); + +- for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) { ++ for (index = 0; index < intr->number_of_vectors; index++) { + if (intr->flags & INTR_FLAG_IRQ_REQUESTED(index)) { + lan743x_intr_unregister_isr(adapter, index); + intr->flags &= ~INTR_FLAG_IRQ_REQUESTED(index); +@@ -475,10 +478,11 @@ static void lan743x_intr_close(struct lan743x_adapter *adapter) + + static int lan743x_intr_open(struct lan743x_adapter *adapter) + { +- struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT]; ++ struct msix_entry msix_entries[PCI11X1X_MAX_VECTOR_COUNT]; + struct lan743x_intr *intr = &adapter->intr; + unsigned int used_tx_channels; + u32 int_vec_en_auto_clr = 0; ++ u8 max_vector_count; + u32 int_vec_map0 = 0; + u32 int_vec_map1 = 0; + int ret = -ENODEV; +@@ -488,9 +492,10 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + intr->number_of_vectors = 0; + + /* Try to set up MSIX interrupts */ ++ max_vector_count = adapter->max_vector_count; + memset(&msix_entries[0], 0, +- sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT); +- for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) ++ sizeof(struct msix_entry) * max_vector_count); ++ for (index = 0; index < max_vector_count; index++) + msix_entries[index].entry = index; + used_tx_channels = adapter->used_tx_channels; + ret = pci_enable_msix_range(adapter->pdev, +@@ -586,8 +591,15 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + lan743x_csr_write(adapter, INT_MOD_CFG5, LAN743X_INT_MOD); + lan743x_csr_write(adapter, INT_MOD_CFG6, LAN743X_INT_MOD); + lan743x_csr_write(adapter, INT_MOD_CFG7, LAN743X_INT_MOD); +- lan743x_csr_write(adapter, INT_MOD_MAP0, 0x00005432); +- lan743x_csr_write(adapter, INT_MOD_MAP1, 0x00000001); ++ if (adapter->is_pci11x1x) { ++ lan743x_csr_write(adapter, INT_MOD_CFG8, LAN743X_INT_MOD); ++ lan743x_csr_write(adapter, INT_MOD_CFG9, LAN743X_INT_MOD); ++ lan743x_csr_write(adapter, INT_MOD_MAP0, 0x00007654); ++ lan743x_csr_write(adapter, INT_MOD_MAP1, 0x00003210); ++ } else { ++ lan743x_csr_write(adapter, INT_MOD_MAP0, 0x00005432); ++ lan743x_csr_write(adapter, INT_MOD_MAP1, 0x00000001); ++ } + lan743x_csr_write(adapter, INT_MOD_MAP2, 0x00FFFFFF); + } + +@@ -662,7 +674,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) + LAN743X_VECTOR_FLAG_SOURCE_STATUS_AUTO_CLEAR; + } + for (index = 0; index < number_of_rx_vectors; index++) { +- int vector = index + 1 + LAN743X_USED_TX_CHANNELS; ++ int vector = index + 1 + used_tx_channels; + u32 int_bit = INT_BIT_DMA_RX_(index); + + /* map RX interrupt to vector */ +@@ -2728,9 +2740,11 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, + if (adapter->is_pci11x1x) { + adapter->max_tx_channels = PCI11X1X_MAX_TX_CHANNELS; + adapter->used_tx_channels = PCI11X1X_USED_TX_CHANNELS; ++ adapter->max_vector_count = PCI11X1X_MAX_VECTOR_COUNT; + } else { + adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS; + adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS; ++ adapter->max_vector_count = LAN743X_MAX_VECTOR_COUNT; + } + + adapter->intr.irq = adapter->pdev->irq; +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index fc33a05ff02d2..52d787aed0d17 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -293,6 +293,8 @@ + #define INT_MOD_CFG5 (0x7D4) + #define INT_MOD_CFG6 (0x7D8) + #define INT_MOD_CFG7 (0x7DC) ++#define INT_MOD_CFG8 (0x7E0) ++#define INT_MOD_CFG9 (0x7E4) + + #define PTP_CMD_CTL (0x0A00) + #define PTP_CMD_CTL_PTP_CLK_STP_NSEC_ BIT(6) +@@ -645,13 +647,14 @@ struct lan743x_vector { + }; + + #define LAN743X_MAX_VECTOR_COUNT (8) ++#define PCI11X1X_MAX_VECTOR_COUNT (16) + + struct lan743x_intr { + int flags; + + unsigned int irq; + +- struct lan743x_vector vector_list[LAN743X_MAX_VECTOR_COUNT]; ++ struct lan743x_vector vector_list[PCI11X1X_MAX_VECTOR_COUNT]; + int number_of_vectors; + bool using_vectors; + +@@ -762,6 +765,7 @@ struct lan743x_adapter { + bool is_pci11x1x; + u8 max_tx_channels; + u8 used_tx_channels; ++ u8 max_vector_count; + + #define LAN743X_ADAPTER_FLAG_OTP BIT(0) + u32 flags; +-- +2.43.0 + diff --git a/queue-5.4/net-lan743x-support-wol-at-both-the-phy-and-mac-appr.patch b/queue-5.4/net-lan743x-support-wol-at-both-the-phy-and-mac-appr.patch new file mode 100644 index 00000000000..c7965883158 --- /dev/null +++ b/queue-5.4/net-lan743x-support-wol-at-both-the-phy-and-mac-appr.patch @@ -0,0 +1,165 @@ +From 011430715ffb28689b6d78d4c65aa2728f6682f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 22:41:56 +0530 +Subject: net: lan743x: Support WOL at both the PHY and MAC appropriately + +From: Raju Lakkaraju + +[ Upstream commit 8c248cd836014339498486f14f435c0e344183a7 ] + +Prevent options not supported by the PHY from being requested to it by the MAC +Whenever a WOL option is supported by both, the PHY is given priority +since that usually leads to better power savings. + +Fixes: e9e13b6adc33 ("lan743x: fix for potential NULL pointer dereference with bare card") +Reviewed-by: Wojciech Drewek +Signed-off-by: Raju Lakkaraju +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/microchip/lan743x_ethtool.c | 44 +++++++++++++++++-- + drivers/net/ethernet/microchip/lan743x_main.c | 18 ++++++-- + drivers/net/ethernet/microchip/lan743x_main.h | 4 ++ + 3 files changed, 58 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c +index 469a591cf9cd2..aa549bb7201b7 100644 +--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c ++++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c +@@ -784,8 +784,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev, + if (netdev->phydev) + phy_ethtool_get_wol(netdev->phydev, wol); + +- wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | +- WAKE_MAGIC | WAKE_PHY | WAKE_ARP; ++ if (wol->supported != adapter->phy_wol_supported) ++ netif_warn(adapter, drv, adapter->netdev, ++ "PHY changed its supported WOL! old=%x, new=%x\n", ++ adapter->phy_wol_supported, wol->supported); ++ ++ wol->supported |= MAC_SUPPORTED_WAKES; + + if (adapter->is_pci11x1x) + wol->supported |= WAKE_MAGICSECURE; +@@ -800,7 +804,39 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, + { + struct lan743x_adapter *adapter = netdev_priv(netdev); + ++ /* WAKE_MAGICSEGURE is a modifier of and only valid together with ++ * WAKE_MAGIC ++ */ ++ if ((wol->wolopts & WAKE_MAGICSECURE) && !(wol->wolopts & WAKE_MAGIC)) ++ return -EINVAL; ++ ++ if (netdev->phydev) { ++ struct ethtool_wolinfo phy_wol; ++ int ret; ++ ++ phy_wol.wolopts = wol->wolopts & adapter->phy_wol_supported; ++ ++ /* If WAKE_MAGICSECURE was requested, filter out WAKE_MAGIC ++ * for PHYs that do not support WAKE_MAGICSECURE ++ */ ++ if (wol->wolopts & WAKE_MAGICSECURE && ++ !(adapter->phy_wol_supported & WAKE_MAGICSECURE)) ++ phy_wol.wolopts &= ~WAKE_MAGIC; ++ ++ ret = phy_ethtool_set_wol(netdev->phydev, &phy_wol); ++ if (ret && (ret != -EOPNOTSUPP)) ++ return ret; ++ ++ if (ret == -EOPNOTSUPP) ++ adapter->phy_wolopts = 0; ++ else ++ adapter->phy_wolopts = phy_wol.wolopts; ++ } else { ++ adapter->phy_wolopts = 0; ++ } ++ + adapter->wolopts = 0; ++ wol->wolopts &= ~adapter->phy_wolopts; + if (wol->wolopts & WAKE_UCAST) + adapter->wolopts |= WAKE_UCAST; + if (wol->wolopts & WAKE_MCAST) +@@ -821,10 +857,10 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev, + memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX); + } + ++ wol->wolopts = adapter->wolopts | adapter->phy_wolopts; + device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts); + +- return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol) +- : -ENETDOWN; ++ return 0; + } + #endif /* CONFIG_PM */ + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index f77d3221072d9..4cd042db45b96 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -2594,6 +2594,17 @@ static int lan743x_netdev_open(struct net_device *netdev) + if (ret) + goto close_tx; + } ++ ++#ifdef CONFIG_PM ++ if (adapter->netdev->phydev) { ++ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; ++ ++ phy_ethtool_get_wol(netdev->phydev, &wol); ++ adapter->phy_wol_supported = wol.supported; ++ adapter->phy_wolopts = wol.wolopts; ++ } ++#endif ++ + return 0; + + close_tx: +@@ -3025,10 +3036,9 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) + + pmtctl |= PMT_CTL_ETH_PHY_D3_COLD_OVR_ | PMT_CTL_ETH_PHY_D3_OVR_; + +- if (adapter->wolopts & WAKE_PHY) { +- pmtctl |= PMT_CTL_ETH_PHY_EDPD_PLL_CTL_; ++ if (adapter->phy_wolopts) + pmtctl |= PMT_CTL_ETH_PHY_WAKE_EN_; +- } ++ + if (adapter->wolopts & WAKE_MAGIC) { + wucsr |= MAC_WUCSR_MPEN_; + macrx |= MAC_RX_RXEN_; +@@ -3124,7 +3134,7 @@ static int lan743x_pm_suspend(struct device *dev) + lan743x_csr_write(adapter, MAC_WUCSR2, 0); + lan743x_csr_write(adapter, MAC_WK_SRC, 0xFFFFFFFF); + +- if (adapter->wolopts) ++ if (adapter->wolopts || adapter->phy_wolopts) + lan743x_pm_set_wol(adapter); + + if (adapter->is_pci11x1x) { +diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h +index 1825021c63f81..13634771ae2c0 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.h ++++ b/drivers/net/ethernet/microchip/lan743x_main.h +@@ -758,6 +758,8 @@ struct lan743x_rx { + u32 frame_count; + }; + ++#define MAC_SUPPORTED_WAKES (WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | \ ++ WAKE_MAGIC | WAKE_ARP) + struct lan743x_adapter { + struct net_device *netdev; + struct mii_bus *mdiobus; +@@ -765,6 +767,8 @@ struct lan743x_adapter { + #ifdef CONFIG_PM + u32 wolopts; + u8 sopass[SOPASS_MAX]; ++ u32 phy_wolopts; ++ u32 phy_wol_supported; + #endif + struct pci_dev *pdev; + struct lan743x_csr csr; +-- +2.43.0 + diff --git a/queue-5.4/net-microchip-make-lan743x_pm_suspend-function-retur.patch b/queue-5.4/net-microchip-make-lan743x_pm_suspend-function-retur.patch new file mode 100644 index 00000000000..c3ae129b3f9 --- /dev/null +++ b/queue-5.4/net-microchip-make-lan743x_pm_suspend-function-retur.patch @@ -0,0 +1,48 @@ +From e6a73b840d68707c457fcf7d624d217aabc1ddb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Sep 2020 11:21:40 +0800 +Subject: net: microchip: Make `lan743x_pm_suspend` function return right value + +From: Zheng Yongjun + +[ Upstream commit 46237bf3ee834252edb73cfc48855e99b3bd744b ] + +drivers/net/ethernet/microchip/lan743x_main.c: In function lan743x_pm_suspend: + +`ret` is set but not used. In fact, `pci_prepare_to_sleep` function value should +be the right value of `lan743x_pm_suspend` function, therefore, fix it. + +Signed-off-by: Zheng Yongjun +Signed-off-by: David S. Miller +Stable-dep-of: 7725363936a8 ("net: lan743x: disable WOL upon resume to restore full data path operation") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microchip/lan743x_main.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 6458dbd6c631a..083f7a051ca38 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -2997,7 +2997,6 @@ static int lan743x_pm_suspend(struct device *dev) + struct pci_dev *pdev = to_pci_dev(dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct lan743x_adapter *adapter = netdev_priv(netdev); +- int ret; + + lan743x_pcidev_shutdown(pdev); + +@@ -3010,9 +3009,7 @@ static int lan743x_pm_suspend(struct device *dev) + lan743x_pm_set_wol(adapter); + + /* Host sets PME_En, put D3hot */ +- ret = pci_prepare_to_sleep(pdev); +- +- return 0; ++ return pci_prepare_to_sleep(pdev);; + } + + static int lan743x_pm_resume(struct device *dev) +-- +2.43.0 + diff --git a/queue-5.4/net-sched-act_api-fix-possible-infinite-loop-in-tcf_.patch b/queue-5.4/net-sched-act_api-fix-possible-infinite-loop-in-tcf_.patch new file mode 100644 index 00000000000..12e1d3a0d5d --- /dev/null +++ b/queue-5.4/net-sched-act_api-fix-possible-infinite-loop-in-tcf_.patch @@ -0,0 +1,77 @@ +From 9ae30af6fc8b137678f0b9ebf615570f745b33c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 19:03:26 +0000 +Subject: net/sched: act_api: fix possible infinite loop in + tcf_idr_check_alloc() + +From: David Ruth + +[ Upstream commit d864319871b05fadd153e0aede4811ca7008f5d6 ] + +syzbot found hanging tasks waiting on rtnl_lock [1] + +A reproducer is available in the syzbot bug. + +When a request to add multiple actions with the same index is sent, the +second request will block forever on the first request. This holds +rtnl_lock, and causes tasks to hang. + +Return -EAGAIN to prevent infinite looping, while keeping documented +behavior. + +[1] + +INFO: task kworker/1:0:5088 blocked for more than 143 seconds. +Not tainted 6.9.0-rc4-syzkaller-00173-g3cdb45594619 #0 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +task:kworker/1:0 state:D stack:23744 pid:5088 tgid:5088 ppid:2 flags:0x00004000 +Workqueue: events_power_efficient reg_check_chans_work +Call Trace: + +context_switch kernel/sched/core.c:5409 [inline] +__schedule+0xf15/0x5d00 kernel/sched/core.c:6746 +__schedule_loop kernel/sched/core.c:6823 [inline] +schedule+0xe7/0x350 kernel/sched/core.c:6838 +schedule_preempt_disabled+0x13/0x30 kernel/sched/core.c:6895 +__mutex_lock_common kernel/locking/mutex.c:684 [inline] +__mutex_lock+0x5b8/0x9c0 kernel/locking/mutex.c:752 +wiphy_lock include/net/cfg80211.h:5953 [inline] +reg_leave_invalid_chans net/wireless/reg.c:2466 [inline] +reg_check_chans_work+0x10a/0x10e0 net/wireless/reg.c:2481 + +Fixes: 0190c1d452a9 ("net: sched: atomically check-allocate action") +Reported-by: syzbot+b87c222546179f4513a7@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=b87c222546179f4513a7 +Signed-off-by: David Ruth +Reviewed-by: Jamal Hadi Salim +Link: https://lore.kernel.org/r/20240614190326.1349786-1-druth@chromium.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/act_api.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index 92477d51c49dd..52394e45bac55 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -493,7 +493,6 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + u32 max; + + if (*index) { +-again: + rcu_read_lock(); + p = idr_find(&idrinfo->action_idr, *index); + +@@ -502,7 +501,7 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + * index but did not assign the pointer yet. + */ + rcu_read_unlock(); +- goto again; ++ return -EAGAIN; + } + + if (!p) { +-- +2.43.0 + diff --git a/queue-5.4/net-sched-act_api-rely-on-rcu-in-tcf_idr_check_alloc.patch b/queue-5.4/net-sched-act_api-rely-on-rcu-in-tcf_idr_check_alloc.patch new file mode 100644 index 00000000000..3fee370e521 --- /dev/null +++ b/queue-5.4/net-sched-act_api-rely-on-rcu-in-tcf_idr_check_alloc.patch @@ -0,0 +1,173 @@ +From 2bac5964ffa9af891b90bcbc433923161e22502d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Dec 2023 15:18:06 -0300 +Subject: net/sched: act_api: rely on rcu in tcf_idr_check_alloc + +From: Pedro Tammela + +[ Upstream commit 4b55e86736d5b492cf689125da2600f59c7d2c39 ] + +Instead of relying only on the idrinfo->lock mutex for +bind/alloc logic, rely on a combination of rcu + mutex + atomics +to better scale the case where multiple rtnl-less filters are +binding to the same action object. + +Action binding happens when an action index is specified explicitly and +an action exists which such index exists. Example: + tc actions add action drop index 1 + tc filter add ... matchall action drop index 1 + tc filter add ... matchall action drop index 1 + tc filter add ... matchall action drop index 1 + tc filter ls ... + filter protocol all pref 49150 matchall chain 0 filter protocol all pref 49150 matchall chain 0 handle 0x1 + not_in_hw + action order 1: gact action drop + random type none pass val 0 + index 1 ref 4 bind 3 + + filter protocol all pref 49151 matchall chain 0 filter protocol all pref 49151 matchall chain 0 handle 0x1 + not_in_hw + action order 1: gact action drop + random type none pass val 0 + index 1 ref 4 bind 3 + + filter protocol all pref 49152 matchall chain 0 filter protocol all pref 49152 matchall chain 0 handle 0x1 + not_in_hw + action order 1: gact action drop + random type none pass val 0 + index 1 ref 4 bind 3 + +When no index is specified, as before, grab the mutex and allocate +in the idr the next available id. In this version, as opposed to before, +it's simplified to store the -EBUSY pointer instead of the previous +alloc + replace combination. + +When an index is specified, rely on rcu to find if there's an object in +such index. If there's none, fallback to the above, serializing on the +mutex and reserving the specified id. If there's one, it can be an -EBUSY +pointer, in which case we just try again until it's an action, or an action. +Given the rcu guarantees, the action found could be dead and therefore +we need to bump the refcount if it's not 0, handling the case it's +in fact 0. + +As bind and the action refcount are already atomics, these increments can +happen without the mutex protection while many tcf_idr_check_alloc race +to bind to the same action instance. + +In case binding encounters a parallel delete or add, it will return +-EAGAIN in order to try again. Both filter and action apis already +have the retry machinery in-place. In case it's an unlocked filter it +retries under the rtnl lock. + +Signed-off-by: Pedro Tammela +Acked-by: Jamal Hadi Salim +Reviewed-by: Vlad Buslov +Link: https://lore.kernel.org/r/20231211181807.96028-2-pctammela@mojatatu.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: d864319871b0 ("net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc()") +Signed-off-by: Sasha Levin +--- + net/sched/act_api.c | 65 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 43 insertions(+), 22 deletions(-) + +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index db1c0139f99c6..92477d51c49dd 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -479,6 +479,9 @@ EXPORT_SYMBOL(tcf_idr_cleanup); + * its reference and bind counters, and return 1. Otherwise insert temporary + * error pointer (to prevent concurrent users from inserting actions with same + * index) and return 0. ++ * ++ * May return -EAGAIN for binding actions in case of a parallel add/delete on ++ * the requested index. + */ + + int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, +@@ -487,43 +490,61 @@ int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + struct tcf_idrinfo *idrinfo = tn->idrinfo; + struct tc_action *p; + int ret; ++ u32 max; + +-again: +- mutex_lock(&idrinfo->lock); + if (*index) { ++again: ++ rcu_read_lock(); + p = idr_find(&idrinfo->action_idr, *index); ++ + if (IS_ERR(p)) { + /* This means that another process allocated + * index but did not assign the pointer yet. + */ +- mutex_unlock(&idrinfo->lock); ++ rcu_read_unlock(); + goto again; + } + +- if (p) { +- refcount_inc(&p->tcfa_refcnt); +- if (bind) +- atomic_inc(&p->tcfa_bindcnt); +- *a = p; +- ret = 1; +- } else { +- *a = NULL; +- ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index, +- *index, GFP_KERNEL); +- if (!ret) +- idr_replace(&idrinfo->action_idr, +- ERR_PTR(-EBUSY), *index); ++ if (!p) { ++ /* Empty slot, try to allocate it */ ++ max = *index; ++ rcu_read_unlock(); ++ goto new; ++ } ++ ++ if (!refcount_inc_not_zero(&p->tcfa_refcnt)) { ++ /* Action was deleted in parallel */ ++ rcu_read_unlock(); ++ return -EAGAIN; + } ++ ++ if (bind) ++ atomic_inc(&p->tcfa_bindcnt); ++ *a = p; ++ ++ rcu_read_unlock(); ++ ++ return 1; + } else { ++ /* Find a slot */ + *index = 1; +- *a = NULL; +- ret = idr_alloc_u32(&idrinfo->action_idr, NULL, index, +- UINT_MAX, GFP_KERNEL); +- if (!ret) +- idr_replace(&idrinfo->action_idr, ERR_PTR(-EBUSY), +- *index); ++ max = UINT_MAX; + } ++ ++new: ++ *a = NULL; ++ ++ mutex_lock(&idrinfo->lock); ++ ret = idr_alloc_u32(&idrinfo->action_idr, ERR_PTR(-EBUSY), index, max, ++ GFP_KERNEL); + mutex_unlock(&idrinfo->lock); ++ ++ /* N binds raced for action allocation, ++ * retry for all the ones that failed. ++ */ ++ if (ret == -ENOSPC && *index == max) ++ ret = -EAGAIN; ++ + return ret; + } + EXPORT_SYMBOL(tcf_idr_check_alloc); +-- +2.43.0 + diff --git a/queue-5.4/net-usb-rtl8150-fix-unintiatilzed-variables-in-rtl81.patch b/queue-5.4/net-usb-rtl8150-fix-unintiatilzed-variables-in-rtl81.patch new file mode 100644 index 00000000000..d78e525a516 --- /dev/null +++ b/queue-5.4/net-usb-rtl8150-fix-unintiatilzed-variables-in-rtl81.patch @@ -0,0 +1,41 @@ +From 885e997e5ecd82220488b17dfea221a9c0e2f7b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jun 2024 15:28:03 +0200 +Subject: net: usb: rtl8150 fix unintiatilzed variables in + rtl8150_get_link_ksettings + +From: Oliver Neukum + +[ Upstream commit fba383985354e83474f95f36d7c65feb75dba19d ] + +This functions retrieves values by passing a pointer. As the function +that retrieves them can fail before touching the pointers, the variables +must be initialized. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+5186630949e3c55f0799@syzkaller.appspotmail.com +Signed-off-by: Oliver Neukum +Link: https://lore.kernel.org/r/20240619132816.11526-1-oneukum@suse.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/rtl8150.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index 491625c1c3084..387091cb91340 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -798,7 +798,8 @@ static int rtl8150_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *ecmd) + { + rtl8150_t *dev = netdev_priv(netdev); +- short lpa, bmcr; ++ short lpa = 0; ++ short bmcr = 0; + u32 supported; + + supported = (SUPPORTED_10baseT_Half | +-- +2.43.0 + diff --git a/queue-5.4/netfilter-ipset-fix-suspicious-rcu_dereference_prote.patch b/queue-5.4/netfilter-ipset-fix-suspicious-rcu_dereference_prote.patch new file mode 100644 index 00000000000..0e23b315def --- /dev/null +++ b/queue-5.4/netfilter-ipset-fix-suspicious-rcu_dereference_prote.patch @@ -0,0 +1,61 @@ +From 4410d0f9bdba0327229e8bad1bc2fd580cf4924b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jun 2024 11:18:15 +0200 +Subject: netfilter: ipset: Fix suspicious rcu_dereference_protected() + +From: Jozsef Kadlecsik + +[ Upstream commit 8ecd06277a7664f4ef018abae3abd3451d64e7a6 ] + +When destroying all sets, we are either in pernet exit phase or +are executing a "destroy all sets command" from userspace. The latter +was taken into account in ip_set_dereference() (nfnetlink mutex is held), +but the former was not. The patch adds the required check to +rcu_dereference_protected() in ip_set_dereference(). + +Fixes: 4e7aaa6b82d6 ("netfilter: ipset: Fix race between namespace cleanup and gc in the list:set type") +Reported-by: syzbot+b62c37cdd58103293a5a@syzkaller.appspotmail.com +Reported-by: syzbot+cfbe1da5fdfc39efc293@syzkaller.appspotmail.com +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-lkp/202406141556.e0b6f17e-lkp@intel.com +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/ipset/ip_set_core.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 04273f94504fb..83fa95ecaad47 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -53,12 +53,13 @@ MODULE_DESCRIPTION("core IP set support"); + MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); + + /* When the nfnl mutex or ip_set_ref_lock is held: */ +-#define ip_set_dereference(p) \ +- rcu_dereference_protected(p, \ ++#define ip_set_dereference(inst) \ ++ rcu_dereference_protected((inst)->ip_set_list, \ + lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ +- lockdep_is_held(&ip_set_ref_lock)) ++ lockdep_is_held(&ip_set_ref_lock) || \ ++ (inst)->is_deleted) + #define ip_set(inst, id) \ +- ip_set_dereference((inst)->ip_set_list)[id] ++ ip_set_dereference(inst)[id] + #define ip_set_ref_netlink(inst,id) \ + rcu_dereference_raw((inst)->ip_set_list)[id] + #define ip_set_dereference_nfnl(p) \ +@@ -985,7 +986,7 @@ static int ip_set_create(struct net *net, struct sock *ctnl, + if (!list) + goto cleanup; + /* nfnl mutex is held, both lists are valid */ +- tmp = ip_set_dereference(inst->ip_set_list); ++ tmp = ip_set_dereference(inst); + memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max); + rcu_assign_pointer(inst->ip_set_list, list); + /* Make sure all current packets have passed through */ +-- +2.43.0 + diff --git a/queue-5.4/netns-make-get_net_ns-handle-zero-refcount-net.patch b/queue-5.4/netns-make-get_net_ns-handle-zero-refcount-net.patch new file mode 100644 index 00000000000..4c1c4f8ebcd --- /dev/null +++ b/queue-5.4/netns-make-get_net_ns-handle-zero-refcount-net.patch @@ -0,0 +1,113 @@ +From f0cb0df161dbbc6a99710fd7ea7f5af481e096f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Jun 2024 21:13:02 +0800 +Subject: netns: Make get_net_ns() handle zero refcount net + +From: Yue Haibing + +[ Upstream commit ff960f9d3edbe08a736b5a224d91a305ccc946b0 ] + +Syzkaller hit a warning: +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 3 PID: 7890 at lib/refcount.c:25 refcount_warn_saturate+0xdf/0x1d0 +Modules linked in: +CPU: 3 PID: 7890 Comm: tun Not tainted 6.10.0-rc3-00100-gcaa4f9578aba-dirty #310 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 +RIP: 0010:refcount_warn_saturate+0xdf/0x1d0 +Code: 41 49 04 31 ff 89 de e8 9f 1e cd fe 84 db 75 9c e8 76 26 cd fe c6 05 b6 41 49 04 01 90 48 c7 c7 b8 8e 25 86 e8 d2 05 b5 fe 90 <0f> 0b 90 90 e9 79 ff ff ff e8 53 26 cd fe 0f b6 1 +RSP: 0018:ffff8881067b7da0 EFLAGS: 00010286 +RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff811c72ac +RDX: ffff8881026a2140 RSI: ffffffff811c72b5 RDI: 0000000000000001 +RBP: ffff8881067b7db0 R08: 0000000000000000 R09: 205b5d3730353139 +R10: 0000000000000000 R11: 205d303938375420 R12: ffff8881086500c4 +R13: ffff8881086500c4 R14: ffff8881086500b0 R15: ffff888108650040 +FS: 00007f5b2961a4c0(0000) GS:ffff88823bd00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 000055d7ed36fd18 CR3: 00000001482f6000 CR4: 00000000000006f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + ? show_regs+0xa3/0xc0 + ? __warn+0xa5/0x1c0 + ? refcount_warn_saturate+0xdf/0x1d0 + ? report_bug+0x1fc/0x2d0 + ? refcount_warn_saturate+0xdf/0x1d0 + ? handle_bug+0xa1/0x110 + ? exc_invalid_op+0x3c/0xb0 + ? asm_exc_invalid_op+0x1f/0x30 + ? __warn_printk+0xcc/0x140 + ? __warn_printk+0xd5/0x140 + ? refcount_warn_saturate+0xdf/0x1d0 + get_net_ns+0xa4/0xc0 + ? __pfx_get_net_ns+0x10/0x10 + open_related_ns+0x5a/0x130 + __tun_chr_ioctl+0x1616/0x2370 + ? __sanitizer_cov_trace_switch+0x58/0xa0 + ? __sanitizer_cov_trace_const_cmp2+0x1c/0x30 + ? __pfx_tun_chr_ioctl+0x10/0x10 + tun_chr_ioctl+0x2f/0x40 + __x64_sys_ioctl+0x11b/0x160 + x64_sys_call+0x1211/0x20d0 + do_syscall_64+0x9e/0x1d0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7f5b28f165d7 +Code: b3 66 90 48 8b 05 b1 48 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 81 48 2d 00 8 +RSP: 002b:00007ffc2b59c5e8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f5b28f165d7 +RDX: 0000000000000000 RSI: 00000000000054e3 RDI: 0000000000000003 +RBP: 00007ffc2b59c650 R08: 00007f5b291ed8c0 R09: 00007f5b2961a4c0 +R10: 0000000029690010 R11: 0000000000000246 R12: 0000000000400730 +R13: 00007ffc2b59cf40 R14: 0000000000000000 R15: 0000000000000000 + +Kernel panic - not syncing: kernel: panic_on_warn set ... + +This is trigger as below: + ns0 ns1 +tun_set_iff() //dev is tun0 + tun->dev = dev +//ip link set tun0 netns ns1 + put_net() //ref is 0 +__tun_chr_ioctl() //TUNGETDEVNETNS + net = dev_net(tun->dev); + open_related_ns(&net->ns, get_net_ns); //ns1 + get_net_ns() + get_net() //addition on 0 + +Use maybe_get_net() in get_net_ns in case net's ref is zero to fix this + +Fixes: 0c3e0e3bb623 ("tun: Add ioctl() TUNGETDEVNETNS cmd to allow obtaining real net ns of tun device") +Signed-off-by: Yue Haibing +Link: https://lore.kernel.org/r/20240614131302.2698509-1-yuehaibing@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/core/net_namespace.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 5827de79610b9..c94179d30d426 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -664,11 +664,16 @@ EXPORT_SYMBOL_GPL(__put_net); + * get_net_ns - increment the refcount of the network namespace + * @ns: common namespace (net) + * +- * Returns the net's common namespace. ++ * Returns the net's common namespace or ERR_PTR() if ref is zero. + */ + struct ns_common *get_net_ns(struct ns_common *ns) + { +- return &get_net(container_of(ns, struct net, ns))->ns; ++ struct net *net; ++ ++ net = maybe_get_net(container_of(ns, struct net, ns)); ++ if (net) ++ return &net->ns; ++ return ERR_PTR(-EINVAL); + } + EXPORT_SYMBOL_GPL(get_net_ns); + +-- +2.43.0 + diff --git a/queue-5.4/netrom-fix-a-memory-leak-in-nr_heartbeat_expiry.patch b/queue-5.4/netrom-fix-a-memory-leak-in-nr_heartbeat_expiry.patch new file mode 100644 index 00000000000..13be022752f --- /dev/null +++ b/queue-5.4/netrom-fix-a-memory-leak-in-nr_heartbeat_expiry.patch @@ -0,0 +1,83 @@ +From 29826e67b227ffeac20745f03d1c4bbc2a35a730 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jun 2024 08:23:00 +0000 +Subject: netrom: Fix a memory leak in nr_heartbeat_expiry() + +From: Gavrilov Ilia + +[ Upstream commit 0b9130247f3b6a1122478471ff0e014ea96bb735 ] + +syzbot reported a memory leak in nr_create() [0]. + +Commit 409db27e3a2e ("netrom: Fix use-after-free of a listening socket.") +added sock_hold() to the nr_heartbeat_expiry() function, where +a) a socket has a SOCK_DESTROY flag or +b) a listening socket has a SOCK_DEAD flag. + +But in the case "a," when the SOCK_DESTROY flag is set, the file descriptor +has already been closed and the nr_release() function has been called. +So it makes no sense to hold the reference count because no one will +call another nr_destroy_socket() and put it as in the case "b." + +nr_connect + nr_establish_data_link + nr_start_heartbeat + +nr_release + switch (nr->state) + case NR_STATE_3 + nr->state = NR_STATE_2 + sock_set_flag(sk, SOCK_DESTROY); + + nr_rx_frame + nr_process_rx_frame + switch (nr->state) + case NR_STATE_2 + nr_state2_machine() + nr_disconnect() + nr_sk(sk)->state = NR_STATE_0 + sock_set_flag(sk, SOCK_DEAD) + + nr_heartbeat_expiry + switch (nr->state) + case NR_STATE_0 + if (sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN + && sock_flag(sk, SOCK_DEAD))) + sock_hold() // ( !!! ) + nr_destroy_socket() + +To fix the memory leak, let's call sock_hold() only for a listening socket. + +Found by InfoTeCS on behalf of Linux Verification Center +(linuxtesting.org) with Syzkaller. + +[0]: https://syzkaller.appspot.com/bug?extid=d327a1f3b12e1e206c16 + +Reported-by: syzbot+d327a1f3b12e1e206c16@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=d327a1f3b12e1e206c16 +Fixes: 409db27e3a2e ("netrom: Fix use-after-free of a listening socket.") +Signed-off-by: Gavrilov Ilia +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/netrom/nr_timer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c +index 4e7c968cde2dc..5e3ca068f04e0 100644 +--- a/net/netrom/nr_timer.c ++++ b/net/netrom/nr_timer.c +@@ -121,7 +121,8 @@ static void nr_heartbeat_expiry(struct timer_list *t) + is accepted() it isn't 'dead' so doesn't get removed. */ + if (sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { +- sock_hold(sk); ++ if (sk->sk_state == TCP_LISTEN) ++ sock_hold(sk); + bh_unlock_sock(sk); + nr_destroy_socket(sk); + goto out; +-- +2.43.0 + diff --git a/queue-5.4/series b/queue-5.4/series index 122d2cdf6eb..f47dca4f697 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -118,3 +118,24 @@ usb-misc-uss720-check-for-incompatible-versions-of-t.patch udf-udftime-prevent-overflow-in-udf_disk_stamp_to_ti.patch pci-pm-avoid-d3cold-for-hp-pavilion-17-pc-1972-pcie-.patch mips-octeon-add-pcie-link-status-check.patch +mips-routerboard-532-fix-vendor-retry-check-code.patch +mips-bmips-bcm6358-make-sure-cbr-is-correctly-set.patch +cipso-fix-total-option-length-computation.patch +netrom-fix-a-memory-leak-in-nr_heartbeat_expiry.patch +ipv6-prevent-possible-null-deref-in-fib6_nh_init.patch +ipv6-prevent-possible-null-dereference-in-rt6_probe.patch +xfrm6-check-ip6_dst_idev-return-value-in-xfrm6_get_s.patch +netns-make-get_net_ns-handle-zero-refcount-net.patch +net-microchip-make-lan743x_pm_suspend-function-retur.patch +net-lan743x-add-pci11010-pci11414-device-ids.patch +net-lan743x-add-support-for-4-tx-queues.patch +net-lan743x-add-support-to-secure-on-wol.patch +net-lan743x-disable-wol-upon-resume-to-restore-full-.patch +net-lan743x-increase-msi-x-vectors-to-16-and-int-de-.patch +net-lan743x-add-support-for-sgmii-interface.patch +net-lan743x-support-wol-at-both-the-phy-and-mac-appr.patch +net-sched-act_api-rely-on-rcu-in-tcf_idr_check_alloc.patch +net-sched-act_api-fix-possible-infinite-loop-in-tcf_.patch +virtio_net-checksum-offloading-handling-fix.patch +netfilter-ipset-fix-suspicious-rcu_dereference_prote.patch +net-usb-rtl8150-fix-unintiatilzed-variables-in-rtl81.patch diff --git a/queue-5.4/virtio_net-checksum-offloading-handling-fix.patch b/queue-5.4/virtio_net-checksum-offloading-handling-fix.patch new file mode 100644 index 00000000000..fe5f50ae713 --- /dev/null +++ b/queue-5.4/virtio_net-checksum-offloading-handling-fix.patch @@ -0,0 +1,64 @@ +From 24ab20f115da5632ced7c1e82b87f7d17227b74e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jun 2024 21:15:23 +0800 +Subject: virtio_net: checksum offloading handling fix + +From: Heng Qi + +[ Upstream commit 604141c036e1b636e2a71cf6e1aa09d1e45f40c2 ] + +In virtio spec 0.95, VIRTIO_NET_F_GUEST_CSUM was designed to handle +partially checksummed packets, and the validation of fully checksummed +packets by the device is independent of VIRTIO_NET_F_GUEST_CSUM +negotiation. However, the specification erroneously stated: + + "If VIRTIO_NET_F_GUEST_CSUM is not negotiated, the device MUST set flags + to zero and SHOULD supply a fully checksummed packet to the driver." + +This statement is inaccurate because even without VIRTIO_NET_F_GUEST_CSUM +negotiation, the device can still set the VIRTIO_NET_HDR_F_DATA_VALID flag. +Essentially, the device can facilitate the validation of these packets' +checksums - a process known as RX checksum offloading - removing the need +for the driver to do so. + +This scenario is currently not implemented in the driver and requires +correction. The necessary specification correction[1] has been made and +approved in the virtio TC vote. +[1] https://lists.oasis-open.org/archives/virtio-comment/202401/msg00011.html + +Fixes: 4f49129be6fa ("virtio-net: Set RXCSUM feature if GUEST_CSUM is available") +Signed-off-by: Heng Qi +Reviewed-by: Jiri Pirko +Acked-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 4faf3275b1f61..ef8770093c48c 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -3157,8 +3157,16 @@ static int virtnet_probe(struct virtio_device *vdev) + dev->features |= dev->hw_features & NETIF_F_ALL_TSO; + /* (!csum && gso) case will be fixed by register_netdev() */ + } +- if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) +- dev->features |= NETIF_F_RXCSUM; ++ ++ /* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't ++ * need to calculate checksums for partially checksummed packets, ++ * as they're considered valid by the upper layer. ++ * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only ++ * receives fully checksummed packets. The device may assist in ++ * validating these packets' checksums, so the driver won't have to. ++ */ ++ dev->features |= NETIF_F_RXCSUM; ++ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) + dev->features |= NETIF_F_GRO_HW; +-- +2.43.0 + diff --git a/queue-5.4/xfrm6-check-ip6_dst_idev-return-value-in-xfrm6_get_s.patch b/queue-5.4/xfrm6-check-ip6_dst_idev-return-value-in-xfrm6_get_s.patch new file mode 100644 index 00000000000..f5414fbc559 --- /dev/null +++ b/queue-5.4/xfrm6-check-ip6_dst_idev-return-value-in-xfrm6_get_s.patch @@ -0,0 +1,92 @@ +From 298ec136c2fcb7f59ecab4c30ad086bb53e1776c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Jun 2024 15:42:31 +0000 +Subject: xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr() + +From: Eric Dumazet + +[ Upstream commit d46401052c2d5614da8efea5788532f0401cb164 ] + +ip6_dst_idev() can return NULL, xfrm6_get_saddr() must act accordingly. + +syzbot reported: + +Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN PTI +KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] +CPU: 1 PID: 12 Comm: kworker/u8:1 Not tainted 6.10.0-rc2-syzkaller-00383-gb8481381d4e2 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/02/2024 +Workqueue: wg-kex-wg1 wg_packet_handshake_send_worker + RIP: 0010:xfrm6_get_saddr+0x93/0x130 net/ipv6/xfrm6_policy.c:64 +Code: df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 97 00 00 00 4c 8b ab d8 00 00 00 48 b8 00 00 00 00 00 fc ff df 4c 89 ea 48 c1 ea 03 <80> 3c 02 00 0f 85 86 00 00 00 4d 8b 6d 00 e8 ca 13 47 01 48 b8 00 +RSP: 0018:ffffc90000117378 EFLAGS: 00010246 +RAX: dffffc0000000000 RBX: ffff88807b079dc0 RCX: ffffffff89a0d6d7 +RDX: 0000000000000000 RSI: ffffffff89a0d6e9 RDI: ffff88807b079e98 +RBP: ffff88807ad73248 R08: 0000000000000007 R09: fffffffffffff000 +R10: ffff88807b079dc0 R11: 0000000000000007 R12: ffffc90000117480 +R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +FS: 0000000000000000(0000) GS:ffff8880b9300000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f4586d00440 CR3: 0000000079042000 CR4: 00000000003506f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + + xfrm_get_saddr net/xfrm/xfrm_policy.c:2452 [inline] + xfrm_tmpl_resolve_one net/xfrm/xfrm_policy.c:2481 [inline] + xfrm_tmpl_resolve+0xa26/0xf10 net/xfrm/xfrm_policy.c:2541 + xfrm_resolve_and_create_bundle+0x140/0x2570 net/xfrm/xfrm_policy.c:2835 + xfrm_bundle_lookup net/xfrm/xfrm_policy.c:3070 [inline] + xfrm_lookup_with_ifid+0x4d1/0x1e60 net/xfrm/xfrm_policy.c:3201 + xfrm_lookup net/xfrm/xfrm_policy.c:3298 [inline] + xfrm_lookup_route+0x3b/0x200 net/xfrm/xfrm_policy.c:3309 + ip6_dst_lookup_flow+0x15c/0x1d0 net/ipv6/ip6_output.c:1256 + send6+0x611/0xd20 drivers/net/wireguard/socket.c:139 + wg_socket_send_skb_to_peer+0xf9/0x220 drivers/net/wireguard/socket.c:178 + wg_socket_send_buffer_to_peer+0x12b/0x190 drivers/net/wireguard/socket.c:200 + wg_packet_send_handshake_initiation+0x227/0x360 drivers/net/wireguard/send.c:40 + wg_packet_handshake_send_worker+0x1c/0x30 drivers/net/wireguard/send.c:51 + process_one_work+0x9fb/0x1b60 kernel/workqueue.c:3231 + process_scheduled_works kernel/workqueue.c:3312 [inline] + worker_thread+0x6c8/0xf70 kernel/workqueue.c:3393 + kthread+0x2c1/0x3a0 kernel/kthread.c:389 + ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://lore.kernel.org/r/20240615154231.234442-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/xfrm6_policy.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index 4c3aa97f23faa..7c903e0e446cb 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -57,12 +57,18 @@ static int xfrm6_get_saddr(struct net *net, int oif, + { + struct dst_entry *dst; + struct net_device *dev; ++ struct inet6_dev *idev; + + dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr, mark); + if (IS_ERR(dst)) + return -EHOSTUNREACH; + +- dev = ip6_dst_idev(dst)->dev; ++ idev = ip6_dst_idev(dst); ++ if (!idev) { ++ dst_release(dst); ++ return -EHOSTUNREACH; ++ } ++ dev = idev->dev; + ipv6_dev_get_saddr(dev_net(dev), dev, &daddr->in6, 0, &saddr->in6); + dst_release(dst); + return 0; +-- +2.43.0 +