--- /dev/null
+From cc04c3de3bab0b9beed062957f05ed5d8777970c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 15:40:03 -0800
+Subject: Input: i8042 - fix leaking of platform device on module removal
+
+From: Chen Jun <chenjun102@huawei.com>
+
+[ Upstream commit 81cd7e8489278d28794e7b272950c3e00c344e44 ]
+
+Avoid resetting the module-wide i8042_platform_device pointer in
+i8042_probe() or i8042_remove(), so that the device can be properly
+destroyed by i8042_exit() on module unload.
+
+Fixes: 9222ba68c3f4 ("Input: i8042 - add deferred probe support")
+Signed-off-by: Chen Jun <chenjun102@huawei.com>
+Link: https://lore.kernel.org/r/20221109034148.23821-1-chenjun102@huawei.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/serio/i8042.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index a9f68f535b72..8648b4c46138 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -1543,8 +1543,6 @@ static int i8042_probe(struct platform_device *dev)
+ {
+ int error;
+
+- i8042_platform_device = dev;
+-
+ if (i8042_reset == I8042_RESET_ALWAYS) {
+ error = i8042_controller_selftest();
+ if (error)
+@@ -1582,7 +1580,6 @@ static int i8042_probe(struct platform_device *dev)
+ i8042_free_aux_ports(); /* in case KBD failed but AUX not */
+ i8042_free_irqs();
+ i8042_controller_reset(false);
+- i8042_platform_device = NULL;
+
+ return error;
+ }
+@@ -1592,7 +1589,6 @@ static int i8042_remove(struct platform_device *dev)
+ i8042_unregister_ports();
+ i8042_free_irqs();
+ i8042_controller_reset(false);
+- i8042_platform_device = NULL;
+
+ return 0;
+ }
+--
+2.35.1
+
--- /dev/null
+From cf8f6996ec58a080ef98f1a63b31ea1c75acdf57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Nov 2022 10:15:34 +0900
+Subject: kprobes: Skip clearing aggrprobe's post_handler in kprobe-on-ftrace
+ case
+
+From: Li Huafei <lihuafei1@huawei.com>
+
+[ Upstream commit 5dd7caf0bdc5d0bae7cf9776b4d739fb09bd5ebb ]
+
+In __unregister_kprobe_top(), if the currently unregistered probe has
+post_handler but other child probes of the aggrprobe do not have
+post_handler, the post_handler of the aggrprobe is cleared. If this is
+a ftrace-based probe, there is a problem. In later calls to
+disarm_kprobe(), we will use kprobe_ftrace_ops because post_handler is
+NULL. But we're armed with kprobe_ipmodify_ops. This triggers a WARN in
+__disarm_kprobe_ftrace() and may even cause use-after-free:
+
+ Failed to disarm kprobe-ftrace at kernel_clone+0x0/0x3c0 (error -2)
+ WARNING: CPU: 5 PID: 137 at kernel/kprobes.c:1135 __disarm_kprobe_ftrace.isra.21+0xcf/0xe0
+ Modules linked in: testKprobe_007(-)
+ CPU: 5 PID: 137 Comm: rmmod Not tainted 6.1.0-rc4-dirty #18
+ [...]
+ Call Trace:
+ <TASK>
+ __disable_kprobe+0xcd/0xe0
+ __unregister_kprobe_top+0x12/0x150
+ ? mutex_lock+0xe/0x30
+ unregister_kprobes.part.23+0x31/0xa0
+ unregister_kprobe+0x32/0x40
+ __x64_sys_delete_module+0x15e/0x260
+ ? do_user_addr_fault+0x2cd/0x6b0
+ do_syscall_64+0x3a/0x90
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+ [...]
+
+For the kprobe-on-ftrace case, we keep the post_handler setting to
+identify this aggrprobe armed with kprobe_ipmodify_ops. This way we
+can disarm it correctly.
+
+Link: https://lore.kernel.org/all/20221112070000.35299-1-lihuafei1@huawei.com/
+
+Fixes: 0bc11ed5ab60 ("kprobes: Allow kprobes coexist with livepatch")
+Reported-by: Zhao Gongyi <zhaogongyi@huawei.com>
+Suggested-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Li Huafei <lihuafei1@huawei.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/kprobes.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index b0f444e86487..75150e755518 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1841,7 +1841,13 @@ static int __unregister_kprobe_top(struct kprobe *p)
+ if ((list_p != p) && (list_p->post_handler))
+ goto noclean;
+ }
+- ap->post_handler = NULL;
++ /*
++ * For the kprobe-on-ftrace case, we keep the
++ * post_handler setting to identify this aggrprobe
++ * armed with kprobe_ipmodify_ops.
++ */
++ if (!kprobe_ftrace(ap))
++ ap->post_handler = NULL;
+ }
+ noclean:
+ /*
+--
+2.35.1
+
--- /dev/null
+From 6e121ef3f53982e168e775c4dececf3a2556c0fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Nov 2022 20:16:19 +0100
+Subject: l2tp: Serialize access to sk_user_data with sk_callback_lock
+
+From: Jakub Sitnicki <jakub@cloudflare.com>
+
+[ Upstream commit b68777d54fac21fc833ec26ea1a2a84f975ab035 ]
+
+sk->sk_user_data has multiple users, which are not compatible with each
+other. Writers must synchronize by grabbing the sk->sk_callback_lock.
+
+l2tp currently fails to grab the lock when modifying the underlying tunnel
+socket fields. Fix it by adding appropriate locking.
+
+We err on the side of safety and grab the sk_callback_lock also inside the
+sk_destruct callback overridden by l2tp, even though there should be no
+refs allowing access to the sock at the time when sk_destruct gets called.
+
+v4:
+- serialize write to sk_user_data in l2tp sk_destruct
+
+v3:
+- switch from sock lock to sk_callback_lock
+- document write-protection for sk_user_data
+
+v2:
+- update Fixes to point to origin of the bug
+- use real names in Reported/Tested-by tags
+
+Cc: Tom Parkin <tparkin@katalix.com>
+Fixes: 3557baabf280 ("[L2TP]: PPP over L2TP driver core")
+Reported-by: Haowei Yan <g1042620637@gmail.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 2 +-
+ net/l2tp/l2tp_core.c | 19 +++++++++++++------
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 90a8b8b26a20..69bbbe8bbf34 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -315,7 +315,7 @@ struct bpf_local_storage;
+ * @sk_tskey: counter to disambiguate concurrent tstamp requests
+ * @sk_zckey: counter to order MSG_ZEROCOPY notifications
+ * @sk_socket: Identd and reporting IO signals
+- * @sk_user_data: RPC layer private data
++ * @sk_user_data: RPC layer private data. Write-protected by @sk_callback_lock.
+ * @sk_frag: cached page frag
+ * @sk_peek_off: current peek_offset value
+ * @sk_send_head: front of stuff to transmit
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index dc8987ed08ad..e89852bc5309 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1150,8 +1150,10 @@ static void l2tp_tunnel_destruct(struct sock *sk)
+ }
+
+ /* Remove hooks into tunnel socket */
++ write_lock_bh(&sk->sk_callback_lock);
+ sk->sk_destruct = tunnel->old_sk_destruct;
+ sk->sk_user_data = NULL;
++ write_unlock_bh(&sk->sk_callback_lock);
+
+ /* Call the original destructor */
+ if (sk->sk_destruct)
+@@ -1471,16 +1473,18 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ sock = sockfd_lookup(tunnel->fd, &ret);
+ if (!sock)
+ goto err;
+-
+- ret = l2tp_validate_socket(sock->sk, net, tunnel->encap);
+- if (ret < 0)
+- goto err_sock;
+ }
+
++ sk = sock->sk;
++ write_lock(&sk->sk_callback_lock);
++
++ ret = l2tp_validate_socket(sk, net, tunnel->encap);
++ if (ret < 0)
++ goto err_sock;
++
+ tunnel->l2tp_net = net;
+ pn = l2tp_pernet(net);
+
+- sk = sock->sk;
+ sock_hold(sk);
+ tunnel->sock = sk;
+
+@@ -1506,7 +1510,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+
+ setup_udp_tunnel_sock(net, sock, &udp_cfg);
+ } else {
+- sk->sk_user_data = tunnel;
++ rcu_assign_sk_user_data(sk, tunnel);
+ }
+
+ tunnel->old_sk_destruct = sk->sk_destruct;
+@@ -1520,6 +1524,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ if (tunnel->fd >= 0)
+ sockfd_put(sock);
+
++ write_unlock(&sk->sk_callback_lock);
+ return 0;
+
+ err_sock:
+@@ -1527,6 +1532,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ sock_release(sock);
+ else
+ sockfd_put(sock);
++
++ write_unlock(&sk->sk_callback_lock);
+ err:
+ return ret;
+ }
+--
+2.35.1
+
--- /dev/null
+From 81910e59f8971e9939e76923de503aef9e126c27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Apr 2021 15:04:24 +0000
+Subject: net: fix a concurrency bug in l2tp_tunnel_register()
+
+From: Gong, Sishuai <sishuai@purdue.edu>
+
+[ Upstream commit 69e16d01d1de4f1249869de342915f608feb55d5 ]
+
+l2tp_tunnel_register() registers a tunnel without fully
+initializing its attribute. This can allow another kernel thread
+running l2tp_xmit_core() to access the uninitialized data and
+then cause a kernel NULL pointer dereference error, as shown below.
+
+Thread 1 Thread 2
+//l2tp_tunnel_register()
+list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+ //pppol2tp_connect()
+ tunnel = l2tp_tunnel_get(sock_net(sk), info.tunnel_id);
+ // Fetch the new tunnel
+ ...
+ //l2tp_xmit_core()
+ struct sock *sk = tunnel->sock;
+ ...
+ bh_lock_sock(sk);
+ //Null pointer error happens
+tunnel->sock = sk;
+
+Fix this bug by initializing tunnel->sock before adding the
+tunnel into l2tp_tunnel_list.
+
+Reviewed-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: Sishuai Gong <sishuai@purdue.edu>
+Reported-by: Sishuai Gong <sishuai@purdue.edu>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: b68777d54fac ("l2tp: Serialize access to sk_user_data with sk_callback_lock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_core.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 561b6d67ab8b..dc8987ed08ad 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1480,11 +1480,15 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ tunnel->l2tp_net = net;
+ pn = l2tp_pernet(net);
+
++ sk = sock->sk;
++ sock_hold(sk);
++ tunnel->sock = sk;
++
+ spin_lock_bh(&pn->l2tp_tunnel_list_lock);
+ list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) {
+ if (tunnel_walk->tunnel_id == tunnel->tunnel_id) {
+ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+-
++ sock_put(sk);
+ ret = -EEXIST;
+ goto err_sock;
+ }
+@@ -1492,10 +1496,6 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
+ list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
+ spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
+
+- sk = sock->sk;
+- sock_hold(sk);
+- tunnel->sock = sk;
+-
+ if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
+ struct udp_tunnel_sock_cfg udp_cfg = {
+ .sk_user_data = tunnel,
+--
+2.35.1
+
--- /dev/null
+From 8b2733594317cb6a52021f0942d878cc020d4234 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 22:24:00 +0800
+Subject: net: use struct_group to copy ip/ipv6 header addresses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit 58e0be1ef6118c5352b56a4d06e974c5599993a5 ]
+
+kernel test robot reported warnings when build bonding module with
+make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/net/bonding/:
+
+ from ../drivers/net/bonding/bond_main.c:35:
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘iph_to_flow_copy_v4addrs’ at ../include/net/ip.h:566:2,
+ inlined from ‘bond_flow_ip’ at ../drivers/net/bonding/bond_main.c:3984:3:
+../include/linux/fortify-string.h:413:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of f
+ield (2nd parameter); maybe use struct_group()? [-Wattribute-warning]
+ 413 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In function ‘fortify_memcpy_chk’,
+ inlined from ‘iph_to_flow_copy_v6addrs’ at ../include/net/ipv6.h:900:2,
+ inlined from ‘bond_flow_ip’ at ../drivers/net/bonding/bond_main.c:3994:3:
+../include/linux/fortify-string.h:413:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of f
+ield (2nd parameter); maybe use struct_group()? [-Wattribute-warning]
+ 413 | __read_overflow2_field(q_size_field, size);
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is because we try to copy the whole ip/ip6 address to the flow_key,
+while we only point the to ip/ip6 saddr. Note that since these are UAPI
+headers, __struct_group() is used to avoid the compiler warnings.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: c3f8324188fa ("net: Add full IPv6 addresses to flow_keys")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://lore.kernel.org/r/20221115142400.1204786-1-liuhangbin@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 2 +-
+ include/net/ipv6.h | 2 +-
+ include/uapi/linux/ip.h | 6 ++++--
+ include/uapi/linux/ipv6.h | 6 ++++--
+ 4 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index c5822d7824cd..4b775af57268 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -545,7 +545,7 @@ static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
+ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
+ offsetof(typeof(flow->addrs), v4addrs.src) +
+ sizeof(flow->addrs.v4addrs.src));
+- memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
++ memcpy(&flow->addrs.v4addrs, &iph->addrs, sizeof(flow->addrs.v4addrs));
+ flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ }
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 60601896d474..89ce8a50f236 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -842,7 +842,7 @@ static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,
+ BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) !=
+ offsetof(typeof(flow->addrs), v6addrs.src) +
+ sizeof(flow->addrs.v6addrs.src));
+- memcpy(&flow->addrs.v6addrs, &iph->saddr, sizeof(flow->addrs.v6addrs));
++ memcpy(&flow->addrs.v6addrs, &iph->addrs, sizeof(flow->addrs.v6addrs));
+ flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ }
+
+diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
+index e42d13b55cf3..d2f143393780 100644
+--- a/include/uapi/linux/ip.h
++++ b/include/uapi/linux/ip.h
+@@ -100,8 +100,10 @@ struct iphdr {
+ __u8 ttl;
+ __u8 protocol;
+ __sum16 check;
+- __be32 saddr;
+- __be32 daddr;
++ __struct_group(/* no tag */, addrs, /* no attrs */,
++ __be32 saddr;
++ __be32 daddr;
++ );
+ /*The options start here. */
+ };
+
+diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
+index 13e8751bf24a..766ab5c8ee65 100644
+--- a/include/uapi/linux/ipv6.h
++++ b/include/uapi/linux/ipv6.h
+@@ -130,8 +130,10 @@ struct ipv6hdr {
+ __u8 nexthdr;
+ __u8 hop_limit;
+
+- struct in6_addr saddr;
+- struct in6_addr daddr;
++ __struct_group(/* no tag */, addrs, /* no attrs */,
++ struct in6_addr saddr;
++ struct in6_addr daddr;
++ );
+ };
+
+
+--
+2.35.1
+
--- /dev/null
+From e11b9bdd91df8b0fe3d85beab0bcb8df22d92252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Oct 2022 12:30:13 -0400
+Subject: ring-buffer: Include dropped pages in counting dirty patches
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 31029a8b2c7e656a0289194ef16415050ae4c4ac ]
+
+The function ring_buffer_nr_dirty_pages() was created to find out how many
+pages are filled in the ring buffer. There's two running counters. One is
+incremented whenever a new page is touched (pages_touched) and the other
+is whenever a page is read (pages_read). The dirty count is the number
+touched minus the number read. This is used to determine if a blocked task
+should be woken up if the percentage of the ring buffer it is waiting for
+is hit.
+
+The problem is that it does not take into account dropped pages (when the
+new writes overwrite pages that were not read). And then the dirty pages
+will always be greater than the percentage.
+
+This makes the "buffer_percent" file inaccurate, as the number of dirty
+pages end up always being larger than the percentage, event when it's not
+and this causes user space to be woken up more than it wants to be.
+
+Add a new counter to keep track of lost pages, and include that in the
+accounting of dirty pages so that it is actually accurate.
+
+Link: https://lkml.kernel.org/r/20221021123013.55fb6055@gandalf.local.home
+
+Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/ring_buffer.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 9a1f82cafad4..49ebb8c66268 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -517,6 +517,7 @@ struct ring_buffer_per_cpu {
+ local_t committing;
+ local_t commits;
+ local_t pages_touched;
++ local_t pages_lost;
+ local_t pages_read;
+ long last_pages_touch;
+ size_t shortest_full;
+@@ -771,10 +772,18 @@ size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
+ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
+ {
+ size_t read;
++ size_t lost;
+ size_t cnt;
+
+ read = local_read(&buffer->buffers[cpu]->pages_read);
++ lost = local_read(&buffer->buffers[cpu]->pages_lost);
+ cnt = local_read(&buffer->buffers[cpu]->pages_touched);
++
++ if (WARN_ON_ONCE(cnt < lost))
++ return 0;
++
++ cnt -= lost;
++
+ /* The reader can read an empty page, but not more than that */
+ if (cnt < read) {
+ WARN_ON_ONCE(read > cnt + 1);
+@@ -1897,6 +1906,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ */
+ local_add(page_entries, &cpu_buffer->overrun);
+ local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++ local_inc(&cpu_buffer->pages_lost);
+ }
+
+ /*
+@@ -2387,6 +2397,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
+ */
+ local_add(entries, &cpu_buffer->overrun);
+ local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++ local_inc(&cpu_buffer->pages_lost);
+
+ /*
+ * The entries will be zeroed out when we move the
+@@ -4981,6 +4992,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+ local_set(&cpu_buffer->committing, 0);
+ local_set(&cpu_buffer->commits, 0);
+ local_set(&cpu_buffer->pages_touched, 0);
++ local_set(&cpu_buffer->pages_lost, 0);
+ local_set(&cpu_buffer->pages_read, 0);
+ cpu_buffer->last_pages_touch = 0;
+ cpu_buffer->shortest_full = 0;
+--
+2.35.1
+
--- /dev/null
+From c90d2940b92e49636babe1f48200bf6096c21de3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Nov 2022 08:44:21 +0000
+Subject: scsi: scsi_debug: Fix possible UAF in sdebug_add_host_helper()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit e208a1d795a08d1ac0398c79ad9c58106531bcc5 ]
+
+If device_register() fails in sdebug_add_host_helper(), it will goto clean
+and sdbg_host will be freed, but sdbg_host->host_list will not be removed
+from sdebug_host_list, then list traversal may cause UAF. Fix it.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Yuan Can <yuancan@huawei.com>
+Link: https://lore.kernel.org/r/20221117084421.58918-1-yuancan@huawei.com
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 5eb959b5f701..261b915835b4 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -7079,8 +7079,12 @@ static int sdebug_add_host_helper(int per_host_idx)
+ dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts);
+
+ error = device_register(&sdbg_host->dev);
+- if (error)
++ if (error) {
++ spin_lock(&sdebug_host_list_lock);
++ list_del(&sdbg_host->host_list);
++ spin_unlock(&sdebug_host_list_lock);
+ goto clean;
++ }
+
+ ++sdebug_num_hosts;
+ return 0;
+--
+2.35.1
+
--- /dev/null
+From 9bf9344de09326c564568057ac8ec4b2c371346c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Nov 2022 09:50:42 +0800
+Subject: scsi: target: tcm_loop: Fix possible name leak in
+ tcm_loop_setup_hba_bus()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit bc68e428d4963af0201e92159629ab96948f0893 ]
+
+If device_register() fails in tcm_loop_setup_hba_bus(), the name allocated
+by dev_set_name() need be freed. As comment of device_register() says, it
+should use put_device() to give up the reference in the error path. So fix
+this by calling put_device(), then the name can be freed in kobject_cleanup().
+The 'tl_hba' will be freed in tcm_loop_release_adapter(), so it don't need
+goto error label in this case.
+
+Fixes: 3703b2c5d041 ("[SCSI] tcm_loop: Add multi-fabric Linux/SCSI LLD fabric module")
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20221115015042.3652261-1-yangyingliang@huawei.com
+Reviewed-by: Mike Christie <michael.chritie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/target/loopback/tcm_loop.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
+index 16d5a4e117a2..5ae5d94c5b93 100644
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -394,6 +394,7 @@ static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host
+ ret = device_register(&tl_hba->dev);
+ if (ret) {
+ pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
++ put_device(&tl_hba->dev);
+ return -ENODEV;
+ }
+
+@@ -1072,7 +1073,7 @@ static struct se_wwn *tcm_loop_make_scsi_hba(
+ */
+ ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
+ if (ret)
+- goto out;
++ return ERR_PTR(ret);
+
+ sh = tl_hba->sh;
+ tcm_loop_hba_no_cnt++;
+--
+2.35.1
+
perf-x86-intel-pt-fix-sampling-using-single-range-output.patch
nvme-restrict-management-ioctls-to-admin.patch
nvme-ensure-subsystem-reset-is-single-threaded.patch
+net-fix-a-concurrency-bug-in-l2tp_tunnel_register.patch
+l2tp-serialize-access-to-sk_user_data-with-sk_callba.patch
+ring-buffer-include-dropped-pages-in-counting-dirty-.patch
+usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch
+stddef-introduce-struct_group-helper-macro.patch
+net-use-struct_group-to-copy-ip-ipv6-header-addresse.patch
+scsi-target-tcm_loop-fix-possible-name-leak-in-tcm_l.patch
+scsi-scsi_debug-fix-possible-uaf-in-sdebug_add_host_.patch
+kprobes-skip-clearing-aggrprobe-s-post_handler-in-kp.patch
+input-i8042-fix-leaking-of-platform-device-on-module.patch
--- /dev/null
+From 3ce381dd279808d9bd2fac5f4e57f9ccaa5b665b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 May 2021 20:01:15 -0700
+Subject: stddef: Introduce struct_group() helper macro
+
+From: Kees Cook <keescook@chromium.org>
+
+[ Upstream commit 50d7bd38c3aafc4749e05e8d7fcb616979143602 ]
+
+Kernel code has a regular need to describe groups of members within a
+structure usually when they need to be copied or initialized separately
+from the rest of the surrounding structure. The generally accepted design
+pattern in C is to use a named sub-struct:
+
+ struct foo {
+ int one;
+ struct {
+ int two;
+ int three, four;
+ } thing;
+ int five;
+ };
+
+This would allow for traditional references and sizing:
+
+ memcpy(&dst.thing, &src.thing, sizeof(dst.thing));
+
+However, doing this would mean that referencing struct members enclosed
+by such named structs would always require including the sub-struct name
+in identifiers:
+
+ do_something(dst.thing.three);
+
+This has tended to be quite inflexible, especially when such groupings
+need to be added to established code which causes huge naming churn.
+Three workarounds exist in the kernel for this problem, and each have
+other negative properties.
+
+To avoid the naming churn, there is a design pattern of adding macro
+aliases for the named struct:
+
+ #define f_three thing.three
+
+This ends up polluting the global namespace, and makes it difficult to
+search for identifiers.
+
+Another common work-around in kernel code avoids the pollution by avoiding
+the named struct entirely, instead identifying the group's boundaries using
+either a pair of empty anonymous structs of a pair of zero-element arrays:
+
+ struct foo {
+ int one;
+ struct { } start;
+ int two;
+ int three, four;
+ struct { } finish;
+ int five;
+ };
+
+ struct foo {
+ int one;
+ int start[0];
+ int two;
+ int three, four;
+ int finish[0];
+ int five;
+ };
+
+This allows code to avoid needing to use a sub-struct named for member
+references within the surrounding structure, but loses the benefits of
+being able to actually use such a struct, making it rather fragile. Using
+these requires open-coded calculation of sizes and offsets. The efforts
+made to avoid common mistakes include lots of comments, or adding various
+BUILD_BUG_ON()s. Such code is left with no way for the compiler to reason
+about the boundaries (e.g. the "start" object looks like it's 0 bytes
+in length), making bounds checking depend on open-coded calculations:
+
+ if (length > offsetof(struct foo, finish) -
+ offsetof(struct foo, start))
+ return -EINVAL;
+ memcpy(&dst.start, &src.start, offsetof(struct foo, finish) -
+ offsetof(struct foo, start));
+
+However, the vast majority of places in the kernel that operate on
+groups of members do so without any identification of the grouping,
+relying either on comments or implicit knowledge of the struct contents,
+which is even harder for the compiler to reason about, and results in
+even more fragile manual sizing, usually depending on member locations
+outside of the region (e.g. to copy "two" and "three", use the start of
+"four" to find the size):
+
+ BUILD_BUG_ON((offsetof(struct foo, four) <
+ offsetof(struct foo, two)) ||
+ (offsetof(struct foo, four) <
+ offsetof(struct foo, three));
+ if (length > offsetof(struct foo, four) -
+ offsetof(struct foo, two))
+ return -EINVAL;
+ memcpy(&dst.two, &src.two, length);
+
+In order to have a regular programmatic way to describe a struct
+region that can be used for references and sizing, can be examined for
+bounds checking, avoids forcing the use of intermediate identifiers,
+and avoids polluting the global namespace, introduce the struct_group()
+macro. This macro wraps the member declarations to create an anonymous
+union of an anonymous struct (no intermediate name) and a named struct
+(for references and sizing):
+
+ struct foo {
+ int one;
+ struct_group(thing,
+ int two;
+ int three, four;
+ );
+ int five;
+ };
+
+ if (length > sizeof(src.thing))
+ return -EINVAL;
+ memcpy(&dst.thing, &src.thing, length);
+ do_something(dst.three);
+
+There are some rare cases where the resulting struct_group() needs
+attributes added, so struct_group_attr() is also introduced to allow
+for specifying struct attributes (e.g. __align(x) or __packed).
+Additionally, there are places where such declarations would like to
+have the struct be tagged, so struct_group_tagged() is added.
+
+Given there is a need for a handful of UAPI uses too, the underlying
+__struct_group() macro has been defined in UAPI so it can be used there
+too.
+
+To avoid confusing scripts/kernel-doc, hide the macro from its struct
+parsing.
+
+Co-developed-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Keith Packard <keithp@keithp.com>
+Acked-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Link: https://lore.kernel.org/lkml/20210728023217.GC35706@embeddedor
+Enhanced-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Link: https://lore.kernel.org/lkml/41183a98-bdb9-4ad6-7eab-5a7292a6df84@rasmusvillemoes.dk
+Enhanced-by: Dan Williams <dan.j.williams@intel.com>
+Link: https://lore.kernel.org/lkml/1d9a2e6df2a9a35b2cdd50a9a68cac5991e7e5f0.camel@intel.com
+Enhanced-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://lore.kernel.org/lkml/YQKa76A6XuFqgM03@phenom.ffwll.local
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Stable-dep-of: 58e0be1ef611 ("net: use struct_group to copy ip/ipv6 header addresses")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/stddef.h | 48 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/stddef.h | 21 ++++++++++++++++
+ scripts/kernel-doc | 7 ++++++
+ 3 files changed, 76 insertions(+)
+
+diff --git a/include/linux/stddef.h b/include/linux/stddef.h
+index 998a4ba28eba..938216f8ab7e 100644
+--- a/include/linux/stddef.h
++++ b/include/linux/stddef.h
+@@ -36,4 +36,52 @@ enum {
+ #define offsetofend(TYPE, MEMBER) \
+ (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
+
++/**
++ * struct_group() - Wrap a set of declarations in a mirrored struct
++ *
++ * @NAME: The identifier name of the mirrored sub-struct
++ * @MEMBERS: The member declarations for the mirrored structs
++ *
++ * Used to create an anonymous union of two structs with identical
++ * layout and size: one anonymous and one named. The former can be
++ * used normally without sub-struct naming, and the latter can be
++ * used to reason about the start, end, and size of the group of
++ * struct members.
++ */
++#define struct_group(NAME, MEMBERS...) \
++ __struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS)
++
++/**
++ * struct_group_attr() - Create a struct_group() with trailing attributes
++ *
++ * @NAME: The identifier name of the mirrored sub-struct
++ * @ATTRS: Any struct attributes to apply
++ * @MEMBERS: The member declarations for the mirrored structs
++ *
++ * Used to create an anonymous union of two structs with identical
++ * layout and size: one anonymous and one named. The former can be
++ * used normally without sub-struct naming, and the latter can be
++ * used to reason about the start, end, and size of the group of
++ * struct members. Includes structure attributes argument.
++ */
++#define struct_group_attr(NAME, ATTRS, MEMBERS...) \
++ __struct_group(/* no tag */, NAME, ATTRS, MEMBERS)
++
++/**
++ * struct_group_tagged() - Create a struct_group with a reusable tag
++ *
++ * @TAG: The tag name for the named sub-struct
++ * @NAME: The identifier name of the mirrored sub-struct
++ * @MEMBERS: The member declarations for the mirrored structs
++ *
++ * Used to create an anonymous union of two structs with identical
++ * layout and size: one anonymous and one named. The former can be
++ * used normally without sub-struct naming, and the latter can be
++ * used to reason about the start, end, and size of the group of
++ * struct members. Includes struct tag argument for the named copy,
++ * so the specified layout can be reused later.
++ */
++#define struct_group_tagged(TAG, NAME, MEMBERS...) \
++ __struct_group(TAG, NAME, /* no attrs */, MEMBERS)
++
+ #endif
+diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
+index ee8220f8dcf5..610204f7c275 100644
+--- a/include/uapi/linux/stddef.h
++++ b/include/uapi/linux/stddef.h
+@@ -4,3 +4,24 @@
+ #ifndef __always_inline
+ #define __always_inline inline
+ #endif
++
++/**
++ * __struct_group() - Create a mirrored named and anonyomous struct
++ *
++ * @TAG: The tag name for the named sub-struct (usually empty)
++ * @NAME: The identifier name of the mirrored sub-struct
++ * @ATTRS: Any struct attributes (usually empty)
++ * @MEMBERS: The member declarations for the mirrored structs
++ *
++ * Used to create an anonymous union of two structs with identical layout
++ * and size: one anonymous and one named. The former's members can be used
++ * normally without sub-struct naming, and the latter can be used to
++ * reason about the start, end, and size of the group of struct members.
++ * The named struct can also be explicitly tagged for layer reuse, as well
++ * as both having struct attributes appended.
++ */
++#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
++ union { \
++ struct { MEMBERS } ATTRS; \
++ struct TAG { MEMBERS } ATTRS NAME; \
++ }
+diff --git a/scripts/kernel-doc b/scripts/kernel-doc
+index 6325bec3f66f..19af6dd160e6 100755
+--- a/scripts/kernel-doc
++++ b/scripts/kernel-doc
+@@ -1215,6 +1215,13 @@ sub dump_struct($$) {
+ $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
+ $members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
+ $members =~ s/\s*____cacheline_aligned/ /gos;
++ # unwrap struct_group():
++ # - first eat non-declaration parameters and rewrite for final match
++ # - then remove macro, outer parens, and trailing semicolon
++ $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos;
++ $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos;
++ $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos;
++ $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos;
+
+ # replace DECLARE_BITMAP
+ $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
+--
+2.35.1
+
--- /dev/null
+From 42d9e50404659f76a1b583b06c503b676d7531db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Jul 2022 22:47:51 +0200
+Subject: usbnet: smsc95xx: Fix deadlock on runtime resume
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 7b960c967f2aa01ab8f45c5a0bd78e754cffdeee ]
+
+Commit 05b35e7eb9a1 ("smsc95xx: add phylib support") amended
+smsc95xx_resume() to call phy_init_hw(). That function waits for the
+device to runtime resume even though it is placed in the runtime resume
+path, causing a deadlock.
+
+The problem is that phy_init_hw() calls down to smsc95xx_mdiobus_read(),
+which never uses the _nopm variant of usbnet_read_cmd().
+
+Commit b4df480f68ae ("usbnet: smsc95xx: add reset_resume function with
+reset operation") causes a similar deadlock on resume if the device was
+already runtime suspended when entering system sleep:
+
+That's because the commit introduced smsc95xx_reset_resume(), which
+calls down to smsc95xx_reset(), which neglects to use _nopm accessors.
+
+Fix by auto-detecting whether a device access is performed by the
+suspend/resume task_struct and use the _nopm variant if so. This works
+because the PM core guarantees that suspend/resume callbacks are run in
+task context.
+
+Stacktrace for posterity:
+
+ INFO: task kworker/2:1:49 blocked for more than 122 seconds.
+ Workqueue: usb_hub_wq hub_event
+ schedule
+ rpm_resume
+ __pm_runtime_resume
+ usb_autopm_get_interface
+ usbnet_read_cmd
+ __smsc95xx_read_reg
+ __smsc95xx_phy_wait_not_busy
+ __smsc95xx_mdio_read
+ smsc95xx_mdiobus_read
+ __mdiobus_read
+ mdiobus_read
+ smsc_phy_reset
+ phy_init_hw
+ smsc95xx_resume
+ usb_resume_interface
+ usb_resume_both
+ usb_runtime_resume
+ __rpm_callback
+ rpm_callback
+ rpm_resume
+ __pm_runtime_resume
+ usb_autoresume_device
+ hub_event
+ process_one_work
+
+Fixes: b4df480f68ae ("usbnet: smsc95xx: add reset_resume function with reset operation")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.16+
+Cc: Andre Edich <andre.edich@microchip.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/smsc95xx.c | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index 65d42f5d42a3..e1cd4c2de2d3 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -61,6 +61,7 @@ struct smsc95xx_priv {
+ u8 suspend_flags;
+ struct mii_bus *mdiobus;
+ struct phy_device *phydev;
++ struct task_struct *pm_task;
+ };
+
+ static bool turbo_mode = true;
+@@ -70,13 +71,14 @@ MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+ static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
+ u32 *data, int in_pm)
+ {
++ struct smsc95xx_priv *pdata = dev->driver_priv;
+ u32 buf;
+ int ret;
+ int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
+
+ BUG_ON(!dev);
+
+- if (!in_pm)
++ if (current != pdata->pm_task)
+ fn = usbnet_read_cmd;
+ else
+ fn = usbnet_read_cmd_nopm;
+@@ -100,13 +102,14 @@ static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
+ static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index,
+ u32 data, int in_pm)
+ {
++ struct smsc95xx_priv *pdata = dev->driver_priv;
+ u32 buf;
+ int ret;
+ int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
+
+ BUG_ON(!dev);
+
+- if (!in_pm)
++ if (current != pdata->pm_task)
+ fn = usbnet_write_cmd;
+ else
+ fn = usbnet_write_cmd_nopm;
+@@ -1468,9 +1471,12 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
+ u32 val, link_up;
+ int ret;
+
++ pdata->pm_task = current;
++
+ ret = usbnet_suspend(intf, message);
+ if (ret < 0) {
+ netdev_warn(dev->net, "usbnet_suspend error\n");
++ pdata->pm_task = NULL;
+ return ret;
+ }
+
+@@ -1717,6 +1723,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
+ if (ret && PMSG_IS_AUTO(message))
+ usbnet_resume(intf);
+
++ pdata->pm_task = NULL;
+ return ret;
+ }
+
+@@ -1737,29 +1744,31 @@ static int smsc95xx_resume(struct usb_interface *intf)
+ /* do this first to ensure it's cleared even in error case */
+ pdata->suspend_flags = 0;
+
++ pdata->pm_task = current;
++
+ if (suspend_flags & SUSPEND_ALLMODES) {
+ /* clear wake-up sources */
+ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
+ if (ret < 0)
+- return ret;
++ goto done;
+
+ val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
+
+ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
+ if (ret < 0)
+- return ret;
++ goto done;
+
+ /* clear wake-up status */
+ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
+ if (ret < 0)
+- return ret;
++ goto done;
+
+ val &= ~PM_CTL_WOL_EN_;
+ val |= PM_CTL_WUPS_;
+
+ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
+ if (ret < 0)
+- return ret;
++ goto done;
+ }
+
+ ret = usbnet_resume(intf);
+@@ -1767,15 +1776,21 @@ static int smsc95xx_resume(struct usb_interface *intf)
+ netdev_warn(dev->net, "usbnet_resume error\n");
+
+ phy_init_hw(pdata->phydev);
++
++done:
++ pdata->pm_task = NULL;
+ return ret;
+ }
+
+ static int smsc95xx_reset_resume(struct usb_interface *intf)
+ {
+ struct usbnet *dev = usb_get_intfdata(intf);
++ struct smsc95xx_priv *pdata = dev->driver_priv;
+ int ret;
+
++ pdata->pm_task = current;
+ ret = smsc95xx_reset(dev);
++ pdata->pm_task = NULL;
+ if (ret < 0)
+ return ret;
+
+--
+2.35.1
+