--- /dev/null
+From 08c27f3322fec11950b8f1384aa0f3b11d028528 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Mon, 5 Apr 2021 19:16:50 +0900
+Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 08c27f3322fec11950b8f1384aa0f3b11d028528 upstream.
+
+KMSAN found uninitialized value at batadv_tt_prepare_tvlv_local_data()
+[1], for commit ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16
+in TT code") inserted 'reserved' field into "struct batadv_tvlv_tt_data"
+and commit 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN
+specific") moved that field to "struct batadv_tvlv_tt_vlan_data" but left
+that field uninitialized.
+
+[1] https://syzkaller.appspot.com/bug?id=07f3e6dba96f0eb3cabab986adcd8a58b9bdbe9d
+
+Reported-by: syzbot <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
+Tested-by: syzbot <syzbot+50ee810676e6a089487b@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Fixes: ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16 in TT code")
+Fixes: 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN specific")
+Acked-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/translation-table.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -891,6 +891,7 @@ batadv_tt_prepare_tvlv_global_data(struc
+ hlist_for_each_entry(vlan, &orig_node->vlan_list, list) {
+ tt_vlan->vid = htons(vlan->vid);
+ tt_vlan->crc = htonl(vlan->tt.crc);
++ tt_vlan->reserved = 0;
+
+ tt_vlan++;
+ }
+@@ -974,6 +975,7 @@ batadv_tt_prepare_tvlv_local_data(struct
+
+ tt_vlan->vid = htons(vlan->vid);
+ tt_vlan->crc = htonl(vlan->tt.crc);
++ tt_vlan->reserved = 0;
+
+ tt_vlan++;
+ }
--- /dev/null
+From 12aa8a9467b354ef893ce0fc5719a4de4949a9fb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@redhat.com>
+Date: Fri, 26 Mar 2021 11:03:13 +0100
+Subject: bpf: Enforce that struct_ops programs be GPL-only
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+commit 12aa8a9467b354ef893ce0fc5719a4de4949a9fb upstream.
+
+With the introduction of the struct_ops program type, it became possible to
+implement kernel functionality in BPF, making it viable to use BPF in place
+of a regular kernel module for these particular operations.
+
+Thus far, the only user of this mechanism is for implementing TCP
+congestion control algorithms. These are clearly marked as GPL-only when
+implemented as modules (as seen by the use of EXPORT_SYMBOL_GPL for
+tcp_register_congestion_control()), so it seems like an oversight that this
+was not carried over to BPF implementations. Since this is the only user
+of the struct_ops mechanism, just enforcing GPL-only for the struct_ops
+program type seems like the simplest way to fix this.
+
+Fixes: 0baf26b0fcd7 ("bpf: tcp: Support tcp_congestion_ops in bpf")
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Link: https://lore.kernel.org/bpf/20210326100314.121853-1-toke@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/verifier.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -11429,6 +11429,11 @@ static int check_struct_ops_btf_id(struc
+ u32 btf_id, member_idx;
+ const char *mname;
+
++ if (!prog->gpl_compatible) {
++ verbose(env, "struct ops programs must have a GPL compatible license\n");
++ return -EINVAL;
++ }
++
+ btf_id = prog->aux->attach_btf_id;
+ st_ops = bpf_struct_ops_find(btf_id);
+ if (!st_ops) {
--- /dev/null
+From 25fc94b2f02d832fa8e29419699dcc20b0b05c6a Mon Sep 17 00:00:00 2001
+From: Lorenz Bauer <lmb@cloudflare.com>
+Date: Fri, 26 Mar 2021 16:05:00 +0000
+Subject: bpf: link: Refuse non-O_RDWR flags in BPF_OBJ_GET
+
+From: Lorenz Bauer <lmb@cloudflare.com>
+
+commit 25fc94b2f02d832fa8e29419699dcc20b0b05c6a upstream.
+
+Invoking BPF_OBJ_GET on a pinned bpf_link checks the path access
+permissions based on file_flags, but the returned fd ignores flags.
+This means that any user can acquire a "read-write" fd for a pinned
+link with mode 0664 by invoking BPF_OBJ_GET with BPF_F_RDONLY in
+file_flags. The fd can be used to invoke BPF_LINK_DETACH, etc.
+
+Fix this by refusing non-O_RDWR flags in BPF_OBJ_GET. This works
+because OBJ_GET by default returns a read write mapping and libbpf
+doesn't expose a way to override this behaviour for programs
+and links.
+
+Fixes: 70ed506c3bbc ("bpf: Introduce pinnable bpf_link abstraction")
+Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/20210326160501.46234-1-lmb@cloudflare.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/bpf/inode.c
++++ b/kernel/bpf/inode.c
+@@ -546,7 +546,7 @@ int bpf_obj_get_user(const char __user *
+ else if (type == BPF_TYPE_MAP)
+ ret = bpf_map_new_fd(raw, f_flags);
+ else if (type == BPF_TYPE_LINK)
+- ret = bpf_link_new_fd(raw);
++ ret = (f_flags != O_RDWR) ? -EINVAL : bpf_link_new_fd(raw);
+ else
+ return -ENOENT;
+
--- /dev/null
+From 06ab134ce8ecfa5a69e850f88f81c8a4c3fa91df Mon Sep 17 00:00:00 2001
+From: Dave Marchevsky <davemarchevsky@fb.com>
+Date: Wed, 31 Mar 2021 17:07:47 -0700
+Subject: bpf: Refcount task stack in bpf_get_task_stack
+
+From: Dave Marchevsky <davemarchevsky@fb.com>
+
+commit 06ab134ce8ecfa5a69e850f88f81c8a4c3fa91df upstream.
+
+On x86 the struct pt_regs * grabbed by task_pt_regs() points to an
+offset of task->stack. The pt_regs are later dereferenced in
+__bpf_get_stack (e.g. by user_mode() check). This can cause a fault if
+the task in question exits while bpf_get_task_stack is executing, as
+warned by task_stack_page's comment:
+
+* When accessing the stack of a non-current task that might exit, use
+* try_get_task_stack() instead. task_stack_page will return a pointer
+* that could get freed out from under you.
+
+Taking the comment's advice and using try_get_task_stack() and
+put_task_stack() to hold task->stack refcount, or bail early if it's
+already 0. Incrementing stack_refcount will ensure the task's stack
+sticks around while we're using its data.
+
+I noticed this bug while testing a bpf task iter similar to
+bpf_iter_task_stack in selftests, except mine grabbed user stack, and
+getting intermittent crashes, which resulted in dumps like:
+
+ BUG: unable to handle page fault for address: 0000000000003fe0
+ \#PF: supervisor read access in kernel mode
+ \#PF: error_code(0x0000) - not-present page
+ RIP: 0010:__bpf_get_stack+0xd0/0x230
+ <snip...>
+ Call Trace:
+ bpf_prog_0a2be35c092cb190_get_task_stacks+0x5d/0x3ec
+ bpf_iter_run_prog+0x24/0x81
+ __task_seq_show+0x58/0x80
+ bpf_seq_read+0xf7/0x3d0
+ vfs_read+0x91/0x140
+ ksys_read+0x59/0xd0
+ do_syscall_64+0x48/0x120
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fixes: fa28dcb82a38 ("bpf: Introduce helper bpf_get_task_stack()")
+Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Song Liu <songliubraving@fb.com>
+Link: https://lore.kernel.org/bpf/20210401000747.3648767-1-davemarchevsky@fb.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/stackmap.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/kernel/bpf/stackmap.c
++++ b/kernel/bpf/stackmap.c
+@@ -662,9 +662,17 @@ const struct bpf_func_proto bpf_get_stac
+ BPF_CALL_4(bpf_get_task_stack, struct task_struct *, task, void *, buf,
+ u32, size, u64, flags)
+ {
+- struct pt_regs *regs = task_pt_regs(task);
++ struct pt_regs *regs;
++ long res;
+
+- return __bpf_get_stack(regs, task, NULL, buf, size, flags);
++ if (!try_get_task_stack(task))
++ return -EFAULT;
++
++ regs = task_pt_regs(task);
++ res = __bpf_get_stack(regs, task, NULL, buf, size, flags);
++ put_task_stack(task);
++
++ return res;
+ }
+
+ BTF_ID_LIST_SINGLE(bpf_get_task_stack_btf_ids, struct, task_struct)
--- /dev/null
+From 144748eb0c445091466c9b741ebd0bfcc5914f3d Mon Sep 17 00:00:00 2001
+From: John Fastabend <john.fastabend@gmail.com>
+Date: Thu, 1 Apr 2021 15:00:40 -0700
+Subject: bpf, sockmap: Fix incorrect fwd_alloc accounting
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+commit 144748eb0c445091466c9b741ebd0bfcc5914f3d upstream.
+
+Incorrect accounting fwd_alloc can result in a warning when the socket
+is torn down,
+
+ [18455.319240] WARNING: CPU: 0 PID: 24075 at net/core/stream.c:208 sk_stream_kill_queues+0x21f/0x230
+ [...]
+ [18455.319543] Call Trace:
+ [18455.319556] inet_csk_destroy_sock+0xba/0x1f0
+ [18455.319577] tcp_rcv_state_process+0x1b4e/0x2380
+ [18455.319593] ? lock_downgrade+0x3a0/0x3a0
+ [18455.319617] ? tcp_finish_connect+0x1e0/0x1e0
+ [18455.319631] ? sk_reset_timer+0x15/0x70
+ [18455.319646] ? tcp_schedule_loss_probe+0x1b2/0x240
+ [18455.319663] ? lock_release+0xb2/0x3f0
+ [18455.319676] ? __release_sock+0x8a/0x1b0
+ [18455.319690] ? lock_downgrade+0x3a0/0x3a0
+ [18455.319704] ? lock_release+0x3f0/0x3f0
+ [18455.319717] ? __tcp_close+0x2c6/0x790
+ [18455.319736] ? tcp_v4_do_rcv+0x168/0x370
+ [18455.319750] tcp_v4_do_rcv+0x168/0x370
+ [18455.319767] __release_sock+0xbc/0x1b0
+ [18455.319785] __tcp_close+0x2ee/0x790
+ [18455.319805] tcp_close+0x20/0x80
+
+This currently happens because on redirect case we do skb_set_owner_r()
+with the original sock. This increments the fwd_alloc memory accounting
+on the original sock. Then on redirect we may push this into the queue
+of the psock we are redirecting to. When the skb is flushed from the
+queue we give the memory back to the original sock. The problem is if
+the original sock is destroyed/closed with skbs on another psocks queue
+then the original sock will not have a way to reclaim the memory before
+being destroyed. Then above warning will be thrown
+
+ sockA sockB
+
+ sk_psock_strp_read()
+ sk_psock_verdict_apply()
+ -- SK_REDIRECT --
+ sk_psock_skb_redirect()
+ skb_queue_tail(psock_other->ingress_skb..)
+
+ sk_close()
+ sock_map_unref()
+ sk_psock_put()
+ sk_psock_drop()
+ sk_psock_zap_ingress()
+
+At this point we have torn down our own psock, but have the outstanding
+skb in psock_other. Note that SK_PASS doesn't have this problem because
+the sk_psock_drop() logic releases the skb, its still associated with
+our psock.
+
+To resolve lets only account for sockets on the ingress queue that are
+still associated with the current socket. On the redirect case we will
+check memory limits per 6fa9201a89898, but will omit fwd_alloc accounting
+until skb is actually enqueued. When the skb is sent via skb_send_sock_locked
+or received with sk_psock_skb_ingress memory will be claimed on psock_other.
+
+Fixes: 6fa9201a89898 ("bpf, sockmap: Avoid returning unneeded EAGAIN when redirecting to self")
+Reported-by: Andrii Nakryiko <andrii@kernel.org>
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/161731444013.68884.4021114312848535993.stgit@john-XPS-13-9370
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/skmsg.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -488,6 +488,7 @@ static int sk_psock_skb_ingress_self(str
+ if (unlikely(!msg))
+ return -EAGAIN;
+ sk_msg_init(msg);
++ skb_set_owner_r(skb, sk);
+ return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
+ }
+
+@@ -791,7 +792,6 @@ static void sk_psock_tls_verdict_apply(s
+ {
+ switch (verdict) {
+ case __SK_REDIRECT:
+- skb_set_owner_r(skb, sk);
+ sk_psock_skb_redirect(skb);
+ break;
+ case __SK_PASS:
+@@ -809,10 +809,6 @@ int sk_psock_tls_strp_read(struct sk_pso
+ rcu_read_lock();
+ prog = READ_ONCE(psock->progs.skb_verdict);
+ if (likely(prog)) {
+- /* We skip full set_owner_r here because if we do a SK_PASS
+- * or SK_DROP we can skip skb memory accounting and use the
+- * TLS context.
+- */
+ skb->sk = psock->sk;
+ tcp_skb_bpf_redirect_clear(skb);
+ ret = sk_psock_bpf_run(psock, prog, skb);
+@@ -881,12 +877,13 @@ static void sk_psock_strp_read(struct st
+ kfree_skb(skb);
+ goto out;
+ }
+- skb_set_owner_r(skb, sk);
+ prog = READ_ONCE(psock->progs.skb_verdict);
+ if (likely(prog)) {
++ skb->sk = sk;
+ tcp_skb_bpf_redirect_clear(skb);
+ ret = sk_psock_bpf_run(psock, prog, skb);
+ ret = sk_psock_map_verd(ret, tcp_skb_bpf_redirect_fetch(skb));
++ skb->sk = NULL;
+ }
+ sk_psock_verdict_apply(psock, skb, ret);
+ out:
+@@ -957,12 +954,13 @@ static int sk_psock_verdict_recv(read_de
+ kfree_skb(skb);
+ goto out;
+ }
+- skb_set_owner_r(skb, sk);
+ prog = READ_ONCE(psock->progs.skb_verdict);
+ if (likely(prog)) {
++ skb->sk = sk;
+ tcp_skb_bpf_redirect_clear(skb);
+ ret = sk_psock_bpf_run(psock, prog, skb);
+ ret = sk_psock_map_verd(ret, tcp_skb_bpf_redirect_fetch(skb));
++ skb->sk = NULL;
+ }
+ sk_psock_verdict_apply(psock, skb, ret);
+ out:
--- /dev/null
+From 1c84b33101c82683dee8b06761ca1f69e78c8ee7 Mon Sep 17 00:00:00 2001
+From: John Fastabend <john.fastabend@gmail.com>
+Date: Thu, 1 Apr 2021 15:00:19 -0700
+Subject: bpf, sockmap: Fix sk->prot unhash op reset
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+commit 1c84b33101c82683dee8b06761ca1f69e78c8ee7 upstream.
+
+In '4da6a196f93b1' we fixed a potential unhash loop caused when
+a TLS socket in a sockmap was removed from the sockmap. This
+happened because the unhash operation on the TLS ctx continued
+to point at the sockmap implementation of unhash even though the
+psock has already been removed. The sockmap unhash handler when a
+psock is removed does the following,
+
+ void sock_map_unhash(struct sock *sk)
+ {
+ void (*saved_unhash)(struct sock *sk);
+ struct sk_psock *psock;
+
+ rcu_read_lock();
+ psock = sk_psock(sk);
+ if (unlikely(!psock)) {
+ rcu_read_unlock();
+ if (sk->sk_prot->unhash)
+ sk->sk_prot->unhash(sk);
+ return;
+ }
+ [...]
+ }
+
+The unlikely() case is there to handle the case where psock is detached
+but the proto ops have not been updated yet. But, in the above case
+with TLS and removed psock we never fixed sk_prot->unhash() and unhash()
+points back to sock_map_unhash resulting in a loop. To fix this we added
+this bit of code,
+
+ static inline void sk_psock_restore_proto(struct sock *sk,
+ struct sk_psock *psock)
+ {
+ sk->sk_prot->unhash = psock->saved_unhash;
+
+This will set the sk_prot->unhash back to its saved value. This is the
+correct callback for a TLS socket that has been removed from the sock_map.
+Unfortunately, this also overwrites the unhash pointer for all psocks.
+We effectively break sockmap unhash handling for any future socks.
+Omitting the unhash operation will leave stale entries in the map if
+a socket transition through unhash, but does not do close() op.
+
+To fix set unhash correctly before calling into tls_update. This way the
+TLS enabled socket will point to the saved unhash() handler.
+
+Fixes: 4da6a196f93b1 ("bpf: Sockmap/tls, during free we may call tcp_bpf_unhash() in loop")
+Reported-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reported-by: Lorenz Bauer <lmb@cloudflare.com>
+Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/bpf/161731441904.68884.15593917809745631972.stgit@john-XPS-13-9370
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/skmsg.h | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -349,8 +349,13 @@ static inline void sk_psock_update_proto
+ static inline void sk_psock_restore_proto(struct sock *sk,
+ struct sk_psock *psock)
+ {
+- sk->sk_prot->unhash = psock->saved_unhash;
+ if (inet_csk_has_ulp(sk)) {
++ /* TLS does not have an unhash proto in SW cases, but we need
++ * to ensure we stop using the sock_map unhash routine because
++ * the associated psock is being removed. So use the original
++ * unhash handler.
++ */
++ WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash);
+ tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space);
+ } else {
+ sk->sk_write_space = psock->saved_write_space;
--- /dev/null
+From b5ac0146492fc5c199de767e492be8a66471011a Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 8 Apr 2021 14:28:27 +0200
+Subject: cfg80211: check S1G beacon compat element length
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit b5ac0146492fc5c199de767e492be8a66471011a upstream.
+
+We need to check the length of this element so that we don't
+access data beyond its end. Fix that.
+
+Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
+Link: https://lore.kernel.org/r/20210408142826.f6f4525012de.I9fdeff0afdc683a6024e5ea49d2daa3cd2459d11@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/scan.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -2351,14 +2351,16 @@ cfg80211_inform_single_bss_frame_data(st
+ return NULL;
+
+ if (ext) {
+- struct ieee80211_s1g_bcn_compat_ie *compat;
+- u8 *ie;
++ const struct ieee80211_s1g_bcn_compat_ie *compat;
++ const struct element *elem;
+
+- ie = (void *)cfg80211_find_ie(WLAN_EID_S1G_BCN_COMPAT,
+- variable, ielen);
+- if (!ie)
++ elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT,
++ variable, ielen);
++ if (!elem)
+ return NULL;
+- compat = (void *)(ie + 2);
++ if (elem->datalen < sizeof(*compat))
++ return NULL;
++ compat = (void *)elem->data;
+ bssid = ext->u.s1g_beacon.sa;
+ capability = le16_to_cpu(compat->compat_info);
+ beacon_int = le16_to_cpu(compat->beacon_int);
--- /dev/null
+From 6e5a03bcba44e080a6bf300194a68ce9bb1e5184 Mon Sep 17 00:00:00 2001
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+Date: Mon, 29 Mar 2021 04:50:02 -0700
+Subject: ethernet/netronome/nfp: Fix a use after free in nfp_bpf_ctrl_msg_rx
+
+From: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+
+commit 6e5a03bcba44e080a6bf300194a68ce9bb1e5184 upstream.
+
+In nfp_bpf_ctrl_msg_rx, if
+nfp_ccm_get_type(skb) == NFP_CCM_TYPE_BPF_BPF_EVENT is true, the skb
+will be freed. But the skb is still used by nfp_ccm_rx(&bpf->ccm, skb).
+
+My patch adds a return when the skb was freed.
+
+Fixes: bcf0cafab44fd ("nfp: split out common control message handling code")
+Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/netronome/nfp/bpf/cmsg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
++++ b/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c
+@@ -454,6 +454,7 @@ void nfp_bpf_ctrl_msg_rx(struct nfp_app
+ dev_consume_skb_any(skb);
+ else
+ dev_kfree_skb_any(skb);
++ return;
+ }
+
+ nfp_ccm_rx(&bpf->ccm, skb);
--- /dev/null
+From d6d04ee6d2c9bb5084c8f6074195d6aa0024e825 Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:41 +0100
+Subject: i40e: Fix sparse error: uninitialized symbol 'ring'
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+commit d6d04ee6d2c9bb5084c8f6074195d6aa0024e825 upstream.
+
+Init pointer with NULL in default switch case statement.
+
+Previously the error was produced when compiling against sparse.
+i40e_debugfs.c:582 i40e_dbg_dump_desc() error: uninitialized symbol 'ring'.
+
+Fixes: 44ea803e2fa7 ("i40e: introduce new dump desc XDP command")
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+@@ -578,6 +578,9 @@ static void i40e_dbg_dump_desc(int cnt,
+ case RING_TYPE_XDP:
+ ring = kmemdup(vsi->xdp_rings[ring_id], sizeof(*ring), GFP_KERNEL);
+ break;
++ default:
++ ring = NULL;
++ break;
+ }
+ if (!ring)
+ return;
--- /dev/null
+From 6b5674fe6b9bf05394886ebcec62b2d7dae88c42 Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:42 +0100
+Subject: i40e: Fix sparse error: 'vsi->netdev' could be null
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+commit 6b5674fe6b9bf05394886ebcec62b2d7dae88c42 upstream.
+
+Remove vsi->netdev->name from the trace.
+This is redundant information. With the devinfo trace, the adapter
+is already identifiable.
+
+Previously following error was produced when compiling against sparse.
+i40e_main.c:2571 i40e_sync_vsi_filters() error:
+ we previously assumed 'vsi->netdev' could be null (see line 2323)
+
+Fixes: b603f9dc20af ("i40e: Log info when PF is entering and leaving Allmulti mode.")
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -2560,8 +2560,7 @@ int i40e_sync_vsi_filters(struct i40e_vs
+ i40e_stat_str(hw, aq_ret),
+ i40e_aq_str(hw, hw->aq.asq_last_status));
+ } else {
+- dev_info(&pf->pdev->dev, "%s is %s allmulti mode.\n",
+- vsi->netdev->name,
++ dev_info(&pf->pdev->dev, "%s allmulti mode.\n",
+ cur_multipromisc ? "entering" : "leaving");
+ }
+ }
--- /dev/null
+From 12738ac4754ec92a6a45bf3677d8da780a1412b3 Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:40 +0100
+Subject: i40e: Fix sparse errors in i40e_txrx.c
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+commit 12738ac4754ec92a6a45bf3677d8da780a1412b3 upstream.
+
+Remove error handling through pointers. Instead use plain int
+to return value from i40e_run_xdp(...).
+
+Previously:
+- sparse errors were produced during compilation:
+i40e_txrx.c:2338 i40e_run_xdp() error: (-2147483647) too low for ERR_PTR
+i40e_txrx.c:2558 i40e_clean_rx_irq() error: 'skb' dereferencing possible ERR_PTR()
+
+- sk_buff* was used to return value, but it has never had valid
+pointer to sk_buff. Returned value was always int handled as
+a pointer.
+
+Fixes: 0c8493d90b6b ("i40e: add XDP support for pass and drop actions")
+Fixes: 2e6893123830 ("i40e: split XDP_TX tail and XDP_REDIRECT map flushing")
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_txrx.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+@@ -2187,8 +2187,7 @@ int i40e_xmit_xdp_tx_ring(struct xdp_buf
+ * @rx_ring: Rx ring being processed
+ * @xdp: XDP buffer containing the frame
+ **/
+-static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
+- struct xdp_buff *xdp)
++static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
+ {
+ int err, result = I40E_XDP_PASS;
+ struct i40e_ring *xdp_ring;
+@@ -2227,7 +2226,7 @@ static struct sk_buff *i40e_run_xdp(stru
+ }
+ xdp_out:
+ rcu_read_unlock();
+- return ERR_PTR(-result);
++ return result;
+ }
+
+ /**
+@@ -2339,6 +2338,7 @@ static int i40e_clean_rx_irq(struct i40e
+ unsigned int xdp_xmit = 0;
+ bool failure = false;
+ struct xdp_buff xdp;
++ int xdp_res = 0;
+
+ #if (PAGE_SIZE < 8192)
+ xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, 0);
+@@ -2405,12 +2405,10 @@ static int i40e_clean_rx_irq(struct i40e
+ /* At larger PAGE_SIZE, frame_sz depend on len size */
+ xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, size);
+ #endif
+- skb = i40e_run_xdp(rx_ring, &xdp);
++ xdp_res = i40e_run_xdp(rx_ring, &xdp);
+ }
+
+- if (IS_ERR(skb)) {
+- unsigned int xdp_res = -PTR_ERR(skb);
+-
++ if (xdp_res) {
+ if (xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR)) {
+ xdp_xmit |= xdp_res;
+ i40e_rx_buffer_flip(rx_ring, rx_buffer, size);
--- /dev/null
+From 8a1e918d833ca5c391c4ded5dc006e2d1ce6d37c Mon Sep 17 00:00:00 2001
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Date: Fri, 26 Mar 2021 19:43:43 +0100
+Subject: i40e: Fix sparse warning: missing error code 'err'
+
+From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+
+commit 8a1e918d833ca5c391c4ded5dc006e2d1ce6d37c upstream.
+
+Set proper return values inside error checking if-statements.
+
+Previously following warning was produced when compiling against sparse.
+i40e_main.c:15162 i40e_init_recovery_mode() warn: missing error code 'err'
+
+Fixes: 4ff0ee1af0169 ("i40e: Introduce recovery mode support")
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Tested-by: Dave Switzer <david.switzer@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -14647,12 +14647,16 @@ static int i40e_init_recovery_mode(struc
+ * in order to register the netdev
+ */
+ v_idx = i40e_vsi_mem_alloc(pf, I40E_VSI_MAIN);
+- if (v_idx < 0)
++ if (v_idx < 0) {
++ err = v_idx;
+ goto err_switch_setup;
++ }
+ pf->lan_vsi = v_idx;
+ vsi = pf->vsi[v_idx];
+- if (!vsi)
++ if (!vsi) {
++ err = -EFAULT;
+ goto err_switch_setup;
++ }
+ vsi->alloc_queue_pairs = 1;
+ err = i40e_config_netdev(vsi);
+ if (err)
--- /dev/null
+From b7eeb52721fe417730fc5adc5cbeeb5fe349ab26 Mon Sep 17 00:00:00 2001
+From: Robert Malz <robertx.malz@intel.com>
+Date: Fri, 26 Feb 2021 13:19:32 -0800
+Subject: ice: Cleanup fltr list in case of allocation issues
+
+From: Robert Malz <robertx.malz@intel.com>
+
+commit b7eeb52721fe417730fc5adc5cbeeb5fe349ab26 upstream.
+
+When ice_remove_vsi_lkup_fltr is called, by calling
+ice_add_to_vsi_fltr_list local copy of vsi filter list
+is created. If any issues during creation of vsi filter
+list occurs it up for the caller to free already
+allocated memory. This patch ensures proper memory
+deallocation in these cases.
+
+Fixes: 80d144c9ac82 ("ice: Refactor switch rule management structures and functions")
+Signed-off-by: Robert Malz <robertx.malz@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_switch.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_switch.c
++++ b/drivers/net/ethernet/intel/ice/ice_switch.c
+@@ -2628,7 +2628,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *
+ &remove_list_head);
+ mutex_unlock(rule_lock);
+ if (status)
+- return;
++ goto free_fltr_list;
+
+ switch (lkup) {
+ case ICE_SW_LKUP_MAC:
+@@ -2651,6 +2651,7 @@ ice_remove_vsi_lkup_fltr(struct ice_hw *
+ break;
+ }
+
++free_fltr_list:
+ list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
+ list_del(&fm_entry->list_entry);
+ devm_kfree(ice_hw_to_dev(hw), fm_entry);
--- /dev/null
+From 08771bce330036d473be6ce851cd00bcd351ebf6 Mon Sep 17 00:00:00 2001
+From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+Date: Fri, 26 Feb 2021 13:19:22 -0800
+Subject: ice: Continue probe on link/PHY errors
+
+From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+
+commit 08771bce330036d473be6ce851cd00bcd351ebf6 upstream.
+
+An incorrect NVM update procedure can result in the driver failing probe.
+In this case, the recommended resolution method is to update the NVM
+using the right procedure. However, if the driver fails probe, the user
+will not be able to update the NVM. So do not fail probe on link/PHY
+errors.
+
+Fixes: 1a3571b5938c ("ice: restore PHY settings on media insertion")
+Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_main.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4170,28 +4170,25 @@ ice_probe(struct pci_dev *pdev, const st
+ goto err_send_version_unroll;
+ }
+
++ /* not a fatal error if this fails */
+ err = ice_init_nvm_phy_type(pf->hw.port_info);
+- if (err) {
++ if (err)
+ dev_err(dev, "ice_init_nvm_phy_type failed: %d\n", err);
+- goto err_send_version_unroll;
+- }
+
++ /* not a fatal error if this fails */
+ err = ice_update_link_info(pf->hw.port_info);
+- if (err) {
++ if (err)
+ dev_err(dev, "ice_update_link_info failed: %d\n", err);
+- goto err_send_version_unroll;
+- }
+
+ ice_init_link_dflt_override(pf->hw.port_info);
+
+ /* if media available, initialize PHY settings */
+ if (pf->hw.port_info->phy.link_info.link_info &
+ ICE_AQ_MEDIA_AVAILABLE) {
++ /* not a fatal error if this fails */
+ err = ice_init_phy_user_cfg(pf->hw.port_info);
+- if (err) {
++ if (err)
+ dev_err(dev, "ice_init_phy_user_cfg failed: %d\n", err);
+- goto err_send_version_unroll;
+- }
+
+ if (!test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags)) {
+ struct ice_vsi *vsi = ice_get_main_vsi(pf);
--- /dev/null
+From 7a91d3f02b04b2fb18c2dfa8b6c4e5a40a2753f5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jacek=20Bu=C5=82atek?= <jacekx.bulatek@intel.com>
+Date: Fri, 26 Feb 2021 13:19:29 -0800
+Subject: ice: Fix for dereference of NULL pointer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jacek Bułatek <jacekx.bulatek@intel.com>
+
+commit 7a91d3f02b04b2fb18c2dfa8b6c4e5a40a2753f5 upstream.
+
+Add handling of allocation fault for ice_vsi_list_map_info.
+
+Also *fi should not be NULL pointer, it is a reference to raw
+data field, so remove this variable and use the reference
+directly.
+
+Fixes: 9daf8208dd4d ("ice: Add support for switch filter programming")
+Signed-off-by: Jacek Bułatek <jacekx.bulatek@intel.com>
+Co-developed-by: Haiyue Wang <haiyue.wang@intel.com>
+Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_switch.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_switch.c
++++ b/drivers/net/ethernet/intel/ice/ice_switch.c
+@@ -1239,6 +1239,9 @@ ice_add_update_vsi_list(struct ice_hw *h
+ ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
+ vsi_list_id);
+
++ if (!m_entry->vsi_list_info)
++ return ICE_ERR_NO_MEMORY;
++
+ /* If this entry was large action then the large action needs
+ * to be updated to point to FWD to VSI list
+ */
+@@ -2224,6 +2227,7 @@ ice_vsi_uses_fltr(struct ice_fltr_mgmt_l
+ return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
+ fm_entry->fltr_info.vsi_handle == vsi_handle) ||
+ (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
++ fm_entry->vsi_list_info &&
+ (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
+ }
+
+@@ -2296,14 +2300,12 @@ ice_add_to_vsi_fltr_list(struct ice_hw *
+ return ICE_ERR_PARAM;
+
+ list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
+- struct ice_fltr_info *fi;
+-
+- fi = &fm_entry->fltr_info;
+- if (!fi || !ice_vsi_uses_fltr(fm_entry, vsi_handle))
++ if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
+ continue;
+
+ status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
+- vsi_list_head, fi);
++ vsi_list_head,
++ &fm_entry->fltr_info);
+ if (status)
+ return status;
+ }
--- /dev/null
+From 59df14f9cc2326bd6432d60eca0df8201d9d3d4b Mon Sep 17 00:00:00 2001
+From: Bruce Allan <bruce.w.allan@intel.com>
+Date: Fri, 26 Feb 2021 13:19:27 -0800
+Subject: ice: fix memory allocation call
+
+From: Bruce Allan <bruce.w.allan@intel.com>
+
+commit 59df14f9cc2326bd6432d60eca0df8201d9d3d4b upstream.
+
+Fix the order of number of array members and member size parameters in a
+*calloc() call.
+
+Fixes: b3c3890489f6 ("ice: avoid unnecessary single-member variable-length structs")
+Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_common.c
++++ b/drivers/net/ethernet/intel/ice/ice_common.c
+@@ -717,8 +717,8 @@ static enum ice_status ice_cfg_fw_log(st
+
+ if (!data) {
+ data = devm_kcalloc(ice_hw_to_dev(hw),
+- sizeof(*data),
+ ICE_AQC_FW_LOG_ID_MAX,
++ sizeof(*data),
+ GFP_KERNEL);
+ if (!data)
+ return ICE_ERR_NO_MEMORY;
--- /dev/null
+From 1831da7ea5bdf5531d78bcf81f526faa4c4375fa Mon Sep 17 00:00:00 2001
+From: Yongxin Liu <yongxin.liu@windriver.com>
+Date: Thu, 1 Apr 2021 11:59:15 -0700
+Subject: ice: fix memory leak of aRFS after resuming from suspend
+
+From: Yongxin Liu <yongxin.liu@windriver.com>
+
+commit 1831da7ea5bdf5531d78bcf81f526faa4c4375fa upstream.
+
+In ice_suspend(), ice_clear_interrupt_scheme() is called, and then
+irq_free_descs() will be eventually called to free irq and its descriptor.
+
+In ice_resume(), ice_init_interrupt_scheme() is called to allocate new
+irqs. However, in ice_rebuild_arfs(), struct irq_glue and struct cpu_rmap
+maybe cannot be freed, if the irqs that released in ice_suspend() were
+reassigned to other devices, which makes irq descriptor's affinity_notify
+lost.
+
+So call ice_free_cpu_rx_rmap() before ice_clear_interrupt_scheme(), which
+can make sure all irq_glue and cpu_rmap can be correctly released before
+corresponding irq and descriptor are released.
+
+Fix the following memory leak.
+
+unreferenced object 0xffff95bd951afc00 (size 512):
+ comm "kworker/0:1", pid 134, jiffies 4294684283 (age 13051.958s)
+ hex dump (first 32 bytes):
+ 18 00 00 00 18 00 18 00 70 fc 1a 95 bd 95 ff ff ........p.......
+ 00 00 ff ff 01 00 ff ff 02 00 ff ff 03 00 ff ff ................
+ backtrace:
+ [<0000000072e4b914>] __kmalloc+0x336/0x540
+ [<0000000054642a87>] alloc_cpu_rmap+0x3b/0xb0
+ [<00000000f220deec>] ice_set_cpu_rx_rmap+0x6a/0x110 [ice]
+ [<000000002370a632>] ice_probe+0x941/0x1180 [ice]
+ [<00000000d692edba>] local_pci_probe+0x47/0xa0
+ [<00000000503934f0>] work_for_cpu_fn+0x1a/0x30
+ [<00000000555a9e4a>] process_one_work+0x1dd/0x410
+ [<000000002c4b414a>] worker_thread+0x221/0x3f0
+ [<00000000bb2b556b>] kthread+0x14c/0x170
+ [<00000000ad2cf1cd>] ret_from_fork+0x1f/0x30
+unreferenced object 0xffff95bd81b0a2a0 (size 96):
+ comm "kworker/0:1", pid 134, jiffies 4294684283 (age 13051.958s)
+ hex dump (first 32 bytes):
+ 38 00 00 00 01 00 00 00 e0 ff ff ff 0f 00 00 00 8...............
+ b0 a2 b0 81 bd 95 ff ff b0 a2 b0 81 bd 95 ff ff ................
+ backtrace:
+ [<00000000582dd5c5>] kmem_cache_alloc_trace+0x31f/0x4c0
+ [<000000002659850d>] irq_cpu_rmap_add+0x25/0xe0
+ [<00000000495a3055>] ice_set_cpu_rx_rmap+0xb4/0x110 [ice]
+ [<000000002370a632>] ice_probe+0x941/0x1180 [ice]
+ [<00000000d692edba>] local_pci_probe+0x47/0xa0
+ [<00000000503934f0>] work_for_cpu_fn+0x1a/0x30
+ [<00000000555a9e4a>] process_one_work+0x1dd/0x410
+ [<000000002c4b414a>] worker_thread+0x221/0x3f0
+ [<00000000bb2b556b>] kthread+0x14c/0x170
+ [<00000000ad2cf1cd>] ret_from_fork+0x1f/0x30
+
+Fixes: 769c500dcc1e ("ice: Add advanced power mgmt for WoL")
+Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4538,6 +4538,7 @@ static int __maybe_unused ice_suspend(st
+ continue;
+ ice_vsi_free_q_vectors(pf->vsi[v]);
+ }
++ ice_free_cpu_rx_rmap(ice_get_main_vsi(pf));
+ ice_clear_interrupt_scheme(pf);
+
+ pci_save_state(pdev);
--- /dev/null
+From f88c529ac77b3c21819d2cf1dfcfae1937849743 Mon Sep 17 00:00:00 2001
+From: Fabio Pricoco <fabio.pricoco@intel.com>
+Date: Fri, 26 Feb 2021 13:19:24 -0800
+Subject: ice: Increase control queue timeout
+
+From: Fabio Pricoco <fabio.pricoco@intel.com>
+
+commit f88c529ac77b3c21819d2cf1dfcfae1937849743 upstream.
+
+250 msec timeout is insufficient for some AQ commands. Advice from FW
+team was to increase the timeout. Increase to 1 second.
+
+Fixes: 7ec59eeac804 ("ice: Add support for control queues")
+Signed-off-by: Fabio Pricoco <fabio.pricoco@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_controlq.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_controlq.h
++++ b/drivers/net/ethernet/intel/ice/ice_controlq.h
+@@ -31,8 +31,8 @@ enum ice_ctl_q {
+ ICE_CTL_Q_MAILBOX,
+ };
+
+-/* Control Queue timeout settings - max delay 250ms */
+-#define ICE_CTL_Q_SQ_CMD_TIMEOUT 2500 /* Count 2500 times */
++/* Control Queue timeout settings - max delay 1s */
++#define ICE_CTL_Q_SQ_CMD_TIMEOUT 10000 /* Count 10000 times */
+ #define ICE_CTL_Q_SQ_CMD_USEC 100 /* Check every 100usec */
+ #define ICE_CTL_Q_ADMIN_INIT_TIMEOUT 10 /* Count 10 times */
+ #define ICE_CTL_Q_ADMIN_INIT_MSEC 100 /* Check every 100msec */
--- /dev/null
+From e95fc8573e07c5e4825df4650fd8b8c93fad27a7 Mon Sep 17 00:00:00 2001
+From: Krzysztof Goreczny <krzysztof.goreczny@intel.com>
+Date: Fri, 26 Feb 2021 13:19:26 -0800
+Subject: ice: prevent ice_open and ice_stop during reset
+
+From: Krzysztof Goreczny <krzysztof.goreczny@intel.com>
+
+commit e95fc8573e07c5e4825df4650fd8b8c93fad27a7 upstream.
+
+There is a possibility of race between ice_open or ice_stop calls
+performed by OS and reset handling routine both trying to modify VSI
+resources. Observed scenarios:
+- reset handler deallocates memory in ice_vsi_free_arrays and ice_open
+ tries to access it in ice_vsi_cfg_txq leading to driver crash
+- reset handler deallocates memory in ice_vsi_free_arrays and ice_close
+ tries to access it in ice_down leading to driver crash
+- reset handler clears port scheduler topology and sets port state to
+ ICE_SCHED_PORT_STATE_INIT leading to ice_ena_vsi_txq fail in ice_open
+
+To prevent this additional checks in ice_open and ice_stop are
+introduced to make sure that OS is not allowed to alter VSI config while
+reset is in progress.
+
+Fixes: cdedef59deb0 ("ice: Configure VSIs for Tx/Rx")
+Signed-off-by: Krzysztof Goreczny <krzysztof.goreczny@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 1 +
+ drivers/net/ethernet/intel/ice/ice_lib.c | 4 ++--
+ drivers/net/ethernet/intel/ice/ice_main.c | 28 ++++++++++++++++++++++++++++
+ 3 files changed, 31 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -605,6 +605,7 @@ int ice_fdir_create_dflt_rules(struct ic
+ int ice_aq_wait_for_event(struct ice_pf *pf, u16 opcode, unsigned long timeout,
+ struct ice_rq_event_info *event);
+ int ice_open(struct net_device *netdev);
++int ice_open_internal(struct net_device *netdev);
+ int ice_stop(struct net_device *netdev);
+ void ice_service_task_schedule(struct ice_pf *pf);
+
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2489,7 +2489,7 @@ int ice_ena_vsi(struct ice_vsi *vsi, boo
+ if (!locked)
+ rtnl_lock();
+
+- err = ice_open(vsi->netdev);
++ err = ice_open_internal(vsi->netdev);
+
+ if (!locked)
+ rtnl_unlock();
+@@ -2518,7 +2518,7 @@ void ice_dis_vsi(struct ice_vsi *vsi, bo
+ if (!locked)
+ rtnl_lock();
+
+- ice_stop(vsi->netdev);
++ ice_vsi_close(vsi);
+
+ if (!locked)
+ rtnl_unlock();
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -6615,6 +6615,28 @@ static void ice_tx_timeout(struct net_de
+ int ice_open(struct net_device *netdev)
+ {
+ struct ice_netdev_priv *np = netdev_priv(netdev);
++ struct ice_pf *pf = np->vsi->back;
++
++ if (ice_is_reset_in_progress(pf->state)) {
++ netdev_err(netdev, "can't open net device while reset is in progress");
++ return -EBUSY;
++ }
++
++ return ice_open_internal(netdev);
++}
++
++/**
++ * ice_open_internal - Called when a network interface becomes active
++ * @netdev: network interface device structure
++ *
++ * Internal ice_open implementation. Should not be used directly except for ice_open and reset
++ * handling routine
++ *
++ * Returns 0 on success, negative value on failure
++ */
++int ice_open_internal(struct net_device *netdev)
++{
++ struct ice_netdev_priv *np = netdev_priv(netdev);
+ struct ice_vsi *vsi = np->vsi;
+ struct ice_pf *pf = vsi->back;
+ struct ice_port_info *pi;
+@@ -6693,6 +6715,12 @@ int ice_stop(struct net_device *netdev)
+ {
+ struct ice_netdev_priv *np = netdev_priv(netdev);
+ struct ice_vsi *vsi = np->vsi;
++ struct ice_pf *pf = vsi->back;
++
++ if (ice_is_reset_in_progress(pf->state)) {
++ netdev_err(netdev, "can't stop net device while reset is in progress");
++ return -EBUSY;
++ }
+
+ ice_vsi_close(vsi);
+
--- /dev/null
+From 741b7b743bbcb5a3848e4e55982064214f900d2f Mon Sep 17 00:00:00 2001
+From: Dave Ertman <david.m.ertman@intel.com>
+Date: Fri, 26 Feb 2021 13:19:28 -0800
+Subject: ice: remove DCBNL_DEVRESET bit from PF state
+
+From: Dave Ertman <david.m.ertman@intel.com>
+
+commit 741b7b743bbcb5a3848e4e55982064214f900d2f upstream.
+
+The original purpose of the ICE_DCBNL_DEVRESET was to protect
+the driver during DCBNL device resets. But, the flow for
+DCBNL device resets now consists of only calls up the stack
+such as dev_close() and dev_open() that will result in NDO calls
+to the driver. These will be handled with state changes from the
+stack. Also, there is a problem of the dev_close and dev_open
+being blocked by checks for reset in progress also using the
+ICE_DCBNL_DEVRESET bit.
+
+Since the ICE_DCBNL_DEVRESET bit is not necessary for protecting
+the driver from DCBNL device resets and it is actually blocking
+changes coming from the DCBNL interface, remove the bit from the
+PF state and don't block driver function based on DCBNL reset in
+progress.
+
+Fixes: b94b013eb626 ("ice: Implement DCBNL support")
+Signed-off-by: Dave Ertman <david.m.ertman@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 1 -
+ drivers/net/ethernet/intel/ice/ice_dcb_nl.c | 2 --
+ drivers/net/ethernet/intel/ice/ice_lib.c | 1 -
+ 3 files changed, 4 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -194,7 +194,6 @@ enum ice_state {
+ __ICE_NEEDS_RESTART,
+ __ICE_PREPARED_FOR_RESET, /* set by driver when prepared */
+ __ICE_RESET_OICR_RECV, /* set by driver after rcv reset OICR */
+- __ICE_DCBNL_DEVRESET, /* set by dcbnl devreset */
+ __ICE_PFR_REQ, /* set by driver and peers */
+ __ICE_CORER_REQ, /* set by driver and peers */
+ __ICE_GLOBR_REQ, /* set by driver and peers */
+--- a/drivers/net/ethernet/intel/ice/ice_dcb_nl.c
++++ b/drivers/net/ethernet/intel/ice/ice_dcb_nl.c
+@@ -18,12 +18,10 @@ static void ice_dcbnl_devreset(struct ne
+ while (ice_is_reset_in_progress(pf->state))
+ usleep_range(1000, 2000);
+
+- set_bit(__ICE_DCBNL_DEVRESET, pf->state);
+ dev_close(netdev);
+ netdev_state_change(netdev);
+ dev_open(netdev, NULL);
+ netdev_state_change(netdev);
+- clear_bit(__ICE_DCBNL_DEVRESET, pf->state);
+ }
+
+ /**
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2944,7 +2944,6 @@ err_vsi:
+ bool ice_is_reset_in_progress(unsigned long *state)
+ {
+ return test_bit(__ICE_RESET_OICR_RECV, state) ||
+- test_bit(__ICE_DCBNL_DEVRESET, state) ||
+ test_bit(__ICE_PFR_REQ, state) ||
+ test_bit(__ICE_CORER_REQ, state) ||
+ test_bit(__ICE_GLOBR_REQ, state);
--- /dev/null
+From 3176551979b92b02756979c0f1e2d03d1fc82b1e Mon Sep 17 00:00:00 2001
+From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+Date: Fri, 26 Feb 2021 13:19:30 -0800
+Subject: ice: Use port number instead of PF ID for WoL
+
+From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+
+commit 3176551979b92b02756979c0f1e2d03d1fc82b1e upstream.
+
+As per the spec, the WoL control word read from the NVM should be
+interpreted as port numbers, and not PF numbers. So when checking
+if WoL supported, use the port number instead of the PF ID.
+
+Also, ice_is_wol_supported doesn't really need a pointer to the pf
+struct, but just needs a pointer to the hw instance.
+
+Fixes: 769c500dcc1e ("ice: Add advanced power mgmt for WoL")
+Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
+Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 2 +-
+ drivers/net/ethernet/intel/ice/ice_ethtool.c | 4 ++--
+ drivers/net/ethernet/intel/ice/ice_main.c | 9 ++++-----
+ 3 files changed, 7 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -586,7 +586,7 @@ int ice_schedule_reset(struct ice_pf *pf
+ void ice_print_link_msg(struct ice_vsi *vsi, bool isup);
+ const char *ice_stat_str(enum ice_status stat_err);
+ const char *ice_aq_str(enum ice_aq_err aq_err);
+-bool ice_is_wol_supported(struct ice_pf *pf);
++bool ice_is_wol_supported(struct ice_hw *hw);
+ int
+ ice_fdir_write_fltr(struct ice_pf *pf, struct ice_fdir_fltr *input, bool add,
+ bool is_tun);
+--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+@@ -3472,7 +3472,7 @@ static void ice_get_wol(struct net_devic
+ netdev_warn(netdev, "Wake on LAN is not supported on this interface!\n");
+
+ /* Get WoL settings based on the HW capability */
+- if (ice_is_wol_supported(pf)) {
++ if (ice_is_wol_supported(&pf->hw)) {
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = pf->wol_ena ? WAKE_MAGIC : 0;
+ } else {
+@@ -3492,7 +3492,7 @@ static int ice_set_wol(struct net_device
+ struct ice_vsi *vsi = np->vsi;
+ struct ice_pf *pf = vsi->back;
+
+- if (vsi->type != ICE_VSI_PF || !ice_is_wol_supported(pf))
++ if (vsi->type != ICE_VSI_PF || !ice_is_wol_supported(&pf->hw))
+ return -EOPNOTSUPP;
+
+ /* only magic packet is supported */
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -3515,15 +3515,14 @@ static int ice_init_interrupt_scheme(str
+ }
+
+ /**
+- * ice_is_wol_supported - get NVM state of WoL
+- * @pf: board private structure
++ * ice_is_wol_supported - check if WoL is supported
++ * @hw: pointer to hardware info
+ *
+ * Check if WoL is supported based on the HW configuration.
+ * Returns true if NVM supports and enables WoL for this port, false otherwise
+ */
+-bool ice_is_wol_supported(struct ice_pf *pf)
++bool ice_is_wol_supported(struct ice_hw *hw)
+ {
+- struct ice_hw *hw = &pf->hw;
+ u16 wol_ctrl;
+
+ /* A bit set to 1 in the NVM Software Reserved Word 2 (WoL control
+@@ -3532,7 +3531,7 @@ bool ice_is_wol_supported(struct ice_pf
+ if (ice_read_sr_word(hw, ICE_SR_NVM_WOL_CFG, &wol_ctrl))
+ return false;
+
+- return !(BIT(hw->pf_id) & wol_ctrl);
++ return !(BIT(hw->port_info->lport) & wol_ctrl);
+ }
+
+ /**
--- /dev/null
+From 25628bc08d4526d3673ca7d039eb636aa9006076 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 26 Mar 2021 12:57:18 +0200
+Subject: iwlwifi: pcie: properly set LTR workarounds on 22000 devices
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 25628bc08d4526d3673ca7d039eb636aa9006076 upstream.
+
+As the context info gen3 code is only called for >=AX210 devices
+(from iwl_trans_pcie_gen2_start_fw()) the code there to set LTR
+on 22000 devices cannot actually do anything (22000 < AX210).
+
+Fix this by moving the LTR code to iwl_trans_pcie_gen2_start_fw()
+where it can handle both devices. This then requires that we kick
+the firmware only after that rather than doing it from the context
+info code.
+
+Note that this again had a dead branch in gen3 code, which I've
+removed here.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Fixes: ed0022da8bd9 ("iwlwifi: pcie: set LTR on more devices")
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/iwlwifi.20210326125611.675486178ed1.Ib61463aba6920645059e366dcdca4c4c77f0ff58@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 31 -------------
+ drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 3 -
+ drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 35 +++++++++++++++
+ 3 files changed, 37 insertions(+), 32 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+@@ -5,7 +5,7 @@
+ *
+ * GPL LICENSE SUMMARY
+ *
+- * Copyright(c) 2018 - 2020 Intel Corporation
++ * Copyright(c) 2018 - 2021 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+@@ -122,15 +122,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct
+ const struct fw_img *fw)
+ {
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+- u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
+- u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
+- CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
+- u32_encode_bits(250,
+- CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
+- CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
+- u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
+- CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
+- u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
+ struct iwl_context_info_gen3 *ctxt_info_gen3;
+ struct iwl_prph_scratch *prph_scratch;
+ struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
+@@ -264,26 +255,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct
+ iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
+ CSR_AUTO_FUNC_BOOT_ENA);
+
+- /*
+- * To workaround hardware latency issues during the boot process,
+- * initialize the LTR to ~250 usec (see ltr_val above).
+- * The firmware initializes this again later (to a smaller value).
+- */
+- if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
+- trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
+- !trans->trans_cfg->integrated) {
+- iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
+- } else if (trans->trans_cfg->integrated &&
+- trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
+- iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
+- iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
+- }
+-
+- if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
+- iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
+- else
+- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT);
+-
+ return 0;
+
+ err_free_ctxt_info:
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
+@@ -6,7 +6,7 @@
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2017 Intel Deutschland GmbH
+- * Copyright(c) 2018 - 2020 Intel Corporation
++ * Copyright(c) 2018 - 2021 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+@@ -288,7 +288,6 @@ int iwl_pcie_ctxt_info_init(struct iwl_t
+
+ /* kick FW self load */
+ iwl_write64(trans, CSR_CTXT_INFO_BA, trans_pcie->ctxt_info_dma_addr);
+- iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
+
+ /* Context info will be released upon alive or failure to get one */
+
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+@@ -281,6 +281,34 @@ void iwl_trans_pcie_gen2_fw_alive(struct
+ mutex_unlock(&trans_pcie->mutex);
+ }
+
++static void iwl_pcie_set_ltr(struct iwl_trans *trans)
++{
++ u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
++ u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
++ CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
++ u32_encode_bits(250,
++ CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
++ CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
++ u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
++ CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
++ u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
++
++ /*
++ * To workaround hardware latency issues during the boot process,
++ * initialize the LTR to ~250 usec (see ltr_val above).
++ * The firmware initializes this again later (to a smaller value).
++ */
++ if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
++ trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
++ !trans->trans_cfg->integrated) {
++ iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
++ } else if (trans->trans_cfg->integrated &&
++ trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
++ iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
++ iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
++ }
++}
++
+ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
+ const struct fw_img *fw, bool run_in_rfkill)
+ {
+@@ -347,6 +375,13 @@ int iwl_trans_pcie_gen2_start_fw(struct
+ if (ret)
+ goto out;
+
++ iwl_pcie_set_ltr(trans);
++
++ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
++ iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
++ else
++ iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
++
+ /* re-check RF-Kill state since we may have missed the interrupt */
+ hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
+ if (hw_rfkill && !run_in_rfkill)
--- /dev/null
+From df662016310aa4475d7986fd726af45c8fe4f362 Mon Sep 17 00:00:00 2001
+From: Ciara Loftus <ciara.loftus@intel.com>
+Date: Wed, 31 Mar 2021 06:12:16 +0000
+Subject: libbpf: Ensure umem pointer is non-NULL before dereferencing
+
+From: Ciara Loftus <ciara.loftus@intel.com>
+
+commit df662016310aa4475d7986fd726af45c8fe4f362 upstream.
+
+Calls to xsk_socket__create dereference the umem to access the
+fill_save and comp_save pointers. Make sure the umem is non-NULL
+before doing this.
+
+Fixes: 2f6324a3937f ("libbpf: Support shared umems between queues and devices")
+Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Link: https://lore.kernel.org/bpf/20210331061218.1647-2-ciara.loftus@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/lib/bpf/xsk.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -870,6 +870,9 @@ int xsk_socket__create(struct xsk_socket
+ struct xsk_ring_cons *rx, struct xsk_ring_prod *tx,
+ const struct xsk_socket_config *usr_config)
+ {
++ if (!umem)
++ return -EFAULT;
++
+ return xsk_socket__create_shared(xsk_ptr, ifname, queue_id, umem,
+ rx, tx, umem->fill_save,
+ umem->comp_save, usr_config);
--- /dev/null
+From 6032ebb54c60cae24329f6aba3ce0c1ca8ad6abe Mon Sep 17 00:00:00 2001
+From: Pedro Tammela <pctammela@gmail.com>
+Date: Thu, 25 Mar 2021 12:01:15 -0300
+Subject: libbpf: Fix bail out from 'ringbuf_process_ring()' on error
+
+From: Pedro Tammela <pctammela@gmail.com>
+
+commit 6032ebb54c60cae24329f6aba3ce0c1ca8ad6abe upstream.
+
+The current code bails out with negative and positive returns.
+If the callback returns a positive return code, 'ring_buffer__consume()'
+and 'ring_buffer__poll()' will return a spurious number of records
+consumed, but mostly important will continue the processing loop.
+
+This patch makes positive returns from the callback a no-op.
+
+Fixes: bf99c936f947 ("libbpf: Add BPF ring buffer support")
+Signed-off-by: Pedro Tammela <pctammela@mojatatu.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20210325150115.138750-1-pctammela@mojatatu.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/lib/bpf/ringbuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/lib/bpf/ringbuf.c
++++ b/tools/lib/bpf/ringbuf.c
+@@ -227,7 +227,7 @@ static int ringbuf_process_ring(struct r
+ if ((len & BPF_RINGBUF_DISCARD_BIT) == 0) {
+ sample = (void *)len_ptr + BPF_RINGBUF_HDR_SZ;
+ err = r->sample_cb(r->ctx, sample, len);
+- if (err) {
++ if (err < 0) {
+ /* update consumer pos and bail out */
+ smp_store_release(r->consumer_pos,
+ cons_pos);
--- /dev/null
+From ca7a83e2487ad0bc9a3e0e7a8645354aa1782f13 Mon Sep 17 00:00:00 2001
+From: Ciara Loftus <ciara.loftus@intel.com>
+Date: Wed, 31 Mar 2021 06:12:18 +0000
+Subject: libbpf: Only create rx and tx XDP rings when necessary
+
+From: Ciara Loftus <ciara.loftus@intel.com>
+
+commit ca7a83e2487ad0bc9a3e0e7a8645354aa1782f13 upstream.
+
+Prior to this commit xsk_socket__create(_shared) always attempted to create
+the rx and tx rings for the socket. However this causes an issue when the
+socket being setup is that which shares the fd with the UMEM. If a
+previous call to this function failed with this socket after the rings were
+set up, a subsequent call would always fail because the rings are not torn
+down after the first call and when we try to set them up again we encounter
+an error because they already exist. Solve this by remembering whether the
+rings were set up by introducing new bools to struct xsk_umem which
+represent the ring setup status and using them to determine whether or
+not to set up the rings.
+
+Fixes: 1cad07884239 ("libbpf: add support for using AF_XDP sockets")
+Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210331061218.1647-4-ciara.loftus@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/lib/bpf/xsk.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -54,6 +54,8 @@ struct xsk_umem {
+ int fd;
+ int refcount;
+ struct list_head ctx_list;
++ bool rx_ring_setup_done;
++ bool tx_ring_setup_done;
+ };
+
+ struct xsk_ctx {
+@@ -708,6 +710,7 @@ int xsk_socket__create_shared(struct xsk
+ struct xsk_ctx *ctx;
+ int err, ifindex;
+ bool unmap = umem->fill_save != fill;
++ bool rx_setup_done = false, tx_setup_done = false;
+
+ if (!umem || !xsk_ptr || !(rx || tx))
+ return -EFAULT;
+@@ -735,6 +738,8 @@ int xsk_socket__create_shared(struct xsk
+ }
+ } else {
+ xsk->fd = umem->fd;
++ rx_setup_done = umem->rx_ring_setup_done;
++ tx_setup_done = umem->tx_ring_setup_done;
+ }
+
+ ctx = xsk_get_ctx(umem, ifindex, queue_id);
+@@ -753,7 +758,7 @@ int xsk_socket__create_shared(struct xsk
+ }
+ xsk->ctx = ctx;
+
+- if (rx) {
++ if (rx && !rx_setup_done) {
+ err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,
+ &xsk->config.rx_size,
+ sizeof(xsk->config.rx_size));
+@@ -761,8 +766,10 @@ int xsk_socket__create_shared(struct xsk
+ err = -errno;
+ goto out_put_ctx;
+ }
++ if (xsk->fd == umem->fd)
++ umem->rx_ring_setup_done = true;
+ }
+- if (tx) {
++ if (tx && !tx_setup_done) {
+ err = setsockopt(xsk->fd, SOL_XDP, XDP_TX_RING,
+ &xsk->config.tx_size,
+ sizeof(xsk->config.tx_size));
+@@ -770,6 +777,8 @@ int xsk_socket__create_shared(struct xsk
+ err = -errno;
+ goto out_put_ctx;
+ }
++ if (xsk->fd == umem->fd)
++ umem->rx_ring_setup_done = true;
+ }
+
+ err = xsk_get_mmap_offsets(xsk->fd, &off);
--- /dev/null
+From 43f1bc1efff16f553dd573d02eb7a15750925568 Mon Sep 17 00:00:00 2001
+From: Ciara Loftus <ciara.loftus@intel.com>
+Date: Wed, 31 Mar 2021 06:12:17 +0000
+Subject: libbpf: Restore umem state after socket create failure
+
+From: Ciara Loftus <ciara.loftus@intel.com>
+
+commit 43f1bc1efff16f553dd573d02eb7a15750925568 upstream.
+
+If the call to xsk_socket__create fails, the user may want to retry the
+socket creation using the same umem. Ensure that the umem is in the
+same state on exit if the call fails by:
+1. ensuring the umem _save pointers are unmodified.
+2. not unmapping the set of umem rings that were set up with the umem
+during xsk_umem__create, since those maps existed before the call to
+xsk_socket__create and should remain in tact even in the event of
+failure.
+
+Fixes: 2f6324a3937f ("libbpf: Support shared umems between queues and devices")
+Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20210331061218.1647-3-ciara.loftus@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/lib/bpf/xsk.c | 41 +++++++++++++++++++++++------------------
+ 1 file changed, 23 insertions(+), 18 deletions(-)
+
+--- a/tools/lib/bpf/xsk.c
++++ b/tools/lib/bpf/xsk.c
+@@ -628,26 +628,30 @@ static struct xsk_ctx *xsk_get_ctx(struc
+ return NULL;
+ }
+
+-static void xsk_put_ctx(struct xsk_ctx *ctx)
++static void xsk_put_ctx(struct xsk_ctx *ctx, bool unmap)
+ {
+ struct xsk_umem *umem = ctx->umem;
+ struct xdp_mmap_offsets off;
+ int err;
+
+- if (--ctx->refcount == 0) {
+- err = xsk_get_mmap_offsets(umem->fd, &off);
+- if (!err) {
+- munmap(ctx->fill->ring - off.fr.desc,
+- off.fr.desc + umem->config.fill_size *
+- sizeof(__u64));
+- munmap(ctx->comp->ring - off.cr.desc,
+- off.cr.desc + umem->config.comp_size *
+- sizeof(__u64));
+- }
++ if (--ctx->refcount)
++ return;
+
+- list_del(&ctx->list);
+- free(ctx);
+- }
++ if (!unmap)
++ goto out_free;
++
++ err = xsk_get_mmap_offsets(umem->fd, &off);
++ if (err)
++ goto out_free;
++
++ munmap(ctx->fill->ring - off.fr.desc, off.fr.desc + umem->config.fill_size *
++ sizeof(__u64));
++ munmap(ctx->comp->ring - off.cr.desc, off.cr.desc + umem->config.comp_size *
++ sizeof(__u64));
++
++out_free:
++ list_del(&ctx->list);
++ free(ctx);
+ }
+
+ static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk,
+@@ -682,8 +686,6 @@ static struct xsk_ctx *xsk_create_ctx(st
+ memcpy(ctx->ifname, ifname, IFNAMSIZ - 1);
+ ctx->ifname[IFNAMSIZ - 1] = '\0';
+
+- umem->fill_save = NULL;
+- umem->comp_save = NULL;
+ ctx->fill = fill;
+ ctx->comp = comp;
+ list_add(&ctx->list, &umem->ctx_list);
+@@ -705,6 +707,7 @@ int xsk_socket__create_shared(struct xsk
+ struct xsk_socket *xsk;
+ struct xsk_ctx *ctx;
+ int err, ifindex;
++ bool unmap = umem->fill_save != fill;
+
+ if (!umem || !xsk_ptr || !(rx || tx))
+ return -EFAULT;
+@@ -845,6 +848,8 @@ int xsk_socket__create_shared(struct xsk
+ }
+
+ *xsk_ptr = xsk;
++ umem->fill_save = NULL;
++ umem->comp_save = NULL;
+ return 0;
+
+ out_mmap_tx:
+@@ -856,7 +861,7 @@ out_mmap_rx:
+ munmap(rx_map, off.rx.desc +
+ xsk->config.rx_size * sizeof(struct xdp_desc));
+ out_put_ctx:
+- xsk_put_ctx(ctx);
++ xsk_put_ctx(ctx, unmap);
+ out_socket:
+ if (--umem->refcount)
+ close(xsk->fd);
+@@ -922,7 +927,7 @@ void xsk_socket__delete(struct xsk_socke
+ }
+ }
+
+- xsk_put_ctx(ctx);
++ xsk_put_ctx(ctx, true);
+
+ umem->refcount--;
+ /* Do not close an fd that also has an associated umem connected
--- /dev/null
+From 7d73cd946d4bc7d44cdc5121b1c61d5d71425dea Mon Sep 17 00:00:00 2001
+From: Ben Greear <greearb@candelatech.com>
+Date: Tue, 30 Mar 2021 16:07:49 -0700
+Subject: mac80211: fix time-is-after bug in mlme
+
+From: Ben Greear <greearb@candelatech.com>
+
+commit 7d73cd946d4bc7d44cdc5121b1c61d5d71425dea upstream.
+
+The incorrect timeout check caused probing to happen when it did
+not need to happen. This in turn caused tx performance drop
+for around 5 seconds in ath10k-ct driver. Possibly that tx drop
+is due to a secondary issue, but fixing the probe to not happen
+when traffic is running fixes the symptom.
+
+Signed-off-by: Ben Greear <greearb@candelatech.com>
+Fixes: 9abf4e49830d ("mac80211: optimize station connection monitor")
+Acked-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20210330230749.14097-1-greearb@candelatech.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/mlme.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4660,7 +4660,10 @@ static void ieee80211_sta_conn_mon_timer
+ timeout = sta->rx_stats.last_rx;
+ timeout += IEEE80211_CONNECTION_IDLE_TIME;
+
+- if (time_is_before_jiffies(timeout)) {
++ /* If timeout is after now, then update timer to fire at
++ * the later date, but do not actually probe at this time.
++ */
++ if (time_is_after_jiffies(timeout)) {
+ mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
+ return;
+ }
--- /dev/null
+From 1153a74768a9212daadbb50767aa400bc6a0c9b0 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 23 Mar 2021 21:05:01 +0100
+Subject: mac80211: fix TXQ AC confusion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 1153a74768a9212daadbb50767aa400bc6a0c9b0 upstream.
+
+Normally, TXQs have
+
+ txq->tid = tid;
+ txq->ac = ieee80211_ac_from_tid(tid);
+
+However, the special management TXQ actually has
+
+ txq->tid = IEEE80211_NUM_TIDS; // 16
+ txq->ac = IEEE80211_AC_VO;
+
+This makes sense, but ieee80211_ac_from_tid(16) is the same
+as ieee80211_ac_from_tid(0) which is just IEEE80211_AC_BE.
+
+Now, normally this is fine. However, if the netdev queues
+were stopped, then the code in ieee80211_tx_dequeue() will
+propagate the stop from the interface (vif->txqs_stopped[])
+if the AC 2 (ieee80211_ac_from_tid(txq->tid)) is marked as
+stopped. On wake, however, __ieee80211_wake_txqs() will wake
+the TXQ if AC 0 (txq->ac) is woken up.
+
+If a driver stops all queues with ieee80211_stop_tx_queues()
+and then wakes them again with ieee80211_wake_tx_queues(),
+the ieee80211_wake_txqs() tasklet will run to resync queue
+and TXQ state. If all queues were woken, then what'll happen
+is that _ieee80211_wake_txqs() will run in order of HW queues
+0-3, typically (and certainly for iwlwifi) corresponding to
+ACs 0-3, so it'll call __ieee80211_wake_txqs() for each AC in
+order 0-3.
+
+When __ieee80211_wake_txqs() is called for AC 0 (VO) that'll
+wake up the management TXQ (remember its tid is 16), and the
+driver's wake_tx_queue() will be called. That tries to get a
+frame, which will immediately *stop* the TXQ again, because
+now we check against AC 2, and AC 2 hasn't yet been marked as
+woken up again in sdata->vif.txqs_stopped[] since we're only
+in the __ieee80211_wake_txqs() call for AC 0.
+
+Thus, the management TXQ will never be started again.
+
+Fix this by checking txq->ac directly instead of calculating
+the AC as ieee80211_ac_from_tid(txq->tid).
+
+Fixes: adf8ed01e4fd ("mac80211: add an optional TXQ for other PS-buffered frames")
+Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Link: https://lore.kernel.org/r/20210323210500.bf4d50afea4a.I136ffde910486301f8818f5442e3c9bf8670a9c4@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -3605,7 +3605,7 @@ begin:
+ test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags))
+ goto out;
+
+- if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) {
++ if (vif->txqs_stopped[txq->ac]) {
+ set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags);
+ goto out;
+ }
--- /dev/null
+From 61431a5907fc36d0738e9a547c7e1556349a03e9 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 30 Mar 2021 16:43:43 -0700
+Subject: net: ensure mac header is set in virtio_net_hdr_to_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 61431a5907fc36d0738e9a547c7e1556349a03e9 upstream.
+
+Commit 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
+added a call to dev_parse_header_protocol() but mac_header is not yet set.
+
+This means that eth_hdr() reads complete garbage, and syzbot complained about it [1]
+
+This patch resets mac_header earlier, to get more coverage about this change.
+
+Audit of virtio_net_hdr_to_skb() callers shows that this change should be safe.
+
+[1]
+
+BUG: KASAN: use-after-free in eth_header_parse_protocol+0xdc/0xe0 net/ethernet/eth.c:282
+Read of size 2 at addr ffff888017a6200b by task syz-executor313/8409
+
+CPU: 1 PID: 8409 Comm: syz-executor313 Not tainted 5.12.0-rc2-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:79 [inline]
+ dump_stack+0x141/0x1d7 lib/dump_stack.c:120
+ print_address_description.constprop.0.cold+0x5b/0x2f8 mm/kasan/report.c:232
+ __kasan_report mm/kasan/report.c:399 [inline]
+ kasan_report.cold+0x7c/0xd8 mm/kasan/report.c:416
+ eth_header_parse_protocol+0xdc/0xe0 net/ethernet/eth.c:282
+ dev_parse_header_protocol include/linux/netdevice.h:3177 [inline]
+ virtio_net_hdr_to_skb.constprop.0+0x99d/0xcd0 include/linux/virtio_net.h:83
+ packet_snd net/packet/af_packet.c:2994 [inline]
+ packet_sendmsg+0x2325/0x52b0 net/packet/af_packet.c:3031
+ sock_sendmsg_nosec net/socket.c:654 [inline]
+ sock_sendmsg+0xcf/0x120 net/socket.c:674
+ sock_no_sendpage+0xf3/0x130 net/core/sock.c:2860
+ kernel_sendpage.part.0+0x1ab/0x350 net/socket.c:3631
+ kernel_sendpage net/socket.c:3628 [inline]
+ sock_sendpage+0xe5/0x140 net/socket.c:947
+ pipe_to_sendpage+0x2ad/0x380 fs/splice.c:364
+ splice_from_pipe_feed fs/splice.c:418 [inline]
+ __splice_from_pipe+0x43e/0x8a0 fs/splice.c:562
+ splice_from_pipe fs/splice.c:597 [inline]
+ generic_splice_sendpage+0xd4/0x140 fs/splice.c:746
+ do_splice_from fs/splice.c:767 [inline]
+ do_splice+0xb7e/0x1940 fs/splice.c:1079
+ __do_splice+0x134/0x250 fs/splice.c:1144
+ __do_sys_splice fs/splice.c:1350 [inline]
+ __se_sys_splice fs/splice.c:1332 [inline]
+ __x64_sys_splice+0x198/0x250 fs/splice.c:1332
+ do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+
+Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Balazs Nemeth <bnemeth@redhat.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/virtio_net.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -62,6 +62,8 @@ static inline int virtio_net_hdr_to_skb(
+ return -EINVAL;
+ }
+
++ skb_reset_mac_header(skb);
++
+ if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+ u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
+ u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
--- /dev/null
+From 8a12f8836145ffe37e9c8733dce18c22fb668b66 Mon Sep 17 00:00:00 2001
+From: Anirudh Rayabharam <mail@anirudhrb.com>
+Date: Wed, 7 Apr 2021 22:57:22 +0530
+Subject: net: hso: fix null-ptr-deref during tty device unregistration
+
+From: Anirudh Rayabharam <mail@anirudhrb.com>
+
+commit 8a12f8836145ffe37e9c8733dce18c22fb668b66 upstream.
+
+Multiple ttys try to claim the same the minor number causing a double
+unregistration of the same device. The first unregistration succeeds
+but the next one results in a null-ptr-deref.
+
+The get_free_serial_index() function returns an available minor number
+but doesn't assign it immediately. The assignment is done by the caller
+later. But before this assignment, calls to get_free_serial_index()
+would return the same minor number.
+
+Fix this by modifying get_free_serial_index to assign the minor number
+immediately after one is found to be and rename it to obtain_minor()
+to better reflect what it does. Similary, rename set_serial_by_index()
+to release_minor() and modify it to free up the minor number of the
+given hso_serial. Every obtain_minor() should have corresponding
+release_minor() call.
+
+Fixes: 72dc1c096c705 ("HSO: add option hso driver")
+Reported-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com
+Tested-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Anirudh Rayabharam <mail@anirudhrb.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/hso.c | 33 ++++++++++++---------------------
+ 1 file changed, 12 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/usb/hso.c
++++ b/drivers/net/usb/hso.c
+@@ -611,7 +611,7 @@ static struct hso_serial *get_serial_by_
+ return serial;
+ }
+
+-static int get_free_serial_index(void)
++static int obtain_minor(struct hso_serial *serial)
+ {
+ int index;
+ unsigned long flags;
+@@ -619,8 +619,10 @@ static int get_free_serial_index(void)
+ spin_lock_irqsave(&serial_table_lock, flags);
+ for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) {
+ if (serial_table[index] == NULL) {
++ serial_table[index] = serial->parent;
++ serial->minor = index;
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+- return index;
++ return 0;
+ }
+ }
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+@@ -629,15 +631,12 @@ static int get_free_serial_index(void)
+ return -1;
+ }
+
+-static void set_serial_by_index(unsigned index, struct hso_serial *serial)
++static void release_minor(struct hso_serial *serial)
+ {
+ unsigned long flags;
+
+ spin_lock_irqsave(&serial_table_lock, flags);
+- if (serial)
+- serial_table[index] = serial->parent;
+- else
+- serial_table[index] = NULL;
++ serial_table[serial->minor] = NULL;
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+ }
+
+@@ -2230,6 +2229,7 @@ static int hso_stop_serial_device(struct
+ static void hso_serial_tty_unregister(struct hso_serial *serial)
+ {
+ tty_unregister_device(tty_drv, serial->minor);
++ release_minor(serial);
+ }
+
+ static void hso_serial_common_free(struct hso_serial *serial)
+@@ -2253,24 +2253,22 @@ static void hso_serial_common_free(struc
+ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
+ int rx_size, int tx_size)
+ {
+- int minor;
+ int i;
+
+ tty_port_init(&serial->port);
+
+- minor = get_free_serial_index();
+- if (minor < 0)
++ if (obtain_minor(serial))
+ goto exit2;
+
+ /* register our minor number */
+ serial->parent->dev = tty_port_register_device_attr(&serial->port,
+- tty_drv, minor, &serial->parent->interface->dev,
++ tty_drv, serial->minor, &serial->parent->interface->dev,
+ serial->parent, hso_serial_dev_groups);
+- if (IS_ERR(serial->parent->dev))
++ if (IS_ERR(serial->parent->dev)) {
++ release_minor(serial);
+ goto exit2;
++ }
+
+- /* fill in specific data for later use */
+- serial->minor = minor;
+ serial->magic = HSO_SERIAL_MAGIC;
+ spin_lock_init(&serial->serial_lock);
+ serial->num_rx_urbs = num_urbs;
+@@ -2667,9 +2665,6 @@ static struct hso_device *hso_create_bul
+
+ serial->write_data = hso_std_serial_write_data;
+
+- /* and record this serial */
+- set_serial_by_index(serial->minor, serial);
+-
+ /* setup the proc dirs and files if needed */
+ hso_log_port(hso_dev);
+
+@@ -2726,9 +2721,6 @@ struct hso_device *hso_create_mux_serial
+ serial->shared_int->ref_count++;
+ mutex_unlock(&serial->shared_int->shared_int_lock);
+
+- /* and record this serial */
+- set_serial_by_index(serial->minor, serial);
+-
+ /* setup the proc dirs and files if needed */
+ hso_log_port(hso_dev);
+
+@@ -3113,7 +3105,6 @@ static void hso_free_interface(struct us
+ cancel_work_sync(&serial_table[i]->async_get_intf);
+ hso_serial_tty_unregister(serial);
+ kref_put(&serial_table[i]->ref, hso_serial_ref_free);
+- set_serial_by_index(i, NULL);
+ }
+ }
+
--- /dev/null
+From 9d6803921a16f4d768dc41a75375629828f4d91e Mon Sep 17 00:00:00 2001
+From: Kurt Kanzenbach <kurt@linutronix.de>
+Date: Tue, 6 Apr 2021 09:35:09 +0200
+Subject: net: hsr: Reset MAC header for Tx path
+
+From: Kurt Kanzenbach <kurt@linutronix.de>
+
+commit 9d6803921a16f4d768dc41a75375629828f4d91e upstream.
+
+Reset MAC header in HSR Tx path. This is needed, because direct packet
+transmission, e.g. by specifying PACKET_QDISC_BYPASS does not reset the MAC
+header.
+
+This has been observed using the following setup:
+
+|$ ip link add name hsr0 type hsr slave1 lan0 slave2 lan1 supervision 45 version 1
+|$ ifconfig hsr0 up
+|$ ./test hsr0
+
+The test binary is using mmap'ed sockets and is specifying the
+PACKET_QDISC_BYPASS socket option.
+
+This patch resolves the following warning on a non-patched kernel:
+
+|[ 112.725394] ------------[ cut here ]------------
+|[ 112.731418] WARNING: CPU: 1 PID: 257 at net/hsr/hsr_forward.c:560 hsr_forward_skb+0x484/0x568
+|[ 112.739962] net/hsr/hsr_forward.c:560: Malformed frame (port_src hsr0)
+
+The warning can be safely removed, because the other call sites of
+hsr_forward_skb() make sure that the skb is prepared correctly.
+
+Fixes: d346a3fae3ff ("packet: introduce PACKET_QDISC_BYPASS socket option")
+Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/hsr/hsr_device.c | 1 +
+ net/hsr/hsr_forward.c | 6 ------
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -217,6 +217,7 @@ static netdev_tx_t hsr_dev_xmit(struct s
+ master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
+ if (master) {
+ skb->dev = master->dev;
++ skb_reset_mac_header(skb);
+ hsr_forward_skb(skb, master);
+ } else {
+ atomic_long_inc(&dev->tx_dropped);
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -528,12 +528,6 @@ void hsr_forward_skb(struct sk_buff *skb
+ {
+ struct hsr_frame_info frame;
+
+- if (skb_mac_header(skb) != skb->data) {
+- WARN_ONCE(1, "%s:%d: Malformed frame (port_src %s)\n",
+- __FILE__, __LINE__, port->dev->name);
+- goto out_drop;
+- }
+-
+ if (fill_frame_info(&frame, skb, port) < 0)
+ goto out_drop;
+
--- /dev/null
+From 630e4576f83accf90366686f39808d665d8dbecc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= <maze@google.com>
+Date: Mon, 5 Apr 2021 00:06:52 -0700
+Subject: net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Maciej Żenczykowski <maze@google.com>
+
+commit 630e4576f83accf90366686f39808d665d8dbecc upstream.
+
+Found by virtue of ipv6 raw sockets not honouring the per-socket
+IP{,V6}_FREEBIND setting.
+
+Based on hits found via:
+ git grep '[.]ip_nonlocal_bind'
+We fix both raw ipv6 sockets to honour IP{,V6}_FREEBIND and IP{,V6}_TRANSPARENT,
+and we fix sctp sockets to honour IP{,V6}_TRANSPARENT (they already honoured
+FREEBIND), and not just the ipv6 'ip_nonlocal_bind' sysctl.
+
+The helper is defined as:
+ static inline bool ipv6_can_nonlocal_bind(struct net *net, struct inet_sock *inet) {
+ return net->ipv6.sysctl.ip_nonlocal_bind || inet->freebind || inet->transparent;
+ }
+so this change only widens the accepted opt-outs and is thus a clean bugfix.
+
+I'm not entirely sure what 'fixes' tag to add, since this is AFAICT an ancient bug,
+but IMHO this should be applied to stable kernels as far back as possible.
+As such I'm adding a 'fixes' tag with the commit that originally added the helper,
+which happened in 4.19. Backporting to older LTS kernels (at least 4.9 and 4.14)
+would presumably require open-coding it or backporting the helper as well.
+
+Other possibly relevant commits:
+ v4.18-rc6-1502-g83ba4645152d net: add helpers checking if socket can be bound to nonlocal address
+ v4.18-rc6-1431-gd0c1f01138c4 net/ipv6: allow any source address for sendmsg pktinfo with ip_nonlocal_bind
+ v4.14-rc5-271-gb71d21c274ef sctp: full support for ipv6 ip_nonlocal_bind & IP_FREEBIND
+ v4.7-rc7-1883-g9b9742022888 sctp: support ipv6 nonlocal bind
+ v4.1-12247-g35a256fee52c ipv6: Nonlocal bind
+
+Cc: Lorenzo Colitti <lorenzo@google.com>
+Fixes: 83ba4645152d ("net: add helpers checking if socket can be bound to nonlocal address")
+Signed-off-by: Maciej Żenczykowski <maze@google.com>
+Reviewed-By: Lorenzo Colitti <lorenzo@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/raw.c | 2 +-
+ net/sctp/ipv6.c | 7 +++----
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -298,7 +298,7 @@ static int rawv6_bind(struct sock *sk, s
+ */
+ v4addr = LOOPBACK4_IPV6;
+ if (!(addr_type & IPV6_ADDR_MULTICAST) &&
+- !sock_net(sk)->ipv6.sysctl.ip_nonlocal_bind) {
++ !ipv6_can_nonlocal_bind(sock_net(sk), inet)) {
+ err = -EADDRNOTAVAIL;
+ if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr,
+ dev, 0)) {
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -643,8 +643,8 @@ static int sctp_v6_available(union sctp_
+ if (!(type & IPV6_ADDR_UNICAST))
+ return 0;
+
+- return sp->inet.freebind || net->ipv6.sysctl.ip_nonlocal_bind ||
+- ipv6_chk_addr(net, in6, NULL, 0);
++ return ipv6_can_nonlocal_bind(net, &sp->inet) ||
++ ipv6_chk_addr(net, in6, NULL, 0);
+ }
+
+ /* This function checks if the address is a valid address to be used for
+@@ -933,8 +933,7 @@ static int sctp_inet6_bind_verify(struct
+ net = sock_net(&opt->inet.sk);
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id);
+- if (!dev || !(opt->inet.freebind ||
+- net->ipv6.sysctl.ip_nonlocal_bind ||
++ if (!dev || !(ipv6_can_nonlocal_bind(net, &opt->inet) ||
+ ipv6_chk_addr(net, &addr->v6.sin6_addr,
+ dev, 0))) {
+ rcu_read_unlock();
--- /dev/null
+From 9adc89af724f12a03b47099cd943ed54e877cd59 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Tue, 30 Mar 2021 18:43:54 +0200
+Subject: net: let skb_orphan_partial wake-up waiters.
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 9adc89af724f12a03b47099cd943ed54e877cd59 upstream.
+
+Currently the mentioned helper can end-up freeing the socket wmem
+without waking-up any processes waiting for more write memory.
+
+If the partially orphaned skb is attached to an UDP (or raw) socket,
+the lack of wake-up can hang the user-space.
+
+Even for TCP sockets not calling the sk destructor could have bad
+effects on TSQ.
+
+Address the issue using skb_orphan to release the sk wmem before
+setting the new sock_efree destructor. Additionally bundle the
+whole ownership update in a new helper, so that later other
+potential users could avoid duplicate code.
+
+v1 -> v2:
+ - use skb_orphan() instead of sort of open coding it (Eric)
+ - provide an helper for the ownership change (Eric)
+
+Fixes: f6ba8d33cfbb ("netem: fix skb_orphan_partial()")
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/sock.h | 9 +++++++++
+ net/core/sock.c | 12 +++---------
+ 2 files changed, 12 insertions(+), 9 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2197,6 +2197,15 @@ static inline void skb_set_owner_r(struc
+ sk_mem_charge(sk, skb->truesize);
+ }
+
++static inline void skb_set_owner_sk_safe(struct sk_buff *skb, struct sock *sk)
++{
++ if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) {
++ skb_orphan(skb);
++ skb->destructor = sock_efree;
++ skb->sk = sk;
++ }
++}
++
+ void sk_reset_timer(struct sock *sk, struct timer_list *timer,
+ unsigned long expires);
+
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2099,16 +2099,10 @@ void skb_orphan_partial(struct sk_buff *
+ if (skb_is_tcp_pure_ack(skb))
+ return;
+
+- if (can_skb_orphan_partial(skb)) {
+- struct sock *sk = skb->sk;
+-
+- if (refcount_inc_not_zero(&sk->sk_refcnt)) {
+- WARN_ON(refcount_sub_and_test(skb->truesize, &sk->sk_wmem_alloc));
+- skb->destructor = sock_efree;
+- }
+- } else {
++ if (can_skb_orphan_partial(skb))
++ skb_set_owner_sk_safe(skb, skb->sk);
++ else
+ skb_orphan(skb);
+- }
+ }
+ EXPORT_SYMBOL(skb_orphan_partial);
+
--- /dev/null
+From 87c750e8c38bce706eb32e4d8f1e3402f2cebbd4 Mon Sep 17 00:00:00 2001
+From: Vlad Buslov <vladbu@nvidia.com>
+Date: Wed, 7 Apr 2021 18:36:03 +0300
+Subject: net: sched: fix action overwrite reference counting
+
+From: Vlad Buslov <vladbu@nvidia.com>
+
+commit 87c750e8c38bce706eb32e4d8f1e3402f2cebbd4 upstream.
+
+Action init code increments reference counter when it changes an action.
+This is the desired behavior for cls API which needs to obtain action
+reference for every classifier that points to action. However, act API just
+needs to change the action and releases the reference before returning.
+This sequence breaks when the requested action doesn't exist, which causes
+act API init code to create new action with specified index, but action is
+still released before returning and is deleted (unless it was referenced
+concurrently by cls API).
+
+Reproduction:
+
+$ sudo tc actions ls action gact
+$ sudo tc actions change action gact drop index 1
+$ sudo tc actions ls action gact
+
+Extend tcf_action_init() to accept 'init_res' array and initialize it with
+action->ops->init() result. In tcf_action_add() remove pointers to created
+actions from actions array before passing it to tcf_action_put_many().
+
+Fixes: cae422f379f3 ("net: sched: use reference counting action init")
+Reported-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
+Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/act_api.h | 5 +++--
+ net/sched/act_api.c | 22 +++++++++++++++-------
+ net/sched/cls_api.c | 9 +++++----
+ 3 files changed, 23 insertions(+), 13 deletions(-)
+
+--- a/include/net/act_api.h
++++ b/include/net/act_api.h
+@@ -185,7 +185,7 @@ int tcf_action_exec(struct sk_buff *skb,
+ int nr_actions, struct tcf_result *res);
+ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
+ struct nlattr *est, char *name, int ovr, int bind,
+- struct tc_action *actions[], size_t *attr_size,
++ struct tc_action *actions[], int init_res[], size_t *attr_size,
+ bool rtnl_held, struct netlink_ext_ack *extack);
+ struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
+ bool rtnl_held,
+@@ -193,7 +193,8 @@ struct tc_action_ops *tc_action_load_ops
+ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
+ struct nlattr *nla, struct nlattr *est,
+ char *name, int ovr, int bind,
+- struct tc_action_ops *ops, bool rtnl_held,
++ struct tc_action_ops *a_o, int *init_res,
++ bool rtnl_held,
+ struct netlink_ext_ack *extack);
+ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind,
+ int ref, bool terse);
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -972,7 +972,8 @@ struct tc_action_ops *tc_action_load_ops
+ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
+ struct nlattr *nla, struct nlattr *est,
+ char *name, int ovr, int bind,
+- struct tc_action_ops *a_o, bool rtnl_held,
++ struct tc_action_ops *a_o, int *init_res,
++ bool rtnl_held,
+ struct netlink_ext_ack *extack)
+ {
+ struct nla_bitfield32 flags = { 0, 0 };
+@@ -1008,6 +1009,7 @@ struct tc_action *tcf_action_init_1(stru
+ }
+ if (err < 0)
+ goto err_out;
++ *init_res = err;
+
+ if (!name && tb[TCA_ACT_COOKIE])
+ tcf_set_action_cookie(&a->act_cookie, cookie);
+@@ -1036,7 +1038,7 @@ err_out:
+
+ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
+ struct nlattr *est, char *name, int ovr, int bind,
+- struct tc_action *actions[], size_t *attr_size,
++ struct tc_action *actions[], int init_res[], size_t *attr_size,
+ bool rtnl_held, struct netlink_ext_ack *extack)
+ {
+ struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {};
+@@ -1064,7 +1066,8 @@ int tcf_action_init(struct net *net, str
+
+ for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+ act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
+- ops[i - 1], rtnl_held, extack);
++ ops[i - 1], &init_res[i - 1], rtnl_held,
++ extack);
+ if (IS_ERR(act)) {
+ err = PTR_ERR(act);
+ goto err;
+@@ -1477,12 +1480,13 @@ static int tcf_action_add(struct net *ne
+ struct netlink_ext_ack *extack)
+ {
+ size_t attr_size = 0;
+- int loop, ret;
++ int loop, ret, i;
+ struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
++ int init_res[TCA_ACT_MAX_PRIO] = {};
+
+ for (loop = 0; loop < 10; loop++) {
+ ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0,
+- actions, &attr_size, true, extack);
++ actions, init_res, &attr_size, true, extack);
+ if (ret != -EAGAIN)
+ break;
+ }
+@@ -1490,8 +1494,12 @@ static int tcf_action_add(struct net *ne
+ if (ret < 0)
+ return ret;
+ ret = tcf_add_notify(net, n, actions, portid, attr_size, extack);
+- if (ovr)
+- tcf_action_put_many(actions);
++
++ /* only put existing actions */
++ for (i = 0; i < TCA_ACT_MAX_PRIO; i++)
++ if (init_res[i] == ACT_P_CREATED)
++ actions[i] = NULL;
++ tcf_action_put_many(actions);
+
+ return ret;
+ }
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3051,6 +3051,7 @@ int tcf_exts_validate(struct net *net, s
+ {
+ #ifdef CONFIG_NET_CLS_ACT
+ {
++ int init_res[TCA_ACT_MAX_PRIO] = {};
+ struct tc_action *act;
+ size_t attr_size = 0;
+
+@@ -3062,8 +3063,8 @@ int tcf_exts_validate(struct net *net, s
+ return PTR_ERR(a_o);
+ act = tcf_action_init_1(net, tp, tb[exts->police],
+ rate_tlv, "police", ovr,
+- TCA_ACT_BIND, a_o, rtnl_held,
+- extack);
++ TCA_ACT_BIND, a_o, init_res,
++ rtnl_held, extack);
+ if (IS_ERR(act)) {
+ module_put(a_o->owner);
+ return PTR_ERR(act);
+@@ -3078,8 +3079,8 @@ int tcf_exts_validate(struct net *net, s
+
+ err = tcf_action_init(net, tp, tb[exts->action],
+ rate_tlv, NULL, ovr, TCA_ACT_BIND,
+- exts->actions, &attr_size,
+- rtnl_held, extack);
++ exts->actions, init_res,
++ &attr_size, rtnl_held, extack);
+ if (err < 0)
+ return err;
+ exts->nr_actions = err;
--- /dev/null
+From 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e Mon Sep 17 00:00:00 2001
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Date: Thu, 8 Apr 2021 18:14:31 +0300
+Subject: net: sched: sch_teql: fix null-pointer dereference
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+commit 1ffbc7ea91606e4abd10eb60de5367f1c86daf5e upstream.
+
+Reproduce:
+
+ modprobe sch_teql
+ tc qdisc add dev teql0 root teql0
+
+This leads to (for instance in Centos 7 VM) OOPS:
+
+[ 532.366633] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8
+[ 532.366733] IP: [<ffffffffc06124a8>] teql_destroy+0x18/0x100 [sch_teql]
+[ 532.366825] PGD 80000001376d5067 PUD 137e37067 PMD 0
+[ 532.366906] Oops: 0000 [#1] SMP
+[ 532.366987] Modules linked in: sch_teql ...
+[ 532.367945] CPU: 1 PID: 3026 Comm: tc Kdump: loaded Tainted: G ------------ T 3.10.0-1062.7.1.el7.x86_64 #1
+[ 532.368041] Hardware name: Virtuozzo KVM, BIOS 1.11.0-2.vz7.2 04/01/2014
+[ 532.368125] task: ffff8b7d37d31070 ti: ffff8b7c9fdbc000 task.ti: ffff8b7c9fdbc000
+[ 532.368224] RIP: 0010:[<ffffffffc06124a8>] [<ffffffffc06124a8>] teql_destroy+0x18/0x100 [sch_teql]
+[ 532.368320] RSP: 0018:ffff8b7c9fdbf8e0 EFLAGS: 00010286
+[ 532.368394] RAX: ffffffffc0612490 RBX: ffff8b7cb1565e00 RCX: ffff8b7d35ba2000
+[ 532.368476] RDX: ffff8b7d35ba2000 RSI: 0000000000000000 RDI: ffff8b7cb1565e00
+[ 532.368557] RBP: ffff8b7c9fdbf8f8 R08: ffff8b7d3fd1f140 R09: ffff8b7d3b001600
+[ 532.368638] R10: ffff8b7d3b001600 R11: ffffffff84c7d65b R12: 00000000ffffffd8
+[ 532.368719] R13: 0000000000008000 R14: ffff8b7d35ba2000 R15: ffff8b7c9fdbf9a8
+[ 532.368800] FS: 00007f6a4e872740(0000) GS:ffff8b7d3fd00000(0000) knlGS:0000000000000000
+[ 532.368885] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 532.368961] CR2: 00000000000000a8 CR3: 00000001396ee000 CR4: 00000000000206e0
+[ 532.369046] Call Trace:
+[ 532.369159] [<ffffffff84c8192e>] qdisc_create+0x36e/0x450
+[ 532.369268] [<ffffffff846a9b49>] ? ns_capable+0x29/0x50
+[ 532.369366] [<ffffffff849afde2>] ? nla_parse+0x32/0x120
+[ 532.369442] [<ffffffff84c81b4c>] tc_modify_qdisc+0x13c/0x610
+[ 532.371508] [<ffffffff84c693e7>] rtnetlink_rcv_msg+0xa7/0x260
+[ 532.372668] [<ffffffff84907b65>] ? sock_has_perm+0x75/0x90
+[ 532.373790] [<ffffffff84c69340>] ? rtnl_newlink+0x890/0x890
+[ 532.374914] [<ffffffff84c8da7b>] netlink_rcv_skb+0xab/0xc0
+[ 532.376055] [<ffffffff84c63708>] rtnetlink_rcv+0x28/0x30
+[ 532.377204] [<ffffffff84c8d400>] netlink_unicast+0x170/0x210
+[ 532.378333] [<ffffffff84c8d7a8>] netlink_sendmsg+0x308/0x420
+[ 532.379465] [<ffffffff84c2f3a6>] sock_sendmsg+0xb6/0xf0
+[ 532.380710] [<ffffffffc034a56e>] ? __xfs_filemap_fault+0x8e/0x1d0 [xfs]
+[ 532.381868] [<ffffffffc034a75c>] ? xfs_filemap_fault+0x2c/0x30 [xfs]
+[ 532.383037] [<ffffffff847ec23a>] ? __do_fault.isra.61+0x8a/0x100
+[ 532.384144] [<ffffffff84c30269>] ___sys_sendmsg+0x3e9/0x400
+[ 532.385268] [<ffffffff847f3fad>] ? handle_mm_fault+0x39d/0x9b0
+[ 532.386387] [<ffffffff84d88678>] ? __do_page_fault+0x238/0x500
+[ 532.387472] [<ffffffff84c31921>] __sys_sendmsg+0x51/0x90
+[ 532.388560] [<ffffffff84c31972>] SyS_sendmsg+0x12/0x20
+[ 532.389636] [<ffffffff84d8dede>] system_call_fastpath+0x25/0x2a
+[ 532.390704] [<ffffffff84d8de21>] ? system_call_after_swapgs+0xae/0x146
+[ 532.391753] Code: 00 00 00 00 00 00 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 e5 41 55 41 54 53 48 8b b7 48 01 00 00 48 89 fb <48> 8b 8e a8 00 00 00 48 85 c9 74 43 48 89 ca eb 0f 0f 1f 80 00
+[ 532.394036] RIP [<ffffffffc06124a8>] teql_destroy+0x18/0x100 [sch_teql]
+[ 532.395127] RSP <ffff8b7c9fdbf8e0>
+[ 532.396179] CR2: 00000000000000a8
+
+Null pointer dereference happens on master->slaves dereference in
+teql_destroy() as master is null-pointer.
+
+When qdisc_create() calls teql_qdisc_init() it imediately fails after
+check "if (m->dev == dev)" because both devices are teql0, and it does
+not set qdisc_priv(sch)->m leaving it zero on error path, then
+qdisc_create() imediately calls teql_destroy() which does not expect
+zero master pointer and we get OOPS.
+
+Fixes: 87b60cfacf9f ("net_sched: fix error recovery at qdisc creation")
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/sch_teql.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/sched/sch_teql.c
++++ b/net/sched/sch_teql.c
+@@ -134,6 +134,9 @@ teql_destroy(struct Qdisc *sch)
+ struct teql_sched_data *dat = qdisc_priv(sch);
+ struct teql_master *master = dat->m;
+
++ if (!master)
++ return;
++
+ prev = master->slaves;
+ if (prev) {
+ do {
--- /dev/null
+From 9a6847ba1747858ccac53c5aba3e25c54fbdf846 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 8 Apr 2021 15:45:20 +0200
+Subject: nl80211: fix beacon head validation
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 9a6847ba1747858ccac53c5aba3e25c54fbdf846 upstream.
+
+If the beacon head attribute (NL80211_ATTR_BEACON_HEAD)
+is too short to even contain the frame control field,
+we access uninitialized data beyond the buffer. Fix this
+by checking the minimal required size first. We used to
+do this until S1G support was added, where the fixed
+data portion has a different size.
+
+Reported-and-tested-by: syzbot+72b99dcf4607e8c770f3@syzkaller.appspotmail.com
+Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Fixes: 1d47f1198d58 ("nl80211: correctly validate S1G beacon head")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Link: https://lore.kernel.org/r/20210408154518.d9b06d39b4ee.Iff908997b2a4067e8d456b3cb96cab9771d252b8@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/nl80211.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -209,9 +209,13 @@ static int validate_beacon_head(const st
+ unsigned int len = nla_len(attr);
+ const struct element *elem;
+ const struct ieee80211_mgmt *mgmt = (void *)data;
+- bool s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
+ unsigned int fixedlen, hdrlen;
++ bool s1g_bcn;
+
++ if (len < offsetofend(typeof(*mgmt), frame_control))
++ goto err;
++
++ s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
+ if (s1g_bcn) {
+ fixedlen = offsetof(struct ieee80211_ext,
+ u.s1g_beacon.variable);
--- /dev/null
+From abaf94ecc9c356d0b885a84edef4905cdd89cfdd Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 8 Apr 2021 14:28:34 +0200
+Subject: nl80211: fix potential leak of ACL params
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit abaf94ecc9c356d0b885a84edef4905cdd89cfdd upstream.
+
+In case nl80211_parse_unsol_bcast_probe_resp() results in an
+error, need to "goto out" instead of just returning to free
+possibly allocated data.
+
+Fixes: 7443dcd1f171 ("nl80211: Unsolicited broadcast probe response support")
+Link: https://lore.kernel.org/r/20210408142833.d8bc2e2e454a.If290b1ba85789726a671ff0b237726d4851b5b0f@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/nl80211.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -5,7 +5,7 @@
+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2013-2014 Intel Mobile Communications GmbH
+ * Copyright 2015-2017 Intel Deutschland GmbH
+- * Copyright (C) 2018-2020 Intel Corporation
++ * Copyright (C) 2018-2021 Intel Corporation
+ */
+
+ #include <linux/if.h>
+@@ -5324,7 +5324,7 @@ static int nl80211_start_ap(struct sk_bu
+ rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
+ ¶ms);
+ if (err)
+- return err;
++ goto out;
+ }
+
+ nl80211_calculate_ap_params(¶ms);
parisc-parisc-agp-requires-sba-iommu-driver.patch
parisc-avoid-a-warning-on-u8-cast-for-cmpxchg-on-u8-pointers.patch
arm-dts-turris-omnia-configure-led-intn-pin-as-interrupt-pin.patch
+batman-adv-initialize-struct-batadv_tvlv_tt_vlan_data-reserved-field.patch
+ice-continue-probe-on-link-phy-errors.patch
+ice-increase-control-queue-timeout.patch
+ice-prevent-ice_open-and-ice_stop-during-reset.patch
+ice-fix-memory-allocation-call.patch
+ice-remove-dcbnl_devreset-bit-from-pf-state.patch
+ice-fix-for-dereference-of-null-pointer.patch
+ice-use-port-number-instead-of-pf-id-for-wol.patch
+ice-cleanup-fltr-list-in-case-of-allocation-issues.patch
+iwlwifi-pcie-properly-set-ltr-workarounds-on-22000-devices.patch
+ice-fix-memory-leak-of-arfs-after-resuming-from-suspend.patch
+net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch
+libbpf-fix-bail-out-from-ringbuf_process_ring-on-error.patch
+bpf-enforce-that-struct_ops-programs-be-gpl-only.patch
+bpf-link-refuse-non-o_rdwr-flags-in-bpf_obj_get.patch
+ethernet-netronome-nfp-fix-a-use-after-free-in-nfp_bpf_ctrl_msg_rx.patch
+libbpf-ensure-umem-pointer-is-non-null-before-dereferencing.patch
+libbpf-restore-umem-state-after-socket-create-failure.patch
+libbpf-only-create-rx-and-tx-xdp-rings-when-necessary.patch
+bpf-refcount-task-stack-in-bpf_get_task_stack.patch
+bpf-sockmap-fix-sk-prot-unhash-op-reset.patch
+bpf-sockmap-fix-incorrect-fwd_alloc-accounting.patch
+net-ensure-mac-header-is-set-in-virtio_net_hdr_to_skb.patch
+virtio_net-do-not-pull-payload-in-skb-head.patch
+i40e-fix-sparse-warning-missing-error-code-err.patch
+i40e-fix-sparse-error-vsi-netdev-could-be-null.patch
+i40e-fix-sparse-error-uninitialized-symbol-ring.patch
+i40e-fix-sparse-errors-in-i40e_txrx.c.patch
+vdpa-mlx5-fix-suspend-resume-index-restoration.patch
+net-sched-sch_teql-fix-null-pointer-dereference.patch
+net-sched-fix-action-overwrite-reference-counting.patch
+nl80211-fix-beacon-head-validation.patch
+nl80211-fix-potential-leak-of-acl-params.patch
+cfg80211-check-s1g-beacon-compat-element-length.patch
+mac80211-fix-time-is-after-bug-in-mlme.patch
+mac80211-fix-txq-ac-confusion.patch
+net-hsr-reset-mac-header-for-tx-path.patch
+net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch
+net-let-skb_orphan_partial-wake-up-waiters.patch
--- /dev/null
+From bc04d93ea30a0a8eb2a2648b848cef35d1f6f798 Mon Sep 17 00:00:00 2001
+From: Eli Cohen <elic@nvidia.com>
+Date: Thu, 8 Apr 2021 12:10:47 +0300
+Subject: vdpa/mlx5: Fix suspend/resume index restoration
+
+From: Eli Cohen <elic@nvidia.com>
+
+commit bc04d93ea30a0a8eb2a2648b848cef35d1f6f798 upstream.
+
+When we suspend the VM, the VDPA interface will be reset. When the VM is
+resumed again, clear_virtqueues() will clear the available and used
+indices resulting in hardware virqtqueue objects becoming out of sync.
+We can avoid this function alltogether since qemu will clear them if
+required, e.g. when the VM went through a reboot.
+
+Moreover, since the hw available and used indices should always be
+identical on query and should be restored to the same value same value
+for virtqueues that complete in order, we set the single value provided
+by set_vq_state(). In get_vq_state() we return the value of hardware
+used index.
+
+Fixes: b35ccebe3ef7 ("vdpa/mlx5: Restore the hardware used index after change map")
+Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices")
+Signed-off-by: Eli Cohen <elic@nvidia.com>
+Link: https://lore.kernel.org/r/20210408091047.4269-6-elic@nvidia.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vdpa/mlx5/net/mlx5_vnet.c | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+@@ -1154,6 +1154,7 @@ static void suspend_vq(struct mlx5_vdpa_
+ return;
+ }
+ mvq->avail_idx = attr.available_index;
++ mvq->used_idx = attr.used_index;
+ }
+
+ static void suspend_vqs(struct mlx5_vdpa_net *ndev)
+@@ -1411,6 +1412,7 @@ static int mlx5_vdpa_set_vq_state(struct
+ return -EINVAL;
+ }
+
++ mvq->used_idx = state->avail_index;
+ mvq->avail_idx = state->avail_index;
+ return 0;
+ }
+@@ -1428,7 +1430,11 @@ static int mlx5_vdpa_get_vq_state(struct
+ * that cares about emulating the index after vq is stopped.
+ */
+ if (!mvq->initialized) {
+- state->avail_index = mvq->avail_idx;
++ /* Firmware returns a wrong value for the available index.
++ * Since both values should be identical, we take the value of
++ * used_idx which is reported correctly.
++ */
++ state->avail_index = mvq->used_idx;
+ return 0;
+ }
+
+@@ -1437,7 +1443,7 @@ static int mlx5_vdpa_get_vq_state(struct
+ mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
+ return err;
+ }
+- state->avail_index = attr.available_index;
++ state->avail_index = attr.used_index;
+ return 0;
+ }
+
+@@ -1525,16 +1531,6 @@ static void teardown_virtqueues(struct m
+ }
+ }
+
+-static void clear_virtqueues(struct mlx5_vdpa_net *ndev)
+-{
+- int i;
+-
+- for (i = ndev->mvdev.max_vqs - 1; i >= 0; i--) {
+- ndev->vqs[i].avail_idx = 0;
+- ndev->vqs[i].used_idx = 0;
+- }
+-}
+-
+ /* TODO: cross-endian support */
+ static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
+ {
+@@ -1770,7 +1766,6 @@ static void mlx5_vdpa_set_status(struct
+ if (!status) {
+ mlx5_vdpa_info(mvdev, "performing device reset\n");
+ teardown_driver(ndev);
+- clear_virtqueues(ndev);
+ mlx5_vdpa_destroy_mr(&ndev->mvdev);
+ ndev->mvdev.status = 0;
+ ndev->mvdev.mlx_features = 0;
--- /dev/null
+From 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 2 Apr 2021 06:26:02 -0700
+Subject: virtio_net: Do not pull payload in skb->head
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 0f6925b3e8da0dbbb52447ca8a8b42b371aac7db upstream.
+
+Xuan Zhuo reported that commit 3226b158e67c ("net: avoid 32 x truesize
+under-estimation for tiny skbs") brought a ~10% performance drop.
+
+The reason for the performance drop was that GRO was forced
+to chain sk_buff (using skb_shinfo(skb)->frag_list), which
+uses more memory but also cause packet consumers to go over
+a lot of overhead handling all the tiny skbs.
+
+It turns out that virtio_net page_to_skb() has a wrong strategy :
+It allocates skbs with GOOD_COPY_LEN (128) bytes in skb->head, then
+copies 128 bytes from the page, before feeding the packet to GRO stack.
+
+This was suboptimal before commit 3226b158e67c ("net: avoid 32 x truesize
+under-estimation for tiny skbs") because GRO was using 2 frags per MSS,
+meaning we were not packing MSS with 100% efficiency.
+
+Fix is to pull only the ethernet header in page_to_skb()
+
+Then, we change virtio_net_hdr_to_skb() to pull the missing
+headers, instead of assuming they were already pulled by callers.
+
+This fixes the performance regression, but could also allow virtio_net
+to accept packets with more than 128bytes of headers.
+
+Many thanks to Xuan Zhuo for his report, and his tests/help.
+
+Fixes: 3226b158e67c ("net: avoid 32 x truesize under-estimation for tiny skbs")
+Reported-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Link: https://www.spinics.net/lists/netdev/msg731397.html
+Co-Developed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: virtualization@lists.linux-foundation.org
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c | 10 +++++++---
+ include/linux/virtio_net.h | 14 +++++++++-----
+ 2 files changed, 16 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -406,9 +406,13 @@ static struct sk_buff *page_to_skb(struc
+ offset += hdr_padded_len;
+ p += hdr_padded_len;
+
+- copy = len;
+- if (copy > skb_tailroom(skb))
+- copy = skb_tailroom(skb);
++ /* Copy all frame if it fits skb->head, otherwise
++ * we let virtio_net_hdr_to_skb() and GRO pull headers as needed.
++ */
++ if (len <= skb_tailroom(skb))
++ copy = len;
++ else
++ copy = ETH_HLEN + metasize;
+ skb_put_data(skb, p, copy);
+
+ if (metasize) {
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -65,14 +65,18 @@ static inline int virtio_net_hdr_to_skb(
+ skb_reset_mac_header(skb);
+
+ if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+- u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
+- u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
++ u32 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
++ u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
++ u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16));
++
++ if (!pskb_may_pull(skb, needed))
++ return -EINVAL;
+
+ if (!skb_partial_csum_set(skb, start, off))
+ return -EINVAL;
+
+ p_off = skb_transport_offset(skb) + thlen;
+- if (p_off > skb_headlen(skb))
++ if (!pskb_may_pull(skb, p_off))
+ return -EINVAL;
+ } else {
+ /* gso packets without NEEDS_CSUM do not set transport_offset.
+@@ -102,14 +106,14 @@ retry:
+ }
+
+ p_off = keys.control.thoff + thlen;
+- if (p_off > skb_headlen(skb) ||
++ if (!pskb_may_pull(skb, p_off) ||
+ keys.basic.ip_proto != ip_proto)
+ return -EINVAL;
+
+ skb_set_transport_header(skb, keys.control.thoff);
+ } else if (gso_type) {
+ p_off = thlen;
+- if (p_off > skb_headlen(skb))
++ if (!pskb_may_pull(skb, p_off))
+ return -EINVAL;
+ }
+ }