]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Apr 2020 17:26:19 +0000 (19:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Apr 2020 17:26:19 +0000 (19:26 +0200)
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
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
rbd-avoid-a-deadlock-on-header_rwsem-when-flushing-notifies.patch
rbd-call-rbd_dev_unprobe-after-unwatching-and-flushing-notifies.patch
rbd-don-t-test-rbd_dev-opts-in-rbd_dev_image_release.patch
x86-hyper-v-free-hv_panic_page-when-fail-to-register-kmsg-dump.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

25 files changed:
queue-5.6/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch [new file with mode: 0644]
queue-5.6/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch [new file with mode: 0644]
queue-5.6/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch [new file with mode: 0644]
queue-5.6/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch [new file with mode: 0644]
queue-5.6/afs-fix-rename-operation-status-delivery.patch [new file with mode: 0644]
queue-5.6/alsa-hda-don-t-release-card-at-firmware-loading-error.patch [new file with mode: 0644]
queue-5.6/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch [new file with mode: 0644]
queue-5.6/irqchip-mbigen-free-msi_desc-on-device-teardown.patch [new file with mode: 0644]
queue-5.6/kbuild-btf-fix-dependencies-for-debug_info_btf.patch [new file with mode: 0644]
queue-5.6/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch [new file with mode: 0644]
queue-5.6/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch [new file with mode: 0644]
queue-5.6/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch [new file with mode: 0644]
queue-5.6/of-unittest-kmemleak-in-of_unittest_platform_populate.patch [new file with mode: 0644]
queue-5.6/of-unittest-kmemleak-on-changeset-destroy.patch [new file with mode: 0644]
queue-5.6/rbd-avoid-a-deadlock-on-header_rwsem-when-flushing-notifies.patch [new file with mode: 0644]
queue-5.6/rbd-call-rbd_dev_unprobe-after-unwatching-and-flushing-notifies.patch [new file with mode: 0644]
queue-5.6/rbd-don-t-test-rbd_dev-opts-in-rbd_dev_image_release.patch [new file with mode: 0644]
queue-5.6/series
queue-5.6/x86-hyper-v-free-hv_panic_page-when-fail-to-register-kmsg-dump.patch [new file with mode: 0644]
queue-5.6/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch [new file with mode: 0644]
queue-5.6/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch [new file with mode: 0644]
queue-5.6/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch [new file with mode: 0644]
queue-5.6/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch [new file with mode: 0644]
queue-5.6/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch [new file with mode: 0644]
queue-5.6/xsk-add-missing-check-on-user-supplied-headroom-size.patch [new file with mode: 0644]

diff --git a/queue-5.6/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch b/queue-5.6/afs-fix-afs_d_validate-to-set-the-right-directory-version.patch
new file mode 100644 (file)
index 0000000..b783f88
--- /dev/null
@@ -0,0 +1,47 @@
+From 40fc81027f892284ce31f8b6de1e497f5b47e71f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Sat, 11 Apr 2020 08:50:45 +0100
+Subject: afs: Fix afs_d_validate() to set the right directory version
+
+From: David Howells <dhowells@redhat.com>
+
+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 <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch b/queue-5.6/afs-fix-decoding-of-inline-abort-codes-from-version-1-status-records.patch
new file mode 100644 (file)
index 0000000..fc0ba3a
--- /dev/null
@@ -0,0 +1,38 @@
+From 3e0d9892c0e7fa426ca6bf921cb4b543ca265714 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+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 <dhowells@redhat.com>
+
+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 <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch b/queue-5.6/afs-fix-missing-xdr-advance-in-xdr_decode_-afs-yfs-fsfetchstatus.patch
new file mode 100644 (file)
index 0000000..d08716b
--- /dev/null
@@ -0,0 +1,122 @@
+From c72057b56f7e24865840a6961d801a7f21d30a5f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2020 16:13:20 +0100
+Subject: afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus()
+
+From: David Howells <dhowells@redhat.com>
+
+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 <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch b/queue-5.6/afs-fix-race-between-post-modification-dir-edit-and-readdir-d_revalidate.patch
new file mode 100644 (file)
index 0000000..9f7c9cf
--- /dev/null
@@ -0,0 +1,351 @@
+From 2105c2820d366b76f38e6ad61c75771881ecc532 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+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 <dhowells@redhat.com>
+
+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 <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/afs-fix-rename-operation-status-delivery.patch b/queue-5.6/afs-fix-rename-operation-status-delivery.patch
new file mode 100644 (file)
index 0000000..48026f5
--- /dev/null
@@ -0,0 +1,119 @@
+From b98f0ec91c42d87a70da42726b852ac8d78a3257 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Apr 2020 20:56:20 +0100
+Subject: afs: Fix rename operation status delivery
+
+From: David Howells <dhowells@redhat.com>
+
+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 <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -986,16 +986,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
+@@ -1157,11 +1157,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.6/alsa-hda-don-t-release-card-at-firmware-loading-error.patch b/queue-5.6/alsa-hda-don-t-release-card-at-firmware-loading-error.patch
new file mode 100644 (file)
index 0000000..7f5d659
--- /dev/null
@@ -0,0 +1,59 @@
+From 25faa4bd37c10f19e4b848b9032a17a3d44c6f09 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 13 Apr 2020 10:20:29 +0200
+Subject: ALSA: hda: Don't release card at firmware loading error
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -2031,24 +2031,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.6/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch b/queue-5.6/arm-dts-imx6-use-gpc-for-fec-interrupt-controller-to-fix-wake-on-lan.patch
new file mode 100644 (file)
index 0000000..5e669ed
--- /dev/null
@@ -0,0 +1,56 @@
+From 4141f1a40fc0789f6fd4330e171e1edf155426aa Mon Sep 17 00:00:00 2001
+From: Martin Fuzzey <martin.fuzzey@flowbird.group>
+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 <martin.fuzzey@flowbird.group>
+
+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 <martin.fuzzey@flowbird.group>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/irqchip-mbigen-free-msi_desc-on-device-teardown.patch b/queue-5.6/irqchip-mbigen-free-msi_desc-on-device-teardown.patch
new file mode 100644 (file)
index 0000000..c32019a
--- /dev/null
@@ -0,0 +1,43 @@
+From edfc23f6f9fdbd7825d50ac1f380243cde19b679 Mon Sep 17 00:00:00 2001
+From: Zenghui Yu <yuzenghui@huawei.com>
+Date: Wed, 8 Apr 2020 19:43:52 +0800
+Subject: irqchip/mbigen: Free msi_desc on device teardown
+
+From: Zenghui Yu <yuzenghui@huawei.com>
+
+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 <yuzenghui@huawei.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20200408114352.1604-1-yuzenghui@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/kbuild-btf-fix-dependencies-for-debug_info_btf.patch b/queue-5.6/kbuild-btf-fix-dependencies-for-debug_info_btf.patch
new file mode 100644 (file)
index 0000000..a820785
--- /dev/null
@@ -0,0 +1,42 @@
+From 7d32e69310d67e6b04af04f26193f79dfc2f05c7 Mon Sep 17 00:00:00 2001
+From: Slava Bacherikov <slava@bacher09.org>
+Date: Thu, 2 Apr 2020 23:41:39 +0300
+Subject: kbuild, btf: Fix dependencies for DEBUG_INFO_BTF
+
+From: Slava Bacherikov <slava@bacher09.org>
+
+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 <jannh@google.com>
+Reported-by: Liu Yiding <liuyd.fnst@cn.fujitsu.com>
+Signed-off-by: Slava Bacherikov <slava@bacher09.org>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Acked-by: KP Singh <kpsingh@google.com>
+Acked-by: Andrii Nakryiko <andriin@fb.com>
+Link: https://lore.kernel.org/bpf/20200402204138.408021-1-slava@bacher09.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/Kconfig.debug |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -241,6 +241,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.6/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch b/queue-5.6/netfilter-nf_tables-report-eopnotsupp-on-unsupported-flags-object-type.patch
new file mode 100644 (file)
index 0000000..411180c
--- /dev/null
@@ -0,0 +1,41 @@
+From d9583cdf2f38d0f526d9a8c8564dd2e35e649bc7 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Tue, 7 Apr 2020 14:10:11 +0200
+Subject: netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+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 <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -3950,7 +3950,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))
+@@ -3988,7 +3988,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.6/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch b/queue-5.6/of-overlay-kmemleak-in-dup_and_fixup_symbol_prop.patch
new file mode 100644 (file)
index 0000000..9fb37b1
--- /dev/null
@@ -0,0 +1,35 @@
+From 478ff649b1c8eb2409b1a54fb75eb46f7c29f140 Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Thu, 16 Apr 2020 16:42:49 -0500
+Subject: of: overlay: kmemleak in dup_and_fixup_symbol_prop()
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+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. <erhard_f@mailbox.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch b/queue-5.6/of-unittest-kmemleak-in-of_unittest_overlay_high_level.patch
new file mode 100644 (file)
index 0000000..4748924
--- /dev/null
@@ -0,0 +1,40 @@
+From 145fc138f9aae4f9e1331352e301df28e16aed35 Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Thu, 16 Apr 2020 16:42:48 -0500
+Subject: of: unittest: kmemleak in of_unittest_overlay_high_level()
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+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. <erhard_f@mailbox.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/unittest.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -2571,8 +2571,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.6/of-unittest-kmemleak-in-of_unittest_platform_populate.patch b/queue-5.6/of-unittest-kmemleak-in-of_unittest_platform_populate.patch
new file mode 100644 (file)
index 0000000..1bf1fbd
--- /dev/null
@@ -0,0 +1,44 @@
+From 216830d2413cc61be3f76bc02ffd905e47d2439e Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Thu, 16 Apr 2020 16:42:47 -0500
+Subject: of: unittest: kmemleak in of_unittest_platform_populate()
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+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. <erhard_f@mailbox.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/unittest.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -1155,10 +1155,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.6/of-unittest-kmemleak-on-changeset-destroy.patch b/queue-5.6/of-unittest-kmemleak-on-changeset-destroy.patch
new file mode 100644 (file)
index 0000000..0a53311
--- /dev/null
@@ -0,0 +1,40 @@
+From b3fb36ed694b05738d45218ea72cf7feb10ce2b1 Mon Sep 17 00:00:00 2001
+From: Frank Rowand <frank.rowand@sony.com>
+Date: Thu, 16 Apr 2020 16:42:46 -0500
+Subject: of: unittest: kmemleak on changeset destroy
+
+From: Frank Rowand <frank.rowand@sony.com>
+
+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. <erhard_f@mailbox.org>
+Signed-off-by: Frank Rowand <frank.rowand@sony.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/of/unittest.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/of/unittest.c
++++ b/drivers/of/unittest.c
+@@ -777,6 +777,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.6/rbd-avoid-a-deadlock-on-header_rwsem-when-flushing-notifies.patch b/queue-5.6/rbd-avoid-a-deadlock-on-header_rwsem-when-flushing-notifies.patch
new file mode 100644 (file)
index 0000000..abe73dc
--- /dev/null
@@ -0,0 +1,84 @@
+From 0e4e1de5b63fa423b13593337a27fd2d2b0bcf77 Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 13 Mar 2020 11:20:51 +0100
+Subject: rbd: avoid a deadlock on header_rwsem when flushing notifies
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 0e4e1de5b63fa423b13593337a27fd2d2b0bcf77 upstream.
+
+rbd_unregister_watch() flushes notifies and therefore cannot be called
+under header_rwsem because a header update notify takes header_rwsem to
+synchronize with "rbd map".  If mapping an image fails after the watch
+is established and a header update notify sneaks in, we deadlock when
+erroring out from rbd_dev_image_probe().
+
+Move watch registration and unregistration out of the critical section.
+The only reason they were put there was to make header_rwsem management
+slightly more obvious.
+
+Fixes: 811c66887746 ("rbd: fix rbd map vs notify races")
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Jason Dillaman <dillaman@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |   17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -4554,6 +4554,10 @@ static void cancel_tasks_sync(struct rbd
+       cancel_work_sync(&rbd_dev->unlock_work);
+ }
++/*
++ * header_rwsem must not be held to avoid a deadlock with
++ * rbd_dev_refresh() when flushing notifies.
++ */
+ static void rbd_unregister_watch(struct rbd_device *rbd_dev)
+ {
+       cancel_tasks_sync(rbd_dev);
+@@ -6964,6 +6968,9 @@ static void rbd_dev_image_release(struct
+  * device.  If this image is the one being mapped (i.e., not a
+  * parent), initiate a watch on its header object before using that
+  * object to get detailed information about the rbd image.
++ *
++ * On success, returns with header_rwsem held for write if called
++ * with @depth == 0.
+  */
+ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
+ {
+@@ -6993,6 +7000,9 @@ static int rbd_dev_image_probe(struct rb
+               }
+       }
++      if (!depth)
++              down_write(&rbd_dev->header_rwsem);
++
+       ret = rbd_dev_header_info(rbd_dev);
+       if (ret) {
+               if (ret == -ENOENT && !need_watch)
+@@ -7044,6 +7054,8 @@ static int rbd_dev_image_probe(struct rb
+ err_out_probe:
+       rbd_dev_unprobe(rbd_dev);
+ err_out_watch:
++      if (!depth)
++              up_write(&rbd_dev->header_rwsem);
+       if (need_watch)
+               rbd_unregister_watch(rbd_dev);
+ err_out_format:
+@@ -7107,12 +7119,9 @@ static ssize_t do_rbd_add(struct bus_typ
+               goto err_out_rbd_dev;
+       }
+-      down_write(&rbd_dev->header_rwsem);
+       rc = rbd_dev_image_probe(rbd_dev, 0);
+-      if (rc < 0) {
+-              up_write(&rbd_dev->header_rwsem);
++      if (rc < 0)
+               goto err_out_rbd_dev;
+-      }
+       if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) {
+               rbd_warn(rbd_dev, "alloc_size adjusted to %u",
diff --git a/queue-5.6/rbd-call-rbd_dev_unprobe-after-unwatching-and-flushing-notifies.patch b/queue-5.6/rbd-call-rbd_dev_unprobe-after-unwatching-and-flushing-notifies.patch
new file mode 100644 (file)
index 0000000..0424be3
--- /dev/null
@@ -0,0 +1,77 @@
+From 952c48b0ed18919bff7528501e9a3fff8a24f8cd Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Mon, 16 Mar 2020 15:52:54 +0100
+Subject: rbd: call rbd_dev_unprobe() after unwatching and flushing notifies
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit 952c48b0ed18919bff7528501e9a3fff8a24f8cd upstream.
+
+rbd_dev_unprobe() is supposed to undo most of rbd_dev_image_probe(),
+including rbd_dev_header_info(), which means that rbd_dev_header_info()
+isn't supposed to be called after rbd_dev_unprobe().
+
+However, rbd_dev_image_release() calls rbd_dev_unprobe() before
+rbd_unregister_watch().  This is racy because a header update notify
+can sneak in:
+
+  "rbd unmap" thread                   ceph-watch-notify worker
+
+  rbd_dev_image_release()
+    rbd_dev_unprobe()
+      free and zero out header
+                                       rbd_watch_cb()
+                                         rbd_dev_refresh()
+                                           rbd_dev_header_info()
+                                             read in header
+
+The same goes for "rbd map" because rbd_dev_image_probe() calls
+rbd_dev_unprobe() on errors.  In both cases this results in a memory
+leak.
+
+Fixes: fd22aef8b47c ("rbd: move rbd_unregister_watch() call into rbd_dev_image_release()")
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Jason Dillaman <dillaman@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -6955,9 +6955,10 @@ static void rbd_print_dne(struct rbd_dev
+ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
+ {
+-      rbd_dev_unprobe(rbd_dev);
+       if (rbd_dev->opts)
+               rbd_unregister_watch(rbd_dev);
++
++      rbd_dev_unprobe(rbd_dev);
+       rbd_dev->image_format = 0;
+       kfree(rbd_dev->spec->image_id);
+       rbd_dev->spec->image_id = NULL;
+@@ -7007,7 +7008,7 @@ static int rbd_dev_image_probe(struct rb
+       if (ret) {
+               if (ret == -ENOENT && !need_watch)
+                       rbd_print_dne(rbd_dev, false);
+-              goto err_out_watch;
++              goto err_out_probe;
+       }
+       /*
+@@ -7052,12 +7053,11 @@ static int rbd_dev_image_probe(struct rb
+       return 0;
+ err_out_probe:
+-      rbd_dev_unprobe(rbd_dev);
+-err_out_watch:
+       if (!depth)
+               up_write(&rbd_dev->header_rwsem);
+       if (need_watch)
+               rbd_unregister_watch(rbd_dev);
++      rbd_dev_unprobe(rbd_dev);
+ err_out_format:
+       rbd_dev->image_format = 0;
+       kfree(rbd_dev->spec->image_id);
diff --git a/queue-5.6/rbd-don-t-test-rbd_dev-opts-in-rbd_dev_image_release.patch b/queue-5.6/rbd-don-t-test-rbd_dev-opts-in-rbd_dev_image_release.patch
new file mode 100644 (file)
index 0000000..423ce30
--- /dev/null
@@ -0,0 +1,36 @@
+From b8776051529230f76e464d5ffc5d1cf8465576bf Mon Sep 17 00:00:00 2001
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Mon, 16 Mar 2020 17:16:28 +0100
+Subject: rbd: don't test rbd_dev->opts in rbd_dev_image_release()
+
+From: Ilya Dryomov <idryomov@gmail.com>
+
+commit b8776051529230f76e464d5ffc5d1cf8465576bf upstream.
+
+rbd_dev->opts is used to distinguish between the image that is being
+mapped and a parent.  However, because we no longer establish watch for
+read-only mappings, this test is imprecise and results in unnecessary
+rbd_unregister_watch() calls.
+
+Make it consistent with need_watch in rbd_dev_image_probe().
+
+Fixes: b9ef2b8858a0 ("rbd: don't establish watch for read-only mappings")
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Reviewed-by: Jason Dillaman <dillaman@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/rbd.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -6955,7 +6955,7 @@ static void rbd_print_dne(struct rbd_dev
+ static void rbd_dev_image_release(struct rbd_device *rbd_dev)
+ {
+-      if (rbd_dev->opts)
++      if (!rbd_is_ro(rbd_dev))
+               rbd_unregister_watch(rbd_dev);
+       rbd_dev_unprobe(rbd_dev);
index 8eae10edde665d1d66bad379245fe3e8176f2e93..220299fef7d30dc10c1653e5b703aa1e29a6544b 100644 (file)
@@ -9,3 +9,27 @@ xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch
 libbpf-fix-bpf_get_link_xdp_id-flags-handling.patch
 arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch
 bpf-prevent-re-mmap-ing-bpf-map-as-writable-for-initially-r-o-mapping.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
+rbd-avoid-a-deadlock-on-header_rwsem-when-flushing-notifies.patch
+rbd-call-rbd_dev_unprobe-after-unwatching-and-flushing-notifies.patch
+rbd-don-t-test-rbd_dev-opts-in-rbd_dev_image_release.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-free-hv_panic_page-when-fail-to-register-kmsg-dump.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
diff --git a/queue-5.6/x86-hyper-v-free-hv_panic_page-when-fail-to-register-kmsg-dump.patch b/queue-5.6/x86-hyper-v-free-hv_panic_page-when-fail-to-register-kmsg-dump.patch
new file mode 100644 (file)
index 0000000..4974fbe
--- /dev/null
@@ -0,0 +1,48 @@
+From 7f11a2cc10a4ae3a70e2c73361f4a9a33503539b Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Date: Mon, 6 Apr 2020 08:53:27 -0700
+Subject: x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump
+
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+
+commit 7f11a2cc10a4ae3a70e2c73361f4a9a33503539b upstream.
+
+If kmsg_dump_register() fails, hv_panic_page will not be used
+anywhere.  So free and reset it.
+
+Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic")
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-3-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/vmbus_drv.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -1385,9 +1385,13 @@ static int vmbus_bus_init(void)
+                       hv_panic_page = (void *)hv_alloc_hyperv_zeroed_page();
+                       if (hv_panic_page) {
+                               ret = kmsg_dump_register(&hv_kmsg_dumper);
+-                              if (ret)
++                              if (ret) {
+                                       pr_err("Hyper-V: kmsg dump register "
+                                               "error 0x%x\n", ret);
++                                      hv_free_hyperv_page(
++                                          (unsigned long)hv_panic_page);
++                                      hv_panic_page = NULL;
++                              }
+                       } else
+                               pr_err("Hyper-V: panic message page memory "
+                                       "allocation failed");
+@@ -1416,7 +1420,6 @@ err_alloc:
+       hv_remove_vmbus_irq();
+       bus_unregister(&hv_bus);
+-      hv_free_hyperv_page((unsigned long)hv_panic_page);
+       unregister_sysctl_table(hv_ctl_table_hdr);
+       hv_ctl_table_hdr = NULL;
+       return ret;
diff --git a/queue-5.6/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch b/queue-5.6/x86-hyper-v-report-crash-data-in-die-when-panic_on_oops-is-set.patch
new file mode 100644 (file)
index 0000000..374988d
--- /dev/null
@@ -0,0 +1,94 @@
+From f3a99e761efa616028b255b4de58e9b5b87c5545 Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+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 <Tianyu.Lan@microsoft.com>
+
+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 <Tianyu.Lan@microsoft.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-7-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -20,6 +20,7 @@
+ #include <linux/mm.h>
+ #include <linux/hyperv.h>
+ #include <linux/slab.h>
++#include <linux/kernel.h>
+ #include <linux/cpuhotplug.h>
+ #include <linux/syscore_ops.h>
+ #include <clocksource/hyperv_timer.h>
+@@ -419,11 +420,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 <linux/kdebug.h>
+ #include <linux/efi.h>
+ #include <linux/random.h>
++#include <linux/kernel.h>
+ #include <linux/syscore_ops.h>
+ #include <clocksource/hyperv_timer.h>
+ #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);
+ bool hv_is_hibernation_supported(void);
diff --git a/queue-5.6/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch b/queue-5.6/x86-hyper-v-report-crash-register-data-or-kmsg-before-running-crash-kernel.patch
new file mode 100644 (file)
index 0000000..192c392
--- /dev/null
@@ -0,0 +1,45 @@
+From a11589563e96bf262767294b89b25a9d44e7303b Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+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 <Tianyu.Lan@microsoft.com>
+
+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 <mikelley@microsoft.com>
+Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-5-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch b/queue-5.6/x86-hyper-v-report-crash-register-data-when-sysctl_record_panic_msg-is-not-set.patch
new file mode 100644 (file)
index 0000000..768c7b3
--- /dev/null
@@ -0,0 +1,77 @@
+From 040026df7088c56ccbad28f7042308f67bde63df Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+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 <Tianyu.Lan@microsoft.com>
+
+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 <mikelley@microsoft.com>
+Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-6-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+@@ -1268,13 +1280,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.6/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch b/queue-5.6/x86-hyper-v-trigger-crash-enlightenment-only-once-during-system-crash.patch
new file mode 100644 (file)
index 0000000..a09df30
--- /dev/null
@@ -0,0 +1,62 @@
+From 73f26e526f19afb3a06b76b970a76bcac2cafd05 Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Date: Mon, 6 Apr 2020 08:53:28 -0700
+Subject: x86/Hyper-V: Trigger crash enlightenment only once during system crash.
+
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+
+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 <mikelley@microsoft.com>
+Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-4-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.6/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch b/queue-5.6/x86-hyper-v-unload-vmbus-channel-in-hv-panic-callback.patch
new file mode 100644 (file)
index 0000000..f76cf40
--- /dev/null
@@ -0,0 +1,109 @@
+From 74347a99e73ae00b8385f1209aaea193c670f901 Mon Sep 17 00:00:00 2001
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Date: Mon, 6 Apr 2020 08:53:26 -0700
+Subject: x86/Hyper-V: Unload vmbus channel in hv panic callback
+
+From: Tianyu Lan <Tianyu.Lan@microsoft.com>
+
+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 <mikelley@microsoft.com>
+Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
+Link: https://lore.kernel.org/r/20200406155331.2105-2-Tianyu.Lan@microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+@@ -1391,10 +1394,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;
+@@ -2204,8 +2213,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);
+@@ -2289,7 +2296,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);
+@@ -2306,7 +2312,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.6/xsk-add-missing-check-on-user-supplied-headroom-size.patch b/queue-5.6/xsk-add-missing-check-on-user-supplied-headroom-size.patch
new file mode 100644 (file)
index 0000000..acfc2e6
--- /dev/null
@@ -0,0 +1,49 @@
+From 99e3a236dd43d06c65af0a2ef9cb44306aef6e02 Mon Sep 17 00:00:00 2001
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+Date: Tue, 14 Apr 2020 09:35:15 +0200
+Subject: xsk: Add missing check on user supplied headroom size
+
+From: Magnus Karlsson <magnus.karlsson@intel.com>
+
+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 <minhquangbui99@gmail.com>
+Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+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 <gregkh@linuxfoundation.org>
+
+---
+ 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;