From: Greg Kroah-Hartman Date: Tue, 10 Jul 2018 14:42:19 +0000 (+0200) Subject: 4.17-stable patches X-Git-Tag: v3.18.115~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5a271bfaf3d79ab385b57d35c469dcca9d698903;p=thirdparty%2Fkernel%2Fstable-queue.git 4.17-stable patches 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 --- 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 index 00000000000..65b0b8ca970 --- /dev/null +++ b/queue-4.17/dax-change-bdev_dax_supported-to-support-boolean-returns.patch @@ -0,0 +1,180 @@ +From 80660f20252d6f76c9f203874ad7c7a4a8508cf8 Mon Sep 17 00:00:00 2001 +From: Dave Jiang +Date: Wed, 30 May 2018 13:03:46 -0700 +Subject: dax: change bdev_dax_supported() to support boolean returns + +From: Dave Jiang + +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 +Signed-off-by: Ross Zwisler +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a454253b444 --- /dev/null +++ b/queue-4.17/dax-check-for-queue_flag_dax-in-bdev_dax_supported.patch @@ -0,0 +1,53 @@ +From 15256f6cc4b44f2e70503758150267fd2a53c0d6 Mon Sep 17 00:00:00 2001 +From: Ross Zwisler +Date: Tue, 26 Jun 2018 16:30:40 -0600 +Subject: dax: check for QUEUE_FLAG_DAX in bdev_dax_supported() + +From: Ross Zwisler + +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 +Suggested-by: Mike Snitzer +Fixes: commit 545ed20e6df6 ("dm: add infrastructure for DAX support") +Cc: stable@vger.kernel.org +Acked-by: Dan Williams +Reviewed-by: Toshi Kani +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..9c26bfd26c6 --- /dev/null +++ b/queue-4.17/dm-prevent-dax-mounts-if-not-supported.patch @@ -0,0 +1,72 @@ +From dbc626597c39b24cefce09fbd8e9dea85869a801 Mon Sep 17 00:00:00 2001 +From: Ross Zwisler +Date: Tue, 26 Jun 2018 16:30:41 -0600 +Subject: dm: prevent DAX mounts if not supported + +From: Ross Zwisler + +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 +Fixes: commit 545ed20e6df6 ("dm: add infrastructure for DAX support") +Cc: stable@vger.kernel.org +Acked-by: Dan Williams +Reviewed-by: Toshi Kani +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..eb4204b320d --- /dev/null +++ b/queue-4.17/fs-allow-per-device-dax-status-checking-for-filesystems.patch @@ -0,0 +1,236 @@ +From ba23cba9b3bdc967aabdc6ff1e3e9b11ce05bb4f Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Wed, 30 May 2018 13:03:45 -0700 +Subject: fs: allow per-device dax status checking for filesystems + +From: Darrick J. Wong + +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 +[rez: Re-added __bdev_dax_supported() for !CONFIG_FS_DAX cases] +Signed-off-by: Ross Zwisler +Reviewed-by: Eric Sandeen +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..a7e33f0ea69 --- /dev/null +++ b/queue-4.17/hid-core-allow-concurrent-registration-of-drivers.patch @@ -0,0 +1,72 @@ +From 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Thu, 31 May 2018 13:49:29 +0200 +Subject: HID: core: allow concurrent registration of drivers + +From: Benjamin Tissoires + +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 +Signed-off-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..18f1cce850a --- /dev/null +++ b/queue-4.17/hid-debug-check-length-before-copy_to_user.patch @@ -0,0 +1,53 @@ +From 717adfdaf14704fd3ec7fa2c04520c0723247eac Mon Sep 17 00:00:00 2001 +From: Daniel Rosenberg +Date: Mon, 2 Jul 2018 16:59:37 -0700 +Subject: HID: debug: check length before copy_to_user() + +From: Daniel Rosenberg + +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 +Reviewed-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..209d980f383 --- /dev/null +++ b/queue-4.17/hid-hiddev-fix-potential-spectre-v1.patch @@ -0,0 +1,90 @@ +From 4f65245f2d178b9cba48350620d76faa4a098841 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Fri, 29 Jun 2018 17:08:44 -0500 +Subject: HID: hiddev: fix potential Spectre v1 + +From: Gustavo A. R. Silva + +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 +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #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 index 00000000000..087ef31f75f --- /dev/null +++ b/queue-4.17/hid-i2c-hid-fix-incomplete-report-noise.patch @@ -0,0 +1,46 @@ +From ef6eaf27274c0351f7059163918f3795da13199c Mon Sep 17 00:00:00 2001 +From: Jason Andryuk +Date: Fri, 22 Jun 2018 12:25:49 -0400 +Subject: HID: i2c-hid: Fix "incomplete report" noise + +From: Jason Andryuk + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Jason Andryuk +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e7d859aa8d4 --- /dev/null +++ b/queue-4.17/i2c-core-smbus-fix-a-potential-missing-check-bug.patch @@ -0,0 +1,44 @@ +From 8e03477cb709b73a2c1e1f4349ee3b7b33c50416 Mon Sep 17 00:00:00 2001 +From: Wenwen Wang +Date: Sat, 5 May 2018 08:02:21 -0500 +Subject: i2c: core: smbus: fix a potential missing-check bug + +From: Wenwen Wang + +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 +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9266fa4a517 --- /dev/null +++ b/queue-4.17/i2c-smbus-kill-memory-leak-on-emulated-and-failed-dma-smbus-xfers.patch @@ -0,0 +1,62 @@ +From 9aa613674f89d01248ae2e4afe691b515ff8fbb6 Mon Sep 17 00:00:00 2001 +From: Peter Rosin +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 + +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 +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + + /** diff --git a/queue-4.17/series b/queue-4.17/series index b0533556c3d..522a1f84715 100644 --- a/queue-4.17/series +++ b/queue-4.17/series @@ -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