From: Greg Kroah-Hartman Date: Wed, 10 Mar 2021 12:15:41 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.261~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1145bc13ff0c49fd79f0285718f3a6a6fb28bda5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: dm-table-fix-dax-iterate_devices-based-device-capability-checks.patch dm-table-fix-iterate_devices-based-device-capability-checks.patch iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch --- diff --git a/queue-4.9/dm-table-fix-dax-iterate_devices-based-device-capability-checks.patch b/queue-4.9/dm-table-fix-dax-iterate_devices-based-device-capability-checks.patch new file mode 100644 index 00000000000..8370e106ee1 --- /dev/null +++ b/queue-4.9/dm-table-fix-dax-iterate_devices-based-device-capability-checks.patch @@ -0,0 +1,53 @@ +From foo@baz Wed Mar 10 01:11:05 PM CET 2021 +From: Jeffle Xu +Date: Tue, 9 Mar 2021 11:20:23 +0800 +Subject: dm table: fix DAX iterate_devices based device capability checks +To: snitzer@redhat.com, gregkh@linuxfoundation.org, sashal@kernel.org +Cc: stable@vger.kernel.org, jefflexu@linux.alibaba.com +Message-ID: <20210309032023.98465-3-jefflexu@linux.alibaba.com> + +From: Jeffle Xu + +commit 5b0fab508992c2e120971da658ce80027acbc405 upstream. + +Fix dm_table_supports_dax() and invert logic of both +iterate_devices_callout_fn so that all devices' DAX capabilities are +properly checked. + +Fixes: 545ed20e6df6 ("dm: add infrastructure for DAX support") +Cc: stable@vger.kernel.org +Signed-off-by: Jeffle Xu +Signed-off-by: Mike Snitzer +[jeffle: no dax write cache, no dax synchronous] +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-table.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -848,12 +848,12 @@ void dm_table_set_type(struct dm_table * + } + 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) ++static int device_not_dax_capable(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 q && !blk_queue_dax(q); + } + + static bool dm_table_supports_dax(struct dm_table *t) +@@ -869,7 +869,7 @@ static bool dm_table_supports_dax(struct + return false; + + if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, device_supports_dax, NULL)) ++ ti->type->iterate_devices(ti, device_not_dax_capable, NULL)) + return false; + } + diff --git a/queue-4.9/dm-table-fix-iterate_devices-based-device-capability-checks.patch b/queue-4.9/dm-table-fix-iterate_devices-based-device-capability-checks.patch new file mode 100644 index 00000000000..7a17d707f94 --- /dev/null +++ b/queue-4.9/dm-table-fix-iterate_devices-based-device-capability-checks.patch @@ -0,0 +1,179 @@ +From foo@baz Wed Mar 10 01:11:05 PM CET 2021 +From: Jeffle Xu +Date: Tue, 9 Mar 2021 11:20:22 +0800 +Subject: dm table: fix iterate_devices based device capability checks +To: snitzer@redhat.com, gregkh@linuxfoundation.org, sashal@kernel.org +Cc: stable@vger.kernel.org, jefflexu@linux.alibaba.com +Message-ID: <20210309032023.98465-2-jefflexu@linux.alibaba.com> + +From: Jeffle Xu + +commit a4c8dd9c2d0987cf542a2a0c42684c9c6d78a04e upstream. + +According to the definition of dm_iterate_devices_fn: + * This function must iterate through each section of device used by the + * target until it encounters a non-zero return code, which it then returns. + * Returns zero if no callout returned non-zero. + +For some target type (e.g. dm-stripe), one call of iterate_devices() may +iterate multiple underlying devices internally, in which case a non-zero +return code returned by iterate_devices_callout_fn will stop the iteration +in advance. No iterate_devices_callout_fn should return non-zero unless +device iteration should stop. + +Rename dm_table_requires_stable_pages() to dm_table_any_dev_attr() and +elevate it for reuse to stop iterating (and return non-zero) on the +first device that causes iterate_devices_callout_fn to return non-zero. +Use dm_table_any_dev_attr() to properly iterate through devices. + +Rename device_is_nonrot() to device_is_rotational() and invert logic +accordingly to fix improper disposition. + +[jeffle: backport notes] +No stable writes. Also convert the no_sg_merge capability check, which +is introduced by commit 200612ec33e5 ("dm table: propagate +QUEUE_FLAG_NO_SG_MERGE"), and removed since commit 2705c93742e9 ("block: +kill QUEUE_FLAG_NO_SG_MERGE") in v5.1. + +Fixes: c3c4555edd10 ("dm table: clear add_random unless all devices have it set") +Fixes: 4693c9668fdc ("dm table: propagate non rotational flag") +Cc: stable@vger.kernel.org +Signed-off-by: Jeffle Xu +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-table.c | 83 +++++++++++++++++++++++++++++++------------------- + 1 file changed, 53 insertions(+), 30 deletions(-) + +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -1306,6 +1306,46 @@ struct dm_target *dm_table_find_target(s + return &t->targets[(KEYS_PER_NODE * n) + k]; + } + ++/* ++ * type->iterate_devices() should be called when the sanity check needs to ++ * iterate and check all underlying data devices. iterate_devices() will ++ * iterate all underlying data devices until it encounters a non-zero return ++ * code, returned by whether the input iterate_devices_callout_fn, or ++ * iterate_devices() itself internally. ++ * ++ * For some target type (e.g. dm-stripe), one call of iterate_devices() may ++ * iterate multiple underlying devices internally, in which case a non-zero ++ * return code returned by iterate_devices_callout_fn will stop the iteration ++ * in advance. ++ * ++ * Cases requiring _any_ underlying device supporting some kind of attribute, ++ * should use the iteration structure like dm_table_any_dev_attr(), or call ++ * it directly. @func should handle semantics of positive examples, e.g. ++ * capable of something. ++ * ++ * Cases requiring _all_ underlying devices supporting some kind of attribute, ++ * should use the iteration structure like dm_table_supports_nowait() or ++ * dm_table_supports_discards(). Or introduce dm_table_all_devs_attr() that ++ * uses an @anti_func that handle semantics of counter examples, e.g. not ++ * capable of something. So: return !dm_table_any_dev_attr(t, anti_func); ++ */ ++static bool dm_table_any_dev_attr(struct dm_table *t, ++ iterate_devices_callout_fn func) ++{ ++ struct dm_target *ti; ++ unsigned int i; ++ ++ for (i = 0; i < dm_table_get_num_targets(t); i++) { ++ ti = dm_table_get_target(t, i); ++ ++ if (ti->type->iterate_devices && ++ ti->type->iterate_devices(ti, func, NULL)) ++ return true; ++ } ++ ++ return false; ++} ++ + static int count_device(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) + { +@@ -1476,12 +1516,12 @@ static bool dm_table_discard_zeroes_data + return true; + } + +-static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int device_is_rotational(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_nonrot(q); ++ return q && !blk_queue_nonrot(q); + } + + static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev, +@@ -1492,29 +1532,12 @@ static int device_is_not_random(struct d + return q && !blk_queue_add_random(q); + } + +-static int queue_supports_sg_merge(struct dm_target *ti, struct dm_dev *dev, +- sector_t start, sector_t len, void *data) ++static int queue_no_sg_merge(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 && !test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); +-} +- +-static bool dm_table_all_devices_attribute(struct dm_table *t, +- iterate_devices_callout_fn func) +-{ +- struct dm_target *ti; +- unsigned i = 0; +- +- while (i < dm_table_get_num_targets(t)) { +- ti = dm_table_get_target(t, i++); +- +- if (!ti->type->iterate_devices || +- !ti->type->iterate_devices(ti, func, NULL)) +- return false; +- } +- +- return true; ++ return q && test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); + } + + static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, +@@ -1607,18 +1630,18 @@ void dm_table_set_restrictions(struct dm + q->limits.discard_zeroes_data = 0; + + /* Ensure that all underlying devices are non-rotational. */ +- if (dm_table_all_devices_attribute(t, device_is_nonrot)) +- queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); +- else ++ if (dm_table_any_dev_attr(t, device_is_rotational)) + queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q); ++ else ++ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); + + if (!dm_table_supports_write_same(t)) + q->limits.max_write_same_sectors = 0; + +- if (dm_table_all_devices_attribute(t, queue_supports_sg_merge)) +- queue_flag_clear_unlocked(QUEUE_FLAG_NO_SG_MERGE, q); +- else ++ if (dm_table_any_dev_attr(t, queue_no_sg_merge)) + queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q); ++ else ++ queue_flag_clear_unlocked(QUEUE_FLAG_NO_SG_MERGE, q); + + dm_table_verify_integrity(t); + +@@ -1628,7 +1651,7 @@ void dm_table_set_restrictions(struct dm + * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not + * have it set. + */ +- if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random)) ++ if (blk_queue_add_random(q) && dm_table_any_dev_attr(t, device_is_not_random)) + queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q); + + /* diff --git a/queue-4.9/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch b/queue-4.9/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch new file mode 100644 index 00000000000..7e565c5fb30 --- /dev/null +++ b/queue-4.9/iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch @@ -0,0 +1,79 @@ +From 140456f994195b568ecd7fc2287a34eadffef3ca Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Wed, 17 Feb 2021 17:30:04 +0300 +Subject: iommu/amd: Fix sleeping in atomic in increase_address_space() + +From: Andrey Ryabinin + +commit 140456f994195b568ecd7fc2287a34eadffef3ca upstream. + +increase_address_space() calls get_zeroed_page(gfp) under spin_lock with +disabled interrupts. gfp flags passed to increase_address_space() may allow +sleeping, so it comes to this: + + BUG: sleeping function called from invalid context at mm/page_alloc.c:4342 + in_atomic(): 1, irqs_disabled(): 1, pid: 21555, name: epdcbbf1qnhbsd8 + + Call Trace: + dump_stack+0x66/0x8b + ___might_sleep+0xec/0x110 + __alloc_pages_nodemask+0x104/0x300 + get_zeroed_page+0x15/0x40 + iommu_map_page+0xdd/0x3e0 + amd_iommu_map+0x50/0x70 + iommu_map+0x106/0x220 + vfio_iommu_type1_ioctl+0x76e/0x950 [vfio_iommu_type1] + do_vfs_ioctl+0xa3/0x6f0 + ksys_ioctl+0x66/0x70 + __x64_sys_ioctl+0x16/0x20 + do_syscall_64+0x4e/0x100 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fix this by moving get_zeroed_page() out of spin_lock/unlock section. + +Fixes: 754265bcab ("iommu/amd: Fix race in increase_address_space()") +Signed-off-by: Andrey Ryabinin +Acked-by: Will Deacon +Cc: +Link: https://lore.kernel.org/r/20210217143004.19165-1-arbn@yandex-team.com +Signed-off-by: Joerg Roedel +Signed-off-by: Andrey Ryabinin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -1331,24 +1331,26 @@ static void increase_address_space(struc + unsigned long flags; + u64 *pte; + ++ pte = (void *)get_zeroed_page(gfp); ++ if (!pte) ++ goto out; ++ + spin_lock_irqsave(&domain->lock, flags); + + if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) + /* address space already 64 bit large */ + goto out; + +- pte = (void *)get_zeroed_page(gfp); +- if (!pte) +- goto out; +- + *pte = PM_LEVEL_PDE(domain->mode, + virt_to_phys(domain->pt_root)); + domain->pt_root = pte; + domain->mode += 1; + domain->updated = true; ++ pte = NULL; + + out: + spin_unlock_irqrestore(&domain->lock, flags); ++ free_page((unsigned long)pte); + + return; + } diff --git a/queue-4.9/series b/queue-4.9/series index 60d0426cbca..ac010d76ca3 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -3,3 +3,6 @@ btrfs-fix-raid6-qstripe-kmap.patch usbip-tools-fix-build-error-for-multiple-definition.patch alsa-ctxfi-cthw20k2-fix-mask-on-conf-to-allow-4-bits.patch rsxx-return-efault-if-copy_to_user-fails.patch +dm-table-fix-iterate_devices-based-device-capability-checks.patch +dm-table-fix-dax-iterate_devices-based-device-capability-checks.patch +iommu-amd-fix-sleeping-in-atomic-in-increase_address_space.patch