From: Sasha Levin Date: Mon, 12 Oct 2020 02:46:07 +0000 (-0400) Subject: Fixes for 5.8 X-Git-Tag: v4.4.239~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=072a11a419521f236ecbb388ac9fa4832bbf713b;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.8 Signed-off-by: Sasha Levin --- 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 index 00000000000..4a5df379734 --- /dev/null +++ b/queue-5.8/afs-fix-deadlock-between-writeback-and-truncate.patch @@ -0,0 +1,240 @@ +From 6363cd4a14c1bf4eed3d9e9266152249da6eb41f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Oct 2020 14:22:12 +0100 +Subject: afs: Fix deadlock between writeback and truncate + +From: David Howells + +[ 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 +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a72be5f0de0 --- /dev/null +++ b/queue-5.8/bonding-set-dev-needed_headroom-in-bond_setup_by_sla.patch @@ -0,0 +1,71 @@ +From ad49b3af34bfb062b57f370f9002f03e803eee03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Sep 2020 06:38:07 -0700 +Subject: bonding: set dev->needed_headroom in bond_setup_by_slave() + +From: Eric Dumazet + +[ 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] +[ 171.243512] [] skb_push+0x49/0x50 +[ 171.243516] [] ipgre_header+0x2a/0xf0 +[ 171.243520] [] neigh_connected_output+0xb7/0x100 +[ 171.243524] [] ip6_finish_output2+0x383/0x490 +[ 171.243528] [] __ip6_finish_output+0xa2/0x110 +[ 171.243531] [] ip6_finish_output+0x2c/0xa0 +[ 171.243534] [] ip6_output+0x69/0x110 +[ 171.243537] [] ? ip6_output+0x110/0x110 +[ 171.243541] [] mld_sendpack+0x1b2/0x2d0 +[ 171.243544] [] ? mld_send_report+0xf0/0xf0 +[ 171.243548] [] mld_ifc_timer_expire+0x2d7/0x3b0 +[ 171.243551] [] ? mld_gq_timer_expire+0x50/0x50 +[ 171.243556] [] call_timer_fn+0x30/0x130 +[ 171.243559] [] expire_timers+0x4c/0x110 +[ 171.243563] [] __run_timers+0x213/0x260 +[ 171.243566] [] ? ktime_get+0x3d/0xa0 +[ 171.243570] [] ? clockevents_program_event+0x7e/0xe0 +[ 171.243574] [] ? sched_clock_cpu+0x15/0x190 +[ 171.243577] [] run_timer_softirq+0x1d/0x40 +[ 171.243581] [] __do_softirq+0x152/0x2f0 +[ 171.243585] [] irq_exit+0x9f/0xb0 +[ 171.243588] [] smp_apic_timer_interrupt+0xfd/0x1a0 +[ 171.243591] [] apic_timer_interrupt+0x86/0x90 + +Fixes: f5184d267c1a ("net: Allow netdevices to specify needed head/tailroom") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c193c9620b1 --- /dev/null +++ b/queue-5.8/hinic-add-log-in-exception-handling-processes.patch @@ -0,0 +1,518 @@ +From 81df94accb34d9f236d24a135cbffe18dcc01330 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Jul 2020 15:11:19 +0800 +Subject: hinic: add log in exception handling processes + +From: Luo bin + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 + #include + ++#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 index 00000000000..3ec6a13f6b3 --- /dev/null +++ b/queue-5.8/hinic-fix-wrong-return-value-of-mac-set-cmd.patch @@ -0,0 +1,79 @@ +From 14e1094642c4b02bc436f6e3f95f4f1b2fc87941 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Sep 2020 09:31:51 +0800 +Subject: hinic: fix wrong return value of mac-set cmd + +From: Luo bin + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..054f8d87def --- /dev/null +++ b/queue-5.8/i2c-meson-fix-clock-setting-overwrite.patch-20597 @@ -0,0 +1,55 @@ +From cc7541d5ca5e81e749490a5ea65d1cede0dbaefb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Oct 2020 10:07:49 +0200 +Subject: i2c: meson: fix clock setting overwrite + +From: Jerome Brunet + +[ 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 +Signed-off-by: Wolfram Sang +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..1475f7980b7 --- /dev/null +++ b/queue-5.8/iavf-fix-incorrect-adapter-get-in-iavf_resume.patch @@ -0,0 +1,42 @@ +From cbf584431870e096c0ee647a0b80f4737723a9f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Sep 2020 12:54:59 +0000 +Subject: iavf: Fix incorrect adapter get in iavf_resume + +From: Sylwester Dziedziuch + +[ 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 +Reviewed-by: Aleksandr Loktionov +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fbf59168c97 --- /dev/null +++ b/queue-5.8/iavf-use-generic-power-management.patch @@ -0,0 +1,130 @@ +From d1447d2ffbeb284928bca6524ea5838510f75b86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jun 2020 14:59:39 +0530 +Subject: iavf: use generic power management + +From: Vaibhav Gupta + +[ 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 +Tested-by: Andrew Bowers +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7f96be700c4 --- /dev/null +++ b/queue-5.8/ice-fix-memory-leak-if-register_netdev_fails.patch @@ -0,0 +1,122 @@ +From e47886203033768701068d4a935a7219a6a0d5e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Sep 2020 08:53:46 -0700 +Subject: ice: fix memory leak if register_netdev_fails + +From: Jacob Keller + +[ 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 +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6df1d9a907a --- /dev/null +++ b/queue-5.8/ice-fix-memory-leak-in-ice_vsi_setup.patch @@ -0,0 +1,68 @@ +From dee6e0c675f38a8a5d3087018bb2110bcfe10140 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Sep 2020 08:53:47 -0700 +Subject: ice: fix memory leak in ice_vsi_setup + +From: Jacob Keller + +[ 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 +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9dd0e4a7bda --- /dev/null +++ b/queue-5.8/mdio-fix-mdio-thunder.c-dependency-build-error.patch @@ -0,0 +1,45 @@ +From bd64853b791603930c08d9fc762fc68d5a9cbb65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Sep 2020 21:33:43 -0700 +Subject: mdio: fix mdio-thunder.c dependency & build error + +From: Randy Dunlap + +[ 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 +Signed-off-by: Randy Dunlap +Cc: Bartosz Golaszewski +Cc: Andrew Lunn +Cc: Heiner Kallweit +Cc: netdev@vger.kernel.org +Cc: David Daney +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5b9ded93dd1 --- /dev/null +++ b/queue-5.8/mlxsw-spectrum_acl-fix-mlxsw_sp_acl_tcam_group_add-s.patch @@ -0,0 +1,47 @@ +From 38db94f0d730c829bf9ccf494310a0833a78b0a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Jiri Pirko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..403d73c8c9d --- /dev/null +++ b/queue-5.8/mmc-core-don-t-set-limits.discard_granularity-as-0.patch @@ -0,0 +1,70 @@ +From ec52fc9c1c1659f99f34a68b4dc3aa21e61dfca7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Oct 2020 09:38:52 +0800 +Subject: mmc: core: don't set limits.discard_granularity as 0 + +From: Coly Li + +[ 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 +Signed-off-by: Coly Li +Acked-by: Adrian Hunter +Cc: Ulf Hansson +Link: https://lore.kernel.org/r/20201002013852.51968-1-colyli@suse.de +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c6a8165f325 --- /dev/null +++ b/queue-5.8/net-dsa-felix-convert-tas-link-speed-based-on-phylin.patch @@ -0,0 +1,59 @@ +From 08c118f7c0d39b3ff8f35351f73f5757dc09cd6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Sep 2020 09:57:46 +0800 +Subject: net: dsa: felix: convert TAS link speed based on phylink speed + +From: Xiaoliang Yang + +[ 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 +Reviewed-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d51389b8b08 --- /dev/null +++ b/queue-5.8/net-ethernet-cavium-octeon_mgmt-use-phy_start-and-ph.patch @@ -0,0 +1,54 @@ +From 9e7008e4df8f01a06e4b19690ce9f9c414a22d91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Sep 2020 15:44:39 +0300 +Subject: net: ethernet: cavium: octeon_mgmt: use phy_start and phy_stop + +From: Ivan Khoronzhuk + +[ 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 +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c7569421370 --- /dev/null +++ b/queue-5.8/net-hinic-fix-devlink-build-errors.patch @@ -0,0 +1,62 @@ +From 099bc6f51926c54ccff81dd23286a7b4ae40093c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Oct 2020 10:54:49 -0700 +Subject: net: hinic: fix DEVLINK build errors + +From: Randy Dunlap + +[ 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 +Cc: Bin Luo +Cc: "David S. Miller" +Cc: Jakub Kicinski +Cc: Aviad Krawczyk +Cc: Zhao Chen +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..62175644ada --- /dev/null +++ b/queue-5.8/net-mlx5-add-retry-mechanism-to-the-command-entry-in.patch @@ -0,0 +1,69 @@ +From e4fc4b14a9882fdca0c88ee695afb0f5e98a04a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..967f07d9c4e --- /dev/null +++ b/queue-5.8/net-mlx5-avoid-possible-free-of-command-entry-while-.patch @@ -0,0 +1,337 @@ +From bb9b3734c22098f899ca675a5933315e495e03a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a0c55fc59ad --- /dev/null +++ b/queue-5.8/net-mlx5-fix-a-race-when-moving-command-interface-to.patch @@ -0,0 +1,48 @@ +From d6e2bb53af7adf1d65646f6015381e7d4de4755c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d302e9c2bd6 --- /dev/null +++ b/queue-5.8/net-mlx5-fix-request_irqs-error-flow.patch @@ -0,0 +1,80 @@ +From 59366a5aabec18cf14e5a8e68e1bf0aca71ce4ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Aug 2020 21:37:31 +0300 +Subject: net/mlx5: Fix request_irqs error flow + +From: Maor Gottlieb + +[ 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 +Reviewed-by: Eran Ben Elisha +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3e4b1dc3819 --- /dev/null +++ b/queue-5.8/net-mlx5-poll-cmd-eq-in-case-of-command-timeout.patch @@ -0,0 +1,222 @@ +From 37d9534d2aa73452a10cbd0864821ad6b89558b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Jul 2020 10:25:52 +0300 +Subject: net/mlx5: poll cmd EQ in case of command timeout + +From: Eran Ben Elisha + +[ 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 +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ee71ee88ec3 --- /dev/null +++ b/queue-5.8/net-mlx5e-add-resiliency-in-striding-rq-mode-for-pac.patch @@ -0,0 +1,199 @@ +From 6c0b169fb7769fcc7f294a15c68b6663af98d236 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Tariq Toukan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a36e7affd51 --- /dev/null +++ b/queue-5.8/net-mlx5e-fix-race-condition-on-nhe-n-pointer-in-nei.patch @@ -0,0 +1,216 @@ +From 828f5136942b591a56332784c07f146a5cf2e9ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Roi Dayan +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..68a31b69af9 --- /dev/null +++ b/queue-5.8/net-mlx5e-fix-return-status-when-setting-unsupported.patch @@ -0,0 +1,44 @@ +From bfe3da92d7e5343a8245298aab8ed064f39674ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Aug 2020 10:44:36 +0300 +Subject: net/mlx5e: Fix return status when setting unsupported FEC mode + +From: Aya Levin + +[ 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 +Reviewed-by: Eran Ben Elisha +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..52a2c357f57 --- /dev/null +++ b/queue-5.8/net-mlx5e-fix-vlan-cleanup-flow.patch @@ -0,0 +1,82 @@ +From 439b5b803dd808af8556349bc4ff40a82326e61c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 13 Sep 2020 17:57:23 +0300 +Subject: net/mlx5e: Fix VLAN cleanup flow + +From: Aya Levin + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6d40c89b8ff --- /dev/null +++ b/queue-5.8/net-mlx5e-fix-vlan-create-flow.patch @@ -0,0 +1,55 @@ +From a73007e120ca239b898ce7c04424d07e4306d248 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 13 Sep 2020 18:05:40 +0300 +Subject: net/mlx5e: Fix VLAN create flow + +From: Aya Levin + +[ 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 +Reviewed-by: Moshe Shemesh +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..28453d559d7 --- /dev/null +++ b/queue-5.8/net-mscc-ocelot-divide-watermark-value-by-60-when-wr.patch @@ -0,0 +1,66 @@ +From 756bf7d6fe164f45068d2d64f1fb44668571a305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..849871593ce --- /dev/null +++ b/queue-5.8/net-mscc-ocelot-extend-watermark-encoding-function.patch @@ -0,0 +1,129 @@ +From 16a55873c5b6ded5eb896fe3f635f63bc233150b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jul 2020 19:57:08 +0300 +Subject: net: mscc: ocelot: extend watermark encoding function + +From: Maxim Kochetkov + +[ 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 +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d0b43b674df --- /dev/null +++ b/queue-5.8/net-mscc-ocelot-rename-ocelot_board.c-to-ocelot_vsc7.patch @@ -0,0 +1,38 @@ +From 6d873f8c1ab3be90a82dd1fe0b82df152ff566ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 20 Jun 2020 18:43:39 +0300 +Subject: net: mscc: ocelot: rename ocelot_board.c to ocelot_vsc7514.c + +From: Vladimir Oltean + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c8a1b190750 --- /dev/null +++ b/queue-5.8/net-mscc-ocelot-split-writes-to-pause-frame-enable-b.patch @@ -0,0 +1,72 @@ +From d7691ec043d0d59ccac605702eb4659d5387be0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2582e3cdd67 --- /dev/null +++ b/queue-5.8/net-mvneta-fix-double-free-of-txq-buf.patch @@ -0,0 +1,68 @@ +From 7d74114c69e99679c6db2696afbf9cf1584879ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 3 Oct 2020 11:51:21 -0700 +Subject: net: mvneta: fix double free of txq->buf + +From: Tom Rix + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..be487da68a1 --- /dev/null +++ b/queue-5.8/net-phy-realtek-fix-rtl8211e-rx-tx-delay-config.patch @@ -0,0 +1,126 @@ +From 381e7d30daf811ed8bfbcf5a386a6099534719fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Sep 2020 10:10:49 +0800 +Subject: net: phy: realtek: fix rtl8211e rx/tx delay config + +From: Willy Liu + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0986d09b107 --- /dev/null +++ b/queue-5.8/net-stmmac-fix-clock-handling-on-remove-path.patch @@ -0,0 +1,42 @@ +From 39cf7098049d671b75bf9ea06fffe7c164e8c0c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Sep 2020 17:54:06 +0800 +Subject: net: stmmac: Fix clock handling on remove path + +From: Wong Vee Khee + +[ 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 +Reviewed-by: Voon Weifeng +Signed-off-by: Wong Vee Khee +Reviewed-by: Andy Shevchenko +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d3e52e20d0f --- /dev/null +++ b/queue-5.8/net-stmmac-modify-configuration-method-of-eee-timers.patch @@ -0,0 +1,183 @@ +From 29de328e553b5dd1b716a2719c63041c4593686f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Oct 2020 23:56:09 +0800 +Subject: net: stmmac: Modify configuration method of EEE timers + +From: Vineetha G. Jaya Kumaran + +[ 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 +Signed-off-by: Voon Weifeng +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..936a3854ecc --- /dev/null +++ b/queue-5.8/net-stmmac-removed-enabling-eee-in-eee-set-callback.patch @@ -0,0 +1,66 @@ +From 8fb800fd4a9ebc0dd2e4b64b9dbc0d7af4b0c295 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Sep 2020 16:56:14 +0800 +Subject: net: stmmac: removed enabling eee in EEE set callback + +From: Voon Weifeng + +[ 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 +Acked-by: Mark Gross +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..75404cc5a6f --- /dev/null +++ b/queue-5.8/net-usb-ax88179_178a-fix-missing-stop-entry-in-drive.patch @@ -0,0 +1,34 @@ +From 4aab70f68d7f1d005a88dcf6ccd7cdd185c39be0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Sep 2020 11:01:04 +0200 +Subject: net: usb: ax88179_178a: fix missing stop entry in driver_info + +From: Wilken Gottwalt + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9fa7d434180 --- /dev/null +++ b/queue-5.8/octeontx2-af-fix-enable-disable-of-default-npc-entri.patch @@ -0,0 +1,149 @@ +From c00b85434f51c745c21021afa5ffb37d4a60eb45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Sep 2020 21:38:27 +0530 +Subject: octeontx2-af: Fix enable/disable of default NPC entries + +From: Subbaraya Sundeep + +[ 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 +Signed-off-by: Geetha sowjanya +Signed-off-by: Sunil Goutham +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..5067fca4e49 --- /dev/null +++ b/queue-5.8/octeontx2-pf-fix-synchnorization-issue-in-mbox.patch @@ -0,0 +1,146 @@ +From d95cc206fef0dc19efe226ff6c9c7033ae4ea594 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Sep 2020 21:39:35 +0530 +Subject: octeontx2-pf: Fix synchnorization issue in mbox + +From: Hariprasad Kelam + +[ 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 +Signed-off-by: Geetha sowjanya +Signed-off-by: Sunil Goutham +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e0887d3c960 --- /dev/null +++ b/queue-5.8/octeontx2-pf-fix-tcp-udp-checksum-offload-for-ipv6-f.patch @@ -0,0 +1,40 @@ +From 945b1fb6238d18809885bb6f517f410e12d89f90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Sep 2020 21:38:52 +0530 +Subject: octeontx2-pf: Fix TCP/UDP checksum offload for IPv6 frames + +From: Geetha sowjanya + +[ 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 +Signed-off-by: Sunil Goutham +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f65ab57f5c3 --- /dev/null +++ b/queue-5.8/octeontx2-pf-fix-the-device-state-on-error.patch @@ -0,0 +1,47 @@ +From 683674ba6ee5d3ae8545e56208bde08d2e4d8d3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Sep 2020 21:39:14 +0530 +Subject: octeontx2-pf: Fix the device state on error + +From: Hariprasad Kelam + +[ 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 +Signed-off-by: Geetha sowjanya +Signed-off-by: Sunil Goutham +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0674d12dc1c --- /dev/null +++ b/queue-5.8/perf-fix-task_function_call-error-handling.patch @@ -0,0 +1,57 @@ +From 0a2000dbaf1285b6d4e3b4cc8d255f89bf94d506 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Aug 2020 12:17:32 +0530 +Subject: perf: Fix task_function_call() error handling + +From: Kajol Jain + +[ 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 +Signed-off-by: Kajol Jain +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Reviewed-by: Barret Rhoden +Tested-by: Srikar Dronamraju +Link: https://lkml.kernel.org/r/20200827064732.20860-1-kjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9ab99684133 --- /dev/null +++ b/queue-5.8/pipe-fix-memory-leaks-in-create_pipe_files.patch @@ -0,0 +1,86 @@ +From aa49f48a540c33b9727766728007adc3b0ba59fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Oct 2020 08:50:55 -0400 +Subject: pipe: Fix memory leaks in create_pipe_files() + +From: Qian Cai + +[ 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 +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f8f9a0268cd --- /dev/null +++ b/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-fuji.patch @@ -0,0 +1,46 @@ +From b7fdec6b486de64111a449f3f842374b40997a6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Sep 2020 19:16:53 +0300 +Subject: platform/x86: fix kconfig dependency warning for FUJITSU_LAPTOP + +From: Necip Fazil Yildiran + +[ 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 +Fixes: d89bcc83e709 ("platform/x86: fujitsu-laptop: select LEDS_CLASS") +Signed-off-by: Necip Fazil Yildiran +Signed-off-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..475cfe66a0f --- /dev/null +++ b/queue-5.8/platform-x86-fix-kconfig-dependency-warning-for-lg_l.patch @@ -0,0 +1,47 @@ +From 06f583650ac148554057e626b96ecaceb57dc18f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Sep 2020 12:09:23 +0300 +Subject: platform/x86: fix kconfig dependency warning for LG_LAPTOP + +From: Necip Fazil Yildiran + +[ 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 +Reviewed-by: Hans de Goede +Acked-by: mark gross +Signed-off-by: Andy Shevchenko +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6e8a81a6799 --- /dev/null +++ b/queue-5.8/r8169-fix-rtl8168f-rtl8411-ephy-config.patch @@ -0,0 +1,44 @@ +From 6a64cf74cc352a1564768ee225bc204851a370d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Sep 2020 19:44:29 +0200 +Subject: r8169: fix RTL8168f/RTL8411 EPHY config + +From: Heiner Kallweit + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..de934e5d7f2 --- /dev/null +++ b/queue-5.8/rxrpc-downgrade-the-bug-for-unsupported-token-type-i.patch @@ -0,0 +1,47 @@ +From 45d553032ea1640cba86f1d5372a4d5e959d76d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Sep 2020 22:09:04 +0100 +Subject: rxrpc: Downgrade the BUG() for unsupported token type in rxrpc_read() + +From: David Howells + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3ea442262d9 --- /dev/null +++ b/queue-5.8/rxrpc-fix-rxkad-token-xdr-encoding.patch @@ -0,0 +1,68 @@ +From b77cfb367121de563b936fa94561e519d9efb30e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Sep 2020 14:01:24 -0300 +Subject: rxrpc: Fix rxkad token xdr encoding + +From: Marc Dionne + +[ 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 +Signed-off-by: David Howells +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0ef2d069ac8 --- /dev/null +++ b/queue-5.8/rxrpc-fix-server-keyring-leak.patch @@ -0,0 +1,37 @@ +From fe62be4b36ee352077f12cc85db025eb1e662fc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Oct 2020 14:04:51 +0100 +Subject: rxrpc: Fix server keyring leak + +From: David Howells + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..39f40691a1e --- /dev/null +++ b/queue-5.8/rxrpc-fix-some-missing-_bh-annotations-on-locking-co.patch @@ -0,0 +1,51 @@ +From 923313ac0f53f60652490440bfee4b3fdabfeb96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Oct 2020 11:57:40 +0100 +Subject: rxrpc: Fix some missing _bh annotations on locking conn->state_lock + +From: David Howells + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a55346846a0 --- /dev/null +++ b/queue-5.8/rxrpc-the-server-keyring-isn-t-network-namespaced.patch @@ -0,0 +1,36 @@ +From 4be391491415826e942f4082a5c3094ed4f69605 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Sep 2020 19:52:08 +0100 +Subject: rxrpc: The server keyring isn't network-namespaced + +From: David Howells + +[ 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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.8/series b/queue-5.8/series index 6c4187f6c50..b2441752f5a 100644 --- a/queue-5.8/series +++ b/queue-5.8/series @@ -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 index 00000000000..f993510a299 --- /dev/null +++ b/queue-5.8/vhost-vdpa-fix-page-pinning-leakage-in-error-path.patch @@ -0,0 +1,192 @@ +From 6098a4938ee29ac1e249c3c9edd2f4bf7484879d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 3 Oct 2020 01:02:10 -0400 +Subject: vhost-vdpa: fix page pinning leakage in error path + +From: Si-Wei Liu + +[ 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 +Link: https://lore.kernel.org/r/1601701330-16837-3-git-send-email-si-wei.liu@oracle.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..d25474179ea --- /dev/null +++ b/queue-5.8/vhost-vdpa-fix-vhost_vdpa_map-on-error-condition.patch @@ -0,0 +1,38 @@ +From 6e289072fcf3bd115f394124c6e6e7ef912ab09a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 3 Oct 2020 01:02:09 -0400 +Subject: vhost-vdpa: fix vhost_vdpa_map() on error condition + +From: Si-Wei Liu + +[ 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 +Link: https://lore.kernel.org/r/1601701330-16837-2-git-send-email-si-wei.liu@oracle.com +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..21d3128ddcb --- /dev/null +++ b/queue-5.8/virtio-net-don-t-disable-guest-csum-when-disable-lro.patch @@ -0,0 +1,54 @@ +From 1eadbc0bd166a51c8a5acdd0f4b6bdb5e482409a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Sep 2020 09:58:06 +0800 +Subject: virtio-net: don't disable guest csum when disable LRO + +From: Tonghao Zhang + +[ 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 +Cc: Jason Wang +Cc: Willem de Bruijn +Signed-off-by: Tonghao Zhang +Acked-by: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6676948ae28 --- /dev/null +++ b/queue-5.8/vmxnet3-fix-cksum-offload-issues-for-non-udp-tunnels.patch @@ -0,0 +1,113 @@ +From d643ec2a060b329712672580c46168a0f6f23bbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Sep 2020 23:11:29 -0700 +Subject: vmxnet3: fix cksum offload issues for non-udp tunnels + +From: Ronak Doshi + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..69364c38afb --- /dev/null +++ b/queue-5.8/xfrm-clone-whole-liftime_cur-structure-in-xfrm_do_mi.patch @@ -0,0 +1,39 @@ +From 9a61b4626f16987ee72bd78cf32c273060e119c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Sep 2020 08:50:29 +0200 +Subject: xfrm: clone whole liftime_cur structure in xfrm_do_migrate + +From: Antony Antony + +[ 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 +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..db74dac61a8 --- /dev/null +++ b/queue-5.8/xfrm-clone-xfrma_replay_esn_val-in-xfrm_do_migrate.patch @@ -0,0 +1,58 @@ +From 120ca7918e12c6d70eebbb2f020a9e6269b362ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Sep 2020 08:49:55 +0200 +Subject: xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate + +From: Antony Antony + +[ 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 +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..aaeb63c1fdd --- /dev/null +++ b/queue-5.8/xfrm-clone-xfrma_sec_ctx-in-xfrm_do_migrate.patch @@ -0,0 +1,74 @@ +From d2586ede1aee870625c6c631945e4c6805a179fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Sep 2020 08:50:11 +0200 +Subject: xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate + +From: Antony Antony + +[ 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 +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c49d60255be --- /dev/null +++ b/queue-5.8/xfrm-clone-xfrma_set_mark-in-xfrm_do_migrate.patch @@ -0,0 +1,35 @@ +From cf6513a3038dfd88448d5f2db01fc6cc31808b9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Sep 2020 08:49:38 +0200 +Subject: xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate + +From: Antony Antony + +[ 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 +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..55159f4ccd9 --- /dev/null +++ b/queue-5.8/xfrm-use-correct-address-family-in-xfrm_state_find.patch @@ -0,0 +1,82 @@ +From b05b44fbe46e60572c96afecee04829e4df41743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Sep 2020 14:42:56 +1000 +Subject: xfrm: Use correct address family in xfrm_state_find + +From: Herbert Xu + +[ 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 +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..e0fa304f7f0 --- /dev/null +++ b/queue-5.8/xsk-do-not-discard-packet-when-netdev_tx_busy.patch @@ -0,0 +1,77 @@ +From 5ad4437b7eb8ffe86631333e2d93ef35d0c5a55a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Sep 2020 14:00:25 +0200 +Subject: xsk: Do not discard packet when NETDEV_TX_BUSY + +From: Magnus Karlsson + +[ 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 +Suggested-by: Arkadiusz Zema +Suggested-by: Daniel Borkmann +Signed-off-by: Magnus Karlsson +Signed-off-by: Daniel Borkmann +Reviewed-by: Jesse Brandeburg +Link: https://lore.kernel.org/bpf/1600257625-2353-1-git-send-email-magnus.karlsson@gmail.com +Signed-off-by: Sasha Levin +--- + 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 +