]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.8
authorSasha Levin <sashal@kernel.org>
Mon, 12 Oct 2020 02:46:07 +0000 (22:46 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 12 Oct 2020 02:46:07 +0000 (22:46 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
60 files changed:
queue-5.8/afs-fix-deadlock-between-writeback-and-truncate.patch [new file with mode: 0644]
queue-5.8/bonding-set-dev-needed_headroom-in-bond_setup_by_sla.patch [new file with mode: 0644]
queue-5.8/hinic-add-log-in-exception-handling-processes.patch [new file with mode: 0644]
queue-5.8/hinic-fix-wrong-return-value-of-mac-set-cmd.patch [new file with mode: 0644]
queue-5.8/i2c-meson-fix-clock-setting-overwrite.patch-20597 [new file with mode: 0644]
queue-5.8/iavf-fix-incorrect-adapter-get-in-iavf_resume.patch [new file with mode: 0644]
queue-5.8/iavf-use-generic-power-management.patch [new file with mode: 0644]
queue-5.8/ice-fix-memory-leak-if-register_netdev_fails.patch [new file with mode: 0644]
queue-5.8/ice-fix-memory-leak-in-ice_vsi_setup.patch [new file with mode: 0644]
queue-5.8/mdio-fix-mdio-thunder.c-dependency-build-error.patch [new file with mode: 0644]
queue-5.8/mlxsw-spectrum_acl-fix-mlxsw_sp_acl_tcam_group_add-s.patch [new file with mode: 0644]
queue-5.8/mmc-core-don-t-set-limits.discard_granularity-as-0.patch [new file with mode: 0644]
queue-5.8/net-dsa-felix-convert-tas-link-speed-based-on-phylin.patch [new file with mode: 0644]
queue-5.8/net-ethernet-cavium-octeon_mgmt-use-phy_start-and-ph.patch [new file with mode: 0644]
queue-5.8/net-hinic-fix-devlink-build-errors.patch [new file with mode: 0644]
queue-5.8/net-mlx5-add-retry-mechanism-to-the-command-entry-in.patch [new file with mode: 0644]
queue-5.8/net-mlx5-avoid-possible-free-of-command-entry-while-.patch [new file with mode: 0644]
queue-5.8/net-mlx5-fix-a-race-when-moving-command-interface-to.patch [new file with mode: 0644]
queue-5.8/net-mlx5-fix-request_irqs-error-flow.patch [new file with mode: 0644]
queue-5.8/net-mlx5-poll-cmd-eq-in-case-of-command-timeout.patch [new file with mode: 0644]
queue-5.8/net-mlx5e-add-resiliency-in-striding-rq-mode-for-pac.patch [new file with mode: 0644]
queue-5.8/net-mlx5e-fix-race-condition-on-nhe-n-pointer-in-nei.patch [new file with mode: 0644]
queue-5.8/net-mlx5e-fix-return-status-when-setting-unsupported.patch [new file with mode: 0644]
queue-5.8/net-mlx5e-fix-vlan-cleanup-flow.patch [new file with mode: 0644]
queue-5.8/net-mlx5e-fix-vlan-create-flow.patch [new file with mode: 0644]
queue-5.8/net-mscc-ocelot-divide-watermark-value-by-60-when-wr.patch [new file with mode: 0644]
queue-5.8/net-mscc-ocelot-extend-watermark-encoding-function.patch [new file with mode: 0644]
queue-5.8/net-mscc-ocelot-rename-ocelot_board.c-to-ocelot_vsc7.patch [new file with mode: 0644]
queue-5.8/net-mscc-ocelot-split-writes-to-pause-frame-enable-b.patch [new file with mode: 0644]
queue-5.8/net-mvneta-fix-double-free-of-txq-buf.patch [new file with mode: 0644]
queue-5.8/net-phy-realtek-fix-rtl8211e-rx-tx-delay-config.patch [new file with mode: 0644]
queue-5.8/net-stmmac-fix-clock-handling-on-remove-path.patch [new file with mode: 0644]
queue-5.8/net-stmmac-modify-configuration-method-of-eee-timers.patch [new file with mode: 0644]
queue-5.8/net-stmmac-removed-enabling-eee-in-eee-set-callback.patch [new file with mode: 0644]
queue-5.8/net-usb-ax88179_178a-fix-missing-stop-entry-in-drive.patch [new file with mode: 0644]
queue-5.8/octeontx2-af-fix-enable-disable-of-default-npc-entri.patch [new file with mode: 0644]
queue-5.8/octeontx2-pf-fix-synchnorization-issue-in-mbox.patch [new file with mode: 0644]
queue-5.8/octeontx2-pf-fix-tcp-udp-checksum-offload-for-ipv6-f.patch [new file with mode: 0644]
queue-5.8/octeontx2-pf-fix-the-device-state-on-error.patch [new file with mode: 0644]
queue-5.8/perf-fix-task_function_call-error-handling.patch [new file with mode: 0644]
queue-5.8/pipe-fix-memory-leaks-in-create_pipe_files.patch [new file with mode: 0644]
queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-fuji.patch [new file with mode: 0644]
queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-lg_l.patch [new file with mode: 0644]
queue-5.8/r8169-fix-rtl8168f-rtl8411-ephy-config.patch [new file with mode: 0644]
queue-5.8/rxrpc-downgrade-the-bug-for-unsupported-token-type-i.patch [new file with mode: 0644]
queue-5.8/rxrpc-fix-rxkad-token-xdr-encoding.patch [new file with mode: 0644]
queue-5.8/rxrpc-fix-server-keyring-leak.patch [new file with mode: 0644]
queue-5.8/rxrpc-fix-some-missing-_bh-annotations-on-locking-co.patch [new file with mode: 0644]
queue-5.8/rxrpc-the-server-keyring-isn-t-network-namespaced.patch [new file with mode: 0644]
queue-5.8/series
queue-5.8/vhost-vdpa-fix-page-pinning-leakage-in-error-path.patch [new file with mode: 0644]
queue-5.8/vhost-vdpa-fix-vhost_vdpa_map-on-error-condition.patch [new file with mode: 0644]
queue-5.8/virtio-net-don-t-disable-guest-csum-when-disable-lro.patch [new file with mode: 0644]
queue-5.8/vmxnet3-fix-cksum-offload-issues-for-non-udp-tunnels.patch [new file with mode: 0644]
queue-5.8/xfrm-clone-whole-liftime_cur-structure-in-xfrm_do_mi.patch [new file with mode: 0644]
queue-5.8/xfrm-clone-xfrma_replay_esn_val-in-xfrm_do_migrate.patch [new file with mode: 0644]
queue-5.8/xfrm-clone-xfrma_sec_ctx-in-xfrm_do_migrate.patch [new file with mode: 0644]
queue-5.8/xfrm-clone-xfrma_set_mark-in-xfrm_do_migrate.patch [new file with mode: 0644]
queue-5.8/xfrm-use-correct-address-family-in-xfrm_state_find.patch [new file with mode: 0644]
queue-5.8/xsk-do-not-discard-packet-when-netdev_tx_busy.patch [new file with mode: 0644]

diff --git a/queue-5.8/afs-fix-deadlock-between-writeback-and-truncate.patch b/queue-5.8/afs-fix-deadlock-between-writeback-and-truncate.patch
new file mode 100644 (file)
index 0000000..4a5df37
--- /dev/null
@@ -0,0 +1,240 @@
+From 6363cd4a14c1bf4eed3d9e9266152249da6eb41f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Oct 2020 14:22:12 +0100
+Subject: afs: Fix deadlock between writeback and truncate
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit ec0fa0b659144d9c68204d23f627b6a65fa53e50 ]
+
+The afs filesystem has a lock[*] that it uses to serialise I/O operations
+going to the server (vnode->io_lock), as the server will only perform one
+modification operation at a time on any given file or directory.  This
+prevents the the filesystem from filling up all the call slots to a server
+with calls that aren't going to be executed in parallel anyway, thereby
+allowing operations on other files to obtain slots.
+
+  [*] Note that is probably redundant for directories at least since
+      i_rwsem is used to serialise directory modifications and
+      lookup/reading vs modification.  The server does allow parallel
+      non-modification ops, however.
+
+When a file truncation op completes, we truncate the in-memory copy of the
+file to match - but we do it whilst still holding the io_lock, the idea
+being to prevent races with other operations.
+
+However, if writeback starts in a worker thread simultaneously with
+truncation (whilst notify_change() is called with i_rwsem locked, writeback
+pays it no heed), it may manage to set PG_writeback bits on the pages that
+will get truncated before afs_setattr_success() manages to call
+truncate_pagecache().  Truncate will then wait for those pages - whilst
+still inside io_lock:
+
+    # cat /proc/8837/stack
+    [<0>] wait_on_page_bit_common+0x184/0x1e7
+    [<0>] truncate_inode_pages_range+0x37f/0x3eb
+    [<0>] truncate_pagecache+0x3c/0x53
+    [<0>] afs_setattr_success+0x4d/0x6e
+    [<0>] afs_wait_for_operation+0xd8/0x169
+    [<0>] afs_do_sync_operation+0x16/0x1f
+    [<0>] afs_setattr+0x1fb/0x25d
+    [<0>] notify_change+0x2cf/0x3c4
+    [<0>] do_truncate+0x7f/0xb2
+    [<0>] do_sys_ftruncate+0xd1/0x104
+    [<0>] do_syscall_64+0x2d/0x3a
+    [<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+The writeback operation, however, stalls indefinitely because it needs to
+get the io_lock to proceed:
+
+    # cat /proc/5940/stack
+    [<0>] afs_get_io_locks+0x58/0x1ae
+    [<0>] afs_begin_vnode_operation+0xc7/0xd1
+    [<0>] afs_store_data+0x1b2/0x2a3
+    [<0>] afs_write_back_from_locked_page+0x418/0x57c
+    [<0>] afs_writepages_region+0x196/0x224
+    [<0>] afs_writepages+0x74/0x156
+    [<0>] do_writepages+0x2d/0x56
+    [<0>] __writeback_single_inode+0x84/0x207
+    [<0>] writeback_sb_inodes+0x238/0x3cf
+    [<0>] __writeback_inodes_wb+0x68/0x9f
+    [<0>] wb_writeback+0x145/0x26c
+    [<0>] wb_do_writeback+0x16a/0x194
+    [<0>] wb_workfn+0x74/0x177
+    [<0>] process_one_work+0x174/0x264
+    [<0>] worker_thread+0x117/0x1b9
+    [<0>] kthread+0xec/0xf1
+    [<0>] ret_from_fork+0x1f/0x30
+
+and thus deadlock has occurred.
+
+Note that whilst afs_setattr() calls filemap_write_and_wait(), the fact
+that the caller is holding i_rwsem doesn't preclude more pages being
+dirtied through an mmap'd region.
+
+Fix this by:
+
+ (1) Use the vnode validate_lock to mediate access between afs_setattr()
+     and afs_writepages():
+
+     (a) Exclusively lock validate_lock in afs_setattr() around the whole
+        RPC operation.
+
+     (b) If WB_SYNC_ALL isn't set on entry to afs_writepages(), trying to
+        shared-lock validate_lock and returning immediately if we couldn't
+        get it.
+
+     (c) If WB_SYNC_ALL is set, wait for the lock.
+
+     The validate_lock is also used to validate a file and to zap its cache
+     if the file was altered by a third party, so it's probably a good fit
+     for this.
+
+ (2) Move the truncation outside of the io_lock in setattr, using the same
+     hook as is used for local directory editing.
+
+     This requires the old i_size to be retained in the operation record as
+     we commit the revised status to the inode members inside the io_lock
+     still, but we still need to know if we reduced the file size.
+
+Fixes: d2ddc776a458 ("afs: Overhaul volume and server record caching and fileserver rotation")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/inode.c    | 47 ++++++++++++++++++++++++++++++++++++++---------
+ fs/afs/internal.h |  1 +
+ fs/afs/write.c    | 11 +++++++++++
+ 3 files changed, 50 insertions(+), 9 deletions(-)
+
+diff --git a/fs/afs/inode.c b/fs/afs/inode.c
+index 1d13d2e882ada..0fe8844b4bee2 100644
+--- a/fs/afs/inode.c
++++ b/fs/afs/inode.c
+@@ -810,14 +810,32 @@ void afs_evict_inode(struct inode *inode)
+ static void afs_setattr_success(struct afs_operation *op)
+ {
+-      struct inode *inode = &op->file[0].vnode->vfs_inode;
++      struct afs_vnode_param *vp = &op->file[0];
++      struct inode *inode = &vp->vnode->vfs_inode;
++      loff_t old_i_size = i_size_read(inode);
++
++      op->setattr.old_i_size = old_i_size;
++      afs_vnode_commit_status(op, vp);
++      /* inode->i_size has now been changed. */
++
++      if (op->setattr.attr->ia_valid & ATTR_SIZE) {
++              loff_t size = op->setattr.attr->ia_size;
++              if (size > old_i_size)
++                      pagecache_isize_extended(inode, old_i_size, size);
++      }
++}
++
++static void afs_setattr_edit_file(struct afs_operation *op)
++{
++      struct afs_vnode_param *vp = &op->file[0];
++      struct inode *inode = &vp->vnode->vfs_inode;
+-      afs_vnode_commit_status(op, &op->file[0]);
+       if (op->setattr.attr->ia_valid & ATTR_SIZE) {
+-              loff_t i_size = inode->i_size, size = op->setattr.attr->ia_size;
+-              if (size > i_size)
+-                      pagecache_isize_extended(inode, i_size, size);
+-              truncate_pagecache(inode, size);
++              loff_t size = op->setattr.attr->ia_size;
++              loff_t i_size = op->setattr.old_i_size;
++
++              if (size < i_size)
++                      truncate_pagecache(inode, size);
+       }
+ }
+@@ -825,6 +843,7 @@ static const struct afs_operation_ops afs_setattr_operation = {
+       .issue_afs_rpc  = afs_fs_setattr,
+       .issue_yfs_rpc  = yfs_fs_setattr,
+       .success        = afs_setattr_success,
++      .edit_dir       = afs_setattr_edit_file,
+ };
+ /*
+@@ -863,11 +882,16 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
+       if (S_ISREG(vnode->vfs_inode.i_mode))
+               filemap_write_and_wait(vnode->vfs_inode.i_mapping);
++      /* Prevent any new writebacks from starting whilst we do this. */
++      down_write(&vnode->validate_lock);
++
+       op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ?
+                                 afs_file_key(attr->ia_file) : NULL),
+                                vnode->volume);
+-      if (IS_ERR(op))
+-              return PTR_ERR(op);
++      if (IS_ERR(op)) {
++              ret = PTR_ERR(op);
++              goto out_unlock;
++      }
+       afs_op_set_vnode(op, 0, vnode);
+       op->setattr.attr = attr;
+@@ -880,5 +904,10 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
+       op->file[0].update_ctime = 1;
+       op->ops = &afs_setattr_operation;
+-      return afs_do_sync_operation(op);
++      ret = afs_do_sync_operation(op);
++
++out_unlock:
++      up_write(&vnode->validate_lock);
++      _leave(" = %d", ret);
++      return ret;
+ }
+diff --git a/fs/afs/internal.h b/fs/afs/internal.h
+index 792ac711985eb..e1ebead2e505a 100644
+--- a/fs/afs/internal.h
++++ b/fs/afs/internal.h
+@@ -810,6 +810,7 @@ struct afs_operation {
+               } store;
+               struct {
+                       struct iattr    *attr;
++                      loff_t          old_i_size;
+               } setattr;
+               struct afs_acl  *acl;
+               struct yfs_acl  *yacl;
+diff --git a/fs/afs/write.c b/fs/afs/write.c
+index a121c247d95a3..0a98cf36e78a3 100644
+--- a/fs/afs/write.c
++++ b/fs/afs/write.c
+@@ -738,11 +738,21 @@ static int afs_writepages_region(struct address_space *mapping,
+ int afs_writepages(struct address_space *mapping,
+                  struct writeback_control *wbc)
+ {
++      struct afs_vnode *vnode = AFS_FS_I(mapping->host);
+       pgoff_t start, end, next;
+       int ret;
+       _enter("");
++      /* We have to be careful as we can end up racing with setattr()
++       * truncating the pagecache since the caller doesn't take a lock here
++       * to prevent it.
++       */
++      if (wbc->sync_mode == WB_SYNC_ALL)
++              down_read(&vnode->validate_lock);
++      else if (!down_read_trylock(&vnode->validate_lock))
++              return 0;
++
+       if (wbc->range_cyclic) {
+               start = mapping->writeback_index;
+               end = -1;
+@@ -762,6 +772,7 @@ int afs_writepages(struct address_space *mapping,
+               ret = afs_writepages_region(mapping, wbc, start, end, &next);
+       }
++      up_read(&vnode->validate_lock);
+       _leave(" = %d", ret);
+       return ret;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/bonding-set-dev-needed_headroom-in-bond_setup_by_sla.patch b/queue-5.8/bonding-set-dev-needed_headroom-in-bond_setup_by_sla.patch
new file mode 100644 (file)
index 0000000..a72be5f
--- /dev/null
@@ -0,0 +1,71 @@
+From ad49b3af34bfb062b57f370f9002f03e803eee03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Sep 2020 06:38:07 -0700
+Subject: bonding: set dev->needed_headroom in bond_setup_by_slave()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f32f19339596b214c208c0dba716f4b6cc4f6958 ]
+
+syzbot managed to crash a host by creating a bond
+with a GRE device.
+
+For non Ethernet device, bonding calls bond_setup_by_slave()
+instead of ether_setup(), and unfortunately dev->needed_headroom
+was not copied from the new added member.
+
+[  171.243095] skbuff: skb_under_panic: text:ffffffffa184b9ea len:116 put:20 head:ffff883f84012dc0 data:ffff883f84012dbc tail:0x70 end:0xd00 dev:bond0
+[  171.243111] ------------[ cut here ]------------
+[  171.243112] kernel BUG at net/core/skbuff.c:112!
+[  171.243117] invalid opcode: 0000 [#1] SMP KASAN PTI
+[  171.243469] gsmi: Log Shutdown Reason 0x03
+[  171.243505] Call Trace:
+[  171.243506]  <IRQ>
+[  171.243512]  [<ffffffffa171be59>] skb_push+0x49/0x50
+[  171.243516]  [<ffffffffa184b9ea>] ipgre_header+0x2a/0xf0
+[  171.243520]  [<ffffffffa17452d7>] neigh_connected_output+0xb7/0x100
+[  171.243524]  [<ffffffffa186f1d3>] ip6_finish_output2+0x383/0x490
+[  171.243528]  [<ffffffffa186ede2>] __ip6_finish_output+0xa2/0x110
+[  171.243531]  [<ffffffffa186acbc>] ip6_finish_output+0x2c/0xa0
+[  171.243534]  [<ffffffffa186abe9>] ip6_output+0x69/0x110
+[  171.243537]  [<ffffffffa186ac90>] ? ip6_output+0x110/0x110
+[  171.243541]  [<ffffffffa189d952>] mld_sendpack+0x1b2/0x2d0
+[  171.243544]  [<ffffffffa189d290>] ? mld_send_report+0xf0/0xf0
+[  171.243548]  [<ffffffffa189c797>] mld_ifc_timer_expire+0x2d7/0x3b0
+[  171.243551]  [<ffffffffa189c4c0>] ? mld_gq_timer_expire+0x50/0x50
+[  171.243556]  [<ffffffffa0fea270>] call_timer_fn+0x30/0x130
+[  171.243559]  [<ffffffffa0fea17c>] expire_timers+0x4c/0x110
+[  171.243563]  [<ffffffffa0fea0e3>] __run_timers+0x213/0x260
+[  171.243566]  [<ffffffffa0fecb7d>] ? ktime_get+0x3d/0xa0
+[  171.243570]  [<ffffffffa0ff9c4e>] ? clockevents_program_event+0x7e/0xe0
+[  171.243574]  [<ffffffffa0f7e5d5>] ? sched_clock_cpu+0x15/0x190
+[  171.243577]  [<ffffffffa0fe973d>] run_timer_softirq+0x1d/0x40
+[  171.243581]  [<ffffffffa1c00152>] __do_softirq+0x152/0x2f0
+[  171.243585]  [<ffffffffa0f44e1f>] irq_exit+0x9f/0xb0
+[  171.243588]  [<ffffffffa1a02e1d>] smp_apic_timer_interrupt+0xfd/0x1a0
+[  171.243591]  [<ffffffffa1a01ea6>] apic_timer_interrupt+0x86/0x90
+
+Fixes: f5184d267c1a ("net: Allow netdevices to specify needed head/tailroom")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 500aa3e19a4c7..fddf7c502355b 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -1195,6 +1195,7 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
+       bond_dev->type              = slave_dev->type;
+       bond_dev->hard_header_len   = slave_dev->hard_header_len;
++      bond_dev->needed_headroom   = slave_dev->needed_headroom;
+       bond_dev->addr_len          = slave_dev->addr_len;
+       memcpy(bond_dev->broadcast, slave_dev->broadcast,
+-- 
+2.25.1
+
diff --git a/queue-5.8/hinic-add-log-in-exception-handling-processes.patch b/queue-5.8/hinic-add-log-in-exception-handling-processes.patch
new file mode 100644 (file)
index 0000000..c193c96
--- /dev/null
@@ -0,0 +1,518 @@
+From 81df94accb34d9f236d24a135cbffe18dcc01330 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jul 2020 15:11:19 +0800
+Subject: hinic: add log in exception handling processes
+
+From: Luo bin <luobin9@huawei.com>
+
+[ Upstream commit 90f86b8a36c065286b743eed29661fc5cd00d342 ]
+
+improve the error message when functions return failure and dump
+relevant registers in some exception handling processes
+
+Signed-off-by: Luo bin <luobin9@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/huawei/hinic/hinic_hw_api_cmd.c  | 27 +++++++-
+ .../ethernet/huawei/hinic/hinic_hw_api_cmd.h  |  4 ++
+ .../net/ethernet/huawei/hinic/hinic_hw_cmdq.c |  2 +
+ .../net/ethernet/huawei/hinic/hinic_hw_cmdq.h |  2 +
+ .../net/ethernet/huawei/hinic/hinic_hw_dev.c  | 12 ++--
+ .../net/ethernet/huawei/hinic/hinic_hw_eqs.c  | 39 ++++++++++++
+ .../net/ethernet/huawei/hinic/hinic_hw_eqs.h  |  6 +-
+ .../net/ethernet/huawei/hinic/hinic_hw_if.c   | 23 +++++++
+ .../net/ethernet/huawei/hinic/hinic_hw_if.h   | 10 ++-
+ .../net/ethernet/huawei/hinic/hinic_hw_mbox.c |  2 +
+ .../net/ethernet/huawei/hinic/hinic_hw_mgmt.c |  1 +
+ .../net/ethernet/huawei/hinic/hinic_port.c    | 62 +++++++++----------
+ .../net/ethernet/huawei/hinic/hinic_sriov.c   |  6 +-
+ 13 files changed, 151 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
+index 583fd24c29cf6..29e88e25a4a4f 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c
+@@ -112,6 +112,26 @@ static u32 get_hw_cons_idx(struct hinic_api_cmd_chain *chain)
+       return HINIC_API_CMD_STATUS_GET(val, CONS_IDX);
+ }
++static void dump_api_chain_reg(struct hinic_api_cmd_chain *chain)
++{
++      u32 addr, val;
++
++      addr = HINIC_CSR_API_CMD_STATUS_ADDR(chain->chain_type);
++      val  = hinic_hwif_read_reg(chain->hwif, addr);
++
++      dev_err(&chain->hwif->pdev->dev, "Chain type: 0x%x, cpld error: 0x%x, check error: 0x%x, current fsm: 0x%x\n",
++              chain->chain_type, HINIC_API_CMD_STATUS_GET(val, CPLD_ERR),
++              HINIC_API_CMD_STATUS_GET(val, CHKSUM_ERR),
++              HINIC_API_CMD_STATUS_GET(val, FSM));
++
++      dev_err(&chain->hwif->pdev->dev, "Chain hw current ci: 0x%x\n",
++              HINIC_API_CMD_STATUS_GET(val, CONS_IDX));
++
++      addr = HINIC_CSR_API_CMD_CHAIN_PI_ADDR(chain->chain_type);
++      val  = hinic_hwif_read_reg(chain->hwif, addr);
++      dev_err(&chain->hwif->pdev->dev, "Chain hw current pi: 0x%x\n", val);
++}
++
+ /**
+  * chain_busy - check if the chain is still processing last requests
+  * @chain: chain to check
+@@ -131,8 +151,10 @@ static int chain_busy(struct hinic_api_cmd_chain *chain)
+               /* check for a space for a new command */
+               if (chain->cons_idx == MASKED_IDX(chain, prod_idx + 1)) {
+-                      dev_err(&pdev->dev, "API CMD chain %d is busy\n",
+-                              chain->chain_type);
++                      dev_err(&pdev->dev, "API CMD chain %d is busy, cons_idx: %d, prod_idx: %d\n",
++                              chain->chain_type, chain->cons_idx,
++                              chain->prod_idx);
++                      dump_api_chain_reg(chain);
+                       return -EBUSY;
+               }
+               break;
+@@ -332,6 +354,7 @@ static int wait_for_api_cmd_completion(struct hinic_api_cmd_chain *chain)
+               err = wait_for_status_poll(chain);
+               if (err) {
+                       dev_err(&pdev->dev, "API CMD Poll status timeout\n");
++                      dump_api_chain_reg(chain);
+                       break;
+               }
+               break;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
+index 0ba00fd828dfc..6d1654b050ad5 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
+@@ -103,10 +103,14 @@
+        HINIC_API_CMD_STATUS_HEADER_##member##_MASK)
+ #define HINIC_API_CMD_STATUS_CONS_IDX_SHIFT                     0
++#define HINIC_API_CMD_STATUS_FSM_SHIFT                                24
+ #define HINIC_API_CMD_STATUS_CHKSUM_ERR_SHIFT                   28
++#define HINIC_API_CMD_STATUS_CPLD_ERR_SHIFT                   30
+ #define HINIC_API_CMD_STATUS_CONS_IDX_MASK                      0xFFFFFF
++#define HINIC_API_CMD_STATUS_FSM_MASK                         0xFU
+ #define HINIC_API_CMD_STATUS_CHKSUM_ERR_MASK                    0x3
++#define HINIC_API_CMD_STATUS_CPLD_ERR_MASK                    0x1U
+ #define HINIC_API_CMD_STATUS_GET(val, member)                   \
+       (((val) >> HINIC_API_CMD_STATUS_##member##_SHIFT) &     \
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+index cb5b6e5f787f2..e0eb294779ec1 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+@@ -401,6 +401,7 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,
+               spin_unlock_bh(&cmdq->cmdq_lock);
++              hinic_dump_ceq_info(cmdq->hwdev);
+               return -ETIMEDOUT;
+       }
+@@ -807,6 +808,7 @@ static int init_cmdqs_ctxt(struct hinic_hwdev *hwdev,
+       cmdq_type = HINIC_CMDQ_SYNC;
+       for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
++              cmdqs->cmdq[cmdq_type].hwdev = hwdev;
+               err = init_cmdq(&cmdqs->cmdq[cmdq_type],
+                               &cmdqs->saved_wqs[cmdq_type], cmdq_type,
+                               db_area[cmdq_type]);
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
+index 3e4b0aef9fe6c..f40c31e1879f1 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
+@@ -130,6 +130,8 @@ struct hinic_cmdq_ctxt {
+ };
+ struct hinic_cmdq {
++      struct hinic_hwdev      *hwdev;
++
+       struct hinic_wq         *wq;
+       enum hinic_cmdq_type    cmdq_type;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+index b735bc537508f..298ceb930cc62 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+@@ -253,9 +253,9 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev)
+                                &fw_ctxt, sizeof(fw_ctxt),
+                                &fw_ctxt, &out_size);
+       if (err || (out_size != sizeof(fw_ctxt)) || fw_ctxt.status) {
+-              dev_err(&pdev->dev, "Failed to init FW ctxt, ret = %d\n",
+-                      fw_ctxt.status);
+-              return -EFAULT;
++              dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, fw_ctxt.status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -420,9 +420,9 @@ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
+                                &cmd_base_qpn, sizeof(cmd_base_qpn),
+                                &cmd_base_qpn, &out_size);
+       if (err || (out_size != sizeof(cmd_base_qpn)) || cmd_base_qpn.status) {
+-              dev_err(&pdev->dev, "Failed to get base qpn, status = %d\n",
+-                      cmd_base_qpn.status);
+-              return -EFAULT;
++              dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, cmd_base_qpn.status, out_size);
++              return -EIO;
+       }
+       *base_qpn = cmd_base_qpn.qpn;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
+index 397936cac304c..ca8cb68a8d206 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
+@@ -953,3 +953,42 @@ void hinic_ceqs_free(struct hinic_ceqs *ceqs)
+       for (q_id = 0; q_id < ceqs->num_ceqs; q_id++)
+               remove_eq(&ceqs->ceq[q_id]);
+ }
++
++void hinic_dump_ceq_info(struct hinic_hwdev *hwdev)
++{
++      struct hinic_eq *eq = NULL;
++      u32 addr, ci, pi;
++      int q_id;
++
++      for (q_id = 0; q_id < hwdev->func_to_io.ceqs.num_ceqs; q_id++) {
++              eq = &hwdev->func_to_io.ceqs.ceq[q_id];
++              addr = EQ_CONS_IDX_REG_ADDR(eq);
++              ci = hinic_hwif_read_reg(hwdev->hwif, addr);
++              addr = EQ_PROD_IDX_REG_ADDR(eq);
++              pi = hinic_hwif_read_reg(hwdev->hwif, addr);
++              dev_err(&hwdev->hwif->pdev->dev, "Ceq id: %d, ci: 0x%08x, sw_ci: 0x%08x, pi: 0x%x, tasklet_state: 0x%lx, wrap: %d, ceqe: 0x%x\n",
++                      q_id, ci, eq->cons_idx, pi,
++                      eq->ceq_tasklet.state,
++                      eq->wrapped, be32_to_cpu(*(__be32 *)(GET_CURR_CEQ_ELEM(eq))));
++      }
++}
++
++void hinic_dump_aeq_info(struct hinic_hwdev *hwdev)
++{
++      struct hinic_aeq_elem *aeqe_pos = NULL;
++      struct hinic_eq *eq = NULL;
++      u32 addr, ci, pi;
++      int q_id;
++
++      for (q_id = 0; q_id < hwdev->aeqs.num_aeqs; q_id++) {
++              eq = &hwdev->aeqs.aeq[q_id];
++              addr = EQ_CONS_IDX_REG_ADDR(eq);
++              ci = hinic_hwif_read_reg(hwdev->hwif, addr);
++              addr = EQ_PROD_IDX_REG_ADDR(eq);
++              pi = hinic_hwif_read_reg(hwdev->hwif, addr);
++              aeqe_pos = GET_CURR_AEQ_ELEM(eq);
++              dev_err(&hwdev->hwif->pdev->dev, "Aeq id: %d, ci: 0x%08x, pi: 0x%x, work_state: 0x%x, wrap: %d, desc: 0x%x\n",
++                      q_id, ci, pi, work_busy(&eq->aeq_work.work),
++                      eq->wrapped, be32_to_cpu(aeqe_pos->desc));
++      }
++}
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
+index 74b9ff90640c2..43065fc708693 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
+@@ -162,7 +162,7 @@ enum hinic_eqe_state {
+ struct hinic_aeq_elem {
+       u8      data[HINIC_AEQE_DATA_SIZE];
+-      u32     desc;
++      __be32  desc;
+ };
+ struct hinic_eq_work {
+@@ -254,4 +254,8 @@ int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
+ void hinic_ceqs_free(struct hinic_ceqs *ceqs);
++void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);
++
++void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);
++
+ #endif
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
+index cf127d896ba69..bc8925c0c982c 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.c
+@@ -21,6 +21,8 @@
+ #define WAIT_HWIF_READY_TIMEOUT       10000
++#define HINIC_SELFTEST_RESULT 0x883C
++
+ /**
+  * hinic_msix_attr_set - set message attribute for msix entry
+  * @hwif: the HW interface of a pci function device
+@@ -369,6 +371,26 @@ u16 hinic_pf_id_of_vf_hw(struct hinic_hwif *hwif)
+       return HINIC_FA0_GET(attr0, PF_IDX);
+ }
++static void __print_selftest_reg(struct hinic_hwif *hwif)
++{
++      u32 addr, attr0, attr1;
++
++      addr   = HINIC_CSR_FUNC_ATTR1_ADDR;
++      attr1  = hinic_hwif_read_reg(hwif, addr);
++
++      if (attr1 == HINIC_PCIE_LINK_DOWN) {
++              dev_err(&hwif->pdev->dev, "PCIE is link down\n");
++              return;
++      }
++
++      addr   = HINIC_CSR_FUNC_ATTR0_ADDR;
++      attr0  = hinic_hwif_read_reg(hwif, addr);
++      if (HINIC_FA0_GET(attr0, FUNC_TYPE) != HINIC_VF &&
++          !HINIC_FA0_GET(attr0, PCI_INTF_IDX))
++              dev_err(&hwif->pdev->dev, "Selftest reg: 0x%08x\n",
++                      hinic_hwif_read_reg(hwif, HINIC_SELFTEST_RESULT));
++}
++
+ /**
+  * hinic_init_hwif - initialize the hw interface
+  * @hwif: the HW interface of a pci function device
+@@ -398,6 +420,7 @@ int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev)
+       err = wait_hwif_ready(hwif);
+       if (err) {
+               dev_err(&pdev->dev, "HW interface is not ready\n");
++              __print_selftest_reg(hwif);
+               goto err_hwif_ready;
+       }
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
+index 0872e035faa11..c06f2253151e2 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h
+@@ -12,6 +12,8 @@
+ #include <linux/types.h>
+ #include <asm/byteorder.h>
++#define HINIC_PCIE_LINK_DOWN                                  0xFFFFFFFF
++
+ #define HINIC_DMA_ATTR_ST_SHIFT                                 0
+ #define HINIC_DMA_ATTR_AT_SHIFT                                 8
+ #define HINIC_DMA_ATTR_PH_SHIFT                                 10
+@@ -249,13 +251,17 @@ struct hinic_hwif {
+ static inline u32 hinic_hwif_read_reg(struct hinic_hwif *hwif, u32 reg)
+ {
+-      return be32_to_cpu(readl(hwif->cfg_regs_bar + reg));
++      u32 out = readl(hwif->cfg_regs_bar + reg);
++
++      return be32_to_cpu(*(__be32 *)&out);
+ }
+ static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg,
+                                       u32 val)
+ {
+-      writel(cpu_to_be32(val), hwif->cfg_regs_bar + reg);
++      __be32 in = cpu_to_be32(val);
++
++      writel(*(u32 *)&in, hwif->cfg_regs_bar + reg);
+ }
+ int hinic_msix_attr_set(struct hinic_hwif *hwif, u16 msix_index,
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
+index bc2f87e6cb5d7..47c93f946b94d 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
+@@ -650,6 +650,7 @@ wait_for_mbox_seg_completion(struct hinic_mbox_func_to_func *func_to_func,
+               if (!wait_for_completion_timeout(done, jif)) {
+                       dev_err(&hwdev->hwif->pdev->dev, "Send mailbox segment timeout\n");
+                       dump_mox_reg(hwdev);
++                      hinic_dump_aeq_info(hwdev);
+                       return -ETIMEDOUT;
+               }
+@@ -897,6 +898,7 @@ int hinic_mbox_to_func(struct hinic_mbox_func_to_func *func_to_func,
+               set_mbox_to_func_event(func_to_func, EVENT_TIMEOUT);
+               dev_err(&func_to_func->hwif->pdev->dev,
+                       "Send mbox msg timeout, msg_id: %d\n", msg_info.msg_id);
++              hinic_dump_aeq_info(func_to_func->hwdev);
+               err = -ETIMEDOUT;
+               goto err_send_mbox;
+       }
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
+index 7fe39a155b329..070288c8b4f37 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c
+@@ -276,6 +276,7 @@ static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,
+       if (!wait_for_completion_timeout(recv_done, timeo)) {
+               dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
++              hinic_dump_aeq_info(pf_to_mgmt->hwdev);
+               err = -ETIMEDOUT;
+               goto unlock_sync_msg;
+       }
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port.c b/drivers/net/ethernet/huawei/hinic/hinic_port.c
+index 175c0ee000384..82d5c50630e64 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_port.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_port.c
+@@ -61,8 +61,8 @@ static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
+           (port_mac_cmd.status  &&
+           port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY &&
+           port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
+-              dev_err(&pdev->dev, "Failed to change MAC, ret = %d\n",
+-                      port_mac_cmd.status);
++              dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, port_mac_cmd.status, out_size);
+               return -EFAULT;
+       }
+@@ -129,8 +129,8 @@ int hinic_port_get_mac(struct hinic_dev *nic_dev, u8 *addr)
+                                &port_mac_cmd, sizeof(port_mac_cmd),
+                                &port_mac_cmd, &out_size);
+       if (err || (out_size != sizeof(port_mac_cmd)) || port_mac_cmd.status) {
+-              dev_err(&pdev->dev, "Failed to get mac, ret = %d\n",
+-                      port_mac_cmd.status);
++              dev_err(&pdev->dev, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, port_mac_cmd.status, out_size);
+               return -EFAULT;
+       }
+@@ -172,9 +172,9 @@ int hinic_port_set_mtu(struct hinic_dev *nic_dev, int new_mtu)
+       err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
+                                &port_mtu_cmd, sizeof(port_mtu_cmd),
+                                &port_mtu_cmd, &out_size);
+-      if (err || (out_size != sizeof(port_mtu_cmd)) || port_mtu_cmd.status) {
+-              dev_err(&pdev->dev, "Failed to set mtu, ret = %d\n",
+-                      port_mtu_cmd.status);
++      if (err || out_size != sizeof(port_mtu_cmd) || port_mtu_cmd.status) {
++              dev_err(&pdev->dev, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, port_mtu_cmd.status, out_size);
+               return -EFAULT;
+       }
+@@ -264,8 +264,8 @@ int hinic_port_link_state(struct hinic_dev *nic_dev,
+                                &link_cmd, sizeof(link_cmd),
+                                &link_cmd, &out_size);
+       if (err || (out_size != sizeof(link_cmd)) || link_cmd.status) {
+-              dev_err(&pdev->dev, "Failed to get link state, ret = %d\n",
+-                      link_cmd.status);
++              dev_err(&pdev->dev, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, link_cmd.status, out_size);
+               return -EINVAL;
+       }
+@@ -298,8 +298,8 @@ int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)
+                                &port_state, sizeof(port_state),
+                                &port_state, &out_size);
+       if (err || (out_size != sizeof(port_state)) || port_state.status) {
+-              dev_err(&pdev->dev, "Failed to set port state, ret = %d\n",
+-                      port_state.status);
++              dev_err(&pdev->dev, "Failed to set port state, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, port_state.status, out_size);
+               return -EFAULT;
+       }
+@@ -330,8 +330,8 @@ int hinic_port_set_func_state(struct hinic_dev *nic_dev,
+                                &func_state, sizeof(func_state),
+                                &func_state, &out_size);
+       if (err || (out_size != sizeof(func_state)) || func_state.status) {
+-              dev_err(&pdev->dev, "Failed to set port func state, ret = %d\n",
+-                      func_state.status);
++              dev_err(&pdev->dev, "Failed to set port func state, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, func_state.status, out_size);
+               return -EFAULT;
+       }
+@@ -361,9 +361,9 @@ int hinic_port_get_cap(struct hinic_dev *nic_dev,
+                                port_cap, &out_size);
+       if (err || (out_size != sizeof(*port_cap)) || port_cap->status) {
+               dev_err(&pdev->dev,
+-                      "Failed to get port capabilities, ret = %d\n",
+-                      port_cap->status);
+-              return -EINVAL;
++                      "Failed to get port capabilities, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, port_cap->status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -393,9 +393,9 @@ int hinic_port_set_tso(struct hinic_dev *nic_dev, enum hinic_tso_state state)
+                                &tso_cfg, &out_size);
+       if (err || out_size != sizeof(tso_cfg) || tso_cfg.status) {
+               dev_err(&pdev->dev,
+-                      "Failed to set port tso, ret = %d\n",
+-                      tso_cfg.status);
+-              return -EINVAL;
++                      "Failed to set port tso, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, tso_cfg.status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -423,9 +423,9 @@ int hinic_set_rx_csum_offload(struct hinic_dev *nic_dev, u32 en)
+                                &rx_csum_cfg, &out_size);
+       if (err || !out_size || rx_csum_cfg.status) {
+               dev_err(&pdev->dev,
+-                      "Failed to set rx csum offload, ret = %d\n",
+-                      rx_csum_cfg.status);
+-              return -EINVAL;
++                      "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, rx_csum_cfg.status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -480,9 +480,9 @@ int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
+                                &rq_num, &out_size);
+       if (err || !out_size || rq_num.status) {
+               dev_err(&pdev->dev,
+-                      "Failed to rxq number, ret = %d\n",
+-                      rq_num.status);
+-              return -EINVAL;
++                      "Failed to set rxq number, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, rq_num.status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -508,9 +508,9 @@ static int hinic_set_rx_lro(struct hinic_dev *nic_dev, u8 ipv4_en, u8 ipv6_en,
+                                &lro_cfg, &out_size);
+       if (err || !out_size || lro_cfg.status) {
+               dev_err(&pdev->dev,
+-                      "Failed to set lro offload, ret = %d\n",
+-                      lro_cfg.status);
+-              return -EINVAL;
++                      "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, lro_cfg.status, out_size);
++              return -EIO;
+       }
+       return 0;
+@@ -542,10 +542,10 @@ static int hinic_set_rx_lro_timer(struct hinic_dev *nic_dev, u32 timer_value)
+       if (err || !out_size || lro_timer.status) {
+               dev_err(&pdev->dev,
+-                      "Failed to set lro timer, ret = %d\n",
+-                      lro_timer.status);
++                      "Failed to set lro timer, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, lro_timer.status, out_size);
+-              return -EINVAL;
++              return -EIO;
+       }
+       return 0;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+index efab2dd2c889b..1043389754df0 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+@@ -40,9 +40,9 @@ static int hinic_set_mac(struct hinic_hwdev *hwdev, const u8 *mac_addr,
+       if (err || out_size != sizeof(mac_info) ||
+           (mac_info.status && mac_info.status != HINIC_PF_SET_VF_ALREADY &&
+           mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
+-              dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to change MAC, ret = %d\n",
+-                      mac_info.status);
+-              return -EFAULT;
++              dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x\n",
++                      err, mac_info.status, out_size);
++              return -EIO;
+       }
+       return 0;
+-- 
+2.25.1
+
diff --git a/queue-5.8/hinic-fix-wrong-return-value-of-mac-set-cmd.patch b/queue-5.8/hinic-fix-wrong-return-value-of-mac-set-cmd.patch
new file mode 100644 (file)
index 0000000..3ec6a13
--- /dev/null
@@ -0,0 +1,79 @@
+From 14e1094642c4b02bc436f6e3f95f4f1b2fc87941 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Sep 2020 09:31:51 +0800
+Subject: hinic: fix wrong return value of mac-set cmd
+
+From: Luo bin <luobin9@huawei.com>
+
+[ Upstream commit f68910a8056f9451ee9fe7e1b962f7d90d326ad3 ]
+
+It should also be regarded as an error when hw return status=4 for PF's
+setting mac cmd. Only if PF return status=4 to VF should this cmd be
+taken special treatment.
+
+Fixes: 7dd29ee12865 ("hinic: add sriov feature support")
+Signed-off-by: Luo bin <luobin9@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/hinic_port.c  |  6 +++---
+ drivers/net/ethernet/huawei/hinic/hinic_sriov.c | 12 ++----------
+ 2 files changed, 5 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port.c b/drivers/net/ethernet/huawei/hinic/hinic_port.c
+index 82d5c50630e64..2be7c254cca90 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_port.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_port.c
+@@ -58,9 +58,9 @@ static int change_mac(struct hinic_dev *nic_dev, const u8 *addr,
+                                sizeof(port_mac_cmd),
+                                &port_mac_cmd, &out_size);
+       if (err || out_size != sizeof(port_mac_cmd) ||
+-          (port_mac_cmd.status  &&
+-          port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY &&
+-          port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
++          (port_mac_cmd.status &&
++           (port_mac_cmd.status != HINIC_PF_SET_VF_ALREADY || !HINIC_IS_VF(hwif)) &&
++           port_mac_cmd.status != HINIC_MGMT_STATUS_EXIST)) {
+               dev_err(&pdev->dev, "Failed to change MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+                       err, port_mac_cmd.status, out_size);
+               return -EFAULT;
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+index 1043389754df0..b757f7057b8fe 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+@@ -38,8 +38,7 @@ static int hinic_set_mac(struct hinic_hwdev *hwdev, const u8 *mac_addr,
+       err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
+                                sizeof(mac_info), &mac_info, &out_size);
+       if (err || out_size != sizeof(mac_info) ||
+-          (mac_info.status && mac_info.status != HINIC_PF_SET_VF_ALREADY &&
+-          mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
++          (mac_info.status && mac_info.status != HINIC_MGMT_STATUS_EXIST)) {
+               dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x\n",
+                       err, mac_info.status, out_size);
+               return -EIO;
+@@ -452,8 +451,7 @@ struct hinic_sriov_info *hinic_get_sriov_info_by_pcidev(struct pci_dev *pdev)
+ static int hinic_check_mac_info(u8 status, u16 vlan_id)
+ {
+-      if ((status && status != HINIC_MGMT_STATUS_EXIST &&
+-           status != HINIC_PF_SET_VF_ALREADY) ||
++      if ((status && status != HINIC_MGMT_STATUS_EXIST) ||
+           (vlan_id & CHECK_IPSU_15BIT &&
+            status == HINIC_MGMT_STATUS_EXIST))
+               return -EINVAL;
+@@ -495,12 +493,6 @@ static int hinic_update_mac(struct hinic_hwdev *hwdev, u8 *old_mac,
+               return -EINVAL;
+       }
+-      if (mac_info.status == HINIC_PF_SET_VF_ALREADY) {
+-              dev_warn(&hwdev->hwif->pdev->dev,
+-                       "PF has already set VF MAC. Ignore update operation\n");
+-              return HINIC_PF_SET_VF_ALREADY;
+-      }
+-
+       if (mac_info.status == HINIC_MGMT_STATUS_EXIST)
+               dev_warn(&hwdev->hwif->pdev->dev, "MAC is repeated. Ignore update operation\n");
+-- 
+2.25.1
+
diff --git a/queue-5.8/i2c-meson-fix-clock-setting-overwrite.patch-20597 b/queue-5.8/i2c-meson-fix-clock-setting-overwrite.patch-20597
new file mode 100644 (file)
index 0000000..054f8d8
--- /dev/null
@@ -0,0 +1,55 @@
+From cc7541d5ca5e81e749490a5ea65d1cede0dbaefb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Oct 2020 10:07:49 +0200
+Subject: i2c: meson: fix clock setting overwrite
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 28683e847e2f20eed22cdd24f185d7783db396d3 ]
+
+When the slave address is written in do_start(), SLAVE_ADDR is written
+completely. This may overwrite some setting related to the clock rate
+or signal filtering.
+
+Fix this by writing only the bits related to slave address. To avoid
+causing unexpected changed, explicitly disable filtering or high/low
+clock mode which may have been left over by the bootloader.
+
+Fixes: 30021e3707a7 ("i2c: add support for Amlogic Meson I2C controller")
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-meson.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c
+index ef73a42577cc7..a85a40fdf2f6e 100644
+--- a/drivers/i2c/busses/i2c-meson.c
++++ b/drivers/i2c/busses/i2c-meson.c
+@@ -43,6 +43,12 @@
+ #define REG_SLV_SCL_LOW               GENMASK(27, 16)
+ #define REG_SLV_SCL_LOW_EN    BIT(28)
++#define REG_SLV_ADDR          GENMASK(7, 0)
++#define REG_SLV_SDA_FILTER    GENMASK(10, 8)
++#define REG_SLV_SCL_FILTER    GENMASK(13, 11)
++#define REG_SLV_SCL_LOW               GENMASK(27, 16)
++#define REG_SLV_SCL_LOW_EN    BIT(28)
++
+ #define I2C_TIMEOUT_MS                500
+ #define FILTER_DELAY          15
+@@ -158,6 +164,9 @@ static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq)
+       /* Disable HIGH/LOW mode */
+       meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, 0);
++      /* Disable HIGH/LOW mode */
++      meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, 0);
++
+       dev_dbg(i2c->dev, "%s: clk %lu, freq %u, div %u\n", __func__,
+               clk_rate, freq, div);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/iavf-fix-incorrect-adapter-get-in-iavf_resume.patch b/queue-5.8/iavf-fix-incorrect-adapter-get-in-iavf_resume.patch
new file mode 100644 (file)
index 0000000..1475f79
--- /dev/null
@@ -0,0 +1,42 @@
+From cbf584431870e096c0ee647a0b80f4737723a9f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Sep 2020 12:54:59 +0000
+Subject: iavf: Fix incorrect adapter get in iavf_resume
+
+From: Sylwester Dziedziuch <sylwesterx.dziedziuch@intel.com>
+
+[ Upstream commit 75598a8fc0e0dff2aa5d46c62531b36a595f1d4f ]
+
+When calling iavf_resume there was a crash because wrong
+function was used to get iavf_adapter and net_device pointers.
+Changed how iavf_resume is getting iavf_adapter and net_device
+pointers from pci_dev.
+
+Fixes: 5eae00c57f5e ("i40evf: main driver core")
+Signed-off-by: Sylwester Dziedziuch <sylwesterx.dziedziuch@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index b3b349ecb0a8d..91343e2d3a145 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3817,8 +3817,8 @@ static int __maybe_unused iavf_suspend(struct device *dev_d)
+ static int __maybe_unused iavf_resume(struct device *dev_d)
+ {
+       struct pci_dev *pdev = to_pci_dev(dev_d);
+-      struct iavf_adapter *adapter = pci_get_drvdata(pdev);
+-      struct net_device *netdev = adapter->netdev;
++      struct net_device *netdev = pci_get_drvdata(pdev);
++      struct iavf_adapter *adapter = netdev_priv(netdev);
+       u32 err;
+       pci_set_master(pdev);
+-- 
+2.25.1
+
diff --git a/queue-5.8/iavf-use-generic-power-management.patch b/queue-5.8/iavf-use-generic-power-management.patch
new file mode 100644 (file)
index 0000000..fbf5916
--- /dev/null
@@ -0,0 +1,130 @@
+From d1447d2ffbeb284928bca6524ea5838510f75b86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Jun 2020 14:59:39 +0530
+Subject: iavf: use generic power management
+
+From: Vaibhav Gupta <vaibhavgupta40@gmail.com>
+
+[ Upstream commit bc5cbd73eb493944b8665dc517f684c40eb18a4a ]
+
+With the support of generic PM callbacks, drivers no longer need to use
+legacy .suspend() and .resume() in which they had to maintain PCI states
+changes and device's power state themselves. The required operations are
+done by PCI core.
+
+PCI drivers are not expected to invoke PCI helper functions like
+pci_save/restore_state(), pci_enable/disable_device(),
+pci_set_power_state(), etc. Their tasks are completed by PCI core itself.
+
+Compile-tested only.
+
+Signed-off-by: Vaibhav Gupta <vaibhavgupta40@gmail.com>
+Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 45 ++++++---------------
+ 1 file changed, 12 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index d338efe5f3f55..b3b349ecb0a8d 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3777,7 +3777,6 @@ err_dma:
+       return err;
+ }
+-#ifdef CONFIG_PM
+ /**
+  * iavf_suspend - Power management suspend routine
+  * @pdev: PCI device information struct
+@@ -3785,11 +3784,10 @@ err_dma:
+  *
+  * Called when the system (VM) is entering sleep/suspend.
+  **/
+-static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
++static int __maybe_unused iavf_suspend(struct device *dev_d)
+ {
+-      struct net_device *netdev = pci_get_drvdata(pdev);
++      struct net_device *netdev = dev_get_drvdata(dev_d);
+       struct iavf_adapter *adapter = netdev_priv(netdev);
+-      int retval = 0;
+       netif_device_detach(netdev);
+@@ -3807,12 +3805,6 @@ static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
+       clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section);
+-      retval = pci_save_state(pdev);
+-      if (retval)
+-              return retval;
+-
+-      pci_disable_device(pdev);
+-
+       return 0;
+ }
+@@ -3822,24 +3814,13 @@ static int iavf_suspend(struct pci_dev *pdev, pm_message_t state)
+  *
+  * Called when the system (VM) is resumed from sleep/suspend.
+  **/
+-static int iavf_resume(struct pci_dev *pdev)
++static int __maybe_unused iavf_resume(struct device *dev_d)
+ {
++      struct pci_dev *pdev = to_pci_dev(dev_d);
+       struct iavf_adapter *adapter = pci_get_drvdata(pdev);
+       struct net_device *netdev = adapter->netdev;
+       u32 err;
+-      pci_set_power_state(pdev, PCI_D0);
+-      pci_restore_state(pdev);
+-      /* pci_restore_state clears dev->state_saved so call
+-       * pci_save_state to restore it.
+-       */
+-      pci_save_state(pdev);
+-
+-      err = pci_enable_device_mem(pdev);
+-      if (err) {
+-              dev_err(&pdev->dev, "Cannot enable PCI device from suspend.\n");
+-              return err;
+-      }
+       pci_set_master(pdev);
+       rtnl_lock();
+@@ -3863,7 +3844,6 @@ static int iavf_resume(struct pci_dev *pdev)
+       return err;
+ }
+-#endif /* CONFIG_PM */
+ /**
+  * iavf_remove - Device Removal Routine
+  * @pdev: PCI device information struct
+@@ -3965,16 +3945,15 @@ static void iavf_remove(struct pci_dev *pdev)
+       pci_disable_device(pdev);
+ }
++static SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume);
++
+ static struct pci_driver iavf_driver = {
+-      .name     = iavf_driver_name,
+-      .id_table = iavf_pci_tbl,
+-      .probe    = iavf_probe,
+-      .remove   = iavf_remove,
+-#ifdef CONFIG_PM
+-      .suspend  = iavf_suspend,
+-      .resume   = iavf_resume,
+-#endif
+-      .shutdown = iavf_shutdown,
++      .name      = iavf_driver_name,
++      .id_table  = iavf_pci_tbl,
++      .probe     = iavf_probe,
++      .remove    = iavf_remove,
++      .driver.pm = &iavf_pm_ops,
++      .shutdown  = iavf_shutdown,
+ };
+ /**
+-- 
+2.25.1
+
diff --git a/queue-5.8/ice-fix-memory-leak-if-register_netdev_fails.patch b/queue-5.8/ice-fix-memory-leak-if-register_netdev_fails.patch
new file mode 100644 (file)
index 0000000..7f96be7
--- /dev/null
@@ -0,0 +1,122 @@
+From e47886203033768701068d4a935a7219a6a0d5e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Sep 2020 08:53:46 -0700
+Subject: ice: fix memory leak if register_netdev_fails
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 135f4b9e9340dadb78e9737bb4eb9817b9c89dac ]
+
+The ice_setup_pf_sw function can cause a memory leak if register_netdev
+fails, due to accidentally failing to free the VSI rings. Fix the memory
+leak by using ice_vsi_release, ensuring we actually go through the full
+teardown process.
+
+This should be safe even if the netdevice is not registered because we
+will have set the netdev pointer to NULL, ensuring ice_vsi_release won't
+call unregister_netdev.
+
+An alternative fix would be moving management of the PF VSI netdev into
+the main VSI setup code. This is complicated and likely requires
+significant refactor in how we manage VSIs
+
+Fixes: 3a858ba392c3 ("ice: Add support for VSI allocation and deallocation")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_lib.c  |  6 +++---
+ drivers/net/ethernet/intel/ice/ice_lib.h  |  6 ------
+ drivers/net/ethernet/intel/ice/ice_main.c | 13 +++----------
+ 3 files changed, 6 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 2e3a39cea2c03..133ba6f08e574 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -240,7 +240,7 @@ static int ice_get_free_slot(void *array, int size, int curr)
+  * ice_vsi_delete - delete a VSI from the switch
+  * @vsi: pointer to VSI being removed
+  */
+-void ice_vsi_delete(struct ice_vsi *vsi)
++static void ice_vsi_delete(struct ice_vsi *vsi)
+ {
+       struct ice_pf *pf = vsi->back;
+       struct ice_vsi_ctx *ctxt;
+@@ -307,7 +307,7 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi)
+  *
+  * Returns 0 on success, negative on failure
+  */
+-int ice_vsi_clear(struct ice_vsi *vsi)
++static int ice_vsi_clear(struct ice_vsi *vsi)
+ {
+       struct ice_pf *pf = NULL;
+       struct device *dev;
+@@ -557,7 +557,7 @@ static int ice_vsi_get_qs(struct ice_vsi *vsi)
+  * ice_vsi_put_qs - Release queues from VSI to PF
+  * @vsi: the VSI that is going to release queues
+  */
+-void ice_vsi_put_qs(struct ice_vsi *vsi)
++static void ice_vsi_put_qs(struct ice_vsi *vsi)
+ {
+       struct ice_pf *pf = vsi->back;
+       int i;
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
+index d80e6afa45112..2954b30e6ec79 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_lib.h
+@@ -43,10 +43,6 @@ int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
+ void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
+-void ice_vsi_delete(struct ice_vsi *vsi);
+-
+-int ice_vsi_clear(struct ice_vsi *vsi);
+-
+ #ifdef CONFIG_DCB
+ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc);
+ #endif /* CONFIG_DCB */
+@@ -77,8 +73,6 @@ bool ice_is_reset_in_progress(unsigned long *state);
+ void
+ ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio);
+-void ice_vsi_put_qs(struct ice_vsi *vsi);
+-
+ void ice_vsi_dis_irq(struct ice_vsi *vsi);
+ void ice_vsi_free_irq(struct ice_vsi *vsi);
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 4cbd49c87568a..4b52f1dea7f3a 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -2605,10 +2605,8 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
+               return -EBUSY;
+       vsi = ice_pf_vsi_setup(pf, pf->hw.port_info);
+-      if (!vsi) {
+-              status = -ENOMEM;
+-              goto unroll_vsi_setup;
+-      }
++      if (!vsi)
++              return -ENOMEM;
+       status = ice_cfg_netdev(vsi);
+       if (status) {
+@@ -2655,12 +2653,7 @@ unroll_napi_add:
+       }
+ unroll_vsi_setup:
+-      if (vsi) {
+-              ice_vsi_free_q_vectors(vsi);
+-              ice_vsi_delete(vsi);
+-              ice_vsi_put_qs(vsi);
+-              ice_vsi_clear(vsi);
+-      }
++      ice_vsi_release(vsi);
+       return status;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/ice-fix-memory-leak-in-ice_vsi_setup.patch b/queue-5.8/ice-fix-memory-leak-in-ice_vsi_setup.patch
new file mode 100644 (file)
index 0000000..6df1d9a
--- /dev/null
@@ -0,0 +1,68 @@
+From dee6e0c675f38a8a5d3087018bb2110bcfe10140 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Sep 2020 08:53:47 -0700
+Subject: ice: fix memory leak in ice_vsi_setup
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit f6a07271bb1535d9549380461437cc48d9e19958 ]
+
+During ice_vsi_setup, if ice_cfg_vsi_lan fails, it does not properly
+release memory associated with the VSI rings. If we had used devres
+allocations for the rings, this would be ok. However, we use kzalloc and
+kfree_rcu for these ring structures.
+
+Using the correct label to cleanup the rings during ice_vsi_setup
+highlights an issue in the ice_vsi_clear_rings function: it can leave
+behind stale ring pointers in the q_vectors structure.
+
+When releasing rings, we must also ensure that no q_vector associated
+with the VSI will point to this ring again. To resolve this, loop over
+all q_vectors and release their ring mapping. Because we are about to
+free all rings, no q_vector should remain pointing to any of the rings
+in this VSI.
+
+Fixes: 5513b920a4f7 ("ice: Update Tx scheduler tree for VSI multi-Tx queue support")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_lib.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 133ba6f08e574..4c5845a0965a9 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -1190,6 +1190,18 @@ static void ice_vsi_clear_rings(struct ice_vsi *vsi)
+ {
+       int i;
++      /* Avoid stale references by clearing map from vector to ring */
++      if (vsi->q_vectors) {
++              ice_for_each_q_vector(vsi, i) {
++                      struct ice_q_vector *q_vector = vsi->q_vectors[i];
++
++                      if (q_vector) {
++                              q_vector->tx.ring = NULL;
++                              q_vector->rx.ring = NULL;
++                      }
++              }
++      }
++
+       if (vsi->tx_rings) {
+               for (i = 0; i < vsi->alloc_txq; i++) {
+                       if (vsi->tx_rings[i]) {
+@@ -2254,7 +2266,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
+       if (status) {
+               dev_err(dev, "VSI %d failed lan queue config, error %s\n",
+                       vsi->vsi_num, ice_stat_str(status));
+-              goto unroll_vector_base;
++              goto unroll_clear_rings;
+       }
+       /* Add switch rule to drop all Tx Flow Control Frames, of look up
+-- 
+2.25.1
+
diff --git a/queue-5.8/mdio-fix-mdio-thunder.c-dependency-build-error.patch b/queue-5.8/mdio-fix-mdio-thunder.c-dependency-build-error.patch
new file mode 100644 (file)
index 0000000..9dd0e4a
--- /dev/null
@@ -0,0 +1,45 @@
+From bd64853b791603930c08d9fc762fc68d5a9cbb65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 26 Sep 2020 21:33:43 -0700
+Subject: mdio: fix mdio-thunder.c dependency & build error
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 7dbbcf496f2a4b6d82cfc7810a0746e160b79762 ]
+
+Fix build error by selecting MDIO_DEVRES for MDIO_THUNDER.
+Fixes this build error:
+
+ld: drivers/net/phy/mdio-thunder.o: in function `thunder_mdiobus_pci_probe':
+drivers/net/phy/mdio-thunder.c:78: undefined reference to `devm_mdiobus_alloc_size'
+
+Fixes: 379d7ac7ca31 ("phy: mdio-thunder: Add driver for Cavium Thunder SoC MDIO buses.")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Heiner Kallweit <hkallweit1@gmail.com>
+Cc: netdev@vger.kernel.org
+Cc: David Daney <david.daney@cavium.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index e351d65533aa8..06146ae4c6d8d 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -217,6 +217,7 @@ config MDIO_THUNDER
+       depends on 64BIT
+       depends on PCI
+       select MDIO_CAVIUM
++      select MDIO_DEVRES
+       help
+         This driver supports the MDIO interfaces found on Cavium
+         ThunderX SoCs when the MDIO bus device appears as a PCI
+-- 
+2.25.1
+
diff --git a/queue-5.8/mlxsw-spectrum_acl-fix-mlxsw_sp_acl_tcam_group_add-s.patch b/queue-5.8/mlxsw-spectrum_acl-fix-mlxsw_sp_acl_tcam_group_add-s.patch
new file mode 100644 (file)
index 0000000..5b9ded9
--- /dev/null
@@ -0,0 +1,47 @@
+From 38db94f0d730c829bf9ccf494310a0833a78b0a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Sep 2020 09:42:11 +0300
+Subject: mlxsw: spectrum_acl: Fix mlxsw_sp_acl_tcam_group_add()'s error path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 72865028582a678be1e05240e55d452e5c258eca ]
+
+If mlxsw_sp_acl_tcam_group_id_get() fails, the mutex initialized earlier
+is not destroyed.
+
+Fix this by initializing the mutex after calling the function. This is
+symmetric to mlxsw_sp_acl_tcam_group_del().
+
+Fixes: 5ec2ee28d27b ("mlxsw: spectrum_acl: Introduce a mutex to guard region list updates")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index 5c020403342f9..7cccc41dd69c9 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -292,13 +292,14 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp_acl_tcam *tcam,
+       int err;
+       group->tcam = tcam;
+-      mutex_init(&group->lock);
+       INIT_LIST_HEAD(&group->region_list);
+       err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id);
+       if (err)
+               return err;
++      mutex_init(&group->lock);
++
+       return 0;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/mmc-core-don-t-set-limits.discard_granularity-as-0.patch b/queue-5.8/mmc-core-don-t-set-limits.discard_granularity-as-0.patch
new file mode 100644 (file)
index 0000000..403d73c
--- /dev/null
@@ -0,0 +1,70 @@
+From ec52fc9c1c1659f99f34a68b4dc3aa21e61dfca7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Oct 2020 09:38:52 +0800
+Subject: mmc: core: don't set limits.discard_granularity as 0
+
+From: Coly Li <colyli@suse.de>
+
+[ Upstream commit 4243219141b67d7c2fdb2d8073c17c539b9263eb ]
+
+In mmc_queue_setup_discard() the mmc driver queue's discard_granularity
+might be set as 0 (when card->pref_erase > max_discard) while the mmc
+device still declares to support discard operation. This is buggy and
+triggered the following kernel warning message,
+
+WARNING: CPU: 0 PID: 135 at __blkdev_issue_discard+0x200/0x294
+CPU: 0 PID: 135 Comm: f2fs_discard-17 Not tainted 5.9.0-rc6 #1
+Hardware name: Google Kevin (DT)
+pstate: 00000005 (nzcv daif -PAN -UAO BTYPE=--)
+pc : __blkdev_issue_discard+0x200/0x294
+lr : __blkdev_issue_discard+0x54/0x294
+sp : ffff800011dd3b10
+x29: ffff800011dd3b10 x28: 0000000000000000 x27: ffff800011dd3cc4 x26: ffff800011dd3e18 x25: 000000000004e69b x24: 0000000000000c40 x23: ffff0000f1deaaf0 x22: ffff0000f2849200 x21: 00000000002734d8 x20: 0000000000000008 x19: 0000000000000000 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000394 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: 00000000000008b0 x9 : ffff800011dd3cb0 x8 : 000000000004e69b x7 : 0000000000000000 x6 : ffff0000f1926400 x5 : ffff0000f1940800 x4 : 0000000000000000 x3 : 0000000000000c40 x2 : 0000000000000008 x1 : 00000000002734d8 x0 : 0000000000000000 Call trace:
+__blkdev_issue_discard+0x200/0x294
+__submit_discard_cmd+0x128/0x374
+__issue_discard_cmd_orderly+0x188/0x244
+__issue_discard_cmd+0x2e8/0x33c
+issue_discard_thread+0xe8/0x2f0
+kthread+0x11c/0x120
+ret_from_fork+0x10/0x1c
+---[ end trace e4c8023d33dfe77a ]---
+
+This patch fixes the issue by setting discard_granularity as SECTOR_SIZE
+instead of 0 when (card->pref_erase > max_discard) is true. Now no more
+complain from __blkdev_issue_discard() for the improper value of discard
+granularity.
+
+This issue is exposed after commit b35fd7422c2f ("block: check queue's
+limits.discard_granularity in __blkdev_issue_discard()"), a "Fixes:" tag
+is also added for the commit to make sure people won't miss this patch
+after applying the change of __blkdev_issue_discard().
+
+Fixes: e056a1b5b67b ("mmc: queue: let host controllers specify maximum discard timeout")
+Fixes: b35fd7422c2f ("block: check queue's limits.discard_granularity in __blkdev_issue_discard()").
+Reported-and-tested-by: Vicente Bergas <vicencb@gmail.com>
+Signed-off-by: Coly Li <colyli@suse.de>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20201002013852.51968-1-colyli@suse.de
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mmc/core/queue.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
+index 4b1eb89b401d9..1ad518821157f 100644
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -190,7 +190,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
+       q->limits.discard_granularity = card->pref_erase << 9;
+       /* granularity must not be greater than max. discard */
+       if (card->pref_erase > max_discard)
+-              q->limits.discard_granularity = 0;
++              q->limits.discard_granularity = SECTOR_SIZE;
+       if (mmc_can_secure_erase_trim(card))
+               blk_queue_flag_set(QUEUE_FLAG_SECERASE, q);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-dsa-felix-convert-tas-link-speed-based-on-phylin.patch b/queue-5.8/net-dsa-felix-convert-tas-link-speed-based-on-phylin.patch
new file mode 100644 (file)
index 0000000..c6a8165
--- /dev/null
@@ -0,0 +1,59 @@
+From 08c118f7c0d39b3ff8f35351f73f5757dc09cd6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Sep 2020 09:57:46 +0800
+Subject: net: dsa: felix: convert TAS link speed based on phylink speed
+
+From: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
+
+[ Upstream commit dba1e4660a87927bdc03c23e36fd2c81a16a7ab1 ]
+
+state->speed holds a value of 10, 100, 1000 or 2500, but
+QSYS_TAG_CONFIG_LINK_SPEED expects a value of 0, 1, 2, 3. So convert the
+speed to a proper value.
+
+Fixes: de143c0e274b ("net: dsa: felix: Configure Time-Aware Scheduler via taprio offload")
+Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index 7c167a394b762..a83ecd1c5d6c2 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1215,8 +1215,28 @@ static void vsc9959_mdio_bus_free(struct ocelot *ocelot)
+ static void vsc9959_sched_speed_set(struct ocelot *ocelot, int port,
+                                   u32 speed)
+ {
++      u8 tas_speed;
++
++      switch (speed) {
++      case SPEED_10:
++              tas_speed = OCELOT_SPEED_10;
++              break;
++      case SPEED_100:
++              tas_speed = OCELOT_SPEED_100;
++              break;
++      case SPEED_1000:
++              tas_speed = OCELOT_SPEED_1000;
++              break;
++      case SPEED_2500:
++              tas_speed = OCELOT_SPEED_2500;
++              break;
++      default:
++              tas_speed = OCELOT_SPEED_1000;
++              break;
++      }
++
+       ocelot_rmw_rix(ocelot,
+-                     QSYS_TAG_CONFIG_LINK_SPEED(speed),
++                     QSYS_TAG_CONFIG_LINK_SPEED(tas_speed),
+                      QSYS_TAG_CONFIG_LINK_SPEED_M,
+                      QSYS_TAG_CONFIG, port);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-ethernet-cavium-octeon_mgmt-use-phy_start-and-ph.patch b/queue-5.8/net-ethernet-cavium-octeon_mgmt-use-phy_start-and-ph.patch
new file mode 100644 (file)
index 0000000..d51389b
--- /dev/null
@@ -0,0 +1,54 @@
+From 9e7008e4df8f01a06e4b19690ce9f9c414a22d91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Sep 2020 15:44:39 +0300
+Subject: net: ethernet: cavium: octeon_mgmt: use phy_start and phy_stop
+
+From: Ivan Khoronzhuk <ivan.khoronzhuk@gmail.com>
+
+[ Upstream commit 4663ff60257aec4ee1e2e969a7c046f0aff35ab8 ]
+
+To start also "phy state machine", with UP state as it should be,
+the phy_start() has to be used, in another case machine even is not
+triggered. After this change negotiation is supposed to be triggered
+by SM workqueue.
+
+It's not correct usage, but it appears after the following patch,
+so add it as a fix.
+
+Fixes: 74a992b3598a ("net: phy: add phy_check_link_status")
+Signed-off-by: Ivan Khoronzhuk <ikhoronz@cisco.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cavium/octeon/octeon_mgmt.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+index cbaa1924afbe1..706e959bf02ac 100644
+--- a/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
++++ b/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
+@@ -1219,7 +1219,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
+        */
+       if (netdev->phydev) {
+               netif_carrier_off(netdev);
+-              phy_start_aneg(netdev->phydev);
++              phy_start(netdev->phydev);
+       }
+       netif_wake_queue(netdev);
+@@ -1247,8 +1247,10 @@ static int octeon_mgmt_stop(struct net_device *netdev)
+       napi_disable(&p->napi);
+       netif_stop_queue(netdev);
+-      if (netdev->phydev)
++      if (netdev->phydev) {
++              phy_stop(netdev->phydev);
+               phy_disconnect(netdev->phydev);
++      }
+       netif_carrier_off(netdev);
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-hinic-fix-devlink-build-errors.patch b/queue-5.8/net-hinic-fix-devlink-build-errors.patch
new file mode 100644 (file)
index 0000000..c756942
--- /dev/null
@@ -0,0 +1,62 @@
+From 099bc6f51926c54ccff81dd23286a7b4ae40093c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Oct 2020 10:54:49 -0700
+Subject: net: hinic: fix DEVLINK build errors
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit 1f7e877c20517735bceff1535e1b7fa846b2f215 ]
+
+Fix many (lots deleted here) build errors in hinic by selecting NET_DEVLINK.
+
+ld: drivers/net/ethernet/huawei/hinic/hinic_hw_dev.o: in function `mgmt_watchdog_timeout_event_handler':
+hinic_hw_dev.c:(.text+0x30a): undefined reference to `devlink_health_report'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_fw_reporter_dump':
+hinic_devlink.c:(.text+0x1c): undefined reference to `devlink_fmsg_u32_pair_put'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_fw_reporter_dump':
+hinic_devlink.c:(.text+0x126): undefined reference to `devlink_fmsg_binary_pair_put'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_hw_reporter_dump':
+hinic_devlink.c:(.text+0x1ba): undefined reference to `devlink_fmsg_string_pair_put'
+ld: hinic_devlink.c:(.text+0x227): undefined reference to `devlink_fmsg_u8_pair_put'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_devlink_alloc':
+hinic_devlink.c:(.text+0xaee): undefined reference to `devlink_alloc'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_devlink_free':
+hinic_devlink.c:(.text+0xb04): undefined reference to `devlink_free'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_devlink_register':
+hinic_devlink.c:(.text+0xb26): undefined reference to `devlink_register'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_devlink_unregister':
+hinic_devlink.c:(.text+0xb46): undefined reference to `devlink_unregister'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_health_reporters_create':
+hinic_devlink.c:(.text+0xb75): undefined reference to `devlink_health_reporter_create'
+ld: hinic_devlink.c:(.text+0xb95): undefined reference to `devlink_health_reporter_create'
+ld: hinic_devlink.c:(.text+0xbac): undefined reference to `devlink_health_reporter_destroy'
+ld: drivers/net/ethernet/huawei/hinic/hinic_devlink.o: in function `hinic_health_reporters_destroy':
+
+Fixes: 51ba902a16e6 ("net-next/hinic: Initialize hw interface")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Cc: Bin Luo <luobin9@huawei.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Aviad Krawczyk <aviad.krawczyk@huawei.com>
+Cc: Zhao Chen <zhaochen6@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/huawei/hinic/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/huawei/hinic/Kconfig b/drivers/net/ethernet/huawei/hinic/Kconfig
+index 936e2dd3bb135..b47bd5440c5f0 100644
+--- a/drivers/net/ethernet/huawei/hinic/Kconfig
++++ b/drivers/net/ethernet/huawei/hinic/Kconfig
+@@ -6,6 +6,7 @@
+ config HINIC
+       tristate "Huawei Intelligent PCIE Network Interface Card"
+       depends on (PCI_MSI && (X86 || ARM64))
++      select NET_DEVLINK
+       help
+         This driver supports HiNIC PCIE Ethernet cards.
+         To compile this driver as part of the kernel, choose Y here.
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5-add-retry-mechanism-to-the-command-entry-in.patch b/queue-5.8/net-mlx5-add-retry-mechanism-to-the-command-entry-in.patch
new file mode 100644 (file)
index 0000000..6217564
--- /dev/null
@@ -0,0 +1,69 @@
+From e4fc4b14a9882fdca0c88ee695afb0f5e98a04a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Aug 2020 15:04:35 +0300
+Subject: net/mlx5: Add retry mechanism to the command entry index allocation
+
+From: Eran Ben Elisha <eranbe@nvidia.com>
+
+[ Upstream commit 410bd754cd73c4a2ac3856d9a03d7b08f9c906bf ]
+
+It is possible that new command entry index allocation will temporarily
+fail. The new command holds the semaphore, so it means that a free entry
+should be ready soon. Add one second retry mechanism before returning an
+error.
+
+Patch "net/mlx5: Avoid possible free of command entry while timeout comp
+handler" increase the possibility to bump into this temporarily failure
+as it delays the entry index release for non-callback commands.
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Eran Ben Elisha <eranbe@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 21 ++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 37dae95e61d5f..2b597ac365f84 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -883,6 +883,25 @@ static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)
+       return cmd->allowed_opcode == opcode;
+ }
++static int cmd_alloc_index_retry(struct mlx5_cmd *cmd)
++{
++      unsigned long alloc_end = jiffies + msecs_to_jiffies(1000);
++      int idx;
++
++retry:
++      idx = cmd_alloc_index(cmd);
++      if (idx < 0 && time_before(jiffies, alloc_end)) {
++              /* Index allocation can fail on heavy load of commands. This is a temporary
++               * situation as the current command already holds the semaphore, meaning that
++               * another command completion is being handled and it is expected to release
++               * the entry index soon.
++               */
++              cpu_relax();
++              goto retry;
++      }
++      return idx;
++}
++
+ static void cmd_work_handler(struct work_struct *work)
+ {
+       struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
+@@ -900,7 +919,7 @@ static void cmd_work_handler(struct work_struct *work)
+       sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
+       down(sem);
+       if (!ent->page_queue) {
+-              alloc_ret = cmd_alloc_index(cmd);
++              alloc_ret = cmd_alloc_index_retry(cmd);
+               if (alloc_ret < 0) {
+                       mlx5_core_err_rl(dev, "failed to allocate command entry\n");
+                       if (ent->callback) {
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5-avoid-possible-free-of-command-entry-while-.patch b/queue-5.8/net-mlx5-avoid-possible-free-of-command-entry-while-.patch
new file mode 100644 (file)
index 0000000..967f07d
--- /dev/null
@@ -0,0 +1,337 @@
+From bb9b3734c22098f899ca675a5933315e495e03a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Aug 2020 10:40:21 +0300
+Subject: net/mlx5: Avoid possible free of command entry while timeout comp
+ handler
+
+From: Eran Ben Elisha <eranbe@mellanox.com>
+
+[ Upstream commit 50b2412b7e7862c5af0cbf4b10d93bc5c712d021 ]
+
+Upon command completion timeout, driver simulates a forced command
+completion. In a rare case where real interrupt for that command arrives
+simultaneously, it might release the command entry while the forced
+handler might still access it.
+
+Fix that by adding an entry refcount, to track current amount of allowed
+handlers. Command entry to be released only when this refcount is
+decremented to zero.
+
+Command refcount is always initialized to one. For callback commands,
+command completion handler is the symmetric flow to decrement it. For
+non-callback commands, it is wait_func().
+
+Before ringing the doorbell, increment the refcount for the real completion
+handler. Once the real completion handler is called, it will decrement it.
+
+For callback commands, once the delayed work is scheduled, increment the
+refcount. Upon callback command completion handler, we will try to cancel
+the timeout callback. In case of success, we need to decrement the callback
+refcount as it will never run.
+
+In addition, gather the entry index free and the entry free into a one
+flow for all command types release.
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
+Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 109 ++++++++++++------
+ include/linux/mlx5/driver.h                   |   2 +
+ 2 files changed, 73 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 1d91a0d0ab1d7..c0055f5479ce0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -69,12 +69,10 @@ enum {
+       MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR            = 0x10,
+ };
+-static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
+-                                         struct mlx5_cmd_msg *in,
+-                                         struct mlx5_cmd_msg *out,
+-                                         void *uout, int uout_size,
+-                                         mlx5_cmd_cbk_t cbk,
+-                                         void *context, int page_queue)
++static struct mlx5_cmd_work_ent *
++cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in,
++            struct mlx5_cmd_msg *out, void *uout, int uout_size,
++            mlx5_cmd_cbk_t cbk, void *context, int page_queue)
+ {
+       gfp_t alloc_flags = cbk ? GFP_ATOMIC : GFP_KERNEL;
+       struct mlx5_cmd_work_ent *ent;
+@@ -83,6 +81,7 @@ static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
+       if (!ent)
+               return ERR_PTR(-ENOMEM);
++      ent->idx        = -EINVAL;
+       ent->in         = in;
+       ent->out        = out;
+       ent->uout       = uout;
+@@ -91,10 +90,16 @@ static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd,
+       ent->context    = context;
+       ent->cmd        = cmd;
+       ent->page_queue = page_queue;
++      refcount_set(&ent->refcnt, 1);
+       return ent;
+ }
++static void cmd_free_ent(struct mlx5_cmd_work_ent *ent)
++{
++      kfree(ent);
++}
++
+ static u8 alloc_token(struct mlx5_cmd *cmd)
+ {
+       u8 token;
+@@ -109,7 +114,7 @@ static u8 alloc_token(struct mlx5_cmd *cmd)
+       return token;
+ }
+-static int alloc_ent(struct mlx5_cmd *cmd)
++static int cmd_alloc_index(struct mlx5_cmd *cmd)
+ {
+       unsigned long flags;
+       int ret;
+@@ -123,7 +128,7 @@ static int alloc_ent(struct mlx5_cmd *cmd)
+       return ret < cmd->max_reg_cmds ? ret : -ENOMEM;
+ }
+-static void free_ent(struct mlx5_cmd *cmd, int idx)
++static void cmd_free_index(struct mlx5_cmd *cmd, int idx)
+ {
+       unsigned long flags;
+@@ -132,6 +137,22 @@ static void free_ent(struct mlx5_cmd *cmd, int idx)
+       spin_unlock_irqrestore(&cmd->alloc_lock, flags);
+ }
++static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
++{
++      refcount_inc(&ent->refcnt);
++}
++
++static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
++{
++      if (!refcount_dec_and_test(&ent->refcnt))
++              return;
++
++      if (ent->idx >= 0)
++              cmd_free_index(ent->cmd, ent->idx);
++
++      cmd_free_ent(ent);
++}
++
+ static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx)
+ {
+       return cmd->cmd_buf + (idx << cmd->log_stride);
+@@ -219,11 +240,6 @@ static void poll_timeout(struct mlx5_cmd_work_ent *ent)
+       ent->ret = -ETIMEDOUT;
+ }
+-static void free_cmd(struct mlx5_cmd_work_ent *ent)
+-{
+-      kfree(ent);
+-}
+-
+ static int verify_signature(struct mlx5_cmd_work_ent *ent)
+ {
+       struct mlx5_cmd_mailbox *next = ent->out->next;
+@@ -842,6 +858,7 @@ static void cb_timeout_handler(struct work_struct *work)
+                      mlx5_command_str(msg_to_opcode(ent->in)),
+                      msg_to_opcode(ent->in));
+       mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
++      cmd_ent_put(ent); /* for the cmd_ent_get() took on schedule delayed work */
+ }
+ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
+@@ -873,14 +890,14 @@ static void cmd_work_handler(struct work_struct *work)
+       sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
+       down(sem);
+       if (!ent->page_queue) {
+-              alloc_ret = alloc_ent(cmd);
++              alloc_ret = cmd_alloc_index(cmd);
+               if (alloc_ret < 0) {
+                       mlx5_core_err_rl(dev, "failed to allocate command entry\n");
+                       if (ent->callback) {
+                               ent->callback(-EAGAIN, ent->context);
+                               mlx5_free_cmd_msg(dev, ent->out);
+                               free_msg(dev, ent->in);
+-                              free_cmd(ent);
++                              cmd_ent_put(ent);
+                       } else {
+                               ent->ret = -EAGAIN;
+                               complete(&ent->done);
+@@ -916,8 +933,8 @@ static void cmd_work_handler(struct work_struct *work)
+       ent->ts1 = ktime_get_ns();
+       cmd_mode = cmd->mode;
+-      if (ent->callback)
+-              schedule_delayed_work(&ent->cb_timeout_work, cb_timeout);
++      if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, cb_timeout))
++              cmd_ent_get(ent);
+       set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
+       /* Skip sending command to fw if internal error */
+@@ -933,13 +950,10 @@ static void cmd_work_handler(struct work_struct *work)
+               MLX5_SET(mbox_out, ent->out, syndrome, drv_synd);
+               mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
+-              /* no doorbell, no need to keep the entry */
+-              free_ent(cmd, ent->idx);
+-              if (ent->callback)
+-                      free_cmd(ent);
+               return;
+       }
++      cmd_ent_get(ent); /* for the _real_ FW event on completion */
+       /* ring doorbell after the descriptor is valid */
+       mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
+       wmb();
+@@ -1039,11 +1053,16 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
+       if (callback && page_queue)
+               return -EINVAL;
+-      ent = alloc_cmd(cmd, in, out, uout, uout_size, callback, context,
+-                      page_queue);
++      ent = cmd_alloc_ent(cmd, in, out, uout, uout_size,
++                          callback, context, page_queue);
+       if (IS_ERR(ent))
+               return PTR_ERR(ent);
++      /* put for this ent is when consumed, depending on the use case
++       * 1) (!callback) blocking flow: by caller after wait_func completes
++       * 2) (callback) flow: by mlx5_cmd_comp_handler() when ent is handled
++       */
++
+       ent->token = token;
+       ent->polling = force_polling;
+@@ -1062,12 +1081,10 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
+       }
+       if (callback)
+-              goto out;
++              goto out; /* mlx5_cmd_comp_handler() will put(ent) */
+       err = wait_func(dev, ent);
+-      if (err == -ETIMEDOUT)
+-              goto out;
+-      if (err == -ECANCELED)
++      if (err == -ETIMEDOUT || err == -ECANCELED)
+               goto out_free;
+       ds = ent->ts2 - ent->ts1;
+@@ -1085,7 +1102,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
+       *status = ent->status;
+ out_free:
+-      free_cmd(ent);
++      cmd_ent_put(ent);
+ out:
+       return err;
+ }
+@@ -1516,14 +1533,19 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+                               if (!forced) {
+                                       mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n",
+                                                     ent->idx);
+-                                      free_ent(cmd, ent->idx);
+-                                      free_cmd(ent);
++                                      cmd_ent_put(ent);
+                               }
+                               continue;
+                       }
+-                      if (ent->callback)
+-                              cancel_delayed_work(&ent->cb_timeout_work);
++                      if (ent->callback && cancel_delayed_work(&ent->cb_timeout_work))
++                              cmd_ent_put(ent); /* timeout work was canceled */
++
++                      if (!forced || /* Real FW completion */
++                          pci_channel_offline(dev->pdev) || /* FW is inaccessible */
++                          dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
++                              cmd_ent_put(ent);
++
+                       if (ent->page_queue)
+                               sem = &cmd->pages_sem;
+                       else
+@@ -1545,10 +1567,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+                                             ent->ret, deliv_status_to_str(ent->status), ent->status);
+                       }
+-                      /* only real completion will free the entry slot */
+-                      if (!forced)
+-                              free_ent(cmd, ent->idx);
+-
+                       if (ent->callback) {
+                               ds = ent->ts2 - ent->ts1;
+                               if (ent->op < MLX5_CMD_OP_MAX) {
+@@ -1576,10 +1594,13 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+                               free_msg(dev, ent->in);
+                               err = err ? err : ent->status;
+-                              if (!forced)
+-                                      free_cmd(ent);
++                              /* final consumer is done, release ent */
++                              cmd_ent_put(ent);
+                               callback(err, context);
+                       } else {
++                              /* release wait_func() so mlx5_cmd_invoke()
++                               * can make the final ent_put()
++                               */
+                               complete(&ent->done);
+                       }
+                       up(sem);
+@@ -1589,8 +1610,11 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+ void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
+ {
++      struct mlx5_cmd *cmd = &dev->cmd;
++      unsigned long bitmask;
+       unsigned long flags;
+       u64 vector;
++      int i;
+       /* wait for pending handlers to complete */
+       mlx5_eq_synchronize_cmd_irq(dev);
+@@ -1599,11 +1623,20 @@ void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
+       if (!vector)
+               goto no_trig;
++      bitmask = vector;
++      /* we must increment the allocated entries refcount before triggering the completions
++       * to guarantee pending commands will not get freed in the meanwhile.
++       * For that reason, it also has to be done inside the alloc_lock.
++       */
++      for_each_set_bit(i, &bitmask, (1 << cmd->log_sz))
++              cmd_ent_get(cmd->ent_arr[i]);
+       vector |= MLX5_TRIGGERED_CMD_COMP;
+       spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
+       mlx5_core_dbg(dev, "vector 0x%llx\n", vector);
+       mlx5_cmd_comp_handler(dev, vector, true);
++      for_each_set_bit(i, &bitmask, (1 << cmd->log_sz))
++              cmd_ent_put(cmd->ent_arr[i]);
+       return;
+ no_trig:
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 1e6ca716635a9..484cd8ba869c5 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -764,6 +764,8 @@ struct mlx5_cmd_work_ent {
+       u64                     ts2;
+       u16                     op;
+       bool                    polling;
++      /* Track the max comp handlers */
++      refcount_t              refcnt;
+ };
+ struct mlx5_pas {
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5-fix-a-race-when-moving-command-interface-to.patch b/queue-5.8/net-mlx5-fix-a-race-when-moving-command-interface-to.patch
new file mode 100644 (file)
index 0000000..a0c55fc
--- /dev/null
@@ -0,0 +1,48 @@
+From d6e2bb53af7adf1d65646f6015381e7d4de4755c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 16:55:20 +0300
+Subject: net/mlx5: Fix a race when moving command interface to polling mode
+
+From: Eran Ben Elisha <eranbe@mellanox.com>
+
+[ Upstream commit 432161ea26d6d5e5c3f7306d9407d26ed1e1953e ]
+
+As part of driver unload, it destroys the commands EQ (via FW command).
+As the commands EQ is destroyed, FW will not generate EQEs for any command
+that driver sends afterwards. Driver should poll for later commands status.
+
+Driver commands mode metadata is updated before the commands EQ is
+actually destroyed. This can lead for double completion handle by the
+driver (polling and interrupt), if a command is executed and completed by
+FW after the mode was changed, but before the EQ was destroyed.
+
+Fix that by using the mlx5_cmd_allowed_opcode mechanism to guarantee
+that only DESTROY_EQ command can be executed during this time period.
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
+Reviewed-by: Moshe Shemesh <moshe@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/eq.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+index 31ef9f8420c87..1318d774b18f2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+@@ -656,8 +656,10 @@ static void destroy_async_eqs(struct mlx5_core_dev *dev)
+       cleanup_async_eq(dev, &table->pages_eq, "pages");
+       cleanup_async_eq(dev, &table->async_eq, "async");
++      mlx5_cmd_allowed_opcode(dev, MLX5_CMD_OP_DESTROY_EQ);
+       mlx5_cmd_use_polling(dev);
+       cleanup_async_eq(dev, &table->cmd_eq, "cmd");
++      mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL);
+       mlx5_eq_notifier_unregister(dev, &table->cq_err_nb);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5-fix-request_irqs-error-flow.patch b/queue-5.8/net-mlx5-fix-request_irqs-error-flow.patch
new file mode 100644 (file)
index 0000000..d302e9c
--- /dev/null
@@ -0,0 +1,80 @@
+From 59366a5aabec18cf14e5a8e68e1bf0aca71ce4ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 31 Aug 2020 21:37:31 +0300
+Subject: net/mlx5: Fix request_irqs error flow
+
+From: Maor Gottlieb <maorg@nvidia.com>
+
+[ Upstream commit 732ebfab7fe96b7ac9a3df3208f14752a4bb6db3 ]
+
+Fix error flow handling in request_irqs which try to free irq
+that we failed to request.
+It fixes the below trace.
+
+WARNING: CPU: 1 PID: 7587 at kernel/irq/manage.c:1684 free_irq+0x4d/0x60
+CPU: 1 PID: 7587 Comm: bash Tainted: G        W  OE    4.15.15-1.el7MELLANOXsmp-x86_64 #1
+Hardware name: Advantech SKY-6200/SKY-6200, BIOS F2.00 08/06/2020
+RIP: 0010:free_irq+0x4d/0x60
+RSP: 0018:ffffc9000ef47af0 EFLAGS: 00010282
+RAX: ffff88001476ae00 RBX: 0000000000000655 RCX: 0000000000000000
+RDX: ffff88001476ae00 RSI: ffffc9000ef47ab8 RDI: ffff8800398bb478
+RBP: ffff88001476a838 R08: ffff88001476ae00 R09: 000000000000156d
+R10: 0000000000000000 R11: 0000000000000004 R12: ffff88001476a838
+R13: 0000000000000006 R14: ffff88001476a888 R15: 00000000ffffffe4
+FS:  00007efeadd32740(0000) GS:ffff88047fc40000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007fc9cc010008 CR3: 00000001a2380004 CR4: 00000000007606e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ mlx5_irq_table_create+0x38d/0x400 [mlx5_core]
+ ? atomic_notifier_chain_register+0x50/0x60
+ mlx5_load_one+0x7ee/0x1130 [mlx5_core]
+ init_one+0x4c9/0x650 [mlx5_core]
+ pci_device_probe+0xb8/0x120
+ driver_probe_device+0x2a1/0x470
+ ? driver_allows_async_probing+0x30/0x30
+ bus_for_each_drv+0x54/0x80
+ __device_attach+0xa3/0x100
+ pci_bus_add_device+0x4a/0x90
+ pci_iov_add_virtfn+0x2dc/0x2f0
+ pci_enable_sriov+0x32e/0x420
+ mlx5_core_sriov_configure+0x61/0x1b0 [mlx5_core]
+ ? kstrtoll+0x22/0x70
+ num_vf_store+0x4b/0x70 [mlx5_core]
+ kernfs_fop_write+0x102/0x180
+ __vfs_write+0x26/0x140
+ ? rcu_all_qs+0x5/0x80
+ ? _cond_resched+0x15/0x30
+ ? __sb_start_write+0x41/0x80
+ vfs_write+0xad/0x1a0
+ SyS_write+0x42/0x90
+ do_syscall_64+0x60/0x110
+ entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+
+Fixes: 24163189da48 ("net/mlx5: Separate IRQ request/free from EQ life cycle")
+Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
+Reviewed-by: Eran Ben Elisha <eranbe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+index 373981a659c7c..6fd9749203944 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+@@ -115,7 +115,7 @@ static int request_irqs(struct mlx5_core_dev *dev, int nvec)
+       return 0;
+ err_request_irq:
+-      for (; i >= 0; i--) {
++      while (i--) {
+               struct mlx5_irq *irq = mlx5_irq_get(dev, i);
+               int irqn = pci_irq_vector(dev->pdev, i);
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5-poll-cmd-eq-in-case-of-command-timeout.patch b/queue-5.8/net-mlx5-poll-cmd-eq-in-case-of-command-timeout.patch
new file mode 100644 (file)
index 0000000..3e4b1dc
--- /dev/null
@@ -0,0 +1,222 @@
+From 37d9534d2aa73452a10cbd0864821ad6b89558b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2020 10:25:52 +0300
+Subject: net/mlx5: poll cmd EQ in case of command timeout
+
+From: Eran Ben Elisha <eranbe@mellanox.com>
+
+[ Upstream commit 1d5558b1f0de81f54ddee05f3793acc5260d107f ]
+
+Once driver detects a command interface command timeout, it warns the
+user and returns timeout error to the caller. In such case, the entry of
+the command is not evacuated (because only real event interrupt is allowed
+to clear command interface entry). If the HW event interrupt
+of this entry will never arrive, this entry will be left unused forever.
+Command interface entries are limited and eventually we can end up without
+the ability to post a new command.
+
+In addition, if driver will not consume the EQE of the lost interrupt and
+rearm the EQ, no new interrupts will arrive for other commands.
+
+Add a resiliency mechanism for manually polling the command EQ in case of
+a command timeout. In case resiliency mechanism will find non-handled EQE,
+it will consume it, and the command interface will be fully functional
+again. Once the resiliency flow finished, wait another 5 seconds for the
+command interface to complete for this command entry.
+
+Define mlx5_cmd_eq_recover() to manage the cmd EQ polling resiliency flow.
+Add an async EQ spinlock to avoid races between resiliency flows and real
+interrupts that might run simultaneously.
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 53 ++++++++++++++++---
+ drivers/net/ethernet/mellanox/mlx5/core/eq.c  | 40 +++++++++++++-
+ .../net/ethernet/mellanox/mlx5/core/lib/eq.h  |  2 +
+ 3 files changed, 86 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index c0055f5479ce0..37dae95e61d5f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -853,11 +853,21 @@ static void cb_timeout_handler(struct work_struct *work)
+       struct mlx5_core_dev *dev = container_of(ent->cmd, struct mlx5_core_dev,
+                                                cmd);
++      mlx5_cmd_eq_recover(dev);
++
++      /* Maybe got handled by eq recover ? */
++      if (!test_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state)) {
++              mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, recovered after timeout\n", ent->idx,
++                             mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
++              goto out; /* phew, already handled */
++      }
++
+       ent->ret = -ETIMEDOUT;
+-      mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
+-                     mlx5_command_str(msg_to_opcode(ent->in)),
+-                     msg_to_opcode(ent->in));
++      mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n",
++                     ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
+       mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
++
++out:
+       cmd_ent_put(ent); /* for the cmd_ent_get() took on schedule delayed work */
+ }
+@@ -997,6 +1007,35 @@ static const char *deliv_status_to_str(u8 status)
+       }
+ }
++enum {
++      MLX5_CMD_TIMEOUT_RECOVER_MSEC   = 5 * 1000,
++};
++
++static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev,
++                                        struct mlx5_cmd_work_ent *ent)
++{
++      unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_RECOVER_MSEC);
++
++      mlx5_cmd_eq_recover(dev);
++
++      /* Re-wait on the ent->done after executing the recovery flow. If the
++       * recovery flow (or any other recovery flow running simultaneously)
++       * has recovered an EQE, it should cause the entry to be completed by
++       * the command interface.
++       */
++      if (wait_for_completion_timeout(&ent->done, timeout)) {
++              mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) recovered after timeout\n", ent->idx,
++                             mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
++              return;
++      }
++
++      mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) No done completion\n", ent->idx,
++                     mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in));
++
++      ent->ret = -ETIMEDOUT;
++      mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
++}
++
+ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
+ {
+       unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
+@@ -1008,12 +1047,10 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
+               ent->ret = -ECANCELED;
+               goto out_err;
+       }
+-      if (cmd->mode == CMD_MODE_POLLING || ent->polling) {
++      if (cmd->mode == CMD_MODE_POLLING || ent->polling)
+               wait_for_completion(&ent->done);
+-      } else if (!wait_for_completion_timeout(&ent->done, timeout)) {
+-              ent->ret = -ETIMEDOUT;
+-              mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
+-      }
++      else if (!wait_for_completion_timeout(&ent->done, timeout))
++              wait_func_handle_exec_timeout(dev, ent);
+ out_err:
+       err = ent->ret;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+index 1318d774b18f2..22a19d391e179 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+@@ -189,6 +189,29 @@ u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq)
+       return count_eqe;
+ }
++static void mlx5_eq_async_int_lock(struct mlx5_eq_async *eq, unsigned long *flags)
++      __acquires(&eq->lock)
++{
++      if (in_irq())
++              spin_lock(&eq->lock);
++      else
++              spin_lock_irqsave(&eq->lock, *flags);
++}
++
++static void mlx5_eq_async_int_unlock(struct mlx5_eq_async *eq, unsigned long *flags)
++      __releases(&eq->lock)
++{
++      if (in_irq())
++              spin_unlock(&eq->lock);
++      else
++              spin_unlock_irqrestore(&eq->lock, *flags);
++}
++
++enum async_eq_nb_action {
++      ASYNC_EQ_IRQ_HANDLER = 0,
++      ASYNC_EQ_RECOVER = 1,
++};
++
+ static int mlx5_eq_async_int(struct notifier_block *nb,
+                            unsigned long action, void *data)
+ {
+@@ -198,11 +221,14 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
+       struct mlx5_eq_table *eqt;
+       struct mlx5_core_dev *dev;
+       struct mlx5_eqe *eqe;
++      unsigned long flags;
+       int num_eqes = 0;
+       dev = eq->dev;
+       eqt = dev->priv.eq_table;
++      mlx5_eq_async_int_lock(eq_async, &flags);
++
+       eqe = next_eqe_sw(eq);
+       if (!eqe)
+               goto out;
+@@ -223,8 +249,19 @@ static int mlx5_eq_async_int(struct notifier_block *nb,
+ out:
+       eq_update_ci(eq, 1);
++      mlx5_eq_async_int_unlock(eq_async, &flags);
+-      return 0;
++      return unlikely(action == ASYNC_EQ_RECOVER) ? num_eqes : 0;
++}
++
++void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev)
++{
++      struct mlx5_eq_async *eq = &dev->priv.eq_table->cmd_eq;
++      int eqes;
++
++      eqes = mlx5_eq_async_int(&eq->irq_nb, ASYNC_EQ_RECOVER, NULL);
++      if (eqes)
++              mlx5_core_warn(dev, "Recovered %d EQEs on cmd_eq\n", eqes);
+ }
+ static void init_eq_buf(struct mlx5_eq *eq)
+@@ -569,6 +606,7 @@ setup_async_eq(struct mlx5_core_dev *dev, struct mlx5_eq_async *eq,
+       int err;
+       eq->irq_nb.notifier_call = mlx5_eq_async_int;
++      spin_lock_init(&eq->lock);
+       err = create_async_eq(dev, &eq->core, param);
+       if (err) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h
+index 4aaca7400fb29..5c681e31983bc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h
+@@ -37,6 +37,7 @@ struct mlx5_eq {
+ struct mlx5_eq_async {
+       struct mlx5_eq          core;
+       struct notifier_block   irq_nb;
++      spinlock_t              lock; /* To avoid irq EQ handle races with resiliency flows */
+ };
+ struct mlx5_eq_comp {
+@@ -81,6 +82,7 @@ void mlx5_cq_tasklet_cb(unsigned long data);
+ struct cpumask *mlx5_eq_comp_cpumask(struct mlx5_core_dev *dev, int ix);
+ u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq);
++void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev);
+ void mlx5_eq_synchronize_async_irq(struct mlx5_core_dev *dev);
+ void mlx5_eq_synchronize_cmd_irq(struct mlx5_core_dev *dev);
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5e-add-resiliency-in-striding-rq-mode-for-pac.patch b/queue-5.8/net-mlx5e-add-resiliency-in-striding-rq-mode-for-pac.patch
new file mode 100644 (file)
index 0000000..ee71ee8
--- /dev/null
@@ -0,0 +1,199 @@
+From 6c0b169fb7769fcc7f294a15c68b6663af98d236 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jul 2020 16:53:18 +0300
+Subject: net/mlx5e: Add resiliency in Striding RQ mode for packets larger than
+ MTU
+
+From: Aya Levin <ayal@mellanox.com>
+
+[ Upstream commit c3c9402373fe20e2d08c04f437ce4dcd252cffb2 ]
+
+Prior to this fix, in Striding RQ mode the driver was vulnerable when
+receiving packets in the range (stride size - headroom, stride size].
+Where stride size is calculated by mtu+headroom+tailroom aligned to the
+closest power of 2.
+Usually, this filtering is performed by the HW, except for a few cases:
+- Between 2 VFs over the same PF with different MTUs
+- On bluefield, when the host physical function sets a larger MTU than
+  the ARM has configured on its representor and uplink representor.
+
+When the HW filtering is not present, packets that are larger than MTU
+might be harmful for the RQ's integrity, in the following impacts:
+1) Overflow from one WQE to the next, causing a memory corruption that
+in most cases is unharmful: as the write happens to the headroom of next
+packet, which will be overwritten by build_skb(). In very rare cases,
+high stress/load, this is harmful. When the next WQE is not yet reposted
+and points to existing SKB head.
+2) Each oversize packet overflows to the headroom of the next WQE. On
+the last WQE of the WQ, where addresses wrap-around, the address of the
+remainder headroom does not belong to the next WQE, but it is out of the
+memory region range. This results in a HW CQE error that moves the RQ
+into an error state.
+
+Solution:
+Add a page buffer at the end of each WQE to absorb the leak. Actually
+the maximal overflow size is headroom but since all memory units must be
+of the same size, we use page size to comply with UMR WQEs. The increase
+in memory consumption is of a single page per RQ. Initialize the mkey
+with all MTTs pointing to a default page. When the channels are
+activated, UMR WQEs will redirect the RX WQEs to the actual memory from
+the RQ's pool, while the overflow MTTs remain mapped to the default page.
+
+Fixes: 73281b78a37a ("net/mlx5e: Derive Striding RQ size from MTU")
+Signed-off-by: Aya Levin <ayal@mellanox.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h  |  8 ++-
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 55 +++++++++++++++++--
+ 2 files changed, 58 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index 76b23ba7a4687..cb3857e136d62 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -90,7 +90,12 @@ struct page_pool;
+ #define MLX5_MPWRQ_PAGES_PER_WQE              BIT(MLX5_MPWRQ_WQE_PAGE_ORDER)
+ #define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2)
+-#define MLX5E_REQUIRED_WQE_MTTS               (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8))
++/* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between
++ * WQEs, This page will absorb write overflow by the hardware, when
++ * receiving packets larger than MTU. These oversize packets are
++ * dropped by the driver at a later stage.
++ */
++#define MLX5E_REQUIRED_WQE_MTTS               (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE + 1, 8))
+ #define MLX5E_LOG_ALIGNED_MPWQE_PPW   (ilog2(MLX5E_REQUIRED_WQE_MTTS))
+ #define MLX5E_REQUIRED_MTTS(wqes)     (wqes * MLX5E_REQUIRED_WQE_MTTS)
+ #define MLX5E_MAX_RQ_NUM_MTTS \
+@@ -621,6 +626,7 @@ struct mlx5e_rq {
+       u32                    rqn;
+       struct mlx5_core_dev  *mdev;
+       struct mlx5_core_mkey  umr_mkey;
++      struct mlx5e_dma_info  wqe_overflow;
+       /* XDP read-mostly */
+       struct xdp_rxq_info    xdp_rxq;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index cccf65fc116ee..b23ad0b6761c4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -258,12 +258,17 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
+ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
+                                u64 npages, u8 page_shift,
+-                               struct mlx5_core_mkey *umr_mkey)
++                               struct mlx5_core_mkey *umr_mkey,
++                               dma_addr_t filler_addr)
+ {
+-      int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
++      struct mlx5_mtt *mtt;
++      int inlen;
+       void *mkc;
+       u32 *in;
+       int err;
++      int i;
++
++      inlen = MLX5_ST_SZ_BYTES(create_mkey_in) + sizeof(*mtt) * npages;
+       in = kvzalloc(inlen, GFP_KERNEL);
+       if (!in)
+@@ -283,6 +288,18 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
+       MLX5_SET(mkc, mkc, translations_octword_size,
+                MLX5_MTT_OCTW(npages));
+       MLX5_SET(mkc, mkc, log_page_size, page_shift);
++      MLX5_SET(create_mkey_in, in, translations_octword_actual_size,
++               MLX5_MTT_OCTW(npages));
++
++      /* Initialize the mkey with all MTTs pointing to a default
++       * page (filler_addr). When the channels are activated, UMR
++       * WQEs will redirect the RX WQEs to the actual memory from
++       * the RQ's pool, while the gaps (wqe_overflow) remain mapped
++       * to the default page.
++       */
++      mtt = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt);
++      for (i = 0 ; i < npages ; i++)
++              mtt[i].ptag = cpu_to_be64(filler_addr);
+       err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen);
+@@ -294,7 +311,8 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq
+ {
+       u64 num_mtts = MLX5E_REQUIRED_MTTS(mlx5_wq_ll_get_size(&rq->mpwqe.wq));
+-      return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey);
++      return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey,
++                                   rq->wqe_overflow.addr);
+ }
+ static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix)
+@@ -362,6 +380,28 @@ static void mlx5e_rq_err_cqe_work(struct work_struct *recover_work)
+       mlx5e_reporter_rq_cqe_err(rq);
+ }
++static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
++{
++      rq->wqe_overflow.page = alloc_page(GFP_KERNEL);
++      if (!rq->wqe_overflow.page)
++              return -ENOMEM;
++
++      rq->wqe_overflow.addr = dma_map_page(rq->pdev, rq->wqe_overflow.page, 0,
++                                           PAGE_SIZE, rq->buff.map_dir);
++      if (dma_mapping_error(rq->pdev, rq->wqe_overflow.addr)) {
++              __free_page(rq->wqe_overflow.page);
++              return -ENOMEM;
++      }
++      return 0;
++}
++
++static void mlx5e_free_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
++{
++       dma_unmap_page(rq->pdev, rq->wqe_overflow.addr, PAGE_SIZE,
++                      rq->buff.map_dir);
++       __free_page(rq->wqe_overflow.page);
++}
++
+ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
+                         struct mlx5e_params *params,
+                         struct mlx5e_xsk_param *xsk,
+@@ -421,6 +461,10 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
+               if (err)
+                       goto err_rq_wq_destroy;
++              err = mlx5e_alloc_mpwqe_rq_drop_page(rq);
++              if (err)
++                      goto err_rq_wq_destroy;
++
+               rq->mpwqe.wq.db = &rq->mpwqe.wq.db[MLX5_RCV_DBR];
+               wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
+@@ -459,7 +503,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
+               err = mlx5e_create_rq_umr_mkey(mdev, rq);
+               if (err)
+-                      goto err_rq_wq_destroy;
++                      goto err_rq_drop_page;
+               rq->mkey_be = cpu_to_be32(rq->umr_mkey.key);
+               err = mlx5e_rq_alloc_mpwqe_info(rq, c);
+@@ -598,6 +642,8 @@ err_free:
+       case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+               kvfree(rq->mpwqe.info);
+               mlx5_core_destroy_mkey(mdev, &rq->umr_mkey);
++err_rq_drop_page:
++              mlx5e_free_mpwqe_rq_drop_page(rq);
+               break;
+       default: /* MLX5_WQ_TYPE_CYCLIC */
+               kvfree(rq->wqe.frags);
+@@ -631,6 +677,7 @@ static void mlx5e_free_rq(struct mlx5e_rq *rq)
+       case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
+               kvfree(rq->mpwqe.info);
+               mlx5_core_destroy_mkey(rq->mdev, &rq->umr_mkey);
++              mlx5e_free_mpwqe_rq_drop_page(rq);
+               break;
+       default: /* MLX5_WQ_TYPE_CYCLIC */
+               kvfree(rq->wqe.frags);
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5e-fix-race-condition-on-nhe-n-pointer-in-nei.patch b/queue-5.8/net-mlx5e-fix-race-condition-on-nhe-n-pointer-in-nei.patch
new file mode 100644 (file)
index 0000000..a36e7af
--- /dev/null
@@ -0,0 +1,216 @@
+From 828f5136942b591a56332784c07f146a5cf2e9ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 20 Sep 2020 19:59:08 +0300
+Subject: net/mlx5e: Fix race condition on nhe->n pointer in neigh update
+
+From: Vlad Buslov <vladbu@nvidia.com>
+
+[ Upstream commit 1253935ad801485270194d5651acab04abc97b36 ]
+
+Current neigh update event handler implementation takes reference to
+neighbour structure, assigns it to nhe->n, tries to schedule workqueue task
+and releases the reference if task was already enqueued. This results
+potentially overwriting existing nhe->n pointer with another neighbour
+instance, which causes double release of the instance (once in neigh update
+handler that failed to enqueue to workqueue and another one in neigh update
+workqueue task that processes updated nhe->n pointer instead of original
+one):
+
+[ 3376.512806] ------------[ cut here ]------------
+[ 3376.513534] refcount_t: underflow; use-after-free.
+[ 3376.521213] Modules linked in: act_skbedit act_mirred act_tunnel_key vxlan ip6_udp_tunnel udp_tunnel nfnetlink act_gact cls_flower sch_ingress openvswitch nsh nf_conncount nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 mlx5_ib mlx5_core mlxfw pci_hyperv_intf ptp pps_core nfsv3 nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd
+ grace fscache ib_isert iscsi_target_mod ib_srpt target_core_mod ib_srp rpcrdma rdma_ucm ib_umad ib_ipoib ib_iser rdma_cm ib_cm iw_cm rfkill ib_uverbs ib_core sunrpc kvm_intel kvm iTCO_wdt iTCO_vendor_support virtio_net irqbypass net_failover crc32_pclmul lpc_ich i2c_i801 failover pcspkr i2c_smbus mfd_core ghash_clmulni_intel sch_fq_codel drm i2c
+_core ip_tables crc32c_intel serio_raw [last unloaded: mlxfw]
+[ 3376.529468] CPU: 8 PID: 22756 Comm: kworker/u20:5 Not tainted 5.9.0-rc5+ #6
+[ 3376.530399] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+[ 3376.531975] Workqueue: mlx5e mlx5e_rep_neigh_update [mlx5_core]
+[ 3376.532820] RIP: 0010:refcount_warn_saturate+0xd8/0xe0
+[ 3376.533589] Code: ff 48 c7 c7 e0 b8 27 82 c6 05 0b b6 09 01 01 e8 94 93 c1 ff 0f 0b c3 48 c7 c7 88 b8 27 82 c6 05 f7 b5 09 01 01 e8 7e 93 c1 ff <0f> 0b c3 0f 1f 44 00 00 8b 07 3d 00 00 00 c0 74 12 83 f8 01 74 13
+[ 3376.536017] RSP: 0018:ffffc90002a97e30 EFLAGS: 00010286
+[ 3376.536793] RAX: 0000000000000000 RBX: ffff8882de30d648 RCX: 0000000000000000
+[ 3376.537718] RDX: ffff8882f5c28f20 RSI: ffff8882f5c18e40 RDI: ffff8882f5c18e40
+[ 3376.538654] RBP: ffff8882cdf56c00 R08: 000000000000c580 R09: 0000000000001a4d
+[ 3376.539582] R10: 0000000000000731 R11: ffffc90002a97ccd R12: 0000000000000000
+[ 3376.540519] R13: ffff8882de30d600 R14: ffff8882de30d640 R15: ffff88821e000900
+[ 3376.541444] FS:  0000000000000000(0000) GS:ffff8882f5c00000(0000) knlGS:0000000000000000
+[ 3376.542732] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 3376.543545] CR2: 0000556e5504b248 CR3: 00000002c6f10005 CR4: 0000000000770ee0
+[ 3376.544483] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 3376.545419] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 3376.546344] PKRU: 55555554
+[ 3376.546911] Call Trace:
+[ 3376.547479]  mlx5e_rep_neigh_update.cold+0x33/0xe2 [mlx5_core]
+[ 3376.548299]  process_one_work+0x1d8/0x390
+[ 3376.548977]  worker_thread+0x4d/0x3e0
+[ 3376.549631]  ? rescuer_thread+0x3e0/0x3e0
+[ 3376.550295]  kthread+0x118/0x130
+[ 3376.550914]  ? kthread_create_worker_on_cpu+0x70/0x70
+[ 3376.551675]  ret_from_fork+0x1f/0x30
+[ 3376.552312] ---[ end trace d84e8f46d2a77eec ]---
+
+Fix the bug by moving work_struct to dedicated dynamically-allocated
+structure. This enabled every event handler to work on its own private
+neighbour pointer and removes the need for handling the case when task is
+already enqueued.
+
+Fixes: 232c001398ae ("net/mlx5e: Add support to neighbour update flow")
+Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
+Reviewed-by: Roi Dayan <roid@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/rep/neigh.c         | 81 ++++++++++++-------
+ .../net/ethernet/mellanox/mlx5/core/en_rep.h  |  6 --
+ 2 files changed, 50 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
+index c3d167fa944c7..6a9d783d129b2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c
+@@ -109,11 +109,25 @@ static void mlx5e_rep_neigh_stats_work(struct work_struct *work)
+       rtnl_unlock();
+ }
++struct neigh_update_work {
++      struct work_struct work;
++      struct neighbour *n;
++      struct mlx5e_neigh_hash_entry *nhe;
++};
++
++static void mlx5e_release_neigh_update_work(struct neigh_update_work *update_work)
++{
++      neigh_release(update_work->n);
++      mlx5e_rep_neigh_entry_release(update_work->nhe);
++      kfree(update_work);
++}
++
+ static void mlx5e_rep_neigh_update(struct work_struct *work)
+ {
+-      struct mlx5e_neigh_hash_entry *nhe =
+-              container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
+-      struct neighbour *n = nhe->n;
++      struct neigh_update_work *update_work = container_of(work, struct neigh_update_work,
++                                                           work);
++      struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;
++      struct neighbour *n = update_work->n;
+       struct mlx5e_encap_entry *e;
+       unsigned char ha[ETH_ALEN];
+       struct mlx5e_priv *priv;
+@@ -145,30 +159,42 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
+               mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
+               mlx5e_encap_put(priv, e);
+       }
+-      mlx5e_rep_neigh_entry_release(nhe);
+       rtnl_unlock();
+-      neigh_release(n);
++      mlx5e_release_neigh_update_work(update_work);
+ }
+-static void mlx5e_rep_queue_neigh_update_work(struct mlx5e_priv *priv,
+-                                            struct mlx5e_neigh_hash_entry *nhe,
+-                                            struct neighbour *n)
++static struct neigh_update_work *mlx5e_alloc_neigh_update_work(struct mlx5e_priv *priv,
++                                                             struct neighbour *n)
+ {
+-      /* Take a reference to ensure the neighbour and mlx5 encap
+-       * entry won't be destructed until we drop the reference in
+-       * delayed work.
+-       */
+-      neigh_hold(n);
++      struct neigh_update_work *update_work;
++      struct mlx5e_neigh_hash_entry *nhe;
++      struct mlx5e_neigh m_neigh = {};
+-      /* This assignment is valid as long as the the neigh reference
+-       * is taken
+-       */
+-      nhe->n = n;
++      update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC);
++      if (WARN_ON(!update_work))
++              return NULL;
+-      if (!queue_work(priv->wq, &nhe->neigh_update_work)) {
+-              mlx5e_rep_neigh_entry_release(nhe);
+-              neigh_release(n);
++      m_neigh.dev = n->dev;
++      m_neigh.family = n->ops->family;
++      memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
++
++      /* Obtain reference to nhe as last step in order not to release it in
++       * atomic context.
++       */
++      rcu_read_lock();
++      nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
++      rcu_read_unlock();
++      if (!nhe) {
++              kfree(update_work);
++              return NULL;
+       }
++
++      INIT_WORK(&update_work->work, mlx5e_rep_neigh_update);
++      neigh_hold(n);
++      update_work->n = n;
++      update_work->nhe = nhe;
++
++      return update_work;
+ }
+ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
+@@ -180,7 +206,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
+       struct net_device *netdev = rpriv->netdev;
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+       struct mlx5e_neigh_hash_entry *nhe = NULL;
+-      struct mlx5e_neigh m_neigh = {};
++      struct neigh_update_work *update_work;
+       struct neigh_parms *p;
+       struct neighbour *n;
+       bool found = false;
+@@ -195,17 +221,11 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
+ #endif
+                       return NOTIFY_DONE;
+-              m_neigh.dev = n->dev;
+-              m_neigh.family = n->ops->family;
+-              memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
+-
+-              rcu_read_lock();
+-              nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
+-              rcu_read_unlock();
+-              if (!nhe)
++              update_work = mlx5e_alloc_neigh_update_work(priv, n);
++              if (!update_work)
+                       return NOTIFY_DONE;
+-              mlx5e_rep_queue_neigh_update_work(priv, nhe, n);
++              queue_work(priv->wq, &update_work->work);
+               break;
+       case NETEVENT_DELAY_PROBE_TIME_UPDATE:
+@@ -351,7 +371,6 @@ int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv,
+       (*nhe)->priv = priv;
+       memcpy(&(*nhe)->m_neigh, &e->m_neigh, sizeof(e->m_neigh));
+-      INIT_WORK(&(*nhe)->neigh_update_work, mlx5e_rep_neigh_update);
+       spin_lock_init(&(*nhe)->encap_list_lock);
+       INIT_LIST_HEAD(&(*nhe)->encap_list);
+       refcount_set(&(*nhe)->refcnt, 1);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+index 1d56698014843..fcaabafb2e56d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+@@ -133,12 +133,6 @@ struct mlx5e_neigh_hash_entry {
+       /* encap list sharing the same neigh */
+       struct list_head encap_list;
+-      /* valid only when the neigh reference is taken during
+-       * neigh_update_work workqueue callback.
+-       */
+-      struct neighbour *n;
+-      struct work_struct neigh_update_work;
+-
+       /* neigh hash entry can be deleted only when the refcount is zero.
+        * refcount is needed to avoid neigh hash entry removal by TC, while
+        * it's used by the neigh notification call.
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5e-fix-return-status-when-setting-unsupported.patch b/queue-5.8/net-mlx5e-fix-return-status-when-setting-unsupported.patch
new file mode 100644 (file)
index 0000000..68a31b6
--- /dev/null
@@ -0,0 +1,44 @@
+From bfe3da92d7e5343a8245298aab8ed064f39674ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Aug 2020 10:44:36 +0300
+Subject: net/mlx5e: Fix return status when setting unsupported FEC mode
+
+From: Aya Levin <ayal@mellanox.com>
+
+[ Upstream commit 2608a2f831c47dfdf18885a7289be5af97182b05 ]
+
+Verify the configured FEC mode is supported by at least a single link
+mode before applying the command. Otherwise fail the command and return
+"Operation not supported".
+Prior to this patch, the command was successful, yet it falsely set all
+link modes to FEC auto mode - like configuring FEC mode to auto. Auto
+mode is the default configuration if a link mode doesn't support the
+configured FEC mode.
+
+Fixes: b5ede32d3329 ("net/mlx5e: Add support for FEC modes based on 50G per lane links")
+Signed-off-by: Aya Levin <ayal@mellanox.com>
+Reviewed-by: Eran Ben Elisha <eranbe@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/port.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+index 98e909bf3c1ec..3e32264cf6131 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+@@ -566,6 +566,9 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
+       if (fec_policy >= (1 << MLX5E_FEC_LLRS_272_257_1) && !fec_50g_per_lane)
+               return -EOPNOTSUPP;
++      if (fec_policy && !mlx5e_fec_in_caps(dev, fec_policy))
++              return -EOPNOTSUPP;
++
+       MLX5_SET(pplm_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 0);
+       if (err)
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5e-fix-vlan-cleanup-flow.patch b/queue-5.8/net-mlx5e-fix-vlan-cleanup-flow.patch
new file mode 100644 (file)
index 0000000..52a2c35
--- /dev/null
@@ -0,0 +1,82 @@
+From 439b5b803dd808af8556349bc4ff40a82326e61c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Sep 2020 17:57:23 +0300
+Subject: net/mlx5e: Fix VLAN cleanup flow
+
+From: Aya Levin <ayal@nvidia.com>
+
+[ Upstream commit 8c7353b6f716436ad0bfda2b5c5524ab2dde5894 ]
+
+Prior to this patch unloading an interface in promiscuous mode with RX
+VLAN filtering feature turned off - resulted in a warning. This is due
+to a wrong condition in the VLAN rules cleanup flow, which left the
+any-vid rules in the VLAN steering table. These rules prevented
+destroying the flow group and the flow table.
+
+The any-vid rules are removed in 2 flows, but none of them remove it in
+case both promiscuous is set and VLAN filtering is off. Fix the issue by
+changing the condition of the VLAN table cleanup flow to clean also in
+case of promiscuous mode.
+
+mlx5_core 0000:00:08.0: mlx5_destroy_flow_group:2123:(pid 28729): Flow group 20 wasn't destroyed, refcount > 1
+mlx5_core 0000:00:08.0: mlx5_destroy_flow_group:2123:(pid 28729): Flow group 19 wasn't destroyed, refcount > 1
+mlx5_core 0000:00:08.0: mlx5_destroy_flow_table:2112:(pid 28729): Flow table 262149 wasn't destroyed, refcount > 1
+...
+...
+------------[ cut here ]------------
+FW pages counter is 11560 after reclaiming all pages
+WARNING: CPU: 1 PID: 28729 at
+drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c:660
+mlx5_reclaim_startup_pages+0x178/0x230 [mlx5_core]
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
+Call Trace:
+  mlx5_function_teardown+0x2f/0x90 [mlx5_core]
+  mlx5_unload_one+0x71/0x110 [mlx5_core]
+  remove_one+0x44/0x80 [mlx5_core]
+  pci_device_remove+0x3e/0xc0
+  device_release_driver_internal+0xfb/0x1c0
+  device_release_driver+0x12/0x20
+  pci_stop_bus_device+0x68/0x90
+  pci_stop_and_remove_bus_device+0x12/0x20
+  hv_eject_device_work+0x6f/0x170 [pci_hyperv]
+  ? __schedule+0x349/0x790
+  process_one_work+0x206/0x400
+  worker_thread+0x34/0x3f0
+  ? process_one_work+0x400/0x400
+  kthread+0x126/0x140
+  ? kthread_park+0x90/0x90
+  ret_from_fork+0x22/0x30
+   ---[ end trace 6283bde8d26170dc ]---
+
+Fixes: 9df30601c843 ("net/mlx5e: Restore vlan filter after seamless reset")
+Signed-off-by: Aya Levin <ayal@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+index 73d3dc07331f1..c5be0cdfaf0fa 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+@@ -415,8 +415,12 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
+       for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID)
+               mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
+-      if (priv->fs.vlan.cvlan_filter_disabled &&
+-          !(priv->netdev->flags & IFF_PROMISC))
++      WARN_ON_ONCE(!(test_bit(MLX5E_STATE_DESTROYING, &priv->state)));
++
++      /* must be called after DESTROY bit is set and
++       * set_rx_mode is called and flushed
++       */
++      if (priv->fs.vlan.cvlan_filter_disabled)
+               mlx5e_del_any_vid_rules(priv);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mlx5e-fix-vlan-create-flow.patch b/queue-5.8/net-mlx5e-fix-vlan-create-flow.patch
new file mode 100644 (file)
index 0000000..6d40c89
--- /dev/null
@@ -0,0 +1,55 @@
+From a73007e120ca239b898ce7c04424d07e4306d248 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 13 Sep 2020 18:05:40 +0300
+Subject: net/mlx5e: Fix VLAN create flow
+
+From: Aya Levin <ayal@nvidia.com>
+
+[ Upstream commit d4a16052bccdd695982f89d815ca075825115821 ]
+
+When interface is attached while in promiscuous mode and with VLAN
+filtering turned off, both configurations are not respected and VLAN
+filtering is performed.
+There are 2 flows which add the any-vid rules during interface attach:
+VLAN creation table and set rx mode. Each is relaying on the other to
+add any-vid rules, eventually non of them does.
+
+Fix this by adding any-vid rules on VLAN creation regardless of
+promiscuous mode.
+
+Fixes: 9df30601c843 ("net/mlx5e: Restore vlan filter after seamless reset")
+Signed-off-by: Aya Levin <ayal@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+index c5be0cdfaf0fa..713dc210f710c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+@@ -217,6 +217,9 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
+               break;
+       }
++      if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type))
++              return 0;
++
+       *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
+       if (IS_ERR(*rule_p)) {
+@@ -397,8 +400,7 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
+       for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID)
+               mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
+-      if (priv->fs.vlan.cvlan_filter_disabled &&
+-          !(priv->netdev->flags & IFF_PROMISC))
++      if (priv->fs.vlan.cvlan_filter_disabled)
+               mlx5e_add_any_vid_rules(priv);
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mscc-ocelot-divide-watermark-value-by-60-when-wr.patch b/queue-5.8/net-mscc-ocelot-divide-watermark-value-by-60-when-wr.patch
new file mode 100644 (file)
index 0000000..28453d5
--- /dev/null
@@ -0,0 +1,66 @@
+From 756bf7d6fe164f45068d2d64f1fb44668571a305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Oct 2020 12:09:11 +0300
+Subject: net: mscc: ocelot: divide watermark value by 60 when writing to
+ SYS_ATOP
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 601e984f23abcaa7cf3eb078c13de4db3cf6a4f0 ]
+
+Tail dropping is enabled for a port when:
+
+1. A source port consumes more packet buffers than the watermark encoded
+   in SYS:PORT:ATOP_CFG.ATOP.
+
+AND
+
+2. Total memory use exceeds the consumption watermark encoded in
+   SYS:PAUSE_CFG:ATOP_TOT_CFG.
+
+The unit of these watermarks is a 60 byte memory cell. That unit is
+programmed properly into ATOP_TOT_CFG, but not into ATOP. Actually when
+written into ATOP, it would get truncated and wrap around.
+
+Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
+index 1438839e3f6ea..61bbb7a090042 100644
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -2001,7 +2001,7 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
+       struct ocelot_port *ocelot_port = ocelot->ports[port];
+       int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
+       int pause_start, pause_stop;
+-      int atop_wm;
++      int atop, atop_tot;
+       if (port == ocelot->npi) {
+               maxlen += OCELOT_TAG_LEN;
+@@ -2022,12 +2022,12 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
+       ocelot_rmw_rix(ocelot, SYS_PAUSE_CFG_PAUSE_STOP(pause_stop),
+                      SYS_PAUSE_CFG_PAUSE_STOP_M, SYS_PAUSE_CFG, port);
+-      /* Tail dropping watermark */
+-      atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
++      /* Tail dropping watermarks */
++      atop_tot = (ocelot->shared_queue_sz - 9 * maxlen) /
+                  OCELOT_BUFFER_CELL_SZ;
+-      ocelot_write_rix(ocelot, ocelot->ops->wm_enc(9 * maxlen),
+-                       SYS_ATOP, port);
+-      ocelot_write(ocelot, ocelot->ops->wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
++      atop = (9 * maxlen) / OCELOT_BUFFER_CELL_SZ;
++      ocelot_write_rix(ocelot, ocelot->ops->wm_enc(atop), SYS_ATOP, port);
++      ocelot_write(ocelot, ocelot->ops->wm_enc(atop_tot), SYS_ATOP_TOT_CFG);
+ }
+ EXPORT_SYMBOL(ocelot_port_set_maxlen);
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mscc-ocelot-extend-watermark-encoding-function.patch b/queue-5.8/net-mscc-ocelot-extend-watermark-encoding-function.patch
new file mode 100644 (file)
index 0000000..8498715
--- /dev/null
@@ -0,0 +1,129 @@
+From 16a55873c5b6ded5eb896fe3f635f63bc233150b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2020 19:57:08 +0300
+Subject: net: mscc: ocelot: extend watermark encoding function
+
+From: Maxim Kochetkov <fido_max@inbox.ru>
+
+[ Upstream commit aa92d836d5c40a7e21e563a272ad177f1bfd44dd ]
+
+The ocelot_wm_encode function deals with setting thresholds for pause
+frame start and stop. In Ocelot and Felix the register layout is the
+same, but for Seville, it isn't. The easiest way to accommodate Seville
+hardware configuration is to introduce a function pointer for setting
+this up.
+
+Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/ocelot/felix_vsc9959.c     | 13 +++++++++++++
+ drivers/net/ethernet/mscc/ocelot.c         | 16 ++--------------
+ drivers/net/ethernet/mscc/ocelot_vsc7514.c | 13 +++++++++++++
+ include/soc/mscc/ocelot.h                  |  1 +
+ 4 files changed, 29 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
+index a83ecd1c5d6c2..259a612da0030 100644
+--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
++++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
+@@ -1105,8 +1105,21 @@ static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port,
+       }
+ }
++/* Watermark encode
++ * Bit 8:   Unit; 0:1, 1:16
++ * Bit 7-0: Value to be multiplied with unit
++ */
++static u16 vsc9959_wm_enc(u16 value)
++{
++      if (value >= BIT(8))
++              return BIT(8) | (value / 16);
++
++      return value;
++}
++
+ static const struct ocelot_ops vsc9959_ops = {
+       .reset                  = vsc9959_reset,
++      .wm_enc                 = vsc9959_wm_enc,
+ };
+ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
+index 6e68713c0ac6b..1438839e3f6ea 100644
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -396,18 +396,6 @@ static void ocelot_vlan_init(struct ocelot *ocelot)
+       }
+ }
+-/* Watermark encode
+- * Bit 8:   Unit; 0:1, 1:16
+- * Bit 7-0: Value to be multiplied with unit
+- */
+-static u16 ocelot_wm_enc(u16 value)
+-{
+-      if (value >= BIT(8))
+-              return BIT(8) | (value / 16);
+-
+-      return value;
+-}
+-
+ void ocelot_adjust_link(struct ocelot *ocelot, int port,
+                       struct phy_device *phydev)
+ {
+@@ -2037,9 +2025,9 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
+       /* Tail dropping watermark */
+       atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
+                  OCELOT_BUFFER_CELL_SZ;
+-      ocelot_write_rix(ocelot, ocelot_wm_enc(9 * maxlen),
++      ocelot_write_rix(ocelot, ocelot->ops->wm_enc(9 * maxlen),
+                        SYS_ATOP, port);
+-      ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
++      ocelot_write(ocelot, ocelot->ops->wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
+ }
+ EXPORT_SYMBOL(ocelot_port_set_maxlen);
+diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+index 4a15d2ff8b706..66b58b242f778 100644
+--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
++++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+@@ -240,8 +240,21 @@ static int ocelot_reset(struct ocelot *ocelot)
+       return 0;
+ }
++/* Watermark encode
++ * Bit 8:   Unit; 0:1, 1:16
++ * Bit 7-0: Value to be multiplied with unit
++ */
++static u16 ocelot_wm_enc(u16 value)
++{
++      if (value >= BIT(8))
++              return BIT(8) | (value / 16);
++
++      return value;
++}
++
+ static const struct ocelot_ops ocelot_ops = {
+       .reset                  = ocelot_reset,
++      .wm_enc                 = ocelot_wm_enc,
+ };
+ static const struct vcap_field vsc7514_vcap_is2_keys[] = {
+diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
+index 4953e9994df34..8e174a24c5757 100644
+--- a/include/soc/mscc/ocelot.h
++++ b/include/soc/mscc/ocelot.h
+@@ -468,6 +468,7 @@ struct ocelot;
+ struct ocelot_ops {
+       int (*reset)(struct ocelot *ocelot);
++      u16 (*wm_enc)(u16 value);
+ };
+ struct ocelot_acl_block {
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mscc-ocelot-rename-ocelot_board.c-to-ocelot_vsc7.patch b/queue-5.8/net-mscc-ocelot-rename-ocelot_board.c-to-ocelot_vsc7.patch
new file mode 100644 (file)
index 0000000..d0b43b6
--- /dev/null
@@ -0,0 +1,38 @@
+From 6d873f8c1ab3be90a82dd1fe0b82df152ff566ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2020 18:43:39 +0300
+Subject: net: mscc: ocelot: rename ocelot_board.c to ocelot_vsc7514.c
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 589aa6e7c9de322d47eb33a5cee8cc38838319e6 ]
+
+To follow the model of felix and seville where we have one
+platform-specific file, rename this file to the actual SoC it serves.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/Makefile                             | 2 +-
+ drivers/net/ethernet/mscc/{ocelot_board.c => ocelot_vsc7514.c} | 0
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+ rename drivers/net/ethernet/mscc/{ocelot_board.c => ocelot_vsc7514.c} (100%)
+
+diff --git a/drivers/net/ethernet/mscc/Makefile b/drivers/net/ethernet/mscc/Makefile
+index 91b33b55054e1..ad97a5cca6f99 100644
+--- a/drivers/net/ethernet/mscc/Makefile
++++ b/drivers/net/ethernet/mscc/Makefile
+@@ -2,4 +2,4 @@
+ obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot_common.o
+ mscc_ocelot_common-y := ocelot.o ocelot_io.o
+ mscc_ocelot_common-y += ocelot_regs.o ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o ocelot_ptp.o
+-obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_board.o
++obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_vsc7514.o
+diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+similarity index 100%
+rename from drivers/net/ethernet/mscc/ocelot_board.c
+rename to drivers/net/ethernet/mscc/ocelot_vsc7514.c
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mscc-ocelot-split-writes-to-pause-frame-enable-b.patch b/queue-5.8/net-mscc-ocelot-split-writes-to-pause-frame-enable-b.patch
new file mode 100644 (file)
index 0000000..c8a1b19
--- /dev/null
@@ -0,0 +1,72 @@
+From d7691ec043d0d59ccac605702eb4659d5387be0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2020 19:57:05 +0300
+Subject: net: mscc: ocelot: split writes to pause frame enable bit and to
+ thresholds
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit e8e6e73db14273464b374d49ca7242c0994945f3 ]
+
+We don't want ocelot_port_set_maxlen to enable pause frame TX, just to
+adjust the pause thresholds.
+
+Move the unconditional enabling of pause TX to ocelot_init_port. There
+is no good place to put such setting because it shouldn't be
+unconditional. But at the moment it is, we're not changing that.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
+index d0b79cca51840..6e68713c0ac6b 100644
+--- a/drivers/net/ethernet/mscc/ocelot.c
++++ b/drivers/net/ethernet/mscc/ocelot.c
+@@ -2012,6 +2012,7 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
+ {
+       struct ocelot_port *ocelot_port = ocelot->ports[port];
+       int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
++      int pause_start, pause_stop;
+       int atop_wm;
+       if (port == ocelot->npi) {
+@@ -2025,13 +2026,13 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
+       ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG);
+-      /* Set Pause WM hysteresis
+-       * 152 = 6 * maxlen / OCELOT_BUFFER_CELL_SZ
+-       * 101 = 4 * maxlen / OCELOT_BUFFER_CELL_SZ
+-       */
+-      ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA |
+-                       SYS_PAUSE_CFG_PAUSE_STOP(101) |
+-                       SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port);
++      /* Set Pause watermark hysteresis */
++      pause_start = 6 * maxlen / OCELOT_BUFFER_CELL_SZ;
++      pause_stop = 4 * maxlen / OCELOT_BUFFER_CELL_SZ;
++      ocelot_rmw_rix(ocelot, SYS_PAUSE_CFG_PAUSE_START(pause_start),
++                     SYS_PAUSE_CFG_PAUSE_START_M, SYS_PAUSE_CFG, port);
++      ocelot_rmw_rix(ocelot, SYS_PAUSE_CFG_PAUSE_STOP(pause_stop),
++                     SYS_PAUSE_CFG_PAUSE_STOP_M, SYS_PAUSE_CFG, port);
+       /* Tail dropping watermark */
+       atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) /
+@@ -2094,6 +2095,10 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
+       ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG);
+       ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG);
++      /* Enable transmission of pause frames */
++      ocelot_rmw_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA, SYS_PAUSE_CFG_PAUSE_ENA,
++                     SYS_PAUSE_CFG, port);
++
+       /* Drop frames with multicast source address */
+       ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
+                      ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA,
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-mvneta-fix-double-free-of-txq-buf.patch b/queue-5.8/net-mvneta-fix-double-free-of-txq-buf.patch
new file mode 100644 (file)
index 0000000..2582e3c
--- /dev/null
@@ -0,0 +1,68 @@
+From 7d74114c69e99679c6db2696afbf9cf1584879ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Oct 2020 11:51:21 -0700
+Subject: net: mvneta: fix double free of txq->buf
+
+From: Tom Rix <trix@redhat.com>
+
+[ Upstream commit f4544e5361da5050ff5c0330ceea095cb5dbdd72 ]
+
+clang static analysis reports this problem:
+
+drivers/net/ethernet/marvell/mvneta.c:3465:2: warning:
+  Attempt to free released memory
+        kfree(txq->buf);
+        ^~~~~~~~~~~~~~~
+
+When mvneta_txq_sw_init() fails to alloc txq->tso_hdrs,
+it frees without poisoning txq->buf.  The error is caught
+in the mvneta_setup_txqs() caller which handles the error
+by cleaning up all of the txqs with a call to
+mvneta_txq_sw_deinit which also frees txq->buf.
+
+Since mvneta_txq_sw_deinit is a general cleaner, all of the
+partial cleaning in mvneta_txq_sw_deinit()'s error handling
+is not needed.
+
+Fixes: 2adb719d74f6 ("net: mvneta: Implement software TSO")
+Signed-off-by: Tom Rix <trix@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/mvneta.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
+index 7d5d9d34f4e47..69a234e83b8b7 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -3372,24 +3372,15 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp,
+       txq->last_desc = txq->size - 1;
+       txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL);
+-      if (!txq->buf) {
+-              dma_free_coherent(pp->dev->dev.parent,
+-                                txq->size * MVNETA_DESC_ALIGNED_SIZE,
+-                                txq->descs, txq->descs_phys);
++      if (!txq->buf)
+               return -ENOMEM;
+-      }
+       /* Allocate DMA buffers for TSO MAC/IP/TCP headers */
+       txq->tso_hdrs = dma_alloc_coherent(pp->dev->dev.parent,
+                                          txq->size * TSO_HEADER_SIZE,
+                                          &txq->tso_hdrs_phys, GFP_KERNEL);
+-      if (!txq->tso_hdrs) {
+-              kfree(txq->buf);
+-              dma_free_coherent(pp->dev->dev.parent,
+-                                txq->size * MVNETA_DESC_ALIGNED_SIZE,
+-                                txq->descs, txq->descs_phys);
++      if (!txq->tso_hdrs)
+               return -ENOMEM;
+-      }
+       /* Setup XPS mapping */
+       if (txq_number > 1)
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-phy-realtek-fix-rtl8211e-rx-tx-delay-config.patch b/queue-5.8/net-phy-realtek-fix-rtl8211e-rx-tx-delay-config.patch
new file mode 100644 (file)
index 0000000..be487da
--- /dev/null
@@ -0,0 +1,126 @@
+From 381e7d30daf811ed8bfbcf5a386a6099534719fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Sep 2020 10:10:49 +0800
+Subject: net: phy: realtek: fix rtl8211e rx/tx delay config
+
+From: Willy Liu <willy.liu@realtek.com>
+
+[ Upstream commit bbc4d71d63549bcd003a430de18a72a742d8c91e ]
+
+There are two chip pins named TXDLY and RXDLY which actually adds the 2ns
+delays to TXC and RXC for TXD/RXD latching. These two pins can config via
+4.7k-ohm resistor to 3.3V hw setting, but also config via software setting
+(extension page 0xa4 register 0x1c bit13 12 and 11).
+
+The configuration register definitions from table 13 official PHY datasheet:
+PHYAD[2:0] = PHY Address
+AN[1:0] = Auto-Negotiation
+Mode = Interface Mode Select
+RX Delay = RX Delay
+TX Delay = TX Delay
+SELRGV = RGMII/GMII Selection
+
+This table describes how to config these hw pins via external pull-high or pull-
+low resistor.
+
+It is a misunderstanding that mapping it as register bits below:
+8:6 = PHY Address
+5:4 = Auto-Negotiation
+3 = Interface Mode Select
+2 = RX Delay
+1 = TX Delay
+0 = SELRGV
+So I removed these descriptions above and add related settings as below:
+14 = reserved
+13 = force Tx RX Delay controlled by bit12 bit11
+12 = Tx Delay
+11 = Rx Delay
+10:0 = Test && debug settings reserved by realtek
+
+Test && debug settings are not recommend to modify by default.
+
+Fixes: f81dadbcf7fd ("net: phy: realtek: Add rtl8211e rx/tx delays config")
+Signed-off-by: Willy Liu <willy.liu@realtek.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/realtek.c | 31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
+index c7229d022a27b..48ba757046cea 100644
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1,6 +1,5 @@
+ // SPDX-License-Identifier: GPL-2.0+
+-/*
+- * drivers/net/phy/realtek.c
++/* drivers/net/phy/realtek.c
+  *
+  * Driver for Realtek PHYs
+  *
+@@ -32,9 +31,9 @@
+ #define RTL8211F_TX_DELAY                     BIT(8)
+ #define RTL8211F_RX_DELAY                     BIT(3)
+-#define RTL8211E_TX_DELAY                     BIT(1)
+-#define RTL8211E_RX_DELAY                     BIT(2)
+-#define RTL8211E_MODE_MII_GMII                        BIT(3)
++#define RTL8211E_CTRL_DELAY                   BIT(13)
++#define RTL8211E_TX_DELAY                     BIT(12)
++#define RTL8211E_RX_DELAY                     BIT(11)
+ #define RTL8201F_ISR                          0x1e
+ #define RTL8201F_IER                          0x13
+@@ -246,16 +245,16 @@ static int rtl8211e_config_init(struct phy_device *phydev)
+       /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
+       switch (phydev->interface) {
+       case PHY_INTERFACE_MODE_RGMII:
+-              val = 0;
++              val = RTL8211E_CTRL_DELAY | 0;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_ID:
+-              val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
++              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_RXID:
+-              val = RTL8211E_RX_DELAY;
++              val = RTL8211E_CTRL_DELAY | RTL8211E_RX_DELAY;
+               break;
+       case PHY_INTERFACE_MODE_RGMII_TXID:
+-              val = RTL8211E_TX_DELAY;
++              val = RTL8211E_CTRL_DELAY | RTL8211E_TX_DELAY;
+               break;
+       default: /* the rest of the modes imply leaving delays as is. */
+               return 0;
+@@ -263,11 +262,12 @@ static int rtl8211e_config_init(struct phy_device *phydev)
+       /* According to a sample driver there is a 0x1c config register on the
+        * 0xa4 extension page (0x7) layout. It can be used to disable/enable
+-       * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can
+-       * also be used to customize the whole configuration register:
+-       * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select,
+-       * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet
+-       * for details).
++       * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins.
++       * The configuration register definition:
++       * 14 = reserved
++       * 13 = Force Tx RX Delay controlled by bit12 bit11,
++       * 12 = RX Delay, 11 = TX Delay
++       * 10:0 = Test && debug settings reserved by realtek
+        */
+       oldpage = phy_select_page(phydev, 0x7);
+       if (oldpage < 0)
+@@ -277,7 +277,8 @@ static int rtl8211e_config_init(struct phy_device *phydev)
+       if (ret)
+               goto err_restore_page;
+-      ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
++      ret = __phy_modify(phydev, 0x1c, RTL8211E_CTRL_DELAY
++                         | RTL8211E_TX_DELAY | RTL8211E_RX_DELAY,
+                          val);
+ err_restore_page:
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-stmmac-fix-clock-handling-on-remove-path.patch b/queue-5.8/net-stmmac-fix-clock-handling-on-remove-path.patch
new file mode 100644 (file)
index 0000000..0986d09
--- /dev/null
@@ -0,0 +1,42 @@
+From 39cf7098049d671b75bf9ea06fffe7c164e8c0c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Sep 2020 17:54:06 +0800
+Subject: net: stmmac: Fix clock handling on remove path
+
+From: Wong Vee Khee <vee.khee.wong@intel.com>
+
+[ Upstream commit ac322f86b56cb99d1c4224c209095aa67647c967 ]
+
+While unloading the dwmac-intel driver, clk_disable_unprepare() is
+being called twice in stmmac_dvr_remove() and
+intel_eth_pci_remove(). This causes kernel panic on the second call.
+
+Removing the second call of clk_disable_unprepare() in
+intel_eth_pci_remove().
+
+Fixes: 09f012e64e4b ("stmmac: intel: Fix clock handling on error and remove paths")
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Voon Weifeng <weifeng.voon@intel.com>
+Signed-off-by: Wong Vee Khee <vee.khee.wong@intel.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+index 2ac9dfb3462c6..9e6d60e75f85d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+@@ -653,7 +653,6 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
+       pci_free_irq_vectors(pdev);
+-      clk_disable_unprepare(priv->plat->stmmac_clk);
+       clk_unregister_fixed_rate(priv->plat->stmmac_clk);
+       pcim_iounmap_regions(pdev, BIT(0));
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-stmmac-modify-configuration-method-of-eee-timers.patch b/queue-5.8/net-stmmac-modify-configuration-method-of-eee-timers.patch
new file mode 100644 (file)
index 0000000..d3e52e2
--- /dev/null
@@ -0,0 +1,183 @@
+From 29de328e553b5dd1b716a2719c63041c4593686f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Oct 2020 23:56:09 +0800
+Subject: net: stmmac: Modify configuration method of EEE timers
+
+From: Vineetha G. Jaya Kumaran <vineetha.g.jaya.kumaran@intel.com>
+
+[ Upstream commit 388e201d41fa1ed8f2dce0f0567f56f8e919ffb0 ]
+
+Ethtool manual stated that the tx-timer is the "the amount of time the
+device should stay in idle mode prior to asserting its Tx LPI". The
+previous implementation for "ethtool --set-eee tx-timer" sets the LPI TW
+timer duration which is not correct. Hence, this patch fixes the
+"ethtool --set-eee tx-timer" to configure the EEE LPI timer.
+
+The LPI TW Timer will be using the defined default value instead of
+"ethtool --set-eee tx-timer" which follows the EEE LS timer implementation.
+
+Changelog V2
+*Not removing/modifying the eee_timer.
+*EEE LPI timer can be configured through ethtool and also the eee_timer
+module param.
+*EEE TW Timer will be configured with default value only, not able to be
+configured through ethtool or module param. This follows the implementation
+of the EEE LS Timer.
+
+Fixes: d765955d2ae0 ("stmmac: add the Energy Efficient Ethernet support")
+Signed-off-by: Vineetha G. Jaya Kumaran <vineetha.g.jaya.kumaran@intel.com>
+Signed-off-by: Voon Weifeng <weifeng.voon@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 ++
+ .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 12 +++++++++-
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 23 ++++++++++++-------
+ 3 files changed, 28 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index 9c02fc754bf1b..545696971f65e 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -203,6 +203,8 @@ struct stmmac_priv {
+       int eee_enabled;
+       int eee_active;
+       int tx_lpi_timer;
++      int tx_lpi_enabled;
++      int eee_tw_timer;
+       unsigned int mode;
+       unsigned int chain_mode;
+       int extend_desc;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index c16d0cc3e9c44..b82c6715f95f3 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -652,6 +652,7 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
+       edata->eee_enabled = priv->eee_enabled;
+       edata->eee_active = priv->eee_active;
+       edata->tx_lpi_timer = priv->tx_lpi_timer;
++      edata->tx_lpi_enabled = priv->tx_lpi_enabled;
+       return phylink_ethtool_get_eee(priv->phylink, edata);
+ }
+@@ -665,6 +666,10 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+       if (!priv->dma_cap.eee)
+               return -EOPNOTSUPP;
++      if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)
++              netdev_warn(priv->dev,
++                          "Setting EEE tx-lpi is not supported\n");
++
+       if (!edata->eee_enabled)
+               stmmac_disable_eee_mode(priv);
+@@ -672,7 +677,12 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+       if (ret)
+               return ret;
+-      priv->tx_lpi_timer = edata->tx_lpi_timer;
++      if (edata->eee_enabled &&
++          priv->tx_lpi_timer != edata->tx_lpi_timer) {
++              priv->tx_lpi_timer = edata->tx_lpi_timer;
++              stmmac_eee_init(priv);
++      }
++
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 73677c3b33b65..73465e5f5a417 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -94,7 +94,7 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
+ module_param(eee_timer, int, 0644);
+ MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
+-#define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x))
++#define STMMAC_LPI_T(x) (jiffies + usecs_to_jiffies(x))
+ /* By default the driver will use the ring mode to manage tx and rx descriptors,
+  * but allow user to force to use the chain instead of the ring
+@@ -370,7 +370,7 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t)
+       struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer);
+       stmmac_enable_eee_mode(priv);
+-      mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
++      mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
+ }
+ /**
+@@ -383,7 +383,7 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t)
+  */
+ bool stmmac_eee_init(struct stmmac_priv *priv)
+ {
+-      int tx_lpi_timer = priv->tx_lpi_timer;
++      int eee_tw_timer = priv->eee_tw_timer;
+       /* Using PCS we cannot dial with the phy registers at this stage
+        * so we do not support extra feature like EEE.
+@@ -403,7 +403,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
+               if (priv->eee_enabled) {
+                       netdev_dbg(priv->dev, "disable EEE\n");
+                       del_timer_sync(&priv->eee_ctrl_timer);
+-                      stmmac_set_eee_timer(priv, priv->hw, 0, tx_lpi_timer);
++                      stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer);
+               }
+               mutex_unlock(&priv->lock);
+               return false;
+@@ -411,11 +411,12 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
+       if (priv->eee_active && !priv->eee_enabled) {
+               timer_setup(&priv->eee_ctrl_timer, stmmac_eee_ctrl_timer, 0);
+-              mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
+               stmmac_set_eee_timer(priv, priv->hw, STMMAC_DEFAULT_LIT_LS,
+-                                   tx_lpi_timer);
++                                   eee_tw_timer);
+       }
++      mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
++
+       mutex_unlock(&priv->lock);
+       netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n");
+       return true;
+@@ -930,6 +931,7 @@ static void stmmac_mac_link_down(struct phylink_config *config,
+       stmmac_mac_set(priv, priv->ioaddr, false);
+       priv->eee_active = false;
++      priv->tx_lpi_enabled = false;
+       stmmac_eee_init(priv);
+       stmmac_set_eee_pls(priv, priv->hw, false);
+ }
+@@ -1027,6 +1029,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
+       if (phy && priv->dma_cap.eee) {
+               priv->eee_active = phy_init_eee(phy, 1) >= 0;
+               priv->eee_enabled = stmmac_eee_init(priv);
++              priv->tx_lpi_enabled = priv->eee_enabled;
+               stmmac_set_eee_pls(priv, priv->hw, true);
+       }
+ }
+@@ -2057,7 +2060,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
+       if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
+               stmmac_enable_eee_mode(priv);
+-              mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
++              mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
+       }
+       /* We still have pending packets, let's call for a new scheduling */
+@@ -2690,7 +2693,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+                       netdev_warn(priv->dev, "PTP init failed\n");
+       }
+-      priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
++      priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
++
++      /* Convert the timer from msec to usec */
++      if (!priv->tx_lpi_timer)
++              priv->tx_lpi_timer = eee_timer * 1000;
+       if (priv->use_riwt) {
+               if (!priv->rx_riwt)
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-stmmac-removed-enabling-eee-in-eee-set-callback.patch b/queue-5.8/net-stmmac-removed-enabling-eee-in-eee-set-callback.patch
new file mode 100644 (file)
index 0000000..936a385
--- /dev/null
@@ -0,0 +1,66 @@
+From 8fb800fd4a9ebc0dd2e4b64b9dbc0d7af4b0c295 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Sep 2020 16:56:14 +0800
+Subject: net: stmmac: removed enabling eee in EEE set callback
+
+From: Voon Weifeng <weifeng.voon@intel.com>
+
+[ Upstream commit 7241c5a697479c7d0c5a96595822cdab750d41ae ]
+
+EEE should be only be enabled during stmmac_mac_link_up() when the
+link are up and being set up properly. set_eee should only do settings
+configuration and disabling the eee.
+
+Without this fix, turning on EEE using ethtool will return
+"Operation not supported". This is due to the driver is in a dead loop
+waiting for eee to be advertised in the for eee to be activated but the
+driver will only configure the EEE advertisement after the eee is
+activated.
+
+Ethtool should only return "Operation not supported" if there is no EEE
+capbility in the MAC controller.
+
+Fixes: 8a7493e58ad6 ("net: stmmac: Fix a race in EEE enable callback")
+Signed-off-by: Voon Weifeng <weifeng.voon@intel.com>
+Acked-by: Mark Gross <mgross@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c  | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index eae11c5850251..c16d0cc3e9c44 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -662,23 +662,16 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int ret;
+-      if (!edata->eee_enabled) {
++      if (!priv->dma_cap.eee)
++              return -EOPNOTSUPP;
++
++      if (!edata->eee_enabled)
+               stmmac_disable_eee_mode(priv);
+-      } else {
+-              /* We are asking for enabling the EEE but it is safe
+-               * to verify all by invoking the eee_init function.
+-               * In case of failure it will return an error.
+-               */
+-              edata->eee_enabled = stmmac_eee_init(priv);
+-              if (!edata->eee_enabled)
+-                      return -EOPNOTSUPP;
+-      }
+       ret = phylink_ethtool_set_eee(priv->phylink, edata);
+       if (ret)
+               return ret;
+-      priv->eee_enabled = edata->eee_enabled;
+       priv->tx_lpi_timer = edata->tx_lpi_timer;
+       return 0;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/net-usb-ax88179_178a-fix-missing-stop-entry-in-drive.patch b/queue-5.8/net-usb-ax88179_178a-fix-missing-stop-entry-in-drive.patch
new file mode 100644 (file)
index 0000000..75404cc
--- /dev/null
@@ -0,0 +1,34 @@
+From 4aab70f68d7f1d005a88dcf6ccd7cdd185c39be0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Sep 2020 11:01:04 +0200
+Subject: net: usb: ax88179_178a: fix missing stop entry in driver_info
+
+From: Wilken Gottwalt <wilken.gottwalt@mailbox.org>
+
+[ Upstream commit 9666ea66a74adfe295cb3a8760c76e1ef70f9caf ]
+
+Adds the missing .stop entry in the Belkin driver_info structure.
+
+Fixes: e20bd60bf62a ("net: usb: asix88179_178a: Add support for the Belkin B2B128")
+Signed-off-by: Wilken Gottwalt <wilken.gottwalt@mailbox.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/ax88179_178a.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
+index a38e868e44d46..f0ef3706aad96 100644
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -1823,6 +1823,7 @@ static const struct driver_info belkin_info = {
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset  = ax88179_reset,
++      .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+-- 
+2.25.1
+
diff --git a/queue-5.8/octeontx2-af-fix-enable-disable-of-default-npc-entri.patch b/queue-5.8/octeontx2-af-fix-enable-disable-of-default-npc-entri.patch
new file mode 100644 (file)
index 0000000..9fa7d43
--- /dev/null
@@ -0,0 +1,149 @@
+From c00b85434f51c745c21021afa5ffb37d4a60eb45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Sep 2020 21:38:27 +0530
+Subject: octeontx2-af: Fix enable/disable of default NPC entries
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit e154b5b70368a84a19505a0be9b0096c66562b56 ]
+
+Packet replication feature present in Octeontx2
+is a hardware linked list of PF and its VF
+interfaces so that broadcast packets are sent
+to all interfaces present in the list. It is
+driver job to add and delete a PF/VF interface
+to/from the list when the interface is brought
+up and down. This patch fixes the
+npc_enadis_default_entries function to handle
+broadcast replication properly if packet replication
+feature is present.
+
+Fixes: 40df309e4166 ("octeontx2-af: Support to enable/disable default MCAM entries")
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/marvell/octeontx2/af/rvu.h   |  3 ++-
+ .../ethernet/marvell/octeontx2/af/rvu_nix.c   |  5 ++--
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c   | 26 ++++++++++++++-----
+ 3 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index dcf25a0920084..b89dde2c8b089 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -463,6 +463,7 @@ void rvu_nix_freemem(struct rvu *rvu);
+ int rvu_get_nixlf_count(struct rvu *rvu);
+ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf);
+ int nix_get_nixlf(struct rvu *rvu, u16 pcifunc, int *nixlf, int *nix_blkaddr);
++int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
+ /* NPC APIs */
+ int rvu_npc_init(struct rvu *rvu);
+@@ -477,7 +478,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
+ void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
+ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
+                                      int nixlf, u64 chan);
+-void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc);
++void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable);
+ int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf);
+ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
+ void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 36953d4f51c73..3495b3a6828c0 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -17,7 +17,6 @@
+ #include "npc.h"
+ #include "cgx.h"
+-static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
+ static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
+                           int type, int chan_id);
+@@ -2020,7 +2019,7 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
+       return 0;
+ }
+-static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
++int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
+ {
+       int err = 0, idx, next_idx, last_idx;
+       struct nix_mce_list *mce_list;
+@@ -2065,7 +2064,7 @@ static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
+       /* Disable MCAM entry in NPC */
+       if (!mce_list->count) {
+-              rvu_npc_disable_bcast_entry(rvu, pcifunc);
++              rvu_npc_enable_bcast_entry(rvu, pcifunc, false);
+               goto end;
+       }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index 0a214084406a6..fbaf9bcd83f2f 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -530,7 +530,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
+                             NIX_INTF_RX, &entry, true);
+ }
+-void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
++void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable)
+ {
+       struct npc_mcam *mcam = &rvu->hw->mcam;
+       int blkaddr, index;
+@@ -543,7 +543,7 @@ void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
+       pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
+       index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY);
+-      npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
++      npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
+ }
+ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+@@ -622,23 +622,35 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
+                                        nixlf, NIXLF_UCAST_ENTRY);
+       npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
+-      /* For PF, ena/dis promisc and bcast MCAM match entries */
+-      if (pcifunc & RVU_PFVF_FUNC_MASK)
++      /* For PF, ena/dis promisc and bcast MCAM match entries.
++       * For VFs add/delete from bcast list when RX multicast
++       * feature is present.
++       */
++      if (pcifunc & RVU_PFVF_FUNC_MASK && !rvu->hw->cap.nix_rx_multicast)
+               return;
+       /* For bcast, enable/disable only if it's action is not
+        * packet replication, incase if action is replication
+-       * then this PF's nixlf is removed from bcast replication
++       * then this PF/VF's nixlf is removed from bcast replication
+        * list.
+        */
+-      index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++      index = npc_get_nixlf_mcam_index(mcam, pcifunc & ~RVU_PFVF_FUNC_MASK,
+                                        nixlf, NIXLF_BCAST_ENTRY);
+       bank = npc_get_bank(mcam, index);
+       *(u64 *)&action = rvu_read64(rvu, blkaddr,
+            NPC_AF_MCAMEX_BANKX_ACTION(index & (mcam->banksize - 1), bank));
+-      if (action.op != NIX_RX_ACTIONOP_MCAST)
++
++      /* VFs will not have BCAST entry */
++      if (action.op != NIX_RX_ACTIONOP_MCAST &&
++          !(pcifunc & RVU_PFVF_FUNC_MASK)) {
+               npc_enable_mcam_entry(rvu, mcam,
+                                     blkaddr, index, enable);
++      } else {
++              nix_update_bcast_mce_list(rvu, pcifunc, enable);
++              /* Enable PF's BCAST entry for packet replication */
++              rvu_npc_enable_bcast_entry(rvu, pcifunc, enable);
++      }
++
+       if (enable)
+               rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
+       else
+-- 
+2.25.1
+
diff --git a/queue-5.8/octeontx2-pf-fix-synchnorization-issue-in-mbox.patch b/queue-5.8/octeontx2-pf-fix-synchnorization-issue-in-mbox.patch
new file mode 100644 (file)
index 0000000..5067fca
--- /dev/null
@@ -0,0 +1,146 @@
+From d95cc206fef0dc19efe226ff6c9c7033ae4ea594 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Sep 2020 21:39:35 +0530
+Subject: octeontx2-pf: Fix synchnorization issue in mbox
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 66a5209b53418111757716d71e52727b782eabd4 ]
+
+Mbox implementation in octeontx2 driver has three states
+alloc, send and reset in mbox response. VF allocate and
+sends message to PF for processing, PF ACKs them back and
+reset the mbox memory. In some case we see synchronization
+issue where after msgs_acked is incremented and before
+mbox_reset API is called, if current execution is scheduled
+out and a different thread is scheduled in which checks for
+msgs_acked. Since the new thread sees msgs_acked == msgs_sent
+it will try to allocate a new message and to send a new mbox
+message to PF.Now if mbox_reset is scheduled in, PF will see
+'0' in msgs_send.
+This patch fixes the issue by calling mbox_reset before
+incrementing msgs_acked flag for last processing message and
+checks for valid message size.
+
+Fixes: d424b6c02 ("octeontx2-pf: Enable SRIOV and added VF mbox handling")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/mbox.c     | 12 ++++++++++--
+ drivers/net/ethernet/marvell/octeontx2/af/mbox.h     |  1 +
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 11 ++++++-----
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c |  4 ++--
+ 4 files changed, 19 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c
+index 387e33fa417aa..2718fe201c147 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c
+@@ -17,7 +17,7 @@
+ static const u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+-void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
++void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
+ {
+       void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);
+       struct otx2_mbox_dev *mdev = &mbox->dev[devid];
+@@ -26,13 +26,21 @@ void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
+       tx_hdr = hw_mbase + mbox->tx_start;
+       rx_hdr = hw_mbase + mbox->rx_start;
+-      spin_lock(&mdev->mbox_lock);
+       mdev->msg_size = 0;
+       mdev->rsp_size = 0;
+       tx_hdr->num_msgs = 0;
+       tx_hdr->msg_size = 0;
+       rx_hdr->num_msgs = 0;
+       rx_hdr->msg_size = 0;
++}
++EXPORT_SYMBOL(__otx2_mbox_reset);
++
++void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
++{
++      struct otx2_mbox_dev *mdev = &mbox->dev[devid];
++
++      spin_lock(&mdev->mbox_lock);
++      __otx2_mbox_reset(mbox, devid);
+       spin_unlock(&mdev->mbox_lock);
+ }
+ EXPORT_SYMBOL(otx2_mbox_reset);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+index 6dfd0f90cd704..ab433789d2c31 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+@@ -93,6 +93,7 @@ struct mbox_msghdr {
+ };
+ void otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
++void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
+ void otx2_mbox_destroy(struct otx2_mbox *mbox);
+ int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase,
+                  struct pci_dev *pdev, void __force *reg_base,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 5d620a39ea802..2fb45670aca49 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -370,8 +370,8 @@ static int otx2_forward_vf_mbox_msgs(struct otx2_nic *pf,
+               dst_mbox = &pf->mbox;
+               dst_size = dst_mbox->mbox.tx_size -
+                               ALIGN(sizeof(*mbox_hdr), MBOX_MSG_ALIGN);
+-              /* Check if msgs fit into destination area */
+-              if (mbox_hdr->msg_size > dst_size)
++              /* Check if msgs fit into destination area and has valid size */
++              if (mbox_hdr->msg_size > dst_size || !mbox_hdr->msg_size)
+                       return -EINVAL;
+               dst_mdev = &dst_mbox->mbox.dev[0];
+@@ -526,10 +526,10 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
+ end:
+               offset = mbox->rx_start + msg->next_msgoff;
++              if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
++                      __otx2_mbox_reset(mbox, 0);
+               mdev->msgs_acked++;
+       }
+-
+-      otx2_mbox_reset(mbox, vf_idx);
+ }
+ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
+@@ -803,10 +803,11 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work)
+               msg = (struct mbox_msghdr *)(mdev->mbase + offset);
+               otx2_process_pfaf_mbox_msg(pf, msg);
+               offset = mbox->rx_start + msg->next_msgoff;
++              if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
++                      __otx2_mbox_reset(mbox, 0);
+               mdev->msgs_acked++;
+       }
+-      otx2_mbox_reset(mbox, 0);
+ }
+ static void otx2_handle_link_event(struct otx2_nic *pf)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+index 92a3db69a6cd6..2f90f17214415 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+@@ -99,10 +99,10 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
+               msg = (struct mbox_msghdr *)(mdev->mbase + offset);
+               otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
+               offset = mbox->rx_start + msg->next_msgoff;
++              if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
++                      __otx2_mbox_reset(mbox, 0);
+               mdev->msgs_acked++;
+       }
+-
+-      otx2_mbox_reset(mbox, 0);
+ }
+ static int otx2vf_process_mbox_msg_up(struct otx2_nic *vf,
+-- 
+2.25.1
+
diff --git a/queue-5.8/octeontx2-pf-fix-tcp-udp-checksum-offload-for-ipv6-f.patch b/queue-5.8/octeontx2-pf-fix-tcp-udp-checksum-offload-for-ipv6-f.patch
new file mode 100644 (file)
index 0000000..e0887d3
--- /dev/null
@@ -0,0 +1,40 @@
+From 945b1fb6238d18809885bb6f517f410e12d89f90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Sep 2020 21:38:52 +0530
+Subject: octeontx2-pf: Fix TCP/UDP checksum offload for IPv6 frames
+
+From: Geetha sowjanya <gakula@marvell.com>
+
+[ Upstream commit 89eae5e87b4fa799726a3e8911c90d418cb5d2b1 ]
+
+For TCP/UDP checksum offload feature in Octeontx2
+expects L3TYPE to be set irrespective of IP header
+checksum is being offloaded or not. Currently for
+IPv6 frames L3TYPE is not being set resulting in
+packet drop with checksum error. This patch fixes
+this issue.
+
+Fixes: 3ca6c4c88 ("octeontx2-pf: Add packet transmission support")
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+index b04f5429d72d9..334eab976ee4a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+@@ -524,6 +524,7 @@ static void otx2_sqe_add_hdr(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
+                       sqe_hdr->ol3type = NIX_SENDL3TYPE_IP4_CKSUM;
+               } else if (skb->protocol == htons(ETH_P_IPV6)) {
+                       proto = ipv6_hdr(skb)->nexthdr;
++                      sqe_hdr->ol3type = NIX_SENDL3TYPE_IP6;
+               }
+               if (proto == IPPROTO_TCP)
+-- 
+2.25.1
+
diff --git a/queue-5.8/octeontx2-pf-fix-the-device-state-on-error.patch b/queue-5.8/octeontx2-pf-fix-the-device-state-on-error.patch
new file mode 100644 (file)
index 0000000..f65ab57
--- /dev/null
@@ -0,0 +1,47 @@
+From 683674ba6ee5d3ae8545e56208bde08d2e4d8d3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Sep 2020 21:39:14 +0530
+Subject: octeontx2-pf: Fix the device state on error
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 1ea0166da0509e987caa42c30a6a71f2c6ca1875 ]
+
+Currently in otx2_open on failure of nix_lf_start
+transmit queues are not stopped which are already
+started in link_event. Since the tx queues are not
+stopped network stack still try's to send the packets
+leading to driver crash while access the device resources.
+
+Fixes: 50fe6c02e ("octeontx2-pf: Register and handle link notifications")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Signed-off-by: Geetha sowjanya <gakula@marvell.com>
+Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 75a8c407e815c..5d620a39ea802 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -1560,10 +1560,13 @@ int otx2_open(struct net_device *netdev)
+       err = otx2_rxtx_enable(pf, true);
+       if (err)
+-              goto err_free_cints;
++              goto err_tx_stop_queues;
+       return 0;
++err_tx_stop_queues:
++      netif_tx_stop_all_queues(netdev);
++      netif_carrier_off(netdev);
+ err_free_cints:
+       otx2_free_cints(pf, qidx);
+       vec = pci_irq_vector(pf->pdev,
+-- 
+2.25.1
+
diff --git a/queue-5.8/perf-fix-task_function_call-error-handling.patch b/queue-5.8/perf-fix-task_function_call-error-handling.patch
new file mode 100644 (file)
index 0000000..0674d12
--- /dev/null
@@ -0,0 +1,57 @@
+From 0a2000dbaf1285b6d4e3b4cc8d255f89bf94d506 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Aug 2020 12:17:32 +0530
+Subject: perf: Fix task_function_call() error handling
+
+From: Kajol Jain <kjain@linux.ibm.com>
+
+[ Upstream commit 6d6b8b9f4fceab7266ca03d194f60ec72bd4b654 ]
+
+The error handling introduced by commit:
+
+  2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()")
+
+looses any return value from smp_call_function_single() that is not
+{0, -EINVAL}. This is a problem because it will return -EXNIO when the
+target CPU is offline. Worse, in that case it'll turn into an infinite
+loop.
+
+Fixes: 2ed6edd33a21 ("perf: Add cond_resched() to task_function_call()")
+Reported-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Barret Rhoden <brho@google.com>
+Tested-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Link: https://lkml.kernel.org/r/20200827064732.20860-1-kjain@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 856d98c36f562..fd8cd00099dae 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -99,7 +99,7 @@ static void remote_function(void *data)
+  * retry due to any failures in smp_call_function_single(), such as if the
+  * task_cpu() goes offline concurrently.
+  *
+- * returns @func return value or -ESRCH when the process isn't running
++ * returns @func return value or -ESRCH or -ENXIO when the process isn't running
+  */
+ static int
+ task_function_call(struct task_struct *p, remote_function_f func, void *info)
+@@ -115,7 +115,8 @@ task_function_call(struct task_struct *p, remote_function_f func, void *info)
+       for (;;) {
+               ret = smp_call_function_single(task_cpu(p), remote_function,
+                                              &data, 1);
+-              ret = !ret ? data.ret : -EAGAIN;
++              if (!ret)
++                      ret = data.ret;
+               if (ret != -EAGAIN)
+                       break;
+-- 
+2.25.1
+
diff --git a/queue-5.8/pipe-fix-memory-leaks-in-create_pipe_files.patch b/queue-5.8/pipe-fix-memory-leaks-in-create_pipe_files.patch
new file mode 100644 (file)
index 0000000..9ab9968
--- /dev/null
@@ -0,0 +1,86 @@
+From aa49f48a540c33b9727766728007adc3b0ba59fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Oct 2020 08:50:55 -0400
+Subject: pipe: Fix memory leaks in create_pipe_files()
+
+From: Qian Cai <cai@redhat.com>
+
+[ Upstream commit 8a018eb55e3ac033592afbcb476b0ffe64465b12 ]
+
+        Calling pipe2() with O_NOTIFICATION_PIPE could results in memory
+leaks unless watch_queue_init() is successful.
+
+        In case of watch_queue_init() failure in pipe2() we are left
+with inode and pipe_inode_info instances that need to be freed.  That
+failure exit has been introduced in commit c73be61cede5 ("pipe: Add
+general notification queue support") and its handling should've been
+identical to nearby treatment of alloc_file_pseudo() failures - it
+is dealing with the same situation.  As it is, the mainline kernel
+leaks in that case.
+
+        Another problem is that CONFIG_WATCH_QUEUE and !CONFIG_WATCH_QUEUE
+cases are treated differently (and the former leaks just pipe_inode_info,
+the latter - both pipe_inode_info and inode).
+
+        Fixed by providing a dummy wacth_queue_init() in !CONFIG_WATCH_QUEUE
+case and by having failures of wacth_queue_init() handled the same way
+we handle alloc_file_pseudo() ones.
+
+Fixes: c73be61cede5 ("pipe: Add general notification queue support")
+Signed-off-by: Qian Cai <cai@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/pipe.c                   | 11 +++++------
+ include/linux/watch_queue.h |  6 ++++++
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/fs/pipe.c b/fs/pipe.c
+index 117db82b10af5..0ac197658a2d6 100644
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -894,19 +894,18 @@ int create_pipe_files(struct file **res, int flags)
+ {
+       struct inode *inode = get_pipe_inode();
+       struct file *f;
++      int error;
+       if (!inode)
+               return -ENFILE;
+       if (flags & O_NOTIFICATION_PIPE) {
+-#ifdef CONFIG_WATCH_QUEUE
+-              if (watch_queue_init(inode->i_pipe) < 0) {
++              error = watch_queue_init(inode->i_pipe);
++              if (error) {
++                      free_pipe_info(inode->i_pipe);
+                       iput(inode);
+-                      return -ENOMEM;
++                      return error;
+               }
+-#else
+-              return -ENOPKG;
+-#endif
+       }
+       f = alloc_file_pseudo(inode, pipe_mnt, "",
+diff --git a/include/linux/watch_queue.h b/include/linux/watch_queue.h
+index 5e08db2adc319..c994d1b2cdbaa 100644
+--- a/include/linux/watch_queue.h
++++ b/include/linux/watch_queue.h
+@@ -122,6 +122,12 @@ static inline void remove_watch_list(struct watch_list *wlist, u64 id)
+  */
+ #define watch_sizeof(STRUCT) (sizeof(STRUCT) << WATCH_INFO_LENGTH__SHIFT)
++#else
++static inline int watch_queue_init(struct pipe_inode_info *pipe)
++{
++      return -ENOPKG;
++}
++
+ #endif
+ #endif /* _LINUX_WATCH_QUEUE_H */
+-- 
+2.25.1
+
diff --git a/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-fuji.patch b/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-fuji.patch
new file mode 100644 (file)
index 0000000..f8f9a02
--- /dev/null
@@ -0,0 +1,46 @@
+From b7fdec6b486de64111a449f3f842374b40997a6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Sep 2020 19:16:53 +0300
+Subject: platform/x86: fix kconfig dependency warning for FUJITSU_LAPTOP
+
+From: Necip Fazil Yildiran <fazilyildiran@gmail.com>
+
+[ Upstream commit afdd1ebb72051e8b6b83c4d7dc542a9be0e1352d ]
+
+When FUJITSU_LAPTOP is enabled and NEW_LEDS is disabled, it results in the
+following Kbuild warning:
+
+WARNING: unmet direct dependencies detected for LEDS_CLASS
+  Depends on [n]: NEW_LEDS [=n]
+  Selected by [y]:
+  - FUJITSU_LAPTOP [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && ACPI [=y] && INPUT [=y] && BACKLIGHT_CLASS_DEVICE [=y] && (ACPI_VIDEO [=n] || ACPI_VIDEO [=n]=n)
+
+The reason is that FUJITSU_LAPTOP selects LEDS_CLASS without depending on
+or selecting NEW_LEDS while LEDS_CLASS is subordinate to NEW_LEDS.
+
+Honor the kconfig menu hierarchy to remove kconfig dependency warnings.
+
+Reported-by: Hans de Goede <hdegoede@redhat.com>
+Fixes: d89bcc83e709 ("platform/x86: fujitsu-laptop: select LEDS_CLASS")
+Signed-off-by: Necip Fazil Yildiran <fazilyildiran@gmail.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index e1668a9538c8f..a5ad36083b671 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -469,6 +469,7 @@ config FUJITSU_LAPTOP
+       depends on BACKLIGHT_CLASS_DEVICE
+       depends on ACPI_VIDEO || ACPI_VIDEO = n
+       select INPUT_SPARSEKMAP
++      select NEW_LEDS
+       select LEDS_CLASS
+       help
+         This is a driver for laptops built by Fujitsu:
+-- 
+2.25.1
+
diff --git a/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-lg_l.patch b/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-lg_l.patch
new file mode 100644 (file)
index 0000000..475cfe6
--- /dev/null
@@ -0,0 +1,47 @@
+From 06f583650ac148554057e626b96ecaceb57dc18f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Sep 2020 12:09:23 +0300
+Subject: platform/x86: fix kconfig dependency warning for LG_LAPTOP
+
+From: Necip Fazil Yildiran <fazilyildiran@gmail.com>
+
+[ Upstream commit 8f0c01e666685c4d2e1a233e6f4d7ab16c9f8b2a ]
+
+When LG_LAPTOP is enabled and NEW_LEDS is disabled, it results in the
+following Kbuild warning:
+
+WARNING: unmet direct dependencies detected for LEDS_CLASS
+  Depends on [n]: NEW_LEDS [=n]
+  Selected by [y]:
+  - LG_LAPTOP [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && ACPI [=y] && ACPI_WMI [=y] && INPUT [=y]
+
+The reason is that LG_LAPTOP selects LEDS_CLASS without depending on or
+selecting NEW_LEDS while LEDS_CLASS is subordinate to NEW_LEDS.
+
+Honor the kconfig menu hierarchy to remove kconfig dependency warnings.
+
+Fixes: dbf0c5a6b1f8 ("platform/x86: Add LG Gram laptop special features driver")
+Signed-off-by: Necip Fazil Yildiran <fazilyildiran@gmail.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: mark gross <mgross@linux.intel.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
+index 0581a54cf562f..e1668a9538c8f 100644
+--- a/drivers/platform/x86/Kconfig
++++ b/drivers/platform/x86/Kconfig
+@@ -1091,6 +1091,7 @@ config LG_LAPTOP
+       depends on ACPI_WMI
+       depends on INPUT
+       select INPUT_SPARSEKMAP
++      select NEW_LEDS
+       select LEDS_CLASS
+       help
+        This driver adds support for hotkeys as well as control of keyboard
+-- 
+2.25.1
+
diff --git a/queue-5.8/r8169-fix-rtl8168f-rtl8411-ephy-config.patch b/queue-5.8/r8169-fix-rtl8168f-rtl8411-ephy-config.patch
new file mode 100644 (file)
index 0000000..6e8a81a
--- /dev/null
@@ -0,0 +1,44 @@
+From 6a64cf74cc352a1564768ee225bc204851a370d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Sep 2020 19:44:29 +0200
+Subject: r8169: fix RTL8168f/RTL8411 EPHY config
+
+From: Heiner Kallweit <hkallweit1@gmail.com>
+
+[ Upstream commit 709a16be0593c08190982cfbdca6df95e6d5823b ]
+
+Mistakenly bit 2 was set instead of bit 3 as in the vendor driver.
+
+Fixes: a7a92cf81589 ("r8169: sync PCIe PHY init with vendor driver 8.047.01")
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
+index a5d54fa012213..fe173ea894e2c 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2958,7 +2958,7 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
+               { 0x08, 0x0001, 0x0002 },
+               { 0x09, 0x0000, 0x0080 },
+               { 0x19, 0x0000, 0x0224 },
+-              { 0x00, 0x0000, 0x0004 },
++              { 0x00, 0x0000, 0x0008 },
+               { 0x0c, 0x3df0, 0x0200 },
+       };
+@@ -2975,7 +2975,7 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
+               { 0x06, 0x00c0, 0x0020 },
+               { 0x0f, 0xffff, 0x5200 },
+               { 0x19, 0x0000, 0x0224 },
+-              { 0x00, 0x0000, 0x0004 },
++              { 0x00, 0x0000, 0x0008 },
+               { 0x0c, 0x3df0, 0x0200 },
+       };
+-- 
+2.25.1
+
diff --git a/queue-5.8/rxrpc-downgrade-the-bug-for-unsupported-token-type-i.patch b/queue-5.8/rxrpc-downgrade-the-bug-for-unsupported-token-type-i.patch
new file mode 100644 (file)
index 0000000..de934e5
--- /dev/null
@@ -0,0 +1,47 @@
+From 45d553032ea1640cba86f1d5372a4d5e959d76d9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Sep 2020 22:09:04 +0100
+Subject: rxrpc: Downgrade the BUG() for unsupported token type in rxrpc_read()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 9a059cd5ca7d9c5c4ca5a6e755cf72f230176b6a ]
+
+If rxrpc_read() (which allows KEYCTL_READ to read a key), sees a token of a
+type it doesn't recognise, it can BUG in a couple of places, which is
+unnecessary as it can easily get back to userspace.
+
+Fix this to print an error message instead.
+
+Fixes: 99455153d067 ("RxRPC: Parse security index 5 keys (Kerberos 5)")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/key.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index d77e89766406a..32f46edcf7c67 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -1108,7 +1108,8 @@ static long rxrpc_read(const struct key *key,
+                       break;
+               default: /* we have a ticket we can't encode */
+-                      BUG();
++                      pr_err("Unsupported key token type (%u)\n",
++                             token->security_index);
+                       continue;
+               }
+@@ -1224,7 +1225,6 @@ static long rxrpc_read(const struct key *key,
+                       break;
+               default:
+-                      BUG();
+                       break;
+               }
+-- 
+2.25.1
+
diff --git a/queue-5.8/rxrpc-fix-rxkad-token-xdr-encoding.patch b/queue-5.8/rxrpc-fix-rxkad-token-xdr-encoding.patch
new file mode 100644 (file)
index 0000000..3ea4422
--- /dev/null
@@ -0,0 +1,68 @@
+From b77cfb367121de563b936fa94561e519d9efb30e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Sep 2020 14:01:24 -0300
+Subject: rxrpc: Fix rxkad token xdr encoding
+
+From: Marc Dionne <marc.dionne@auristor.com>
+
+[ Upstream commit 56305118e05b2db8d0395bba640ac9a3aee92624 ]
+
+The session key should be encoded with just the 8 data bytes and
+no length; ENCODE_DATA precedes it with a 4 byte length, which
+confuses some existing tools that try to parse this format.
+
+Add an ENCODE_BYTES macro that does not include a length, and use
+it for the key.  Also adjust the expected length.
+
+Note that commit 774521f353e1d ("rxrpc: Fix an assertion in
+rxrpc_read()") had fixed a BUG by changing the length rather than
+fixing the encoding.  The original length was correct.
+
+Fixes: 99455153d067 ("RxRPC: Parse security index 5 keys (Kerberos 5)")
+Signed-off-by: Marc Dionne <marc.dionne@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/key.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index 0c98313dd7a8c..d77e89766406a 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -1073,7 +1073,7 @@ static long rxrpc_read(const struct key *key,
+               switch (token->security_index) {
+               case RXRPC_SECURITY_RXKAD:
+-                      toksize += 9 * 4;       /* viceid, kvno, key*2 + len, begin,
++                      toksize += 8 * 4;       /* viceid, kvno, key*2, begin,
+                                                * end, primary, tktlen */
+                       toksize += RND(token->kad->ticket_len);
+                       break;
+@@ -1139,6 +1139,14 @@ static long rxrpc_read(const struct key *key,
+                       memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
+               xdr += (_l + 3) >> 2;                                   \
+       } while(0)
++#define ENCODE_BYTES(l, s)                                            \
++      do {                                                            \
++              u32 _l = (l);                                           \
++              memcpy(xdr, (s), _l);                                   \
++              if (_l & 3)                                             \
++                      memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
++              xdr += (_l + 3) >> 2;                                   \
++      } while(0)
+ #define ENCODE64(x)                                   \
+       do {                                            \
+               __be64 y = cpu_to_be64(x);              \
+@@ -1166,7 +1174,7 @@ static long rxrpc_read(const struct key *key,
+               case RXRPC_SECURITY_RXKAD:
+                       ENCODE(token->kad->vice_id);
+                       ENCODE(token->kad->kvno);
+-                      ENCODE_DATA(8, token->kad->session_key);
++                      ENCODE_BYTES(8, token->kad->session_key);
+                       ENCODE(token->kad->start);
+                       ENCODE(token->kad->expiry);
+                       ENCODE(token->kad->primary_flag);
+-- 
+2.25.1
+
diff --git a/queue-5.8/rxrpc-fix-server-keyring-leak.patch b/queue-5.8/rxrpc-fix-server-keyring-leak.patch
new file mode 100644 (file)
index 0000000..0ef2d06
--- /dev/null
@@ -0,0 +1,37 @@
+From fe62be4b36ee352077f12cc85db025eb1e662fc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Oct 2020 14:04:51 +0100
+Subject: rxrpc: Fix server keyring leak
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 38b1dc47a35ba14c3f4472138ea56d014c2d609b ]
+
+If someone calls setsockopt() twice to set a server key keyring, the first
+keyring is leaked.
+
+Fix it to return an error instead if the server key keyring is already set.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/key.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index 64cbbd2f16944..85a9ff8cd236a 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -903,7 +903,7 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
+       _enter("");
+-      if (optlen <= 0 || optlen > PAGE_SIZE - 1)
++      if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities)
+               return -EINVAL;
+       description = memdup_user_nul(optval, optlen);
+-- 
+2.25.1
+
diff --git a/queue-5.8/rxrpc-fix-some-missing-_bh-annotations-on-locking-co.patch b/queue-5.8/rxrpc-fix-some-missing-_bh-annotations-on-locking-co.patch
new file mode 100644 (file)
index 0000000..39f4069
--- /dev/null
@@ -0,0 +1,51 @@
+From 923313ac0f53f60652490440bfee4b3fdabfeb96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Oct 2020 11:57:40 +0100
+Subject: rxrpc: Fix some missing _bh annotations on locking conn->state_lock
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit fa1d113a0f96f9ab7e4fe4f8825753ba1e34a9d3 ]
+
+conn->state_lock may be taken in softirq mode, but a previous patch
+replaced an outer lock in the response-packet event handling code, and lost
+the _bh from that when doing so.
+
+Fix this by applying the _bh annotation to the state_lock locking.
+
+Fixes: a1399f8bb033 ("rxrpc: Call channels should have separate call number spaces")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/conn_event.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
+index 447f55ca68860..6e972b4823efa 100644
+--- a/net/rxrpc/conn_event.c
++++ b/net/rxrpc/conn_event.c
+@@ -340,18 +340,18 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
+                       return ret;
+               spin_lock(&conn->channel_lock);
+-              spin_lock(&conn->state_lock);
++              spin_lock_bh(&conn->state_lock);
+               if (conn->state == RXRPC_CONN_SERVICE_CHALLENGING) {
+                       conn->state = RXRPC_CONN_SERVICE;
+-                      spin_unlock(&conn->state_lock);
++                      spin_unlock_bh(&conn->state_lock);
+                       for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
+                               rxrpc_call_is_secure(
+                                       rcu_dereference_protected(
+                                               conn->channels[loop].call,
+                                               lockdep_is_held(&conn->channel_lock)));
+               } else {
+-                      spin_unlock(&conn->state_lock);
++                      spin_unlock_bh(&conn->state_lock);
+               }
+               spin_unlock(&conn->channel_lock);
+-- 
+2.25.1
+
diff --git a/queue-5.8/rxrpc-the-server-keyring-isn-t-network-namespaced.patch b/queue-5.8/rxrpc-the-server-keyring-isn-t-network-namespaced.patch
new file mode 100644 (file)
index 0000000..a553468
--- /dev/null
@@ -0,0 +1,36 @@
+From 4be391491415826e942f4082a5c3094ed4f69605 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Sep 2020 19:52:08 +0100
+Subject: rxrpc: The server keyring isn't network-namespaced
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit fea99111244bae44e7d82a973744d27ea1567814 ]
+
+The keyring containing the server's tokens isn't network-namespaced, so it
+shouldn't be looked up with a network namespace.  It is expected to be
+owned specifically by the server, so namespacing is unnecessary.
+
+Fixes: a58946c158a0 ("keys: Pass the network namespace into request_key mechanism")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/key.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
+index 32f46edcf7c67..64cbbd2f16944 100644
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -941,7 +941,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
+       if (IS_ERR(description))
+               return PTR_ERR(description);
+-      key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk), NULL);
++      key = request_key(&key_type_keyring, description, NULL);
+       if (IS_ERR(key)) {
+               kfree(description);
+               _leave(" = %ld", PTR_ERR(key));
+-- 
+2.25.1
+
index 6c4187f6c5078c99f5217d3e67b2919a128683a2..b2441752f5add4bb11991b503ce9e6b63c75d1ce 100644 (file)
@@ -51,3 +51,62 @@ drm-amd-display-fix-return-value-check-for-hdcp_work.patch
 drm-vmwgfx-fix-error-handling-in-get_node.patch
 btrfs-move-btrfs_rm_dev_replace_free_srcdev-outside-.patch
 iommu-vt-d-fix-lockdep-splat-in-iommu_flush_dev_iotl.patch
+xfrm-clone-xfrma_set_mark-in-xfrm_do_migrate.patch
+xfrm-clone-xfrma_replay_esn_val-in-xfrm_do_migrate.patch
+xfrm-clone-xfrma_sec_ctx-in-xfrm_do_migrate.patch
+xfrm-clone-whole-liftime_cur-structure-in-xfrm_do_mi.patch
+xsk-do-not-discard-packet-when-netdev_tx_busy.patch
+net-stmmac-removed-enabling-eee-in-eee-set-callback.patch
+platform-x86-fix-kconfig-dependency-warning-for-lg_l.patch
+platform-x86-fix-kconfig-dependency-warning-for-fuji.patch
+hinic-add-log-in-exception-handling-processes.patch
+hinic-fix-wrong-return-value-of-mac-set-cmd.patch
+net-dsa-felix-convert-tas-link-speed-based-on-phylin.patch
+xfrm-use-correct-address-family-in-xfrm_state_find.patch
+iavf-use-generic-power-management.patch
+iavf-fix-incorrect-adapter-get-in-iavf_resume.patch
+ice-fix-memory-leak-if-register_netdev_fails.patch
+ice-fix-memory-leak-in-ice_vsi_setup.patch
+vmxnet3-fix-cksum-offload-issues-for-non-udp-tunnels.patch
+net-stmmac-fix-clock-handling-on-remove-path.patch
+net-ethernet-cavium-octeon_mgmt-use-phy_start-and-ph.patch
+bonding-set-dev-needed_headroom-in-bond_setup_by_sla.patch
+mdio-fix-mdio-thunder.c-dependency-build-error.patch
+mlxsw-spectrum_acl-fix-mlxsw_sp_acl_tcam_group_add-s.patch
+r8169-fix-rtl8168f-rtl8411-ephy-config.patch
+net-usb-ax88179_178a-fix-missing-stop-entry-in-drive.patch
+virtio-net-don-t-disable-guest-csum-when-disable-lro.patch
+net-phy-realtek-fix-rtl8211e-rx-tx-delay-config.patch
+octeontx2-af-fix-enable-disable-of-default-npc-entri.patch
+octeontx2-pf-fix-tcp-udp-checksum-offload-for-ipv6-f.patch
+octeontx2-pf-fix-the-device-state-on-error.patch
+octeontx2-pf-fix-synchnorization-issue-in-mbox.patch
+pipe-fix-memory-leaks-in-create_pipe_files.patch
+net-mlx5-fix-a-race-when-moving-command-interface-to.patch
+net-mlx5-avoid-possible-free-of-command-entry-while-.patch
+net-mlx5-poll-cmd-eq-in-case-of-command-timeout.patch
+net-mlx5-add-retry-mechanism-to-the-command-entry-in.patch
+net-mlx5-fix-request_irqs-error-flow.patch
+net-mlx5e-add-resiliency-in-striding-rq-mode-for-pac.patch
+net-mlx5e-fix-return-status-when-setting-unsupported.patch
+net-mlx5e-fix-vlan-cleanup-flow.patch
+net-mlx5e-fix-vlan-create-flow.patch
+net-mlx5e-fix-race-condition-on-nhe-n-pointer-in-nei.patch
+net-stmmac-modify-configuration-method-of-eee-timers.patch
+net-hinic-fix-devlink-build-errors.patch
+vhost-vdpa-fix-vhost_vdpa_map-on-error-condition.patch
+vhost-vdpa-fix-page-pinning-leakage-in-error-path.patch
+net-mvneta-fix-double-free-of-txq-buf.patch
+rxrpc-fix-rxkad-token-xdr-encoding.patch
+rxrpc-downgrade-the-bug-for-unsupported-token-type-i.patch
+rxrpc-fix-some-missing-_bh-annotations-on-locking-co.patch
+rxrpc-the-server-keyring-isn-t-network-namespaced.patch
+rxrpc-fix-server-keyring-leak.patch
+net-mscc-ocelot-rename-ocelot_board.c-to-ocelot_vsc7.patch
+net-mscc-ocelot-split-writes-to-pause-frame-enable-b.patch
+net-mscc-ocelot-extend-watermark-encoding-function.patch
+net-mscc-ocelot-divide-watermark-value-by-60-when-wr.patch
+i2c-meson-fix-clock-setting-overwrite.patch-20597
+afs-fix-deadlock-between-writeback-and-truncate.patch
+perf-fix-task_function_call-error-handling.patch
+mmc-core-don-t-set-limits.discard_granularity-as-0.patch
diff --git a/queue-5.8/vhost-vdpa-fix-page-pinning-leakage-in-error-path.patch b/queue-5.8/vhost-vdpa-fix-page-pinning-leakage-in-error-path.patch
new file mode 100644 (file)
index 0000000..f993510
--- /dev/null
@@ -0,0 +1,192 @@
+From 6098a4938ee29ac1e249c3c9edd2f4bf7484879d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Oct 2020 01:02:10 -0400
+Subject: vhost-vdpa: fix page pinning leakage in error path
+
+From: Si-Wei Liu <si-wei.liu@oracle.com>
+
+[ Upstream commit 7ed9e3d97c32d969caded2dfb6e67c1a2cc5a0b1 ]
+
+Pinned pages are not properly accounted particularly when
+mapping error occurs on IOTLB update. Clean up dangling
+pinned pages for the error path. As the inflight pinned
+pages, specifically for memory region that strides across
+multiple chunks, would need more than one free page for
+book keeping and accounting. For simplicity, pin pages
+for all memory in the IOVA range in one go rather than
+have multiple pin_user_pages calls to make up the entire
+region. This way it's easier to track and account the
+pages already mapped, particularly for clean-up in the
+error path.
+
+Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
+Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
+Link: https://lore.kernel.org/r/1601701330-16837-3-git-send-email-si-wei.liu@oracle.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vhost/vdpa.c | 119 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 71 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index 5259f5210b375..e172c2efc663c 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -555,21 +555,19 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
+       struct vhost_dev *dev = &v->vdev;
+       struct vhost_iotlb *iotlb = dev->iotlb;
+       struct page **page_list;
+-      unsigned long list_size = PAGE_SIZE / sizeof(struct page *);
++      struct vm_area_struct **vmas;
+       unsigned int gup_flags = FOLL_LONGTERM;
+-      unsigned long npages, cur_base, map_pfn, last_pfn = 0;
+-      unsigned long locked, lock_limit, pinned, i;
++      unsigned long map_pfn, last_pfn = 0;
++      unsigned long npages, lock_limit;
++      unsigned long i, nmap = 0;
+       u64 iova = msg->iova;
++      long pinned;
+       int ret = 0;
+       if (vhost_iotlb_itree_first(iotlb, msg->iova,
+                                   msg->iova + msg->size - 1))
+               return -EEXIST;
+-      page_list = (struct page **) __get_free_page(GFP_KERNEL);
+-      if (!page_list)
+-              return -ENOMEM;
+-
+       if (msg->perm & VHOST_ACCESS_WO)
+               gup_flags |= FOLL_WRITE;
+@@ -577,61 +575,86 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
+       if (!npages)
+               return -EINVAL;
++      page_list = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
++      vmas = kvmalloc_array(npages, sizeof(struct vm_area_struct *),
++                            GFP_KERNEL);
++      if (!page_list || !vmas) {
++              ret = -ENOMEM;
++              goto free;
++      }
++
+       mmap_read_lock(dev->mm);
+-      locked = atomic64_add_return(npages, &dev->mm->pinned_vm);
+       lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+-
+-      if (locked > lock_limit) {
++      if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) {
+               ret = -ENOMEM;
+-              goto out;
++              goto unlock;
+       }
+-      cur_base = msg->uaddr & PAGE_MASK;
+-      iova &= PAGE_MASK;
++      pinned = pin_user_pages(msg->uaddr & PAGE_MASK, npages, gup_flags,
++                              page_list, vmas);
++      if (npages != pinned) {
++              if (pinned < 0) {
++                      ret = pinned;
++              } else {
++                      unpin_user_pages(page_list, pinned);
++                      ret = -ENOMEM;
++              }
++              goto unlock;
++      }
+-      while (npages) {
+-              pinned = min_t(unsigned long, npages, list_size);
+-              ret = pin_user_pages(cur_base, pinned,
+-                                   gup_flags, page_list, NULL);
+-              if (ret != pinned)
+-                      goto out;
+-
+-              if (!last_pfn)
+-                      map_pfn = page_to_pfn(page_list[0]);
+-
+-              for (i = 0; i < ret; i++) {
+-                      unsigned long this_pfn = page_to_pfn(page_list[i]);
+-                      u64 csize;
+-
+-                      if (last_pfn && (this_pfn != last_pfn + 1)) {
+-                              /* Pin a contiguous chunk of memory */
+-                              csize = (last_pfn - map_pfn + 1) << PAGE_SHIFT;
+-                              if (vhost_vdpa_map(v, iova, csize,
+-                                                 map_pfn << PAGE_SHIFT,
+-                                                 msg->perm))
+-                                      goto out;
+-                              map_pfn = this_pfn;
+-                              iova += csize;
++      iova &= PAGE_MASK;
++      map_pfn = page_to_pfn(page_list[0]);
++
++      /* One more iteration to avoid extra vdpa_map() call out of loop. */
++      for (i = 0; i <= npages; i++) {
++              unsigned long this_pfn;
++              u64 csize;
++
++              /* The last chunk may have no valid PFN next to it */
++              this_pfn = i < npages ? page_to_pfn(page_list[i]) : -1UL;
++
++              if (last_pfn && (this_pfn == -1UL ||
++                               this_pfn != last_pfn + 1)) {
++                      /* Pin a contiguous chunk of memory */
++                      csize = last_pfn - map_pfn + 1;
++                      ret = vhost_vdpa_map(v, iova, csize << PAGE_SHIFT,
++                                           map_pfn << PAGE_SHIFT,
++                                           msg->perm);
++                      if (ret) {
++                              /*
++                               * Unpin the rest chunks of memory on the
++                               * flight with no corresponding vdpa_map()
++                               * calls having been made yet. On the other
++                               * hand, vdpa_unmap() in the failure path
++                               * is in charge of accounting the number of
++                               * pinned pages for its own.
++                               * This asymmetrical pattern of accounting
++                               * is for efficiency to pin all pages at
++                               * once, while there is no other callsite
++                               * of vdpa_map() than here above.
++                               */
++                              unpin_user_pages(&page_list[nmap],
++                                               npages - nmap);
++                              goto out;
+                       }
+-
+-                      last_pfn = this_pfn;
++                      atomic64_add(csize, &dev->mm->pinned_vm);
++                      nmap += csize;
++                      iova += csize << PAGE_SHIFT;
++                      map_pfn = this_pfn;
+               }
+-
+-              cur_base += ret << PAGE_SHIFT;
+-              npages -= ret;
++              last_pfn = this_pfn;
+       }
+-      /* Pin the rest chunk */
+-      ret = vhost_vdpa_map(v, iova, (last_pfn - map_pfn + 1) << PAGE_SHIFT,
+-                           map_pfn << PAGE_SHIFT, msg->perm);
++      WARN_ON(nmap != npages);
+ out:
+-      if (ret) {
++      if (ret)
+               vhost_vdpa_unmap(v, msg->iova, msg->size);
+-              atomic64_sub(npages, &dev->mm->pinned_vm);
+-      }
++unlock:
+       mmap_read_unlock(dev->mm);
+-      free_page((unsigned long)page_list);
++free:
++      kvfree(vmas);
++      kvfree(page_list);
+       return ret;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/vhost-vdpa-fix-vhost_vdpa_map-on-error-condition.patch b/queue-5.8/vhost-vdpa-fix-vhost_vdpa_map-on-error-condition.patch
new file mode 100644 (file)
index 0000000..d254741
--- /dev/null
@@ -0,0 +1,38 @@
+From 6e289072fcf3bd115f394124c6e6e7ef912ab09a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Oct 2020 01:02:09 -0400
+Subject: vhost-vdpa: fix vhost_vdpa_map() on error condition
+
+From: Si-Wei Liu <si-wei.liu@oracle.com>
+
+[ Upstream commit 1477c8aebb94a1db398c12d929a9d27bbd678d8c ]
+
+vhost_vdpa_map() should remove the iotlb entry just added
+if the corresponding mapping fails to set up properly.
+
+Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
+Signed-off-by: Si-Wei Liu <si-wei.liu@oracle.com>
+Link: https://lore.kernel.org/r/1601701330-16837-2-git-send-email-si-wei.liu@oracle.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vhost/vdpa.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index a54b60d6623f0..5259f5210b375 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -527,6 +527,9 @@ static int vhost_vdpa_map(struct vhost_vdpa *v,
+               r = iommu_map(v->domain, iova, pa, size,
+                             perm_to_iommu_flags(perm));
++      if (r)
++              vhost_iotlb_del_range(dev->iotlb, iova, iova + size - 1);
++
+       return r;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/virtio-net-don-t-disable-guest-csum-when-disable-lro.patch b/queue-5.8/virtio-net-don-t-disable-guest-csum-when-disable-lro.patch
new file mode 100644 (file)
index 0000000..21d3128
--- /dev/null
@@ -0,0 +1,54 @@
+From 1eadbc0bd166a51c8a5acdd0f4b6bdb5e482409a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Sep 2020 09:58:06 +0800
+Subject: virtio-net: don't disable guest csum when disable LRO
+
+From: Tonghao Zhang <xiangxia.m.yue@gmail.com>
+
+[ Upstream commit 1a03b8a35a957f9f38ecb8a97443b7380bbf6a8b ]
+
+Open vSwitch and Linux bridge will disable LRO of the interface
+when this interface added to them. Now when disable the LRO, the
+virtio-net csum is disable too. That drops the forwarding performance.
+
+Fixes: a02e8964eaf9 ("virtio-net: ethtool configurable LRO")
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
+Acked-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/virtio_net.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index ba38765dc4905..c34927b1d806e 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -63,6 +63,11 @@ static const unsigned long guest_offloads[] = {
+       VIRTIO_NET_F_GUEST_CSUM
+ };
++#define GUEST_OFFLOAD_LRO_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \
++                              (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \
++                              (1ULL << VIRTIO_NET_F_GUEST_ECN)  | \
++                              (1ULL << VIRTIO_NET_F_GUEST_UFO))
++
+ struct virtnet_stat_desc {
+       char desc[ETH_GSTRING_LEN];
+       size_t offset;
+@@ -2547,7 +2552,8 @@ static int virtnet_set_features(struct net_device *dev,
+               if (features & NETIF_F_LRO)
+                       offloads = vi->guest_offloads_capable;
+               else
+-                      offloads = 0;
++                      offloads = vi->guest_offloads_capable &
++                                 ~GUEST_OFFLOAD_LRO_MASK;
+               err = virtnet_set_guest_offloads(vi, offloads);
+               if (err)
+-- 
+2.25.1
+
diff --git a/queue-5.8/vmxnet3-fix-cksum-offload-issues-for-non-udp-tunnels.patch b/queue-5.8/vmxnet3-fix-cksum-offload-issues-for-non-udp-tunnels.patch
new file mode 100644 (file)
index 0000000..6676948
--- /dev/null
@@ -0,0 +1,113 @@
+From d643ec2a060b329712672580c46168a0f6f23bbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Sep 2020 23:11:29 -0700
+Subject: vmxnet3: fix cksum offload issues for non-udp tunnels
+
+From: Ronak Doshi <doshir@vmware.com>
+
+[ Upstream commit 1dac3b1bc66dc68dbb0c9f43adac71a7d0a0331a ]
+
+Commit dacce2be3312 ("vmxnet3: add geneve and vxlan tunnel offload
+support") added support for encapsulation offload. However, the inner
+offload capability is to be restrictued to UDP tunnels.
+
+This patch fixes the issue for non-udp tunnels by adding features
+check capability and filtering appropriate features for non-udp tunnels.
+
+Fixes: dacce2be3312 ("vmxnet3: add geneve and vxlan tunnel offload support")
+Signed-off-by: Ronak Doshi <doshir@vmware.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vmxnet3/vmxnet3_drv.c     |  5 ++---
+ drivers/net/vmxnet3/vmxnet3_ethtool.c | 28 +++++++++++++++++++++++++++
+ drivers/net/vmxnet3/vmxnet3_int.h     |  4 ++++
+ 3 files changed, 34 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index 2818015324b8b..336504b7531d9 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -1032,7 +1032,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+       /* Use temporary descriptor to avoid touching bits multiple times */
+       union Vmxnet3_GenericDesc tempTxDesc;
+ #endif
+-      struct udphdr *udph;
+       count = txd_estimate(skb);
+@@ -1135,8 +1134,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
+                       gdesc->txd.om = VMXNET3_OM_ENCAP;
+                       gdesc->txd.msscof = ctx.mss;
+-                      udph = udp_hdr(skb);
+-                      if (udph->check)
++                      if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
+                               gdesc->txd.oco = 1;
+               } else {
+                       gdesc->txd.hlen = ctx.l4_offset + ctx.l4_hdr_size;
+@@ -3371,6 +3369,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
+               .ndo_change_mtu = vmxnet3_change_mtu,
+               .ndo_fix_features = vmxnet3_fix_features,
+               .ndo_set_features = vmxnet3_set_features,
++              .ndo_features_check = vmxnet3_features_check,
+               .ndo_get_stats64 = vmxnet3_get_stats64,
+               .ndo_tx_timeout = vmxnet3_tx_timeout,
+               .ndo_set_rx_mode = vmxnet3_set_mc,
+diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
+index def27afa1c69f..3586677920046 100644
+--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
++++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
+@@ -267,6 +267,34 @@ netdev_features_t vmxnet3_fix_features(struct net_device *netdev,
+       return features;
+ }
++netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
++                                       struct net_device *netdev,
++                                       netdev_features_t features)
++{
++      struct vmxnet3_adapter *adapter = netdev_priv(netdev);
++
++      /* Validate if the tunneled packet is being offloaded by the device */
++      if (VMXNET3_VERSION_GE_4(adapter) &&
++          skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) {
++              u8 l4_proto = 0;
++
++              switch (vlan_get_protocol(skb)) {
++              case htons(ETH_P_IP):
++                      l4_proto = ip_hdr(skb)->protocol;
++                      break;
++              case htons(ETH_P_IPV6):
++                      l4_proto = ipv6_hdr(skb)->nexthdr;
++                      break;
++              default:
++                      return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
++              }
++
++              if (l4_proto != IPPROTO_UDP)
++                      return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
++      }
++      return features;
++}
++
+ static void vmxnet3_enable_encap_offloads(struct net_device *netdev)
+ {
+       struct vmxnet3_adapter *adapter = netdev_priv(netdev);
+diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
+index 5d2b062215a27..d958b92c94299 100644
+--- a/drivers/net/vmxnet3/vmxnet3_int.h
++++ b/drivers/net/vmxnet3/vmxnet3_int.h
+@@ -470,6 +470,10 @@ vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
+ netdev_features_t
+ vmxnet3_fix_features(struct net_device *netdev, netdev_features_t features);
++netdev_features_t
++vmxnet3_features_check(struct sk_buff *skb,
++                     struct net_device *netdev, netdev_features_t features);
++
+ int
+ vmxnet3_set_features(struct net_device *netdev, netdev_features_t features);
+-- 
+2.25.1
+
diff --git a/queue-5.8/xfrm-clone-whole-liftime_cur-structure-in-xfrm_do_mi.patch b/queue-5.8/xfrm-clone-whole-liftime_cur-structure-in-xfrm_do_mi.patch
new file mode 100644 (file)
index 0000000..69364c3
--- /dev/null
@@ -0,0 +1,39 @@
+From 9a61b4626f16987ee72bd78cf32c273060e119c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Sep 2020 08:50:29 +0200
+Subject: xfrm: clone whole liftime_cur structure in xfrm_do_migrate
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit 8366685b2883e523f91e9816d7be371eb1144749 ]
+
+When we clone state only add_time was cloned. It missed values like
+bytes, packets.  Now clone the all members of the structure.
+
+v1->v3:
+ - use memcpy to copy the entire structure
+
+Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint address(es)")
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 3a2c1f15d31dd..6b431a3830721 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1550,7 +1550,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+       x->tfcpad = orig->tfcpad;
+       x->replay_maxdiff = orig->replay_maxdiff;
+       x->replay_maxage = orig->replay_maxage;
+-      x->curlft.add_time = orig->curlft.add_time;
++      memcpy(&x->curlft, &orig->curlft, sizeof(x->curlft));
+       x->km.state = orig->km.state;
+       x->km.seq = orig->km.seq;
+       x->replay = orig->replay;
+-- 
+2.25.1
+
diff --git a/queue-5.8/xfrm-clone-xfrma_replay_esn_val-in-xfrm_do_migrate.patch b/queue-5.8/xfrm-clone-xfrma_replay_esn_val-in-xfrm_do_migrate.patch
new file mode 100644 (file)
index 0000000..db74dac
--- /dev/null
@@ -0,0 +1,58 @@
+From 120ca7918e12c6d70eebbb2f020a9e6269b362ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Sep 2020 08:49:55 +0200
+Subject: xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit 91a46c6d1b4fcbfa4773df9421b8ad3e58088101 ]
+
+XFRMA_REPLAY_ESN_VAL was not cloned completely from the old to the new.
+Migrate this attribute during XFRMA_MSG_MIGRATE
+
+v1->v2:
+ - move curleft cloning to a separate patch
+
+Fixes: af2f464e326e ("xfrm: Assign esn pointers when cloning a state")
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/xfrm.h | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h
+index 51f65d23ebafa..2e32cb10ac16b 100644
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -1767,21 +1767,17 @@ static inline unsigned int xfrm_replay_state_esn_len(struct xfrm_replay_state_es
+ static inline int xfrm_replay_clone(struct xfrm_state *x,
+                                    struct xfrm_state *orig)
+ {
+-      x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
++
++      x->replay_esn = kmemdup(orig->replay_esn,
++                              xfrm_replay_state_esn_len(orig->replay_esn),
+                               GFP_KERNEL);
+       if (!x->replay_esn)
+               return -ENOMEM;
+-
+-      x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
+-      x->replay_esn->replay_window = orig->replay_esn->replay_window;
+-
+-      x->preplay_esn = kmemdup(x->replay_esn,
+-                               xfrm_replay_state_esn_len(x->replay_esn),
++      x->preplay_esn = kmemdup(orig->preplay_esn,
++                               xfrm_replay_state_esn_len(orig->preplay_esn),
+                                GFP_KERNEL);
+-      if (!x->preplay_esn) {
+-              kfree(x->replay_esn);
++      if (!x->preplay_esn)
+               return -ENOMEM;
+-      }
+       return 0;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.8/xfrm-clone-xfrma_sec_ctx-in-xfrm_do_migrate.patch b/queue-5.8/xfrm-clone-xfrma_sec_ctx-in-xfrm_do_migrate.patch
new file mode 100644 (file)
index 0000000..aaeb63c
--- /dev/null
@@ -0,0 +1,74 @@
+From d2586ede1aee870625c6c631945e4c6805a179fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Sep 2020 08:50:11 +0200
+Subject: xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit 7aa05d304785204703a67a6aa7f1db402889a172 ]
+
+XFRMA_SEC_CTX was not cloned from the old to the new.
+Migrate this attribute during XFRMA_MSG_MIGRATE
+
+v1->v2:
+ - return -ENOMEM on error
+v2->v3:
+ - fix return type to int
+
+Fixes: 80c9abaabf42 ("[XFRM]: Extension for dynamic update of endpoint address(es)")
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 8ec3a6a12dd34..3a2c1f15d31dd 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1441,6 +1441,30 @@ out:
+ EXPORT_SYMBOL(xfrm_state_add);
+ #ifdef CONFIG_XFRM_MIGRATE
++static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx *security)
++{
++      struct xfrm_user_sec_ctx *uctx;
++      int size = sizeof(*uctx) + security->ctx_len;
++      int err;
++
++      uctx = kmalloc(size, GFP_KERNEL);
++      if (!uctx)
++              return -ENOMEM;
++
++      uctx->exttype = XFRMA_SEC_CTX;
++      uctx->len = size;
++      uctx->ctx_doi = security->ctx_doi;
++      uctx->ctx_alg = security->ctx_alg;
++      uctx->ctx_len = security->ctx_len;
++      memcpy(uctx + 1, security->ctx_str, security->ctx_len);
++      err = security_xfrm_state_alloc(x, uctx);
++      kfree(uctx);
++      if (err)
++              return err;
++
++      return 0;
++}
++
+ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+                                          struct xfrm_encap_tmpl *encap)
+ {
+@@ -1497,6 +1521,10 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+                       goto error;
+       }
++      if (orig->security)
++              if (clone_security(x, orig->security))
++                      goto error;
++
+       if (orig->coaddr) {
+               x->coaddr = kmemdup(orig->coaddr, sizeof(*x->coaddr),
+                                   GFP_KERNEL);
+-- 
+2.25.1
+
diff --git a/queue-5.8/xfrm-clone-xfrma_set_mark-in-xfrm_do_migrate.patch b/queue-5.8/xfrm-clone-xfrma_set_mark-in-xfrm_do_migrate.patch
new file mode 100644 (file)
index 0000000..c49d602
--- /dev/null
@@ -0,0 +1,35 @@
+From cf6513a3038dfd88448d5f2db01fc6cc31808b9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Sep 2020 08:49:38 +0200
+Subject: xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate
+
+From: Antony Antony <antony.antony@secunet.com>
+
+[ Upstream commit 545e5c571662b1cd79d9588f9d3b6e36985b8007 ]
+
+XFRMA_SET_MARK and XFRMA_SET_MARK_MASK was not cloned from the old
+to the new. Migrate these two attributes during XFRMA_MSG_MIGRATE
+
+Fixes: 9b42c1f179a6 ("xfrm: Extend the output_mark to support input direction and masking.")
+Signed-off-by: Antony Antony <antony.antony@secunet.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 8be2d926acc21..8ec3a6a12dd34 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1510,6 +1510,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
+       }
+       memcpy(&x->mark, &orig->mark, sizeof(x->mark));
++      memcpy(&x->props.smark, &orig->props.smark, sizeof(x->props.smark));
+       if (xfrm_init_state(x) < 0)
+               goto error;
+-- 
+2.25.1
+
diff --git a/queue-5.8/xfrm-use-correct-address-family-in-xfrm_state_find.patch b/queue-5.8/xfrm-use-correct-address-family-in-xfrm_state_find.patch
new file mode 100644 (file)
index 0000000..55159f4
--- /dev/null
@@ -0,0 +1,82 @@
+From b05b44fbe46e60572c96afecee04829e4df41743 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Sep 2020 14:42:56 +1000
+Subject: xfrm: Use correct address family in xfrm_state_find
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit e94ee171349db84c7cfdc5fefbebe414054d0924 ]
+
+The struct flowi must never be interpreted by itself as its size
+depends on the address family.  Therefore it must always be grouped
+with its original family value.
+
+In this particular instance, the original family value is lost in
+the function xfrm_state_find.  Therefore we get a bogus read when
+it's coupled with the wrong family which would occur with inter-
+family xfrm states.
+
+This patch fixes it by keeping the original family value.
+
+Note that the same bug could potentially occur in LSM through
+the xfrm_state_pol_flow_match hook.  I checked the current code
+there and it seems to be safe for now as only secid is used which
+is part of struct flowi_common.  But that API should be changed
+so that so that we don't get new bugs in the future.  We could
+do that by replacing fl with just secid or adding a family field.
+
+Reported-by: syzbot+577fbac3145a6eb2e7a5@syzkaller.appspotmail.com
+Fixes: 48b8d78315bf ("[XFRM]: State selection update to use inner...")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xfrm/xfrm_state.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 6b431a3830721..158510cd34ae8 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -1019,7 +1019,8 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
+        */
+       if (x->km.state == XFRM_STATE_VALID) {
+               if ((x->sel.family &&
+-                   !xfrm_selector_match(&x->sel, fl, x->sel.family)) ||
++                   (x->sel.family != family ||
++                    !xfrm_selector_match(&x->sel, fl, family))) ||
+                   !security_xfrm_state_pol_flow_match(x, pol, fl))
+                       return;
+@@ -1032,7 +1033,9 @@ static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
+               *acq_in_progress = 1;
+       } else if (x->km.state == XFRM_STATE_ERROR ||
+                  x->km.state == XFRM_STATE_EXPIRED) {
+-              if (xfrm_selector_match(&x->sel, fl, x->sel.family) &&
++              if ((!x->sel.family ||
++                   (x->sel.family == family &&
++                    xfrm_selector_match(&x->sel, fl, family))) &&
+                   security_xfrm_state_pol_flow_match(x, pol, fl))
+                       *error = -ESRCH;
+       }
+@@ -1072,7 +1075,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
+                   tmpl->mode == x->props.mode &&
+                   tmpl->id.proto == x->id.proto &&
+                   (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
+-                      xfrm_state_look_at(pol, x, fl, encap_family,
++                      xfrm_state_look_at(pol, x, fl, family,
+                                          &best, &acquire_in_progress, &error);
+       }
+       if (best || acquire_in_progress)
+@@ -1089,7 +1092,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
+                   tmpl->mode == x->props.mode &&
+                   tmpl->id.proto == x->id.proto &&
+                   (tmpl->id.spi == x->id.spi || !tmpl->id.spi))
+-                      xfrm_state_look_at(pol, x, fl, encap_family,
++                      xfrm_state_look_at(pol, x, fl, family,
+                                          &best, &acquire_in_progress, &error);
+       }
+-- 
+2.25.1
+
diff --git a/queue-5.8/xsk-do-not-discard-packet-when-netdev_tx_busy.patch b/queue-5.8/xsk-do-not-discard-packet-when-netdev_tx_busy.patch
new file mode 100644 (file)
index 0000000..e0fa304
--- /dev/null
@@ -0,0 +1,77 @@
+From 5ad4437b7eb8ffe86631333e2d93ef35d0c5a55a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Sep 2020 14:00:25 +0200
+Subject: xsk: Do not discard packet when NETDEV_TX_BUSY
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+[ Upstream commit 642e450b6b5955f2059d0ae372183f7c6323f951 ]
+
+In the skb Tx path, transmission of a packet is performed with
+dev_direct_xmit(). When NETDEV_TX_BUSY is set in the drivers, it
+signifies that it was not possible to send the packet right now,
+please try later. Unfortunately, the xsk transmit code discarded the
+packet and returned EBUSY to the application. Fix this unnecessary
+packet loss, by not discarding the packet in the Tx ring and return
+EAGAIN. As EAGAIN is returned to the application, it can then retry
+the send operation later and the packet will then likely be sent as
+the driver will then likely have space/resources to send the packet.
+
+In summary, EAGAIN tells the application that the packet was not
+discarded from the Tx ring and that it needs to call send()
+again. EBUSY, on the other hand, signifies that the packet was not
+sent and discarded from the Tx ring. The application needs to put
+the packet on the Tx ring again if it wants it to be sent.
+
+Fixes: 35fcde7f8deb ("xsk: support for Tx")
+Reported-by: Arkadiusz Zema <A.Zema@falconvsystems.com>
+Suggested-by: Arkadiusz Zema <A.Zema@falconvsystems.com>
+Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Link: https://lore.kernel.org/bpf/1600257625-2353-1-git-send-email-magnus.karlsson@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/xdp/xsk.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 3700266229f63..dcce888b8ef54 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -375,15 +375,30 @@ static int xsk_generic_xmit(struct sock *sk)
+               skb_shinfo(skb)->destructor_arg = (void *)(long)desc.addr;
+               skb->destructor = xsk_destruct_skb;
++              /* Hinder dev_direct_xmit from freeing the packet and
++               * therefore completing it in the destructor
++               */
++              refcount_inc(&skb->users);
+               err = dev_direct_xmit(skb, xs->queue_id);
++              if  (err == NETDEV_TX_BUSY) {
++                      /* Tell user-space to retry the send */
++                      skb->destructor = sock_wfree;
++                      /* Free skb without triggering the perf drop trace */
++                      consume_skb(skb);
++                      err = -EAGAIN;
++                      goto out;
++              }
++
+               xskq_cons_release(xs->tx);
+               /* Ignore NET_XMIT_CN as packet might have been sent */
+-              if (err == NET_XMIT_DROP || err == NETDEV_TX_BUSY) {
++              if (err == NET_XMIT_DROP) {
+                       /* SKB completed but not sent */
++                      kfree_skb(skb);
+                       err = -EBUSY;
+                       goto out;
+               }
++              consume_skb(skb);
+               sent_frame = true;
+       }
+-- 
+2.25.1
+