From cadf598c585ae581108eb4adf30e2c643ade05b7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Feb 2020 11:40:44 +0100 Subject: [PATCH] 4.19-stable patches added patches: dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch dm-fix-potential-for-q-make_request_fn-null-pointer.patch dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch dm-zoned-support-zone-sizes-smaller-than-128mib.patch of-add-of_dma_default_coherent-select-it-on-powerpc.patch --- ...-crash-if-used-in-authenticated-mode.patch | 54 ++++++++ ...l-for-q-make_request_fn-null-pointer.patch | 64 +++++++++ ...nsure-new-block-isn-t-already-in-use.patch | 122 ++++++++++++++++++ ...pport-zone-sizes-smaller-than-128mib.patch | 117 +++++++++++++++++ ...efault_coherent-select-it-on-powerpc.patch | 80 ++++++++++++ queue-4.19/series | 5 + 6 files changed, 442 insertions(+) create mode 100644 queue-4.19/dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch create mode 100644 queue-4.19/dm-fix-potential-for-q-make_request_fn-null-pointer.patch create mode 100644 queue-4.19/dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch create mode 100644 queue-4.19/dm-zoned-support-zone-sizes-smaller-than-128mib.patch create mode 100644 queue-4.19/of-add-of_dma_default_coherent-select-it-on-powerpc.patch diff --git a/queue-4.19/dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch b/queue-4.19/dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch new file mode 100644 index 00000000000..4b271925bf9 --- /dev/null +++ b/queue-4.19/dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch @@ -0,0 +1,54 @@ +From 4ea9471fbd1addb25a4d269991dc724e200ca5b5 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 6 Jan 2020 10:11:47 +0100 +Subject: dm crypt: fix benbi IV constructor crash if used in authenticated mode + +From: Milan Broz + +commit 4ea9471fbd1addb25a4d269991dc724e200ca5b5 upstream. + +If benbi IV is used in AEAD construction, for example: + cryptsetup luksFormat --cipher twofish-xts-benbi --key-size 512 --integrity=hmac-sha256 +the constructor uses wrong skcipher function and crashes: + + BUG: kernel NULL pointer dereference, address: 00000014 + ... + EIP: crypt_iv_benbi_ctr+0x15/0x70 [dm_crypt] + Call Trace: + ? crypt_subkey_size+0x20/0x20 [dm_crypt] + crypt_ctr+0x567/0xfc0 [dm_crypt] + dm_table_add_target+0x15f/0x340 [dm_mod] + +Fix this by properly using crypt_aead_blocksize() in this case. + +Fixes: ef43aa38063a6 ("dm crypt: add cryptographic data integrity protection (authenticated encryption)") +Cc: stable@vger.kernel.org # v4.12+ +Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=941051 +Reported-by: Jerad Simpson +Signed-off-by: Milan Broz +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-crypt.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -482,8 +482,14 @@ static int crypt_iv_essiv_gen(struct cry + static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, + const char *opts) + { +- unsigned bs = crypto_skcipher_blocksize(any_tfm(cc)); +- int log = ilog2(bs); ++ unsigned bs; ++ int log; ++ ++ if (test_bit(CRYPT_MODE_INTEGRITY_AEAD, &cc->cipher_flags)) ++ bs = crypto_aead_blocksize(any_tfm_aead(cc)); ++ else ++ bs = crypto_skcipher_blocksize(any_tfm(cc)); ++ log = ilog2(bs); + + /* we need to calculate how far we must shift the sector count + * to get the cipher block count, we use this shift in _gen */ diff --git a/queue-4.19/dm-fix-potential-for-q-make_request_fn-null-pointer.patch b/queue-4.19/dm-fix-potential-for-q-make_request_fn-null-pointer.patch new file mode 100644 index 00000000000..67acc1cd37e --- /dev/null +++ b/queue-4.19/dm-fix-potential-for-q-make_request_fn-null-pointer.patch @@ -0,0 +1,64 @@ +From 47ace7e012b9f7ad71d43ac9063d335ea3d6820b Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Mon, 27 Jan 2020 14:07:23 -0500 +Subject: dm: fix potential for q->make_request_fn NULL pointer + +From: Mike Snitzer + +commit 47ace7e012b9f7ad71d43ac9063d335ea3d6820b upstream. + +Move blk_queue_make_request() to dm.c:alloc_dev() so that +q->make_request_fn is never NULL during the lifetime of a DM device +(even one that is created without a DM table). + +Otherwise generic_make_request() will crash simply by doing: + dmsetup create -n test + mount /dev/dm-N /mnt + +While at it, move ->congested_data initialization out of +dm.c:alloc_dev() and into the bio-based specific init method. + +Reported-by: Stefan Bader +BugLink: https://bugs.launchpad.net/bugs/1860231 +Fixes: ff36ab34583a ("dm: remove request-based logic from make_request_fn wrapper") +Depends-on: c12c9a3c3860c ("dm: various cleanups to md->queue initialization code") +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1819,6 +1819,7 @@ static void dm_init_normal_md_queue(stru + /* + * Initialize aspects of queue that aren't relevant for blk-mq + */ ++ md->queue->backing_dev_info->congested_data = md; + md->queue->backing_dev_info->congested_fn = dm_any_congested; + } + +@@ -1913,7 +1914,12 @@ static struct mapped_device *alloc_dev(i + if (!md->queue) + goto bad; + md->queue->queuedata = md; +- md->queue->backing_dev_info->congested_data = md; ++ /* ++ * default to bio-based required ->make_request_fn until DM ++ * table is loaded and md->type established. If request-based ++ * table is loaded: blk-mq will override accordingly. ++ */ ++ blk_queue_make_request(md->queue, dm_make_request); + + md->disk = alloc_disk_node(1, md->numa_node_id); + if (!md->disk) +@@ -2242,7 +2248,6 @@ int dm_setup_md_queue(struct mapped_devi + case DM_TYPE_BIO_BASED: + case DM_TYPE_DAX_BIO_BASED: + dm_init_normal_md_queue(md); +- blk_queue_make_request(md->queue, dm_make_request); + break; + case DM_TYPE_NVME_BIO_BASED: + dm_init_normal_md_queue(md); diff --git a/queue-4.19/dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch b/queue-4.19/dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch new file mode 100644 index 00000000000..a46b16cb77c --- /dev/null +++ b/queue-4.19/dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch @@ -0,0 +1,122 @@ +From 4feaef830de7ffdd8352e1fe14ad3bf13c9688f8 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Tue, 7 Jan 2020 11:58:42 +0000 +Subject: dm space map common: fix to ensure new block isn't already in use + +From: Joe Thornber + +commit 4feaef830de7ffdd8352e1fe14ad3bf13c9688f8 upstream. + +The space-maps track the reference counts for disk blocks allocated by +both the thin-provisioning and cache targets. There are variants for +tracking metadata blocks and data blocks. + +Transactionality is implemented by never touching blocks from the +previous transaction, so we can rollback in the event of a crash. + +When allocating a new block we need to ensure the block is free (has +reference count of 0) in both the current and previous transaction. +Prior to this fix we were doing this by searching for a free block in +the previous transaction, and relying on a 'begin' counter to track +where the last allocation in the current transaction was. This +'begin' field was not being updated in all code paths (eg, increment +of a data block reference count due to breaking sharing of a neighbour +block in the same btree leaf). + +This fix keeps the 'begin' field, but now it's just a hint to speed up +the search. Instead the current transaction is searched for a free +block, and then the old transaction is double checked to ensure it's +free. Much simpler. + +This fixes reports of sm_disk_new_block()'s BUG_ON() triggering when +DM thin-provisioning's snapshots are heavily used. + +Reported-by: Eric Wheeler +Cc: stable@vger.kernel.org +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/persistent-data/dm-space-map-common.c | 27 +++++++++++++++++++++ + drivers/md/persistent-data/dm-space-map-common.h | 2 + + drivers/md/persistent-data/dm-space-map-disk.c | 6 +++- + drivers/md/persistent-data/dm-space-map-metadata.c | 5 +++ + 4 files changed, 37 insertions(+), 3 deletions(-) + +--- a/drivers/md/persistent-data/dm-space-map-common.c ++++ b/drivers/md/persistent-data/dm-space-map-common.c +@@ -382,6 +382,33 @@ int sm_ll_find_free_block(struct ll_disk + return -ENOSPC; + } + ++int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, ++ dm_block_t begin, dm_block_t end, dm_block_t *b) ++{ ++ int r; ++ uint32_t count; ++ ++ do { ++ r = sm_ll_find_free_block(new_ll, begin, new_ll->nr_blocks, b); ++ if (r) ++ break; ++ ++ /* double check this block wasn't used in the old transaction */ ++ if (*b >= old_ll->nr_blocks) ++ count = 0; ++ else { ++ r = sm_ll_lookup(old_ll, *b, &count); ++ if (r) ++ break; ++ ++ if (count) ++ begin = *b + 1; ++ } ++ } while (count); ++ ++ return r; ++} ++ + static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b, + int (*mutator)(void *context, uint32_t old, uint32_t *new), + void *context, enum allocation_event *ev) +--- a/drivers/md/persistent-data/dm-space-map-common.h ++++ b/drivers/md/persistent-data/dm-space-map-common.h +@@ -109,6 +109,8 @@ int sm_ll_lookup_bitmap(struct ll_disk * + int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result); + int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, + dm_block_t end, dm_block_t *result); ++int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, ++ dm_block_t begin, dm_block_t end, dm_block_t *result); + int sm_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count, enum allocation_event *ev); + int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev); + int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev); +--- a/drivers/md/persistent-data/dm-space-map-disk.c ++++ b/drivers/md/persistent-data/dm-space-map-disk.c +@@ -167,8 +167,10 @@ static int sm_disk_new_block(struct dm_s + enum allocation_event ev; + struct sm_disk *smd = container_of(sm, struct sm_disk, sm); + +- /* FIXME: we should loop round a couple of times */ +- r = sm_ll_find_free_block(&smd->old_ll, smd->begin, smd->old_ll.nr_blocks, b); ++ /* ++ * Any block we allocate has to be free in both the old and current ll. ++ */ ++ r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b); + if (r) + return r; + +--- a/drivers/md/persistent-data/dm-space-map-metadata.c ++++ b/drivers/md/persistent-data/dm-space-map-metadata.c +@@ -448,7 +448,10 @@ static int sm_metadata_new_block_(struct + enum allocation_event ev; + struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); + +- r = sm_ll_find_free_block(&smm->old_ll, smm->begin, smm->old_ll.nr_blocks, b); ++ /* ++ * Any block we allocate has to be free in both the old and current ll. ++ */ ++ r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b); + if (r) + return r; + diff --git a/queue-4.19/dm-zoned-support-zone-sizes-smaller-than-128mib.patch b/queue-4.19/dm-zoned-support-zone-sizes-smaller-than-128mib.patch new file mode 100644 index 00000000000..0cffc1a3b94 --- /dev/null +++ b/queue-4.19/dm-zoned-support-zone-sizes-smaller-than-128mib.patch @@ -0,0 +1,117 @@ +From b39962950339912978484cdac50069258545d753 Mon Sep 17 00:00:00 2001 +From: Dmitry Fomichev +Date: Mon, 23 Dec 2019 17:05:46 -0800 +Subject: dm zoned: support zone sizes smaller than 128MiB + +From: Dmitry Fomichev + +commit b39962950339912978484cdac50069258545d753 upstream. + +dm-zoned is observed to log failed kernel assertions and not work +correctly when operating against a device with a zone size smaller +than 128MiB (e.g. 32768 bits per 4K block). The reason is that the +bitmap size per zone is calculated as zero with such a small zone +size. Fix this problem and also make the code related to zone bitmap +management be able to handle per zone bitmaps smaller than a single +block. + +A dm-zoned-tools patch is required to properly format dm-zoned devices +with zone sizes smaller than 128MiB. + +Fixes: 3b1a94c88b79 ("dm zoned: drive-managed zoned block device target") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Fomichev +Reviewed-by: Damien Le Moal +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-zoned-metadata.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/drivers/md/dm-zoned-metadata.c ++++ b/drivers/md/dm-zoned-metadata.c +@@ -132,6 +132,7 @@ struct dmz_metadata { + + sector_t zone_bitmap_size; + unsigned int zone_nr_bitmap_blocks; ++ unsigned int zone_bits_per_mblk; + + unsigned int nr_bitmap_blocks; + unsigned int nr_map_blocks; +@@ -1165,7 +1166,10 @@ static int dmz_init_zones(struct dmz_met + + /* Init */ + zmd->zone_bitmap_size = dev->zone_nr_blocks >> 3; +- zmd->zone_nr_bitmap_blocks = zmd->zone_bitmap_size >> DMZ_BLOCK_SHIFT; ++ zmd->zone_nr_bitmap_blocks = ++ max_t(sector_t, 1, zmd->zone_bitmap_size >> DMZ_BLOCK_SHIFT); ++ zmd->zone_bits_per_mblk = min_t(sector_t, dev->zone_nr_blocks, ++ DMZ_BLOCK_SIZE_BITS); + + /* Allocate zone array */ + zmd->zones = kcalloc(dev->nr_zones, sizeof(struct dm_zone), GFP_KERNEL); +@@ -1982,7 +1986,7 @@ int dmz_copy_valid_blocks(struct dmz_met + dmz_release_mblock(zmd, to_mblk); + dmz_release_mblock(zmd, from_mblk); + +- chunk_block += DMZ_BLOCK_SIZE_BITS; ++ chunk_block += zmd->zone_bits_per_mblk; + } + + to_zone->weight = from_zone->weight; +@@ -2043,7 +2047,7 @@ int dmz_validate_blocks(struct dmz_metad + + /* Set bits */ + bit = chunk_block & DMZ_BLOCK_MASK_BITS; +- nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); ++ nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); + + count = dmz_set_bits((unsigned long *)mblk->data, bit, nr_bits); + if (count) { +@@ -2122,7 +2126,7 @@ int dmz_invalidate_blocks(struct dmz_met + + /* Clear bits */ + bit = chunk_block & DMZ_BLOCK_MASK_BITS; +- nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); ++ nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); + + count = dmz_clear_bits((unsigned long *)mblk->data, + bit, nr_bits); +@@ -2182,6 +2186,7 @@ static int dmz_to_next_set_block(struct + { + struct dmz_mblock *mblk; + unsigned int bit, set_bit, nr_bits; ++ unsigned int zone_bits = zmd->zone_bits_per_mblk; + unsigned long *bitmap; + int n = 0; + +@@ -2196,15 +2201,15 @@ static int dmz_to_next_set_block(struct + /* Get offset */ + bitmap = (unsigned long *) mblk->data; + bit = chunk_block & DMZ_BLOCK_MASK_BITS; +- nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); ++ nr_bits = min(nr_blocks, zone_bits - bit); + if (set) +- set_bit = find_next_bit(bitmap, DMZ_BLOCK_SIZE_BITS, bit); ++ set_bit = find_next_bit(bitmap, zone_bits, bit); + else +- set_bit = find_next_zero_bit(bitmap, DMZ_BLOCK_SIZE_BITS, bit); ++ set_bit = find_next_zero_bit(bitmap, zone_bits, bit); + dmz_release_mblock(zmd, mblk); + + n += set_bit - bit; +- if (set_bit < DMZ_BLOCK_SIZE_BITS) ++ if (set_bit < zone_bits) + break; + + nr_blocks -= nr_bits; +@@ -2307,7 +2312,7 @@ static void dmz_get_zone_weight(struct d + /* Count bits in this block */ + bitmap = mblk->data; + bit = chunk_block & DMZ_BLOCK_MASK_BITS; +- nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); ++ nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); + n += dmz_count_bits(bitmap, bit, nr_bits); + + dmz_release_mblock(zmd, mblk); diff --git a/queue-4.19/of-add-of_dma_default_coherent-select-it-on-powerpc.patch b/queue-4.19/of-add-of_dma_default_coherent-select-it-on-powerpc.patch new file mode 100644 index 00000000000..8af995d7125 --- /dev/null +++ b/queue-4.19/of-add-of_dma_default_coherent-select-it-on-powerpc.patch @@ -0,0 +1,80 @@ +From dabf6b36b83a18d57e3d4b9d50544ed040d86255 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Sun, 26 Jan 2020 22:52:47 +1100 +Subject: of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc + +From: Michael Ellerman + +commit dabf6b36b83a18d57e3d4b9d50544ed040d86255 upstream. + +There's an OF helper called of_dma_is_coherent(), which checks if a +device has a "dma-coherent" property to see if the device is coherent +for DMA. + +But on some platforms devices are coherent by default, and on some +platforms it's not possible to update existing device trees to add the +"dma-coherent" property. + +So add a Kconfig symbol to allow arch code to tell +of_dma_is_coherent() that devices are coherent by default, regardless +of the presence of the property. + +Select that symbol on powerpc when NOT_COHERENT_CACHE is not set, ie. +when the system has a coherent cache. + +Fixes: 92ea637edea3 ("of: introduce of_dma_is_coherent() helper") +Cc: stable@vger.kernel.org # v3.16+ +Reported-by: Christian Zigotzky +Tested-by: Christian Zigotzky +Signed-off-by: Michael Ellerman +Reviewed-by: Ulf Hansson +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/Kconfig | 1 + + drivers/of/Kconfig | 4 ++++ + drivers/of/address.c | 6 +++++- + 3 files changed, 10 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -230,6 +230,7 @@ config PPC + select NEED_SG_DMA_LENGTH + select NO_BOOTMEM + select OF ++ select OF_DMA_DEFAULT_COHERENT if !NOT_COHERENT_CACHE + select OF_EARLY_FLATTREE + select OF_RESERVED_MEM + select OLD_SIGACTION if PPC32 +--- a/drivers/of/Kconfig ++++ b/drivers/of/Kconfig +@@ -103,4 +103,8 @@ config OF_OVERLAY + config OF_NUMA + bool + ++config OF_DMA_DEFAULT_COHERENT ++ # arches should select this if DMA is coherent by default for OF devices ++ bool ++ + endif # OF +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -970,12 +970,16 @@ EXPORT_SYMBOL_GPL(of_dma_get_range); + * @np: device node + * + * It returns true if "dma-coherent" property was found +- * for this device in DT. ++ * for this device in the DT, or if DMA is coherent by ++ * default for OF devices on the current platform. + */ + bool of_dma_is_coherent(struct device_node *np) + { + struct device_node *node = of_node_get(np); + ++ if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT)) ++ return true; ++ + while (node) { + if (of_property_read_bool(node, "dma-coherent")) { + of_node_put(node); diff --git a/queue-4.19/series b/queue-4.19/series index 5d3d1f335d5..7f8c873fec3 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -82,3 +82,8 @@ f2fs-choose-hardlimit-when-softlimit-is-larger-than-hardlimit-in-f2fs_statfs_pro f2fs-fix-miscounted-block-limit-in-f2fs_statfs_project.patch f2fs-code-cleanup-for-f2fs_statfs_project.patch pm-core-fix-handling-of-devices-deleted-during-system-wide-resume.patch +of-add-of_dma_default_coherent-select-it-on-powerpc.patch +dm-zoned-support-zone-sizes-smaller-than-128mib.patch +dm-space-map-common-fix-to-ensure-new-block-isn-t-already-in-use.patch +dm-crypt-fix-benbi-iv-constructor-crash-if-used-in-authenticated-mode.patch +dm-fix-potential-for-q-make_request_fn-null-pointer.patch -- 2.47.3