]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.17-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jul 2018 14:42:19 +0000 (16:42 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jul 2018 14:42:19 +0000 (16:42 +0200)
added patches:
dax-change-bdev_dax_supported-to-support-boolean-returns.patch
dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch
dm-prevent-dax-mounts-if-not-supported.patch
fs-allow-per-device-dax-status-checking-for-filesystems.patch
hid-core-allow-concurrent-registration-of-drivers.patch
hid-debug-check-length-before-copy_to_user.patch
hid-hiddev-fix-potential-spectre-v1.patch
hid-i2c-hid-fix-incomplete-report-noise.patch
i2c-core-smbus-fix-a-potential-missing-check-bug.patch
i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch

queue-4.17/dax-change-bdev_dax_supported-to-support-boolean-returns.patch [new file with mode: 0644]
queue-4.17/dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch [new file with mode: 0644]
queue-4.17/dm-prevent-dax-mounts-if-not-supported.patch [new file with mode: 0644]
queue-4.17/fs-allow-per-device-dax-status-checking-for-filesystems.patch [new file with mode: 0644]
queue-4.17/hid-core-allow-concurrent-registration-of-drivers.patch [new file with mode: 0644]
queue-4.17/hid-debug-check-length-before-copy_to_user.patch [new file with mode: 0644]
queue-4.17/hid-hiddev-fix-potential-spectre-v1.patch [new file with mode: 0644]
queue-4.17/hid-i2c-hid-fix-incomplete-report-noise.patch [new file with mode: 0644]
queue-4.17/i2c-core-smbus-fix-a-potential-missing-check-bug.patch [new file with mode: 0644]
queue-4.17/i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch [new file with mode: 0644]
queue-4.17/series

diff --git a/queue-4.17/dax-change-bdev_dax_supported-to-support-boolean-returns.patch b/queue-4.17/dax-change-bdev_dax_supported-to-support-boolean-returns.patch
new file mode 100644 (file)
index 0000000..65b0b8c
--- /dev/null
@@ -0,0 +1,180 @@
+From 80660f20252d6f76c9f203874ad7c7a4a8508cf8 Mon Sep 17 00:00:00 2001
+From: Dave Jiang <dave.jiang@intel.com>
+Date: Wed, 30 May 2018 13:03:46 -0700
+Subject: dax: change bdev_dax_supported() to support boolean returns
+
+From: Dave Jiang <dave.jiang@intel.com>
+
+commit 80660f20252d6f76c9f203874ad7c7a4a8508cf8 upstream.
+
+The function return values are confusing with the way the function is
+named. We expect a true or false return value but it actually returns
+0/-errno.  This makes the code very confusing. Changing the return values
+to return a bool where if DAX is supported then return true and no DAX
+support returns false.
+
+Signed-off-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/dax/super.c |   16 ++++++++--------
+ fs/ext2/super.c     |    3 +--
+ fs/ext4/super.c     |    3 +--
+ fs/xfs/xfs_ioctl.c  |    4 ++--
+ fs/xfs/xfs_super.c  |   12 ++++++------
+ include/linux/dax.h |    8 ++++----
+ 6 files changed, 22 insertions(+), 24 deletions(-)
+
+--- a/drivers/dax/super.c
++++ b/drivers/dax/super.c
+@@ -80,9 +80,9 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+  * This is a library function for filesystems to check if the block device
+  * can be mounted with dax option.
+  *
+- * Return: negative errno if unsupported, 0 if supported.
++ * Return: true if supported, false if unsupported
+  */
+-int __bdev_dax_supported(struct block_device *bdev, int blocksize)
++bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
+ {
+       struct dax_device *dax_dev;
+       pgoff_t pgoff;
+@@ -95,21 +95,21 @@ int __bdev_dax_supported(struct block_de
+       if (blocksize != PAGE_SIZE) {
+               pr_debug("%s: error: unsupported blocksize for dax\n",
+                               bdevname(bdev, buf));
+-              return -EINVAL;
++              return false;
+       }
+       err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
+       if (err) {
+               pr_debug("%s: error: unaligned partition for dax\n",
+                               bdevname(bdev, buf));
+-              return err;
++              return false;
+       }
+       dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+       if (!dax_dev) {
+               pr_debug("%s: error: device does not support dax\n",
+                               bdevname(bdev, buf));
+-              return -EOPNOTSUPP;
++              return false;
+       }
+       id = dax_read_lock();
+@@ -121,7 +121,7 @@ int __bdev_dax_supported(struct block_de
+       if (len < 1) {
+               pr_debug("%s: error: dax access failed (%ld)\n",
+                               bdevname(bdev, buf), len);
+-              return len < 0 ? len : -EIO;
++              return false;
+       }
+       if (IS_ENABLED(CONFIG_FS_DAX_LIMITED) && pfn_t_special(pfn)) {
+@@ -139,10 +139,10 @@ int __bdev_dax_supported(struct block_de
+       } else {
+               pr_debug("%s: error: dax support not enabled\n",
+                               bdevname(bdev, buf));
+-              return -EOPNOTSUPP;
++              return false;
+       }
+-      return 0;
++      return true;
+ }
+ EXPORT_SYMBOL_GPL(__bdev_dax_supported);
+ #endif
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -961,8 +961,7 @@ static int ext2_fill_super(struct super_
+       blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
+       if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
+-              err = bdev_dax_supported(sb->s_bdev, blocksize);
+-              if (err) {
++              if (!bdev_dax_supported(sb->s_bdev, blocksize)) {
+                       ext2_msg(sb, KERN_ERR,
+                               "DAX unsupported by block device. Turning off DAX.");
+                       sbi->s_mount_opt &= ~EXT2_MOUNT_DAX;
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3773,8 +3773,7 @@ static int ext4_fill_super(struct super_
+                                       " that may contain inline data");
+                       sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
+               }
+-              err = bdev_dax_supported(sb->s_bdev, blocksize);
+-              if (err) {
++              if (!bdev_dax_supported(sb->s_bdev, blocksize)) {
+                       ext4_msg(sb, KERN_ERR,
+                               "DAX unsupported by block device. Turning off DAX.");
+                       sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
+--- a/fs/xfs/xfs_ioctl.c
++++ b/fs/xfs/xfs_ioctl.c
+@@ -1103,8 +1103,8 @@ xfs_ioctl_setattr_dax_invalidate(
+       if (fa->fsx_xflags & FS_XFLAG_DAX) {
+               if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
+                       return -EINVAL;
+-              if (bdev_dax_supported(xfs_find_bdev_for_inode(VFS_I(ip)),
+-                              sb->s_blocksize) < 0)
++              if (!bdev_dax_supported(xfs_find_bdev_for_inode(VFS_I(ip)),
++                              sb->s_blocksize))
+                       return -EINVAL;
+       }
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -1690,17 +1690,17 @@ xfs_fs_fill_super(
+               sb->s_flags |= SB_I_VERSION;
+       if (mp->m_flags & XFS_MOUNT_DAX) {
+-              int     error2 = 0;
++              bool rtdev_is_dax = false, datadev_is_dax;
+               xfs_warn(mp,
+               "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
+-              error = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
+-                              sb->s_blocksize);
++              datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
++                      sb->s_blocksize);
+               if (mp->m_rtdev_targp)
+-                      error2 = bdev_dax_supported(mp->m_rtdev_targp->bt_bdev,
+-                                      sb->s_blocksize);
+-              if (error && error2) {
++                      rtdev_is_dax = bdev_dax_supported(
++                              mp->m_rtdev_targp->bt_bdev, sb->s_blocksize);
++              if (!rtdev_is_dax && !datadev_is_dax) {
+                       xfs_alert(mp,
+                       "DAX unsupported by block device. Turning off DAX.");
+                       mp->m_flags &= ~XFS_MOUNT_DAX;
+--- a/include/linux/dax.h
++++ b/include/linux/dax.h
+@@ -64,8 +64,8 @@ static inline bool dax_write_cache_enabl
+ struct writeback_control;
+ int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
+ #if IS_ENABLED(CONFIG_FS_DAX)
+-int __bdev_dax_supported(struct block_device *bdev, int blocksize);
+-static inline int bdev_dax_supported(struct block_device *bdev, int blocksize)
++bool __bdev_dax_supported(struct block_device *bdev, int blocksize);
++static inline bool bdev_dax_supported(struct block_device *bdev, int blocksize)
+ {
+       return __bdev_dax_supported(bdev, blocksize);
+ }
+@@ -84,10 +84,10 @@ struct dax_device *fs_dax_get_by_bdev(st
+ int dax_writeback_mapping_range(struct address_space *mapping,
+               struct block_device *bdev, struct writeback_control *wbc);
+ #else
+-static inline int bdev_dax_supported(struct block_device *bdev,
++static inline bool bdev_dax_supported(struct block_device *bdev,
+               int blocksize)
+ {
+-      return -EOPNOTSUPP;
++      return false;
+ }
+ static inline struct dax_device *fs_dax_get_by_host(const char *host)
diff --git a/queue-4.17/dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch b/queue-4.17/dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch
new file mode 100644 (file)
index 0000000..a454253
--- /dev/null
@@ -0,0 +1,53 @@
+From 15256f6cc4b44f2e70503758150267fd2a53c0d6 Mon Sep 17 00:00:00 2001
+From: Ross Zwisler <ross.zwisler@linux.intel.com>
+Date: Tue, 26 Jun 2018 16:30:40 -0600
+Subject: dax: check for QUEUE_FLAG_DAX in bdev_dax_supported()
+
+From: Ross Zwisler <ross.zwisler@linux.intel.com>
+
+commit 15256f6cc4b44f2e70503758150267fd2a53c0d6 upstream.
+
+Add an explicit check for QUEUE_FLAG_DAX to __bdev_dax_supported().  This
+is needed for DM configurations where the first element in the dm-linear or
+dm-stripe target supports DAX, but other elements do not.  Without this
+check __bdev_dax_supported() will pass for such devices, letting a
+filesystem on that device mount with the DAX option.
+
+Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Suggested-by: Mike Snitzer <snitzer@redhat.com>
+Fixes: commit 545ed20e6df6 ("dm: add infrastructure for DAX support")
+Cc: stable@vger.kernel.org
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/dax/super.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/dax/super.c
++++ b/drivers/dax/super.c
+@@ -85,6 +85,7 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
+ {
+       struct dax_device *dax_dev;
++      struct request_queue *q;
+       pgoff_t pgoff;
+       int err, id;
+       void *kaddr;
+@@ -97,6 +98,13 @@ bool __bdev_dax_supported(struct block_d
+                               bdevname(bdev, buf));
+               return false;
+       }
++
++      q = bdev_get_queue(bdev);
++      if (!q || !blk_queue_dax(q)) {
++              pr_debug("%s: error: request queue doesn't support dax\n",
++                              bdevname(bdev, buf));
++              return false;
++      }
+       err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
+       if (err) {
diff --git a/queue-4.17/dm-prevent-dax-mounts-if-not-supported.patch b/queue-4.17/dm-prevent-dax-mounts-if-not-supported.patch
new file mode 100644 (file)
index 0000000..9c26bfd
--- /dev/null
@@ -0,0 +1,72 @@
+From dbc626597c39b24cefce09fbd8e9dea85869a801 Mon Sep 17 00:00:00 2001
+From: Ross Zwisler <ross.zwisler@linux.intel.com>
+Date: Tue, 26 Jun 2018 16:30:41 -0600
+Subject: dm: prevent DAX mounts if not supported
+
+From: Ross Zwisler <ross.zwisler@linux.intel.com>
+
+commit dbc626597c39b24cefce09fbd8e9dea85869a801 upstream.
+
+Currently device_supports_dax() just checks to see if the QUEUE_FLAG_DAX
+flag is set on the device's request queue to decide whether or not the
+device supports filesystem DAX.  Really we should be using
+bdev_dax_supported() like filesystems do at mount time.  This performs
+other tests like checking to make sure the dax_direct_access() path works.
+
+We also explicitly clear QUEUE_FLAG_DAX on the DM device's request queue if
+any of the underlying devices do not support DAX.  This makes the handling
+of QUEUE_FLAG_DAX consistent with the setting/clearing of most other flags
+in dm_table_set_restrictions().
+
+Now that bdev_dax_supported() explicitly checks for QUEUE_FLAG_DAX, this
+will ensure that filesystems built upon DM devices will only be able to
+mount with DAX if all underlying devices also support DAX.
+
+Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Fixes: commit 545ed20e6df6 ("dm: add infrastructure for DAX support")
+Cc: stable@vger.kernel.org
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Toshi Kani <toshi.kani@hpe.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c |    7 ++++---
+ drivers/md/dm.c       |    3 +--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -885,9 +885,7 @@ EXPORT_SYMBOL_GPL(dm_table_set_type);
+ static int device_supports_dax(struct dm_target *ti, struct dm_dev *dev,
+                              sector_t start, sector_t len, void *data)
+ {
+-      struct request_queue *q = bdev_get_queue(dev->bdev);
+-
+-      return q && blk_queue_dax(q);
++      return bdev_dax_supported(dev->bdev, PAGE_SIZE);
+ }
+ static bool dm_table_supports_dax(struct dm_table *t)
+@@ -1907,6 +1905,9 @@ void dm_table_set_restrictions(struct dm
+       if (dm_table_supports_dax(t))
+               blk_queue_flag_set(QUEUE_FLAG_DAX, q);
++      else
++              blk_queue_flag_clear(QUEUE_FLAG_DAX, q);
++
+       if (dm_table_supports_dax_write_cache(t))
+               dax_write_cache(t->md->dax_dev, true);
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1056,8 +1056,7 @@ static long dm_dax_direct_access(struct
+       if (len < 1)
+               goto out;
+       nr_pages = min(len, nr_pages);
+-      if (ti->type->direct_access)
+-              ret = ti->type->direct_access(ti, pgoff, nr_pages, kaddr, pfn);
++      ret = ti->type->direct_access(ti, pgoff, nr_pages, kaddr, pfn);
+  out:
+       dm_put_live_table(md, srcu_idx);
diff --git a/queue-4.17/fs-allow-per-device-dax-status-checking-for-filesystems.patch b/queue-4.17/fs-allow-per-device-dax-status-checking-for-filesystems.patch
new file mode 100644 (file)
index 0000000..eb4204b
--- /dev/null
@@ -0,0 +1,236 @@
+From ba23cba9b3bdc967aabdc6ff1e3e9b11ce05bb4f Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Wed, 30 May 2018 13:03:45 -0700
+Subject: fs: allow per-device dax status checking for filesystems
+
+From: Darrick J. Wong <darrick.wong@oracle.com>
+
+commit ba23cba9b3bdc967aabdc6ff1e3e9b11ce05bb4f upstream.
+
+Change bdev_dax_supported so it takes a bdev parameter.  This enables
+multi-device filesystems like xfs to check that a dax device can work for
+the particular filesystem.  Once that's in place, actually fix all the
+parts of XFS where we need to be able to distinguish between datadev and
+rtdev.
+
+This patch fixes the problem where we screw up the dax support checking
+in xfs if the datadev and rtdev have different dax capabilities.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+[rez: Re-added __bdev_dax_supported() for !CONFIG_FS_DAX cases]
+Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Reviewed-by: Eric Sandeen <sandeen@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dax/super.c |   26 +++++++++++++-------------
+ fs/ext2/super.c     |    2 +-
+ fs/ext4/super.c     |    2 +-
+ fs/xfs/xfs_ioctl.c  |    3 ++-
+ fs/xfs/xfs_iops.c   |   30 +++++++++++++++++++++++++-----
+ fs/xfs/xfs_super.c  |   10 ++++++++--
+ include/linux/dax.h |    9 +++++----
+ 7 files changed, 55 insertions(+), 27 deletions(-)
+
+--- a/drivers/dax/super.c
++++ b/drivers/dax/super.c
+@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+ /**
+  * __bdev_dax_supported() - Check if the device supports dax for filesystem
+- * @sb: The superblock of the device
++ * @bdev: block device to check
+  * @blocksize: The block size of the device
+  *
+  * This is a library function for filesystems to check if the block device
+@@ -82,33 +82,33 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+  *
+  * Return: negative errno if unsupported, 0 if supported.
+  */
+-int __bdev_dax_supported(struct super_block *sb, int blocksize)
++int __bdev_dax_supported(struct block_device *bdev, int blocksize)
+ {
+-      struct block_device *bdev = sb->s_bdev;
+       struct dax_device *dax_dev;
+       pgoff_t pgoff;
+       int err, id;
+       void *kaddr;
+       pfn_t pfn;
+       long len;
++      char buf[BDEVNAME_SIZE];
+       if (blocksize != PAGE_SIZE) {
+-              pr_debug("VFS (%s): error: unsupported blocksize for dax\n",
+-                              sb->s_id);
++              pr_debug("%s: error: unsupported blocksize for dax\n",
++                              bdevname(bdev, buf));
+               return -EINVAL;
+       }
+       err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
+       if (err) {
+-              pr_debug("VFS (%s): error: unaligned partition for dax\n",
+-                              sb->s_id);
++              pr_debug("%s: error: unaligned partition for dax\n",
++                              bdevname(bdev, buf));
+               return err;
+       }
+       dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+       if (!dax_dev) {
+-              pr_debug("VFS (%s): error: device does not support dax\n",
+-                              sb->s_id);
++              pr_debug("%s: error: device does not support dax\n",
++                              bdevname(bdev, buf));
+               return -EOPNOTSUPP;
+       }
+@@ -119,8 +119,8 @@ int __bdev_dax_supported(struct super_bl
+       put_dax(dax_dev);
+       if (len < 1) {
+-              pr_debug("VFS (%s): error: dax access failed (%ld)\n",
+-                              sb->s_id, len);
++              pr_debug("%s: error: dax access failed (%ld)\n",
++                              bdevname(bdev, buf), len);
+               return len < 0 ? len : -EIO;
+       }
+@@ -137,8 +137,8 @@ int __bdev_dax_supported(struct super_bl
+       } else if (pfn_t_devmap(pfn)) {
+               /* pass */;
+       } else {
+-              pr_debug("VFS (%s): error: dax support not enabled\n",
+-                              sb->s_id);
++              pr_debug("%s: error: dax support not enabled\n",
++                              bdevname(bdev, buf));
+               return -EOPNOTSUPP;
+       }
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -961,7 +961,7 @@ static int ext2_fill_super(struct super_
+       blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
+       if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
+-              err = bdev_dax_supported(sb, blocksize);
++              err = bdev_dax_supported(sb->s_bdev, blocksize);
+               if (err) {
+                       ext2_msg(sb, KERN_ERR,
+                               "DAX unsupported by block device. Turning off DAX.");
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3773,7 +3773,7 @@ static int ext4_fill_super(struct super_
+                                       " that may contain inline data");
+                       sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
+               }
+-              err = bdev_dax_supported(sb, blocksize);
++              err = bdev_dax_supported(sb->s_bdev, blocksize);
+               if (err) {
+                       ext4_msg(sb, KERN_ERR,
+                               "DAX unsupported by block device. Turning off DAX.");
+--- a/fs/xfs/xfs_ioctl.c
++++ b/fs/xfs/xfs_ioctl.c
+@@ -1103,7 +1103,8 @@ xfs_ioctl_setattr_dax_invalidate(
+       if (fa->fsx_xflags & FS_XFLAG_DAX) {
+               if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
+                       return -EINVAL;
+-              if (bdev_dax_supported(sb, sb->s_blocksize) < 0)
++              if (bdev_dax_supported(xfs_find_bdev_for_inode(VFS_I(ip)),
++                              sb->s_blocksize) < 0)
+                       return -EINVAL;
+       }
+--- a/fs/xfs/xfs_iops.c
++++ b/fs/xfs/xfs_iops.c
+@@ -1195,6 +1195,30 @@ static const struct inode_operations xfs
+       .update_time            = xfs_vn_update_time,
+ };
++/* Figure out if this file actually supports DAX. */
++static bool
++xfs_inode_supports_dax(
++      struct xfs_inode        *ip)
++{
++      struct xfs_mount        *mp = ip->i_mount;
++
++      /* Only supported on non-reflinked files. */
++      if (!S_ISREG(VFS_I(ip)->i_mode) || xfs_is_reflink_inode(ip))
++              return false;
++
++      /* DAX mount option or DAX iflag must be set. */
++      if (!(mp->m_flags & XFS_MOUNT_DAX) &&
++          !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
++              return false;
++
++      /* Block size must match page size */
++      if (mp->m_sb.sb_blocksize != PAGE_SIZE)
++              return false;
++
++      /* Device has to support DAX too. */
++      return xfs_find_daxdev_for_inode(VFS_I(ip)) != NULL;
++}
++
+ STATIC void
+ xfs_diflags_to_iflags(
+       struct inode            *inode,
+@@ -1213,11 +1237,7 @@ xfs_diflags_to_iflags(
+               inode->i_flags |= S_SYNC;
+       if (flags & XFS_DIFLAG_NOATIME)
+               inode->i_flags |= S_NOATIME;
+-      if (S_ISREG(inode->i_mode) &&
+-          ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
+-          !xfs_is_reflink_inode(ip) &&
+-          (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
+-           ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
++      if (xfs_inode_supports_dax(ip))
+               inode->i_flags |= S_DAX;
+ }
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -1690,11 +1690,17 @@ xfs_fs_fill_super(
+               sb->s_flags |= SB_I_VERSION;
+       if (mp->m_flags & XFS_MOUNT_DAX) {
++              int     error2 = 0;
++
+               xfs_warn(mp,
+               "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
+-              error = bdev_dax_supported(sb, sb->s_blocksize);
+-              if (error) {
++              error = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
++                              sb->s_blocksize);
++              if (mp->m_rtdev_targp)
++                      error2 = bdev_dax_supported(mp->m_rtdev_targp->bt_bdev,
++                                      sb->s_blocksize);
++              if (error && error2) {
+                       xfs_alert(mp,
+                       "DAX unsupported by block device. Turning off DAX.");
+                       mp->m_flags &= ~XFS_MOUNT_DAX;
+--- a/include/linux/dax.h
++++ b/include/linux/dax.h
+@@ -64,10 +64,10 @@ static inline bool dax_write_cache_enabl
+ struct writeback_control;
+ int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
+ #if IS_ENABLED(CONFIG_FS_DAX)
+-int __bdev_dax_supported(struct super_block *sb, int blocksize);
+-static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
++int __bdev_dax_supported(struct block_device *bdev, int blocksize);
++static inline int bdev_dax_supported(struct block_device *bdev, int blocksize)
+ {
+-      return __bdev_dax_supported(sb, blocksize);
++      return __bdev_dax_supported(bdev, blocksize);
+ }
+ static inline struct dax_device *fs_dax_get_by_host(const char *host)
+@@ -84,7 +84,8 @@ struct dax_device *fs_dax_get_by_bdev(st
+ int dax_writeback_mapping_range(struct address_space *mapping,
+               struct block_device *bdev, struct writeback_control *wbc);
+ #else
+-static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
++static inline int bdev_dax_supported(struct block_device *bdev,
++              int blocksize)
+ {
+       return -EOPNOTSUPP;
+ }
diff --git a/queue-4.17/hid-core-allow-concurrent-registration-of-drivers.patch b/queue-4.17/hid-core-allow-concurrent-registration-of-drivers.patch
new file mode 100644 (file)
index 0000000..a7e33f0
--- /dev/null
@@ -0,0 +1,72 @@
+From 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 Mon Sep 17 00:00:00 2001
+From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Date: Thu, 31 May 2018 13:49:29 +0200
+Subject: HID: core: allow concurrent registration of drivers
+
+From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+
+commit 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 upstream.
+
+Detected on the Dell XPS 9365.
+
+The laptop has 2 devices that benefit from the hid-generic auto-unbinding.
+When those 2 devices are presented to the userspace, udev loads both wacom and
+hid-multitouch. When this happens, the code in __hid_bus_reprobe_drivers() is
+called concurrently and the second device gets reprobed twice.
+
+An other bug in the power_supply subsystem prevent to remove the wacom driver
+if it just finished its initialization, which basically kills the wacom node.
+
+[jkosina@suse.cz: reformat changelog a bit]
+Fixes c17a7476e4c4 ("HID: core: rewrite the hid-generic automatic unbind")
+Cc: stable@vger.kernel.org # v4.17
+Tested-by: Mario Limonciello <mario.limonciello@dell.com>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-core.c |    5 ++++-
+ include/linux/hid.h    |    3 ++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1942,6 +1942,8 @@ static int hid_device_probe(struct devic
+       }
+       hdev->io_started = false;
++      clear_bit(ffs(HID_STAT_REPROBED), &hdev->status);
++
+       if (!hdev->driver) {
+               id = hid_match_device(hdev, hdrv);
+               if (id == NULL) {
+@@ -2205,7 +2207,8 @@ static int __hid_bus_reprobe_drivers(str
+       struct hid_device *hdev = to_hid_device(dev);
+       if (hdev->driver == hdrv &&
+-          !hdrv->match(hdev, hid_ignore_special_drivers))
++          !hdrv->match(hdev, hid_ignore_special_drivers) &&
++          !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
+               return device_reprobe(dev);
+       return 0;
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -502,6 +502,7 @@ struct hid_output_fifo {
+ #define HID_STAT_ADDED                BIT(0)
+ #define HID_STAT_PARSED               BIT(1)
++#define HID_STAT_REPROBED     BIT(3)
+ struct hid_input {
+       struct list_head list;
+@@ -568,7 +569,7 @@ struct hid_device {                                                        /* device repo
+       bool battery_avoid_query;
+ #endif
+-      unsigned int status;                                            /* see STAT flags above */
++      unsigned long status;                                           /* see STAT flags above */
+       unsigned claimed;                                               /* Claimed by hidinput, hiddev? */
+       unsigned quirks;                                                /* Various quirks the device can pull on us */
+       bool io_started;                                                /* If IO has started */
diff --git a/queue-4.17/hid-debug-check-length-before-copy_to_user.patch b/queue-4.17/hid-debug-check-length-before-copy_to_user.patch
new file mode 100644 (file)
index 0000000..18f1cce
--- /dev/null
@@ -0,0 +1,53 @@
+From 717adfdaf14704fd3ec7fa2c04520c0723247eac Mon Sep 17 00:00:00 2001
+From: Daniel Rosenberg <drosen@google.com>
+Date: Mon, 2 Jul 2018 16:59:37 -0700
+Subject: HID: debug: check length before copy_to_user()
+
+From: Daniel Rosenberg <drosen@google.com>
+
+commit 717adfdaf14704fd3ec7fa2c04520c0723247eac upstream.
+
+If our length is greater than the size of the buffer, we
+overflow the buffer
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Rosenberg <drosen@google.com>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-debug.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/hid/hid-debug.c
++++ b/drivers/hid/hid-debug.c
+@@ -1154,6 +1154,8 @@ copy_rest:
+                       goto out;
+               if (list->tail > list->head) {
+                       len = list->tail - list->head;
++                      if (len > count)
++                              len = count;
+                       if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
+                               ret = -EFAULT;
+@@ -1163,6 +1165,8 @@ copy_rest:
+                       list->head += len;
+               } else {
+                       len = HID_DEBUG_BUFSIZE - list->head;
++                      if (len > count)
++                              len = count;
+                       if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
+                               ret = -EFAULT;
+@@ -1170,7 +1174,9 @@ copy_rest:
+                       }
+                       list->head = 0;
+                       ret += len;
+-                      goto copy_rest;
++                      count -= len;
++                      if (count > 0)
++                              goto copy_rest;
+               }
+       }
diff --git a/queue-4.17/hid-hiddev-fix-potential-spectre-v1.patch b/queue-4.17/hid-hiddev-fix-potential-spectre-v1.patch
new file mode 100644 (file)
index 0000000..209d980
--- /dev/null
@@ -0,0 +1,90 @@
+From 4f65245f2d178b9cba48350620d76faa4a098841 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Fri, 29 Jun 2018 17:08:44 -0500
+Subject: HID: hiddev: fix potential Spectre v1
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit 4f65245f2d178b9cba48350620d76faa4a098841 upstream.
+
+uref->field_index, uref->usage_index, finfo.field_index and cinfo.index can be
+indirectly controlled by user-space, hence leading to a potential exploitation
+of the Spectre variant 1 vulnerability.
+
+This issue was detected with the help of Smatch:
+
+drivers/hid/usbhid/hiddev.c:473 hiddev_ioctl_usage() warn: potential spectre issue 'report->field' (local cap)
+drivers/hid/usbhid/hiddev.c:477 hiddev_ioctl_usage() warn: potential spectre issue 'field->usage' (local cap)
+drivers/hid/usbhid/hiddev.c:757 hiddev_ioctl() warn: potential spectre issue 'report->field' (local cap)
+drivers/hid/usbhid/hiddev.c:801 hiddev_ioctl() warn: potential spectre issue 'hid->collection' (local cap)
+
+Fix this by sanitizing such structure fields before using them to index
+report->field, field->usage and hid->collection
+
+Notice that given that speculation windows are large, the policy is
+to kill the speculation on the first load and not worry if it can be
+completed with a dependent load/store [1].
+
+[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/usbhid/hiddev.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/hid/usbhid/hiddev.c
++++ b/drivers/hid/usbhid/hiddev.c
+@@ -36,6 +36,7 @@
+ #include <linux/hiddev.h>
+ #include <linux/compat.h>
+ #include <linux/vmalloc.h>
++#include <linux/nospec.h>
+ #include "usbhid.h"
+ #ifdef CONFIG_USB_DYNAMIC_MINORS
+@@ -469,10 +470,14 @@ static noinline int hiddev_ioctl_usage(s
+               if (uref->field_index >= report->maxfield)
+                       goto inval;
++              uref->field_index = array_index_nospec(uref->field_index,
++                                                     report->maxfield);
+               field = report->field[uref->field_index];
+               if (uref->usage_index >= field->maxusage)
+                       goto inval;
++              uref->usage_index = array_index_nospec(uref->usage_index,
++                                                     field->maxusage);
+               uref->usage_code = field->usage[uref->usage_index].hid;
+@@ -499,6 +504,8 @@ static noinline int hiddev_ioctl_usage(s
+                       if (uref->field_index >= report->maxfield)
+                               goto inval;
++                      uref->field_index = array_index_nospec(uref->field_index,
++                                                             report->maxfield);
+                       field = report->field[uref->field_index];
+@@ -753,6 +760,8 @@ static long hiddev_ioctl(struct file *fi
+               if (finfo.field_index >= report->maxfield)
+                       break;
++              finfo.field_index = array_index_nospec(finfo.field_index,
++                                                     report->maxfield);
+               field = report->field[finfo.field_index];
+               memset(&finfo, 0, sizeof(finfo));
+@@ -797,6 +806,8 @@ static long hiddev_ioctl(struct file *fi
+               if (cinfo.index >= hid->maxcollection)
+                       break;
++              cinfo.index = array_index_nospec(cinfo.index,
++                                               hid->maxcollection);
+               cinfo.type = hid->collection[cinfo.index].type;
+               cinfo.usage = hid->collection[cinfo.index].usage;
diff --git a/queue-4.17/hid-i2c-hid-fix-incomplete-report-noise.patch b/queue-4.17/hid-i2c-hid-fix-incomplete-report-noise.patch
new file mode 100644 (file)
index 0000000..087ef31
--- /dev/null
@@ -0,0 +1,46 @@
+From ef6eaf27274c0351f7059163918f3795da13199c Mon Sep 17 00:00:00 2001
+From: Jason Andryuk <jandryuk@gmail.com>
+Date: Fri, 22 Jun 2018 12:25:49 -0400
+Subject: HID: i2c-hid: Fix "incomplete report" noise
+
+From: Jason Andryuk <jandryuk@gmail.com>
+
+commit ef6eaf27274c0351f7059163918f3795da13199c upstream.
+
+Commit ac75a041048b ("HID: i2c-hid: fix size check and type usage") started
+writing messages when the ret_size is <= 2 from i2c_master_recv.  However, my
+device i2c-DLL07D1 returns 2 for a short period of time (~0.5s) after I stop
+moving the pointing stick or touchpad.  It varies, but you get ~50 messages
+each time which spams the log hard.
+
+[  95.925055] i2c_hid i2c-DLL07D1:01: i2c_hid_get_input: incomplete report (83/2)
+
+This has also been observed with a i2c-ALP0017.
+
+[ 1781.266353] i2c_hid i2c-ALP0017:00: i2c_hid_get_input: incomplete report (30/2)
+
+Only print the message when ret_size is totally invalid and less than 2 to cut
+down on the log spam.
+
+Fixes: ac75a041048b ("HID: i2c-hid: fix size check and type usage")
+Reported-by: John Smith <john-s-84@gmx.net>
+Cc: stable@vger.kernel.org
+Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/i2c-hid/i2c-hid.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hid/i2c-hid/i2c-hid.c
++++ b/drivers/hid/i2c-hid/i2c-hid.c
+@@ -486,7 +486,7 @@ static void i2c_hid_get_input(struct i2c
+               return;
+       }
+-      if ((ret_size > size) || (ret_size <= 2)) {
++      if ((ret_size > size) || (ret_size < 2)) {
+               dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
+                       __func__, size, ret_size);
+               return;
diff --git a/queue-4.17/i2c-core-smbus-fix-a-potential-missing-check-bug.patch b/queue-4.17/i2c-core-smbus-fix-a-potential-missing-check-bug.patch
new file mode 100644 (file)
index 0000000..e7d859a
--- /dev/null
@@ -0,0 +1,44 @@
+From 8e03477cb709b73a2c1e1f4349ee3b7b33c50416 Mon Sep 17 00:00:00 2001
+From: Wenwen Wang <wang6495@umn.edu>
+Date: Sat, 5 May 2018 08:02:21 -0500
+Subject: i2c: core: smbus: fix a potential missing-check bug
+
+From: Wenwen Wang <wang6495@umn.edu>
+
+commit 8e03477cb709b73a2c1e1f4349ee3b7b33c50416 upstream.
+
+In i2c_smbus_xfer_emulated(), the function i2c_transfer() is invoked to
+transfer i2c messages. The number of actual transferred messages is
+returned and saved to 'status'. If 'status' is negative, that means an
+error occurred during the transfer process. In that case, the value of
+'status' is an error code to indicate the reason of the transfer failure.
+In most cases, i2c_transfer() can transfer 'num' messages with no error.
+And so 'status' == 'num'. However, due to unexpected errors, it is probable
+that only partial messages are transferred by i2c_transfer(). As a result,
+'status' != 'num'. This special case is not checked after the invocation of
+i2c_transfer() and can potentially lead to unexpected issues in the
+following execution since it is expected that 'status' == 'num'.
+
+This patch checks the return value of i2c_transfer() and returns an error
+code -EIO if the number of actual transferred messages 'status' is not
+equal to 'num'.
+
+Signed-off-by: Wenwen Wang <wang6495@umn.edu>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/i2c-core-smbus.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/i2c/i2c-core-smbus.c
++++ b/drivers/i2c/i2c-core-smbus.c
+@@ -466,6 +466,8 @@ static s32 i2c_smbus_xfer_emulated(struc
+       status = i2c_transfer(adapter, msg, num);
+       if (status < 0)
+               return status;
++      if (status != num)
++              return -EIO;
+       /* Check PEC if last message is a read */
+       if (i && (msg[num-1].flags & I2C_M_RD)) {
diff --git a/queue-4.17/i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch b/queue-4.17/i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch
new file mode 100644 (file)
index 0000000..9266fa4
--- /dev/null
@@ -0,0 +1,62 @@
+From 9aa613674f89d01248ae2e4afe691b515ff8fbb6 Mon Sep 17 00:00:00 2001
+From: Peter Rosin <peda@axentia.se>
+Date: Wed, 20 Jun 2018 11:43:23 +0200
+Subject: i2c: smbus: kill memory leak on emulated and failed DMA SMBus xfers
+
+From: Peter Rosin <peda@axentia.se>
+
+commit 9aa613674f89d01248ae2e4afe691b515ff8fbb6 upstream.
+
+If DMA safe memory was allocated, but the subsequent I2C transfer
+fails the memory is leaked. Plug this leak.
+
+Fixes: 8a77821e74d6 ("i2c: smbus: use DMA safe buffers for emulated SMBus transactions")
+Signed-off-by: Peter Rosin <peda@axentia.se>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/i2c-core-smbus.c |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/i2c/i2c-core-smbus.c
++++ b/drivers/i2c/i2c-core-smbus.c
+@@ -465,15 +465,18 @@ static s32 i2c_smbus_xfer_emulated(struc
+       status = i2c_transfer(adapter, msg, num);
+       if (status < 0)
+-              return status;
+-      if (status != num)
+-              return -EIO;
++              goto cleanup;
++      if (status != num) {
++              status = -EIO;
++              goto cleanup;
++      }
++      status = 0;
+       /* Check PEC if last message is a read */
+       if (i && (msg[num-1].flags & I2C_M_RD)) {
+               status = i2c_smbus_check_pec(partial_pec, &msg[num-1]);
+               if (status < 0)
+-                      return status;
++                      goto cleanup;
+       }
+       if (read_write == I2C_SMBUS_READ)
+@@ -499,12 +502,13 @@ static s32 i2c_smbus_xfer_emulated(struc
+                       break;
+               }
++cleanup:
+       if (msg[0].flags & I2C_M_DMA_SAFE)
+               kfree(msg[0].buf);
+       if (msg[1].flags & I2C_M_DMA_SAFE)
+               kfree(msg[1].buf);
+-      return 0;
++      return status;
+ }
+ /**
index b0533556c3ddbb25178be5152da76ed8b37994fc..522a1f847156166984c382b719f54c44436e092b 100644 (file)
@@ -38,3 +38,13 @@ ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch
 ext4-add-more-inode-number-paranoia-checks.patch
 ext4-add-more-mount-time-checks-of-the-superblock.patch
 ext4-check-superblock-mapped-prior-to-committing.patch
+hid-i2c-hid-fix-incomplete-report-noise.patch
+hid-hiddev-fix-potential-spectre-v1.patch
+hid-debug-check-length-before-copy_to_user.patch
+hid-core-allow-concurrent-registration-of-drivers.patch
+i2c-core-smbus-fix-a-potential-missing-check-bug.patch
+i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch
+fs-allow-per-device-dax-status-checking-for-filesystems.patch
+dax-change-bdev_dax_supported-to-support-boolean-returns.patch
+dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch
+dm-prevent-dax-mounts-if-not-supported.patch