--- /dev/null
+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)
--- /dev/null
+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) {
--- /dev/null
+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);
--- /dev/null
+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;
+ }
--- /dev/null
+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 */
--- /dev/null
+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;
+ }
+
+ }
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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)) {
--- /dev/null
+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;
+ }
+
+ /**
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