From 99f27e945a3f560fa43c28558a07a0a61b704bd3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 21 Apr 2020 19:31:58 +0200 Subject: [PATCH] 5.4-stable patches added patches: afs-fix-afs_d_validate-to-set-the-right-directory-version.patch afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch afs-fix-rename-operation-status-delivery.patch alsa-hda-don-t-release-card-at-firmware-loading-error.patch arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch irqchip-mbigen-free-msi_desc-on-device-teardown.patch kbuild-btf-fix-dependencies-for-debug_info_btf.patch netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch of-unittest-kmemleak-in-of_unittest_platform_populate.patch of-unittest-kmemleak-on-changeset-destroy.patch x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch xsk-add-missing-check-on-user-supplied-headroom-size.patch --- ...e-to-set-the-right-directory-version.patch | 47 +++ ...-codes-from-version-1-status-records.patch | 38 ++ ...in-xdr_decode_-afs-yfs-fsfetchstatus.patch | 122 ++++++ ...on-dir-edit-and-readdir-d_revalidate.patch | 351 ++++++++++++++++++ ...fix-rename-operation-status-delivery.patch | 119 ++++++ ...lease-card-at-firmware-loading-error.patch | 59 +++ ...errupt-controller-to-fix-wake-on-lan.patch | 56 +++ ...reparent_active_queues-in-pd_offline.patch | 65 ++++ ...-actually-work-only-on-leaf-entities.patch | 113 ++++++ ...ocess_ref-in-__bfq_bic_change_cgroup.patch | 62 ++++ ...gen-free-msi_desc-on-device-teardown.patch | 43 +++ ...-fix-dependencies-for-debug_info_btf.patch | 42 +++ ...upp-on-unsupported-flags-object-type.patch | 41 ++ ...memleak-in-dup_and_fixup_symbol_prop.patch | 35 ++ ...ak-in-of_unittest_overlay_high_level.patch | 40 ++ ...eak-in-of_unittest_platform_populate.patch | 44 +++ ...ittest-kmemleak-on-changeset-destroy.patch | 40 ++ queue-5.4/series | 23 ++ ...ata-in-die-when-panic_on_oops-is-set.patch | 94 +++++ ...-or-kmsg-before-running-crash-kernel.patch | 45 +++ ...n-sysctl_record_panic_msg-is-not-set.patch | 77 ++++ ...enment-only-once-during-system-crash.patch | 62 ++++ ...d-vmbus-channel-in-hv-panic-callback.patch | 109 ++++++ ...check-on-user-supplied-headroom-size.patch | 49 +++ 24 files changed, 1776 insertions(+) create mode 100644 queue-5.4/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch create mode 100644 queue-5.4/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch create mode 100644 queue-5.4/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch create mode 100644 queue-5.4/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch create mode 100644 queue-5.4/afs-fix-rename-operation-status-delivery.patch create mode 100644 queue-5.4/alsa-hda-don-t-release-card-at-firmware-loading-error.patch create mode 100644 queue-5.4/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch create mode 100644 queue-5.4/block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch create mode 100644 queue-5.4/block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch create mode 100644 queue-5.4/block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch create mode 100644 queue-5.4/irqchip-mbigen-free-msi_desc-on-device-teardown.patch create mode 100644 queue-5.4/kbuild-btf-fix-dependencies-for-debug_info_btf.patch create mode 100644 queue-5.4/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch create mode 100644 queue-5.4/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch create mode 100644 queue-5.4/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch create mode 100644 queue-5.4/of-unittest-kmemleak-in-of_unittest_platform_populate.patch create mode 100644 queue-5.4/of-unittest-kmemleak-on-changeset-destroy.patch create mode 100644 queue-5.4/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch create mode 100644 queue-5.4/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch create mode 100644 queue-5.4/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch create mode 100644 queue-5.4/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch create mode 100644 queue-5.4/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch create mode 100644 queue-5.4/xsk-add-missing-check-on-user-supplied-headroom-size.patch diff --git a/queue-5.4/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch b/queue-5.4/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch new file mode 100644 index 00000000000..b783f88353a --- /dev/null +++ b/queue-5.4/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch @@ -0,0 +1,47 @@ +From 40fc81027f892284ce31f8b6de1e497f5b47e71f Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Sat, 11 Apr 2020 08:50:45 +0100 +Subject: afs: Fix afs_d_validate() to set the right directory version + +From: David Howells + +commit 40fc81027f892284ce31f8b6de1e497f5b47e71f upstream. + +If a dentry's version is somewhere between invalid_before and the current +directory version, we should be setting it forward to the current version, +not backwards to the invalid_before version. Note that we're only doing +this at all because dentry::d_fsdata isn't large enough on a 32-bit system. + +Fix this by using a separate variable for invalid_before so that we don't +accidentally clobber the current dir version. + +Fixes: a4ff7401fbfa ("afs: Keep track of invalid-before version for dentry coherency") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/dir.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1032,7 +1032,7 @@ static int afs_d_revalidate(struct dentr + struct dentry *parent; + struct inode *inode; + struct key *key; +- afs_dataversion_t dir_version; ++ afs_dataversion_t dir_version, invalid_before; + long de_version; + int ret; + +@@ -1084,8 +1084,8 @@ static int afs_d_revalidate(struct dentr + if (de_version == (long)dir_version) + goto out_valid_noupdate; + +- dir_version = dir->invalid_before; +- if (de_version - (long)dir_version >= 0) ++ invalid_before = dir->invalid_before; ++ if (de_version - (long)invalid_before >= 0) + goto out_valid; + + _debug("dir modified"); diff --git a/queue-5.4/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch b/queue-5.4/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch new file mode 100644 index 00000000000..fc0ba3a71ff --- /dev/null +++ b/queue-5.4/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch @@ -0,0 +1,38 @@ +From 3e0d9892c0e7fa426ca6bf921cb4b543ca265714 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2020 17:32:10 +0100 +Subject: afs: Fix decoding of inline abort codes from version 1 status records + +From: David Howells + +commit 3e0d9892c0e7fa426ca6bf921cb4b543ca265714 upstream. + +If we're decoding an AFSFetchStatus record and we see that the version is 1 +and the abort code is set and we're expecting inline errors, then we store +the abort code and ignore the remaining status record (which is correct), +but we don't set the flag to say we got a valid abort code. + +This can affect operation of YFS.RemoveFile2 when removing a file and the +operation of {,Y}FS.InlineBulkStatus when prospectively constructing or +updating of a set of inodes during a lookup. + +Fix this to indicate the reception of a valid abort code. + +Fixes: a38a75581e6e ("afs: Fix unlink to handle YFS.RemoveFile2 better") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/fsclient.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/afs/fsclient.c ++++ b/fs/afs/fsclient.c +@@ -88,6 +88,7 @@ static int xdr_decode_AFSFetchStatus(con + + if (abort_code != 0 && inline_error) { + status->abort_code = abort_code; ++ scb->have_error = true; + goto good; + } + diff --git a/queue-5.4/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch b/queue-5.4/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch new file mode 100644 index 00000000000..d08716b9aae --- /dev/null +++ b/queue-5.4/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch @@ -0,0 +1,122 @@ +From c72057b56f7e24865840a6961d801a7f21d30a5f Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2020 16:13:20 +0100 +Subject: afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus() + +From: David Howells + +commit c72057b56f7e24865840a6961d801a7f21d30a5f upstream. + +If we receive a status record that has VNOVNODE set in the abort field, +xdr_decode_AFSFetchStatus() and xdr_decode_YFSFetchStatus() don't advance +the XDR pointer, thereby corrupting anything subsequent decodes from the +same block of data. + +This has the potential to affect AFS.InlineBulkStatus and +YFS.InlineBulkStatus operation, but probably doesn't since the status +records are extracted as individual blocks of data and the buffer pointer +is reset between blocks. + +It does affect YFS.RemoveFile2 operation, corrupting the volsync record - +though that is not currently used. + +Other operations abort the entire operation rather than returning an error +inline, in which case there is no decoding to be done. + +Fix this by unconditionally advancing the xdr pointer. + +Fixes: 684b0f68cf1c ("afs: Fix AFSFetchStatus decoder to provide OpenAFS compatibility") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/fsclient.c | 14 +++++++++----- + fs/afs/yfsclient.c | 12 ++++++++---- + 2 files changed, 17 insertions(+), 9 deletions(-) + +--- a/fs/afs/fsclient.c ++++ b/fs/afs/fsclient.c +@@ -65,6 +65,7 @@ static int xdr_decode_AFSFetchStatus(con + bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); + u64 data_version, size; + u32 type, abort_code; ++ int ret; + + abort_code = ntohl(xdr->abort_code); + +@@ -78,7 +79,7 @@ static int xdr_decode_AFSFetchStatus(con + */ + status->abort_code = abort_code; + scb->have_error = true; +- return 0; ++ goto good; + } + + pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); +@@ -87,7 +88,7 @@ static int xdr_decode_AFSFetchStatus(con + + if (abort_code != 0 && inline_error) { + status->abort_code = abort_code; +- return 0; ++ goto good; + } + + type = ntohl(xdr->type); +@@ -123,13 +124,16 @@ static int xdr_decode_AFSFetchStatus(con + data_version |= (u64)ntohl(xdr->data_version_hi) << 32; + status->data_version = data_version; + scb->have_status = true; +- ++good: ++ ret = 0; ++advance: + *_bp = (const void *)*_bp + sizeof(*xdr); +- return 0; ++ return ret; + + bad: + xdr_dump_bad(*_bp); +- return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); ++ ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); ++ goto advance; + } + + static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry) +--- a/fs/afs/yfsclient.c ++++ b/fs/afs/yfsclient.c +@@ -186,13 +186,14 @@ static int xdr_decode_YFSFetchStatus(con + const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp; + struct afs_file_status *status = &scb->status; + u32 type; ++ int ret; + + status->abort_code = ntohl(xdr->abort_code); + if (status->abort_code != 0) { + if (status->abort_code == VNOVNODE) + status->nlink = 0; + scb->have_error = true; +- return 0; ++ goto good; + } + + type = ntohl(xdr->type); +@@ -220,13 +221,16 @@ static int xdr_decode_YFSFetchStatus(con + status->size = xdr_to_u64(xdr->size); + status->data_version = xdr_to_u64(xdr->data_version); + scb->have_status = true; +- ++good: ++ ret = 0; ++advance: + *_bp += xdr_size(xdr); +- return 0; ++ return ret; + + bad: + xdr_dump_bad(*_bp); +- return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); ++ ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status); ++ goto advance; + } + + /* diff --git a/queue-5.4/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch b/queue-5.4/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch new file mode 100644 index 00000000000..9f7c9cf9b68 --- /dev/null +++ b/queue-5.4/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch @@ -0,0 +1,351 @@ +From 2105c2820d366b76f38e6ad61c75771881ecc532 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Fri, 10 Apr 2020 15:23:27 +0100 +Subject: afs: Fix race between post-modification dir edit and readdir/d_revalidate + +From: David Howells + +commit 2105c2820d366b76f38e6ad61c75771881ecc532 upstream. + +AFS directories are retained locally as a structured file, with lookup +being effected by a local search of the file contents. When a modification +(such as mkdir) happens, the dir file content is modified locally rather +than redownloading the directory. + +The directory contents are accessed in a number of ways, with a number of +different locks schemes: + + (1) Download of contents - dvnode->validate_lock/write in afs_read_dir(). + + (2) Lookup and readdir - dvnode->validate_lock/read in afs_dir_iterate(), + downgrading from (1) if necessary. + + (3) d_revalidate of child dentry - dvnode->validate_lock/read in + afs_do_lookup_one() downgrading from (1) if necessary. + + (4) Edit of dir after modification - page locks on individual dir pages. + +Unfortunately, because (4) uses different locking scheme to (1) - (3), +nothing protects against the page being scanned whilst the edit is +underway. Even download is not safe as it doesn't lock the pages - relying +instead on the validate_lock to serialise as a whole (the theory being that +directory contents are treated as a block and always downloaded as a +block). + +Fix this by write-locking dvnode->validate_lock around the edits. Care +must be taken in the rename case as there may be two different dirs - but +they need not be locked at the same time. In any case, once the lock is +taken, the directory version must be rechecked, and the edit skipped if a +later version has been downloaded by revalidation (there can't have been +any local changes because the VFS holds the inode lock, but there can have +been remote changes). + +Fixes: 63a4681ff39c ("afs: Locally edit directory data for mkdir/create/unlink/...") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/dir.c | 91 ++++++++++++++++++++++++++++++++++++----------------- + fs/afs/dir_silly.c | 22 ++++++++---- + 2 files changed, 77 insertions(+), 36 deletions(-) + +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1275,6 +1275,7 @@ static int afs_mkdir(struct inode *dir, + struct afs_fs_cursor fc; + struct afs_vnode *dvnode = AFS_FS_I(dir); + struct key *key; ++ afs_dataversion_t data_version; + int ret; + + mode |= S_IFDIR; +@@ -1295,7 +1296,7 @@ static int afs_mkdir(struct inode *dir, + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t data_version = dvnode->status.data_version + 1; ++ data_version = dvnode->status.data_version + 1; + + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(dvnode); +@@ -1316,10 +1317,14 @@ static int afs_mkdir(struct inode *dir, + goto error_key; + } + +- if (ret == 0 && +- test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) +- afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, +- afs_edit_dir_for_create); ++ if (ret == 0) { ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) ++ afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, ++ afs_edit_dir_for_create); ++ up_write(&dvnode->validate_lock); ++ } + + key_put(key); + kfree(scb); +@@ -1360,6 +1365,7 @@ static int afs_rmdir(struct inode *dir, + struct afs_fs_cursor fc; + struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; + struct key *key; ++ afs_dataversion_t data_version; + int ret; + + _enter("{%llx:%llu},{%pd}", +@@ -1391,7 +1397,7 @@ static int afs_rmdir(struct inode *dir, + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t data_version = dvnode->status.data_version + 1; ++ data_version = dvnode->status.data_version + 1; + + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(dvnode); +@@ -1404,9 +1410,12 @@ static int afs_rmdir(struct inode *dir, + ret = afs_end_vnode_operation(&fc); + if (ret == 0) { + afs_dir_remove_subdir(dentry); +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) + afs_edit_dir_remove(dvnode, &dentry->d_name, + afs_edit_dir_for_rmdir); ++ up_write(&dvnode->validate_lock); + } + } + +@@ -1544,10 +1553,15 @@ static int afs_unlink(struct inode *dir, + ret = afs_end_vnode_operation(&fc); + if (ret == 0 && !(scb[1].have_status || scb[1].have_error)) + ret = afs_dir_remove_link(dvnode, dentry, key); +- if (ret == 0 && +- test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) +- afs_edit_dir_remove(dvnode, &dentry->d_name, +- afs_edit_dir_for_unlink); ++ ++ if (ret == 0) { ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) ++ afs_edit_dir_remove(dvnode, &dentry->d_name, ++ afs_edit_dir_for_unlink); ++ up_write(&dvnode->validate_lock); ++ } + } + + if (need_rehash && ret < 0 && ret != -ENOENT) +@@ -1573,6 +1587,7 @@ static int afs_create(struct inode *dir, + struct afs_status_cb *scb; + struct afs_vnode *dvnode = AFS_FS_I(dir); + struct key *key; ++ afs_dataversion_t data_version; + int ret; + + mode |= S_IFREG; +@@ -1597,7 +1612,7 @@ static int afs_create(struct inode *dir, + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t data_version = dvnode->status.data_version + 1; ++ data_version = dvnode->status.data_version + 1; + + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(dvnode); +@@ -1618,9 +1633,12 @@ static int afs_create(struct inode *dir, + goto error_key; + } + +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) + afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, + afs_edit_dir_for_create); ++ up_write(&dvnode->validate_lock); + + kfree(scb); + key_put(key); +@@ -1648,6 +1666,7 @@ static int afs_link(struct dentry *from, + struct afs_vnode *dvnode = AFS_FS_I(dir); + struct afs_vnode *vnode = AFS_FS_I(d_inode(from)); + struct key *key; ++ afs_dataversion_t data_version; + int ret; + + _enter("{%llx:%llu},{%llx:%llu},{%pd}", +@@ -1672,7 +1691,7 @@ static int afs_link(struct dentry *from, + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t data_version = dvnode->status.data_version + 1; ++ data_version = dvnode->status.data_version + 1; + + if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) { + afs_end_vnode_operation(&fc); +@@ -1702,9 +1721,12 @@ static int afs_link(struct dentry *from, + goto error_key; + } + +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) + afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid, + afs_edit_dir_for_link); ++ up_write(&dvnode->validate_lock); + + key_put(key); + kfree(scb); +@@ -1732,6 +1754,7 @@ static int afs_symlink(struct inode *dir + struct afs_status_cb *scb; + struct afs_vnode *dvnode = AFS_FS_I(dir); + struct key *key; ++ afs_dataversion_t data_version; + int ret; + + _enter("{%llx:%llu},{%pd},%s", +@@ -1759,7 +1782,7 @@ static int afs_symlink(struct inode *dir + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t data_version = dvnode->status.data_version + 1; ++ data_version = dvnode->status.data_version + 1; + + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(dvnode); +@@ -1780,9 +1803,12 @@ static int afs_symlink(struct inode *dir + goto error_key; + } + +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == data_version) + afs_edit_dir_add(dvnode, &dentry->d_name, &iget_data.fid, + afs_edit_dir_for_symlink); ++ up_write(&dvnode->validate_lock); + + key_put(key); + kfree(scb); +@@ -1812,6 +1838,8 @@ static int afs_rename(struct inode *old_ + struct dentry *tmp = NULL, *rehash = NULL; + struct inode *new_inode; + struct key *key; ++ afs_dataversion_t orig_data_version; ++ afs_dataversion_t new_data_version; + bool new_negative = d_is_negative(new_dentry); + int ret; + +@@ -1890,9 +1918,6 @@ static int afs_rename(struct inode *old_ + + ret = -ERESTARTSYS; + if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { +- afs_dataversion_t orig_data_version; +- afs_dataversion_t new_data_version; +- + orig_data_version = orig_dvnode->status.data_version + 1; + + if (orig_dvnode != new_dvnode) { +@@ -1928,18 +1953,25 @@ static int afs_rename(struct inode *old_ + if (ret == 0) { + if (rehash) + d_rehash(rehash); +- if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags)) +- afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, +- afs_edit_dir_for_rename_0); +- +- if (!new_negative && +- test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) +- afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, +- afs_edit_dir_for_rename_1); ++ down_write(&orig_dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) && ++ orig_dvnode->status.data_version == orig_data_version) ++ afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, ++ afs_edit_dir_for_rename_0); ++ if (orig_dvnode != new_dvnode) { ++ up_write(&orig_dvnode->validate_lock); ++ ++ down_write(&new_dvnode->validate_lock); ++ } ++ if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) && ++ orig_dvnode->status.data_version == new_data_version) { ++ if (!new_negative) ++ afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, ++ afs_edit_dir_for_rename_1); + +- if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) + afs_edit_dir_add(new_dvnode, &new_dentry->d_name, + &vnode->fid, afs_edit_dir_for_rename_2); ++ } + + new_inode = d_inode(new_dentry); + if (new_inode) { +@@ -1958,6 +1990,7 @@ static int afs_rename(struct inode *old_ + afs_update_dentry_version(&fc, old_dentry, &scb[1]); + afs_update_dentry_version(&fc, new_dentry, &scb[1]); + d_move(old_dentry, new_dentry); ++ up_write(&new_dvnode->validate_lock); + goto error_tmp; + } + +--- a/fs/afs/dir_silly.c ++++ b/fs/afs/dir_silly.c +@@ -21,6 +21,7 @@ static int afs_do_silly_rename(struct af + { + struct afs_fs_cursor fc; + struct afs_status_cb *scb; ++ afs_dataversion_t dir_data_version; + int ret = -ERESTARTSYS; + + _enter("%pd,%pd", old, new); +@@ -31,7 +32,7 @@ static int afs_do_silly_rename(struct af + + trace_afs_silly_rename(vnode, false); + if (afs_begin_vnode_operation(&fc, dvnode, key, true)) { +- afs_dataversion_t dir_data_version = dvnode->status.data_version + 1; ++ dir_data_version = dvnode->status.data_version + 1; + + while (afs_select_fileserver(&fc)) { + fc.cb_break = afs_calc_vnode_cb_break(dvnode); +@@ -54,12 +55,15 @@ static int afs_do_silly_rename(struct af + dvnode->silly_key = key_get(key); + } + +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == dir_data_version) { + afs_edit_dir_remove(dvnode, &old->d_name, + afs_edit_dir_for_silly_0); +- if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) + afs_edit_dir_add(dvnode, &new->d_name, + &vnode->fid, afs_edit_dir_for_silly_1); ++ } ++ up_write(&dvnode->validate_lock); + } + + kfree(scb); +@@ -181,10 +185,14 @@ static int afs_do_silly_unlink(struct af + clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); + } + } +- if (ret == 0 && +- test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) +- afs_edit_dir_remove(dvnode, &dentry->d_name, +- afs_edit_dir_for_unlink); ++ if (ret == 0) { ++ down_write(&dvnode->validate_lock); ++ if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) && ++ dvnode->status.data_version == dir_data_version) ++ afs_edit_dir_remove(dvnode, &dentry->d_name, ++ afs_edit_dir_for_unlink); ++ up_write(&dvnode->validate_lock); ++ } + } + + kfree(scb); diff --git a/queue-5.4/afs-fix-rename-operation-status-delivery.patch b/queue-5.4/afs-fix-rename-operation-status-delivery.patch new file mode 100644 index 00000000000..1af6c50270d --- /dev/null +++ b/queue-5.4/afs-fix-rename-operation-status-delivery.patch @@ -0,0 +1,119 @@ +From b98f0ec91c42d87a70da42726b852ac8d78a3257 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 8 Apr 2020 20:56:20 +0100 +Subject: afs: Fix rename operation status delivery + +From: David Howells + +commit b98f0ec91c42d87a70da42726b852ac8d78a3257 upstream. + +The afs_deliver_fs_rename() and yfs_deliver_fs_rename() functions both only +decode the second file status returned unless the parent directories are +different - unfortunately, this means that the xdr pointer isn't advanced +and the volsync record will be read incorrectly in such an instance. + +Fix this by always decoding the second status into the second +status/callback block which wasn't being used if the dirs were the same. + +The afs_update_dentry_version() calls that update the directory data +version numbers on the dentries can then unconditionally use the second +status record as this will always reflect the state of the destination dir +(the two records will be identical if the destination dir is the same as +the source dir) + +Fixes: 260a980317da ("[AFS]: Add "directory write" support.") +Fixes: 30062bd13e36 ("afs: Implement YFS support in the fs client") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/dir.c | 13 +++---------- + fs/afs/fsclient.c | 12 ++++++------ + fs/afs/yfsclient.c | 8 +++----- + 3 files changed, 12 insertions(+), 21 deletions(-) + +--- a/fs/afs/dir.c ++++ b/fs/afs/dir.c +@@ -1892,7 +1892,6 @@ static int afs_rename(struct inode *old_ + if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) { + afs_dataversion_t orig_data_version; + afs_dataversion_t new_data_version; +- struct afs_status_cb *new_scb = &scb[1]; + + orig_data_version = orig_dvnode->status.data_version + 1; + +@@ -1904,7 +1903,6 @@ static int afs_rename(struct inode *old_ + new_data_version = new_dvnode->status.data_version + 1; + } else { + new_data_version = orig_data_version; +- new_scb = &scb[0]; + } + + while (afs_select_fileserver(&fc)) { +@@ -1912,7 +1910,7 @@ static int afs_rename(struct inode *old_ + fc.cb_break_2 = afs_calc_vnode_cb_break(new_dvnode); + afs_fs_rename(&fc, old_dentry->d_name.name, + new_dvnode, new_dentry->d_name.name, +- &scb[0], new_scb); ++ &scb[0], &scb[1]); + } + + afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break, +@@ -1957,13 +1955,8 @@ static int afs_rename(struct inode *old_ + * Note that if we ever implement RENAME_EXCHANGE, we'll have + * to update both dentries with opposing dir versions. + */ +- if (new_dvnode != orig_dvnode) { +- afs_update_dentry_version(&fc, old_dentry, &scb[1]); +- afs_update_dentry_version(&fc, new_dentry, &scb[1]); +- } else { +- afs_update_dentry_version(&fc, old_dentry, &scb[0]); +- afs_update_dentry_version(&fc, new_dentry, &scb[0]); +- } ++ afs_update_dentry_version(&fc, old_dentry, &scb[1]); ++ afs_update_dentry_version(&fc, new_dentry, &scb[1]); + d_move(old_dentry, new_dentry); + goto error_tmp; + } +--- a/fs/afs/fsclient.c ++++ b/fs/afs/fsclient.c +@@ -988,16 +988,16 @@ static int afs_deliver_fs_rename(struct + if (ret < 0) + return ret; + +- /* unmarshall the reply once we've received all of it */ ++ /* If the two dirs are the same, we have two copies of the same status ++ * report, so we just decode it twice. ++ */ + bp = call->buffer; + ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb); + if (ret < 0) + return ret; +- if (call->out_dir_scb != call->out_scb) { +- ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); +- if (ret < 0) +- return ret; +- } ++ ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb); ++ if (ret < 0) ++ return ret; + xdr_decode_AFSVolSync(&bp, call->out_volsync); + + _leave(" = 0 [done]"); +--- a/fs/afs/yfsclient.c ++++ b/fs/afs/yfsclient.c +@@ -1158,11 +1158,9 @@ static int yfs_deliver_fs_rename(struct + ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb); + if (ret < 0) + return ret; +- if (call->out_dir_scb != call->out_scb) { +- ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); +- if (ret < 0) +- return ret; +- } ++ ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb); ++ if (ret < 0) ++ return ret; + + xdr_decode_YFSVolSync(&bp, call->out_volsync); + _leave(" = 0 [done]"); diff --git a/queue-5.4/alsa-hda-don-t-release-card-at-firmware-loading-error.patch b/queue-5.4/alsa-hda-don-t-release-card-at-firmware-loading-error.patch new file mode 100644 index 00000000000..18d1b36e2c9 --- /dev/null +++ b/queue-5.4/alsa-hda-don-t-release-card-at-firmware-loading-error.patch @@ -0,0 +1,59 @@ +From 25faa4bd37c10f19e4b848b9032a17a3d44c6f09 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 13 Apr 2020 10:20:29 +0200 +Subject: ALSA: hda: Don't release card at firmware loading error + +From: Takashi Iwai + +commit 25faa4bd37c10f19e4b848b9032a17a3d44c6f09 upstream. + +At the error path of the firmware loading error, the driver tries to +release the card object and set NULL to drvdata. This may be referred +badly at the possible PM action, as the driver itself is still bound +and the PM callbacks read the card object. + +Instead, we continue the probing as if it were no option set. This is +often a better choice than the forced abort, too. + +Fixes: 5cb543dba986 ("ALSA: hda - Deferred probing with request_firmware_nowait()") +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207043 +Link: https://lore.kernel.org/r/20200413082034.25166-2-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/hda_intel.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -1980,24 +1980,15 @@ static void azx_firmware_cb(const struct + { + struct snd_card *card = context; + struct azx *chip = card->private_data; +- struct pci_dev *pci = chip->pci; + +- if (!fw) { +- dev_err(card->dev, "Cannot load firmware, aborting\n"); +- goto error; +- } +- +- chip->fw = fw; ++ if (fw) ++ chip->fw = fw; ++ else ++ dev_err(card->dev, "Cannot load firmware, continue without patching\n"); + if (!chip->disabled) { + /* continue probing */ +- if (azx_probe_continue(chip)) +- goto error; ++ azx_probe_continue(chip); + } +- return; /* OK */ +- +- error: +- snd_card_free(card); +- pci_set_drvdata(pci, NULL); + } + #endif + diff --git a/queue-5.4/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch b/queue-5.4/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch new file mode 100644 index 00000000000..5e669edb0e8 --- /dev/null +++ b/queue-5.4/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch @@ -0,0 +1,56 @@ +From 4141f1a40fc0789f6fd4330e171e1edf155426aa Mon Sep 17 00:00:00 2001 +From: Martin Fuzzey +Date: Thu, 2 Apr 2020 15:51:28 +0200 +Subject: ARM: dts: imx6: Use gpc for FEC interrupt controller to fix wake on LAN. + +From: Martin Fuzzey + +commit 4141f1a40fc0789f6fd4330e171e1edf155426aa upstream. + +In order to wake from suspend by ethernet magic packets the GPC +must be used as intc does not have wakeup functionality. + +But the FEC DT node currently uses interrupt-extended, +specificying intc, thus breaking WoL. + +This problem is probably fallout from the stacked domain conversion +as intc used to chain to GPC. + +So replace "interrupts-extended" by "interrupts" to use the default +parent which is GPC. + +Fixes: b923ff6af0d5 ("ARM: imx6: convert GPC to stacked domains") + +Signed-off-by: Martin Fuzzey +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/imx6qdl.dtsi | 5 ++--- + arch/arm/boot/dts/imx6qp.dtsi | 1 - + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/arch/arm/boot/dts/imx6qdl.dtsi ++++ b/arch/arm/boot/dts/imx6qdl.dtsi +@@ -1039,9 +1039,8 @@ + compatible = "fsl,imx6q-fec"; + reg = <0x02188000 0x4000>; + interrupt-names = "int0", "pps"; +- interrupts-extended = +- <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>, +- <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; ++ interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, ++ <0 119 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET_REF>; +--- a/arch/arm/boot/dts/imx6qp.dtsi ++++ b/arch/arm/boot/dts/imx6qp.dtsi +@@ -77,7 +77,6 @@ + }; + + &fec { +- /delete-property/interrupts-extended; + interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, + <0 119 IRQ_TYPE_LEVEL_HIGH>; + }; diff --git a/queue-5.4/block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch b/queue-5.4/block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch new file mode 100644 index 00000000000..456494d0cb8 --- /dev/null +++ b/queue-5.4/block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch @@ -0,0 +1,65 @@ +From 4d38a87fbb77fb9ff2ff4e914162a8ae6453eff5 Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Sat, 21 Mar 2020 10:45:21 +0100 +Subject: block, bfq: invoke flush_idle_tree after reparent_active_queues in pd_offline + +From: Paolo Valente + +commit 4d38a87fbb77fb9ff2ff4e914162a8ae6453eff5 upstream. + +In bfq_pd_offline(), the function bfq_flush_idle_tree() is invoked to +flush the rb tree that contains all idle entities belonging to the pd +(cgroup) being destroyed. In particular, bfq_flush_idle_tree() is +invoked before bfq_reparent_active_queues(). Yet the latter may happen +to add some entities to the idle tree. It happens if, in some of the +calls to bfq_bfqq_move() performed by bfq_reparent_active_queues(), +the queue to move is empty and gets expired. + +This commit simply reverses the invocation order between +bfq_flush_idle_tree() and bfq_reparent_active_queues(). + +Tested-by: cki-project@redhat.com +Signed-off-by: Paolo Valente +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/bfq-cgroup.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +--- a/block/bfq-cgroup.c ++++ b/block/bfq-cgroup.c +@@ -877,13 +877,6 @@ static void bfq_pd_offline(struct blkg_p + st = bfqg->sched_data.service_tree + i; + + /* +- * The idle tree may still contain bfq_queues belonging +- * to exited task because they never migrated to a different +- * cgroup from the one being destroyed now. +- */ +- bfq_flush_idle_tree(st); +- +- /* + * It may happen that some queues are still active + * (busy) upon group destruction (if the corresponding + * processes have been forced to terminate). We move +@@ -896,6 +889,19 @@ static void bfq_pd_offline(struct blkg_p + * scheduler has taken no reference. + */ + bfq_reparent_active_queues(bfqd, bfqg, st, i); ++ ++ /* ++ * The idle tree may still contain bfq_queues ++ * belonging to exited task because they never ++ * migrated to a different cgroup from the one being ++ * destroyed now. In addition, even ++ * bfq_reparent_active_queues() may happen to add some ++ * entities to the idle tree. It happens if, in some ++ * of the calls to bfq_bfqq_move() performed by ++ * bfq_reparent_active_queues(), the queue to move is ++ * empty and gets expired. ++ */ ++ bfq_flush_idle_tree(st); + } + + __bfq_deactivate_entity(entity, false); diff --git a/queue-5.4/block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch b/queue-5.4/block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch new file mode 100644 index 00000000000..c6781d8ec7f --- /dev/null +++ b/queue-5.4/block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch @@ -0,0 +1,113 @@ +From 576682fa52cbd95deb3773449566274f206acc58 Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Sat, 21 Mar 2020 10:45:20 +0100 +Subject: block, bfq: make reparent_leaf_entity actually work only on leaf entities + +From: Paolo Valente + +commit 576682fa52cbd95deb3773449566274f206acc58 upstream. + +bfq_reparent_leaf_entity() reparents the input leaf entity (a leaf +entity represents just a bfq_queue in an entity tree). Yet, the input +entity is guaranteed to always be a leaf entity only in two-level +entity trees. In this respect, because of the error fixed by +commit 14afc5936197 ("block, bfq: fix overwrite of bfq_group pointer +in bfq_find_set_group()"), all (wrongly collapsed) entity trees happened +to actually have only two levels. After the latter commit, this does not +hold any longer. + +This commit fixes this problem by modifying +bfq_reparent_leaf_entity(), so that it searches an active leaf entity +down the path that stems from the input entity. Such a leaf entity is +guaranteed to exist when bfq_reparent_leaf_entity() is invoked. + +Tested-by: cki-project@redhat.com +Signed-off-by: Paolo Valente +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/bfq-cgroup.c | 48 +++++++++++++++++++++++++++++++----------------- + 1 file changed, 31 insertions(+), 17 deletions(-) + +--- a/block/bfq-cgroup.c ++++ b/block/bfq-cgroup.c +@@ -798,39 +798,53 @@ static void bfq_flush_idle_tree(struct b + /** + * bfq_reparent_leaf_entity - move leaf entity to the root_group. + * @bfqd: the device data structure with the root group. +- * @entity: the entity to move. ++ * @entity: the entity to move, if entity is a leaf; or the parent entity ++ * of an active leaf entity to move, if entity is not a leaf. + */ + static void bfq_reparent_leaf_entity(struct bfq_data *bfqd, +- struct bfq_entity *entity) ++ struct bfq_entity *entity, ++ int ioprio_class) + { +- struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_queue *bfqq; ++ struct bfq_entity *child_entity = entity; + ++ while (child_entity->my_sched_data) { /* leaf not reached yet */ ++ struct bfq_sched_data *child_sd = child_entity->my_sched_data; ++ struct bfq_service_tree *child_st = child_sd->service_tree + ++ ioprio_class; ++ struct rb_root *child_active = &child_st->active; ++ ++ child_entity = bfq_entity_of(rb_first(child_active)); ++ ++ if (!child_entity) ++ child_entity = child_sd->in_service_entity; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(child_entity); + bfq_bfqq_move(bfqd, bfqq, bfqd->root_group); + } + + /** +- * bfq_reparent_active_entities - move to the root group all active +- * entities. ++ * bfq_reparent_active_queues - move to the root group all active queues. + * @bfqd: the device data structure with the root group. + * @bfqg: the group to move from. +- * @st: the service tree with the entities. ++ * @st: the service tree to start the search from. + */ +-static void bfq_reparent_active_entities(struct bfq_data *bfqd, +- struct bfq_group *bfqg, +- struct bfq_service_tree *st) ++static void bfq_reparent_active_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st, ++ int ioprio_class) + { + struct rb_root *active = &st->active; +- struct bfq_entity *entity = NULL; +- +- if (!RB_EMPTY_ROOT(&st->active)) +- entity = bfq_entity_of(rb_first(active)); ++ struct bfq_entity *entity; + +- for (; entity ; entity = bfq_entity_of(rb_first(active))) +- bfq_reparent_leaf_entity(bfqd, entity); ++ while ((entity = bfq_entity_of(rb_first(active)))) ++ bfq_reparent_leaf_entity(bfqd, entity, ioprio_class); + + if (bfqg->sched_data.in_service_entity) + bfq_reparent_leaf_entity(bfqd, +- bfqg->sched_data.in_service_entity); ++ bfqg->sched_data.in_service_entity, ++ ioprio_class); + } + + /** +@@ -881,7 +895,7 @@ static void bfq_pd_offline(struct blkg_p + * There is no need to put the sync queues, as the + * scheduler has taken no reference. + */ +- bfq_reparent_active_entities(bfqd, bfqg, st); ++ bfq_reparent_active_queues(bfqd, bfqg, st, i); + } + + __bfq_deactivate_entity(entity, false); diff --git a/queue-5.4/block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch b/queue-5.4/block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch new file mode 100644 index 00000000000..f432c75489d --- /dev/null +++ b/queue-5.4/block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch @@ -0,0 +1,62 @@ +From c8997736650060594845e42c5d01d3118aec8d25 Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Sat, 21 Mar 2020 10:45:19 +0100 +Subject: block, bfq: turn put_queue into release_process_ref in __bfq_bic_change_cgroup + +From: Paolo Valente + +commit c8997736650060594845e42c5d01d3118aec8d25 upstream. + +A bfq_put_queue() may be invoked in __bfq_bic_change_cgroup(). The +goal of this put is to release a process reference to a bfq_queue. But +process-reference releases may trigger also some extra operation, and, +to this goal, are handled through bfq_release_process_ref(). So, turn +the invocation of bfq_put_queue() into an invocation of +bfq_release_process_ref(). + +Tested-by: cki-project@redhat.com +Signed-off-by: Paolo Valente +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/bfq-cgroup.c | 5 +---- + block/bfq-iosched.c | 2 -- + block/bfq-iosched.h | 1 + + 3 files changed, 2 insertions(+), 6 deletions(-) + +--- a/block/bfq-cgroup.c ++++ b/block/bfq-cgroup.c +@@ -697,10 +697,7 @@ static struct bfq_group *__bfq_bic_chang + + if (entity->sched_data != &bfqg->sched_data) { + bic_set_bfqq(bic, NULL, 0); +- bfq_log_bfqq(bfqd, async_bfqq, +- "bic_change_group: %p %d", +- async_bfqq, async_bfqq->ref); +- bfq_put_queue(async_bfqq); ++ bfq_release_process_ref(bfqd, async_bfqq); + } + } + +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -2717,8 +2717,6 @@ static void bfq_bfqq_save_state(struct b + } + } + +- +-static + void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq) + { + /* +--- a/block/bfq-iosched.h ++++ b/block/bfq-iosched.h +@@ -950,6 +950,7 @@ void bfq_bfqq_expire(struct bfq_data *bf + bool compensate, enum bfqq_expiration reason); + void bfq_put_queue(struct bfq_queue *bfqq); + void bfq_end_wr_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq); + void bfq_schedule_dispatch(struct bfq_data *bfqd); + void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); + diff --git a/queue-5.4/irqchip-mbigen-free-msi_desc-on-device-teardown.patch b/queue-5.4/irqchip-mbigen-free-msi_desc-on-device-teardown.patch new file mode 100644 index 00000000000..c32019a06b8 --- /dev/null +++ b/queue-5.4/irqchip-mbigen-free-msi_desc-on-device-teardown.patch @@ -0,0 +1,43 @@ +From edfc23f6f9fdbd7825d50ac1f380243cde19b679 Mon Sep 17 00:00:00 2001 +From: Zenghui Yu +Date: Wed, 8 Apr 2020 19:43:52 +0800 +Subject: irqchip/mbigen: Free msi_desc on device teardown + +From: Zenghui Yu + +commit edfc23f6f9fdbd7825d50ac1f380243cde19b679 upstream. + +Using irq_domain_free_irqs_common() on the irqdomain free path will +leave the MSI descriptor unfreed when platform devices get removed. +Properly free it by MSI domain free function. + +Fixes: 9650c60ebfec0 ("irqchip/mbigen: Create irq domain for each mbigen device") +Signed-off-by: Zenghui Yu +Signed-off-by: Marc Zyngier +Link: https://lore.kernel.org/r/20200408114352.1604-1-yuzenghui@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-mbigen.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-mbigen.c ++++ b/drivers/irqchip/irq-mbigen.c +@@ -220,10 +220,16 @@ static int mbigen_irq_domain_alloc(struc + return 0; + } + ++static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq, ++ unsigned int nr_irqs) ++{ ++ platform_msi_domain_free(domain, virq, nr_irqs); ++} ++ + static const struct irq_domain_ops mbigen_domain_ops = { + .translate = mbigen_domain_translate, + .alloc = mbigen_irq_domain_alloc, +- .free = irq_domain_free_irqs_common, ++ .free = mbigen_irq_domain_free, + }; + + static int mbigen_of_create_domain(struct platform_device *pdev, diff --git a/queue-5.4/kbuild-btf-fix-dependencies-for-debug_info_btf.patch b/queue-5.4/kbuild-btf-fix-dependencies-for-debug_info_btf.patch new file mode 100644 index 00000000000..455677c48d6 --- /dev/null +++ b/queue-5.4/kbuild-btf-fix-dependencies-for-debug_info_btf.patch @@ -0,0 +1,42 @@ +From 7d32e69310d67e6b04af04f26193f79dfc2f05c7 Mon Sep 17 00:00:00 2001 +From: Slava Bacherikov +Date: Thu, 2 Apr 2020 23:41:39 +0300 +Subject: kbuild, btf: Fix dependencies for DEBUG_INFO_BTF + +From: Slava Bacherikov + +commit 7d32e69310d67e6b04af04f26193f79dfc2f05c7 upstream. + +Currently turning on DEBUG_INFO_SPLIT when DEBUG_INFO_BTF is also +enabled will produce invalid btf file, since gen_btf function in +link-vmlinux.sh script doesn't handle *.dwo files. + +Enabling DEBUG_INFO_REDUCED will also produce invalid btf file, +and using GCC_PLUGIN_RANDSTRUCT with BTF makes no sense. + +Fixes: e83b9f55448a ("kbuild: add ability to generate BTF type info for vmlinux") +Reported-by: Jann Horn +Reported-by: Liu Yiding +Signed-off-by: Slava Bacherikov +Signed-off-by: Daniel Borkmann +Reviewed-by: Kees Cook +Acked-by: KP Singh +Acked-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20200402204138.408021-1-slava@bacher09.org +Signed-off-by: Greg Kroah-Hartman + +--- + lib/Kconfig.debug | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -223,6 +223,8 @@ config DEBUG_INFO_DWARF4 + config DEBUG_INFO_BTF + bool "Generate BTF typeinfo" + depends on DEBUG_INFO ++ depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED ++ depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST + help + Generate deduplicated BTF type information from DWARF debug info. + Turning this on expects presence of pahole tool, which will convert diff --git a/queue-5.4/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch b/queue-5.4/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch new file mode 100644 index 00000000000..1c22f3b3e14 --- /dev/null +++ b/queue-5.4/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch @@ -0,0 +1,41 @@ +From d9583cdf2f38d0f526d9a8c8564dd2e35e649bc7 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Tue, 7 Apr 2020 14:10:11 +0200 +Subject: netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type + +From: Pablo Neira Ayuso + +commit d9583cdf2f38d0f526d9a8c8564dd2e35e649bc7 upstream. + +EINVAL should be used for malformed netlink messages. New userspace +utility and old kernels might easily result in EINVAL when exercising +new set features, which is misleading. + +Fixes: 8aeff920dcc9 ("netfilter: nf_tables: add stateful object reference to set elements") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_api.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3598,7 +3598,7 @@ static int nf_tables_newset(struct net * + NFT_SET_INTERVAL | NFT_SET_TIMEOUT | + NFT_SET_MAP | NFT_SET_EVAL | + NFT_SET_OBJECT)) +- return -EINVAL; ++ return -EOPNOTSUPP; + /* Only one of these operations is supported */ + if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) == + (NFT_SET_MAP | NFT_SET_OBJECT)) +@@ -3636,7 +3636,7 @@ static int nf_tables_newset(struct net * + objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE])); + if (objtype == NFT_OBJECT_UNSPEC || + objtype > NFT_OBJECT_MAX) +- return -EINVAL; ++ return -EOPNOTSUPP; + } else if (flags & NFT_SET_OBJECT) + return -EINVAL; + else diff --git a/queue-5.4/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch b/queue-5.4/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch new file mode 100644 index 00000000000..9fb37b16294 --- /dev/null +++ b/queue-5.4/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch @@ -0,0 +1,35 @@ +From 478ff649b1c8eb2409b1a54fb75eb46f7c29f140 Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Thu, 16 Apr 2020 16:42:49 -0500 +Subject: of: overlay: kmemleak in dup_and_fixup_symbol_prop() + +From: Frank Rowand + +commit 478ff649b1c8eb2409b1a54fb75eb46f7c29f140 upstream. + +kmemleak reports several memory leaks from devicetree unittest. +This is the fix for problem 4 of 5. + +target_path was not freed in the non-error path. + +Fixes: e0a58f3e08d4 ("of: overlay: remove a dependency on device node full_name") +Reported-by: Erhard F. +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/overlay.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -261,6 +261,8 @@ static struct property *dup_and_fixup_sy + + of_property_set_flag(new_prop, OF_DYNAMIC); + ++ kfree(target_path); ++ + return new_prop; + + err_free_new_prop: diff --git a/queue-5.4/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch b/queue-5.4/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch new file mode 100644 index 00000000000..b9dc352917e --- /dev/null +++ b/queue-5.4/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch @@ -0,0 +1,40 @@ +From 145fc138f9aae4f9e1331352e301df28e16aed35 Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Thu, 16 Apr 2020 16:42:48 -0500 +Subject: of: unittest: kmemleak in of_unittest_overlay_high_level() + +From: Frank Rowand + +commit 145fc138f9aae4f9e1331352e301df28e16aed35 upstream. + +kmemleak reports several memory leaks from devicetree unittest. +This is the fix for problem 3 of 5. + +of_unittest_overlay_high_level() failed to kfree the newly created +property when the property named 'name' is skipped. + +Fixes: 39a751a4cb7e ("of: change overlay apply input data from unflattened to FDT") +Reported-by: Erhard F. +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/unittest.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -2481,8 +2481,11 @@ static __init void of_unittest_overlay_h + goto err_unlock; + } + if (__of_add_property(of_symbols, new_prop)) { ++ kfree(new_prop->name); ++ kfree(new_prop->value); ++ kfree(new_prop); + /* "name" auto-generated by unflatten */ +- if (!strcmp(new_prop->name, "name")) ++ if (!strcmp(prop->name, "name")) + continue; + unittest(0, "duplicate property '%s' in overlay_base node __symbols__", + prop->name); diff --git a/queue-5.4/of-unittest-kmemleak-in-of_unittest_platform_populate.patch b/queue-5.4/of-unittest-kmemleak-in-of_unittest_platform_populate.patch new file mode 100644 index 00000000000..03e1b7f7f9b --- /dev/null +++ b/queue-5.4/of-unittest-kmemleak-in-of_unittest_platform_populate.patch @@ -0,0 +1,44 @@ +From 216830d2413cc61be3f76bc02ffd905e47d2439e Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Thu, 16 Apr 2020 16:42:47 -0500 +Subject: of: unittest: kmemleak in of_unittest_platform_populate() + +From: Frank Rowand + +commit 216830d2413cc61be3f76bc02ffd905e47d2439e upstream. + +kmemleak reports several memory leaks from devicetree unittest. +This is the fix for problem 2 of 5. + +of_unittest_platform_populate() left an elevated reference count for +grandchild nodes (which are platform devices). Fix the platform +device reference counts so that the memory will be freed. + +Fixes: fb2caa50fbac ("of/selftest: add testcase for nodes with same name and address") +Reported-by: Erhard F. +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/unittest.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -1065,10 +1065,13 @@ static void __init of_unittest_platform_ + + of_platform_populate(np, match, NULL, &test_bus->dev); + for_each_child_of_node(np, child) { +- for_each_child_of_node(child, grandchild) +- unittest(of_find_device_by_node(grandchild), ++ for_each_child_of_node(child, grandchild) { ++ pdev = of_find_device_by_node(grandchild); ++ unittest(pdev, + "Could not create device for node '%pOFn'\n", + grandchild); ++ of_dev_put(pdev); ++ } + } + + of_platform_depopulate(&test_bus->dev); diff --git a/queue-5.4/of-unittest-kmemleak-on-changeset-destroy.patch b/queue-5.4/of-unittest-kmemleak-on-changeset-destroy.patch new file mode 100644 index 00000000000..b42529bb87b --- /dev/null +++ b/queue-5.4/of-unittest-kmemleak-on-changeset-destroy.patch @@ -0,0 +1,40 @@ +From b3fb36ed694b05738d45218ea72cf7feb10ce2b1 Mon Sep 17 00:00:00 2001 +From: Frank Rowand +Date: Thu, 16 Apr 2020 16:42:46 -0500 +Subject: of: unittest: kmemleak on changeset destroy + +From: Frank Rowand + +commit b3fb36ed694b05738d45218ea72cf7feb10ce2b1 upstream. + +kmemleak reports several memory leaks from devicetree unittest. +This is the fix for problem 1 of 5. + +of_unittest_changeset() reaches deeply into the dynamic devicetree +functions. Several nodes were left with an elevated reference +count and thus were not properly cleaned up. Fix the reference +counts so that the memory will be freed. + +Fixes: 201c910bd689 ("of: Transactional DT support.") +Reported-by: Erhard F. +Signed-off-by: Frank Rowand +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/unittest.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -776,6 +776,10 @@ static void __init of_unittest_changeset + unittest(!of_changeset_revert(&chgset), "revert failed\n"); + + of_changeset_destroy(&chgset); ++ ++ of_node_put(n1); ++ of_node_put(n2); ++ of_node_put(n21); + #endif + } + diff --git a/queue-5.4/series b/queue-5.4/series index 99f57d66ff3..804f71fa76a 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -6,3 +6,26 @@ arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch objtool-fix-switch-table-detection-in-.text.unlikely.patch scsi-sg-add-sg_remove_request-in-sg_common_write.patch alsa-hda-honor-pm-disablement-in-pm-freeze-and-thaw_noirq-ops.patch +arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch +kbuild-btf-fix-dependencies-for-debug_info_btf.patch +netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch +irqchip-mbigen-free-msi_desc-on-device-teardown.patch +alsa-hda-don-t-release-card-at-firmware-loading-error.patch +xsk-add-missing-check-on-user-supplied-headroom-size.patch +of-unittest-kmemleak-on-changeset-destroy.patch +of-unittest-kmemleak-in-of_unittest_platform_populate.patch +of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch +of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch +x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch +x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch +x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch +x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch +x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch +afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch +afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch +afs-fix-rename-operation-status-delivery.patch +afs-fix-afs_d_validate-to-set-the-right-directory-version.patch +afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch +block-bfq-turn-put_queue-into-release_process_ref-in-__bfq_bic_change_cgroup.patch +block-bfq-make-reparent_leaf_entity-actually-work-only-on-leaf-entities.patch +block-bfq-invoke-flush_idle_tree-after-reparent_active_queues-in-pd_offline.patch diff --git a/queue-5.4/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch b/queue-5.4/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch new file mode 100644 index 00000000000..86ba74d459b --- /dev/null +++ b/queue-5.4/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch @@ -0,0 +1,94 @@ +From f3a99e761efa616028b255b4de58e9b5b87c5545 Mon Sep 17 00:00:00 2001 +From: Tianyu Lan +Date: Mon, 6 Apr 2020 08:53:31 -0700 +Subject: x86/Hyper-V: Report crash data in die() when panic_on_oops is set + +From: Tianyu Lan + +commit f3a99e761efa616028b255b4de58e9b5b87c5545 upstream. + +When oops happens with panic_on_oops unset, the oops +thread is killed by die() and system continues to run. +In such case, guest should not report crash register +data to host since system still runs. Check panic_on_oops +and return directly in hyperv_report_panic() when the function +is called in the die() and panic_on_oops is unset. Fix it. + +Fixes: 7ed4325a44ea ("Drivers: hv: vmbus: Make panic reporting to be more useful") +Signed-off-by: Tianyu Lan +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/20200406155331.2105-7-Tianyu.Lan@microsoft.com +Signed-off-by: Wei Liu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/hyperv/hv_init.c | 6 +++++- + drivers/hv/vmbus_drv.c | 5 +++-- + include/asm-generic/mshyperv.h | 2 +- + 3 files changed, 9 insertions(+), 4 deletions(-) + +--- a/arch/x86/hyperv/hv_init.c ++++ b/arch/x86/hyperv/hv_init.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -354,11 +355,14 @@ void hyperv_cleanup(void) + } + EXPORT_SYMBOL_GPL(hyperv_cleanup); + +-void hyperv_report_panic(struct pt_regs *regs, long err) ++void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) + { + static bool panic_reported; + u64 guest_id; + ++ if (in_die && !panic_on_oops) ++ return; ++ + /* + * We prefer to report panic on 'die' chain as we have proper + * registers to report, but if we miss it (e.g. on BUG()) we need +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include "hyperv_vmbus.h" +@@ -75,7 +76,7 @@ static int hyperv_panic_event(struct not + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE + && hyperv_report_reg()) { + regs = current_pt_regs(); +- hyperv_report_panic(regs, val); ++ hyperv_report_panic(regs, val, false); + } + return NOTIFY_DONE; + } +@@ -92,7 +93,7 @@ static int hyperv_die_event(struct notif + * the notification here. + */ + if (hyperv_report_reg()) +- hyperv_report_panic(regs, val); ++ hyperv_report_panic(regs, val, true); + return NOTIFY_DONE; + } + +--- a/include/asm-generic/mshyperv.h ++++ b/include/asm-generic/mshyperv.h +@@ -163,7 +163,7 @@ static inline int cpumask_to_vpset(struc + return nr_bank; + } + +-void hyperv_report_panic(struct pt_regs *regs, long err); ++void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die); + void hyperv_report_panic_msg(phys_addr_t pa, size_t size); + bool hv_is_hyperv_initialized(void); + void hyperv_cleanup(void); diff --git a/queue-5.4/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch b/queue-5.4/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch new file mode 100644 index 00000000000..192c3921b55 --- /dev/null +++ b/queue-5.4/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch @@ -0,0 +1,45 @@ +From a11589563e96bf262767294b89b25a9d44e7303b Mon Sep 17 00:00:00 2001 +From: Tianyu Lan +Date: Mon, 6 Apr 2020 08:53:29 -0700 +Subject: x86/Hyper-V: Report crash register data or kmsg before running crash kernel + +From: Tianyu Lan + +commit a11589563e96bf262767294b89b25a9d44e7303b upstream. + +We want to notify Hyper-V when a Linux guest VM crash occurs, so +there is a record of the crash even when kdump is enabled. But +crash_kexec_post_notifiers defaults to "false", so the kdump kernel +runs before the notifiers and Hyper-V never gets notified. Fix this by +always setting crash_kexec_post_notifiers to be true for Hyper-V VMs. + +Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") +Reviewed-by: Michael Kelley +Signed-off-by: Tianyu Lan +Link: https://lore.kernel.org/r/20200406155331.2105-5-Tianyu.Lan@microsoft.com +Signed-off-by: Wei Liu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/mshyperv.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -263,6 +263,16 @@ static void __init ms_hyperv_init_platfo + cpuid_eax(HYPERV_CPUID_NESTED_FEATURES); + } + ++ /* ++ * Hyper-V expects to get crash register data or kmsg when ++ * crash enlightment is available and system crashes. Set ++ * crash_kexec_post_notifiers to be true to make sure that ++ * calling crash enlightment interface before running kdump ++ * kernel. ++ */ ++ if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) ++ crash_kexec_post_notifiers = true; ++ + #ifdef CONFIG_X86_LOCAL_APIC + if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && + ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { diff --git a/queue-5.4/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch b/queue-5.4/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch new file mode 100644 index 00000000000..e9599c91d8c --- /dev/null +++ b/queue-5.4/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch @@ -0,0 +1,77 @@ +From 040026df7088c56ccbad28f7042308f67bde63df Mon Sep 17 00:00:00 2001 +From: Tianyu Lan +Date: Mon, 6 Apr 2020 08:53:30 -0700 +Subject: x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not set + +From: Tianyu Lan + +commit 040026df7088c56ccbad28f7042308f67bde63df upstream. + +When sysctl_record_panic_msg is not set, the panic will +not be reported to Hyper-V via hyperv_report_panic_msg(). +So the crash should be reported via hyperv_report_panic(). + +Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") +Reviewed-by: Michael Kelley +Signed-off-by: Tianyu Lan +Link: https://lore.kernel.org/r/20200406155331.2105-6-Tianyu.Lan@microsoft.com +Signed-off-by: Wei Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/vmbus_drv.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -48,6 +48,18 @@ static int hyperv_cpuhp_online; + + static void *hv_panic_page; + ++/* ++ * Boolean to control whether to report panic messages over Hyper-V. ++ * ++ * It can be set via /proc/sys/kernel/hyperv/record_panic_msg ++ */ ++static int sysctl_record_panic_msg = 1; ++ ++static int hyperv_report_reg(void) ++{ ++ return !sysctl_record_panic_msg || !hv_panic_page; ++} ++ + static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, + void *args) + { +@@ -61,7 +73,7 @@ static int hyperv_panic_event(struct not + * the notification here. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE +- && !hv_panic_page) { ++ && hyperv_report_reg()) { + regs = current_pt_regs(); + hyperv_report_panic(regs, val); + } +@@ -79,7 +91,7 @@ static int hyperv_die_event(struct notif + * doing hyperv_report_panic_msg() later with kmsg data, don't do + * the notification here. + */ +- if (!hv_panic_page) ++ if (hyperv_report_reg()) + hyperv_report_panic(regs, val); + return NOTIFY_DONE; + } +@@ -1262,13 +1274,6 @@ static void vmbus_isr(void) + } + + /* +- * Boolean to control whether to report panic messages over Hyper-V. +- * +- * It can be set via /proc/sys/kernel/hyperv/record_panic_msg +- */ +-static int sysctl_record_panic_msg = 1; +- +-/* + * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg + * buffer and call into Hyper-V to transfer the data. + */ diff --git a/queue-5.4/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch b/queue-5.4/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch new file mode 100644 index 00000000000..a09df30e7c5 --- /dev/null +++ b/queue-5.4/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch @@ -0,0 +1,62 @@ +From 73f26e526f19afb3a06b76b970a76bcac2cafd05 Mon Sep 17 00:00:00 2001 +From: Tianyu Lan +Date: Mon, 6 Apr 2020 08:53:28 -0700 +Subject: x86/Hyper-V: Trigger crash enlightenment only once during system crash. + +From: Tianyu Lan + +commit 73f26e526f19afb3a06b76b970a76bcac2cafd05 upstream. + +When a guest VM panics, Hyper-V should be notified only once via the +crash synthetic MSRs. Current Linux code might write these crash MSRs +twice during a system panic: +1) hyperv_panic/die_event() calling hyperv_report_panic() +2) hv_kmsg_dump() calling hyperv_report_panic_msg() + +Fix this by not calling hyperv_report_panic() if a kmsg dump has been +successfully registered. The notification will happen later via +hyperv_report_panic_msg(). + +Fixes: 7ed4325a44ea ("Drivers: hv: vmbus: Make panic reporting to be more useful") +Reviewed-by: Michael Kelley +Signed-off-by: Tianyu Lan +Link: https://lore.kernel.org/r/20200406155331.2105-4-Tianyu.Lan@microsoft.com +Signed-off-by: Wei Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/vmbus_drv.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -55,7 +55,13 @@ static int hyperv_panic_event(struct not + + vmbus_initiate_unload(true); + +- if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { ++ /* ++ * Hyper-V should be notified only once about a panic. If we will be ++ * doing hyperv_report_panic_msg() later with kmsg data, don't do ++ * the notification here. ++ */ ++ if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE ++ && !hv_panic_page) { + regs = current_pt_regs(); + hyperv_report_panic(regs, val); + } +@@ -68,7 +74,13 @@ static int hyperv_die_event(struct notif + struct die_args *die = (struct die_args *)args; + struct pt_regs *regs = die->regs; + +- hyperv_report_panic(regs, val); ++ /* ++ * Hyper-V should be notified only once about a panic. If we will be ++ * doing hyperv_report_panic_msg() later with kmsg data, don't do ++ * the notification here. ++ */ ++ if (!hv_panic_page) ++ hyperv_report_panic(regs, val); + return NOTIFY_DONE; + } + diff --git a/queue-5.4/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch b/queue-5.4/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch new file mode 100644 index 00000000000..5255ef493df --- /dev/null +++ b/queue-5.4/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch @@ -0,0 +1,109 @@ +From 74347a99e73ae00b8385f1209aaea193c670f901 Mon Sep 17 00:00:00 2001 +From: Tianyu Lan +Date: Mon, 6 Apr 2020 08:53:26 -0700 +Subject: x86/Hyper-V: Unload vmbus channel in hv panic callback + +From: Tianyu Lan + +commit 74347a99e73ae00b8385f1209aaea193c670f901 upstream. + +When kdump is not configured, a Hyper-V VM might still respond to +network traffic after a kernel panic when kernel parameter panic=0. +The panic CPU goes into an infinite loop with interrupts enabled, +and the VMbus driver interrupt handler still works because the +VMbus connection is unloaded only in the kdump path. The network +responses make the other end of the connection think the VM is +still functional even though it has panic'ed, which could affect any +failover actions that should be taken. + +Fix this by unloading the VMbus connection during the panic process. +vmbus_initiate_unload() could then be called twice (e.g., by +hyperv_panic_event() and hv_crash_handler(), so reset the connection +state in vmbus_initiate_unload() to ensure the unload is done only +once. + +Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic") +Reviewed-by: Michael Kelley +Signed-off-by: Tianyu Lan +Link: https://lore.kernel.org/r/20200406155331.2105-2-Tianyu.Lan@microsoft.com +Signed-off-by: Wei Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hv/channel_mgmt.c | 3 +++ + drivers/hv/vmbus_drv.c | 21 +++++++++++++-------- + 2 files changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -839,6 +839,9 @@ void vmbus_initiate_unload(bool crash) + { + struct vmbus_channel_message_header hdr; + ++ if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED) ++ return; ++ + /* Pre-Win2012R2 hosts don't support reconnect */ + if (vmbus_proto_version < VERSION_WIN8_1) + return; +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -53,9 +53,12 @@ static int hyperv_panic_event(struct not + { + struct pt_regs *regs; + +- regs = current_pt_regs(); ++ vmbus_initiate_unload(true); + +- hyperv_report_panic(regs, val); ++ if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { ++ regs = current_pt_regs(); ++ hyperv_report_panic(regs, val); ++ } + return NOTIFY_DONE; + } + +@@ -1389,10 +1392,16 @@ static int vmbus_bus_init(void) + } + + register_die_notifier(&hyperv_die_block); +- atomic_notifier_chain_register(&panic_notifier_list, +- &hyperv_panic_block); + } + ++ /* ++ * Always register the panic notifier because we need to unload ++ * the VMbus channel connection to prevent any VMbus ++ * activity after the VM panics. ++ */ ++ atomic_notifier_chain_register(&panic_notifier_list, ++ &hyperv_panic_block); ++ + vmbus_request_offers(); + + return 0; +@@ -2202,8 +2211,6 @@ static int vmbus_bus_suspend(struct devi + + vmbus_initiate_unload(false); + +- vmbus_connection.conn_state = DISCONNECTED; +- + /* Reset the event for the next resume. */ + reinit_completion(&vmbus_connection.ready_for_resume_event); + +@@ -2288,7 +2295,6 @@ static void hv_kexec_handler(void) + { + hv_stimer_global_cleanup(); + vmbus_initiate_unload(false); +- vmbus_connection.conn_state = DISCONNECTED; + /* Make sure conn_state is set as hv_synic_cleanup checks for it */ + mb(); + cpuhp_remove_state(hyperv_cpuhp_online); +@@ -2305,7 +2311,6 @@ static void hv_crash_handler(struct pt_r + * doing the cleanup for current CPU only. This should be sufficient + * for kdump. + */ +- vmbus_connection.conn_state = DISCONNECTED; + cpu = smp_processor_id(); + hv_stimer_cleanup(cpu); + hv_synic_disable_regs(cpu); diff --git a/queue-5.4/xsk-add-missing-check-on-user-supplied-headroom-size.patch b/queue-5.4/xsk-add-missing-check-on-user-supplied-headroom-size.patch new file mode 100644 index 00000000000..acfc2e6ba59 --- /dev/null +++ b/queue-5.4/xsk-add-missing-check-on-user-supplied-headroom-size.patch @@ -0,0 +1,49 @@ +From 99e3a236dd43d06c65af0a2ef9cb44306aef6e02 Mon Sep 17 00:00:00 2001 +From: Magnus Karlsson +Date: Tue, 14 Apr 2020 09:35:15 +0200 +Subject: xsk: Add missing check on user supplied headroom size + +From: Magnus Karlsson + +commit 99e3a236dd43d06c65af0a2ef9cb44306aef6e02 upstream. + +Add a check that the headroom cannot be larger than the available +space in the chunk. In the current code, a malicious user can set the +headroom to a value larger than the chunk size minus the fixed XDP +headroom. That way packets with a length larger than the supported +size in the umem could get accepted and result in an out-of-bounds +write. + +Fixes: c0c77d8fb787 ("xsk: add user memory registration support sockopt") +Reported-by: Bui Quang Minh +Signed-off-by: Magnus Karlsson +Signed-off-by: Daniel Borkmann +Link: https://bugzilla.kernel.org/show_bug.cgi?id=207225 +Link: https://lore.kernel.org/bpf/1586849715-23490-1-git-send-email-magnus.karlsson@intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + net/xdp/xdp_umem.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/xdp/xdp_umem.c ++++ b/net/xdp/xdp_umem.c +@@ -343,7 +343,7 @@ static int xdp_umem_reg(struct xdp_umem + u32 chunk_size = mr->chunk_size, headroom = mr->headroom; + unsigned int chunks, chunks_per_page; + u64 addr = mr->addr, size = mr->len; +- int size_chk, err; ++ int err; + + if (chunk_size < XDP_UMEM_MIN_CHUNK_SIZE || chunk_size > PAGE_SIZE) { + /* Strictly speaking we could support this, if: +@@ -382,8 +382,7 @@ static int xdp_umem_reg(struct xdp_umem + return -EINVAL; + } + +- size_chk = chunk_size - headroom - XDP_PACKET_HEADROOM; +- if (size_chk < 0) ++ if (headroom >= chunk_size - XDP_PACKET_HEADROOM) + return -EINVAL; + + umem->address = (unsigned long)addr; -- 2.47.3