]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 11:37:28 +0000 (12:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 11:37:28 +0000 (12:37 +0100)
added patches:
btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch
btrfs-fix-slab-cache-flags-for-free-space-tree-bitmap.patch
drm-amd-display-copy-over-soc-values-before-bounding-box-creation.patch
drm-amd-display-correct-algorithm-for-reversed-gamma.patch
drm-amd-display-remove-mpc-gamut-remap-logic-for-dcn30.patch
vhost-vdpa-fix-use-after-free-of-v-config_ctx.patch
vhost-vdpa-set-v-config_ctx-to-null-if-eventfd_ctx_fdget-fails.patch

queue-5.11/btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch [new file with mode: 0644]
queue-5.11/btrfs-fix-slab-cache-flags-for-free-space-tree-bitmap.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-copy-over-soc-values-before-bounding-box-creation.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-correct-algorithm-for-reversed-gamma.patch [new file with mode: 0644]
queue-5.11/drm-amd-display-remove-mpc-gamut-remap-logic-for-dcn30.patch [new file with mode: 0644]
queue-5.11/series
queue-5.11/vhost-vdpa-fix-use-after-free-of-v-config_ctx.patch [new file with mode: 0644]
queue-5.11/vhost-vdpa-set-v-config_ctx-to-null-if-eventfd_ctx_fdget-fails.patch [new file with mode: 0644]

diff --git a/queue-5.11/btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch b/queue-5.11/btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch
new file mode 100644 (file)
index 0000000..a6d1346
--- /dev/null
@@ -0,0 +1,282 @@
+From dbcc7d57bffc0c8cac9dac11bec548597d59a6a5 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Thu, 11 Mar 2021 14:31:05 +0000
+Subject: btrfs: fix race when cloning extent buffer during rewind of an old root
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit dbcc7d57bffc0c8cac9dac11bec548597d59a6a5 upstream.
+
+While resolving backreferences, as part of a logical ino ioctl call or
+fiemap, we can end up hitting a BUG_ON() when replaying tree mod log
+operations of a root, triggering a stack trace like the following:
+
+  ------------[ cut here ]------------
+  kernel BUG at fs/btrfs/ctree.c:1210!
+  invalid opcode: 0000 [#1] SMP KASAN PTI
+  CPU: 1 PID: 19054 Comm: crawl_335 Tainted: G        W         5.11.0-2d11c0084b02-misc-next+ #89
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+  RIP: 0010:__tree_mod_log_rewind+0x3b1/0x3c0
+  Code: 05 48 8d 74 10 (...)
+  RSP: 0018:ffffc90001eb70b8 EFLAGS: 00010297
+  RAX: 0000000000000000 RBX: ffff88812344e400 RCX: ffffffffb28933b6
+  RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff88812344e42c
+  RBP: ffffc90001eb7108 R08: 1ffff11020b60a20 R09: ffffed1020b60a20
+  R10: ffff888105b050f9 R11: ffffed1020b60a1f R12: 00000000000000ee
+  R13: ffff8880195520c0 R14: ffff8881bc958500 R15: ffff88812344e42c
+  FS:  00007fd1955e8700(0000) GS:ffff8881f5600000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00007efdb7928718 CR3: 000000010103a006 CR4: 0000000000170ee0
+  Call Trace:
+   btrfs_search_old_slot+0x265/0x10d0
+   ? lock_acquired+0xbb/0x600
+   ? btrfs_search_slot+0x1090/0x1090
+   ? free_extent_buffer.part.61+0xd7/0x140
+   ? free_extent_buffer+0x13/0x20
+   resolve_indirect_refs+0x3e9/0xfc0
+   ? lock_downgrade+0x3d0/0x3d0
+   ? __kasan_check_read+0x11/0x20
+   ? add_prelim_ref.part.11+0x150/0x150
+   ? lock_downgrade+0x3d0/0x3d0
+   ? __kasan_check_read+0x11/0x20
+   ? lock_acquired+0xbb/0x600
+   ? __kasan_check_write+0x14/0x20
+   ? do_raw_spin_unlock+0xa8/0x140
+   ? rb_insert_color+0x30/0x360
+   ? prelim_ref_insert+0x12d/0x430
+   find_parent_nodes+0x5c3/0x1830
+   ? resolve_indirect_refs+0xfc0/0xfc0
+   ? lock_release+0xc8/0x620
+   ? fs_reclaim_acquire+0x67/0xf0
+   ? lock_acquire+0xc7/0x510
+   ? lock_downgrade+0x3d0/0x3d0
+   ? lockdep_hardirqs_on_prepare+0x160/0x210
+   ? lock_release+0xc8/0x620
+   ? fs_reclaim_acquire+0x67/0xf0
+   ? lock_acquire+0xc7/0x510
+   ? poison_range+0x38/0x40
+   ? unpoison_range+0x14/0x40
+   ? trace_hardirqs_on+0x55/0x120
+   btrfs_find_all_roots_safe+0x142/0x1e0
+   ? find_parent_nodes+0x1830/0x1830
+   ? btrfs_inode_flags_to_xflags+0x50/0x50
+   iterate_extent_inodes+0x20e/0x580
+   ? tree_backref_for_extent+0x230/0x230
+   ? lock_downgrade+0x3d0/0x3d0
+   ? read_extent_buffer+0xdd/0x110
+   ? lock_downgrade+0x3d0/0x3d0
+   ? __kasan_check_read+0x11/0x20
+   ? lock_acquired+0xbb/0x600
+   ? __kasan_check_write+0x14/0x20
+   ? _raw_spin_unlock+0x22/0x30
+   ? __kasan_check_write+0x14/0x20
+   iterate_inodes_from_logical+0x129/0x170
+   ? iterate_inodes_from_logical+0x129/0x170
+   ? btrfs_inode_flags_to_xflags+0x50/0x50
+   ? iterate_extent_inodes+0x580/0x580
+   ? __vmalloc_node+0x92/0xb0
+   ? init_data_container+0x34/0xb0
+   ? init_data_container+0x34/0xb0
+   ? kvmalloc_node+0x60/0x80
+   btrfs_ioctl_logical_to_ino+0x158/0x230
+   btrfs_ioctl+0x205e/0x4040
+   ? __might_sleep+0x71/0xe0
+   ? btrfs_ioctl_get_supported_features+0x30/0x30
+   ? getrusage+0x4b6/0x9c0
+   ? __kasan_check_read+0x11/0x20
+   ? lock_release+0xc8/0x620
+   ? __might_fault+0x64/0xd0
+   ? lock_acquire+0xc7/0x510
+   ? lock_downgrade+0x3d0/0x3d0
+   ? lockdep_hardirqs_on_prepare+0x210/0x210
+   ? lockdep_hardirqs_on_prepare+0x210/0x210
+   ? __kasan_check_read+0x11/0x20
+   ? do_vfs_ioctl+0xfc/0x9d0
+   ? ioctl_file_clone+0xe0/0xe0
+   ? lock_downgrade+0x3d0/0x3d0
+   ? lockdep_hardirqs_on_prepare+0x210/0x210
+   ? __kasan_check_read+0x11/0x20
+   ? lock_release+0xc8/0x620
+   ? __task_pid_nr_ns+0xd3/0x250
+   ? lock_acquire+0xc7/0x510
+   ? __fget_files+0x160/0x230
+   ? __fget_light+0xf2/0x110
+   __x64_sys_ioctl+0xc3/0x100
+   do_syscall_64+0x37/0x80
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  RIP: 0033:0x7fd1976e2427
+  Code: 00 00 90 48 8b 05 (...)
+  RSP: 002b:00007fd1955e5cf8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+  RAX: ffffffffffffffda RBX: 00007fd1955e5f40 RCX: 00007fd1976e2427
+  RDX: 00007fd1955e5f48 RSI: 00000000c038943b RDI: 0000000000000004
+  RBP: 0000000001000000 R08: 0000000000000000 R09: 00007fd1955e6120
+  R10: 0000557835366b00 R11: 0000000000000246 R12: 0000000000000004
+  R13: 00007fd1955e5f48 R14: 00007fd1955e5f40 R15: 00007fd1955e5ef8
+  Modules linked in:
+  ---[ end trace ec8931a1c36e57be ]---
+
+  (gdb) l *(__tree_mod_log_rewind+0x3b1)
+  0xffffffff81893521 is in __tree_mod_log_rewind (fs/btrfs/ctree.c:1210).
+  1205                     * the modification. as we're going backwards, we do the
+  1206                     * opposite of each operation here.
+  1207                     */
+  1208                    switch (tm->op) {
+  1209                    case MOD_LOG_KEY_REMOVE_WHILE_FREEING:
+  1210                            BUG_ON(tm->slot < n);
+  1211                            fallthrough;
+  1212                    case MOD_LOG_KEY_REMOVE_WHILE_MOVING:
+  1213                    case MOD_LOG_KEY_REMOVE:
+  1214                            btrfs_set_node_key(eb, &tm->key, tm->slot);
+
+Here's what happens to hit that BUG_ON():
+
+1) We have one tree mod log user (through fiemap or the logical ino ioctl),
+   with a sequence number of 1, so we have fs_info->tree_mod_seq == 1;
+
+2) Another task is at ctree.c:balance_level() and we have eb X currently as
+   the root of the tree, and we promote its single child, eb Y, as the new
+   root.
+
+   Then, at ctree.c:balance_level(), we call:
+
+      tree_mod_log_insert_root(eb X, eb Y, 1);
+
+3) At tree_mod_log_insert_root() we create tree mod log elements for each
+   slot of eb X, of operation type MOD_LOG_KEY_REMOVE_WHILE_FREEING each
+   with a ->logical pointing to ebX->start. These are placed in an array
+   named tm_list.
+   Lets assume there are N elements (N pointers in eb X);
+
+4) Then, still at tree_mod_log_insert_root(), we create a tree mod log
+   element of operation type MOD_LOG_ROOT_REPLACE, ->logical set to
+   ebY->start, ->old_root.logical set to ebX->start, ->old_root.level set
+   to the level of eb X and ->generation set to the generation of eb X;
+
+5) Then tree_mod_log_insert_root() calls tree_mod_log_free_eb() with
+   tm_list as argument. After that, tree_mod_log_free_eb() calls
+   __tree_mod_log_insert() for each member of tm_list in reverse order,
+   from highest slot in eb X, slot N - 1, to slot 0 of eb X;
+
+6) __tree_mod_log_insert() sets the sequence number of each given tree mod
+   log operation - it increments fs_info->tree_mod_seq and sets
+   fs_info->tree_mod_seq as the sequence number of the given tree mod log
+   operation.
+
+   This means that for the tm_list created at tree_mod_log_insert_root(),
+   the element corresponding to slot 0 of eb X has the highest sequence
+   number (1 + N), and the element corresponding to the last slot has the
+   lowest sequence number (2);
+
+7) Then, after inserting tm_list's elements into the tree mod log rbtree,
+   the MOD_LOG_ROOT_REPLACE element is inserted, which gets the highest
+   sequence number, which is N + 2;
+
+8) Back to ctree.c:balance_level(), we free eb X by calling
+   btrfs_free_tree_block() on it. Because eb X was created in the current
+   transaction, has no other references and writeback did not happen for
+   it, we add it back to the free space cache/tree;
+
+9) Later some other task T allocates the metadata extent from eb X, since
+   it is marked as free space in the space cache/tree, and uses it as a
+   node for some other btree;
+
+10) The tree mod log user task calls btrfs_search_old_slot(), which calls
+    get_old_root(), and finally that calls __tree_mod_log_oldest_root()
+    with time_seq == 1 and eb_root == eb Y;
+
+11) First iteration of the while loop finds the tree mod log element with
+    sequence number N + 2, for the logical address of eb Y and of type
+    MOD_LOG_ROOT_REPLACE;
+
+12) Because the operation type is MOD_LOG_ROOT_REPLACE, we don't break out
+    of the loop, and set root_logical to point to tm->old_root.logical
+    which corresponds to the logical address of eb X;
+
+13) On the next iteration of the while loop, the call to
+    tree_mod_log_search_oldest() returns the smallest tree mod log element
+    for the logical address of eb X, which has a sequence number of 2, an
+    operation type of MOD_LOG_KEY_REMOVE_WHILE_FREEING and corresponds to
+    the old slot N - 1 of eb X (eb X had N items in it before being freed);
+
+14) We then break out of the while loop and return the tree mod log operation
+    of type MOD_LOG_ROOT_REPLACE (eb Y), and not the one for slot N - 1 of
+    eb X, to get_old_root();
+
+15) At get_old_root(), we process the MOD_LOG_ROOT_REPLACE operation
+    and set "logical" to the logical address of eb X, which was the old
+    root. We then call tree_mod_log_search() passing it the logical
+    address of eb X and time_seq == 1;
+
+16) Then before calling tree_mod_log_search(), task T adds a key to eb X,
+    which results in adding a tree mod log operation of type
+    MOD_LOG_KEY_ADD to the tree mod log - this is done at
+    ctree.c:insert_ptr() - but after adding the tree mod log operation
+    and before updating the number of items in eb X from 0 to 1...
+
+17) The task at get_old_root() calls tree_mod_log_search() and gets the
+    tree mod log operation of type MOD_LOG_KEY_ADD just added by task T.
+    Then it enters the following if branch:
+
+    if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
+       (...)
+    } (...)
+
+    Calls read_tree_block() for eb X, which gets a reference on eb X but
+    does not lock it - task T has it locked.
+    Then it clones eb X while it has nritems set to 0 in its header, before
+    task T sets nritems to 1 in eb X's header. From hereupon we use the
+    clone of eb X which no other task has access to;
+
+18) Then we call __tree_mod_log_rewind(), passing it the MOD_LOG_KEY_ADD
+    mod log operation we just got from tree_mod_log_search() in the
+    previous step and the cloned version of eb X;
+
+19) At __tree_mod_log_rewind(), we set the local variable "n" to the number
+    of items set in eb X's clone, which is 0. Then we enter the while loop,
+    and in its first iteration we process the MOD_LOG_KEY_ADD operation,
+    which just decrements "n" from 0 to (u32)-1, since "n" is declared with
+    a type of u32. At the end of this iteration we call rb_next() to find the
+    next tree mod log operation for eb X, that gives us the mod log operation
+    of type MOD_LOG_KEY_REMOVE_WHILE_FREEING, for slot 0, with a sequence
+    number of N + 1 (steps 3 to 6);
+
+20) Then we go back to the top of the while loop and trigger the following
+    BUG_ON():
+
+        (...)
+        switch (tm->op) {
+        case MOD_LOG_KEY_REMOVE_WHILE_FREEING:
+                 BUG_ON(tm->slot < n);
+                 fallthrough;
+        (...)
+
+    Because "n" has a value of (u32)-1 (4294967295) and tm->slot is 0.
+
+Fix this by taking a read lock on the extent buffer before cloning it at
+ctree.c:get_old_root(). This should be done regardless of the extent
+buffer having been freed and reused, as a concurrent task might be
+modifying it (while holding a write lock on it).
+
+Reported-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
+Link: https://lore.kernel.org/linux-btrfs/20210227155037.GN28049@hungrycats.org/
+Fixes: 834328a8493079 ("Btrfs: tree mod log's old roots could still be part of the tree")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/ctree.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1365,7 +1365,9 @@ get_old_root(struct btrfs_root *root, u6
+                                  "failed to read tree block %llu from get_old_root",
+                                  logical);
+               } else {
++                      btrfs_tree_read_lock(old);
+                       eb = btrfs_clone_extent_buffer(old);
++                      btrfs_tree_read_unlock(old);
+                       free_extent_buffer(old);
+               }
+       } else if (old_root) {
diff --git a/queue-5.11/btrfs-fix-slab-cache-flags-for-free-space-tree-bitmap.patch b/queue-5.11/btrfs-fix-slab-cache-flags-for-free-space-tree-bitmap.patch
new file mode 100644 (file)
index 0000000..d52c8df
--- /dev/null
@@ -0,0 +1,34 @@
+From 34e49994d0dcdb2d31d4d2908d04f4e9ce57e4d7 Mon Sep 17 00:00:00 2001
+From: David Sterba <dsterba@suse.com>
+Date: Mon, 15 Mar 2021 15:18:24 +0100
+Subject: btrfs: fix slab cache flags for free space tree bitmap
+
+From: David Sterba <dsterba@suse.com>
+
+commit 34e49994d0dcdb2d31d4d2908d04f4e9ce57e4d7 upstream.
+
+The free space tree bitmap slab cache is created with SLAB_RED_ZONE but
+that's a debugging flag and not always enabled. Also the other slabs are
+created with at least SLAB_MEM_SPREAD that we want as well to average
+the memory placement cost.
+
+Reported-by: Vlastimil Babka <vbabka@suse.cz>
+Fixes: 3acd48507dc4 ("btrfs: fix allocation of free space cache v1 bitmap pages")
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8806,7 +8806,7 @@ int __init btrfs_init_cachep(void)
+       btrfs_free_space_bitmap_cachep = kmem_cache_create("btrfs_free_space_bitmap",
+                                                       PAGE_SIZE, PAGE_SIZE,
+-                                                      SLAB_RED_ZONE, NULL);
++                                                      SLAB_MEM_SPREAD, NULL);
+       if (!btrfs_free_space_bitmap_cachep)
+               goto fail;
diff --git a/queue-5.11/drm-amd-display-copy-over-soc-values-before-bounding-box-creation.patch b/queue-5.11/drm-amd-display-copy-over-soc-values-before-bounding-box-creation.patch
new file mode 100644 (file)
index 0000000..bdb12a0
--- /dev/null
@@ -0,0 +1,47 @@
+From 73076790e25717b7d452c2eab0bfb118826e5b61 Mon Sep 17 00:00:00 2001
+From: Sung Lee <sung.lee@amd.com>
+Date: Thu, 4 Feb 2021 08:21:15 -0500
+Subject: drm/amd/display: Copy over soc values before bounding box creation
+
+From: Sung Lee <sung.lee@amd.com>
+
+commit 73076790e25717b7d452c2eab0bfb118826e5b61 upstream.
+
+[Why]
+With certain fclock overclocks, state 1 may be chosen
+as the closest clock level. This may result in this state
+being empty if not populated beforehand, resulting in
+black screens and screen corruption.
+
+[How]
+Copy over all soc states to clock_limits before bounding
+box creation to avoid any cases with empty states.
+
+Fixes: f2459c52c84449 ("drm/amd/display: Add Bounding Box State for Low DF PState but High Voltage State")
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1514
+Signed-off-by: Sung Lee <sung.lee@amd.com>
+Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
+Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
+Acked-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+@@ -1595,6 +1595,11 @@ static void update_bw_bounding_box(struc
+       dcn2_1_soc.num_chans = bw_params->num_channels;
+       ASSERT(clk_table->num_entries);
++      /* Copy dcn2_1_soc.clock_limits to clock_limits to avoid copying over null states later */
++      for (i = 0; i < dcn2_1_soc.num_states + 1; i++) {
++              clock_limits[i] = dcn2_1_soc.clock_limits[i];
++      }
++
+       for (i = 0; i < clk_table->num_entries; i++) {
+               /* loop backwards*/
+               for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
diff --git a/queue-5.11/drm-amd-display-correct-algorithm-for-reversed-gamma.patch b/queue-5.11/drm-amd-display-correct-algorithm-for-reversed-gamma.patch
new file mode 100644 (file)
index 0000000..e32dc0b
--- /dev/null
@@ -0,0 +1,106 @@
+From 34fa493a565cc6fcee6919787c11e264f55603c6 Mon Sep 17 00:00:00 2001
+From: Calvin Hou <Calvin.Hou@amd.com>
+Date: Tue, 2 Mar 2021 10:48:26 -0500
+Subject: drm/amd/display: Correct algorithm for reversed gamma
+
+From: Calvin Hou <Calvin.Hou@amd.com>
+
+commit 34fa493a565cc6fcee6919787c11e264f55603c6 upstream.
+
+[Why]
+DCN30 needs to correctly program reversed gamma curve, which DCN20
+already has.
+Also needs to fix a bug that 252-255 values are clipped.
+
+[How]
+Apply two fixes into DCN30.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1513
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Calvin Hou <Calvin.Hou@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Acked-by: Vladimir Stempen <Vladimir.Stempen@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c |   26 +++++++++++------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+@@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_fo
+       struct pwl_result_data *rgb_resulted;
+       struct pwl_result_data *rgb;
+       struct pwl_result_data *rgb_plus_1;
++      struct pwl_result_data *rgb_minus_1;
+       struct fixed31_32 end_value;
+       int32_t region_start, region_end;
+@@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_fo
+               region_start = -MAX_LOW_POINT;
+               region_end   = NUMBER_REGIONS - MAX_LOW_POINT;
+       } else {
+-              /* 10 segments
++              /* 11 segments
+                * segment is from 2^-10 to 2^0
+                * There are less than 256 points, for optimization
+                */
+@@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_fo
+               seg_distr[7] = 4;
+               seg_distr[8] = 4;
+               seg_distr[9] = 4;
++              seg_distr[10] = 1;
+               region_start = -10;
+-              region_end = 0;
++              region_end = 1;
+       }
+       for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
+@@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_fo
+       rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
+       rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
++      rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
++      rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
++      rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
++
+       // All 3 color channels have same x
+       corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
+                                            dc_fixpt_from_int(region_start));
+@@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_fo
+       rgb = rgb_resulted;
+       rgb_plus_1 = rgb_resulted + 1;
++      rgb_minus_1 = rgb;
+       i = 1;
+       while (i != hw_points + 1) {
+-              if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
+-                      rgb_plus_1->red = rgb->red;
+-              if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
+-                      rgb_plus_1->green = rgb->green;
+-              if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
+-                      rgb_plus_1->blue = rgb->blue;
++              if (i >= hw_points - 1) {
++                      if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
++                              rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red);
++                      if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
++                              rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green);
++                      if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
++                              rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue);
++              }
+               rgb->delta_red   = dc_fixpt_sub(rgb_plus_1->red,   rgb->red);
+               rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
+@@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_fo
+               }
+               ++rgb_plus_1;
++              rgb_minus_1 = rgb;
+               ++rgb;
+               ++i;
+       }
diff --git a/queue-5.11/drm-amd-display-remove-mpc-gamut-remap-logic-for-dcn30.patch b/queue-5.11/drm-amd-display-remove-mpc-gamut-remap-logic-for-dcn30.patch
new file mode 100644 (file)
index 0000000..d3ac88a
--- /dev/null
@@ -0,0 +1,72 @@
+From beb6b2f97e0a02164c7f0df6e08c49219cfc2b80 Mon Sep 17 00:00:00 2001
+From: Dillon Varone <dillon.varone@amd.com>
+Date: Thu, 4 Mar 2021 17:39:10 -0500
+Subject: drm/amd/display: Remove MPC gamut remap logic for DCN30
+
+From: Dillon Varone <dillon.varone@amd.com>
+
+commit beb6b2f97e0a02164c7f0df6e08c49219cfc2b80 upstream.
+
+[Why?]
+Should only reroute gamut remap to mpc unless 3D LUT is not used and all
+planes are using the same src->dest.
+
+[How?]
+Remove DCN30 specific logic for rerouting gamut remap to mpc.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1513
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Dillon Varone <dillon.varone@amd.com>
+Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
+Acked-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Solomon Chiu <solomon.chiu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c |   34 +--------------------
+ 1 file changed, 2 insertions(+), 32 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -1501,38 +1501,8 @@ static void dcn20_update_dchubp_dpp(
+       if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed
+                       || pipe_ctx->stream->update_flags.bits.gamut_remap
+                       || pipe_ctx->stream->update_flags.bits.out_csc) {
+-              struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc;
+-
+-              if (mpc->funcs->set_gamut_remap) {
+-                      int i;
+-                      int mpcc_id = hubp->inst;
+-                      struct mpc_grph_gamut_adjustment adjust;
+-                      bool enable_remap_dpp = false;
+-
+-                      memset(&adjust, 0, sizeof(adjust));
+-                      adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
+-
+-                      /* save the enablement of gamut remap for dpp */
+-                      enable_remap_dpp = pipe_ctx->stream->gamut_remap_matrix.enable_remap;
+-
+-                      /* force bypass gamut remap for dpp/cm */
+-                      pipe_ctx->stream->gamut_remap_matrix.enable_remap = false;
+-                      dc->hwss.program_gamut_remap(pipe_ctx);
+-
+-                      /* restore gamut remap flag and use this remap into mpc */
+-                      pipe_ctx->stream->gamut_remap_matrix.enable_remap = enable_remap_dpp;
+-
+-                      /* build remap matrix for top plane if enabled */
+-                      if (enable_remap_dpp && pipe_ctx->top_pipe == NULL) {
+-                                      adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
+-                                      for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
+-                                              adjust.temperature_matrix[i] =
+-                                                              pipe_ctx->stream->gamut_remap_matrix.matrix[i];
+-                      }
+-                      mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust);
+-              } else
+-                      /* dpp/cm gamut remap*/
+-                      dc->hwss.program_gamut_remap(pipe_ctx);
++              /* dpp/cm gamut remap*/
++              dc->hwss.program_gamut_remap(pipe_ctx);
+               /*call the dcn2 method which uses mpc csc*/
+               dc->hwss.program_output_csc(dc,
index 2a9ec15027220b7b96e97a6782df7f5673ce60c9..09648516e00ee10f59944e2535ddaaee4cb721b3 100644 (file)
@@ -16,3 +16,10 @@ s390-pci-fix-leak-of-pci-device-structure.patch
 zonefs-fix-o_append-async-write-handling.patch
 zonefs-prevent-use-of-seq-files-as-swap-file.patch
 zonefs-fix-to-update-.i_wr_refcnt-correctly-in-zonefs_open_zone.patch
+btrfs-fix-race-when-cloning-extent-buffer-during-rewind-of-an-old-root.patch
+btrfs-fix-slab-cache-flags-for-free-space-tree-bitmap.patch
+vhost-vdpa-fix-use-after-free-of-v-config_ctx.patch
+vhost-vdpa-set-v-config_ctx-to-null-if-eventfd_ctx_fdget-fails.patch
+drm-amd-display-copy-over-soc-values-before-bounding-box-creation.patch
+drm-amd-display-correct-algorithm-for-reversed-gamma.patch
+drm-amd-display-remove-mpc-gamut-remap-logic-for-dcn30.patch
diff --git a/queue-5.11/vhost-vdpa-fix-use-after-free-of-v-config_ctx.patch b/queue-5.11/vhost-vdpa-fix-use-after-free-of-v-config_ctx.patch
new file mode 100644 (file)
index 0000000..1d67a1e
--- /dev/null
@@ -0,0 +1,57 @@
+From f6bbf0010ba004f5e90c7aefdebc0ee4bd3283b9 Mon Sep 17 00:00:00 2001
+From: Stefano Garzarella <sgarzare@redhat.com>
+Date: Thu, 11 Mar 2021 14:52:56 +0100
+Subject: vhost-vdpa: fix use-after-free of v->config_ctx
+
+From: Stefano Garzarella <sgarzare@redhat.com>
+
+commit f6bbf0010ba004f5e90c7aefdebc0ee4bd3283b9 upstream.
+
+When the 'v->config_ctx' eventfd_ctx reference is released we didn't
+set it to NULL. So if the same character device (e.g. /dev/vhost-vdpa-0)
+is re-opened, the 'v->config_ctx' is invalid and calling again
+vhost_vdpa_config_put() causes use-after-free issues like the
+following refcount_t underflow:
+
+    refcount_t: underflow; use-after-free.
+    WARNING: CPU: 2 PID: 872 at lib/refcount.c:28 refcount_warn_saturate+0xae/0xf0
+    RIP: 0010:refcount_warn_saturate+0xae/0xf0
+    Call Trace:
+     eventfd_ctx_put+0x5b/0x70
+     vhost_vdpa_release+0xcd/0x150 [vhost_vdpa]
+     __fput+0x8e/0x240
+     ____fput+0xe/0x10
+     task_work_run+0x66/0xa0
+     exit_to_user_mode_prepare+0x118/0x120
+     syscall_exit_to_user_mode+0x21/0x50
+     ? __x64_sys_close+0x12/0x40
+     do_syscall_64+0x45/0x50
+     entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
+Cc: lingshan.zhu@intel.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://lore.kernel.org/r/20210311135257.109460-2-sgarzare@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Zhu Lingshan <lingshan.zhu@intel.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vdpa.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -308,8 +308,10 @@ static long vhost_vdpa_get_vring_num(str
+ static void vhost_vdpa_config_put(struct vhost_vdpa *v)
+ {
+-      if (v->config_ctx)
++      if (v->config_ctx) {
+               eventfd_ctx_put(v->config_ctx);
++              v->config_ctx = NULL;
++      }
+ }
+ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
diff --git a/queue-5.11/vhost-vdpa-set-v-config_ctx-to-null-if-eventfd_ctx_fdget-fails.patch b/queue-5.11/vhost-vdpa-set-v-config_ctx-to-null-if-eventfd_ctx_fdget-fails.patch
new file mode 100644 (file)
index 0000000..5e99e9e
--- /dev/null
@@ -0,0 +1,45 @@
+From 0bde59c1723a29e294765c96dbe5c7fb639c2f96 Mon Sep 17 00:00:00 2001
+From: Stefano Garzarella <sgarzare@redhat.com>
+Date: Thu, 11 Mar 2021 14:52:57 +0100
+Subject: vhost-vdpa: set v->config_ctx to NULL if eventfd_ctx_fdget() fails
+
+From: Stefano Garzarella <sgarzare@redhat.com>
+
+commit 0bde59c1723a29e294765c96dbe5c7fb639c2f96 upstream.
+
+In vhost_vdpa_set_config_call() if eventfd_ctx_fdget() fails the
+'v->config_ctx' contains an error instead of a valid pointer.
+
+Since we consider 'v->config_ctx' valid if it is not NULL, we should
+set it to NULL in this case to avoid to use an invalid pointer in
+other functions such as vhost_vdpa_config_put().
+
+Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
+Cc: lingshan.zhu@intel.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
+Link: https://lore.kernel.org/r/20210311135257.109460-3-sgarzare@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/vhost/vdpa.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -331,8 +331,12 @@ static long vhost_vdpa_set_config_call(s
+       if (!IS_ERR_OR_NULL(ctx))
+               eventfd_ctx_put(ctx);
+-      if (IS_ERR(v->config_ctx))
+-              return PTR_ERR(v->config_ctx);
++      if (IS_ERR(v->config_ctx)) {
++              long ret = PTR_ERR(v->config_ctx);
++
++              v->config_ctx = NULL;
++              return ret;
++      }
+       v->vdpa->config->set_config_cb(v->vdpa, &cb);