From: Sasha Levin Date: Sun, 26 Sep 2021 22:59:05 +0000 (-0400) Subject: Fixes for 5.14 X-Git-Tag: v5.4.150~41 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=14100c2a2cd6f2224ea86b8387271307dd1dff5f;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.14 Signed-off-by: Sasha Levin --- diff --git a/queue-5.14/afs-fix-corruption-in-reads-at-fpos-2g-4g-from-an-op.patch b/queue-5.14/afs-fix-corruption-in-reads-at-fpos-2g-4g-from-an-op.patch new file mode 100644 index 00000000000..9457dc2e342 --- /dev/null +++ b/queue-5.14/afs-fix-corruption-in-reads-at-fpos-2g-4g-from-an-op.patch @@ -0,0 +1,227 @@ +From 5fb67c8bf3ff9d0dd160763e420c7b0eb612ac87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Sep 2021 00:01:52 +0100 +Subject: afs: Fix corruption in reads at fpos 2G-4G from an OpenAFS server + +From: David Howells + +[ Upstream commit b537a3c21775075395af475dcc6ef212fcf29db8 ] + +AFS-3 has two data fetch RPC variants, FS.FetchData and FS.FetchData64, and +Linux's afs client switches between them when talking to a non-YFS server +if the read size, the file position or the sum of the two have the upper 32 +bits set of the 64-bit value. + +This is a problem, however, since the file position and length fields of +FS.FetchData are *signed* 32-bit values. + +Fix this by capturing the capability bits obtained from the fileserver when +it's sent an FS.GetCapabilities RPC, rather than just discarding them, and +then picking out the VICED_CAPABILITY_64BITFILES flag. This can then be +used to decide whether to use FS.FetchData or FS.FetchData64 - and also +FS.StoreData or FS.StoreData64 - rather than using upper_32_bits() to +switch on the parameter values. + +This capabilities flag could also be used to limit the maximum size of the +file, but all servers must be checked for that. + +Note that the issue does not exist with FS.StoreData - that uses *unsigned* +32-bit values. It's also not a problem with Auristor servers as its +YFS.FetchData64 op uses unsigned 64-bit values. + +This can be tested by cloning a git repo through an OpenAFS client to an +OpenAFS server and then doing "git status" on it from a Linux afs +client[1]. Provided the clone has a pack file that's in the 2G-4G range, +the git status will show errors like: + + error: packfile .git/objects/pack/pack-5e813c51d12b6847bbc0fcd97c2bca66da50079c.pack does not match index + error: packfile .git/objects/pack/pack-5e813c51d12b6847bbc0fcd97c2bca66da50079c.pack does not match index + +This can be observed in the server's FileLog with something like the +following appearing: + +Sun Aug 29 19:31:39 2021 SRXAFS_FetchData, Fid = 2303380852.491776.3263114, Host 192.168.11.201:7001, Id 1001 +Sun Aug 29 19:31:39 2021 CheckRights: len=0, for host=192.168.11.201:7001 +Sun Aug 29 19:31:39 2021 FetchData_RXStyle: Pos 18446744071815340032, Len 3154 +Sun Aug 29 19:31:39 2021 FetchData_RXStyle: file size 2400758866 +... +Sun Aug 29 19:31:40 2021 SRXAFS_FetchData returns 5 + +Note the file position of 18446744071815340032. This is the requested file +position sign-extended. + +Fixes: b9b1f8d5930a ("AFS: write support fixes") +Reported-by: Markus Suvanto +Signed-off-by: David Howells +Reviewed-by: Marc Dionne +Tested-by: Markus Suvanto +cc: linux-afs@lists.infradead.org +cc: openafs-devel@openafs.org +Link: https://bugzilla.kernel.org/show_bug.cgi?id=214217#c9 [1] +Link: https://lore.kernel.org/r/951332.1631308745@warthog.procyon.org.uk/ +Signed-off-by: Sasha Levin +--- + fs/afs/fs_probe.c | 8 +++++++- + fs/afs/fsclient.c | 31 ++++++++++++++++++++----------- + fs/afs/internal.h | 1 + + fs/afs/protocol_afs.h | 15 +++++++++++++++ + fs/afs/protocol_yfs.h | 6 ++++++ + 5 files changed, 49 insertions(+), 12 deletions(-) + create mode 100644 fs/afs/protocol_afs.h + +diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c +index e7e98ad63a91..c0031a3ab42f 100644 +--- a/fs/afs/fs_probe.c ++++ b/fs/afs/fs_probe.c +@@ -9,6 +9,7 @@ + #include + #include "afs_fs.h" + #include "internal.h" ++#include "protocol_afs.h" + #include "protocol_yfs.h" + + static unsigned int afs_fs_probe_fast_poll_interval = 30 * HZ; +@@ -102,7 +103,7 @@ void afs_fileserver_probe_result(struct afs_call *call) + struct afs_addr_list *alist = call->alist; + struct afs_server *server = call->server; + unsigned int index = call->addr_ix; +- unsigned int rtt_us = 0; ++ unsigned int rtt_us = 0, cap0; + int ret = call->error; + + _enter("%pU,%u", &server->uuid, index); +@@ -159,6 +160,11 @@ void afs_fileserver_probe_result(struct afs_call *call) + clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags); + alist->addrs[index].srx_service = call->service_id; + } ++ cap0 = ntohl(call->tmp); ++ if (cap0 & AFS3_VICED_CAPABILITY_64BITFILES) ++ set_bit(AFS_SERVER_FL_HAS_FS64, &server->flags); ++ else ++ clear_bit(AFS_SERVER_FL_HAS_FS64, &server->flags); + } + + if (rxrpc_kernel_get_srtt(call->net->socket, call->rxcall, &rtt_us) && +diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c +index dd3f45d906d2..4943413d9c5f 100644 +--- a/fs/afs/fsclient.c ++++ b/fs/afs/fsclient.c +@@ -456,9 +456,7 @@ void afs_fs_fetch_data(struct afs_operation *op) + struct afs_read *req = op->fetch.req; + __be32 *bp; + +- if (upper_32_bits(req->pos) || +- upper_32_bits(req->len) || +- upper_32_bits(req->pos + req->len)) ++ if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) + return afs_fs_fetch_data64(op); + + _enter(""); +@@ -1113,9 +1111,7 @@ void afs_fs_store_data(struct afs_operation *op) + (unsigned long long)op->store.pos, + (unsigned long long)op->store.i_size); + +- if (upper_32_bits(op->store.pos) || +- upper_32_bits(op->store.size) || +- upper_32_bits(op->store.i_size)) ++ if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) + return afs_fs_store_data64(op); + + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData, +@@ -1229,7 +1225,7 @@ static void afs_fs_setattr_size(struct afs_operation *op) + key_serial(op->key), vp->fid.vid, vp->fid.vnode); + + ASSERT(attr->ia_valid & ATTR_SIZE); +- if (upper_32_bits(attr->ia_size)) ++ if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags)) + return afs_fs_setattr_size64(op); + + call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status, +@@ -1657,20 +1653,33 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call) + return ret; + + count = ntohl(call->tmp); +- + call->count = count; + call->count2 = count; +- afs_extract_discard(call, count * sizeof(__be32)); ++ if (count == 0) { ++ call->unmarshall = 4; ++ call->tmp = 0; ++ break; ++ } ++ ++ /* Extract the first word of the capabilities to call->tmp */ ++ afs_extract_to_tmp(call); + call->unmarshall++; + fallthrough; + +- /* Extract capabilities words */ + case 2: + ret = afs_extract_data(call, false); + if (ret < 0) + return ret; + +- /* TODO: Examine capabilities */ ++ afs_extract_discard(call, (count - 1) * sizeof(__be32)); ++ call->unmarshall++; ++ fallthrough; ++ ++ /* Extract remaining capabilities words */ ++ case 3: ++ ret = afs_extract_data(call, false); ++ if (ret < 0) ++ return ret; + + call->unmarshall++; + break; +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 5ed416f4ff33..928408888054 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -516,6 +516,7 @@ struct afs_server { + #define AFS_SERVER_FL_IS_YFS 16 /* Server is YFS not AFS */ + #define AFS_SERVER_FL_NO_IBULK 17 /* Fileserver doesn't support FS.InlineBulkStatus */ + #define AFS_SERVER_FL_NO_RM2 18 /* Fileserver doesn't support YFS.RemoveFile2 */ ++#define AFS_SERVER_FL_HAS_FS64 19 /* Fileserver supports FS.{Fetch,Store}Data64 */ + atomic_t ref; /* Object refcount */ + atomic_t active; /* Active user count */ + u32 addr_version; /* Address list version */ +diff --git a/fs/afs/protocol_afs.h b/fs/afs/protocol_afs.h +new file mode 100644 +index 000000000000..0c39358c8b70 +--- /dev/null ++++ b/fs/afs/protocol_afs.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* AFS protocol bits ++ * ++ * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ */ ++ ++ ++#define AFSCAPABILITIESMAX 196 /* Maximum number of words in a capability set */ ++ ++/* AFS3 Fileserver capabilities word 0 */ ++#define AFS3_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Uses UAE errors */ ++#define AFS3_VICED_CAPABILITY_64BITFILES 0x0002 /* FetchData64 & StoreData64 supported */ ++#define AFS3_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */ ++#define AFS3_VICED_CAPABILITY_SANEACLS 0x0008 /* ACLs reviewed for sanity - don't use */ +diff --git a/fs/afs/protocol_yfs.h b/fs/afs/protocol_yfs.h +index b5bd03b1d3c7..e4cd89c44c46 100644 +--- a/fs/afs/protocol_yfs.h ++++ b/fs/afs/protocol_yfs.h +@@ -168,3 +168,9 @@ enum yfs_lock_type { + yfs_LockMandatoryWrite = 0x101, + yfs_LockMandatoryExtend = 0x102, + }; ++ ++/* RXYFS Viced Capability Flags */ ++#define YFS_VICED_CAPABILITY_ERRORTRANS 0x0001 /* Deprecated v0.195 */ ++#define YFS_VICED_CAPABILITY_64BITFILES 0x0002 /* Deprecated v0.195 */ ++#define YFS_VICED_CAPABILITY_WRITELOCKACL 0x0004 /* Can lock a file even without lock perm */ ++#define YFS_VICED_CAPABILITY_SANEACLS 0x0008 /* Deprecated v0.195 */ +-- +2.33.0 + diff --git a/queue-5.14/afs-fix-incorrect-triggering-of-sillyrename-on-3rd-p.patch b/queue-5.14/afs-fix-incorrect-triggering-of-sillyrename-on-3rd-p.patch new file mode 100644 index 00000000000..40df497d451 --- /dev/null +++ b/queue-5.14/afs-fix-incorrect-triggering-of-sillyrename-on-3rd-p.patch @@ -0,0 +1,168 @@ +From 91a80e76db4e4b1b7f72cd06d014eadbb8a254d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Sep 2021 18:11:33 +0100 +Subject: afs: Fix incorrect triggering of sillyrename on 3rd-party + invalidation + +From: David Howells + +[ Upstream commit 63d49d843ef5fffeea069e0ffdfbd2bf40ba01c6 ] + +The AFS filesystem is currently triggering the silly-rename cleanup from +afs_d_revalidate() when it sees that a dentry has been changed by a third +party[1]. It should not be doing this as the cleanup includes deleting the +silly-rename target file on iput. + +Fix this by removing the places in the d_revalidate handling that validate +anything other than the directory and the dirent. It probably should not +be looking to validate the target inode of the dentry also. + +This includes removing the point in afs_d_revalidate() where the inode that +a dentry used to point to was marked as being deleted (AFS_VNODE_DELETED). +We don't know it got deleted. It could have been renamed or it could have +hard links remaining. + +This was reproduced by cloning a git repo onto an afs volume on one +machine, switching to another machine and doing "git status", then +switching back to the first and doing "git status". The second status +would show weird output due to ".git/index" getting deleted by the above +mentioned mechanism. + +A simpler way to do it is to do: + + machine 1: touch a + machine 2: touch b; mv -f b a + machine 1: stat a + +on an afs volume. The bug shows up as the stat failing with ENOENT and the +file server log showing that machine 1 deleted "a". + +Fixes: 79ddbfa500b3 ("afs: Implement sillyrename for unlink and rename") +Reported-by: Markus Suvanto +Signed-off-by: David Howells +Tested-by: Markus Suvanto +cc: linux-afs@lists.infradead.org +Link: https://bugzilla.kernel.org/show_bug.cgi?id=214217#c4 [1] +Link: https://lore.kernel.org/r/163111668100.283156.3851669884664475428.stgit@warthog.procyon.org.uk/ +Signed-off-by: Sasha Levin +--- + fs/afs/dir.c | 46 +++++++--------------------------------------- + 1 file changed, 7 insertions(+), 39 deletions(-) + +diff --git a/fs/afs/dir.c b/fs/afs/dir.c +index ac829e63c570..54ee54ae36bc 100644 +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1077,9 +1077,9 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, + */ + static int afs_d_revalidate_rcu(struct dentry *dentry) + { +- struct afs_vnode *dvnode, *vnode; ++ struct afs_vnode *dvnode; + struct dentry *parent; +- struct inode *dir, *inode; ++ struct inode *dir; + long dir_version, de_version; + + _enter("%p", dentry); +@@ -1109,18 +1109,6 @@ static int afs_d_revalidate_rcu(struct dentry *dentry) + return -ECHILD; + } + +- /* Check to see if the vnode referred to by the dentry still +- * has a callback. +- */ +- if (d_really_is_positive(dentry)) { +- inode = d_inode_rcu(dentry); +- if (inode) { +- vnode = AFS_FS_I(inode); +- if (!afs_check_validity(vnode)) +- return -ECHILD; +- } +- } +- + return 1; /* Still valid */ + } + +@@ -1156,17 +1144,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + if (IS_ERR(key)) + key = NULL; + +- if (d_really_is_positive(dentry)) { +- inode = d_inode(dentry); +- if (inode) { +- vnode = AFS_FS_I(inode); +- afs_validate(vnode, key); +- if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) +- goto out_bad; +- } +- } +- +- /* lock down the parent dentry so we can peer at it */ ++ /* Hold the parent dentry so we can peer at it */ + parent = dget_parent(dentry); + dir = AFS_FS_I(d_inode(parent)); + +@@ -1175,7 +1153,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + + if (test_bit(AFS_VNODE_DELETED, &dir->flags)) { + _debug("%pd: parent dir deleted", dentry); +- goto out_bad_parent; ++ goto not_found; + } + + /* We only need to invalidate a dentry if the server's copy changed +@@ -1201,12 +1179,12 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + case 0: + /* the filename maps to something */ + if (d_really_is_negative(dentry)) +- goto out_bad_parent; ++ goto not_found; + inode = d_inode(dentry); + if (is_bad_inode(inode)) { + printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n", + dentry); +- goto out_bad_parent; ++ goto not_found; + } + + vnode = AFS_FS_I(inode); +@@ -1228,9 +1206,6 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + dentry, fid.unique, + vnode->fid.unique, + vnode->vfs_inode.i_generation); +- write_seqlock(&vnode->cb_lock); +- set_bit(AFS_VNODE_DELETED, &vnode->flags); +- write_sequnlock(&vnode->cb_lock); + goto not_found; + } + goto out_valid; +@@ -1245,7 +1220,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + default: + _debug("failed to iterate dir %pd: %d", + parent, ret); +- goto out_bad_parent; ++ goto not_found; + } + + out_valid: +@@ -1256,16 +1231,9 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) + _leave(" = 1 [valid]"); + return 1; + +- /* the dirent, if it exists, now points to a different vnode */ + not_found: +- spin_lock(&dentry->d_lock); +- dentry->d_flags |= DCACHE_NFSFS_RENAMED; +- spin_unlock(&dentry->d_lock); +- +-out_bad_parent: + _debug("dropping dentry %pd2", dentry); + dput(parent); +-out_bad: + key_put(key); + + _leave(" = 0 [bad]"); +-- +2.33.0 + diff --git a/queue-5.14/afs-fix-page-leak.patch b/queue-5.14/afs-fix-page-leak.patch new file mode 100644 index 00000000000..0e6e4e0b1e7 --- /dev/null +++ b/queue-5.14/afs-fix-page-leak.patch @@ -0,0 +1,73 @@ +From d7185ea92614526b1882e73a7d19465cff5fb1c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Sep 2021 09:15:21 +0100 +Subject: afs: Fix page leak + +From: David Howells + +[ Upstream commit 581b2027af0018944ba301d68e7af45c6d1128b5 ] + +There's a loop in afs_extend_writeback() that adds extra pages to a write +we want to make to improve the efficiency of the writeback by making it +larger. This loop stops, however, if we hit a page we can't write back +from immediately, but it doesn't get rid of the page ref we speculatively +acquired. + +This was caused by the removal of the cleanup loop when the code switched +from using find_get_pages_contig() to xarray scanning as the latter only +gets a single page at a time, not a batch. + +Fix this by putting the page on a ref on an early break from the loop. +Unfortunately, we can't just add that page to the pagevec we're employing +as we'll go through that and add those pages to the RPC call. + +This was found by the generic/074 test. It leaks ~4GiB of RAM each time it +is run - which can be observed with "top". + +Fixes: e87b03f5830e ("afs: Prepare for use of THPs") +Reported-by: Marc Dionne +Signed-off-by: David Howells +Reviewed-and-tested-by: Marc Dionne +cc: linux-afs@lists.infradead.org +Link: https://lore.kernel.org/r/163111666635.283156.177701903478910460.stgit@warthog.procyon.org.uk/ +Signed-off-by: Sasha Levin +--- + fs/afs/write.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/fs/afs/write.c b/fs/afs/write.c +index c0534697268e..66b235266893 100644 +--- a/fs/afs/write.c ++++ b/fs/afs/write.c +@@ -471,13 +471,18 @@ static void afs_extend_writeback(struct address_space *mapping, + } + + /* Has the page moved or been split? */ +- if (unlikely(page != xas_reload(&xas))) ++ if (unlikely(page != xas_reload(&xas))) { ++ put_page(page); + break; ++ } + +- if (!trylock_page(page)) ++ if (!trylock_page(page)) { ++ put_page(page); + break; ++ } + if (!PageDirty(page) || PageWriteback(page)) { + unlock_page(page); ++ put_page(page); + break; + } + +@@ -487,6 +492,7 @@ static void afs_extend_writeback(struct address_space *mapping, + t = afs_page_dirty_to(page, priv); + if (f != 0 && !new_content) { + unlock_page(page); ++ put_page(page); + break; + } + +-- +2.33.0 + diff --git a/queue-5.14/afs-fix-updating-of-i_blocks-on-file-dir-extension.patch b/queue-5.14/afs-fix-updating-of-i_blocks-on-file-dir-extension.patch new file mode 100644 index 00000000000..4824a80a3c5 --- /dev/null +++ b/queue-5.14/afs-fix-updating-of-i_blocks-on-file-dir-extension.patch @@ -0,0 +1,118 @@ +From 156ba2d7137e093c21ca9f824caf71e8fe1d8b8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Sep 2021 21:55:19 +0100 +Subject: afs: Fix updating of i_blocks on file/dir extension + +From: David Howells + +[ Upstream commit 9d37e1cab2a9d2cee2737973fa455e6f89eee46a ] + +When an afs file or directory is modified locally such that the total file +size is extended, i_blocks needs to be recalculated too. + +Fix this by making afs_write_end() and afs_edit_dir_add() call +afs_set_i_size() rather than setting inode->i_size directly as that also +recalculates inode->i_blocks. + +This can be tested by creating and writing into directories and files and +then examining them with du. Without this change, directories show a 4 +blocks (they start out at 2048 bytes) and files show 0 blocks; with this +change, they should show a number of blocks proportional to the file size +rounded up to 1024. + +Fixes: 31143d5d515e ("AFS: implement basic file write support") +Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...") +Reported-by: Markus Suvanto +Signed-off-by: David Howells +Reviewed-by: Marc Dionne +Tested-by: Markus Suvanto +cc: linux-afs@lists.infradead.org +Link: https://lore.kernel.org/r/163113612442.352844.11162345591911691150.stgit@warthog.procyon.org.uk/ +Signed-off-by: Sasha Levin +--- + fs/afs/dir_edit.c | 4 ++-- + fs/afs/inode.c | 10 ---------- + fs/afs/internal.h | 10 ++++++++++ + fs/afs/write.c | 2 +- + 4 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c +index f4600c1353ad..540b9fc96824 100644 +--- a/fs/afs/dir_edit.c ++++ b/fs/afs/dir_edit.c +@@ -263,7 +263,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, + if (b == nr_blocks) { + _debug("init %u", b); + afs_edit_init_block(meta, block, b); +- i_size_write(&vnode->vfs_inode, (b + 1) * AFS_DIR_BLOCK_SIZE); ++ afs_set_i_size(vnode, (b + 1) * AFS_DIR_BLOCK_SIZE); + } + + /* Only lower dir pages have a counter in the header. */ +@@ -296,7 +296,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, + new_directory: + afs_edit_init_block(meta, meta, 0); + i_size = AFS_DIR_BLOCK_SIZE; +- i_size_write(&vnode->vfs_inode, i_size); ++ afs_set_i_size(vnode, i_size); + slot = AFS_DIR_RESV_BLOCKS0; + page = page0; + block = meta; +diff --git a/fs/afs/inode.c b/fs/afs/inode.c +index 80b6c8d967d5..c18cbc69fa58 100644 +--- a/fs/afs/inode.c ++++ b/fs/afs/inode.c +@@ -53,16 +53,6 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren + dump_stack(); + } + +-/* +- * Set the file size and block count. Estimate the number of 512 bytes blocks +- * used, rounded up to nearest 1K for consistency with other AFS clients. +- */ +-static void afs_set_i_size(struct afs_vnode *vnode, u64 size) +-{ +- i_size_write(&vnode->vfs_inode, size); +- vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1; +-} +- + /* + * Initialise an inode from the vnode status. + */ +diff --git a/fs/afs/internal.h b/fs/afs/internal.h +index 928408888054..345494881f65 100644 +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -1586,6 +1586,16 @@ static inline void afs_update_dentry_version(struct afs_operation *op, + (void *)(unsigned long)dir_vp->scb.status.data_version; + } + ++/* ++ * Set the file size and block count. Estimate the number of 512 bytes blocks ++ * used, rounded up to nearest 1K for consistency with other AFS clients. ++ */ ++static inline void afs_set_i_size(struct afs_vnode *vnode, u64 size) ++{ ++ i_size_write(&vnode->vfs_inode, size); ++ vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1; ++} ++ + /* + * Check for a conflicting operation on a directory that we just unlinked from. + * If someone managed to sneak a link or an unlink in on the file we just +diff --git a/fs/afs/write.c b/fs/afs/write.c +index 66b235266893..e86f5a245514 100644 +--- a/fs/afs/write.c ++++ b/fs/afs/write.c +@@ -137,7 +137,7 @@ int afs_write_end(struct file *file, struct address_space *mapping, + write_seqlock(&vnode->cb_lock); + i_size = i_size_read(&vnode->vfs_inode); + if (maybe_i_size > i_size) +- i_size_write(&vnode->vfs_inode, maybe_i_size); ++ afs_set_i_size(vnode, maybe_i_size); + write_sequnlock(&vnode->cb_lock); + } + +-- +2.33.0 + diff --git a/queue-5.14/atlantic-fix-issue-in-the-pm-resume-flow.patch b/queue-5.14/atlantic-fix-issue-in-the-pm-resume-flow.patch new file mode 100644 index 00000000000..09efe376db1 --- /dev/null +++ b/queue-5.14/atlantic-fix-issue-in-the-pm-resume-flow.patch @@ -0,0 +1,47 @@ +From 639f62086b5f30c9928cb016aa44d239edbcdb97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Sep 2021 03:16:05 -0700 +Subject: atlantic: Fix issue in the pm resume flow. + +From: Sudarsana Reddy Kalluru + +[ Upstream commit 4d88c339c423eefe2fd48215016cb0c75fcb4c4d ] + +After fixing hibernation resume flow, another usecase was found which +should be explicitly handled - resume when device is in "down" state. +Invoke aq_nic_init jointly with aq_nic_start only if ndev was already +up during suspend/hibernate. We still need to perform nic_deinit() if +caller requests for it, to handle the freeze/resume scenarios. + +Fixes: 57f780f1c433 ("atlantic: Fix driver resume flow.") +Signed-off-by: Sudarsana Reddy Kalluru +Signed-off-by: Igor Russkikh +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +index f26d03735619..5b996330f228 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +@@ -419,13 +419,13 @@ static int atl_resume_common(struct device *dev, bool deep) + if (deep) { + /* Reinitialize Nic/Vecs objects */ + aq_nic_deinit(nic, !nic->aq_hw->aq_nic_cfg->wol); ++ } + ++ if (netif_running(nic->ndev)) { + ret = aq_nic_init(nic); + if (ret) + goto err_exit; +- } + +- if (netif_running(nic->ndev)) { + ret = aq_nic_start(nic); + if (ret) + goto err_exit; +-- +2.33.0 + diff --git a/queue-5.14/bnxt_en-fix-tx-timeout-when-tx-ring-size-is-set-to-t.patch b/queue-5.14/bnxt_en-fix-tx-timeout-when-tx-ring-size-is-set-to-t.patch new file mode 100644 index 00000000000..2d41178ddc3 --- /dev/null +++ b/queue-5.14/bnxt_en-fix-tx-timeout-when-tx-ring-size-is-set-to-t.patch @@ -0,0 +1,105 @@ +From c5193ea352b9a256ce4c490e65cdd3f28039c040 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Sep 2021 02:51:52 -0400 +Subject: bnxt_en: Fix TX timeout when TX ring size is set to the smallest + +From: Michael Chan + +[ Upstream commit 5bed8b0704c9ecccc8f4a2c377d7c8e21090a82e ] + +The smallest TX ring size we support must fit a TX SKB with MAX_SKB_FRAGS ++ 1. Because the first TX BD for a packet is always a long TX BD, we +need an extra TX BD to fit this packet. Define BNXT_MIN_TX_DESC_CNT with +this value to make this more clear. The current code uses a minimum +that is off by 1. Fix it using this constant. + +The tx_wake_thresh to determine when to wake up the TX queue is half the +ring size but we must have at least BNXT_MIN_TX_DESC_CNT for the next +packet which may have maximum fragments. So the comparison of the +available TX BDs with tx_wake_thresh should be >= instead of > in the +current code. Otherwise, at the smallest ring size, we will never wake +up the TX queue and will cause TX timeout. + +Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") +Reviewed-by: Pavan Chebbi +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 ++++---- + drivers/net/ethernet/broadcom/bnxt/bnxt.h | 5 +++++ + drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- + 3 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index fdbf47446a99..f20b57b8cd70 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -385,7 +385,7 @@ static bool bnxt_txr_netif_try_stop_queue(struct bnxt *bp, + * netif_tx_queue_stopped(). + */ + smp_mb(); +- if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) { ++ if (bnxt_tx_avail(bp, txr) >= bp->tx_wake_thresh) { + netif_tx_wake_queue(txq); + return false; + } +@@ -758,7 +758,7 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) + smp_mb(); + + if (unlikely(netif_tx_queue_stopped(txq)) && +- bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && ++ bnxt_tx_avail(bp, txr) >= bp->tx_wake_thresh && + READ_ONCE(txr->dev_state) != BNXT_DEV_STATE_CLOSING) + netif_tx_wake_queue(txq); + } +@@ -2375,7 +2375,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, + if (TX_CMP_TYPE(txcmp) == CMP_TYPE_TX_L2_CMP) { + tx_pkts++; + /* return full budget so NAPI will complete. */ +- if (unlikely(tx_pkts > bp->tx_wake_thresh)) { ++ if (unlikely(tx_pkts >= bp->tx_wake_thresh)) { + rx_pkts = budget; + raw_cons = NEXT_RAW_CMP(raw_cons); + if (budget) +@@ -3531,7 +3531,7 @@ static int bnxt_init_tx_rings(struct bnxt *bp) + u16 i; + + bp->tx_wake_thresh = max_t(int, bp->tx_ring_size / 2, +- MAX_SKB_FRAGS + 1); ++ BNXT_MIN_TX_DESC_CNT); + + for (i = 0; i < bp->tx_nr_rings; i++) { + struct bnxt_tx_ring_info *txr = &bp->tx_ring[i]; +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +index ba4e0fc38520..d4dca4508d26 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +@@ -615,6 +615,11 @@ struct nqe_cn { + #define BNXT_MAX_RX_JUM_DESC_CNT (RX_DESC_CNT * MAX_RX_AGG_PAGES - 1) + #define BNXT_MAX_TX_DESC_CNT (TX_DESC_CNT * MAX_TX_PAGES - 1) + ++/* Minimum TX BDs for a TX packet with MAX_SKB_FRAGS + 1. We need one extra ++ * BD because the first TX BD is always a long BD. ++ */ ++#define BNXT_MIN_TX_DESC_CNT (MAX_SKB_FRAGS + 2) ++ + #define RX_RING(x) (((x) & ~(RX_DESC_CNT - 1)) >> (BNXT_PAGE_SHIFT - 4)) + #define RX_IDX(x) ((x) & (RX_DESC_CNT - 1)) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index 786ca51e669b..3a8c28463592 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -784,7 +784,7 @@ static int bnxt_set_ringparam(struct net_device *dev, + + if ((ering->rx_pending > BNXT_MAX_RX_DESC_CNT) || + (ering->tx_pending > BNXT_MAX_TX_DESC_CNT) || +- (ering->tx_pending <= MAX_SKB_FRAGS)) ++ (ering->tx_pending < BNXT_MIN_TX_DESC_CNT)) + return -EINVAL; + + if (netif_running(dev)) +-- +2.33.0 + diff --git a/queue-5.14/drm-amdkfd-fix-dma-mapping-leaking-warning.patch b/queue-5.14/drm-amdkfd-fix-dma-mapping-leaking-warning.patch new file mode 100644 index 00000000000..b433df5cf07 --- /dev/null +++ b/queue-5.14/drm-amdkfd-fix-dma-mapping-leaking-warning.patch @@ -0,0 +1,92 @@ +From 0f9a3e1ae8c30341caea807fb637c3052c984a55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Sep 2021 16:33:40 -0400 +Subject: drm/amdkfd: fix dma mapping leaking warning + +From: Philip Yang + +[ Upstream commit f63251184a81039ebc805306505838c2a073e51a ] + +For xnack off, restore work dma unmap previous system memory page, and +dma map the updated system memory page to update GPU mapping, this is +not dma mapping leaking, remove the WARN_ONCE for dma mapping leaking. + +prange->dma_addr store the VRAM page pfn after the range migrated to +VRAM, should not dma unmap VRAM page when updating GPU mapping or +remove prange. Add helper svm_is_valid_dma_mapping_addr to check VRAM +page and error cases. + +Mask out SVM_RANGE_VRAM_DOMAIN flag in dma_addr before calling amdgpu vm +update to avoid BUG_ON(*addr & 0xFFFF00000000003FULL), and set it again +immediately after. This flag is used to know the type of page later to +dma unmapping system memory page. + +Fixes: 1d5dbfe6c06a ("drm/amdkfd: classify and map mixed svm range pages in GPU") +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index ddac10b5bd3a..e85035fd1ccb 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -118,6 +118,13 @@ static void svm_range_remove_notifier(struct svm_range *prange) + mmu_interval_notifier_remove(&prange->notifier); + } + ++static bool ++svm_is_valid_dma_mapping_addr(struct device *dev, dma_addr_t dma_addr) ++{ ++ return dma_addr && !dma_mapping_error(dev, dma_addr) && ++ !(dma_addr & SVM_RANGE_VRAM_DOMAIN); ++} ++ + static int + svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, + unsigned long offset, unsigned long npages, +@@ -139,8 +146,7 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, + + addr += offset; + for (i = 0; i < npages; i++) { +- if (WARN_ONCE(addr[i] && !dma_mapping_error(dev, addr[i]), +- "leaking dma mapping\n")) ++ if (svm_is_valid_dma_mapping_addr(dev, addr[i])) + dma_unmap_page(dev, addr[i], PAGE_SIZE, dir); + + page = hmm_pfn_to_page(hmm_pfns[i]); +@@ -209,7 +215,7 @@ void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr, + return; + + for (i = offset; i < offset + npages; i++) { +- if (!dma_addr[i] || dma_mapping_error(dev, dma_addr[i])) ++ if (!svm_is_valid_dma_mapping_addr(dev, dma_addr[i])) + continue; + pr_debug("dma unmapping 0x%llx\n", dma_addr[i] >> PAGE_SHIFT); + dma_unmap_page(dev, dma_addr[i], PAGE_SIZE, dir); +@@ -1165,7 +1171,7 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, + unsigned long last_start; + int last_domain; + int r = 0; +- int64_t i; ++ int64_t i, j; + + last_start = prange->start + offset; + +@@ -1201,6 +1207,10 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, + NULL, dma_addr, + &vm->last_update, + &table_freed); ++ ++ for (j = last_start - prange->start; j <= i; j++) ++ dma_addr[j] |= last_domain; ++ + if (r) { + pr_debug("failed %d to map to gpu 0x%lx\n", r, prange->start); + goto out; +-- +2.33.0 + diff --git a/queue-5.14/drm-amdkfd-map-svm-range-with-correct-access-permiss.patch b/queue-5.14/drm-amdkfd-map-svm-range-with-correct-access-permiss.patch new file mode 100644 index 00000000000..9955f6bd75e --- /dev/null +++ b/queue-5.14/drm-amdkfd-map-svm-range-with-correct-access-permiss.patch @@ -0,0 +1,262 @@ +From e59ed433e8f04fc3300c0a349f2913470b60083b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Aug 2021 09:34:53 -0400 +Subject: drm/amdkfd: map SVM range with correct access permission + +From: Philip Yang + +[ Upstream commit 2f617f4df8dfef68f175160d533f5820a368023e ] + +Restore retry fault or prefetch range, or restore svm range after +eviction to map range to GPU with correct read or write access +permission. + +Range may includes multiple VMAs, update GPU page table with offset of +prange, number of pages for each VMA according VMA access permission. + +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 134 +++++++++++++++++---------- + 1 file changed, 86 insertions(+), 48 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +index 0f7f1e5621ea..ddac10b5bd3a 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +@@ -120,6 +120,7 @@ static void svm_range_remove_notifier(struct svm_range *prange) + + static int + svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, ++ unsigned long offset, unsigned long npages, + unsigned long *hmm_pfns, uint32_t gpuidx) + { + enum dma_data_direction dir = DMA_BIDIRECTIONAL; +@@ -136,7 +137,8 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, + prange->dma_addr[gpuidx] = addr; + } + +- for (i = 0; i < prange->npages; i++) { ++ addr += offset; ++ for (i = 0; i < npages; i++) { + if (WARN_ONCE(addr[i] && !dma_mapping_error(dev, addr[i]), + "leaking dma mapping\n")) + dma_unmap_page(dev, addr[i], PAGE_SIZE, dir); +@@ -167,6 +169,7 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, + + static int + svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap, ++ unsigned long offset, unsigned long npages, + unsigned long *hmm_pfns) + { + struct kfd_process *p; +@@ -187,7 +190,8 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap, + } + adev = (struct amdgpu_device *)pdd->dev->kgd; + +- r = svm_range_dma_map_dev(adev, prange, hmm_pfns, gpuidx); ++ r = svm_range_dma_map_dev(adev, prange, offset, npages, ++ hmm_pfns, gpuidx); + if (r) + break; + } +@@ -1088,11 +1092,6 @@ svm_range_get_pte_flags(struct amdgpu_device *adev, struct svm_range *prange, + pte_flags |= snoop ? AMDGPU_PTE_SNOOPED : 0; + + pte_flags |= amdgpu_gem_va_map_flags(adev, mapping_flags); +- +- pr_debug("svms 0x%p [0x%lx 0x%lx] vram %d PTE 0x%llx mapping 0x%x\n", +- prange->svms, prange->start, prange->last, +- (domain == SVM_RANGE_VRAM_DOMAIN) ? 1:0, pte_flags, mapping_flags); +- + return pte_flags; + } + +@@ -1156,7 +1155,8 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, + + static int + svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, +- struct svm_range *prange, dma_addr_t *dma_addr, ++ struct svm_range *prange, unsigned long offset, ++ unsigned long npages, bool readonly, dma_addr_t *dma_addr, + struct amdgpu_device *bo_adev, struct dma_fence **fence) + { + struct amdgpu_bo_va bo_va; +@@ -1167,14 +1167,15 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, + int r = 0; + int64_t i; + +- pr_debug("svms 0x%p [0x%lx 0x%lx]\n", prange->svms, prange->start, +- prange->last); ++ last_start = prange->start + offset; ++ ++ pr_debug("svms 0x%p [0x%lx 0x%lx] readonly %d\n", prange->svms, ++ last_start, last_start + npages - 1, readonly); + + if (prange->svm_bo && prange->ttm_res) + bo_va.is_xgmi = amdgpu_xgmi_same_hive(adev, bo_adev); + +- last_start = prange->start; +- for (i = 0; i < prange->npages; i++) { ++ for (i = offset; i < offset + npages; i++) { + last_domain = dma_addr[i] & SVM_RANGE_VRAM_DOMAIN; + dma_addr[i] &= ~SVM_RANGE_VRAM_DOMAIN; + if ((prange->start + i) < prange->last && +@@ -1183,13 +1184,21 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, + + pr_debug("Mapping range [0x%lx 0x%llx] on domain: %s\n", + last_start, prange->start + i, last_domain ? "GPU" : "CPU"); ++ + pte_flags = svm_range_get_pte_flags(adev, prange, last_domain); +- r = amdgpu_vm_bo_update_mapping(adev, bo_adev, vm, false, false, NULL, +- last_start, ++ if (readonly) ++ pte_flags &= ~AMDGPU_PTE_WRITEABLE; ++ ++ pr_debug("svms 0x%p map [0x%lx 0x%llx] vram %d PTE 0x%llx\n", ++ prange->svms, last_start, prange->start + i, ++ (last_domain == SVM_RANGE_VRAM_DOMAIN) ? 1 : 0, ++ pte_flags); ++ ++ r = amdgpu_vm_bo_update_mapping(adev, bo_adev, vm, false, false, ++ NULL, last_start, + prange->start + i, pte_flags, + last_start - prange->start, +- NULL, +- dma_addr, ++ NULL, dma_addr, + &vm->last_update, + &table_freed); + if (r) { +@@ -1220,8 +1229,10 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, + return r; + } + +-static int svm_range_map_to_gpus(struct svm_range *prange, +- unsigned long *bitmap, bool wait) ++static int ++svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset, ++ unsigned long npages, bool readonly, ++ unsigned long *bitmap, bool wait) + { + struct kfd_process_device *pdd; + struct amdgpu_device *bo_adev; +@@ -1257,7 +1268,8 @@ static int svm_range_map_to_gpus(struct svm_range *prange, + } + + r = svm_range_map_to_gpu(adev, drm_priv_to_vm(pdd->drm_priv), +- prange, prange->dma_addr[gpuidx], ++ prange, offset, npages, readonly, ++ prange->dma_addr[gpuidx], + bo_adev, wait ? &fence : NULL); + if (r) + break; +@@ -1390,7 +1402,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, + int32_t gpuidx, bool intr, bool wait) + { + struct svm_validate_context ctx; +- struct hmm_range *hmm_range; ++ unsigned long start, end, addr; + struct kfd_process *p; + void *owner; + int32_t idx; +@@ -1448,40 +1460,66 @@ static int svm_range_validate_and_map(struct mm_struct *mm, + break; + } + } +- r = amdgpu_hmm_range_get_pages(&prange->notifier, mm, NULL, +- prange->start << PAGE_SHIFT, +- prange->npages, &hmm_range, +- false, true, owner); +- if (r) { +- pr_debug("failed %d to get svm range pages\n", r); +- goto unreserve_out; +- } + +- r = svm_range_dma_map(prange, ctx.bitmap, +- hmm_range->hmm_pfns); +- if (r) { +- pr_debug("failed %d to dma map range\n", r); +- goto unreserve_out; +- } ++ start = prange->start << PAGE_SHIFT; ++ end = (prange->last + 1) << PAGE_SHIFT; ++ for (addr = start; addr < end && !r; ) { ++ struct hmm_range *hmm_range; ++ struct vm_area_struct *vma; ++ unsigned long next; ++ unsigned long offset; ++ unsigned long npages; ++ bool readonly; + +- prange->validated_once = true; ++ vma = find_vma(mm, addr); ++ if (!vma || addr < vma->vm_start) { ++ r = -EFAULT; ++ goto unreserve_out; ++ } ++ readonly = !(vma->vm_flags & VM_WRITE); + +- svm_range_lock(prange); +- if (amdgpu_hmm_range_get_pages_done(hmm_range)) { +- pr_debug("hmm update the range, need validate again\n"); +- r = -EAGAIN; +- goto unlock_out; +- } +- if (!list_empty(&prange->child_list)) { +- pr_debug("range split by unmap in parallel, validate again\n"); +- r = -EAGAIN; +- goto unlock_out; +- } ++ next = min(vma->vm_end, end); ++ npages = (next - addr) >> PAGE_SHIFT; ++ r = amdgpu_hmm_range_get_pages(&prange->notifier, mm, NULL, ++ addr, npages, &hmm_range, ++ readonly, true, owner); ++ if (r) { ++ pr_debug("failed %d to get svm range pages\n", r); ++ goto unreserve_out; ++ } + +- r = svm_range_map_to_gpus(prange, ctx.bitmap, wait); ++ offset = (addr - start) >> PAGE_SHIFT; ++ r = svm_range_dma_map(prange, ctx.bitmap, offset, npages, ++ hmm_range->hmm_pfns); ++ if (r) { ++ pr_debug("failed %d to dma map range\n", r); ++ goto unreserve_out; ++ } ++ ++ svm_range_lock(prange); ++ if (amdgpu_hmm_range_get_pages_done(hmm_range)) { ++ pr_debug("hmm update the range, need validate again\n"); ++ r = -EAGAIN; ++ goto unlock_out; ++ } ++ if (!list_empty(&prange->child_list)) { ++ pr_debug("range split by unmap in parallel, validate again\n"); ++ r = -EAGAIN; ++ goto unlock_out; ++ } ++ ++ r = svm_range_map_to_gpus(prange, offset, npages, readonly, ++ ctx.bitmap, wait); + + unlock_out: +- svm_range_unlock(prange); ++ svm_range_unlock(prange); ++ ++ addr = next; ++ } ++ ++ if (addr == end) ++ prange->validated_once = true; ++ + unreserve_out: + svm_range_unreserve_bos(&ctx); + +-- +2.33.0 + diff --git a/queue-5.14/enetc-fix-illegal-access-when-reading-affinity_hint.patch b/queue-5.14/enetc-fix-illegal-access-when-reading-affinity_hint.patch new file mode 100644 index 00000000000..42421fb21c6 --- /dev/null +++ b/queue-5.14/enetc-fix-illegal-access-when-reading-affinity_hint.patch @@ -0,0 +1,54 @@ +From 660f756a6358ea6c7aa75a240b0ca081b89f140c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 13:22:05 +0300 +Subject: enetc: Fix illegal access when reading affinity_hint + +From: Claudiu Manoil + +[ Upstream commit 7237a494decfa17d0b9d0076e6cee3235719de90 ] + +irq_set_affinity_hit() stores a reference to the cpumask_t +parameter in the irq descriptor, and that reference can be +accessed later from irq_affinity_hint_proc_show(). Since +the cpu_mask parameter passed to irq_set_affinity_hit() has +only temporary storage (it's on the stack memory), later +accesses to it are illegal. Thus reads from the corresponding +procfs affinity_hint file can result in paging request oops. + +The issue is fixed by the get_cpu_mask() helper, which provides +a permanent storage for the cpumask_t parameter. + +Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") +Signed-off-by: Claudiu Manoil +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index 3ca93adb9662..7f90c27c0e79 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -1879,7 +1879,6 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv) + static int enetc_setup_irqs(struct enetc_ndev_priv *priv) + { + struct pci_dev *pdev = priv->si->pdev; +- cpumask_t cpu_mask; + int i, j, err; + + for (i = 0; i < priv->bdr_int_num; i++) { +@@ -1908,9 +1907,7 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv) + + enetc_wr(hw, ENETC_SIMSITRV(idx), entry); + } +- cpumask_clear(&cpu_mask); +- cpumask_set_cpu(i % num_online_cpus(), &cpu_mask); +- irq_set_affinity_hint(irq, &cpu_mask); ++ irq_set_affinity_hint(irq, get_cpu_mask(i % num_online_cpus())); + } + + return 0; +-- +2.33.0 + diff --git a/queue-5.14/enetc-fix-uninitialized-struct-dim_sample-field-usag.patch b/queue-5.14/enetc-fix-uninitialized-struct-dim_sample-field-usag.patch new file mode 100644 index 00000000000..e0c7dc6436c --- /dev/null +++ b/queue-5.14/enetc-fix-uninitialized-struct-dim_sample-field-usag.patch @@ -0,0 +1,45 @@ +From e5f82d256992b7f85706f6310223fcc2dbdeb2ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 13:22:06 +0300 +Subject: enetc: Fix uninitialized struct dim_sample field usage + +From: Claudiu Manoil + +[ Upstream commit 9f7afa05c9522b086327929ae622facab0f0f72b ] + +The only struct dim_sample member that does not get +initialized by dim_update_sample() is comp_ctr. (There +is special API to initialize comp_ctr: +dim_update_sample_with_comps(), and it is currently used +only for RDMA.) comp_ctr is used to compute curr_stats->cmps +and curr_stats->cpe_ratio (see dim_calc_stats()) which in +turn are consumed by the rdma_dim_*() API. Therefore, +functionally, the net_dim*() API consumers are not affected. +Nevertheless, fix the computation of statistics based +on an uninitialized variable, even if the mentioned statistics +are not used at the moment. + +Fixes: ae0e6a5d1627 ("enetc: Add adaptive interrupt coalescing") +Signed-off-by: Claudiu Manoil +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index 7f90c27c0e79..042327b9981f 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -419,7 +419,7 @@ static void enetc_rx_dim_work(struct work_struct *w) + + static void enetc_rx_net_dim(struct enetc_int_vector *v) + { +- struct dim_sample dim_sample; ++ struct dim_sample dim_sample = {}; + + v->comp_cnt++; + +-- +2.33.0 + diff --git a/queue-5.14/gpio-uniphier-fix-void-functions-to-remove-return-va.patch b/queue-5.14/gpio-uniphier-fix-void-functions-to-remove-return-va.patch new file mode 100644 index 00000000000..a3818c8d556 --- /dev/null +++ b/queue-5.14/gpio-uniphier-fix-void-functions-to-remove-return-va.patch @@ -0,0 +1,45 @@ +From 73b2756a7b24d59169de31ec4a1987e6a4b0b770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 20:19:35 +0900 +Subject: gpio: uniphier: Fix void functions to remove return value + +From: Kunihiko Hayashi + +[ Upstream commit 2dd824cca3407bc9a2bd11b00f6e117b66fcfcf1 ] + +The return type of irq_chip.irq_mask() and irq_chip.irq_unmask() should +be void. + +Fixes: dbe776c2ca54 ("gpio: uniphier: add UniPhier GPIO controller driver") +Signed-off-by: Kunihiko Hayashi +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-uniphier.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-uniphier.c b/drivers/gpio/gpio-uniphier.c +index f99f3c10bed0..39dca147d587 100644 +--- a/drivers/gpio/gpio-uniphier.c ++++ b/drivers/gpio/gpio-uniphier.c +@@ -184,7 +184,7 @@ static void uniphier_gpio_irq_mask(struct irq_data *data) + + uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, 0); + +- return irq_chip_mask_parent(data); ++ irq_chip_mask_parent(data); + } + + static void uniphier_gpio_irq_unmask(struct irq_data *data) +@@ -194,7 +194,7 @@ static void uniphier_gpio_irq_unmask(struct irq_data *data) + + uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, mask); + +- return irq_chip_unmask_parent(data); ++ irq_chip_unmask_parent(data); + } + + static int uniphier_gpio_irq_set_type(struct irq_data *data, unsigned int type) +-- +2.33.0 + diff --git a/queue-5.14/gpiolib-acpi-make-set-debounce-timeout-failures-non-.patch b/queue-5.14/gpiolib-acpi-make-set-debounce-timeout-failures-non-.patch new file mode 100644 index 00000000000..01f4ef4991e --- /dev/null +++ b/queue-5.14/gpiolib-acpi-make-set-debounce-timeout-failures-non-.patch @@ -0,0 +1,68 @@ +From 89c5f75daa3cce1e1606458f30182b4aeca7b9fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Aug 2021 12:41:19 +0200 +Subject: gpiolib: acpi: Make set-debounce-timeout failures non fatal + +From: Hans de Goede + +[ Upstream commit cef0d022f55364d69017daeb9443bd31510ad6a2 ] + +Commit 8dcb7a15a585 ("gpiolib: acpi: Take into account debounce settings") +made the gpiolib-acpi code call gpio_set_debounce_timeout() when requesting +GPIOs. + +This in itself is fine, but it also made gpio_set_debounce_timeout() +errors fatal, causing the requesting of the GPIO to fail. This is causing +regressions. E.g. on a HP ElitePad 1000 G2 various _AEI specified GPIO +ACPI event sources specify a debouncy timeout of 20 ms, but the +pinctrl-baytrail.c only supports certain fixed values, the closest +ones being 12 or 24 ms and pinctrl-baytrail.c responds with -EINVAL +when specified a value which is not one of the fixed values. + +This is causing the acpi_request_own_gpiod() call to fail for 3 +ACPI event sources on the HP ElitePad 1000 G2, which in turn is causing +e.g. the battery charging vs discharging status to never get updated, +even though a charger has been plugged-in or unplugged. + +Make gpio_set_debounce_timeout() errors non fatal, warning about the +failure instead, to fix this regression. + +Note we should probably also fix various pinctrl drivers to just +pick the first bigger discrete value rather then returning -EINVAL but +this will need to be done on a per driver basis, where as this fix +at least gets us back to where things were before and thus restores +functionality on devices where this was lost due to +gpio_set_debounce_timeout() errors. + +Fixes: 8dcb7a15a585 ("gpiolib: acpi: Take into account debounce settings") +Depends-on: 2e2b496cebef ("gpiolib: acpi: Extract acpi_request_own_gpiod() helper") +Reviewed-by: Mika Westerberg +Signed-off-by: Hans de Goede +Acked-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpiolib-acpi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c +index 411525ac4cc4..47712b6903b5 100644 +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -313,9 +313,11 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, + + ret = gpio_set_debounce_timeout(desc, agpio->debounce_timeout); + if (ret) +- gpiochip_free_own_desc(desc); ++ dev_warn(chip->parent, ++ "Failed to set debounce-timeout for pin 0x%04X, err %d\n", ++ pin, ret); + +- return ret ? ERR_PTR(ret) : desc; ++ return desc; + } + + static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) +-- +2.33.0 + diff --git a/queue-5.14/igc-fix-build-errors-for-ptp.patch b/queue-5.14/igc-fix-build-errors-for-ptp.patch new file mode 100644 index 00000000000..dd4f8412be2 --- /dev/null +++ b/queue-5.14/igc-fix-build-errors-for-ptp.patch @@ -0,0 +1,68 @@ +From b0109b74618c35b48f2aed1d456a3141bba02ea3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 14:05:47 -0700 +Subject: igc: fix build errors for PTP + +From: Randy Dunlap + +[ Upstream commit 87758511075ec961486fe78d7548dd709b524433 ] + +When IGC=y and PTP_1588_CLOCK=m, the ptp_*() interface family is +not available to the igc driver. Make this driver depend on +PTP_1588_CLOCK_OPTIONAL so that it will build without errors. + +Various igc commits have used ptp_*() functions without checking +that PTP_1588_CLOCK is enabled. Fix all of these here. + +Fixes these build errors: + +ld: drivers/net/ethernet/intel/igc/igc_main.o: in function `igc_msix_other': +igc_main.c:(.text+0x6494): undefined reference to `ptp_clock_event' +ld: igc_main.c:(.text+0x64ef): undefined reference to `ptp_clock_event' +ld: igc_main.c:(.text+0x6559): undefined reference to `ptp_clock_event' +ld: drivers/net/ethernet/intel/igc/igc_ethtool.o: in function `igc_ethtool_get_ts_info': +igc_ethtool.c:(.text+0xc7a): undefined reference to `ptp_clock_index' +ld: drivers/net/ethernet/intel/igc/igc_ptp.o: in function `igc_ptp_feature_enable_i225': +igc_ptp.c:(.text+0x330): undefined reference to `ptp_find_pin' +ld: igc_ptp.c:(.text+0x36f): undefined reference to `ptp_find_pin' +ld: drivers/net/ethernet/intel/igc/igc_ptp.o: in function `igc_ptp_init': +igc_ptp.c:(.text+0x11cd): undefined reference to `ptp_clock_register' +ld: drivers/net/ethernet/intel/igc/igc_ptp.o: in function `igc_ptp_stop': +igc_ptp.c:(.text+0x12dd): undefined reference to `ptp_clock_unregister' +ld: drivers/platform/x86/dell/dell-wmi-privacy.o: in function `dell_privacy_wmi_probe': + +Fixes: 64433e5bf40ab ("igc: Enable internal i225 PPS") +Fixes: 60dbede0c4f3d ("igc: Add support for ethtool GET_TS_INFO command") +Fixes: 87938851b6efb ("igc: enable auxiliary PHC functions for the i225") +Fixes: 5f2958052c582 ("igc: Add basic skeleton for PTP") +Signed-off-by: Randy Dunlap +Cc: Ederson de Souza +Cc: Tony Nguyen +Cc: Vinicius Costa Gomes +Cc: Jeff Kirsher +Cc: "David S. Miller" +Cc: Jakub Kicinski +Cc: Jesse Brandeburg +Cc: intel-wired-lan@lists.osuosl.org +Acked-by: Vinicius Costa Gomes +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig +index 82744a7501c7..c11d974a62d8 100644 +--- a/drivers/net/ethernet/intel/Kconfig ++++ b/drivers/net/ethernet/intel/Kconfig +@@ -335,6 +335,7 @@ config IGC + tristate "Intel(R) Ethernet Controller I225-LM/I225-V support" + default n + depends on PCI ++ depends on PTP_1588_CLOCK_OPTIONAL + help + This driver supports Intel(R) Ethernet Controller I225-LM/I225-V + family of adapters. +-- +2.33.0 + diff --git a/queue-5.14/kselftest-arm64-signal-add-sve-to-the-set-of-feature.patch b/queue-5.14/kselftest-arm64-signal-add-sve-to-the-set-of-feature.patch new file mode 100644 index 00000000000..dc5e07be528 --- /dev/null +++ b/queue-5.14/kselftest-arm64-signal-add-sve-to-the-set-of-feature.patch @@ -0,0 +1,63 @@ +From fa72d24606bffc558979c61627352e16d3d95028 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Aug 2021 14:42:40 +0100 +Subject: kselftest/arm64: signal: Add SVE to the set of features we can check + for + +From: Mark Brown + +[ Upstream commit d4e4dc4fab686c5f3f185272a19b83930664bef5 ] + +Allow testcases for SVE signal handling to flag the dependency and be +skipped on systems without SVE support. + +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20210819134245.13935-2-broonie@kernel.org +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/arm64/signal/test_signals.h | 2 ++ + tools/testing/selftests/arm64/signal/test_signals_utils.c | 3 +++ + 2 files changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h +index f96baf1cef1a..ebe8694dbef0 100644 +--- a/tools/testing/selftests/arm64/signal/test_signals.h ++++ b/tools/testing/selftests/arm64/signal/test_signals.h +@@ -33,10 +33,12 @@ + */ + enum { + FSSBS_BIT, ++ FSVE_BIT, + FMAX_END + }; + + #define FEAT_SSBS (1UL << FSSBS_BIT) ++#define FEAT_SVE (1UL << FSVE_BIT) + + /* + * A descriptor used to describe and configure a test case. +diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c +index 2de6e5ed5e25..6836510a522f 100644 +--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c ++++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c +@@ -26,6 +26,7 @@ static int sig_copyctx = SIGTRAP; + + static char const *const feats_names[FMAX_END] = { + " SSBS ", ++ " SVE ", + }; + + #define MAX_FEATS_SZ 128 +@@ -263,6 +264,8 @@ int test_init(struct tdescr *td) + */ + if (getauxval(AT_HWCAP) & HWCAP_SSBS) + td->feats_supported |= FEAT_SSBS; ++ if (getauxval(AT_HWCAP) & HWCAP_SVE) ++ td->feats_supported |= FEAT_SVE; + if (feats_ok(td)) + fprintf(stderr, + "Required Features: [%s] supported\n", +-- +2.33.0 + diff --git a/queue-5.14/kselftest-arm64-signal-skip-tests-if-required-featur.patch b/queue-5.14/kselftest-arm64-signal-skip-tests-if-required-featur.patch new file mode 100644 index 00000000000..a6292cf595b --- /dev/null +++ b/queue-5.14/kselftest-arm64-signal-skip-tests-if-required-featur.patch @@ -0,0 +1,55 @@ +From d07d4e71c57304f12a160b5fca0f2885dddbb0a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Sep 2021 13:12:28 +0100 +Subject: kselftest/arm64: signal: Skip tests if required features are missing + +From: Cristian Marussi + +[ Upstream commit 0e3dbf765fe22060acbcb8eb8c4d256e655a1247 ] + +During initialization of a signal testcase, features declared as required +are properly checked against the running system but no action is then taken +to effectively skip such a testcase. + +Fix core signals test logic to abort initialization and report such a +testcase as skipped to the KSelfTest framework. + +Fixes: f96bf4340316 ("kselftest: arm64: mangle_pstate_invalid_compat_toggle and common utils") +Signed-off-by: Cristian Marussi +Reviewed-by: Mark Brown +Link: https://lore.kernel.org/r/20210920121228.35368-1-cristian.marussi@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/arm64/signal/test_signals_utils.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c +index 6836510a522f..22722abc9dfa 100644 +--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c ++++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c +@@ -266,16 +266,19 @@ int test_init(struct tdescr *td) + td->feats_supported |= FEAT_SSBS; + if (getauxval(AT_HWCAP) & HWCAP_SVE) + td->feats_supported |= FEAT_SVE; +- if (feats_ok(td)) ++ if (feats_ok(td)) { + fprintf(stderr, + "Required Features: [%s] supported\n", + feats_to_string(td->feats_required & + td->feats_supported)); +- else ++ } else { + fprintf(stderr, + "Required Features: [%s] NOT supported\n", + feats_to_string(td->feats_required & + ~td->feats_supported)); ++ td->result = KSFT_SKIP; ++ return 0; ++ } + } + + /* Perform test specific additional initialization */ +-- +2.33.0 + diff --git a/queue-5.14/mptcp-ensure-tx-skbs-always-have-the-mptcp-ext.patch b/queue-5.14/mptcp-ensure-tx-skbs-always-have-the-mptcp-ext.patch new file mode 100644 index 00000000000..cd36437f6aa --- /dev/null +++ b/queue-5.14/mptcp-ensure-tx-skbs-always-have-the-mptcp-ext.patch @@ -0,0 +1,103 @@ +From b887dc24abdb1f0c5c8503ecdc73472bb79bd3f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 13:12:17 +0200 +Subject: mptcp: ensure tx skbs always have the MPTCP ext + +From: Paolo Abeni + +[ Upstream commit 977d293e23b48a1129830d7968605f61c4af71a0 ] + +Due to signed/unsigned comparison, the expression: + + info->size_goal - skb->len > 0 + +evaluates to true when the size goal is smaller than the +skb size. That results in lack of tx cache refill, so that +the skb allocated by the core TCP code lacks the required +MPTCP skb extensions. + +Due to the above, syzbot is able to trigger the following WARN_ON(): + +WARNING: CPU: 1 PID: 810 at net/mptcp/protocol.c:1366 mptcp_sendmsg_frag+0x1362/0x1bc0 net/mptcp/protocol.c:1366 +Modules linked in: +CPU: 1 PID: 810 Comm: syz-executor.4 Not tainted 5.14.0-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +RIP: 0010:mptcp_sendmsg_frag+0x1362/0x1bc0 net/mptcp/protocol.c:1366 +Code: ff 4c 8b 74 24 50 48 8b 5c 24 58 e9 0f fb ff ff e8 13 44 8b f8 4c 89 e7 45 31 ed e8 98 57 2e fe e9 81 f4 ff ff e8 fe 43 8b f8 <0f> 0b 41 bd ea ff ff ff e9 6f f4 ff ff 4c 89 e7 e8 b9 8e d2 f8 e9 +RSP: 0018:ffffc9000531f6a0 EFLAGS: 00010216 +RAX: 000000000000697f RBX: 0000000000000000 RCX: ffffc90012107000 +RDX: 0000000000040000 RSI: ffffffff88eac9e2 RDI: 0000000000000003 +RBP: ffff888078b15780 R08: 0000000000000000 R09: 0000000000000000 +R10: ffffffff88eac017 R11: 0000000000000000 R12: ffff88801de0a280 +R13: 0000000000006b58 R14: ffff888066278280 R15: ffff88803c2fe9c0 +FS: 00007fd9f866e700(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007faebcb2f718 CR3: 00000000267cb000 CR4: 00000000001506e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + __mptcp_push_pending+0x1fb/0x6b0 net/mptcp/protocol.c:1547 + mptcp_release_cb+0xfe/0x210 net/mptcp/protocol.c:3003 + release_sock+0xb4/0x1b0 net/core/sock.c:3206 + sk_stream_wait_memory+0x604/0xed0 net/core/stream.c:145 + mptcp_sendmsg+0xc39/0x1bc0 net/mptcp/protocol.c:1749 + inet6_sendmsg+0x99/0xe0 net/ipv6/af_inet6.c:643 + sock_sendmsg_nosec net/socket.c:704 [inline] + sock_sendmsg+0xcf/0x120 net/socket.c:724 + sock_write_iter+0x2a0/0x3e0 net/socket.c:1057 + call_write_iter include/linux/fs.h:2163 [inline] + new_sync_write+0x40b/0x640 fs/read_write.c:507 + vfs_write+0x7cf/0xae0 fs/read_write.c:594 + ksys_write+0x1ee/0x250 fs/read_write.c:647 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae +RIP: 0033:0x4665f9 +Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 +RSP: 002b:00007fd9f866e188 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 +RAX: ffffffffffffffda RBX: 000000000056c038 RCX: 00000000004665f9 +RDX: 00000000000e7b78 RSI: 0000000020000000 RDI: 0000000000000003 +RBP: 00000000004bfcc4 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 000000000056c038 +R13: 0000000000a9fb1f R14: 00007fd9f866e300 R15: 0000000000022000 + +Fix the issue rewriting the relevant expression to avoid +sign-related problems - note: size_goal is always >= 0. + +Additionally, ensure that the skb in the tx cache always carries +the relevant extension. + +Reported-and-tested-by: syzbot+263a248eec3e875baa7b@syzkaller.appspotmail.com +Fixes: 1094c6fe7280 ("mptcp: fix possible divide by zero") +Signed-off-by: Paolo Abeni +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/mptcp/protocol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index acbead7cf50f..4d2abdd3cd3b 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1291,7 +1291,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, + goto alloc_skb; + } + +- must_collapse = (info->size_goal - skb->len > 0) && ++ must_collapse = (info->size_goal > skb->len) && + (skb_shinfo(skb)->nr_frags < sysctl_max_skb_frags); + if (must_collapse) { + size_bias = skb->len; +@@ -1300,7 +1300,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, + } + + alloc_skb: +- if (!must_collapse && !ssk->sk_tx_skb_cache && ++ if (!must_collapse && + !mptcp_alloc_tx_skb(sk, ssk, info->data_lock_held)) + return 0; + +-- +2.33.0 + diff --git a/queue-5.14/napi-fix-race-inside-napi_enable.patch b/queue-5.14/napi-fix-race-inside-napi_enable.patch new file mode 100644 index 00000000000..3c17934c5f5 --- /dev/null +++ b/queue-5.14/napi-fix-race-inside-napi_enable.patch @@ -0,0 +1,91 @@ +From e66cad414e6f11dd5921096760711ca2a37ed8c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Sep 2021 16:52:32 +0800 +Subject: napi: fix race inside napi_enable + +From: Xuan Zhuo + +[ Upstream commit 3765996e4f0b8a755cab215a08df744490c76052 ] + +The process will cause napi.state to contain NAPI_STATE_SCHED and +not in the poll_list, which will cause napi_disable() to get stuck. + +The prefix "NAPI_STATE_" is removed in the figure below, and +NAPI_STATE_HASHED is ignored in napi.state. + + CPU0 | CPU1 | napi.state +=============================================================================== +napi_disable() | | SCHED | NPSVC +napi_enable() | | +{ | | + smp_mb__before_atomic(); | | + clear_bit(SCHED, &n->state); | | NPSVC + | napi_schedule_prep() | SCHED | NPSVC + | napi_poll() | + | napi_complete_done() | + | { | + | if (n->state & (NPSVC | | (1) + | _BUSY_POLL))) | + | return false; | + | ................ | + | } | SCHED | NPSVC + | | + clear_bit(NPSVC, &n->state); | | SCHED +} | | + | | +napi_schedule_prep() | | SCHED | MISSED (2) + +(1) Here return direct. Because of NAPI_STATE_NPSVC exists. +(2) NAPI_STATE_SCHED exists. So not add napi.poll_list to sd->poll_list + +Since NAPI_STATE_SCHED already exists and napi is not in the +sd->poll_list queue, NAPI_STATE_SCHED cannot be cleared and will always +exist. + +1. This will cause this queue to no longer receive packets. +2. If you encounter napi_disable under the protection of rtnl_lock, it + will cause the entire rtnl_lock to be locked, affecting the overall + system. + +This patch uses cmpxchg to implement napi_enable(), which ensures that +there will be no race due to the separation of clear two bits. + +Fixes: 2d8bff12699abc ("netpoll: Close race condition between poll_one_napi and napi_disable") +Signed-off-by: Xuan Zhuo +Reviewed-by: Dust Li +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/dev.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/net/core/dev.c b/net/core/dev.c +index 8f1a47ad6781..693f15a05630 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6988,12 +6988,16 @@ EXPORT_SYMBOL(napi_disable); + */ + void napi_enable(struct napi_struct *n) + { +- BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); +- smp_mb__before_atomic(); +- clear_bit(NAPI_STATE_SCHED, &n->state); +- clear_bit(NAPI_STATE_NPSVC, &n->state); +- if (n->dev->threaded && n->thread) +- set_bit(NAPI_STATE_THREADED, &n->state); ++ unsigned long val, new; ++ ++ do { ++ val = READ_ONCE(n->state); ++ BUG_ON(!test_bit(NAPI_STATE_SCHED, &val)); ++ ++ new = val & ~(NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC); ++ if (n->dev->threaded && n->thread) ++ new |= NAPIF_STATE_THREADED; ++ } while (cmpxchg(&n->state, val, new) != val); + } + EXPORT_SYMBOL(napi_enable); + +-- +2.33.0 + diff --git a/queue-5.14/net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch b/queue-5.14/net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch new file mode 100644 index 00000000000..e06db0810a8 --- /dev/null +++ b/queue-5.14/net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch @@ -0,0 +1,51 @@ +From 234407902c72d0dbd894047ec73459057f0f2933 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Sep 2021 13:57:25 +0200 +Subject: net: bgmac-bcma: handle deferred probe error due to mac-address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian Lamparter + +[ Upstream commit 029497e66bdc762e001880e4c85a91f35a54b1e2 ] + +Due to the inclusion of nvmem handling into the mac-address getter +function of_get_mac_address() by +commit d01f449c008a ("of_net: add NVMEM support to of_get_mac_address") +it is now possible to get a -EPROBE_DEFER return code. Which did cause +bgmac to assign a random ethernet address. + +This exact issue happened on my Meraki MR32. The nvmem provider is +an EEPROM (at24c64) which gets instantiated once the module +driver is loaded... This happens once the filesystem becomes available. + +With this patch, bgmac_probe() will propagate the -EPROBE_DEFER error. +Then the driver subsystem will reschedule the probe at a later time. + +Cc: Petr Å tetiar +Cc: Michael Walle +Fixes: d01f449c008a ("of_net: add NVMEM support to of_get_mac_address") +Signed-off-by: Christian Lamparter +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bgmac-bcma.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma.c b/drivers/net/ethernet/broadcom/bgmac-bcma.c +index 85fa0ab7201c..9513cfb5ba58 100644 +--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c ++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c +@@ -129,6 +129,8 @@ static int bgmac_probe(struct bcma_device *core) + bcma_set_drvdata(core, bgmac); + + err = of_get_mac_address(bgmac->dev->of_node, bgmac->net_dev->dev_addr); ++ if (err == -EPROBE_DEFER) ++ return err; + + /* If no MAC address assigned via device tree, check SPROM */ + if (err) { +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-don-t-allocate-the-slave_mii_bus-using-devre.patch b/queue-5.14/net-dsa-don-t-allocate-the-slave_mii_bus-using-devre.patch new file mode 100644 index 00000000000..06f86969bb2 --- /dev/null +++ b/queue-5.14/net-dsa-don-t-allocate-the-slave_mii_bus-using-devre.patch @@ -0,0 +1,167 @@ +From 8dc2ef7557160c7d0c98e378c7ac9c2de6185f42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 00:42:08 +0300 +Subject: net: dsa: don't allocate the slave_mii_bus using devres + +From: Vladimir Oltean + +[ Upstream commit 5135e96a3dd2f4555ae6981c3155a62bcf3227f6 ] + +The Linux device model permits both the ->shutdown and ->remove driver +methods to get called during a shutdown procedure. Example: a DSA switch +which sits on an SPI bus, and the SPI bus driver calls this on its +->shutdown method: + +spi_unregister_controller +-> device_for_each_child(&ctlr->dev, NULL, __unregister); + -> spi_unregister_device(to_spi_device(dev)); + -> device_del(&spi->dev); + +So this is a simple pattern which can theoretically appear on any bus, +although the only other buses on which I've been able to find it are +I2C: + +i2c_del_adapter +-> device_for_each_child(&adap->dev, NULL, __unregister_client); + -> i2c_unregister_device(client); + -> device_unregister(&client->dev); + +The implication of this pattern is that devices on these buses can be +unregistered after having been shut down. The drivers for these devices +might choose to return early either from ->remove or ->shutdown if the +other callback has already run once, and they might choose that the +->shutdown method should only perform a subset of the teardown done by +->remove (to avoid unnecessary delays when rebooting). + +So in other words, the device driver may choose on ->remove to not +do anything (therefore to not unregister an MDIO bus it has registered +on ->probe), because this ->remove is actually triggered by the +device_shutdown path, and its ->shutdown method has already run and done +the minimally required cleanup. + +This used to be fine until the blamed commit, but now, the following +BUG_ON triggers: + +void mdiobus_free(struct mii_bus *bus) +{ + /* For compatibility with error handling in drivers. */ + if (bus->state == MDIOBUS_ALLOCATED) { + kfree(bus); + return; + } + + BUG_ON(bus->state != MDIOBUS_UNREGISTERED); + bus->state = MDIOBUS_RELEASED; + + put_device(&bus->dev); +} + +In other words, there is an attempt to free an MDIO bus which was not +unregistered. The attempt to free it comes from the devres release +callbacks of the SPI device, which are executed after the device is +unregistered. + +I'm not saying that the fact that MDIO buses allocated using devres +would automatically get unregistered wasn't strange. I'm just saying +that the commit didn't care about auditing existing call paths in the +kernel, and now, the following code sequences are potentially buggy: + +(a) devm_mdiobus_alloc followed by plain mdiobus_register, for a device + located on a bus that unregisters its children on shutdown. After + the blamed patch, either both the alloc and the register should use + devres, or none should. + +(b) devm_mdiobus_alloc followed by plain mdiobus_register, and then no + mdiobus_unregister at all in the remove path. After the blamed + patch, nobody unregisters the MDIO bus anymore, so this is even more + buggy than the previous case which needs a specific bus + configuration to be seen, this one is an unconditional bug. + +In this case, DSA falls into category (a), it tries to be helpful and +registers an MDIO bus on behalf of the switch, which might be on such a +bus. I've no idea why it does it under devres. + +It does this on probe: + + if (!ds->slave_mii_bus && ds->ops->phy_read) + alloc and register mdio bus + +and this on remove: + + if (ds->slave_mii_bus && ds->ops->phy_read) + unregister mdio bus + +I _could_ imagine using devres because the condition used on remove is +different than the condition used on probe. So strictly speaking, DSA +cannot determine whether the ds->slave_mii_bus it sees on remove is the +ds->slave_mii_bus that _it_ has allocated on probe. Using devres would +have solved that problem. But nonetheless, the existing code already +proceeds to unregister the MDIO bus, even though it might be +unregistering an MDIO bus it has never registered. So I can only guess +that no driver that implements ds->ops->phy_read also allocates and +registers ds->slave_mii_bus itself. + +So in that case, if unregistering is fine, freeing must be fine too. + +Stop using devres and free the MDIO bus manually. This will make devres +stop attempting to free a still registered MDIO bus on ->shutdown. + +Fixes: ac3a68d56651 ("net: phy: don't abuse devres in devm_mdiobus_register()") +Reported-by: Lino Sanfilippo +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Tested-by: Lino Sanfilippo +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/dsa/dsa2.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index 383fdc0565c7..76ed5ef0e36a 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -792,7 +792,7 @@ static int dsa_switch_setup(struct dsa_switch *ds) + devlink_params_publish(ds->devlink); + + if (!ds->slave_mii_bus && ds->ops->phy_read) { +- ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev); ++ ds->slave_mii_bus = mdiobus_alloc(); + if (!ds->slave_mii_bus) { + err = -ENOMEM; + goto teardown; +@@ -802,13 +802,16 @@ static int dsa_switch_setup(struct dsa_switch *ds) + + err = mdiobus_register(ds->slave_mii_bus); + if (err < 0) +- goto teardown; ++ goto free_slave_mii_bus; + } + + ds->setup = true; + + return 0; + ++free_slave_mii_bus: ++ if (ds->slave_mii_bus && ds->ops->phy_read) ++ mdiobus_free(ds->slave_mii_bus); + teardown: + if (ds->ops->teardown) + ds->ops->teardown(ds); +@@ -833,8 +836,11 @@ static void dsa_switch_teardown(struct dsa_switch *ds) + if (!ds->setup) + return; + +- if (ds->slave_mii_bus && ds->ops->phy_read) ++ if (ds->slave_mii_bus && ds->ops->phy_read) { + mdiobus_unregister(ds->slave_mii_bus); ++ mdiobus_free(ds->slave_mii_bus); ++ ds->slave_mii_bus = NULL; ++ } + + dsa_switch_unregister_notifier(ds); + +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-fix-dsa_tree_setup-error-path.patch b/queue-5.14/net-dsa-fix-dsa_tree_setup-error-path.patch new file mode 100644 index 00000000000..17f99c9ee4c --- /dev/null +++ b/queue-5.14/net-dsa-fix-dsa_tree_setup-error-path.patch @@ -0,0 +1,37 @@ +From 15517d2a4733450b46d8aa9e231a054ec409da14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 01:49:18 +0300 +Subject: net: dsa: fix dsa_tree_setup error path + +From: Vladimir Oltean + +[ Upstream commit e5845aa0eadda3d8a950eb8845c1396827131f30 ] + +Since the blamed commit, dsa_tree_teardown_switches() was split into two +smaller functions, dsa_tree_teardown_switches and dsa_tree_teardown_ports. + +However, the error path of dsa_tree_setup stopped calling dsa_tree_teardown_ports. + +Fixes: a57d8c217aad ("net: dsa: flush switchdev workqueue before tearing down CPU/DSA ports") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/dsa/dsa2.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index 3a8136d5915d..383fdc0565c7 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -1001,6 +1001,7 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst) + teardown_master: + dsa_tree_teardown_master(dst); + teardown_switches: ++ dsa_tree_teardown_ports(dst); + dsa_tree_teardown_switches(dst); + teardown_default_cpu: + dsa_tree_teardown_default_cpu(dst); +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-hellcreek-be-compatible-with-masters-which-u.patch b/queue-5.14/net-dsa-hellcreek-be-compatible-with-masters-which-u.patch new file mode 100644 index 00000000000..dfdbbf3da6e --- /dev/null +++ b/queue-5.14/net-dsa-hellcreek-be-compatible-with-masters-which-u.patch @@ -0,0 +1,83 @@ +From 5a8fa1511bcf9d6bcf04245ccdb61b4d788c0212 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 16:34:34 +0300 +Subject: net: dsa: hellcreek: be compatible with masters which unregister on + shutdown + +From: Vladimir Oltean + +[ Upstream commit 46baae56e1001a771a5d132aa883cb5605013ae2 ] + +Since commit 2f1e8ea726e9 ("net: dsa: link interfaces with the DSA +master to get rid of lockdep warnings"), DSA gained a requirement which +it did not fulfill, which is to unlink itself from the DSA master at +shutdown time. + +Since the hellcreek driver was introduced after the bad commit, it has +never worked with DSA masters which decide to unregister their +net_device on shutdown, effectively hanging the reboot process. + +Hellcreek is a platform device driver, so we probably cannot have the +oddities of ->shutdown and ->remove getting both called for the exact +same struct device. But to be in line with the pattern from the other +device drivers which are on slow buses, implement the same "if this then +not that" pattern of either running the ->shutdown or the ->remove hook. +The driver's current ->remove implementation makes that very easy +because it already zeroes out its device_drvdata on ->remove. + +Fixes: e4b27ebc780f ("net: dsa: Add DSA driver for Hirschmann Hellcreek switches") +Link: https://lore.kernel.org/netdev/20210909095324.12978-1-LinoSanfilippo@gmx.de/ +Reported-by: Lino Sanfilippo +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Acked-by: Kurt Kanzenbach +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/hirschmann/hellcreek.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c +index 7062db6a083c..a0f5ec4f4e58 100644 +--- a/drivers/net/dsa/hirschmann/hellcreek.c ++++ b/drivers/net/dsa/hirschmann/hellcreek.c +@@ -1915,6 +1915,9 @@ static int hellcreek_remove(struct platform_device *pdev) + { + struct hellcreek *hellcreek = platform_get_drvdata(pdev); + ++ if (!hellcreek) ++ return 0; ++ + hellcreek_hwtstamp_free(hellcreek); + hellcreek_ptp_free(hellcreek); + dsa_unregister_switch(hellcreek->ds); +@@ -1923,6 +1926,18 @@ static int hellcreek_remove(struct platform_device *pdev) + return 0; + } + ++static void hellcreek_shutdown(struct platform_device *pdev) ++{ ++ struct hellcreek *hellcreek = platform_get_drvdata(pdev); ++ ++ if (!hellcreek) ++ return; ++ ++ dsa_switch_shutdown(hellcreek->ds); ++ ++ platform_set_drvdata(pdev, NULL); ++} ++ + static const struct hellcreek_platform_data de1soc_r1_pdata = { + .name = "r4c30", + .num_ports = 4, +@@ -1945,6 +1960,7 @@ MODULE_DEVICE_TABLE(of, hellcreek_of_match); + static struct platform_driver hellcreek_driver = { + .probe = hellcreek_probe, + .remove = hellcreek_remove, ++ .shutdown = hellcreek_shutdown, + .driver = { + .name = "hellcreek", + .of_match_table = hellcreek_of_match, +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-microchip-ksz8863-be-compatible-with-masters.patch b/queue-5.14/net-dsa-microchip-ksz8863-be-compatible-with-masters.patch new file mode 100644 index 00000000000..ad48b19bff1 --- /dev/null +++ b/queue-5.14/net-dsa-microchip-ksz8863-be-compatible-with-masters.patch @@ -0,0 +1,72 @@ +From 0294db7d706b7950efb7b6c1cac14101d136710e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 16:34:35 +0300 +Subject: net: dsa: microchip: ksz8863: be compatible with masters which + unregister on shutdown + +From: Vladimir Oltean + +[ Upstream commit fe4053078cd0f02a3fa140c43660f327702a9f10 ] + +Since commit 2f1e8ea726e9 ("net: dsa: link interfaces with the DSA +master to get rid of lockdep warnings"), DSA gained a requirement which +it did not fulfill, which is to unlink itself from the DSA master at +shutdown time. + +Since the Microchip sub-driver for KSZ8863 was introduced after the bad +commit, it has never worked with DSA masters which decide to unregister +their net_device on shutdown, effectively hanging the reboot process. +To fix that, we need to call dsa_switch_shutdown. + +Since this driver expects the MDIO bus to be backed by mdio_bitbang, I +don't think there is currently any MDIO bus driver which implements its +->shutdown by redirecting it to ->remove, but in any case, to be +compatible with that pattern, it is necessary to implement an "if this +then not that" scheme, to avoid ->remove and ->shutdown from being +called both for the same struct device. + +Fixes: 60a364760002 ("net: dsa: microchip: Add Microchip KSZ8863 SMI based driver support") +Link: https://lore.kernel.org/netdev/20210909095324.12978-1-LinoSanfilippo@gmx.de/ +Reported-by: Lino Sanfilippo +Signed-off-by: Vladimir Oltean +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/microchip/ksz8863_smi.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/net/dsa/microchip/ksz8863_smi.c b/drivers/net/dsa/microchip/ksz8863_smi.c +index 11293485138c..5883fa7edda2 100644 +--- a/drivers/net/dsa/microchip/ksz8863_smi.c ++++ b/drivers/net/dsa/microchip/ksz8863_smi.c +@@ -191,6 +191,18 @@ static void ksz8863_smi_remove(struct mdio_device *mdiodev) + + if (dev) + ksz_switch_remove(dev); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++static void ksz8863_smi_shutdown(struct mdio_device *mdiodev) ++{ ++ struct ksz_device *dev = dev_get_drvdata(&mdiodev->dev); ++ ++ if (dev) ++ dsa_switch_shutdown(dev->ds); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); + } + + static const struct of_device_id ksz8863_dt_ids[] = { +@@ -203,6 +215,7 @@ MODULE_DEVICE_TABLE(of, ksz8863_dt_ids); + static struct mdio_driver ksz8863_driver = { + .probe = ksz8863_smi_probe, + .remove = ksz8863_smi_remove, ++ .shutdown = ksz8863_smi_shutdown, + .mdiodrv.driver = { + .name = "ksz8863-switch", + .of_match_table = ksz8863_dt_ids, +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-realtek-register-the-mdio-bus-under-devres.patch b/queue-5.14/net-dsa-realtek-register-the-mdio-bus-under-devres.patch new file mode 100644 index 00000000000..7a3af7e4fa5 --- /dev/null +++ b/queue-5.14/net-dsa-realtek-register-the-mdio-bus-under-devres.patch @@ -0,0 +1,113 @@ +From c11fb6081fa1b7e18811c46f8cdeb8d6028c0236 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 00:42:09 +0300 +Subject: net: dsa: realtek: register the MDIO bus under devres +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vladimir Oltean + +[ Upstream commit 74b6d7d13307b016f4b5bba8198297824c0ee6df ] + +The Linux device model permits both the ->shutdown and ->remove driver +methods to get called during a shutdown procedure. Example: a DSA switch +which sits on an SPI bus, and the SPI bus driver calls this on its +->shutdown method: + +spi_unregister_controller +-> device_for_each_child(&ctlr->dev, NULL, __unregister); + -> spi_unregister_device(to_spi_device(dev)); + -> device_del(&spi->dev); + +So this is a simple pattern which can theoretically appear on any bus, +although the only other buses on which I've been able to find it are +I2C: + +i2c_del_adapter +-> device_for_each_child(&adap->dev, NULL, __unregister_client); + -> i2c_unregister_device(client); + -> device_unregister(&client->dev); + +The implication of this pattern is that devices on these buses can be +unregistered after having been shut down. The drivers for these devices +might choose to return early either from ->remove or ->shutdown if the +other callback has already run once, and they might choose that the +->shutdown method should only perform a subset of the teardown done by +->remove (to avoid unnecessary delays when rebooting). + +So in other words, the device driver may choose on ->remove to not +do anything (therefore to not unregister an MDIO bus it has registered +on ->probe), because this ->remove is actually triggered by the +device_shutdown path, and its ->shutdown method has already run and done +the minimally required cleanup. + +This used to be fine until the blamed commit, but now, the following +BUG_ON triggers: + +void mdiobus_free(struct mii_bus *bus) +{ + /* For compatibility with error handling in drivers. */ + if (bus->state == MDIOBUS_ALLOCATED) { + kfree(bus); + return; + } + + BUG_ON(bus->state != MDIOBUS_UNREGISTERED); + bus->state = MDIOBUS_RELEASED; + + put_device(&bus->dev); +} + +In other words, there is an attempt to free an MDIO bus which was not +unregistered. The attempt to free it comes from the devres release +callbacks of the SPI device, which are executed after the device is +unregistered. + +I'm not saying that the fact that MDIO buses allocated using devres +would automatically get unregistered wasn't strange. I'm just saying +that the commit didn't care about auditing existing call paths in the +kernel, and now, the following code sequences are potentially buggy: + +(a) devm_mdiobus_alloc followed by plain mdiobus_register, for a device + located on a bus that unregisters its children on shutdown. After + the blamed patch, either both the alloc and the register should use + devres, or none should. + +(b) devm_mdiobus_alloc followed by plain mdiobus_register, and then no + mdiobus_unregister at all in the remove path. After the blamed + patch, nobody unregisters the MDIO bus anymore, so this is even more + buggy than the previous case which needs a specific bus + configuration to be seen, this one is an unconditional bug. + +In this case, the Realtek drivers fall under category (b). To solve it, +we can register the MDIO bus under devres too, which restores the +previous behavior. + +Fixes: ac3a68d56651 ("net: phy: don't abuse devres in devm_mdiobus_register()") +Reported-by: Lino Sanfilippo +Reported-by: Alvin Å ipraga +Signed-off-by: Vladimir Oltean +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/realtek-smi-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/realtek-smi-core.c b/drivers/net/dsa/realtek-smi-core.c +index 8e49d4f85d48..6bf46d76c028 100644 +--- a/drivers/net/dsa/realtek-smi-core.c ++++ b/drivers/net/dsa/realtek-smi-core.c +@@ -368,7 +368,7 @@ int realtek_smi_setup_mdio(struct realtek_smi *smi) + smi->slave_mii_bus->parent = smi->dev; + smi->ds->slave_mii_bus = smi->slave_mii_bus; + +- ret = of_mdiobus_register(smi->slave_mii_bus, mdio_np); ++ ret = devm_of_mdiobus_register(smi->dev, smi->slave_mii_bus, mdio_np); + if (ret) { + dev_err(smi->dev, "unable to register MDIO bus %s\n", + smi->slave_mii_bus->id); +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-tear-down-devlink-port-regions-when-tearing-.patch b/queue-5.14/net-dsa-tear-down-devlink-port-regions-when-tearing-.patch new file mode 100644 index 00000000000..c3af3c42592 --- /dev/null +++ b/queue-5.14/net-dsa-tear-down-devlink-port-regions-when-tearing-.patch @@ -0,0 +1,389 @@ +From dd7065123e80821cc872e0d816743672e97fb8e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 17:29:16 +0300 +Subject: net: dsa: tear down devlink port regions when tearing down the + devlink port on error + +From: Vladimir Oltean + +[ Upstream commit fd292c189a979838622d5e03e15fa688c81dd50b ] + +Commit 86f8b1c01a0a ("net: dsa: Do not make user port errors fatal") +decided it was fine to ignore errors on certain ports that fail to +probe, and go on with the ports that do probe fine. + +Commit fb6ec87f7229 ("net: dsa: Fix type was not set for devlink port") +noticed that devlink_port_type_eth_set(dlp, dp->slave); does not get +called, and devlink notices after a timeout of 3600 seconds and prints a +WARN_ON. So it went ahead to unregister the devlink port. And because +there exists an UNUSED port flavour, we actually re-register the devlink +port as UNUSED. + +Commit 08156ba430b4 ("net: dsa: Add devlink port regions support to +DSA") added devlink port regions, which are set up by the driver and not +by DSA. + +When we trigger the devlink port deregistration and reregistration as +unused, devlink now prints another WARN_ON, from here: + +devlink_port_unregister: + WARN_ON(!list_empty(&devlink_port->region_list)); + +So the port still has regions, which makes sense, because they were set +up by the driver, and the driver doesn't know we're unregistering the +devlink port. + +Somebody needs to tear them down, and optionally (actually it would be +nice, to be consistent) set them up again for the new devlink port. + +But DSA's layering stays in our way quite badly here. + +The options I've considered are: + +1. Introduce a function in devlink to just change a port's type and + flavour. No dice, devlink keeps a lot of state, it really wants the + port to not be registered when you set its parameters, so changing + anything can only be done by destroying what we currently have and + recreating it. + +2. Make DSA cache the parameters passed to dsa_devlink_port_region_create, + and the region returned, keep those in a list, then when the devlink + port unregister needs to take place, the existing devlink regions are + destroyed by DSA, and we replay the creation of new regions using the + cached parameters. Problem: mv88e6xxx keeps the region pointers in + chip->ports[port].region, and these will remain stale after DSA frees + them. There are many things DSA can do, but updating mv88e6xxx's + private pointers is not one of them. + +3. Just let the driver do it (i.e. introduce a very specific method + called ds->ops->port_reinit_as_unused, which unregisters its devlink + port devlink regions, then the old devlink port, then registers the + new one, then the devlink port regions for it). While it does work, + as opposed to the others, it's pretty horrible from an API + perspective and we can do better. + +4. Introduce a new pair of methods, ->port_setup and ->port_teardown, + which in the case of mv88e6xxx must register and unregister the + devlink port regions. Call these 2 methods when the port must be + reinitialized as unused. + +Naturally, I went for the 4th approach. + +Fixes: 08156ba430b4 ("net: dsa: Add devlink port regions support to DSA") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++- + drivers/net/dsa/mv88e6xxx/devlink.c | 73 ++++------------------------- + drivers/net/dsa/mv88e6xxx/devlink.h | 6 ++- + include/net/dsa.h | 8 ++++ + net/dsa/dsa2.c | 51 ++++++++++++++++++-- + 5 files changed, 81 insertions(+), 73 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 111a6d5985da..1c122a1f2f97 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -3012,7 +3012,7 @@ static void mv88e6xxx_teardown(struct dsa_switch *ds) + { + mv88e6xxx_teardown_devlink_params(ds); + dsa_devlink_resources_unregister(ds); +- mv88e6xxx_teardown_devlink_regions(ds); ++ mv88e6xxx_teardown_devlink_regions_global(ds); + } + + static int mv88e6xxx_setup(struct dsa_switch *ds) +@@ -3147,7 +3147,7 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) + if (err) + goto out_resources; + +- err = mv88e6xxx_setup_devlink_regions(ds); ++ err = mv88e6xxx_setup_devlink_regions_global(ds); + if (err) + goto out_params; + +@@ -3161,6 +3161,16 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) + return err; + } + ++static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port) ++{ ++ return mv88e6xxx_setup_devlink_regions_port(ds, port); ++} ++ ++static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port) ++{ ++ mv88e6xxx_teardown_devlink_regions_port(ds, port); ++} ++ + /* prod_id for switch families which do not have a PHY model number */ + static const u16 family_prod_id_table[] = { + [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, +@@ -6055,6 +6065,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = { + .change_tag_protocol = mv88e6xxx_change_tag_protocol, + .setup = mv88e6xxx_setup, + .teardown = mv88e6xxx_teardown, ++ .port_setup = mv88e6xxx_port_setup, ++ .port_teardown = mv88e6xxx_port_teardown, + .phylink_validate = mv88e6xxx_validate, + .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state, + .phylink_mac_config = mv88e6xxx_mac_config, +diff --git a/drivers/net/dsa/mv88e6xxx/devlink.c b/drivers/net/dsa/mv88e6xxx/devlink.c +index 0c0f5ea6680c..381068395c63 100644 +--- a/drivers/net/dsa/mv88e6xxx/devlink.c ++++ b/drivers/net/dsa/mv88e6xxx/devlink.c +@@ -647,26 +647,25 @@ static struct mv88e6xxx_region mv88e6xxx_regions[] = { + }, + }; + +-static void +-mv88e6xxx_teardown_devlink_regions_global(struct mv88e6xxx_chip *chip) ++void mv88e6xxx_teardown_devlink_regions_global(struct dsa_switch *ds) + { ++ struct mv88e6xxx_chip *chip = ds->priv; + int i; + + for (i = 0; i < ARRAY_SIZE(mv88e6xxx_regions); i++) + dsa_devlink_region_destroy(chip->regions[i]); + } + +-static void +-mv88e6xxx_teardown_devlink_regions_port(struct mv88e6xxx_chip *chip, +- int port) ++void mv88e6xxx_teardown_devlink_regions_port(struct dsa_switch *ds, int port) + { ++ struct mv88e6xxx_chip *chip = ds->priv; ++ + dsa_devlink_region_destroy(chip->ports[port].region); + } + +-static int mv88e6xxx_setup_devlink_regions_port(struct dsa_switch *ds, +- struct mv88e6xxx_chip *chip, +- int port) ++int mv88e6xxx_setup_devlink_regions_port(struct dsa_switch *ds, int port) + { ++ struct mv88e6xxx_chip *chip = ds->priv; + struct devlink_region *region; + + region = dsa_devlink_port_region_create(ds, +@@ -681,40 +680,10 @@ static int mv88e6xxx_setup_devlink_regions_port(struct dsa_switch *ds, + return 0; + } + +-static void +-mv88e6xxx_teardown_devlink_regions_ports(struct mv88e6xxx_chip *chip) +-{ +- int port; +- +- for (port = 0; port < mv88e6xxx_num_ports(chip); port++) +- mv88e6xxx_teardown_devlink_regions_port(chip, port); +-} +- +-static int mv88e6xxx_setup_devlink_regions_ports(struct dsa_switch *ds, +- struct mv88e6xxx_chip *chip) +-{ +- int port; +- int err; +- +- for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { +- err = mv88e6xxx_setup_devlink_regions_port(ds, chip, port); +- if (err) +- goto out; +- } +- +- return 0; +- +-out: +- while (port-- > 0) +- mv88e6xxx_teardown_devlink_regions_port(chip, port); +- +- return err; +-} +- +-static int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds, +- struct mv88e6xxx_chip *chip) ++int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds) + { + bool (*cond)(struct mv88e6xxx_chip *chip); ++ struct mv88e6xxx_chip *chip = ds->priv; + struct devlink_region_ops *ops; + struct devlink_region *region; + u64 size; +@@ -753,30 +722,6 @@ static int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds, + return PTR_ERR(region); + } + +-int mv88e6xxx_setup_devlink_regions(struct dsa_switch *ds) +-{ +- struct mv88e6xxx_chip *chip = ds->priv; +- int err; +- +- err = mv88e6xxx_setup_devlink_regions_global(ds, chip); +- if (err) +- return err; +- +- err = mv88e6xxx_setup_devlink_regions_ports(ds, chip); +- if (err) +- mv88e6xxx_teardown_devlink_regions_global(chip); +- +- return err; +-} +- +-void mv88e6xxx_teardown_devlink_regions(struct dsa_switch *ds) +-{ +- struct mv88e6xxx_chip *chip = ds->priv; +- +- mv88e6xxx_teardown_devlink_regions_ports(chip); +- mv88e6xxx_teardown_devlink_regions_global(chip); +-} +- + int mv88e6xxx_devlink_info_get(struct dsa_switch *ds, + struct devlink_info_req *req, + struct netlink_ext_ack *extack) +diff --git a/drivers/net/dsa/mv88e6xxx/devlink.h b/drivers/net/dsa/mv88e6xxx/devlink.h +index 3d72db3dcf95..65ce6a6858b9 100644 +--- a/drivers/net/dsa/mv88e6xxx/devlink.h ++++ b/drivers/net/dsa/mv88e6xxx/devlink.h +@@ -12,8 +12,10 @@ int mv88e6xxx_devlink_param_get(struct dsa_switch *ds, u32 id, + struct devlink_param_gset_ctx *ctx); + int mv88e6xxx_devlink_param_set(struct dsa_switch *ds, u32 id, + struct devlink_param_gset_ctx *ctx); +-int mv88e6xxx_setup_devlink_regions(struct dsa_switch *ds); +-void mv88e6xxx_teardown_devlink_regions(struct dsa_switch *ds); ++int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds); ++void mv88e6xxx_teardown_devlink_regions_global(struct dsa_switch *ds); ++int mv88e6xxx_setup_devlink_regions_port(struct dsa_switch *ds, int port); ++void mv88e6xxx_teardown_devlink_regions_port(struct dsa_switch *ds, int port); + + int mv88e6xxx_devlink_info_get(struct dsa_switch *ds, + struct devlink_info_req *req, +diff --git a/include/net/dsa.h b/include/net/dsa.h +index d833f717e802..004514a21e30 100644 +--- a/include/net/dsa.h ++++ b/include/net/dsa.h +@@ -575,8 +575,16 @@ struct dsa_switch_ops { + int (*change_tag_protocol)(struct dsa_switch *ds, int port, + enum dsa_tag_protocol proto); + ++ /* Optional switch-wide initialization and destruction methods */ + int (*setup)(struct dsa_switch *ds); + void (*teardown)(struct dsa_switch *ds); ++ ++ /* Per-port initialization and destruction methods. Mandatory if the ++ * driver registers devlink port regions, optional otherwise. ++ */ ++ int (*port_setup)(struct dsa_switch *ds, int port); ++ void (*port_teardown)(struct dsa_switch *ds, int port); ++ + u32 (*get_phy_flags)(struct dsa_switch *ds, int port); + + /* +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index 79267b00af68..3a8136d5915d 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -342,6 +342,7 @@ static int dsa_port_setup(struct dsa_port *dp) + { + struct devlink_port *dlp = &dp->devlink_port; + bool dsa_port_link_registered = false; ++ struct dsa_switch *ds = dp->ds; + bool dsa_port_enabled = false; + int err = 0; + +@@ -351,6 +352,12 @@ static int dsa_port_setup(struct dsa_port *dp) + INIT_LIST_HEAD(&dp->fdbs); + INIT_LIST_HEAD(&dp->mdbs); + ++ if (ds->ops->port_setup) { ++ err = ds->ops->port_setup(ds, dp->index); ++ if (err) ++ return err; ++ } ++ + switch (dp->type) { + case DSA_PORT_TYPE_UNUSED: + dsa_port_disable(dp); +@@ -393,8 +400,11 @@ static int dsa_port_setup(struct dsa_port *dp) + dsa_port_disable(dp); + if (err && dsa_port_link_registered) + dsa_port_link_unregister_of(dp); +- if (err) ++ if (err) { ++ if (ds->ops->port_teardown) ++ ds->ops->port_teardown(ds, dp->index); + return err; ++ } + + dp->setup = true; + +@@ -446,11 +456,15 @@ static int dsa_port_devlink_setup(struct dsa_port *dp) + static void dsa_port_teardown(struct dsa_port *dp) + { + struct devlink_port *dlp = &dp->devlink_port; ++ struct dsa_switch *ds = dp->ds; + struct dsa_mac_addr *a, *tmp; + + if (!dp->setup) + return; + ++ if (ds->ops->port_teardown) ++ ds->ops->port_teardown(ds, dp->index); ++ + devlink_port_type_clear(dlp); + + switch (dp->type) { +@@ -494,6 +508,36 @@ static void dsa_port_devlink_teardown(struct dsa_port *dp) + dp->devlink_port_setup = false; + } + ++/* Destroy the current devlink port, and create a new one which has the UNUSED ++ * flavour. At this point, any call to ds->ops->port_setup has been already ++ * balanced out by a call to ds->ops->port_teardown, so we know that any ++ * devlink port regions the driver had are now unregistered. We then call its ++ * ds->ops->port_setup again, in order for the driver to re-create them on the ++ * new devlink port. ++ */ ++static int dsa_port_reinit_as_unused(struct dsa_port *dp) ++{ ++ struct dsa_switch *ds = dp->ds; ++ int err; ++ ++ dsa_port_devlink_teardown(dp); ++ dp->type = DSA_PORT_TYPE_UNUSED; ++ err = dsa_port_devlink_setup(dp); ++ if (err) ++ return err; ++ ++ if (ds->ops->port_setup) { ++ /* On error, leave the devlink port registered, ++ * dsa_switch_teardown will clean it up later. ++ */ ++ err = ds->ops->port_setup(ds, dp->index); ++ if (err) ++ return err; ++ } ++ ++ return 0; ++} ++ + static int dsa_devlink_info_get(struct devlink *dl, + struct devlink_info_req *req, + struct netlink_ext_ack *extack) +@@ -850,12 +894,9 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) + list_for_each_entry(dp, &dst->ports, list) { + err = dsa_port_setup(dp); + if (err) { +- dsa_port_devlink_teardown(dp); +- dp->type = DSA_PORT_TYPE_UNUSED; +- err = dsa_port_devlink_setup(dp); ++ err = dsa_port_reinit_as_unused(dp); + if (err) + goto teardown; +- continue; + } + } + +-- +2.33.0 + diff --git a/queue-5.14/net-dsa-xrs700x-be-compatible-with-masters-which-unr.patch b/queue-5.14/net-dsa-xrs700x-be-compatible-with-masters-which-unr.patch new file mode 100644 index 00000000000..12baa550b78 --- /dev/null +++ b/queue-5.14/net-dsa-xrs700x-be-compatible-with-masters-which-unr.patch @@ -0,0 +1,149 @@ +From 3b03f95218d1b0ccc14ca23a3093196e712fa91d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 16:34:36 +0300 +Subject: net: dsa: xrs700x: be compatible with masters which unregister on + shutdown + +From: Vladimir Oltean + +[ Upstream commit a68e9da48568a0adf5dc817ef81971c0d1aa0672 ] + +Since commit 2f1e8ea726e9 ("net: dsa: link interfaces with the DSA +master to get rid of lockdep warnings"), DSA gained a requirement which +it did not fulfill, which is to unlink itself from the DSA master at +shutdown time. + +Since the Arrow SpeedChips XRS700x driver was introduced after the bad +commit, it has never worked with DSA masters which decide to unregister +their net_device on shutdown, effectively hanging the reboot process. +To fix that, we need to call dsa_switch_shutdown. + +These devices can be connected by I2C or by MDIO, and if I search for +I2C or MDIO bus drivers that implement their ->shutdown by redirecting +it to ->remove I don't see any, however this does not mean it would not +be possible. To be compatible with that pattern, it is necessary to +implement an "if this then not that" scheme, to avoid ->remove and +->shutdown from being called both for the same struct device. + +Fixes: ee00b24f32eb ("net: dsa: add Arrow SpeedChips XRS700x driver") +Link: https://lore.kernel.org/netdev/20210909095324.12978-1-LinoSanfilippo@gmx.de/ +Reported-by: Lino Sanfilippo +Signed-off-by: Vladimir Oltean +Reviewed-by: George McCollister +Reviewed-by: Florian Fainelli +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/xrs700x/xrs700x.c | 6 ++++++ + drivers/net/dsa/xrs700x/xrs700x.h | 1 + + drivers/net/dsa/xrs700x/xrs700x_i2c.c | 18 ++++++++++++++++++ + drivers/net/dsa/xrs700x/xrs700x_mdio.c | 18 ++++++++++++++++++ + 4 files changed, 43 insertions(+) + +diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c +index 130abb0f1438..469420941054 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x.c ++++ b/drivers/net/dsa/xrs700x/xrs700x.c +@@ -822,6 +822,12 @@ void xrs700x_switch_remove(struct xrs700x *priv) + } + EXPORT_SYMBOL(xrs700x_switch_remove); + ++void xrs700x_switch_shutdown(struct xrs700x *priv) ++{ ++ dsa_switch_shutdown(priv->ds); ++} ++EXPORT_SYMBOL(xrs700x_switch_shutdown); ++ + MODULE_AUTHOR("George McCollister "); + MODULE_DESCRIPTION("Arrow SpeedChips XRS700x DSA driver"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/net/dsa/xrs700x/xrs700x.h b/drivers/net/dsa/xrs700x/xrs700x.h +index ff62cf61b091..4d58257471d2 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x.h ++++ b/drivers/net/dsa/xrs700x/xrs700x.h +@@ -40,3 +40,4 @@ struct xrs700x { + struct xrs700x *xrs700x_switch_alloc(struct device *base, void *devpriv); + int xrs700x_switch_register(struct xrs700x *priv); + void xrs700x_switch_remove(struct xrs700x *priv); ++void xrs700x_switch_shutdown(struct xrs700x *priv); +diff --git a/drivers/net/dsa/xrs700x/xrs700x_i2c.c b/drivers/net/dsa/xrs700x/xrs700x_i2c.c +index 489d9385b4f0..6deae388a0d6 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x_i2c.c ++++ b/drivers/net/dsa/xrs700x/xrs700x_i2c.c +@@ -109,11 +109,28 @@ static int xrs700x_i2c_remove(struct i2c_client *i2c) + { + struct xrs700x *priv = i2c_get_clientdata(i2c); + ++ if (!priv) ++ return 0; ++ + xrs700x_switch_remove(priv); + ++ i2c_set_clientdata(i2c, NULL); ++ + return 0; + } + ++static void xrs700x_i2c_shutdown(struct i2c_client *i2c) ++{ ++ struct xrs700x *priv = i2c_get_clientdata(i2c); ++ ++ if (!priv) ++ return; ++ ++ xrs700x_switch_shutdown(priv); ++ ++ i2c_set_clientdata(i2c, NULL); ++} ++ + static const struct i2c_device_id xrs700x_i2c_id[] = { + { "xrs700x-switch", 0 }, + {}, +@@ -137,6 +154,7 @@ static struct i2c_driver xrs700x_i2c_driver = { + }, + .probe = xrs700x_i2c_probe, + .remove = xrs700x_i2c_remove, ++ .shutdown = xrs700x_i2c_shutdown, + .id_table = xrs700x_i2c_id, + }; + +diff --git a/drivers/net/dsa/xrs700x/xrs700x_mdio.c b/drivers/net/dsa/xrs700x/xrs700x_mdio.c +index 44f58bee04a4..d01cf1073d49 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x_mdio.c ++++ b/drivers/net/dsa/xrs700x/xrs700x_mdio.c +@@ -136,7 +136,24 @@ static void xrs700x_mdio_remove(struct mdio_device *mdiodev) + { + struct xrs700x *priv = dev_get_drvdata(&mdiodev->dev); + ++ if (!priv) ++ return; ++ + xrs700x_switch_remove(priv); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); ++} ++ ++static void xrs700x_mdio_shutdown(struct mdio_device *mdiodev) ++{ ++ struct xrs700x *priv = dev_get_drvdata(&mdiodev->dev); ++ ++ if (!priv) ++ return; ++ ++ xrs700x_switch_shutdown(priv); ++ ++ dev_set_drvdata(&mdiodev->dev, NULL); + } + + static const struct of_device_id __maybe_unused xrs700x_mdio_dt_ids[] = { +@@ -155,6 +172,7 @@ static struct mdio_driver xrs700x_mdio_driver = { + }, + .probe = xrs700x_mdio_probe, + .remove = xrs700x_mdio_remove, ++ .shutdown = xrs700x_mdio_shutdown, + }; + + mdio_module_driver(xrs700x_mdio_driver); +-- +2.33.0 + diff --git a/queue-5.14/net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch b/queue-5.14/net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch new file mode 100644 index 00000000000..eddfb16725e --- /dev/null +++ b/queue-5.14/net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch @@ -0,0 +1,40 @@ +From bef8eaa6c23d53872ae76a333d7ac4d869ac9bbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 16:55:48 -0700 +Subject: net: ethernet: mtk_eth_soc: avoid creating duplicate offload entries + +From: Felix Fietkau + +[ Upstream commit e68daf61ed13832aef8892200a874139700ca754 ] + +Sometimes multiple CLS_REPLACE calls are issued for the same connection. +rhashtable_insert_fast does not check for these duplicates, so multiple +hardware flow entries can be created. +Fix this by checking for an existing entry early + +Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support") +Signed-off-by: Felix Fietkau +Signed-off-by: Ilya Lipnitskiy +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +index b5f68f66d42a..7bb1f20002b5 100644 +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -186,6 +186,9 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) + int hash; + int i; + ++ if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params)) ++ return -EEXIST; ++ + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) { + struct flow_match_meta match; + +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-check-queue-id-range-before-using.patch b/queue-5.14/net-hns3-check-queue-id-range-before-using.patch new file mode 100644 index 00000000000..e90420470d1 --- /dev/null +++ b/queue-5.14/net-hns3-check-queue-id-range-before-using.patch @@ -0,0 +1,47 @@ +From 25a6211d4eaa481dbd7db76ddd2175150d05227f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:09 +0800 +Subject: net: hns3: check queue id range before using + +From: Yufeng Mo + +[ Upstream commit 63b1279d9905100a14da9e043de7b28e99dba3f8 ] + +The input parameters may not be reliable. Before using the +queue id, we should check this parameter. Otherwise, memory +overwriting may occur. + +Fixes: d34100184685 ("net: hns3: refactor the mailbox message between PF and VF") +Signed-off-by: Yufeng Mo +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index 91c32f99b644..c1a4b79a7050 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -588,9 +588,17 @@ static void hclge_get_queue_id_in_pf(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + struct hclge_respond_to_vf_msg *resp_msg) + { ++ struct hnae3_handle *handle = &vport->nic; ++ struct hclge_dev *hdev = vport->back; + u16 queue_id, qid_in_pf; + + memcpy(&queue_id, mbx_req->msg.data, sizeof(queue_id)); ++ if (queue_id >= handle->kinfo.num_tqps) { ++ dev_err(&hdev->pdev->dev, "Invalid queue id(%u) from VF %u\n", ++ queue_id, mbx_req->mbx_src_vfid); ++ return; ++ } ++ + qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); + memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf)); + resp_msg->len = sizeof(qid_in_pf); +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-check-vlan-id-before-using-it.patch b/queue-5.14/net-hns3-check-vlan-id-before-using-it.patch new file mode 100644 index 00000000000..893549bf696 --- /dev/null +++ b/queue-5.14/net-hns3-check-vlan-id-before-using-it.patch @@ -0,0 +1,38 @@ +From 4e35c958f4a595b20943b5c91ac6f4e38cec0821 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:10 +0800 +Subject: net: hns3: check vlan id before using it + +From: liaoguojia + +[ Upstream commit ef39d632608e66f428c1246836fd060cf4818d67 ] + +The input parameters may not be reliable, so check the vlan id before +using it, otherwise may set wrong vlan id into hardware. + +Fixes: dc8131d846d4 ("net: hns3: Fix for packet loss due wrong filter config in VLAN tbls") +Signed-off-by: liaoguojia +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 3f8d56ccc057..556dfc854763 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -9810,6 +9810,9 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto, + if (is_kill && !vlan_id) + return 0; + ++ if (vlan_id >= VLAN_N_VID) ++ return -EINVAL; ++ + ret = hclge_set_vf_vlan_common(hdev, vport_id, is_kill, vlan_id); + if (ret) { + dev_err(&hdev->pdev->dev, +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-fix-a-return-value-error-in-hclge_get_reset.patch b/queue-5.14/net-hns3-fix-a-return-value-error-in-hclge_get_reset.patch new file mode 100644 index 00000000000..8aa98261a04 --- /dev/null +++ b/queue-5.14/net-hns3-fix-a-return-value-error-in-hclge_get_reset.patch @@ -0,0 +1,73 @@ +From cf5a0e4a2133675e944d0bc5a78a0c7a040a636d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:11 +0800 +Subject: net: hns3: fix a return value error in hclge_get_reset_status() + +From: Yufeng Mo + +[ Upstream commit 5126b9d3d4acdebc12b9d436282f88d8a1b5146c ] + +hclge_get_reset_status() should return the tqp reset status. +However, if the CMDQ fails, the caller will take it as tqp reset +success status by mistake. Therefore, uses a parameters to get +the tqp reset status instead. + +Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") +Signed-off-by: Yufeng Mo +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 556dfc854763..90a72c79fec9 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -10719,7 +10719,8 @@ static int hclge_reset_tqp_cmd_send(struct hclge_dev *hdev, u16 queue_id, + return 0; + } + +-static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id) ++static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id, ++ u8 *reset_status) + { + struct hclge_reset_tqp_queue_cmd *req; + struct hclge_desc desc; +@@ -10737,7 +10738,9 @@ static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id) + return ret; + } + +- return hnae3_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B); ++ *reset_status = hnae3_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B); ++ ++ return 0; + } + + u16 hclge_covert_handle_qid_global(struct hnae3_handle *handle, u16 queue_id) +@@ -10756,7 +10759,7 @@ static int hclge_reset_tqp_cmd(struct hnae3_handle *handle) + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + u16 reset_try_times = 0; +- int reset_status; ++ u8 reset_status; + u16 queue_gid; + int ret; + u16 i; +@@ -10772,7 +10775,11 @@ static int hclge_reset_tqp_cmd(struct hnae3_handle *handle) + } + + while (reset_try_times++ < HCLGE_TQP_RESET_TRY_TIMES) { +- reset_status = hclge_get_reset_status(hdev, queue_gid); ++ ret = hclge_get_reset_status(hdev, queue_gid, ++ &reset_status); ++ if (ret) ++ return ret; ++ + if (reset_status) + break; + +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-fix-change-rss-hfunc-ineffective-issue.patch b/queue-5.14/net-hns3-fix-change-rss-hfunc-ineffective-issue.patch new file mode 100644 index 00000000000..527d26020d6 --- /dev/null +++ b/queue-5.14/net-hns3-fix-change-rss-hfunc-ineffective-issue.patch @@ -0,0 +1,178 @@ +From 2b5f201a21f75fdc152651e60d6cb977a0a2a704 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:06 +0800 +Subject: net: hns3: fix change RSS 'hfunc' ineffective issue + +From: Jian Shen + +[ Upstream commit e184cec5e29d8eb3c3435b12a9074b75e2d69e4a ] + +When user change rss 'hfunc' without set rss 'hkey' by ethtool +-X command, the driver will ignore the 'hfunc' for the hkey is +NULL. It's unreasonable. So fix it. + +Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") +Fixes: 374ad291762a ("net: hns3: Add RSS general configuration support for VF") +Signed-off-by: Jian Shen +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../hisilicon/hns3/hns3pf/hclge_main.c | 45 ++++++++++------ + .../hisilicon/hns3/hns3vf/hclgevf_main.c | 52 ++++++++++++------- + 2 files changed, 64 insertions(+), 33 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 72d55c028ac4..40c4949eed4d 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -4734,6 +4734,24 @@ static int hclge_get_rss(struct hnae3_handle *handle, u32 *indir, + return 0; + } + ++static int hclge_parse_rss_hfunc(struct hclge_vport *vport, const u8 hfunc, ++ u8 *hash_algo) ++{ ++ switch (hfunc) { ++ case ETH_RSS_HASH_TOP: ++ *hash_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ; ++ return 0; ++ case ETH_RSS_HASH_XOR: ++ *hash_algo = HCLGE_RSS_HASH_ALGO_SIMPLE; ++ return 0; ++ case ETH_RSS_HASH_NO_CHANGE: ++ *hash_algo = vport->rss_algo; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ + static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir, + const u8 *key, const u8 hfunc) + { +@@ -4743,30 +4761,27 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir, + u8 hash_algo; + int ret, i; + ++ ret = hclge_parse_rss_hfunc(vport, hfunc, &hash_algo); ++ if (ret) { ++ dev_err(&hdev->pdev->dev, "invalid hfunc type %u\n", hfunc); ++ return ret; ++ } ++ + /* Set the RSS Hash Key if specififed by the user */ + if (key) { +- switch (hfunc) { +- case ETH_RSS_HASH_TOP: +- hash_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ; +- break; +- case ETH_RSS_HASH_XOR: +- hash_algo = HCLGE_RSS_HASH_ALGO_SIMPLE; +- break; +- case ETH_RSS_HASH_NO_CHANGE: +- hash_algo = vport->rss_algo; +- break; +- default: +- return -EINVAL; +- } +- + ret = hclge_set_rss_algo_key(hdev, hash_algo, key); + if (ret) + return ret; + + /* Update the shadow RSS key with user specified qids */ + memcpy(vport->rss_hash_key, key, HCLGE_RSS_KEY_SIZE); +- vport->rss_algo = hash_algo; ++ } else { ++ ret = hclge_set_rss_algo_key(hdev, hash_algo, ++ vport->rss_hash_key); ++ if (ret) ++ return ret; + } ++ vport->rss_algo = hash_algo; + + /* Update the shadow RSS table with user specified qids */ + for (i = 0; i < ae_dev->dev_specs.rss_ind_tbl_size; i++) +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +index be3ea7023ed8..22cf66004dfa 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -814,40 +814,56 @@ static int hclgevf_get_rss(struct hnae3_handle *handle, u32 *indir, u8 *key, + return 0; + } + ++static int hclgevf_parse_rss_hfunc(struct hclgevf_dev *hdev, const u8 hfunc, ++ u8 *hash_algo) ++{ ++ switch (hfunc) { ++ case ETH_RSS_HASH_TOP: ++ *hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; ++ return 0; ++ case ETH_RSS_HASH_XOR: ++ *hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE; ++ return 0; ++ case ETH_RSS_HASH_NO_CHANGE: ++ *hash_algo = hdev->rss_cfg.hash_algo; ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ + static int hclgevf_set_rss(struct hnae3_handle *handle, const u32 *indir, + const u8 *key, const u8 hfunc) + { + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; ++ u8 hash_algo; + int ret, i; + + if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { ++ ret = hclgevf_parse_rss_hfunc(hdev, hfunc, &hash_algo); ++ if (ret) ++ return ret; ++ + /* Set the RSS Hash Key if specififed by the user */ + if (key) { +- switch (hfunc) { +- case ETH_RSS_HASH_TOP: +- rss_cfg->hash_algo = +- HCLGEVF_RSS_HASH_ALGO_TOEPLITZ; +- break; +- case ETH_RSS_HASH_XOR: +- rss_cfg->hash_algo = +- HCLGEVF_RSS_HASH_ALGO_SIMPLE; +- break; +- case ETH_RSS_HASH_NO_CHANGE: +- break; +- default: +- return -EINVAL; +- } +- +- ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, +- key); +- if (ret) ++ ret = hclgevf_set_rss_algo_key(hdev, hash_algo, key); ++ if (ret) { ++ dev_err(&hdev->pdev->dev, ++ "invalid hfunc type %u\n", hfunc); + return ret; ++ } + + /* Update the shadow RSS key with user specified qids */ + memcpy(rss_cfg->rss_hash_key, key, + HCLGEVF_RSS_KEY_SIZE); ++ } else { ++ ret = hclgevf_set_rss_algo_key(hdev, hash_algo, ++ rss_cfg->rss_hash_key); ++ if (ret) ++ return ret; + } ++ rss_cfg->hash_algo = hash_algo; + } + + /* update the shadow RSS table with user specified qids */ +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-fix-inconsistent-vf-id-print.patch b/queue-5.14/net-hns3-fix-inconsistent-vf-id-print.patch new file mode 100644 index 00000000000..1ac7f58e711 --- /dev/null +++ b/queue-5.14/net-hns3-fix-inconsistent-vf-id-print.patch @@ -0,0 +1,45 @@ +From 488c5269b77c657b1523dbefde95331b8be1d403 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:07 +0800 +Subject: net: hns3: fix inconsistent vf id print + +From: Jian Shen + +[ Upstream commit 91bc0d5272d3a4dc3d4fd2a74387c7e7361bbe96 ] + +The vf id from ethtool is added 1 before configured to driver. +So it's necessary to minus 1 when printing it, in order to +keep consistent with user's configuration. + +Fixes: dd74f815dd41 ("net: hns3: Add support for rule add/delete for flow director") +Signed-off-by: Jian Shen +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 40c4949eed4d..45faf924bc36 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -6635,10 +6635,13 @@ static int hclge_fd_parse_ring_cookie(struct hclge_dev *hdev, u64 ring_cookie, + u8 vf = ethtool_get_flow_spec_ring_vf(ring_cookie); + u16 tqps; + ++ /* To keep consistent with user's configuration, minus 1 when ++ * printing 'vf', because vf id from ethtool is added 1 for vf. ++ */ + if (vf > hdev->num_req_vfs) { + dev_err(&hdev->pdev->dev, +- "Error: vf id (%u) > max vf num (%u)\n", +- vf, hdev->num_req_vfs); ++ "Error: vf id (%u) should be less than %u\n", ++ vf - 1, hdev->num_req_vfs); + return -EINVAL; + } + +-- +2.33.0 + diff --git a/queue-5.14/net-hns3-fix-misuse-vf-id-and-vport-id-in-some-logs.patch b/queue-5.14/net-hns3-fix-misuse-vf-id-and-vport-id-in-some-logs.patch new file mode 100644 index 00000000000..ff0c279b675 --- /dev/null +++ b/queue-5.14/net-hns3-fix-misuse-vf-id-and-vport-id-in-some-logs.patch @@ -0,0 +1,125 @@ +From 1c4512efe71744cf3f65712c002f1860847b0d33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Sep 2021 21:52:08 +0800 +Subject: net: hns3: fix misuse vf id and vport id in some logs + +From: Jiaran Zhang + +[ Upstream commit 311c0aaa9b4bb8dc65f22634e15963316b17c921 ] + +vport_id include PF and VFs, vport_id = 0 means PF, other values mean VFs. +So the actual vf id is equal to vport_id minus 1. + +Some VF print logs are actually vport, and logs of vf id actually use +vport id, so this patch fixes them. + +Fixes: ac887be5b0fe ("net: hns3: change print level of RAS error log from warning to error") +Fixes: adcf738b804b ("net: hns3: cleanup some print format warning") +Signed-off-by: Jiaran Zhang +Signed-off-by: Guangbin Huang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c | 8 ++++---- + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 10 ++++++---- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 2 +- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 2 +- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +index ec9a7f8bc3fe..2eeafd61a07e 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +@@ -1878,12 +1878,12 @@ static void hclge_handle_over_8bd_err(struct hclge_dev *hdev, + return; + } + +- dev_err(dev, "PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found, vf_id(%u), queue_id(%u)\n", ++ dev_err(dev, "PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found, vport(%u), queue_id(%u)\n", + vf_id, q_id); + + if (vf_id) { + if (vf_id >= hdev->num_alloc_vport) { +- dev_err(dev, "invalid vf id(%u)\n", vf_id); ++ dev_err(dev, "invalid vport(%u)\n", vf_id); + return; + } + +@@ -1896,8 +1896,8 @@ static void hclge_handle_over_8bd_err(struct hclge_dev *hdev, + + ret = hclge_inform_reset_assert_to_vf(&hdev->vport[vf_id]); + if (ret) +- dev_err(dev, "inform reset to vf(%u) failed %d!\n", +- hdev->vport->vport_id, ret); ++ dev_err(dev, "inform reset to vport(%u) failed %d!\n", ++ vf_id, ret); + } else { + set_bit(HNAE3_FUNC_RESET, reset_requests); + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 45faf924bc36..3f8d56ccc057 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -3660,7 +3660,8 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset) + if (ret) { + dev_err(&hdev->pdev->dev, + "set vf(%u) rst failed %d!\n", +- vport->vport_id, ret); ++ vport->vport_id - HCLGE_VF_VPORT_START_NUM, ++ ret); + return ret; + } + +@@ -3675,7 +3676,8 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset) + if (ret) + dev_warn(&hdev->pdev->dev, + "inform reset to vf(%u) failed %d!\n", +- vport->vport_id, ret); ++ vport->vport_id - HCLGE_VF_VPORT_START_NUM, ++ ret); + } + + return 0; +@@ -11460,11 +11462,11 @@ static void hclge_clear_resetting_state(struct hclge_dev *hdev) + struct hclge_vport *vport = &hdev->vport[i]; + int ret; + +- /* Send cmd to clear VF's FUNC_RST_ING */ ++ /* Send cmd to clear vport's FUNC_RST_ING */ + ret = hclge_set_vf_rst(hdev, vport->vport_id, false); + if (ret) + dev_warn(&hdev->pdev->dev, +- "clear vf(%u) rst failed %d!\n", ++ "clear vport(%u) rst failed %d!\n", + vport->vport_id, ret); + } + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +index 0dbed35645ed..91c32f99b644 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +@@ -564,7 +564,7 @@ static int hclge_reset_vf(struct hclge_vport *vport) + struct hclge_dev *hdev = vport->back; + + dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %u!", +- vport->vport_id); ++ vport->vport_id - HCLGE_VF_VPORT_START_NUM); + + return hclge_func_reset_cmd(hdev, vport->vport_id); + } +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +index 78d5bf1ea561..44618cc4cca1 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +@@ -581,7 +581,7 @@ int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate) + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, +- "vf%u, qs%u failed to set tx_rate:%d, ret=%d\n", ++ "vport%u, qs%u failed to set tx_rate:%d, ret=%d\n", + vport->vport_id, shap_cfg_cmd->qs_id, + max_tx_rate, ret); + return ret; +-- +2.33.0 + diff --git a/queue-5.14/net-mlx4_en-don-t-allow-arfs-for-encapsulated-packet.patch b/queue-5.14/net-mlx4_en-don-t-allow-arfs-for-encapsulated-packet.patch new file mode 100644 index 00000000000..f03816bfec6 --- /dev/null +++ b/queue-5.14/net-mlx4_en-don-t-allow-arfs-for-encapsulated-packet.patch @@ -0,0 +1,38 @@ +From 35cfd3da7421aee86b5c11b996b16ca19a00527f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Sep 2021 09:51:45 +0300 +Subject: net/mlx4_en: Don't allow aRFS for encapsulated packets + +From: Aya Levin + +[ Upstream commit fdbccea419dc782079ce5881d2705cc9e3881480 ] + +Driver doesn't support aRFS for encapsulated packets, return early error +in such a case. + +Fixes: 1eb8c695bda9 ("net/mlx4_en: Add accelerated RFS support") +Signed-off-by: Aya Levin +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index c3171b5f6431..a6878e5f922a 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -372,6 +372,9 @@ mlx4_en_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, + int nhoff = skb_network_offset(skb); + int ret = 0; + ++ if (skb->encapsulation) ++ return -EPROTONOSUPPORT; ++ + if (skb->protocol != htons(ETH_P_IP)) + return -EPROTONOSUPPORT; + +-- +2.33.0 + diff --git a/queue-5.14/net-mlx4_en-resolve-bad-operstate-value.patch b/queue-5.14/net-mlx4_en-resolve-bad-operstate-value.patch new file mode 100644 index 00000000000..e33f5d682fd --- /dev/null +++ b/queue-5.14/net-mlx4_en-resolve-bad-operstate-value.patch @@ -0,0 +1,127 @@ +From 548f95a57741c4879bc873aee299f1dcf6c602a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Sep 2021 14:55:45 +0300 +Subject: net/mlx4_en: Resolve bad operstate value + +From: Lama Kayal + +[ Upstream commit 72a3c58d18fd780eecd80178bb2132ce741a0a74 ] + +Any link state change that's done prior to net device registration +isn't reflected on the state, thus the operational state is left +obsolete, with 'UNKNOWN' status. + +To resolve the issue, query link state from FW upon open operations +to ensure operational state is updated. + +Fixes: c27a02cd94d6 ("mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC") +Signed-off-by: Lama Kayal +Signed-off-by: Tariq Toukan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx4/en_netdev.c | 47 ++++++++++++------- + drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - + 2 files changed, 29 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +index 5d0c9c62382d..c3171b5f6431 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +@@ -1269,7 +1269,6 @@ static void mlx4_en_do_set_rx_mode(struct work_struct *work) + if (!netif_carrier_ok(dev)) { + if (!mlx4_en_QUERY_PORT(mdev, priv->port)) { + if (priv->port_state.link_state) { +- priv->last_link_state = MLX4_DEV_EVENT_PORT_UP; + netif_carrier_on(dev); + en_dbg(LINK, priv, "Link Up\n"); + } +@@ -1557,26 +1556,36 @@ static void mlx4_en_service_task(struct work_struct *work) + mutex_unlock(&mdev->state_lock); + } + +-static void mlx4_en_linkstate(struct work_struct *work) ++static void mlx4_en_linkstate(struct mlx4_en_priv *priv) ++{ ++ struct mlx4_en_port_state *port_state = &priv->port_state; ++ struct mlx4_en_dev *mdev = priv->mdev; ++ struct net_device *dev = priv->dev; ++ bool up; ++ ++ if (mlx4_en_QUERY_PORT(mdev, priv->port)) ++ port_state->link_state = MLX4_PORT_STATE_DEV_EVENT_PORT_DOWN; ++ ++ up = port_state->link_state == MLX4_PORT_STATE_DEV_EVENT_PORT_UP; ++ if (up == netif_carrier_ok(dev)) ++ netif_carrier_event(dev); ++ if (!up) { ++ en_info(priv, "Link Down\n"); ++ netif_carrier_off(dev); ++ } else { ++ en_info(priv, "Link Up\n"); ++ netif_carrier_on(dev); ++ } ++} ++ ++static void mlx4_en_linkstate_work(struct work_struct *work) + { + struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, + linkstate_task); + struct mlx4_en_dev *mdev = priv->mdev; +- int linkstate = priv->link_state; + + mutex_lock(&mdev->state_lock); +- /* If observable port state changed set carrier state and +- * report to system log */ +- if (priv->last_link_state != linkstate) { +- if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) { +- en_info(priv, "Link Down\n"); +- netif_carrier_off(priv->dev); +- } else { +- en_info(priv, "Link Up\n"); +- netif_carrier_on(priv->dev); +- } +- } +- priv->last_link_state = linkstate; ++ mlx4_en_linkstate(priv); + mutex_unlock(&mdev->state_lock); + } + +@@ -2079,9 +2088,11 @@ static int mlx4_en_open(struct net_device *dev) + mlx4_en_clear_stats(dev); + + err = mlx4_en_start_port(dev); +- if (err) ++ if (err) { + en_err(priv, "Failed starting port:%d\n", priv->port); +- ++ goto out; ++ } ++ mlx4_en_linkstate(priv); + out: + mutex_unlock(&mdev->state_lock); + return err; +@@ -3168,7 +3179,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, + spin_lock_init(&priv->stats_lock); + INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); + INIT_WORK(&priv->restart_task, mlx4_en_restart); +- INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); ++ INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate_work); + INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); + INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); + #ifdef CONFIG_RFS_ACCEL +diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +index f3d1a20201ef..6bf558c5ec10 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h ++++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +@@ -552,7 +552,6 @@ struct mlx4_en_priv { + + struct mlx4_hwq_resources res; + int link_state; +- int last_link_state; + bool port_up; + int port; + int registered; +-- +2.33.0 + diff --git a/queue-5.14/net-mscc-ocelot-fix-forwarding-from-blocking-ports-r.patch b/queue-5.14/net-mscc-ocelot-fix-forwarding-from-blocking-ports-r.patch new file mode 100644 index 00000000000..5867692fc2a --- /dev/null +++ b/queue-5.14/net-mscc-ocelot-fix-forwarding-from-blocking-ports-r.patch @@ -0,0 +1,73 @@ +From abda04aac4792a6f6935caa46097f35617fb9e66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 19:03:38 -0700 +Subject: net: mscc: ocelot: fix forwarding from BLOCKING ports remaining + enabled + +From: Vladimir Oltean + +[ Upstream commit acc64f52afac15e9e44d9b5253271346841786e0 ] + +The blamed commit made the fatally incorrect assumption that ports which +aren't in the FORWARDING STP state should not have packets forwarded +towards them, and that is all that needs to be done. + +However, that logic alone permits BLOCKING ports to forward to +FORWARDING ports, which of course allows packet storms to occur when +there is an L2 loop. + +The ocelot_get_bridge_fwd_mask should not only ask "what can the bridge +do for you", but "what can you do for the bridge". This way, only +FORWARDING ports forward to the other FORWARDING ports from the same +bridging domain, and we are still compatible with the idea of multiple +bridges. + +Fixes: df291e54ccca ("net: ocelot: support multiple bridges") +Suggested-by: Colin Foster +Reported-by: Colin Foster +Signed-off-by: Vladimir Oltean +Signed-off-by: Colin Foster +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index 2948d731a1c1..512dff955166 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -1260,14 +1260,19 @@ static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond, + return mask; + } + +-static u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, ++static u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port, + struct net_device *bridge) + { ++ struct ocelot_port *ocelot_port = ocelot->ports[src_port]; + u32 mask = 0; + int port; + ++ if (!ocelot_port || ocelot_port->bridge != bridge || ++ ocelot_port->stp_state != BR_STATE_FORWARDING) ++ return 0; ++ + for (port = 0; port < ocelot->num_phys_ports; port++) { +- struct ocelot_port *ocelot_port = ocelot->ports[port]; ++ ocelot_port = ocelot->ports[port]; + + if (!ocelot_port) + continue; +@@ -1333,7 +1338,7 @@ void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot) + struct net_device *bridge = ocelot_port->bridge; + struct net_device *bond = ocelot_port->bond; + +- mask = ocelot_get_bridge_fwd_mask(ocelot, bridge); ++ mask = ocelot_get_bridge_fwd_mask(ocelot, port, bridge); + mask |= cpu_fwd_mask; + mask &= ~BIT(port); + if (bond) { +-- +2.33.0 + diff --git a/queue-5.14/net-smc-add-missing-error-check-in-smc_clc_prfx_set.patch b/queue-5.14/net-smc-add-missing-error-check-in-smc_clc_prfx_set.patch new file mode 100644 index 00000000000..293d9710912 --- /dev/null +++ b/queue-5.14/net-smc-add-missing-error-check-in-smc_clc_prfx_set.patch @@ -0,0 +1,45 @@ +From 3ced899f64f9ba7a20eaea302c5751da1ad3f568 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Sep 2021 21:18:14 +0200 +Subject: net/smc: add missing error check in smc_clc_prfx_set() + +From: Karsten Graul + +[ Upstream commit 6c90731980655280ea07ce4b21eb97457bf86286 ] + +Coverity stumbled over a missing error check in smc_clc_prfx_set(): + +*** CID 1475954: Error handling issues (CHECKED_RETURN) +/net/smc/smc_clc.c: 233 in smc_clc_prfx_set() +>>> CID 1475954: Error handling issues (CHECKED_RETURN) +>>> Calling "kernel_getsockname" without checking return value (as is done elsewhere 8 out of 10 times). +233 kernel_getsockname(clcsock, (struct sockaddr *)&addrs); + +Add the return code check in smc_clc_prfx_set(). + +Fixes: c246d942eabc ("net/smc: restructure netinfo for CLC proposal msgs") +Reported-by: Julian Wiedmann +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_clc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index e286dafd6e88..6ec1ebe878ae 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -230,7 +230,8 @@ static int smc_clc_prfx_set(struct socket *clcsock, + goto out_rel; + } + /* get address to which the internal TCP socket is bound */ +- kernel_getsockname(clcsock, (struct sockaddr *)&addrs); ++ if (kernel_getsockname(clcsock, (struct sockaddr *)&addrs) < 0) ++ goto out_rel; + /* analyze IP specific data of net_device belonging to TCP socket */ + addr6 = (struct sockaddr_in6 *)&addrs; + rcu_read_lock(); +-- +2.33.0 + diff --git a/queue-5.14/net-smc-fix-workqueue-leaked-lock-in-smc_conn_abort_.patch b/queue-5.14/net-smc-fix-workqueue-leaked-lock-in-smc_conn_abort_.patch new file mode 100644 index 00000000000..de521525369 --- /dev/null +++ b/queue-5.14/net-smc-fix-workqueue-leaked-lock-in-smc_conn_abort_.patch @@ -0,0 +1,48 @@ +From 9c16827976a9392bcbcdd81270f92cb1465a0863 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Sep 2021 21:18:15 +0200 +Subject: net/smc: fix 'workqueue leaked lock' in smc_conn_abort_work + +From: Karsten Graul + +[ Upstream commit a18cee4791b1123d0a6579a7c89f4b87e48abe03 ] + +The abort_work is scheduled when a connection was detected to be +out-of-sync after a link failure. The work calls smc_conn_kill(), +which calls smc_close_active_abort() and that might end up calling +smc_close_cancel_work(). +smc_close_cancel_work() cancels any pending close_work and tx_work but +needs to release the sock_lock before and acquires the sock_lock again +afterwards. So when the sock_lock was NOT acquired before then it may +be held after the abort_work completes. Thats why the sock_lock is +acquired before the call to smc_conn_kill() in __smc_lgr_terminate(), +but this is missing in smc_conn_abort_work(). + +Fix that by acquiring the sock_lock first and release it after the +call to smc_conn_kill(). + +Fixes: b286a0651e44 ("net/smc: handle incoming CDC validation message") +Signed-off-by: Karsten Graul +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c +index c160ff50c053..116cfd6fac1f 100644 +--- a/net/smc/smc_core.c ++++ b/net/smc/smc_core.c +@@ -1474,7 +1474,9 @@ static void smc_conn_abort_work(struct work_struct *work) + abort_work); + struct smc_sock *smc = container_of(conn, struct smc_sock, conn); + ++ lock_sock(&smc->sk); + smc_conn_kill(conn, true); ++ release_sock(&smc->sk); + sock_put(&smc->sk); /* sock_hold done by schedulers of abort_work */ + } + +-- +2.33.0 + diff --git a/queue-5.14/nexthop-fix-memory-leaks-in-nexthop-notification-cha.patch b/queue-5.14/nexthop-fix-memory-leaks-in-nexthop-notification-cha.patch new file mode 100644 index 00000000000..3ea3a2c1c2c --- /dev/null +++ b/queue-5.14/nexthop-fix-memory-leaks-in-nexthop-notification-cha.patch @@ -0,0 +1,163 @@ +From 1295362df462ffbab7d2c6d1ef4e0d1cc97a1286 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 13:25:40 +0300 +Subject: nexthop: Fix memory leaks in nexthop notification chain listeners + +From: Ido Schimmel + +[ Upstream commit 3106a0847525befe3e22fc723909d1b21eb0d520 ] + +syzkaller discovered memory leaks [1] that can be reduced to the +following commands: + + # ip nexthop add id 1 blackhole + # devlink dev reload pci/0000:06:00.0 + +As part of the reload flow, mlxsw will unregister its netdevs and then +unregister from the nexthop notification chain. Before unregistering +from the notification chain, mlxsw will receive delete notifications for +nexthop objects using netdevs registered by mlxsw or their uppers. mlxsw +will not receive notifications for nexthops using netdevs that are not +dismantled as part of the reload flow. For example, the blackhole +nexthop above that internally uses the loopback netdev as its nexthop +device. + +One way to fix this problem is to have listeners flush their nexthop +tables after unregistering from the notification chain. This is +error-prone as evident by this patch and also not symmetric with the +registration path where a listener receives a dump of all the existing +nexthops. + +Therefore, fix this problem by replaying delete notifications for the +listener being unregistered. This is symmetric to the registration path +and also consistent with the netdev notification chain. + +The above means that unregister_nexthop_notifier(), like +register_nexthop_notifier(), will have to take RTNL in order to iterate +over the existing nexthops and that any callers of the function cannot +hold RTNL. This is true for mlxsw and netdevsim, but not for the VXLAN +driver. To avoid a deadlock, change the latter to unregister its nexthop +listener without holding RTNL, making it symmetric to the registration +path. + +[1] +unreferenced object 0xffff88806173d600 (size 512): + comm "syz-executor.0", pid 1290, jiffies 4295583142 (age 143.507s) + hex dump (first 32 bytes): + 41 9d 1e 60 80 88 ff ff 08 d6 73 61 80 88 ff ff A..`......sa.... + 08 d6 73 61 80 88 ff ff 01 00 00 00 00 00 00 00 ..sa............ + backtrace: + [] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] + [] slab_post_alloc_hook+0x96/0x490 mm/slab.h:522 + [] slab_alloc_node mm/slub.c:3206 [inline] + [] slab_alloc mm/slub.c:3214 [inline] + [] kmem_cache_alloc_trace+0x163/0x370 mm/slub.c:3231 + [] kmalloc include/linux/slab.h:591 [inline] + [] kzalloc include/linux/slab.h:721 [inline] + [] mlxsw_sp_nexthop_obj_group_create drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:4918 [inline] + [] mlxsw_sp_nexthop_obj_new drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5054 [inline] + [] mlxsw_sp_nexthop_obj_event+0x59a/0x2910 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5239 + [] notifier_call_chain+0xbd/0x210 kernel/notifier.c:83 + [] blocking_notifier_call_chain kernel/notifier.c:318 [inline] + [] blocking_notifier_call_chain+0x72/0xa0 kernel/notifier.c:306 + [] call_nexthop_notifiers+0x156/0x310 net/ipv4/nexthop.c:244 + [] insert_nexthop net/ipv4/nexthop.c:2336 [inline] + [] nexthop_add net/ipv4/nexthop.c:2644 [inline] + [] rtm_new_nexthop+0x14e8/0x4d10 net/ipv4/nexthop.c:2913 + [] rtnetlink_rcv_msg+0x448/0xbf0 net/core/rtnetlink.c:5572 + [] netlink_rcv_skb+0x173/0x480 net/netlink/af_netlink.c:2504 + [] rtnetlink_rcv+0x22/0x30 net/core/rtnetlink.c:5590 + [] netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline] + [] netlink_unicast+0x5ae/0x7f0 net/netlink/af_netlink.c:1340 + [] netlink_sendmsg+0x8e1/0xe30 net/netlink/af_netlink.c:1929 + [] sock_sendmsg_nosec net/socket.c:704 [inline] + [] sock_sendmsg net/socket.c:724 [inline] + [] ____sys_sendmsg+0x874/0x9f0 net/socket.c:2409 + [] ___sys_sendmsg+0x104/0x170 net/socket.c:2463 + [] __sys_sendmsg+0x111/0x1f0 net/socket.c:2492 + [] __do_sys_sendmsg net/socket.c:2501 [inline] + [] __se_sys_sendmsg net/socket.c:2499 [inline] + [] __x64_sys_sendmsg+0x7d/0xc0 net/socket.c:2499 + +Fixes: 2a014b200bbd ("mlxsw: spectrum_router: Add support for nexthop objects") +Signed-off-by: Ido Schimmel +Reviewed-by: Petr Machata +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan.c | 2 +- + net/ipv4/nexthop.c | 19 ++++++++++++++----- + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 5a8df5a195cb..141635a35c28 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -4756,12 +4756,12 @@ static void __net_exit vxlan_exit_batch_net(struct list_head *net_list) + LIST_HEAD(list); + unsigned int h; + +- rtnl_lock(); + list_for_each_entry(net, net_list, exit_list) { + struct vxlan_net *vn = net_generic(net, vxlan_net_id); + + unregister_nexthop_notifier(net, &vn->nexthop_notifier_block); + } ++ rtnl_lock(); + list_for_each_entry(net, net_list, exit_list) + vxlan_destroy_tunnels(net, &list); + +diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c +index 0e75fd3e57b4..9e8100728d46 100644 +--- a/net/ipv4/nexthop.c ++++ b/net/ipv4/nexthop.c +@@ -3567,6 +3567,7 @@ static struct notifier_block nh_netdev_notifier = { + }; + + static int nexthops_dump(struct net *net, struct notifier_block *nb, ++ enum nexthop_event_type event_type, + struct netlink_ext_ack *extack) + { + struct rb_root *root = &net->nexthop.rb_root; +@@ -3577,8 +3578,7 @@ static int nexthops_dump(struct net *net, struct notifier_block *nb, + struct nexthop *nh; + + nh = rb_entry(node, struct nexthop, rb_node); +- err = call_nexthop_notifier(nb, net, NEXTHOP_EVENT_REPLACE, nh, +- extack); ++ err = call_nexthop_notifier(nb, net, event_type, nh, extack); + if (err) + break; + } +@@ -3592,7 +3592,7 @@ int register_nexthop_notifier(struct net *net, struct notifier_block *nb, + int err; + + rtnl_lock(); +- err = nexthops_dump(net, nb, extack); ++ err = nexthops_dump(net, nb, NEXTHOP_EVENT_REPLACE, extack); + if (err) + goto unlock; + err = blocking_notifier_chain_register(&net->nexthop.notifier_chain, +@@ -3605,8 +3605,17 @@ EXPORT_SYMBOL(register_nexthop_notifier); + + int unregister_nexthop_notifier(struct net *net, struct notifier_block *nb) + { +- return blocking_notifier_chain_unregister(&net->nexthop.notifier_chain, +- nb); ++ int err; ++ ++ rtnl_lock(); ++ err = blocking_notifier_chain_unregister(&net->nexthop.notifier_chain, ++ nb); ++ if (err) ++ goto unlock; ++ nexthops_dump(net, nb, NEXTHOP_EVENT_DEL, NULL); ++unlock: ++ rtnl_unlock(); ++ return err; + } + EXPORT_SYMBOL(unregister_nexthop_notifier); + +-- +2.33.0 + diff --git a/queue-5.14/nfc-st-nci-add-spi-id-matching-dt-compatible.patch b/queue-5.14/nfc-st-nci-add-spi-id-matching-dt-compatible.patch new file mode 100644 index 00000000000..189972a4e32 --- /dev/null +++ b/queue-5.14/nfc-st-nci-add-spi-id-matching-dt-compatible.patch @@ -0,0 +1,38 @@ +From 4e79527d4b128bdc6923fb517e1c5f1d0000f8d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 19:30:37 +0100 +Subject: nfc: st-nci: Add SPI ID matching DT compatible + +From: Mark Brown + +[ Upstream commit 31339440b2d0a4987030aac026adbaba44e22490 ] + +Currently autoloading for SPI devices does not use the DT ID table, it uses +SPI modalises. Supporting OF modalises is going to be difficult if not +impractical, an attempt was made but has been reverted, so ensure that +module autoloading works for this driver by adding the part name used in +the compatible to the list of SPI IDs. + +Fixes: 96c8395e2166 ("spi: Revert modalias changes") +Signed-off-by: Mark Brown +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/nfc/st-nci/spi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/nfc/st-nci/spi.c b/drivers/nfc/st-nci/spi.c +index 250d56f204c3..e62b1a0916d8 100644 +--- a/drivers/nfc/st-nci/spi.c ++++ b/drivers/nfc/st-nci/spi.c +@@ -278,6 +278,7 @@ static int st_nci_spi_remove(struct spi_device *dev) + + static struct spi_device_id st_nci_spi_id_table[] = { + {ST_NCI_SPI_DRIVER_NAME, 0}, ++ {"st21nfcb-spi", 0}, + {} + }; + MODULE_DEVICE_TABLE(spi, st_nci_spi_id_table); +-- +2.33.0 + diff --git a/queue-5.14/nlm-fix-svcxdr_encode_owner.patch b/queue-5.14/nlm-fix-svcxdr_encode_owner.patch new file mode 100644 index 00000000000..a99692d0b0b --- /dev/null +++ b/queue-5.14/nlm-fix-svcxdr_encode_owner.patch @@ -0,0 +1,52 @@ +From e57551cadf48fa479465962c7bedfcb45e1e421b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 17:24:54 -0400 +Subject: NLM: Fix svcxdr_encode_owner() + +From: Chuck Lever + +[ Upstream commit 89c485c7a3ecbc2ebd568f9c9c2edf3a8cf7485b ] + +Dai Ngo reports that, since the XDR overhaul, the NLM server crashes +when the TEST procedure wants to return NLM_DENIED. There is a bug +in svcxdr_encode_owner() that none of our standard test cases found. + +Replace the open-coded function with a call to an appropriate +pre-fabricated XDR helper. + +Reported-by: Dai Ngo +Fixes: a6a63ca5652e ("lockd: Common NLM XDR helpers") +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/lockd/svcxdr.h | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/fs/lockd/svcxdr.h b/fs/lockd/svcxdr.h +index c69a0bb76c94..4f1a451da5ba 100644 +--- a/fs/lockd/svcxdr.h ++++ b/fs/lockd/svcxdr.h +@@ -134,18 +134,9 @@ svcxdr_decode_owner(struct xdr_stream *xdr, struct xdr_netobj *obj) + static inline bool + svcxdr_encode_owner(struct xdr_stream *xdr, const struct xdr_netobj *obj) + { +- unsigned int quadlen = XDR_QUADLEN(obj->len); +- __be32 *p; +- +- if (xdr_stream_encode_u32(xdr, obj->len) < 0) +- return false; +- p = xdr_reserve_space(xdr, obj->len); +- if (!p) ++ if (obj->len > XDR_MAX_NETOBJ) + return false; +- p[quadlen - 1] = 0; /* XDR pad */ +- memcpy(p, obj->data, obj->len); +- +- return true; ++ return xdr_stream_encode_opaque(xdr, obj->data, obj->len) > 0; + } + + #endif /* _LOCKD_SVCXDR_H_ */ +-- +2.33.0 + diff --git a/queue-5.14/platform-x86-dell-fix-dell_wmi_privacy-dependencies-.patch b/queue-5.14/platform-x86-dell-fix-dell_wmi_privacy-dependencies-.patch new file mode 100644 index 00000000000..812193071d3 --- /dev/null +++ b/queue-5.14/platform-x86-dell-fix-dell_wmi_privacy-dependencies-.patch @@ -0,0 +1,49 @@ +From 0d916b317205b9254de5279cbff1b89d0dc19f13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 21:48:29 -0700 +Subject: platform/x86: dell: fix DELL_WMI_PRIVACY dependencies & build error + +From: Randy Dunlap + +[ Upstream commit 5b72dafaca73b33416c82457ae615e6f2022e901 ] + +When DELL_WMI=y, DELL_WMI_PRIVACY=y, and LEDS_TRIGGER_AUDIO=m, there +is a linker error since the LEDS trigger code is built as a loadable +module. This happens because DELL_WMI_PRIVACY is a bool that depends +on a tristate (LEDS_TRIGGER_AUDIO=m), which can be dangerous. + +ld: drivers/platform/x86/dell/dell-wmi-privacy.o: in function `dell_privacy_wmi_probe': +dell-wmi-privacy.c:(.text+0x3df): undefined reference to `ledtrig_audio_get' + +Fixes: 8af9fa37b8a3 ("platform/x86: dell-privacy: Add support for Dell hardware privacy") +Signed-off-by: Randy Dunlap +Cc: Perry Yuan +Cc: Dell.Client.Kernel@dell.com +Cc: platform-driver-x86@vger.kernel.org +Cc: Hans de Goede +Cc: Mark Gross +Link: https://lore.kernel.org/r/20210918044829.19222-1-rdunlap@infradead.org +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/dell/Kconfig | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig +index 9e7314d90bea..1e3da9700005 100644 +--- a/drivers/platform/x86/dell/Kconfig ++++ b/drivers/platform/x86/dell/Kconfig +@@ -166,8 +166,7 @@ config DELL_WMI + + config DELL_WMI_PRIVACY + bool "Dell WMI Hardware Privacy Support" +- depends on DELL_WMI +- depends on LEDS_TRIGGER_AUDIO ++ depends on LEDS_TRIGGER_AUDIO = y || DELL_WMI = LEDS_TRIGGER_AUDIO + help + This option adds integration with the "Dell Hardware Privacy" + feature of Dell laptops to the dell-wmi driver. +-- +2.33.0 + diff --git a/queue-5.14/platform-x86-intel-punit_ipc-drop-wrong-use-of-acpi_.patch b/queue-5.14/platform-x86-intel-punit_ipc-drop-wrong-use-of-acpi_.patch new file mode 100644 index 00000000000..950099e27ce --- /dev/null +++ b/queue-5.14/platform-x86-intel-punit_ipc-drop-wrong-use-of-acpi_.patch @@ -0,0 +1,50 @@ +From 885b7dfc809bad86a3af78286512172c48d89429 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Aug 2021 17:53:10 +0300 +Subject: platform/x86/intel: punit_ipc: Drop wrong use of ACPI_PTR() + +From: Andy Shevchenko + +[ Upstream commit 349bff48ae0f5f8aa2075d0bdc2091a30bd634f6 ] + +ACPI_PTR() is more harmful than helpful. For example, in this case +if CONFIG_ACPI=n, the ID table left unused which is not what we want. + +Instead of adding ifdeffery here and there, drop ACPI_PTR() +and unused acpi.h. + +Fixes: fdca4f16f57d ("platform:x86: add Intel P-Unit mailbox IPC driver") +Reported-by: kernel test robot +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20210827145310.76239-1-andriy.shevchenko@linux.intel.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/intel_punit_ipc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c +index f58b8543f6ac..66bb39fd0ef9 100644 +--- a/drivers/platform/x86/intel_punit_ipc.c ++++ b/drivers/platform/x86/intel_punit_ipc.c +@@ -8,7 +8,6 @@ + * which provide mailbox interface for power management usage. + */ + +-#include + #include + #include + #include +@@ -319,7 +318,7 @@ static struct platform_driver intel_punit_ipc_driver = { + .remove = intel_punit_ipc_remove, + .driver = { + .name = "intel_punit_ipc", +- .acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids), ++ .acpi_match_table = punit_ipc_acpi_ids, + }, + }; + +-- +2.33.0 + diff --git a/queue-5.14/qed-rdma-don-t-wait-for-resources-under-hw-error-rec.patch b/queue-5.14/qed-rdma-don-t-wait-for-resources-under-hw-error-rec.patch new file mode 100644 index 00000000000..2e3abcb3fa2 --- /dev/null +++ b/queue-5.14/qed-rdma-don-t-wait-for-resources-under-hw-error-rec.patch @@ -0,0 +1,65 @@ +From f679c882d482b9c0418cca26c958671be3bc8b77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Sep 2021 13:53:26 +0300 +Subject: qed: rdma - don't wait for resources under hw error recovery flow + +From: Shai Malin + +[ Upstream commit 1ea7812326004afd2803cc968a4776ae5120a597 ] + +If the HW device is during recovery, the HW resources will never return, +hence we shouldn't wait for the CID (HW context ID) bitmaps to clear. +This fix speeds up the error recovery flow. + +Fixes: 64515dc899df ("qed: Add infrastructure for error detection and recovery") +Signed-off-by: Michal Kalderon +Signed-off-by: Ariel Elior +Signed-off-by: Shai Malin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 8 ++++++++ + drivers/net/ethernet/qlogic/qed/qed_roce.c | 8 ++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +index a99861124630..68fbe536a1f3 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +@@ -1297,6 +1297,14 @@ qed_iwarp_wait_cid_map_cleared(struct qed_hwfn *p_hwfn, struct qed_bmap *bmap) + prev_weight = weight; + + while (weight) { ++ /* If the HW device is during recovery, all resources are ++ * immediately reset without receiving a per-cid indication ++ * from HW. In this case we don't expect the cid_map to be ++ * cleared. ++ */ ++ if (p_hwfn->cdev->recov_in_prog) ++ return 0; ++ + msleep(QED_IWARP_MAX_CID_CLEAN_TIME); + + weight = bitmap_weight(bmap->bitmap, bmap->max_count); +diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c +index f16a157bb95a..cf5baa5e59bc 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_roce.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c +@@ -77,6 +77,14 @@ void qed_roce_stop(struct qed_hwfn *p_hwfn) + * Beyond the added delay we clear the bitmap anyway. + */ + while (bitmap_weight(rcid_map->bitmap, rcid_map->max_count)) { ++ /* If the HW device is during recovery, all resources are ++ * immediately reset without receiving a per-cid indication ++ * from HW. In this case we don't expect the cid bitmap to be ++ * cleared. ++ */ ++ if (p_hwfn->cdev->recov_in_prog) ++ return; ++ + msleep(100); + if (wait_count++ > 20) { + DP_NOTICE(p_hwfn, "cid bitmap wait timed out\n"); +-- +2.33.0 + diff --git a/queue-5.14/regulator-max14577-revert-regulator-max14577-add-pro.patch b/queue-5.14/regulator-max14577-revert-regulator-max14577-add-pro.patch new file mode 100644 index 00000000000..40839b1ddc7 --- /dev/null +++ b/queue-5.14/regulator-max14577-revert-regulator-max14577-add-pro.patch @@ -0,0 +1,47 @@ +From bc8597ba213190fa4fd80f5f90008f59d43e9a76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 16:41:02 +0200 +Subject: regulator: max14577: Revert "regulator: max14577: Add proper module + aliases strings" + +From: Krzysztof Kozlowski + +[ Upstream commit dc9660590d106bb58d145233fffca4efadad3655 ] + +This reverts commit 0da6736ecd10b45e535b100acd58df2db4c099d8. + +The MODULE_DEVICE_TABLE already creates proper alias. Having another +MODULE_ALIAS causes the alias to be duplicated: + + $ modinfo max14577-regulator.ko + + alias: platform:max77836-regulator + alias: platform:max14577-regulator + description: Maxim 14577/77836 regulator driver + alias: platform:max77836-regulator + alias: platform:max14577-regulator + +Cc: Marek Szyprowski +Fixes: 0da6736ecd10 ("regulator: max14577: Add proper module aliases strings") +Signed-off-by: Krzysztof Kozlowski +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/r/20210916144102.120980-1-krzysztof.kozlowski@canonical.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/max14577-regulator.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c +index 1d78b455cc48..e34face736f4 100644 +--- a/drivers/regulator/max14577-regulator.c ++++ b/drivers/regulator/max14577-regulator.c +@@ -269,5 +269,3 @@ module_exit(max14577_regulator_exit); + MODULE_AUTHOR("Krzysztof Kozlowski "); + MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:max14577-regulator"); +-MODULE_ALIAS("platform:max77836-regulator"); +-- +2.33.0 + diff --git a/queue-5.14/regulator-qcom-rpmh-regulator-fix-pm8009-1-ldo7-reso.patch b/queue-5.14/regulator-qcom-rpmh-regulator-fix-pm8009-1-ldo7-reso.patch new file mode 100644 index 00000000000..e3ed064038d --- /dev/null +++ b/queue-5.14/regulator-qcom-rpmh-regulator-fix-pm8009-1-ldo7-reso.patch @@ -0,0 +1,38 @@ +From 6e722e572ad63e29284fc219cf733f25e668d552 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Sep 2021 14:43:50 +0300 +Subject: regulator: qcom-rpmh-regulator: fix pm8009-1 ldo7 resource name + +From: Dmitry Baryshkov + +[ Upstream commit 863580418bc82062083be854355f2213d3d804f5 ] + +Fix a typo in the pm8009 LDO7 declaration, it uses resource name ldo%s6 +instead of ldo%s7. + +Fixes: 951384cabc5d ("regulator: qcom-rpmh-regulator: add pm8009-1 chip revision") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20210901114350.1106073-1-dmitry.baryshkov@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/qcom-rpmh-regulator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c +index 6cca910a76de..7f458d510483 100644 +--- a/drivers/regulator/qcom-rpmh-regulator.c ++++ b/drivers/regulator/qcom-rpmh-regulator.c +@@ -991,7 +991,7 @@ static const struct rpmh_vreg_init_data pm8009_1_vreg_data[] = { + RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), + RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), + RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), +- RPMH_VREG("ldo7", "ldo%s6", &pmic5_pldo_lv, "vdd-l7"), ++ RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"), + {} + }; + +-- +2.33.0 + diff --git a/queue-5.14/s390-qeth-fix-deadlock-during-failing-recovery.patch b/queue-5.14/s390-qeth-fix-deadlock-during-failing-recovery.patch new file mode 100644 index 00000000000..73d90284de0 --- /dev/null +++ b/queue-5.14/s390-qeth-fix-deadlock-during-failing-recovery.patch @@ -0,0 +1,107 @@ +From 44f2950e4583910b42bbd6534292658832d84a39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 16:52:17 +0200 +Subject: s390/qeth: fix deadlock during failing recovery + +From: Alexandra Winter + +[ Upstream commit d2b59bd4b06d84a4eadb520b0f71c62fe8ec0a62 ] + +Commit 0b9902c1fcc5 ("s390/qeth: fix deadlock during recovery") removed +taking discipline_mutex inside qeth_do_reset(), fixing potential +deadlocks. An error path was missed though, that still takes +discipline_mutex and thus has the original deadlock potential. + +Intermittent deadlocks were seen when a qeth channel path is configured +offline, causing a race between qeth_do_reset and ccwgroup_remove. +Call qeth_set_offline() directly in the qeth_do_reset() error case and +then a new variant of ccwgroup_set_offline(), without taking +discipline_mutex. + +Fixes: b41b554c1ee7 ("s390/qeth: fix locking for discipline setup / removal") +Signed-off-by: Alexandra Winter +Reviewed-by: Julian Wiedmann +Signed-off-by: Julian Wiedmann +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/ccwgroup.h | 2 +- + drivers/s390/cio/ccwgroup.c | 10 ++++++++-- + drivers/s390/net/qeth_core_main.c | 3 ++- + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h +index 20f169b6db4e..d97301d9d0b8 100644 +--- a/arch/s390/include/asm/ccwgroup.h ++++ b/arch/s390/include/asm/ccwgroup.h +@@ -57,7 +57,7 @@ struct ccwgroup_device *get_ccwgroupdev_by_busid(struct ccwgroup_driver *gdrv, + char *bus_id); + + extern int ccwgroup_set_online(struct ccwgroup_device *gdev); +-extern int ccwgroup_set_offline(struct ccwgroup_device *gdev); ++int ccwgroup_set_offline(struct ccwgroup_device *gdev, bool call_gdrv); + + extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); + extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); +diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c +index 9748165e08e9..f19f02e75115 100644 +--- a/drivers/s390/cio/ccwgroup.c ++++ b/drivers/s390/cio/ccwgroup.c +@@ -77,12 +77,13 @@ EXPORT_SYMBOL(ccwgroup_set_online); + /** + * ccwgroup_set_offline() - disable a ccwgroup device + * @gdev: target ccwgroup device ++ * @call_gdrv: Call the registered gdrv set_offline function + * + * This function attempts to put the ccwgroup device into the offline state. + * Returns: + * %0 on success and a negative error value on failure. + */ +-int ccwgroup_set_offline(struct ccwgroup_device *gdev) ++int ccwgroup_set_offline(struct ccwgroup_device *gdev, bool call_gdrv) + { + struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); + int ret = -EINVAL; +@@ -91,11 +92,16 @@ int ccwgroup_set_offline(struct ccwgroup_device *gdev) + return -EAGAIN; + if (gdev->state == CCWGROUP_OFFLINE) + goto out; ++ if (!call_gdrv) { ++ ret = 0; ++ goto offline; ++ } + if (gdrv->set_offline) + ret = gdrv->set_offline(gdev); + if (ret) + goto out; + ++offline: + gdev->state = CCWGROUP_OFFLINE; + out: + atomic_set(&gdev->onoff, 0); +@@ -124,7 +130,7 @@ static ssize_t ccwgroup_online_store(struct device *dev, + if (value == 1) + ret = ccwgroup_set_online(gdev); + else if (value == 0) +- ret = ccwgroup_set_offline(gdev); ++ ret = ccwgroup_set_offline(gdev, true); + else + ret = -EINVAL; + out: +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 51f7f4e680c3..52dabdb32efb 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -5556,7 +5556,8 @@ static int qeth_do_reset(void *data) + dev_info(&card->gdev->dev, + "Device successfully recovered!\n"); + } else { +- ccwgroup_set_offline(card->gdev); ++ qeth_set_offline(card, disc, true); ++ ccwgroup_set_offline(card->gdev, false); + dev_warn(&card->gdev->dev, + "The qeth device driver failed to recover an error on the device\n"); + } +-- +2.33.0 + diff --git a/queue-5.14/s390-qeth-fix-null-deref-in-qeth_clear_working_pool_.patch b/queue-5.14/s390-qeth-fix-null-deref-in-qeth_clear_working_pool_.patch new file mode 100644 index 00000000000..231ed0e332d --- /dev/null +++ b/queue-5.14/s390-qeth-fix-null-deref-in-qeth_clear_working_pool_.patch @@ -0,0 +1,60 @@ +From 17985268dcd078691463d45b3b8eb53b45b2229b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 16:52:15 +0200 +Subject: s390/qeth: fix NULL deref in qeth_clear_working_pool_list() + +From: Julian Wiedmann + +[ Upstream commit 248f064af222a1f97ee02c84a98013dfbccad386 ] + +When qeth_set_online() calls qeth_clear_working_pool_list() to roll +back after an error exit from qeth_hardsetup_card(), we are at risk of +accessing card->qdio.in_q before it was allocated by +qeth_alloc_qdio_queues() via qeth_mpc_initialize(). + +qeth_clear_working_pool_list() then dereferences NULL, and by writing to +queue->bufs[i].pool_entry scribbles all over the CPU's lowcore. +Resulting in a crash when those lowcore areas are used next (eg. on +the next machine-check interrupt). + +Such a scenario would typically happen when the device is first set +online and its queues aren't allocated yet. An early IO error or certain +misconfigs (eg. mismatched transport mode, bad portno) then cause us to +error out from qeth_hardsetup_card() with card->qdio.in_q still being +NULL. + +Fix it by checking the pointer for NULL before accessing it. + +Note that we also have (rare) paths inside qeth_mpc_initialize() where +a configuration change can cause us to free the existing queues, +expecting that subsequent code will allocate them again. If we then +error out before that re-allocation happens, the same bug occurs. + +Fixes: eff73e16ee11 ("s390/qeth: tolerate pre-filled RX buffer") +Reported-by: Stefan Raspl +Root-caused-by: Heiko Carstens +Signed-off-by: Julian Wiedmann +Reviewed-by: Alexandra Winter +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 62f88ccbd03f..51f7f4e680c3 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -207,6 +207,9 @@ static void qeth_clear_working_pool_list(struct qeth_card *card) + &card->qdio.in_buf_pool.entry_list, list) + list_del(&pool_entry->list); + ++ if (!queue) ++ return; ++ + for (i = 0; i < ARRAY_SIZE(queue->bufs); i++) + queue->bufs[i].pool_entry = NULL; + } +-- +2.33.0 + diff --git a/queue-5.14/series b/queue-5.14/series index 6255335d285..339eb244b46 100644 --- a/queue-5.14/series +++ b/queue-5.14/series @@ -44,3 +44,52 @@ platform-x86-amd-pmc-increase-the-response-register-timeout.patch arm64-restore-forced-disabling-of-kpti-on-thunderx.patch arm64-mitigate-mte-issues-with-str-n-cmp.patch comedi-fix-memory-leak-in-compat_insnlist.patch +regulator-qcom-rpmh-regulator-fix-pm8009-1-ldo7-reso.patch +afs-fix-page-leak.patch +afs-fix-incorrect-triggering-of-sillyrename-on-3rd-p.patch +afs-fix-corruption-in-reads-at-fpos-2g-4g-from-an-op.patch +afs-fix-updating-of-i_blocks-on-file-dir-extension.patch +platform-x86-intel-punit_ipc-drop-wrong-use-of-acpi_.patch +regulator-max14577-revert-regulator-max14577-add-pro.patch +nlm-fix-svcxdr_encode_owner.patch +net-dsa-hellcreek-be-compatible-with-masters-which-u.patch +net-dsa-microchip-ksz8863-be-compatible-with-masters.patch +net-dsa-xrs700x-be-compatible-with-masters-which-unr.patch +virtio-net-fix-pages-leaking-when-building-skb-in-bi.patch +enetc-fix-illegal-access-when-reading-affinity_hint.patch +enetc-fix-uninitialized-struct-dim_sample-field-usag.patch +igc-fix-build-errors-for-ptp.patch +net-dsa-tear-down-devlink-port-regions-when-tearing-.patch +net-bgmac-bcma-handle-deferred-probe-error-due-to-ma.patch +net-mlx4_en-resolve-bad-operstate-value.patch +napi-fix-race-inside-napi_enable.patch +bnxt_en-fix-tx-timeout-when-tx-ring-size-is-set-to-t.patch +net-hns3-fix-change-rss-hfunc-ineffective-issue.patch +net-hns3-fix-inconsistent-vf-id-print.patch +net-hns3-fix-misuse-vf-id-and-vport-id-in-some-logs.patch +net-hns3-check-queue-id-range-before-using.patch +net-hns3-check-vlan-id-before-using-it.patch +net-hns3-fix-a-return-value-error-in-hclge_get_reset.patch +net-smc-add-missing-error-check-in-smc_clc_prfx_set.patch +net-smc-fix-workqueue-leaked-lock-in-smc_conn_abort_.patch +net-dsa-fix-dsa_tree_setup-error-path.patch +net-dsa-don-t-allocate-the-slave_mii_bus-using-devre.patch +net-dsa-realtek-register-the-mdio-bus-under-devres.patch +platform-x86-dell-fix-dell_wmi_privacy-dependencies-.patch +kselftest-arm64-signal-add-sve-to-the-set-of-feature.patch +kselftest-arm64-signal-skip-tests-if-required-featur.patch +spi-revert-modalias-changes.patch +s390-qeth-fix-null-deref-in-qeth_clear_working_pool_.patch +s390-qeth-fix-deadlock-during-failing-recovery.patch +gpiolib-acpi-make-set-debounce-timeout-failures-non-.patch +gpio-uniphier-fix-void-functions-to-remove-return-va.patch +qed-rdma-don-t-wait-for-resources-under-hw-error-rec.patch +mptcp-ensure-tx-skbs-always-have-the-mptcp-ext.patch +nexthop-fix-memory-leaks-in-nexthop-notification-cha.patch +nfc-st-nci-add-spi-id-matching-dt-compatible.patch +net-ethernet-mtk_eth_soc-avoid-creating-duplicate-of.patch +net-mscc-ocelot-fix-forwarding-from-blocking-ports-r.patch +net-mlx4_en-don-t-allow-arfs-for-encapsulated-packet.patch +atlantic-fix-issue-in-the-pm-resume-flow.patch +drm-amdkfd-map-svm-range-with-correct-access-permiss.patch +drm-amdkfd-fix-dma-mapping-leaking-warning.patch diff --git a/queue-5.14/spi-revert-modalias-changes.patch b/queue-5.14/spi-revert-modalias-changes.patch new file mode 100644 index 00000000000..81e409d68a0 --- /dev/null +++ b/queue-5.14/spi-revert-modalias-changes.patch @@ -0,0 +1,100 @@ +From 6db202052a792a3e8d78ce1a7ef4e93683d6b529 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Sep 2021 15:44:06 +0100 +Subject: spi: Revert modalias changes + +From: Mark Brown + +[ Upstream commit 96c8395e2166efa86082f3b71567ffd84936439b ] + +During the v5.13 cycle we updated the SPI subsystem to generate OF style +modaliases for SPI devices, replacing the old Linux style modalises we +used to generate based on spi_device_id which are the DT style name with +the vendor removed. Unfortunately this means that we start only +reporting OF style modalises and not the old ones and there is nothing +that ensures that drivers list every possible OF compatible string in +their OF ID table. The result is that there are systems which have been +relying on loading modules based on the old style that are now broken, +as found by Russell King with spi-nor on Macchiatobin. + +spi-nor is a particularly problematic case for this, it only lists a +single generic DT compatible jedec,spi-nor in the driver but supports a +huge raft of device specific compatibles, with a large set of part +numbers many of which are offered by multiple vendors. Russell's +searches of upstream device trees has turned up examples with vendor +names written in non-standard ways too. To make matters worse up until +8ff16cf77ce3 ("Documentation: devicetree: m25p80: add "nor-jedec" +binding") the generic compatible was not part of the binding so there +are device trees out there written to that binding version which don't +list it all. The sheer number of parts supported together with our +previous approach of ignoring the vendor ID makes robustly fixing this +by adding compatibles to the spi-nor driver seem problematic, the +current DT binding document does not list all the parts supported by the +driver at the minute (further patches will fix this). + +I've also investigated supporting both formats of modalias +simultaneously but that doesn't seem possible, especially without +breaking our userspace ABI which is obviously not viable. + +Instead revert the relevant changes for now: + +e09f2ab8eecc ("spi: update modalias_show after of_device_uevent_modalias support") +3ce6c9e2617e ("spi: add of_device_uevent_modalias support") + +This will unfortunately mean that any system which had started having +modules autoload based on the OF compatibles for drivers that list +things there but not in the spi_device_ids will now not have those +modules load which is itself a regression. Since it affects a narrower +time window and the particularly problematic spi-nor driver may be +critical to system boot on smaller systems this seems the best of a +series of bad options. I will start an audit of SPI drivers to identify +and fix cases where things won't autoload using spi_device_id, this is +not great but seems to be the best way forward that anyone has been able +to identify. + +Thanks to Russell for both his report and the additional diagnostic and +analysis work he has done here, the detailed research above was his +work. + +Fixes: e09f2ab8eecc ("spi: update modalias_show after of_device_uevent_modalias support") +Fixes: 3ce6c9e2617e ("spi: add of_device_uevent_modalias support") +Reported-by: Russell King (Oracle) +Suggested-by: Russell King (Oracle) +Signed-off-by: Mark Brown +Tested-by: Russell King (Oracle) +Cc: Andreas Schwab +Cc: Marco Felsch +Signed-off-by: Sasha Levin +--- + drivers/spi/spi.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index e4dc593b1f32..f95f7666cb5b 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -58,10 +58,6 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) + const struct spi_device *spi = to_spi_device(dev); + int len; + +- len = of_device_modalias(dev, buf, PAGE_SIZE); +- if (len != -ENODEV) +- return len; +- + len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1); + if (len != -ENODEV) + return len; +@@ -367,10 +363,6 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) + const struct spi_device *spi = to_spi_device(dev); + int rc; + +- rc = of_device_uevent_modalias(dev, env); +- if (rc != -ENODEV) +- return rc; +- + rc = acpi_device_uevent_modalias(dev, env); + if (rc != -ENODEV) + return rc; +-- +2.33.0 + diff --git a/queue-5.14/virtio-net-fix-pages-leaking-when-building-skb-in-bi.patch b/queue-5.14/virtio-net-fix-pages-leaking-when-building-skb-in-bi.patch new file mode 100644 index 00000000000..ae75735cc26 --- /dev/null +++ b/queue-5.14/virtio-net-fix-pages-leaking-when-building-skb-in-bi.patch @@ -0,0 +1,42 @@ +From 9a700429bbb267c9789aafca0ca50763c4104370 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Sep 2021 16:34:06 +0800 +Subject: virtio-net: fix pages leaking when building skb in big mode + +From: Jason Wang + +[ Upstream commit afd92d82c9d715fb97565408755acad81573591a ] + +We try to use build_skb() if we had sufficient tailroom. But we forget +to release the unused pages chained via private in big mode which will +leak pages. Fixing this by release the pages after building the skb in +big mode. + +Cc: Xuan Zhuo +Fixes: fb32856b16ad ("virtio-net: page_to_skb() use build_skb when there's sufficient tailroom") +Signed-off-by: Jason Wang +Reviewed-by: Xuan Zhuo +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index eee493685aad..fb96658bb91f 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -435,6 +435,10 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, + + skb_reserve(skb, p - buf); + skb_put(skb, len); ++ ++ page = (struct page *)page->private; ++ if (page) ++ give_pages(rq, page); + goto ok; + } + +-- +2.33.0 +