From: Greg Kroah-Hartman Date: Sun, 7 Mar 2021 14:15:26 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v5.4.104~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9024d1e23b9f4a1a22f1b8d41fc2a7472670d5d9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: btrfs-fix-raid6-qstripe-kmap.patch btrfs-fix-warning-when-creating-a-directory-with-smack-enabled.patch btrfs-free-correct-amount-of-space-in-btrfs_delayed_inode_reserve_metadata.patch btrfs-raid56-simplify-tracking-of-q-stripe-presence.patch btrfs-unlock-extents-in-btrfs_zero_range-in-case-of-quota-reservation-errors.patch btrfs-validate-qgroup-inherit-for-snap_create_v2-ioctl.patch dm-bufio-subtract-the-number-of-initial-sectors-in-dm_bufio_get_device_size.patch dm-verity-fix-fec-for-rs-roots-unaligned-to-block-size.patch drm-amdgpu-fix-parameter-error-of-rreg32_pcie-in-amdgpu_regs_pcie.patch pm-runtime-update-device-status-before-letting-suppliers-suspend.patch tpm-tpm_tis-decorate-tpm_get_timeouts-with-request_locality.patch tpm-tpm_tis-decorate-tpm_tis_gen_interrupt-with-request_locality.patch --- diff --git a/queue-5.4/btrfs-fix-raid6-qstripe-kmap.patch b/queue-5.4/btrfs-fix-raid6-qstripe-kmap.patch new file mode 100644 index 00000000000..fedd94f3577 --- /dev/null +++ b/queue-5.4/btrfs-fix-raid6-qstripe-kmap.patch @@ -0,0 +1,94 @@ +From d70cef0d46729808dc53f145372c02b145c92604 Mon Sep 17 00:00:00 2001 +From: Ira Weiny +Date: Wed, 27 Jan 2021 22:15:03 -0800 +Subject: btrfs: fix raid6 qstripe kmap + +From: Ira Weiny + +commit d70cef0d46729808dc53f145372c02b145c92604 upstream. + +When a qstripe is required an extra page is allocated and mapped. There +were 3 problems: + +1) There is no corresponding call of kunmap() for the qstripe page. +2) There is no reason to map the qstripe page more than once if the + number of bits set in rbio->dbitmap is greater than one. +3) There is no reason to map the parity page and unmap it each time + through the loop. + +The page memory can continue to be reused with a single mapping on each +iteration by raid6_call.gen_syndrome() without remapping. So map the +page for the duration of the loop. + +Similarly, improve the algorithm by mapping the parity page just 1 time. + +Fixes: 5a6ac9eacb49 ("Btrfs, raid56: support parity scrub on raid56") +CC: stable@vger.kernel.org # 4.4.x: c17af96554a8: btrfs: raid56: simplify tracking of Q stripe presence +CC: stable@vger.kernel.org # 4.4.x +Signed-off-by: Ira Weiny +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/raid56.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -2390,16 +2390,21 @@ static noinline void finish_parity_scrub + SetPageUptodate(p_page); + + if (has_qstripe) { ++ /* RAID6, allocate and map temp space for the Q stripe */ + q_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (!q_page) { + __free_page(p_page); + goto cleanup; + } + SetPageUptodate(q_page); ++ pointers[rbio->real_stripes - 1] = kmap(q_page); + } + + atomic_set(&rbio->error, 0); + ++ /* Map the parity stripe just once */ ++ pointers[nr_data] = kmap(p_page); ++ + for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { + struct page *p; + void *parity; +@@ -2409,16 +2414,8 @@ static noinline void finish_parity_scrub + pointers[stripe] = kmap(p); + } + +- /* then add the parity stripe */ +- pointers[stripe++] = kmap(p_page); +- + if (has_qstripe) { +- /* +- * raid6, add the qstripe and call the +- * library function to fill in our p/q +- */ +- pointers[stripe++] = kmap(q_page); +- ++ /* RAID6, call the library function to fill in our P/Q */ + raid6_call.gen_syndrome(rbio->real_stripes, PAGE_SIZE, + pointers); + } else { +@@ -2439,12 +2436,14 @@ static noinline void finish_parity_scrub + + for (stripe = 0; stripe < nr_data; stripe++) + kunmap(page_in_rbio(rbio, stripe, pagenr, 0)); +- kunmap(p_page); + } + ++ kunmap(p_page); + __free_page(p_page); +- if (q_page) ++ if (q_page) { ++ kunmap(q_page); + __free_page(q_page); ++ } + + writeback: + /* diff --git a/queue-5.4/btrfs-fix-warning-when-creating-a-directory-with-smack-enabled.patch b/queue-5.4/btrfs-fix-warning-when-creating-a-directory-with-smack-enabled.patch new file mode 100644 index 00000000000..65aca97fb46 --- /dev/null +++ b/queue-5.4/btrfs-fix-warning-when-creating-a-directory-with-smack-enabled.patch @@ -0,0 +1,146 @@ +From fd57a98d6f0c98fa295813087f13afb26c224e73 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 26 Feb 2021 17:51:44 +0000 +Subject: btrfs: fix warning when creating a directory with smack enabled + +From: Filipe Manana + +commit fd57a98d6f0c98fa295813087f13afb26c224e73 upstream. + +When we have smack enabled, during the creation of a directory smack may +attempt to add a "smack transmute" xattr on the inode, which results in +the following warning and trace: + + WARNING: CPU: 3 PID: 2548 at fs/btrfs/transaction.c:537 start_transaction+0x489/0x4f0 + Modules linked in: nft_objref nf_conntrack_netbios_ns (...) + CPU: 3 PID: 2548 Comm: mkdir Not tainted 5.9.0-rc2smack+ #81 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014 + RIP: 0010:start_transaction+0x489/0x4f0 + Code: e9 be fc ff ff (...) + RSP: 0018:ffffc90001887d10 EFLAGS: 00010202 + RAX: ffff88816f1e0000 RBX: 0000000000000201 RCX: 0000000000000003 + RDX: 0000000000000201 RSI: 0000000000000002 RDI: ffff888177849000 + RBP: ffff888177849000 R08: 0000000000000001 R09: 0000000000000004 + R10: ffffffff825e8f7a R11: 0000000000000003 R12: ffffffffffffffe2 + R13: 0000000000000000 R14: ffff88803d884270 R15: ffff8881680d8000 + FS: 00007f67317b8440(0000) GS:ffff88817bcc0000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 00007f67247a22a8 CR3: 000000004bfbc002 CR4: 0000000000370ee0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + ? slab_free_freelist_hook+0xea/0x1b0 + ? trace_hardirqs_on+0x1c/0xe0 + btrfs_setxattr_trans+0x3c/0xf0 + __vfs_setxattr+0x63/0x80 + smack_d_instantiate+0x2d3/0x360 + security_d_instantiate+0x29/0x40 + d_instantiate_new+0x38/0x90 + btrfs_mkdir+0x1cf/0x1e0 + vfs_mkdir+0x14f/0x200 + do_mkdirat+0x6d/0x110 + do_syscall_64+0x2d/0x40 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + RIP: 0033:0x7f673196ae6b + Code: 8b 05 11 (...) + RSP: 002b:00007ffc3c679b18 EFLAGS: 00000246 ORIG_RAX: 0000000000000053 + RAX: ffffffffffffffda RBX: 00000000000001ff RCX: 00007f673196ae6b + RDX: 0000000000000000 RSI: 00000000000001ff RDI: 00007ffc3c67a30d + RBP: 00007ffc3c67a30d R08: 00000000000001ff R09: 0000000000000000 + R10: 000055d3e39fe930 R11: 0000000000000246 R12: 0000000000000000 + R13: 00007ffc3c679cd8 R14: 00007ffc3c67a30d R15: 00007ffc3c679ce0 + irq event stamp: 11029 + hardirqs last enabled at (11037): [] console_unlock+0x486/0x670 + hardirqs last disabled at (11044): [] console_unlock+0xa1/0x670 + softirqs last enabled at (8864): [] asm_call_on_stack+0xf/0x20 + softirqs last disabled at (8851): [] asm_call_on_stack+0xf/0x20 + +This happens because at btrfs_mkdir() we call d_instantiate_new() while +holding a transaction handle, which results in the following call chain: + + btrfs_mkdir() + trans = btrfs_start_transaction(root, 5); + + d_instantiate_new() + smack_d_instantiate() + __vfs_setxattr() + btrfs_setxattr_trans() + btrfs_start_transaction() + start_transaction() + WARN_ON() + --> a tansaction start has TRANS_EXTWRITERS + set in its type + h->orig_rsv = h->block_rsv + h->block_rsv = NULL + + btrfs_end_transaction(trans) + +Besides the warning triggered at start_transaction, we set the handle's +block_rsv to NULL which may cause some surprises later on. + +So fix this by making btrfs_setxattr_trans() not start a transaction when +we already have a handle on one, stored in current->journal_info, and use +that handle. We are good to use the handle because at btrfs_mkdir() we did +reserve space for the xattr and the inode item. + +Reported-by: Casey Schaufler +CC: stable@vger.kernel.org # 5.4+ +Acked-by: Casey Schaufler +Tested-by: Casey Schaufler +Link: https://lore.kernel.org/linux-btrfs/434d856f-bd7b-4889-a6ec-e81aaebfa735@schaufler-ca.com/ +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/xattr.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/xattr.c ++++ b/fs/btrfs/xattr.c +@@ -227,11 +227,33 @@ int btrfs_setxattr_trans(struct inode *i + { + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; ++ const bool start_trans = (current->journal_info == NULL); + int ret; + +- trans = btrfs_start_transaction(root, 2); +- if (IS_ERR(trans)) +- return PTR_ERR(trans); ++ if (start_trans) { ++ /* ++ * 1 unit for inserting/updating/deleting the xattr ++ * 1 unit for the inode item update ++ */ ++ trans = btrfs_start_transaction(root, 2); ++ if (IS_ERR(trans)) ++ return PTR_ERR(trans); ++ } else { ++ /* ++ * This can happen when smack is enabled and a directory is being ++ * created. It happens through d_instantiate_new(), which calls ++ * smack_d_instantiate(), which in turn calls __vfs_setxattr() to ++ * set the transmute xattr (XATTR_NAME_SMACKTRANSMUTE) on the ++ * inode. We have already reserved space for the xattr and inode ++ * update at btrfs_mkdir(), so just use the transaction handle. ++ * We don't join or start a transaction, as that will reset the ++ * block_rsv of the handle and trigger a warning for the start ++ * case. ++ */ ++ ASSERT(strncmp(name, XATTR_SECURITY_PREFIX, ++ XATTR_SECURITY_PREFIX_LEN) == 0); ++ trans = current->journal_info; ++ } + + ret = btrfs_setxattr(trans, inode, name, value, size, flags); + if (ret) +@@ -242,7 +264,8 @@ int btrfs_setxattr_trans(struct inode *i + ret = btrfs_update_inode(trans, root, inode); + BUG_ON(ret); + out: +- btrfs_end_transaction(trans); ++ if (start_trans) ++ btrfs_end_transaction(trans); + return ret; + } + diff --git a/queue-5.4/btrfs-free-correct-amount-of-space-in-btrfs_delayed_inode_reserve_metadata.patch b/queue-5.4/btrfs-free-correct-amount-of-space-in-btrfs_delayed_inode_reserve_metadata.patch new file mode 100644 index 00000000000..b6b54b03130 --- /dev/null +++ b/queue-5.4/btrfs-free-correct-amount-of-space-in-btrfs_delayed_inode_reserve_metadata.patch @@ -0,0 +1,37 @@ +From 0f9c03d824f6f522d3bc43629635c9765546ebc5 Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Mon, 22 Feb 2021 18:40:42 +0200 +Subject: btrfs: free correct amount of space in btrfs_delayed_inode_reserve_metadata + +From: Nikolay Borisov + +commit 0f9c03d824f6f522d3bc43629635c9765546ebc5 upstream. + +Following commit f218ea6c4792 ("btrfs: delayed-inode: Remove wrong +qgroup meta reservation calls") this function now reserves num_bytes, +rather than the fixed amount of nodesize. As such this requires the +same amount to be freed in case of failure. Fix this by adjusting +the amount we are freeing. + +Fixes: f218ea6c4792 ("btrfs: delayed-inode: Remove wrong qgroup meta reservation calls") +CC: stable@vger.kernel.org # 4.19+ +Reviewed-by: Qu Wenruo +Signed-off-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/delayed-inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/delayed-inode.c ++++ b/fs/btrfs/delayed-inode.c +@@ -649,7 +649,7 @@ static int btrfs_delayed_inode_reserve_m + btrfs_ino(inode), + num_bytes, 1); + } else { +- btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize); ++ btrfs_qgroup_free_meta_prealloc(root, num_bytes); + } + return ret; + } diff --git a/queue-5.4/btrfs-raid56-simplify-tracking-of-q-stripe-presence.patch b/queue-5.4/btrfs-raid56-simplify-tracking-of-q-stripe-presence.patch new file mode 100644 index 00000000000..63c2e1aa36f --- /dev/null +++ b/queue-5.4/btrfs-raid56-simplify-tracking-of-q-stripe-presence.patch @@ -0,0 +1,126 @@ +From c17af96554a8a8777cbb0fd53b8497250e548b43 Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Wed, 19 Feb 2020 15:17:20 +0100 +Subject: btrfs: raid56: simplify tracking of Q stripe presence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Sterba + +commit c17af96554a8a8777cbb0fd53b8497250e548b43 upstream. + +There are temporary variables tracking the index of P and Q stripes, but +none of them is really used as such, merely for determining if the Q +stripe is present. This leads to compiler warnings with +-Wunused-but-set-variable and has been reported several times. + +fs/btrfs/raid56.c: In function ‘finish_rmw’: +fs/btrfs/raid56.c:1199:6: warning: variable ‘p_stripe’ set but not used [-Wunused-but-set-variable] + 1199 | int p_stripe = -1; + | ^~~~~~~~ +fs/btrfs/raid56.c: In function ‘finish_parity_scrub’: +fs/btrfs/raid56.c:2356:6: warning: variable ‘p_stripe’ set but not used [-Wunused-but-set-variable] + 2356 | int p_stripe = -1; + | ^~~~~~~~ + +Replace the two variables with one that has a clear meaning and also get +rid of the warnings. The logic that verifies that there are only 2 +valid cases is unchanged. + +Reviewed-by: Johannes Thumshirn +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/raid56.c | 37 +++++++++++++++---------------------- + 1 file changed, 15 insertions(+), 22 deletions(-) + +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -1198,22 +1198,19 @@ static noinline void finish_rmw(struct b + int nr_data = rbio->nr_data; + int stripe; + int pagenr; +- int p_stripe = -1; +- int q_stripe = -1; ++ bool has_qstripe; + struct bio_list bio_list; + struct bio *bio; + int ret; + + bio_list_init(&bio_list); + +- if (rbio->real_stripes - rbio->nr_data == 1) { +- p_stripe = rbio->real_stripes - 1; +- } else if (rbio->real_stripes - rbio->nr_data == 2) { +- p_stripe = rbio->real_stripes - 2; +- q_stripe = rbio->real_stripes - 1; +- } else { ++ if (rbio->real_stripes - rbio->nr_data == 1) ++ has_qstripe = false; ++ else if (rbio->real_stripes - rbio->nr_data == 2) ++ has_qstripe = true; ++ else + BUG(); +- } + + /* at this point we either have a full stripe, + * or we've read the full stripe from the drive. +@@ -1257,7 +1254,7 @@ static noinline void finish_rmw(struct b + SetPageUptodate(p); + pointers[stripe++] = kmap(p); + +- if (q_stripe != -1) { ++ if (has_qstripe) { + + /* + * raid6, add the qstripe and call the +@@ -2355,8 +2352,7 @@ static noinline void finish_parity_scrub + int nr_data = rbio->nr_data; + int stripe; + int pagenr; +- int p_stripe = -1; +- int q_stripe = -1; ++ bool has_qstripe; + struct page *p_page = NULL; + struct page *q_page = NULL; + struct bio_list bio_list; +@@ -2366,14 +2362,12 @@ static noinline void finish_parity_scrub + + bio_list_init(&bio_list); + +- if (rbio->real_stripes - rbio->nr_data == 1) { +- p_stripe = rbio->real_stripes - 1; +- } else if (rbio->real_stripes - rbio->nr_data == 2) { +- p_stripe = rbio->real_stripes - 2; +- q_stripe = rbio->real_stripes - 1; +- } else { ++ if (rbio->real_stripes - rbio->nr_data == 1) ++ has_qstripe = false; ++ else if (rbio->real_stripes - rbio->nr_data == 2) ++ has_qstripe = true; ++ else + BUG(); +- } + + if (bbio->num_tgtdevs && bbio->tgtdev_map[rbio->scrubp]) { + is_replace = 1; +@@ -2395,7 +2389,7 @@ static noinline void finish_parity_scrub + goto cleanup; + SetPageUptodate(p_page); + +- if (q_stripe != -1) { ++ if (has_qstripe) { + q_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (!q_page) { + __free_page(p_page); +@@ -2418,8 +2412,7 @@ static noinline void finish_parity_scrub + /* then add the parity stripe */ + pointers[stripe++] = kmap(p_page); + +- if (q_stripe != -1) { +- ++ if (has_qstripe) { + /* + * raid6, add the qstripe and call the + * library function to fill in our p/q diff --git a/queue-5.4/btrfs-unlock-extents-in-btrfs_zero_range-in-case-of-quota-reservation-errors.patch b/queue-5.4/btrfs-unlock-extents-in-btrfs_zero_range-in-case-of-quota-reservation-errors.patch new file mode 100644 index 00000000000..0bcb5dcb405 --- /dev/null +++ b/queue-5.4/btrfs-unlock-extents-in-btrfs_zero_range-in-case-of-quota-reservation-errors.patch @@ -0,0 +1,40 @@ +From 4f6a49de64fd1b1dba5229c02047376da7cf24fd Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Tue, 23 Feb 2021 15:20:42 +0200 +Subject: btrfs: unlock extents in btrfs_zero_range in case of quota reservation errors + +From: Nikolay Borisov + +commit 4f6a49de64fd1b1dba5229c02047376da7cf24fd upstream. + +If btrfs_qgroup_reserve_data returns an error (i.e quota limit reached) +the handling logic directly goes to the 'out' label without first +unlocking the extent range between lockstart, lockend. This results in +deadlocks as other processes try to lock the same extent. + +Fixes: a7f8b1c2ac21 ("btrfs: file: reserve qgroup space after the hole punch range is locked") +CC: stable@vger.kernel.org # 5.10+ +Reviewed-by: Qu Wenruo +Signed-off-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/file.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -3151,8 +3151,11 @@ reserve_space: + goto out; + ret = btrfs_qgroup_reserve_data(inode, &data_reserved, + alloc_start, bytes_to_reserve); +- if (ret) ++ if (ret) { ++ unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, ++ lockend, &cached_state); + goto out; ++ } + ret = btrfs_prealloc_file_range(inode, mode, alloc_start, + alloc_end - alloc_start, + i_blocksize(inode), diff --git a/queue-5.4/btrfs-validate-qgroup-inherit-for-snap_create_v2-ioctl.patch b/queue-5.4/btrfs-validate-qgroup-inherit-for-snap_create_v2-ioctl.patch new file mode 100644 index 00000000000..1b3961710a0 --- /dev/null +++ b/queue-5.4/btrfs-validate-qgroup-inherit-for-snap_create_v2-ioctl.patch @@ -0,0 +1,60 @@ +From 5011c5a663b9c6d6aff3d394f11049b371199627 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 17 Feb 2021 09:04:34 +0300 +Subject: btrfs: validate qgroup inherit for SNAP_CREATE_V2 ioctl + +From: Dan Carpenter + +commit 5011c5a663b9c6d6aff3d394f11049b371199627 upstream. + +The problem is we're copying "inherit" from user space but we don't +necessarily know that we're copying enough data for a 64 byte +struct. Then the next problem is that 'inherit' has a variable size +array at the end, and we have to verify that array is the size we +expected. + +Fixes: 6f72c7e20dba ("Btrfs: add qgroup inheritance") +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Dan Carpenter +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ioctl.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -1907,7 +1907,10 @@ static noinline int btrfs_ioctl_snap_cre + if (vol_args->flags & BTRFS_SUBVOL_RDONLY) + readonly = true; + if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { +- if (vol_args->size > PAGE_SIZE) { ++ u64 nums; ++ ++ if (vol_args->size < sizeof(*inherit) || ++ vol_args->size > PAGE_SIZE) { + ret = -EINVAL; + goto free_args; + } +@@ -1916,6 +1919,20 @@ static noinline int btrfs_ioctl_snap_cre + ret = PTR_ERR(inherit); + goto free_args; + } ++ ++ if (inherit->num_qgroups > PAGE_SIZE || ++ inherit->num_ref_copies > PAGE_SIZE || ++ inherit->num_excl_copies > PAGE_SIZE) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } ++ ++ nums = inherit->num_qgroups + 2 * inherit->num_ref_copies + ++ 2 * inherit->num_excl_copies; ++ if (vol_args->size != struct_size(inherit, qgroups, nums)) { ++ ret = -EINVAL; ++ goto free_inherit; ++ } + } + + ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, diff --git a/queue-5.4/dm-bufio-subtract-the-number-of-initial-sectors-in-dm_bufio_get_device_size.patch b/queue-5.4/dm-bufio-subtract-the-number-of-initial-sectors-in-dm_bufio_get_device_size.patch new file mode 100644 index 00000000000..8599dc3c1de --- /dev/null +++ b/queue-5.4/dm-bufio-subtract-the-number-of-initial-sectors-in-dm_bufio_get_device_size.patch @@ -0,0 +1,40 @@ +From a14e5ec66a7a66e57b24e2469f9212a78460207e Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 23 Feb 2021 21:21:20 +0100 +Subject: dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size + +From: Mikulas Patocka + +commit a14e5ec66a7a66e57b24e2469f9212a78460207e upstream. + +dm_bufio_get_device_size returns the device size in blocks. Before +returning the value, we must subtract the nubmer of starting +sectors. The number of starting sectors may not be divisible by block +size. + +Note that currently, no target is using dm_bufio_set_sector_offset and +dm_bufio_get_device_size simultaneously, so this change has no effect. +However, an upcoming dm-verity-fec fix needs this change. + +Signed-off-by: Mikulas Patocka +Reviewed-by: Milan Broz +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-bufio.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1438,6 +1438,10 @@ EXPORT_SYMBOL_GPL(dm_bufio_get_block_siz + sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) + { + sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT; ++ if (s >= c->start) ++ s -= c->start; ++ else ++ s = 0; + if (likely(c->sectors_per_block_bits >= 0)) + s >>= c->sectors_per_block_bits; + else diff --git a/queue-5.4/dm-verity-fix-fec-for-rs-roots-unaligned-to-block-size.patch b/queue-5.4/dm-verity-fix-fec-for-rs-roots-unaligned-to-block-size.patch new file mode 100644 index 00000000000..6d8b8ee8c0c --- /dev/null +++ b/queue-5.4/dm-verity-fix-fec-for-rs-roots-unaligned-to-block-size.patch @@ -0,0 +1,142 @@ +From df7b59ba9245c4a3115ebaa905e3e5719a3810da Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Tue, 23 Feb 2021 21:21:21 +0100 +Subject: dm verity: fix FEC for RS roots unaligned to block size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Milan Broz + +commit df7b59ba9245c4a3115ebaa905e3e5719a3810da upstream. + +Optional Forward Error Correction (FEC) code in dm-verity uses +Reed-Solomon code and should support roots from 2 to 24. + +The error correction parity bytes (of roots lengths per RS block) are +stored on a separate device in sequence without any padding. + +Currently, to access FEC device, the dm-verity-fec code uses dm-bufio +client with block size set to verity data block (usually 4096 or 512 +bytes). + +Because this block size is not divisible by some (most!) of the roots +supported lengths, data repair cannot work for partially stored parity +bytes. + +This fix changes FEC device dm-bufio block size to "roots << SECTOR_SHIFT" +where we can be sure that the full parity data is always available. +(There cannot be partial FEC blocks because parity must cover whole +sectors.) + +Because the optional FEC starting offset could be unaligned to this +new block size, we have to use dm_bufio_set_sector_offset() to +configure it. + +The problem is easily reproduced using veritysetup, e.g. for roots=13: + + # create verity device with RS FEC + dd if=/dev/urandom of=data.img bs=4096 count=8 status=none + veritysetup format data.img hash.img --fec-device=fec.img --fec-roots=13 | awk '/^Root hash/{ print $3 }' >roothash + + # create an erasure that should be always repairable with this roots setting + dd if=/dev/zero of=data.img conv=notrunc bs=1 count=8 seek=4088 status=none + + # try to read it through dm-verity + veritysetup open data.img test hash.img --fec-device=fec.img --fec-roots=13 $(cat roothash) + dd if=/dev/mapper/test of=/dev/null bs=4096 status=noxfer + # wait for possible recursive recovery in kernel + udevadm settle + veritysetup close test + +With this fix, errors are properly repaired. + device-mapper: verity-fec: 7:1: FEC 0: corrected 8 errors + ... + +Without it, FEC code usually ends on unrecoverable failure in RS decoder: + device-mapper: verity-fec: 7:1: FEC 0: failed to correct: -74 + ... + +This problem is present in all kernels since the FEC code's +introduction (kernel 4.5). + +It is thought that this problem is not visible in Android ecosystem +because it always uses a default RS roots=2. + +Depends-on: a14e5ec66a7a ("dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size") +Signed-off-by: Milan Broz +Tested-by: Jérôme Carretero +Reviewed-by: Sami Tolvanen +Cc: stable@vger.kernel.org # 4.5+ +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-verity-fec.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/md/dm-verity-fec.c ++++ b/drivers/md/dm-verity-fec.c +@@ -61,19 +61,18 @@ static int fec_decode_rs8(struct dm_veri + static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, + unsigned *offset, struct dm_buffer **buf) + { +- u64 position, block; ++ u64 position, block, rem; + u8 *res; + + position = (index + rsb) * v->fec->roots; +- block = position >> v->data_dev_block_bits; +- *offset = (unsigned)(position - (block << v->data_dev_block_bits)); ++ block = div64_u64_rem(position, v->fec->roots << SECTOR_SHIFT, &rem); ++ *offset = (unsigned)rem; + +- res = dm_bufio_read(v->fec->bufio, v->fec->start + block, buf); ++ res = dm_bufio_read(v->fec->bufio, block, buf); + if (IS_ERR(res)) { + DMERR("%s: FEC %llu: parity read failed (block %llu): %ld", + v->data_dev->name, (unsigned long long)rsb, +- (unsigned long long)(v->fec->start + block), +- PTR_ERR(res)); ++ (unsigned long long)block, PTR_ERR(res)); + *buf = NULL; + } + +@@ -155,7 +154,7 @@ static int fec_decode_bufs(struct dm_ver + + /* read the next block when we run out of parity bytes */ + offset += v->fec->roots; +- if (offset >= 1 << v->data_dev_block_bits) { ++ if (offset >= v->fec->roots << SECTOR_SHIFT) { + dm_bufio_release(buf); + + par = fec_read_parity(v, rsb, block_offset, &offset, &buf); +@@ -674,7 +673,7 @@ int verity_fec_ctr(struct dm_verity *v) + { + struct dm_verity_fec *f = v->fec; + struct dm_target *ti = v->ti; +- u64 hash_blocks; ++ u64 hash_blocks, fec_blocks; + int ret; + + if (!verity_fec_is_enabled(v)) { +@@ -744,15 +743,17 @@ int verity_fec_ctr(struct dm_verity *v) + } + + f->bufio = dm_bufio_client_create(f->dev->bdev, +- 1 << v->data_dev_block_bits, ++ f->roots << SECTOR_SHIFT, + 1, 0, NULL, NULL); + if (IS_ERR(f->bufio)) { + ti->error = "Cannot initialize FEC bufio client"; + return PTR_ERR(f->bufio); + } + +- if (dm_bufio_get_device_size(f->bufio) < +- ((f->start + f->rounds * f->roots) >> v->data_dev_block_bits)) { ++ dm_bufio_set_sector_offset(f->bufio, f->start << (v->data_dev_block_bits - SECTOR_SHIFT)); ++ ++ fec_blocks = div64_u64(f->rounds * f->roots, v->fec->roots << SECTOR_SHIFT); ++ if (dm_bufio_get_device_size(f->bufio) < fec_blocks) { + ti->error = "FEC device is too small"; + return -E2BIG; + } diff --git a/queue-5.4/drm-amdgpu-fix-parameter-error-of-rreg32_pcie-in-amdgpu_regs_pcie.patch b/queue-5.4/drm-amdgpu-fix-parameter-error-of-rreg32_pcie-in-amdgpu_regs_pcie.patch new file mode 100644 index 00000000000..c14ecfaa5d5 --- /dev/null +++ b/queue-5.4/drm-amdgpu-fix-parameter-error-of-rreg32_pcie-in-amdgpu_regs_pcie.patch @@ -0,0 +1,40 @@ +From 1aa46901ee51c1c5779b3b239ea0374a50c6d9ff Mon Sep 17 00:00:00 2001 +From: Kevin Wang +Date: Tue, 2 Mar 2021 15:54:00 +0800 +Subject: drm/amdgpu: fix parameter error of RREG32_PCIE() in amdgpu_regs_pcie + +From: Kevin Wang + +commit 1aa46901ee51c1c5779b3b239ea0374a50c6d9ff upstream. + +the register offset isn't needed division by 4 to pass RREG32_PCIE() + +Signed-off-by: Kevin Wang +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -240,7 +240,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_ + while (size) { + uint32_t value; + +- value = RREG32_PCIE(*pos >> 2); ++ value = RREG32_PCIE(*pos); + r = put_user(value, (uint32_t *)buf); + if (r) + return r; +@@ -283,7 +283,7 @@ static ssize_t amdgpu_debugfs_regs_pcie_ + if (r) + return r; + +- WREG32_PCIE(*pos >> 2, value); ++ WREG32_PCIE(*pos, value); + + result += 4; + buf += 4; diff --git a/queue-5.4/pm-runtime-update-device-status-before-letting-suppliers-suspend.patch b/queue-5.4/pm-runtime-update-device-status-before-letting-suppliers-suspend.patch new file mode 100644 index 00000000000..13b52e98e90 --- /dev/null +++ b/queue-5.4/pm-runtime-update-device-status-before-letting-suppliers-suspend.patch @@ -0,0 +1,122 @@ +From 44cc89f764646b2f1f2ea5d1a08b230131707851 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 25 Feb 2021 19:23:27 +0100 +Subject: PM: runtime: Update device status before letting suppliers suspend + +From: Rafael J. Wysocki + +commit 44cc89f764646b2f1f2ea5d1a08b230131707851 upstream. + +Because the PM-runtime status of the device is not updated in +__rpm_callback(), attempts to suspend the suppliers of the given +device triggered by rpm_put_suppliers() called by it may fail. + +Fix this by making __rpm_callback() update the device's status to +RPM_SUSPENDED before calling rpm_put_suppliers() if the current +status of the device is RPM_SUSPENDING and the callback just invoked +by it has returned 0 (success). + +While at it, modify the code in __rpm_callback() to always check +the device's PM-runtime status under its PM lock. + +Link: https://lore.kernel.org/linux-pm/CAPDyKFqm06KDw_p8WXsM4dijDbho4bb6T4k50UqqvR1_COsp8g@mail.gmail.com/ +Fixes: 21d5c57b3726 ("PM / runtime: Use device links") +Reported-by: Elaine Zhang +Diagnosed-by: Ulf Hansson +Signed-off-by: Rafael J. Wysocki +Tested-by: Elaine Zhang +Reviewed-by: Ulf Hansson +Cc: 4.10+ # 4.10+ +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/power/runtime.c | 62 +++++++++++++++++++++++++------------------ + 1 file changed, 37 insertions(+), 25 deletions(-) + +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct dev + static int __rpm_callback(int (*cb)(struct device *), struct device *dev) + __releases(&dev->power.lock) __acquires(&dev->power.lock) + { +- int retval, idx; + bool use_links = dev->power.links_count > 0; ++ bool get = false; ++ int retval, idx; ++ bool put; + + if (dev->power.irq_safe) { + spin_unlock(&dev->power.lock); ++ } else if (!use_links) { ++ spin_unlock_irq(&dev->power.lock); + } else { ++ get = dev->power.runtime_status == RPM_RESUMING; ++ + spin_unlock_irq(&dev->power.lock); + +- /* +- * Resume suppliers if necessary. +- * +- * The device's runtime PM status cannot change until this +- * routine returns, so it is safe to read the status outside of +- * the lock. +- */ +- if (use_links && dev->power.runtime_status == RPM_RESUMING) { ++ /* Resume suppliers if necessary. */ ++ if (get) { + idx = device_links_read_lock(); + + retval = rpm_get_suppliers(dev); +@@ -355,24 +355,36 @@ static int __rpm_callback(int (*cb)(stru + + if (dev->power.irq_safe) { + spin_lock(&dev->power.lock); +- } else { +- /* +- * If the device is suspending and the callback has returned +- * success, drop the usage counters of the suppliers that have +- * been reference counted on its resume. +- * +- * Do that if resume fails too. +- */ +- if (use_links +- && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) +- || (dev->power.runtime_status == RPM_RESUMING && retval))) { +- idx = device_links_read_lock(); ++ return retval; ++ } + +- fail: +- rpm_put_suppliers(dev); ++ spin_lock_irq(&dev->power.lock); + +- device_links_read_unlock(idx); +- } ++ if (!use_links) ++ return retval; ++ ++ /* ++ * If the device is suspending and the callback has returned success, ++ * drop the usage counters of the suppliers that have been reference ++ * counted on its resume. ++ * ++ * Do that if the resume fails too. ++ */ ++ put = dev->power.runtime_status == RPM_SUSPENDING && !retval; ++ if (put) ++ __update_runtime_status(dev, RPM_SUSPENDED); ++ else ++ put = get && retval; ++ ++ if (put) { ++ spin_unlock_irq(&dev->power.lock); ++ ++ idx = device_links_read_lock(); ++ ++fail: ++ rpm_put_suppliers(dev); ++ ++ device_links_read_unlock(idx); + + spin_lock_irq(&dev->power.lock); + } diff --git a/queue-5.4/tpm-tpm_tis-decorate-tpm_get_timeouts-with-request_locality.patch b/queue-5.4/tpm-tpm_tis-decorate-tpm_get_timeouts-with-request_locality.patch new file mode 100644 index 00000000000..790d715e14c --- /dev/null +++ b/queue-5.4/tpm-tpm_tis-decorate-tpm_get_timeouts-with-request_locality.patch @@ -0,0 +1,66 @@ +From a5665ec2affdba21bff3b0d4d3aed83b3951e8ff Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Sat, 20 Feb 2021 00:55:59 +0200 +Subject: tpm, tpm_tis: Decorate tpm_get_timeouts() with request_locality() + +From: Jarkko Sakkinen + +commit a5665ec2affdba21bff3b0d4d3aed83b3951e8ff upstream. + +This is shown with Samsung Chromebook Pro (Caroline) with TPM 1.2 +(SLB 9670): + +[ 4.324298] TPM returned invalid status +[ 4.324806] WARNING: CPU: 2 PID: 1 at drivers/char/tpm/tpm_tis_core.c:275 tpm_tis_status+0x86/0x8f + +Background +========== + +TCG PC Client Platform TPM Profile (PTP) Specification, paragraph 6.1 FIFO +Interface Locality Usage per Register, Table 39 Register Behavior Based on +Locality Setting for FIFO - a read attempt to TPM_STS_x Registers returns +0xFF in case of lack of locality. + +The fix +======= + +Decorate tpm_get_timeouts() with request_locality() and release_locality(). + +Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()") +Cc: James Bottomley +Cc: Guenter Roeck +Cc: Laurent Bigonville +Cc: stable@vger.kernel.org +Reported-by: Lukasz Majczak +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm_tis_core.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -939,11 +939,21 @@ int tpm_tis_core_init(struct device *dev + init_waitqueue_head(&priv->read_queue); + init_waitqueue_head(&priv->int_queue); + if (irq != -1) { +- /* Before doing irq testing issue a command to the TPM in polling mode ++ /* ++ * Before doing irq testing issue a command to the TPM in polling mode + * to make sure it works. May as well use that command to set the + * proper timeouts for the driver. + */ +- if (tpm_get_timeouts(chip)) { ++ ++ rc = request_locality(chip, 0); ++ if (rc < 0) ++ goto out_err; ++ ++ rc = tpm_get_timeouts(chip); ++ ++ release_locality(chip, 0); ++ ++ if (rc) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; diff --git a/queue-5.4/tpm-tpm_tis-decorate-tpm_tis_gen_interrupt-with-request_locality.patch b/queue-5.4/tpm-tpm_tis-decorate-tpm_tis_gen_interrupt-with-request_locality.patch new file mode 100644 index 00000000000..d2f96572910 --- /dev/null +++ b/queue-5.4/tpm-tpm_tis-decorate-tpm_tis_gen_interrupt-with-request_locality.patch @@ -0,0 +1,69 @@ +From d53a6adfb553969809eb2b736a976ebb5146cd95 Mon Sep 17 00:00:00 2001 +From: Lukasz Majczak +Date: Tue, 16 Feb 2021 10:17:49 +0200 +Subject: tpm, tpm_tis: Decorate tpm_tis_gen_interrupt() with request_locality() + +From: Lukasz Majczak + +commit d53a6adfb553969809eb2b736a976ebb5146cd95 upstream. + +This is shown with Samsung Chromebook Pro (Caroline) with TPM 1.2 +(SLB 9670): + +[ 4.324298] TPM returned invalid status +[ 4.324806] WARNING: CPU: 2 PID: 1 at drivers/char/tpm/tpm_tis_core.c:275 tpm_tis_status+0x86/0x8f + +Background +========== + +TCG PC Client Platform TPM Profile (PTP) Specification, paragraph 6.1 FIFO +Interface Locality Usage per Register, Table 39 Register Behavior Based on +Locality Setting for FIFO - a read attempt to TPM_STS_x Registers returns +0xFF in case of lack of locality. + +The fix +======= + +Decorate tpm_tis_gen_interrupt() with request_locality() and +release_locality(). + +Cc: Laurent Bigonville +Cc: James Bottomley +Cc: Guenter Roeck +Cc: stable@vger.kernel.org +Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()") +Signed-off-by: Lukasz Majczak +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm_tis_core.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -618,12 +618,22 @@ static int tpm_tis_gen_interrupt(struct + const char *desc = "attempting to generate an interrupt"; + u32 cap2; + cap_t cap; ++ int ret; + ++ /* TPM 2.0 */ + if (chip->flags & TPM_CHIP_FLAG_TPM2) + return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); +- else +- return tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, +- 0); ++ ++ /* TPM 1.2 */ ++ ret = request_locality(chip, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); ++ ++ release_locality(chip, 0); ++ ++ return ret; + } + + /* Register the IRQ and issue a command that will cause an interrupt. If an