--- /dev/null
+From 78a18fec5258c8df9435399a1ea022d73d3eceb9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Fri, 15 Jan 2021 22:57:52 +0100
+Subject: ACPI: scan: Make acpi_bus_get_device() clear return pointer on error
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 78a18fec5258c8df9435399a1ea022d73d3eceb9 upstream.
+
+Set the acpi_device pointer which acpi_bus_get_device() returns-by-
+reference to NULL on errors.
+
+We've recently had 2 cases where callers of acpi_bus_get_device()
+did not properly error check the return value, so set the returned-
+by-reference acpi_device pointer to NULL, because at least some
+callers of acpi_bus_get_device() expect that to be done on errors.
+
+[ rjw: This issue was exposed by commit 71da201f38df ("ACPI: scan:
+ Defer enumeration of devices with _DEP lists") which caused it to
+ be much more likely to occur on some systems, but the real defect
+ had been introduced by an earlier commit. ]
+
+Fixes: 40e7fcb19293 ("ACPI: Add _DEP support to fix battery issue on Asus T100TA")
+Fixes: bcfcd409d4db ("usb: split code locating ACPI companion into port and device")
+Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Diagnosed-by: Rafael J. Wysocki <rafael@kernel.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Cc: All applicable <stable@vger.kernel.org>
+[ rjw: Subject and changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/scan.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -586,6 +586,8 @@ static int acpi_get_device_data(acpi_han
+ if (!device)
+ return -EINVAL;
+
++ *device = NULL;
++
+ status = acpi_get_data_full(handle, acpi_scan_drop_device,
+ (void **)device, callback);
+ if (ACPI_FAILURE(status) || !*device) {
--- /dev/null
+From 495dc7637cb5ca8e39c46db818328410bb6e73a1 Mon Sep 17 00:00:00 2001
+From: Chris Chiu <chiu@endlessos.org>
+Date: Thu, 14 Jan 2021 16:27:28 +0800
+Subject: ALSA: hda/realtek - Limit int mic boost on Acer Aspire E5-575T
+
+From: Chris Chiu <chiu@endlessos.org>
+
+commit 495dc7637cb5ca8e39c46db818328410bb6e73a1 upstream.
+
+The Acer Apire E5-575T laptop with codec ALC255 has a terrible
+background noise comes from internal mic capture. And the jack
+sensing dose not work for headset like some other Acer laptops.
+
+This patch limits the internal mic boost on top of the existing
+ALC255_FIXUP_ACER_MIC_NO_PRESENCE quirk for Acer Aspire E5-575T.
+
+Signed-off-by: Chris Chiu <chiu@endlessos.org>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210114082728.74729-1-chiu@endlessos.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6371,6 +6371,7 @@ enum {
+ ALC256_FIXUP_HP_HEADSET_MIC,
+ ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
+ ALC282_FIXUP_ACER_DISABLE_LINEOUT,
++ ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
+ };
+
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -7808,6 +7809,12 @@ static const struct hda_fixup alc269_fix
+ .chained = true,
+ .chain_id = ALC269_FIXUP_HEADSET_MODE
+ },
++ [ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc269_fixup_limit_int_mic_boost,
++ .chained = true,
++ .chain_id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -7826,6 +7833,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
++ SND_PCI_QUIRK(0x1025, 0x1094, "Acer Aspire E5-575T", ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK),
--- /dev/null
+From 67ea698c3950d10925be33c21ca49ffb64e21842 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 14 Jan 2021 08:24:53 +0100
+Subject: ALSA: hda/via: Add minimum mute flag
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 67ea698c3950d10925be33c21ca49ffb64e21842 upstream.
+
+It turned out that VIA codecs also mute the sound in the lowest mixer
+level. Turn on the dac_min_mute flag to indicate the mute-as-minimum
+in TLV like already done in Conexant and IDT codecs.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=210559
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210114072453.11379-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_via.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_via.c
++++ b/sound/pci/hda/patch_via.c
+@@ -113,6 +113,7 @@ static struct via_spec *via_new_spec(str
+ spec->codec_type = VT1708S;
+ spec->gen.indep_hp = 1;
+ spec->gen.keep_eapd_on = 1;
++ spec->gen.dac_min_mute = 1;
+ spec->gen.pcm_playback_hook = via_playback_pcm_hook;
+ spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
+ codec->power_save_node = 1;
--- /dev/null
+From 217bfbb8b0bfa24619b11ab75c135fec99b99b20 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 15 Jan 2021 10:34:28 +0100
+Subject: ALSA: seq: oss: Fix missing error check in snd_seq_oss_synth_make_info()
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 217bfbb8b0bfa24619b11ab75c135fec99b99b20 upstream.
+
+snd_seq_oss_synth_make_info() didn't check the error code from
+snd_seq_oss_midi_make_info(), and this leads to the call of strlcpy()
+with the uninitialized string as the source, which may lead to the
+access over the limit.
+
+Add the proper error check for avoiding the failure.
+
+Reported-by: syzbot+e42504ff21cff05a595f@syzkaller.appspotmail.com
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210115093428.15882-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/oss/seq_oss_synth.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/core/seq/oss/seq_oss_synth.c
++++ b/sound/core/seq/oss/seq_oss_synth.c
+@@ -611,7 +611,8 @@ snd_seq_oss_synth_make_info(struct seq_o
+
+ if (info->is_midi) {
+ struct midi_info minf;
+- snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf);
++ if (snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf))
++ return -ENXIO;
+ inf->synth_type = SYNTH_TYPE_MIDI;
+ inf->synth_subtype = 0;
+ inf->nr_voices = 16;
--- /dev/null
+From 49ecc679ab48b40ca799bf94b327d5284eac9e46 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 16 Dec 2020 11:22:11 -0500
+Subject: btrfs: do not double free backref nodes on error
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 49ecc679ab48b40ca799bf94b327d5284eac9e46 upstream.
+
+Zygo reported the following KASAN splat:
+
+ BUG: KASAN: use-after-free in btrfs_backref_cleanup_node+0x18a/0x420
+ Read of size 8 at addr ffff888112402950 by task btrfs/28836
+
+ CPU: 0 PID: 28836 Comm: btrfs Tainted: G W 5.10.0-e35f27394290-for-next+ #23
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+ Call Trace:
+ dump_stack+0xbc/0xf9
+ ? btrfs_backref_cleanup_node+0x18a/0x420
+ print_address_description.constprop.8+0x21/0x210
+ ? record_print_text.cold.34+0x11/0x11
+ ? btrfs_backref_cleanup_node+0x18a/0x420
+ ? btrfs_backref_cleanup_node+0x18a/0x420
+ kasan_report.cold.10+0x20/0x37
+ ? btrfs_backref_cleanup_node+0x18a/0x420
+ __asan_load8+0x69/0x90
+ btrfs_backref_cleanup_node+0x18a/0x420
+ btrfs_backref_release_cache+0x83/0x1b0
+ relocate_block_group+0x394/0x780
+ ? merge_reloc_roots+0x4a0/0x4a0
+ btrfs_relocate_block_group+0x26e/0x4c0
+ btrfs_relocate_chunk+0x52/0x120
+ btrfs_balance+0xe2e/0x1900
+ ? check_flags.part.50+0x6c/0x1e0
+ ? btrfs_relocate_chunk+0x120/0x120
+ ? kmem_cache_alloc_trace+0xa06/0xcb0
+ ? _copy_from_user+0x83/0xc0
+ btrfs_ioctl_balance+0x3a7/0x460
+ btrfs_ioctl+0x24c8/0x4360
+ ? __kasan_check_read+0x11/0x20
+ ? check_chain_key+0x1f4/0x2f0
+ ? __asan_loadN+0xf/0x20
+ ? btrfs_ioctl_get_supported_features+0x30/0x30
+ ? kvm_sched_clock_read+0x18/0x30
+ ? check_chain_key+0x1f4/0x2f0
+ ? lock_downgrade+0x3f0/0x3f0
+ ? handle_mm_fault+0xad6/0x2150
+ ? do_vfs_ioctl+0xfc/0x9d0
+ ? ioctl_file_clone+0xe0/0xe0
+ ? check_flags.part.50+0x6c/0x1e0
+ ? check_flags.part.50+0x6c/0x1e0
+ ? check_flags+0x26/0x30
+ ? lock_is_held_type+0xc3/0xf0
+ ? syscall_enter_from_user_mode+0x1b/0x60
+ ? do_syscall_64+0x13/0x80
+ ? rcu_read_lock_sched_held+0xa1/0xd0
+ ? __kasan_check_read+0x11/0x20
+ ? __fget_light+0xae/0x110
+ __x64_sys_ioctl+0xc3/0x100
+ do_syscall_64+0x37/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7f4c4bdfe427
+
+ Allocated by task 28836:
+ kasan_save_stack+0x21/0x50
+ __kasan_kmalloc.constprop.18+0xbe/0xd0
+ kasan_kmalloc+0x9/0x10
+ kmem_cache_alloc_trace+0x410/0xcb0
+ btrfs_backref_alloc_node+0x46/0xf0
+ btrfs_backref_add_tree_node+0x60d/0x11d0
+ build_backref_tree+0xc5/0x700
+ relocate_tree_blocks+0x2be/0xb90
+ relocate_block_group+0x2eb/0x780
+ btrfs_relocate_block_group+0x26e/0x4c0
+ btrfs_relocate_chunk+0x52/0x120
+ btrfs_balance+0xe2e/0x1900
+ btrfs_ioctl_balance+0x3a7/0x460
+ btrfs_ioctl+0x24c8/0x4360
+ __x64_sys_ioctl+0xc3/0x100
+ do_syscall_64+0x37/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ Freed by task 28836:
+ kasan_save_stack+0x21/0x50
+ kasan_set_track+0x20/0x30
+ kasan_set_free_info+0x1f/0x30
+ __kasan_slab_free+0xf3/0x140
+ kasan_slab_free+0xe/0x10
+ kfree+0xde/0x200
+ btrfs_backref_error_cleanup+0x452/0x530
+ build_backref_tree+0x1a5/0x700
+ relocate_tree_blocks+0x2be/0xb90
+ relocate_block_group+0x2eb/0x780
+ btrfs_relocate_block_group+0x26e/0x4c0
+ btrfs_relocate_chunk+0x52/0x120
+ btrfs_balance+0xe2e/0x1900
+ btrfs_ioctl_balance+0x3a7/0x460
+ btrfs_ioctl+0x24c8/0x4360
+ __x64_sys_ioctl+0xc3/0x100
+ do_syscall_64+0x37/0x80
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+This occurred because we freed our backref node in
+btrfs_backref_error_cleanup(), but then tried to free it again in
+btrfs_backref_release_cache(). This is because
+btrfs_backref_release_cache() will cycle through all of the
+cache->leaves nodes and free them up. However
+btrfs_backref_error_cleanup() freed the backref node with
+btrfs_backref_free_node(), which simply kfree()d the backref node
+without unlinking it from the cache. Change this to a
+btrfs_backref_drop_node(), which does the appropriate cleanup and
+removes the node from the cache->leaves list, so when we go to free the
+remaining cache we don't trip over items we've already dropped.
+
+Fixes: 75bfb9aff45e ("Btrfs: cleanup error handling in build_backref_tree")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/backref.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -3124,7 +3124,7 @@ void btrfs_backref_error_cleanup(struct
+ list_del_init(&lower->list);
+ if (lower == node)
+ node = NULL;
+- btrfs_backref_free_node(cache, lower);
++ btrfs_backref_drop_node(cache, lower);
+ }
+
+ btrfs_backref_cleanup_node(cache, node);
--- /dev/null
+From 34d1eb0e599875064955a74712f08ff14c8e3d5f Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 16 Dec 2020 11:22:17 -0500
+Subject: btrfs: don't clear ret in btrfs_start_dirty_block_groups
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 34d1eb0e599875064955a74712f08ff14c8e3d5f upstream.
+
+If we fail to update a block group item in the loop we'll break, however
+we'll do btrfs_run_delayed_refs and lose our error value in ret, and
+thus not clean up properly. Fix this by only running the delayed refs
+if there was no failure.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/block-group.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2687,7 +2687,8 @@ again:
+ * Go through delayed refs for all the stuff we've just kicked off
+ * and then loop back (just once)
+ */
+- ret = btrfs_run_delayed_refs(trans, 0);
++ if (!ret)
++ ret = btrfs_run_delayed_refs(trans, 0);
+ if (!ret && loops == 0) {
+ loops++;
+ spin_lock(&cur_trans->dirty_bgs_lock);
--- /dev/null
+From 18d3bff411c8d46d40537483bdc0b61b33ce0371 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 16 Dec 2020 11:22:05 -0500
+Subject: btrfs: don't get an EINTR during drop_snapshot for reloc
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 18d3bff411c8d46d40537483bdc0b61b33ce0371 upstream.
+
+This was partially fixed by f3e3d9cc3525 ("btrfs: avoid possible signal
+interruption of btrfs_drop_snapshot() on relocation tree"), however it
+missed a spot when we restart a trans handle because we need to end the
+transaction. The fix is the same, simply use btrfs_join_transaction()
+instead of btrfs_start_transaction() when deleting reloc roots.
+
+Fixes: f3e3d9cc3525 ("btrfs: avoid possible signal interruption of btrfs_drop_snapshot() on relocation tree")
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -5571,7 +5571,15 @@ int btrfs_drop_snapshot(struct btrfs_roo
+ goto out_free;
+ }
+
+- trans = btrfs_start_transaction(tree_root, 0);
++ /*
++ * Use join to avoid potential EINTR from transaction
++ * start. See wait_reserve_ticket and the whole
++ * reservation callchain.
++ */
++ if (for_reloc)
++ trans = btrfs_join_transaction(tree_root);
++ else
++ trans = btrfs_start_transaction(tree_root, 0);
+ if (IS_ERR(trans)) {
+ err = PTR_ERR(trans);
+ goto out_free;
--- /dev/null
+From fb286100974e7239af243bc2255a52f29442f9c8 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 16 Dec 2020 11:22:14 -0500
+Subject: btrfs: fix lockdep splat in btrfs_recover_relocation
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit fb286100974e7239af243bc2255a52f29442f9c8 upstream.
+
+While testing the error paths of relocation I hit the following lockdep
+splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.10.0-rc6+ #217 Not tainted
+ ------------------------------------------------------
+ mount/779 is trying to acquire lock:
+ ffffa0e676945418 (&fs_info->balance_mutex){+.+.}-{3:3}, at: btrfs_recover_balance+0x2f0/0x340
+
+ but task is already holding lock:
+ ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #2 (btrfs-root-00){++++}-{3:3}:
+ down_read_nested+0x43/0x130
+ __btrfs_tree_read_lock+0x27/0x100
+ btrfs_read_lock_root_node+0x31/0x40
+ btrfs_search_slot+0x462/0x8f0
+ btrfs_update_root+0x55/0x2b0
+ btrfs_drop_snapshot+0x398/0x750
+ clean_dirty_subvols+0xdf/0x120
+ btrfs_recover_relocation+0x534/0x5a0
+ btrfs_start_pre_rw_mount+0xcb/0x170
+ open_ctree+0x151f/0x1726
+ btrfs_mount_root.cold+0x12/0xea
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ vfs_kern_mount.part.0+0x71/0xb0
+ btrfs_mount+0x10d/0x380
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ path_mount+0x433/0xc10
+ __x64_sys_mount+0xe3/0x120
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #1 (sb_internal#2){.+.+}-{0:0}:
+ start_transaction+0x444/0x700
+ insert_balance_item.isra.0+0x37/0x320
+ btrfs_balance+0x354/0xf40
+ btrfs_ioctl_balance+0x2cf/0x380
+ __x64_sys_ioctl+0x83/0xb0
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #0 (&fs_info->balance_mutex){+.+.}-{3:3}:
+ __lock_acquire+0x1120/0x1e10
+ lock_acquire+0x116/0x370
+ __mutex_lock+0x7e/0x7b0
+ btrfs_recover_balance+0x2f0/0x340
+ open_ctree+0x1095/0x1726
+ btrfs_mount_root.cold+0x12/0xea
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ vfs_kern_mount.part.0+0x71/0xb0
+ btrfs_mount+0x10d/0x380
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ path_mount+0x433/0xc10
+ __x64_sys_mount+0xe3/0x120
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ &fs_info->balance_mutex --> sb_internal#2 --> btrfs-root-00
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(btrfs-root-00);
+ lock(sb_internal#2);
+ lock(btrfs-root-00);
+ lock(&fs_info->balance_mutex);
+
+ *** DEADLOCK ***
+
+ 2 locks held by mount/779:
+ #0: ffffa0e60dc040e0 (&type->s_umount_key#47/1){+.+.}-{3:3}, at: alloc_super+0xb5/0x380
+ #1: ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100
+
+ stack backtrace:
+ CPU: 0 PID: 779 Comm: mount Not tainted 5.10.0-rc6+ #217
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014
+ Call Trace:
+ dump_stack+0x8b/0xb0
+ check_noncircular+0xcf/0xf0
+ ? trace_call_bpf+0x139/0x260
+ __lock_acquire+0x1120/0x1e10
+ lock_acquire+0x116/0x370
+ ? btrfs_recover_balance+0x2f0/0x340
+ __mutex_lock+0x7e/0x7b0
+ ? btrfs_recover_balance+0x2f0/0x340
+ ? btrfs_recover_balance+0x2f0/0x340
+ ? rcu_read_lock_sched_held+0x3f/0x80
+ ? kmem_cache_alloc_trace+0x2c4/0x2f0
+ ? btrfs_get_64+0x5e/0x100
+ btrfs_recover_balance+0x2f0/0x340
+ open_ctree+0x1095/0x1726
+ btrfs_mount_root.cold+0x12/0xea
+ ? rcu_read_lock_sched_held+0x3f/0x80
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ vfs_kern_mount.part.0+0x71/0xb0
+ btrfs_mount+0x10d/0x380
+ ? __kmalloc_track_caller+0x2f2/0x320
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ ? capable+0x3a/0x60
+ path_mount+0x433/0xc10
+ __x64_sys_mount+0xe3/0x120
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+This is straightforward to fix, simply release the path before we setup
+the balance_ctl.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -4288,6 +4288,8 @@ int btrfs_recover_balance(struct btrfs_f
+ btrfs_warn(fs_info,
+ "balance: cannot set exclusive op status, resume manually");
+
++ btrfs_release_path(path);
++
+ mutex_lock(&fs_info->balance_mutex);
+ BUG_ON(fs_info->balance_ctl);
+ spin_lock(&fs_info->balance_lock);
--- /dev/null
+From 518837e65068c385dddc0a87b3e577c8be7c13b1 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 11 Jan 2021 11:41:42 +0000
+Subject: btrfs: send: fix invalid clone operations when cloning from the same file and root
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 518837e65068c385dddc0a87b3e577c8be7c13b1 upstream.
+
+When an incremental send finds an extent that is shared, it checks which
+file extent items in the range refer to that extent, and for those it
+emits clone operations, while for others it emits regular write operations
+to avoid corruption at the destination (as described and fixed by commit
+d906d49fc5f4 ("Btrfs: send, fix file corruption due to incorrect cloning
+operations")).
+
+However when the root we are cloning from is the send root, we are cloning
+from the inode currently being processed and the source file range has
+several extent items that partially point to the desired extent, with an
+offset smaller than the offset in the file extent item for the range we
+want to clone into, it can cause the algorithm to issue a clone operation
+that starts at the current eof of the file being processed in the receiver
+side, in which case the receiver will fail, with EINVAL, when attempting
+to execute the clone operation.
+
+Example reproducer:
+
+ $ cat test-send-clone.sh
+ #!/bin/bash
+
+ DEV=/dev/sdi
+ MNT=/mnt/sdi
+
+ mkfs.btrfs -f $DEV >/dev/null
+ mount $DEV $MNT
+
+ # Create our test file with a single and large extent (1M) and with
+ # different content for different file ranges that will be reflinked
+ # later.
+ xfs_io -f \
+ -c "pwrite -S 0xab 0 128K" \
+ -c "pwrite -S 0xcd 128K 128K" \
+ -c "pwrite -S 0xef 256K 256K" \
+ -c "pwrite -S 0x1a 512K 512K" \
+ $MNT/foobar
+
+ btrfs subvolume snapshot -r $MNT $MNT/snap1
+ btrfs send -f /tmp/snap1.send $MNT/snap1
+
+ # Now do a series of changes to our file such that we end up with
+ # different parts of the extent reflinked into different file offsets
+ # and we overwrite a large part of the extent too, so no file extent
+ # items refer to that part that was overwritten. This used to confuse
+ # the algorithm used by the kernel to figure out which file ranges to
+ # clone, making it attempt to clone from a source range starting at
+ # the current eof of the file, resulting in the receiver to fail since
+ # it is an invalid clone operation.
+ #
+ xfs_io -c "reflink $MNT/foobar 64K 1M 960K" \
+ -c "reflink $MNT/foobar 0K 512K 256K" \
+ -c "reflink $MNT/foobar 512K 128K 256K" \
+ -c "pwrite -S 0x73 384K 640K" \
+ $MNT/foobar
+
+ btrfs subvolume snapshot -r $MNT $MNT/snap2
+ btrfs send -f /tmp/snap2.send -p $MNT/snap1 $MNT/snap2
+
+ echo -e "\nFile digest in the original filesystem:"
+ md5sum $MNT/snap2/foobar
+
+ # Now unmount the filesystem, create a new one, mount it and try to
+ # apply both send streams to recreate both snapshots.
+ umount $DEV
+
+ mkfs.btrfs -f $DEV >/dev/null
+ mount $DEV $MNT
+
+ btrfs receive -f /tmp/snap1.send $MNT
+ btrfs receive -f /tmp/snap2.send $MNT
+
+ # Must match what we got in the original filesystem of course.
+ echo -e "\nFile digest in the new filesystem:"
+ md5sum $MNT/snap2/foobar
+
+ umount $MNT
+
+When running the reproducer, the incremental send operation fails due to
+an invalid clone operation:
+
+ $ ./test-send-clone.sh
+ wrote 131072/131072 bytes at offset 0
+ 128 KiB, 32 ops; 0.0015 sec (80.906 MiB/sec and 20711.9741 ops/sec)
+ wrote 131072/131072 bytes at offset 131072
+ 128 KiB, 32 ops; 0.0013 sec (90.514 MiB/sec and 23171.6148 ops/sec)
+ wrote 262144/262144 bytes at offset 262144
+ 256 KiB, 64 ops; 0.0025 sec (98.270 MiB/sec and 25157.2327 ops/sec)
+ wrote 524288/524288 bytes at offset 524288
+ 512 KiB, 128 ops; 0.0052 sec (95.730 MiB/sec and 24506.9883 ops/sec)
+ Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap1'
+ At subvol /mnt/sdi/snap1
+ linked 983040/983040 bytes at offset 1048576
+ 960 KiB, 1 ops; 0.0006 sec (1.419 GiB/sec and 1550.3876 ops/sec)
+ linked 262144/262144 bytes at offset 524288
+ 256 KiB, 1 ops; 0.0020 sec (120.192 MiB/sec and 480.7692 ops/sec)
+ linked 262144/262144 bytes at offset 131072
+ 256 KiB, 1 ops; 0.0018 sec (133.833 MiB/sec and 535.3319 ops/sec)
+ wrote 655360/655360 bytes at offset 393216
+ 640 KiB, 160 ops; 0.0093 sec (66.781 MiB/sec and 17095.8436 ops/sec)
+ Create a readonly snapshot of '/mnt/sdi' in '/mnt/sdi/snap2'
+ At subvol /mnt/sdi/snap2
+
+ File digest in the original filesystem:
+ 9c13c61cb0b9f5abf45344375cb04dfa /mnt/sdi/snap2/foobar
+ At subvol snap1
+ At snapshot snap2
+ ERROR: failed to clone extents to foobar: Invalid argument
+
+ File digest in the new filesystem:
+ 132f0396da8f48d2e667196bff882cfc /mnt/sdi/snap2/foobar
+
+The clone operation is invalid because its source range starts at the
+current eof of the file in the receiver, causing the receiver to get
+an EINVAL error from the clone operation when attempting it.
+
+For the example above, what happens is the following:
+
+1) When processing the extent at file offset 1M, the algorithm checks that
+ the extent is shared and can be (fully or partially) found at file
+ offset 0.
+
+ At this point the file has a size (and eof) of 1M at the receiver;
+
+2) It finds that our extent item at file offset 1M has a data offset of
+ 64K and, since the file extent item at file offset 0 has a data offset
+ of 0, it issues a clone operation, from the same file and root, that
+ has a source range offset of 64K, destination offset of 1M and a length
+ of 64K, since the extent item at file offset 0 refers only to the first
+ 128K of the shared extent.
+
+ After this clone operation, the file size (and eof) at the receiver is
+ increased from 1M to 1088K (1M + 64K);
+
+3) Now there's still 896K (960K - 64K) of data left to clone or write, so
+ it checks for the next file extent item, which starts at file offset
+ 128K. This file extent item has a data offset of 0 and a length of
+ 256K, so a clone operation with a source range offset of 256K, a
+ destination offset of 1088K (1M + 64K) and length of 128K is issued.
+
+ After this operation the file size (and eof) at the receiver increases
+ from 1088K to 1216K (1088K + 128K);
+
+4) Now there's still 768K (896K - 128K) of data left to clone or write, so
+ it checks for the next file extent item, located at file offset 384K.
+ This file extent item points to a different extent, not the one we want
+ to clone, with a length of 640K. So we issue a write operation into the
+ file range 1216K (1088K + 128K, end of the last clone operation), with
+ a length of 640K and with a data matching the one we can find for that
+ range in send root.
+
+ After this operation, the file size (and eof) at the receiver increases
+ from 1216K to 1856K (1216K + 640K);
+
+5) Now there's still 128K (768K - 640K) of data left to clone or write, so
+ we look into the file extent item, which is for file offset 1M and it
+ points to the extent we want to clone, with a data offset of 64K and a
+ length of 960K.
+
+ However this matches the file offset we started with, the start of the
+ range to clone into. So we can't for sure find any file extent item
+ from here onwards with the rest of the data we want to clone, yet we
+ proceed and since the file extent item points to the shared extent,
+ with a data offset of 64K, we issue a clone operation with a source
+ range starting at file offset 1856K, which matches the file extent
+ item's offset, 1M, plus the amount of data cloned and written so far,
+ which is 64K (step 2) + 128K (step 3) + 640K (step 4). This clone
+ operation is invalid since the source range offset matches the current
+ eof of the file in the receiver. We should have stopped looking for
+ extents to clone at this point and instead fallback to write, which
+ would simply the contain the data in the file range from 1856K to
+ 1856K + 128K.
+
+So fix this by stopping the loop that looks for file ranges to clone at
+clone_range() when we reach the current eof of the file being processed,
+if we are cloning from the same file and using the send root as the clone
+root. This ensures any data not yet cloned will be sent to the receiver
+through a write operation.
+
+A test case for fstests will follow soon.
+
+Reported-by: Massimo B. <massimo.b@gmx.net>
+Link: https://lore.kernel.org/linux-btrfs/6ae34776e85912960a253a8327068a892998e685.camel@gmx.net/
+Fixes: 11f2069c113e ("Btrfs: send, allow clone operations within the same file")
+CC: stable@vger.kernel.org # 5.5+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+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/send.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5512,6 +5512,21 @@ static int clone_range(struct send_ctx *
+ break;
+ offset += clone_len;
+ clone_root->offset += clone_len;
++
++ /*
++ * If we are cloning from the file we are currently processing,
++ * and using the send root as the clone root, we must stop once
++ * the current clone offset reaches the current eof of the file
++ * at the receiver, otherwise we would issue an invalid clone
++ * operation (source range going beyond eof) and cause the
++ * receiver to fail. So if we reach the current eof, bail out
++ * and fallback to a regular write.
++ */
++ if (clone_root->root == sctx->send_root &&
++ clone_root->ino == sctx->cur_ino &&
++ clone_root->offset >= sctx->cur_inode_next_write_offset)
++ break;
++
+ data_offset += clone_len;
+ next:
+ path->slots[0]++;
--- /dev/null
+From 3c02e04fd4f57130e4fa75fab6f528f7a52db9b5 Mon Sep 17 00:00:00 2001
+From: Kirill Tkhai <ktkhai@virtuozzo.com>
+Date: Thu, 31 Dec 2020 00:33:18 +0300
+Subject: crypto: xor - Fix divide error in do_xor_speed()
+
+From: Kirill Tkhai <ktkhai@virtuozzo.com>
+
+commit 3c02e04fd4f57130e4fa75fab6f528f7a52db9b5 upstream.
+
+crypto: Fix divide error in do_xor_speed()
+
+From: Kirill Tkhai <ktkhai@virtuozzo.com>
+
+Latest (but not only latest) linux-next panics with divide
+error on my QEMU setup.
+
+The patch at the bottom of this message fixes the problem.
+
+xor: measuring software checksum speed
+divide error: 0000 [#1] PREEMPT SMP KASAN
+PREEMPT SMP KASAN
+CPU: 3 PID: 1 Comm: swapper/0 Not tainted 5.10.0-next-20201223+ #2177
+RIP: 0010:do_xor_speed+0xbb/0xf3
+Code: 41 ff cc 75 b5 bf 01 00 00 00 e8 3d 23 8b fe 65 8b 05 f6 49 83 7d 85 c0 75 05 e8
+ 84 70 81 fe b8 00 00 50 c3 31 d2 48 8d 7b 10 <f7> f5 41 89 c4 e8 58 07 a2 fe 44 89 63 10 48 8d 7b 08
+ e8 cb 07 a2
+RSP: 0000:ffff888100137dc8 EFLAGS: 00010246
+RAX: 00000000c3500000 RBX: ffffffff823f0160 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000808 RDI: ffffffff823f0170
+RBP: 0000000000000000 R08: ffffffff8109c50f R09: ffffffff824bb6f7
+R10: fffffbfff04976de R11: 0000000000000001 R12: 0000000000000000
+R13: ffff888101997000 R14: ffff888101994000 R15: ffffffff823f0178
+FS: 0000000000000000(0000) GS:ffff8881f7780000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000000 CR3: 000000000220e000 CR4: 00000000000006a0
+Call Trace:
+ calibrate_xor_blocks+0x13c/0x1c4
+ ? do_xor_speed+0xf3/0xf3
+ do_one_initcall+0xc1/0x1b7
+ ? start_kernel+0x373/0x373
+ ? unpoison_range+0x3a/0x60
+ kernel_init_freeable+0x1dd/0x238
+ ? rest_init+0xc6/0xc6
+ kernel_init+0x8/0x10a
+ ret_from_fork+0x1f/0x30
+---[ end trace 5bd3c1d0b77772da ]---
+
+Fixes: c055e3eae0f1 ("crypto: xor - use ktime for template benchmarking")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
+Acked-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/xor.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/crypto/xor.c
++++ b/crypto/xor.c
+@@ -107,6 +107,8 @@ do_xor_speed(struct xor_block_template *
+ preempt_enable();
+
+ // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
++ if (!min)
++ min = 1;
+ speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
+ tmpl->speed = speed;
+
--- /dev/null
+From 809b1e4945774c9ec5619a8f4e2189b7b3833c0c Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Thu, 21 Jan 2021 18:50:56 +0100
+Subject: dm: avoid filesystem lookup in dm_get_dev_t()
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 809b1e4945774c9ec5619a8f4e2189b7b3833c0c upstream.
+
+This reverts commit
+644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()")
+
+dm_get_dev_t() is just used to convert an arbitrary 'path' string
+into a dev_t. It doesn't presume that the device is present; that
+check will be done later, as the only caller is dm_get_device(),
+which does a dm_get_table_device() later on, which will properly
+open the device.
+
+So if the path string already _is_ in major:minor representation
+we can convert it directly, avoiding a recursion into the filesystem
+to lookup the block device.
+
+This avoids a hang in multipath_message() when the filesystem is
+inaccessible.
+
+Fixes: 644bda6f3460 ("dm table: fall back to getting device using name_to_dev_t()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Martin Wilck <mwilck@suse.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -370,14 +370,23 @@ int dm_get_device(struct dm_target *ti,
+ {
+ int r;
+ dev_t dev;
++ unsigned int major, minor;
++ char dummy;
+ struct dm_dev_internal *dd;
+ struct dm_table *t = ti->table;
+
+ BUG_ON(!t);
+
+- dev = dm_get_dev_t(path);
+- if (!dev)
+- return -ENODEV;
++ if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) {
++ /* Extract the major/minor numbers */
++ dev = MKDEV(major, minor);
++ if (MAJOR(dev) != major || MINOR(dev) != minor)
++ return -EOVERFLOW;
++ } else {
++ dev = dm_get_dev_t(path);
++ if (!dev)
++ return -ENODEV;
++ }
+
+ dd = find_device(&t->devices, dev);
+ if (!dd) {
--- /dev/null
+From 004b8ae9e2de55ca7857ba8471209dd3179e088c Mon Sep 17 00:00:00 2001
+From: Ignat Korchagin <ignat@cloudflare.com>
+Date: Tue, 19 Jan 2021 20:40:15 +0000
+Subject: dm crypt: fix copy and paste bug in crypt_alloc_req_aead
+
+From: Ignat Korchagin <ignat@cloudflare.com>
+
+commit 004b8ae9e2de55ca7857ba8471209dd3179e088c upstream.
+
+In commit d68b29584c25 ("dm crypt: use GFP_ATOMIC when allocating
+crypto requests from softirq") code was incorrectly copy and pasted
+from crypt_alloc_req_skcipher()'s crypto request allocation code to
+crypt_alloc_req_aead(). It is OK from runtime perspective as both
+simple encryption request pointer and AEAD request pointer are part of
+a union, but may confuse code reviewers.
+
+Fixes: d68b29584c25 ("dm crypt: use GFP_ATOMIC when allocating crypto requests from softirq")
+Cc: stable@vger.kernel.org # v5.9+
+Reported-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-crypt.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1481,9 +1481,9 @@ static int crypt_alloc_req_skcipher(stru
+ static int crypt_alloc_req_aead(struct crypt_config *cc,
+ struct convert_context *ctx)
+ {
+- if (!ctx->r.req) {
+- ctx->r.req = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+- if (!ctx->r.req)
++ if (!ctx->r.req_aead) {
++ ctx->r.req_aead = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
++ if (!ctx->r.req_aead)
+ return -ENOMEM;
+ }
+
--- /dev/null
+From 5c02406428d5219c367c5f53457698c58bc5f917 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 20 Jan 2021 13:59:11 -0500
+Subject: dm integrity: conditionally disable "recalculate" feature
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 5c02406428d5219c367c5f53457698c58bc5f917 upstream.
+
+Otherwise a malicious user could (ab)use the "recalculate" feature
+that makes dm-integrity calculate the checksums in the background
+while the device is already usable. When the system restarts before all
+checksums have been calculated, the calculation continues where it was
+interrupted even if the recalculate feature is not requested the next
+time the dm device is set up.
+
+Disable recalculating if we use internal_hash or journal_hash with a
+key (e.g. HMAC) and we don't have the "legacy_recalculate" flag.
+
+This may break activation of a volume, created by an older kernel,
+that is not yet fully recalculated -- if this happens, the user should
+add the "legacy_recalculate" flag to constructor parameters.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Reported-by: Daniel Glockner <dg@emlix.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/admin-guide/device-mapper/dm-integrity.rst | 12 +++++-
+ drivers/md/dm-integrity.c | 26 +++++++++++++--
+ 2 files changed, 33 insertions(+), 5 deletions(-)
+
+--- a/Documentation/admin-guide/device-mapper/dm-integrity.rst
++++ b/Documentation/admin-guide/device-mapper/dm-integrity.rst
+@@ -177,14 +177,20 @@ bitmap_flush_interval:number
+ The bitmap flush interval in milliseconds. The metadata buffers
+ are synchronized when this interval expires.
+
++allow_discards
++ Allow block discard requests (a.k.a. TRIM) for the integrity device.
++ Discards are only allowed to devices using internal hash.
++
+ fix_padding
+ Use a smaller padding of the tag area that is more
+ space-efficient. If this option is not present, large padding is
+ used - that is for compatibility with older kernels.
+
+-allow_discards
+- Allow block discard requests (a.k.a. TRIM) for the integrity device.
+- Discards are only allowed to devices using internal hash.
++legacy_recalculate
++ Allow recalculating of volumes with HMAC keys. This is disabled by
++ default for security reasons - an attacker could modify the volume,
++ set recalc_sector to zero, and the kernel would not detect the
++ modification.
+
+ The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and
+ allow_discards can be changed when reloading the target (load an inactive
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -257,8 +257,9 @@ struct dm_integrity_c {
+ bool journal_uptodate;
+ bool just_formatted;
+ bool recalculate_flag;
+- bool fix_padding;
+ bool discard;
++ bool fix_padding;
++ bool legacy_recalculate;
+
+ struct alg_spec internal_hash_alg;
+ struct alg_spec journal_crypt_alg;
+@@ -386,6 +387,14 @@ static int dm_integrity_failed(struct dm
+ return READ_ONCE(ic->failed);
+ }
+
++static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic)
++{
++ if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) &&
++ !ic->legacy_recalculate)
++ return true;
++ return false;
++}
++
+ static commit_id_t dm_integrity_commit_id(struct dm_integrity_c *ic, unsigned i,
+ unsigned j, unsigned char seq)
+ {
+@@ -3140,6 +3149,7 @@ static void dm_integrity_status(struct d
+ arg_count += !!ic->journal_crypt_alg.alg_string;
+ arg_count += !!ic->journal_mac_alg.alg_string;
+ arg_count += (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0;
++ arg_count += ic->legacy_recalculate;
+ DMEMIT("%s %llu %u %c %u", ic->dev->name, ic->start,
+ ic->tag_size, ic->mode, arg_count);
+ if (ic->meta_dev)
+@@ -3163,6 +3173,8 @@ static void dm_integrity_status(struct d
+ }
+ if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0)
+ DMEMIT(" fix_padding");
++ if (ic->legacy_recalculate)
++ DMEMIT(" legacy_recalculate");
+
+ #define EMIT_ALG(a, n) \
+ do { \
+@@ -3792,7 +3804,7 @@ static int dm_integrity_ctr(struct dm_ta
+ unsigned extra_args;
+ struct dm_arg_set as;
+ static const struct dm_arg _args[] = {
+- {0, 15, "Invalid number of feature args"},
++ {0, 16, "Invalid number of feature args"},
+ };
+ unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec;
+ bool should_write_sb;
+@@ -3940,6 +3952,8 @@ static int dm_integrity_ctr(struct dm_ta
+ ic->discard = true;
+ } else if (!strcmp(opt_string, "fix_padding")) {
+ ic->fix_padding = true;
++ } else if (!strcmp(opt_string, "legacy_recalculate")) {
++ ic->legacy_recalculate = true;
+ } else {
+ r = -EINVAL;
+ ti->error = "Invalid argument";
+@@ -4243,6 +4257,14 @@ try_smaller_buffer:
+ }
+ }
+
++ if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
++ le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors &&
++ dm_integrity_disable_recalculate(ic)) {
++ ti->error = "Recalculating with HMAC is disabled for security reasons - if you really need it, use the argument \"legacy_recalculate\"";
++ r = -EOPNOTSUPP;
++ goto bad;
++ }
++
+ ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev,
+ 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL);
+ if (IS_ERR(ic->bufio)) {
--- /dev/null
+From 2d06dfecb132a1cc2e374a44eae83b5c4356b8b4 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 20 Jan 2021 06:02:31 -0500
+Subject: dm integrity: fix a crash if "recalculate" used without "internal_hash"
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 2d06dfecb132a1cc2e374a44eae83b5c4356b8b4 upstream.
+
+Recalculate can only be specified with internal_hash.
+
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-integrity.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4235,6 +4235,12 @@ try_smaller_buffer:
+ r = -ENOMEM;
+ goto bad;
+ }
++ } else {
++ if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) {
++ ti->error = "Recalculate can only be specified with internal_hash";
++ r = -EINVAL;
++ goto bad;
++ }
+ }
+
+ ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev,
--- /dev/null
+From 348fe1ca5ccdca0f8c285e2ab99004fdcd531430 Mon Sep 17 00:00:00 2001
+From: Sung Lee <sung.lee@amd.com>
+Date: Tue, 5 Jan 2021 14:32:29 -0500
+Subject: drm/amd/display: DCN2X Find Secondary Pipe properly in MPO + ODM Case
+
+From: Sung Lee <sung.lee@amd.com>
+
+commit 348fe1ca5ccdca0f8c285e2ab99004fdcd531430 upstream.
+
+[WHY]
+Previously as MPO + ODM Combine was not supported, finding secondary pipes
+for each case was mutually exclusive. Now that both are supported at the same
+time, both cases should be taken into account when finding a secondary pipe.
+
+[HOW]
+If a secondary pipe cannot be found based on previous bottom pipe,
+search for a second pipe using next_odm_pipe instead.
+
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Sung Lee <sung.lee@amd.com>
+Reviewed-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
+Acked-by: Anson Jacob <anson.jacob@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 5.10.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+@@ -2520,8 +2520,7 @@ struct pipe_ctx *dcn20_find_secondary_pi
+ * if this primary pipe has a bottom pipe in prev. state
+ * and if the bottom pipe is still available (which it should be),
+ * pick that pipe as secondary
+- * Same logic applies for ODM pipes. Since mpo is not allowed with odm
+- * check in else case.
++ * Same logic applies for ODM pipes
+ */
+ if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) {
+ preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx;
+@@ -2529,7 +2528,9 @@ struct pipe_ctx *dcn20_find_secondary_pi
+ secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
+ secondary_pipe->pipe_idx = preferred_pipe_idx;
+ }
+- } else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
++ }
++ if (secondary_pipe == NULL &&
++ dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
+ preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx;
+ if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
+ secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
--- /dev/null
+From acc214bfafbafcd29d5d25d1ede5f11c14ffc147 Mon Sep 17 00:00:00 2001
+From: Huang Rui <ray.huang@amd.com>
+Date: Tue, 19 Jan 2021 13:35:21 +0800
+Subject: drm/amdgpu: remove gpu info firmware of green sardine
+
+From: Huang Rui <ray.huang@amd.com>
+
+commit acc214bfafbafcd29d5d25d1ede5f11c14ffc147 upstream.
+
+The ip discovery is supported on green sardine, it doesn't need gpu info
+firmware anymore.
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Prike Liang <Prike.Liang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org # 5.10.x
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -80,7 +80,6 @@ MODULE_FIRMWARE("amdgpu/renoir_gpu_info.
+ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
+ MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
+ MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
+-MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin");
+
+ #define AMDGPU_RESUME_MS 2000
+
--- /dev/null
+From 43b67309b6b2a3c08396cc9b3f83f21aa529d273 Mon Sep 17 00:00:00 2001
+From: Pan Bian <bianpan2016@163.com>
+Date: Tue, 19 Jan 2021 04:11:27 -0800
+Subject: drm/atomic: put state on error path
+
+From: Pan Bian <bianpan2016@163.com>
+
+commit 43b67309b6b2a3c08396cc9b3f83f21aa529d273 upstream.
+
+Put the state before returning error code.
+
+Fixes: 44596b8c4750 ("drm/atomic: Unify conflicting encoder handling.")
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210119121127.84127-1-bianpan2016@163.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_atomic_helper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -3007,7 +3007,7 @@ int drm_atomic_helper_set_config(struct
+
+ ret = handle_conflicting_encoders(state, true);
+ if (ret)
+- return ret;
++ goto fail;
+
+ ret = drm_atomic_commit(state);
+
--- /dev/null
+From 45db630e5f7ec83817c57c8ae387fe219bd42adf Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Mon, 18 Jan 2021 10:17:55 +0000
+Subject: drm/i915: Check for rq->hwsp validity after acquiring RCU lock
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 45db630e5f7ec83817c57c8ae387fe219bd42adf upstream.
+
+Since we allow removing the timeline map at runtime, there is a risk
+that rq->hwsp points into a stale page. To control that risk, we hold
+the RCU read lock while reading *rq->hwsp, but we missed a couple of
+important barriers. First, the unpinning / removal of the timeline map
+must be after all RCU readers into that map are complete, i.e. after an
+rcu barrier (in this case courtesy of call_rcu()). Secondly, we must
+make sure that the rq->hwsp we are about to dereference under the RCU
+lock is valid. In this case, we make the rq->hwsp pointer safe during
+i915_request_retire() and so we know that rq->hwsp may become invalid
+only after the request has been signaled. Therefore is the request is
+not yet signaled when we acquire rq->hwsp under the RCU, we know that
+rq->hwsp will remain valid for the duration of the RCU read lock.
+
+This is a very small window that may lead to either considering the
+request not completed (causing a delay until the request is checked
+again, any wait for the request is not affected) or dereferencing an
+invalid pointer.
+
+Fixes: 3adac4689f58 ("drm/i915: Introduce concept of per-timeline (context) HWSP")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Cc: <stable@vger.kernel.org> # v5.1+
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20201218122421.18344-1-chris@chris-wilson.co.uk
+(cherry picked from commit 9bb36cf66091ddf2d8840e5aa705ad3c93a6279b)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210118101755.476744-1-chris@chris-wilson.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 9 +-----
+ drivers/gpu/drm/i915/gt/intel_timeline.c | 10 +++----
+ drivers/gpu/drm/i915/i915_request.h | 37 ++++++++++++++++++++++++----
+ 3 files changed, 38 insertions(+), 18 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
++++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+@@ -134,11 +134,6 @@ static bool remove_signaling_context(str
+ return true;
+ }
+
+-static inline bool __request_completed(const struct i915_request *rq)
+-{
+- return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
+-}
+-
+ __maybe_unused static bool
+ check_signal_order(struct intel_context *ce, struct i915_request *rq)
+ {
+@@ -257,7 +252,7 @@ static void signal_irq_work(struct irq_w
+ list_for_each_entry_rcu(rq, &ce->signals, signal_link) {
+ bool release;
+
+- if (!__request_completed(rq))
++ if (!__i915_request_is_complete(rq))
+ break;
+
+ if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL,
+@@ -379,7 +374,7 @@ static void insert_breadcrumb(struct i91
+ * straight onto a signaled list, and queue the irq worker for
+ * its signal completion.
+ */
+- if (__request_completed(rq)) {
++ if (__i915_request_is_complete(rq)) {
+ if (__signal_request(rq) &&
+ llist_add(&rq->signal_node, &b->signaled_requests))
+ irq_work_queue(&b->irq_work);
+--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
++++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
+@@ -126,6 +126,10 @@ static void __rcu_cacheline_free(struct
+ struct intel_timeline_cacheline *cl =
+ container_of(rcu, typeof(*cl), rcu);
+
++ /* Must wait until after all *rq->hwsp are complete before removing */
++ i915_gem_object_unpin_map(cl->hwsp->vma->obj);
++ __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
++
+ i915_active_fini(&cl->active);
+ kfree(cl);
+ }
+@@ -133,11 +137,6 @@ static void __rcu_cacheline_free(struct
+ static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
+ {
+ GEM_BUG_ON(!i915_active_is_idle(&cl->active));
+-
+- i915_gem_object_unpin_map(cl->hwsp->vma->obj);
+- i915_vma_put(cl->hwsp->vma);
+- __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
+-
+ call_rcu(&cl->rcu, __rcu_cacheline_free);
+ }
+
+@@ -179,7 +178,6 @@ cacheline_alloc(struct intel_timeline_hw
+ return ERR_CAST(vaddr);
+ }
+
+- i915_vma_get(hwsp->vma);
+ cl->hwsp = hwsp;
+ cl->vaddr = page_pack_bits(vaddr, cacheline);
+
+--- a/drivers/gpu/drm/i915/i915_request.h
++++ b/drivers/gpu/drm/i915/i915_request.h
+@@ -434,7 +434,7 @@ static inline u32 hwsp_seqno(const struc
+
+ static inline bool __i915_request_has_started(const struct i915_request *rq)
+ {
+- return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1);
++ return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno - 1);
+ }
+
+ /**
+@@ -465,11 +465,19 @@ static inline bool __i915_request_has_st
+ */
+ static inline bool i915_request_started(const struct i915_request *rq)
+ {
++ bool result;
++
+ if (i915_request_signaled(rq))
+ return true;
+
+- /* Remember: started but may have since been preempted! */
+- return __i915_request_has_started(rq);
++ result = true;
++ rcu_read_lock(); /* the HWSP may be freed at runtime */
++ if (likely(!i915_request_signaled(rq)))
++ /* Remember: started but may have since been preempted! */
++ result = __i915_request_has_started(rq);
++ rcu_read_unlock();
++
++ return result;
+ }
+
+ /**
+@@ -482,10 +490,16 @@ static inline bool i915_request_started(
+ */
+ static inline bool i915_request_is_running(const struct i915_request *rq)
+ {
++ bool result;
++
+ if (!i915_request_is_active(rq))
+ return false;
+
+- return __i915_request_has_started(rq);
++ rcu_read_lock();
++ result = __i915_request_has_started(rq) && i915_request_is_active(rq);
++ rcu_read_unlock();
++
++ return result;
+ }
+
+ /**
+@@ -509,12 +523,25 @@ static inline bool i915_request_is_ready
+ return !list_empty(&rq->sched.link);
+ }
+
++static inline bool __i915_request_is_complete(const struct i915_request *rq)
++{
++ return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
++}
++
+ static inline bool i915_request_completed(const struct i915_request *rq)
+ {
++ bool result;
++
+ if (i915_request_signaled(rq))
+ return true;
+
+- return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno);
++ result = true;
++ rcu_read_lock(); /* the HWSP may be freed at runtime */
++ if (likely(!i915_request_signaled(rq)))
++ result = __i915_request_is_complete(rq);
++ rcu_read_unlock();
++
++ return result;
+ }
+
+ static inline void i915_request_mark_complete(struct i915_request *rq)
--- /dev/null
+From 488751a0ef9b5ce572c47301ce62d54fc6b5a74d Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Mon, 18 Jan 2021 09:53:32 +0000
+Subject: drm/i915/gt: Prevent use of engine->wa_ctx after error
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 488751a0ef9b5ce572c47301ce62d54fc6b5a74d upstream.
+
+On error we unpin and free the wa_ctx.vma, but do not clear any of the
+derived flags. During lrc_init, we look at the flags and attempt to
+dereference the wa_ctx.vma if they are set. To protect the error path
+where we try to limp along without the wa_ctx, make sure we clear those
+flags!
+
+Reported-by: Matt Roper <matthew.d.roper@intel.com>
+Fixes: 604a8f6f1e33 ("drm/i915/lrc: Only enable per-context and per-bb buffers if set")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
+Cc: <stable@vger.kernel.org> # v4.15+
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210108204026.20682-1-chris@chris-wilson.co.uk
+(cherry-picked from 5b4dc95cf7f573e927fbbd406ebe54225d41b9b2)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210118095332.458813-1-chris@chris-wilson.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/gt/intel_lrc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
++++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
+@@ -3936,6 +3936,9 @@ err:
+ static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine)
+ {
+ i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
++
++ /* Called on error unwind, clear all flags to prevent further use */
++ memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx));
+ }
+
+ typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);
--- /dev/null
+From a37eef63bc9e16e06361b539e528058146af80ab Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Tue, 19 Jan 2021 14:03:18 +0100
+Subject: drm/syncobj: Fix use-after-free
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+
+commit a37eef63bc9e16e06361b539e528058146af80ab upstream.
+
+While reviewing Christian's annotation patch I noticed that we have a
+user-after-free for the WAIT_FOR_SUBMIT case: We drop the syncobj
+reference before we've completed the waiting.
+
+Of course usually there's nothing bad happening here since userspace
+keeps the reference, but we can't rely on userspace to play nice here!
+
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Fixes: bc9c80fe01a2 ("drm/syncobj: use the timeline point in drm_syncobj_find_fence v4")
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Daniel Vetter <daniel@ffwll.ch>
+Cc: dri-devel@lists.freedesktop.org
+Cc: <stable@vger.kernel.org> # v5.2+
+Link: https://patchwork.freedesktop.org/patch/msgid/20210119130318.615145-1-daniel.vetter@ffwll.ch
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_syncobj.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/drm_syncobj.c
++++ b/drivers/gpu/drm/drm_syncobj.c
+@@ -388,19 +388,18 @@ int drm_syncobj_find_fence(struct drm_fi
+ return -ENOENT;
+
+ *fence = drm_syncobj_fence_get(syncobj);
+- drm_syncobj_put(syncobj);
+
+ if (*fence) {
+ ret = dma_fence_chain_find_seqno(fence, point);
+ if (!ret)
+- return 0;
++ goto out;
+ dma_fence_put(*fence);
+ } else {
+ ret = -EINVAL;
+ }
+
+ if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+- return ret;
++ goto out;
+
+ memset(&wait, 0, sizeof(wait));
+ wait.task = current;
+@@ -432,6 +431,9 @@ int drm_syncobj_find_fence(struct drm_fi
+ if (wait.node.next)
+ drm_syncobj_remove_wait(syncobj, &wait);
+
++out:
++ drm_syncobj_put(syncobj);
++
+ return ret;
+ }
+ EXPORT_SYMBOL(drm_syncobj_find_fence);
--- /dev/null
+From 1e249cb5b7fc09ff216aa5a12f6c302e434e88f9 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 12 Jan 2021 11:02:43 -0800
+Subject: fs: fix lazytime expiration handling in __writeback_single_inode()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 1e249cb5b7fc09ff216aa5a12f6c302e434e88f9 upstream.
+
+When lazytime is enabled and an inode is being written due to its
+in-memory updated timestamps having expired, either due to a sync() or
+syncfs() system call or due to dirtytime_expire_interval having elapsed,
+the VFS needs to inform the filesystem so that the filesystem can copy
+the inode's timestamps out to the on-disk data structures.
+
+This is done by __writeback_single_inode() calling
+mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).
+
+However, this occurs after __writeback_single_inode() has already
+cleared the dirty flags from ->i_state. This causes two bugs:
+
+- mark_inode_dirty_sync() redirties the inode, causing it to remain
+ dirty. This wastefully causes the inode to be written twice. But
+ more importantly, it breaks cases where sync_filesystem() is expected
+ to clean dirty inodes. This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
+ ioctl (as reported at
+ https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
+ as possibly filesystem freezing (freeze_super()).
+
+- Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
+ called from __writeback_single_inode() for lazytime expiration,
+ xfs_fs_dirty_inode() ignores the notification. (XFS only cares about
+ lazytime expirations, and it assumes that i_state will contain
+ I_DIRTY_TIME during those.) Therefore, lazy timestamps aren't
+ persisted by sync(), syncfs(), or dirtytime_expire_interval on XFS.
+
+Fix this by moving the call to mark_inode_dirty_sync() to earlier in
+__writeback_single_inode(), before the dirty flags are cleared from
+i_state. This makes filesystems be properly notified of the timestamp
+expiration, and it avoids incorrectly redirtying the inode.
+
+This fixes xfstest generic/580 (which tests
+FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
+enabled. It also fixes the new lazytime xfstest I've proposed, which
+reproduces the above-mentioned XFS bug
+(https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).
+
+Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly. But
+due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
+right thing to do because mark_inode_dirty_sync() now knows not to move
+the inode to a writeback list if it is currently queued for sync.
+
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+Cc: stable@vger.kernel.org
+Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
+Link: https://lore.kernel.org/r/20210112190253.64307-2-ebiggers@kernel.org
+Suggested-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *i
+ }
+
+ /*
+- * Some filesystems may redirty the inode during the writeback
+- * due to delalloc, clear dirty metadata flags right before
+- * write_inode()
++ * If the inode has dirty timestamps and we need to write them, call
++ * mark_inode_dirty_sync() to notify the filesystem about it and to
++ * change I_DIRTY_TIME into I_DIRTY_SYNC.
+ */
+- spin_lock(&inode->i_lock);
+-
+- dirty = inode->i_state & I_DIRTY;
+ if ((inode->i_state & I_DIRTY_TIME) &&
+- ((dirty & I_DIRTY_INODE) ||
+- wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
++ (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+ time_after(jiffies, inode->dirtied_time_when +
+ dirtytime_expire_interval * HZ))) {
+- dirty |= I_DIRTY_TIME;
+ trace_writeback_lazytime(inode);
++ mark_inode_dirty_sync(inode);
+ }
++
++ /*
++ * Some filesystems may redirty the inode during the writeback
++ * due to delalloc, clear dirty metadata flags right before
++ * write_inode()
++ */
++ spin_lock(&inode->i_lock);
++ dirty = inode->i_state & I_DIRTY;
+ inode->i_state &= ~dirty;
+
+ /*
+@@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *i
+
+ spin_unlock(&inode->i_lock);
+
+- if (dirty & I_DIRTY_TIME)
+- mark_inode_dirty_sync(inode);
+ /* Don't write the inode if only I_DIRTY_PAGES was set */
+ if (dirty & ~I_DIRTY_PAGES) {
+ int err = write_inode(inode, wbc);
--- /dev/null
+From bc1c2048abbe3c3074b4de91d213595c57741a6b Mon Sep 17 00:00:00 2001
+From: Mikko Perttunen <mperttunen@nvidia.com>
+Date: Tue, 12 Jan 2021 12:22:25 +0200
+Subject: i2c: bpmp-tegra: Ignore unknown I2C_M flags
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+commit bc1c2048abbe3c3074b4de91d213595c57741a6b upstream.
+
+In order to not to start returning errors when new I2C_M flags are
+added, change behavior to just ignore all flags that we don't know
+about. This includes the I2C_M_DMA_SAFE flag that already exists but
+causes -EINVAL to be returned for valid transactions.
+
+Cc: stable@vger.kernel.org # v4.19+
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-tegra-bpmp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-tegra-bpmp.c
++++ b/drivers/i2c/busses/i2c-tegra-bpmp.c
+@@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 fl
+ flags &= ~I2C_M_RECV_LEN;
+ }
+
+- return (flags != 0) ? -EINVAL : 0;
++ return 0;
+ }
+
+ /**
--- /dev/null
+From 27b7c6e096264cc7b91bb80a4f65f8c0a66f079f Mon Sep 17 00:00:00 2001
+From: Mikko Perttunen <mperttunen@nvidia.com>
+Date: Mon, 11 Jan 2021 18:08:32 +0200
+Subject: i2c: tegra: Wait for config load atomically while in ISR
+
+From: Mikko Perttunen <mperttunen@nvidia.com>
+
+commit 27b7c6e096264cc7b91bb80a4f65f8c0a66f079f upstream.
+
+Upon a communication error, the interrupt handler can call
+tegra_i2c_disable_packet_mode. This causes a sleeping poll to happen
+unless the current transaction was marked atomic. Fix this by
+making the poll happen atomically if we are in an IRQ.
+
+This matches the behavior prior to the patch mentioned
+in the Fixes tag.
+
+Fixes: ede2299f7101 ("i2c: tegra: Support atomic transfers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/busses/i2c-tegra.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -533,7 +533,7 @@ static int tegra_i2c_poll_register(struc
+ void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
+ u32 val;
+
+- if (!i2c_dev->atomic_mode)
++ if (!i2c_dev->atomic_mode && !in_irq())
+ return readl_relaxed_poll_timeout(addr, val, !(val & mask),
+ delay_us, timeout_us);
+
--- /dev/null
+From b503087445ce7e45fabdee87ca9e460d5b5b5168 Mon Sep 17 00:00:00 2001
+From: Peter Collingbourne <pcc@google.com>
+Date: Thu, 14 Jan 2021 12:14:05 -0800
+Subject: mmc: core: don't initialize block size from ext_csd if not present
+
+From: Peter Collingbourne <pcc@google.com>
+
+commit b503087445ce7e45fabdee87ca9e460d5b5b5168 upstream.
+
+If extended CSD was not available, the eMMC driver would incorrectly
+set the block size to 0, as the data_sector_size field of ext_csd
+was never initialized. This issue was exposed by commit 817046ecddbc
+("block: Align max_hw_sectors to logical blocksize") which caused
+max_sectors and max_hw_sectors to be set to 0 after setting the block
+size to 0, resulting in a kernel panic in bio_split when attempting
+to read from the device. Fix it by only reading the block size from
+ext_csd if it is available.
+
+Fixes: a5075eb94837 ("mmc: block: Allow disabling 512B sector size emulation")
+Signed-off-by: Peter Collingbourne <pcc@google.com>
+Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
+Link: https://linux-review.googlesource.com/id/If244d178da4d86b52034459438fec295b02d6e60
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210114201405.2934886-1-pcc@google.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/core/queue.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -384,8 +384,10 @@ static void mmc_setup_queue(struct mmc_q
+ "merging was advertised but not possible");
+ blk_queue_max_segments(mq->queue, mmc_get_max_segments(host));
+
+- if (mmc_card_mmc(card))
++ if (mmc_card_mmc(card) && card->ext_csd.data_sector_size) {
+ block_size = card->ext_csd.data_sector_size;
++ WARN_ON(block_size != 512 && block_size != 4096);
++ }
+
+ blk_queue_logical_block_size(mq->queue, block_size);
+ /*
--- /dev/null
+From 5b191dcba719319148eeecf6ed409949fac55b39 Mon Sep 17 00:00:00 2001
+From: Al Cooper <alcooperx@gmail.com>
+Date: Thu, 7 Jan 2021 17:15:09 -0500
+Subject: mmc: sdhci-brcmstb: Fix mmc timeout errors on S5 suspend
+
+From: Al Cooper <alcooperx@gmail.com>
+
+commit 5b191dcba719319148eeecf6ed409949fac55b39 upstream.
+
+Commit e7b5d63a82fe ("mmc: sdhci-brcmstb: Add shutdown callback")
+that added a shutdown callback to the diver, is causing "mmc timeout"
+errors on S5 suspend. The problem was that the "remove" was queuing
+additional MMC commands after the "shutdown" and these caused
+timeouts as the MMC queues were cleaned up for "remove". The
+shutdown callback will be changed to calling sdhci-pltfm_suspend
+which should get better power savings because the clocks will be
+shutdown.
+
+Fixes: e7b5d63a82fe ("mmc: sdhci-brcmstb: Add shutdown callback")
+Signed-off-by: Al Cooper <alcooperx@gmail.com>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20210107221509.6597-1-alcooperx@gmail.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -314,11 +314,7 @@ err_clk:
+
+ static void sdhci_brcmstb_shutdown(struct platform_device *pdev)
+ {
+- int ret;
+-
+- ret = sdhci_pltfm_unregister(pdev);
+- if (ret)
+- dev_err(&pdev->dev, "failed to shutdown\n");
++ sdhci_pltfm_suspend(&pdev->dev);
+ }
+
+ MODULE_DEVICE_TABLE(of, sdhci_brcm_of_match);
--- /dev/null
+From ca1219c0a7432272324660fc9f61a9940f90c50b Mon Sep 17 00:00:00 2001
+From: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+Date: Tue, 29 Dec 2020 16:16:25 +0800
+Subject: mmc: sdhci-of-dwcmshc: fix rpmb access
+
+From: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+
+commit ca1219c0a7432272324660fc9f61a9940f90c50b upstream.
+
+Commit a44f7cb93732 ("mmc: core: use mrq->sbc when sending CMD23 for
+RPMB") began to use ACMD23 for RPMB if the host supports ACMD23. In
+RPMB ACM23 case, we need to set bit 31 to CMD23 argument, otherwise
+RPMB write operation will return general fail.
+
+However, no matter V4 is enabled or not, the dwcmshc's ARGUMENT2
+register is 32-bit block count register which doesn't support stuff
+bits of CMD23 argument. So let's handle this specific ACMD23 case.
+
+From another side, this patch also prepare for future v4 enabling
+for dwcmshc, because from the 4.10 spec, the ARGUMENT2 register is
+redefined as 32bit block count which doesn't support stuff bits of
+CMD23 argument.
+
+Fixes: a44f7cb93732 ("mmc: core: use mrq->sbc when sending CMD23 for RPMB")
+Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20201229161625.38255233@xhacker.debian
+Cc: stable@vger.kernel.org
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-of-dwcmshc.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
+@@ -16,6 +16,8 @@
+
+ #include "sdhci-pltfm.h"
+
++#define SDHCI_DWCMSHC_ARG2_STUFF GENMASK(31, 16)
++
+ /* DWCMSHC specific Mode Select value */
+ #define DWCMSHC_CTRL_HS400 0x7
+
+@@ -49,6 +51,29 @@ static void dwcmshc_adma_write_desc(stru
+ sdhci_adma_write_desc(host, desc, addr, len, cmd);
+ }
+
++static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,
++ struct mmc_request *mrq)
++{
++ struct sdhci_host *host = mmc_priv(mmc);
++
++ /*
++ * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit
++ * block count register which doesn't support stuff bits of
++ * CMD23 argument on dwcmsch host controller.
++ */
++ if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF))
++ host->flags &= ~SDHCI_AUTO_CMD23;
++ else
++ host->flags |= SDHCI_AUTO_CMD23;
++}
++
++static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq)
++{
++ dwcmshc_check_auto_cmd23(mmc, mrq);
++
++ sdhci_request(mmc, mrq);
++}
++
+ static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
+ unsigned int timing)
+ {
+@@ -133,6 +158,8 @@ static int dwcmshc_probe(struct platform
+
+ sdhci_get_of_property(pdev);
+
++ host->mmc_host_ops.request = dwcmshc_request;
++
+ err = sdhci_add_host(host);
+ if (err)
+ goto err_clk;
--- /dev/null
+From 1a3ed0dc3594d99ff341ec63865a40519ea24b8d Mon Sep 17 00:00:00 2001
+From: Alex Leibovich <alexl@marvell.com>
+Date: Fri, 11 Dec 2020 15:16:56 +0100
+Subject: mmc: sdhci-xenon: fix 1.8v regulator stabilization
+
+From: Alex Leibovich <alexl@marvell.com>
+
+commit 1a3ed0dc3594d99ff341ec63865a40519ea24b8d upstream.
+
+Automatic Clock Gating is a feature used for the power consumption
+optimisation. It turned out that during early init phase it may prevent the
+stable voltage switch to 1.8V - due to that on some platforms an endless
+printout in dmesg can be observed: "mmc1: 1.8V regulator output did not
+became stable" Fix the problem by disabling the ACG at very beginning of
+the sdhci_init and let that be enabled later.
+
+Fixes: 3a3748dba881 ("mmc: sdhci-xenon: Add Marvell Xenon SDHC core functionality")
+Signed-off-by: Alex Leibovich <alexl@marvell.com>
+Signed-off-by: Marcin Wojtas <mw@semihalf.com>
+Cc: stable@vger.kernel.org
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: https://lore.kernel.org/r/20201211141656.24915-1-mw@semihalf.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mmc/host/sdhci-xenon.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/mmc/host/sdhci-xenon.c
++++ b/drivers/mmc/host/sdhci-xenon.c
+@@ -167,7 +167,12 @@ static void xenon_reset_exit(struct sdhc
+ /* Disable tuning request and auto-retuning again */
+ xenon_retune_setup(host);
+
+- xenon_set_acg(host, true);
++ /*
++ * The ACG should be turned off at the early init time, in order
++ * to solve a possible issues with the 1.8V regulator stabilization.
++ * The feature is enabled in later stage.
++ */
++ xenon_set_acg(host, false);
+
+ xenon_set_sdclk_off_idle(host, sdhc_id, false);
+
--- /dev/null
+From 4883a60c17eda6bf52d1c817ee7ead65b4a02da2 Mon Sep 17 00:00:00 2001
+From: Sean Nyekjaer <sean@geanix.com>
+Date: Mon, 21 Dec 2020 11:00:13 +0100
+Subject: mtd: rawnand: gpmi: fix dst bit offset when extracting raw payload
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sean Nyekjaer <sean@geanix.com>
+
+commit 4883a60c17eda6bf52d1c817ee7ead65b4a02da2 upstream.
+
+Re-add the multiply by 8 to "step * eccsize" to correct the destination bit offset
+when extracting the data payload in gpmi_ecc_read_page_raw().
+
+Fixes: e5e5631cc889 ("mtd: rawnand: gpmi: Use nand_extract_bits()")
+Cc: stable@vger.kernel.org
+Reported-by: Martin Hundebøll <martin@geanix.com>
+Signed-off-by: Sean Nyekjaer <sean@geanix.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20201221100013.2715675-1-sean@geanix.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+@@ -1613,7 +1613,7 @@ static int gpmi_ecc_read_page_raw(struct
+ /* Extract interleaved payload data and ECC bits */
+ for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
+ if (buf)
+- nand_extract_bits(buf, step * eccsize, tmp_buf,
++ nand_extract_bits(buf, step * eccsize * 8, tmp_buf,
+ src_bit_off, eccsize * 8);
+ src_bit_off += eccsize * 8;
+
--- /dev/null
+From 3c97be6982e689d7b2430187a11f8c78e573abdb Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Mon, 4 Jan 2021 10:30:57 +0100
+Subject: mtd: rawnand: nandsim: Fix the logic when selecting Hamming soft ECC engine
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+commit 3c97be6982e689d7b2430187a11f8c78e573abdb upstream.
+
+I have been fooled by the logic picking the right ECC engine which is
+spread across two functions: *init_module() and *_attach(). I thought
+this driver was not impacted by the recent changes around the ECC
+engines DT parsing logic but in fact it is.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Fixes: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing bits")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210104093057.31178-1-miquel.raynal@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/nand/raw/nandsim.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/mtd/nand/raw/nandsim.c
++++ b/drivers/mtd/nand/raw/nandsim.c
+@@ -2211,6 +2211,9 @@ static int ns_attach_chip(struct nand_ch
+ {
+ unsigned int eccsteps, eccbytes;
+
++ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
++ chip->ecc.algo = bch ? NAND_ECC_ALGO_BCH : NAND_ECC_ALGO_HAMMING;
++
+ if (!bch)
+ return 0;
+
+@@ -2234,8 +2237,6 @@ static int ns_attach_chip(struct nand_ch
+ return -EINVAL;
+ }
+
+- chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+- chip->ecc.algo = NAND_ECC_ALGO_BCH;
+ chip->ecc.size = 512;
+ chip->ecc.strength = bch;
+ chip->ecc.bytes = eccbytes;
+@@ -2274,8 +2275,6 @@ static int __init ns_init_module(void)
+ nsmtd = nand_to_mtd(chip);
+ nand_set_controller_data(chip, (void *)ns);
+
+- chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+- chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
+ /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */
+ /* and 'badblocks' parameters to work */
+ chip->options |= NAND_SKIP_BBTSCAN;
--- /dev/null
+From 9a85c09a3f507b925d75cb0c7c8f364467038052 Mon Sep 17 00:00:00 2001
+From: Paul Cercueil <paul@crapouillou.net>
+Date: Fri, 11 Dec 2020 23:28:09 +0000
+Subject: pinctrl: ingenic: Fix JZ4760 support
+
+From: Paul Cercueil <paul@crapouillou.net>
+
+commit 9a85c09a3f507b925d75cb0c7c8f364467038052 upstream.
+
+- JZ4760 and JZ4760B have a similar register layout as the JZ4740, and
+ don't use the new register layout, which was introduced with the
+ JZ4770 SoC and not the JZ4760 or JZ4760B SoCs.
+
+- The JZ4740 code path only expected two function modes to be
+ configurable for each pin, and wouldn't work with more than two. Fix
+ it for the JZ4760, which has four configurable function modes.
+
+Fixes: 0257595a5cf4 ("pinctrl: Ingenic: Add pinctrl driver for JZ4760 and JZ4760B.")
+Cc: <stable@vger.kernel.org> # 5.3
+Signed-off-by: Paul Cercueil <paul@crapouillou.net>
+Link: https://lore.kernel.org/r/20201211232810.261565-1-paul@crapouillou.net
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pinctrl/pinctrl-ingenic.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-ingenic.c
++++ b/drivers/pinctrl/pinctrl-ingenic.c
+@@ -2052,7 +2052,7 @@ static inline bool ingenic_gpio_get_valu
+ static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
+ u8 offset, int value)
+ {
+- if (jzgc->jzpc->info->version >= ID_JZ4760)
++ if (jzgc->jzpc->info->version >= ID_JZ4770)
+ ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value);
+ else
+ ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
+@@ -2082,7 +2082,7 @@ static void irq_set_type(struct ingenic_
+ break;
+ }
+
+- if (jzgc->jzpc->info->version >= ID_JZ4760) {
++ if (jzgc->jzpc->info->version >= ID_JZ4770) {
+ reg1 = JZ4760_GPIO_PAT1;
+ reg2 = JZ4760_GPIO_PAT0;
+ } else {
+@@ -2122,7 +2122,7 @@ static void ingenic_gpio_irq_enable(stru
+ struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
+ int irq = irqd->hwirq;
+
+- if (jzgc->jzpc->info->version >= ID_JZ4760)
++ if (jzgc->jzpc->info->version >= ID_JZ4770)
+ ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true);
+ else
+ ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
+@@ -2138,7 +2138,7 @@ static void ingenic_gpio_irq_disable(str
+
+ ingenic_gpio_irq_mask(irqd);
+
+- if (jzgc->jzpc->info->version >= ID_JZ4760)
++ if (jzgc->jzpc->info->version >= ID_JZ4770)
+ ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false);
+ else
+ ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
+@@ -2163,7 +2163,7 @@ static void ingenic_gpio_irq_ack(struct
+ irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH);
+ }
+
+- if (jzgc->jzpc->info->version >= ID_JZ4760)
++ if (jzgc->jzpc->info->version >= ID_JZ4770)
+ ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false);
+ else
+ ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
+@@ -2220,7 +2220,7 @@ static void ingenic_gpio_irq_handler(str
+
+ chained_irq_enter(irq_chip, desc);
+
+- if (jzgc->jzpc->info->version >= ID_JZ4760)
++ if (jzgc->jzpc->info->version >= ID_JZ4770)
+ flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG);
+ else
+ flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
+@@ -2302,7 +2302,7 @@ static int ingenic_gpio_get_direction(st
+ struct ingenic_pinctrl *jzpc = jzgc->jzpc;
+ unsigned int pin = gc->base + offset;
+
+- if (jzpc->info->version >= ID_JZ4760) {
++ if (jzpc->info->version >= ID_JZ4770) {
+ if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) ||
+ ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1))
+ return GPIO_LINE_DIRECTION_IN;
+@@ -2360,7 +2360,7 @@ static int ingenic_pinmux_set_pin_fn(str
+ ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
+ ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
+ ingenic_shadow_config_pin_load(jzpc, pin);
+- } else if (jzpc->info->version >= ID_JZ4760) {
++ } else if (jzpc->info->version >= ID_JZ4770) {
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+ ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
+@@ -2368,7 +2368,7 @@ static int ingenic_pinmux_set_pin_fn(str
+ } else {
+ ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
+ ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
+- ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
++ ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1);
+ }
+
+ return 0;
+@@ -2418,7 +2418,7 @@ static int ingenic_pinmux_gpio_set_direc
+ ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true);
+ ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
+ ingenic_shadow_config_pin_load(jzpc, pin);
+- } else if (jzpc->info->version >= ID_JZ4760) {
++ } else if (jzpc->info->version >= ID_JZ4770) {
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+ ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
+@@ -2448,7 +2448,7 @@ static int ingenic_pinconf_get(struct pi
+ unsigned int offt = pin / PINS_PER_GPIO_CHIP;
+ bool pull;
+
+- if (jzpc->info->version >= ID_JZ4760)
++ if (jzpc->info->version >= ID_JZ4770)
+ pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN);
+ else
+ pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
+@@ -2498,7 +2498,7 @@ static void ingenic_set_bias(struct inge
+ REG_SET(X1830_GPIO_PEH), bias << idxh);
+ }
+
+- } else if (jzpc->info->version >= ID_JZ4760) {
++ } else if (jzpc->info->version >= ID_JZ4770) {
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !bias);
+ } else {
+ ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias);
+@@ -2508,7 +2508,7 @@ static void ingenic_set_bias(struct inge
+ static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc,
+ unsigned int pin, bool high)
+ {
+- if (jzpc->info->version >= ID_JZ4760)
++ if (jzpc->info->version >= ID_JZ4770)
+ ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high);
+ else
+ ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
--- /dev/null
+From 9bba96275576da0cf78ede62aeb2fc975ed8a32d Mon Sep 17 00:00:00 2001
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Date: Wed, 23 Dec 2020 17:36:44 +0300
+Subject: platform/x86: i2c-multi-instantiate: Don't create platform device for INT3515 ACPI nodes
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+commit 9bba96275576da0cf78ede62aeb2fc975ed8a32d upstream.
+
+There are several reports about the tps6598x causing
+interrupt flood on boards with the INT3515 ACPI node, which
+then causes instability. There appears to be several
+problems with the interrupt. One problem is that the
+I2CSerialBus resources do not always map to the Interrupt
+resource with the same index, but that is not the only
+problem. We have not been able to come up with a solution
+for all the issues, and because of that disabling the device
+for now.
+
+The PD controller on these platforms is autonomous, and the
+purpose for the driver is primarily to supply status to the
+userspace, so this will not affect any functionality.
+
+Reported-by: Moody Salem <moody@uniswap.org>
+Fixes: a3dd034a1707 ("ACPI / scan: Create platform device for INT3515 ACPI nodes")
+Cc: stable@vger.kernel.org
+BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1883511
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20201223143644.33341-1-heikki.krogerus@linux.intel.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/i2c-multi-instantiate.c | 31 ++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+--- a/drivers/platform/x86/i2c-multi-instantiate.c
++++ b/drivers/platform/x86/i2c-multi-instantiate.c
+@@ -166,13 +166,29 @@ static const struct i2c_inst_data bsg215
+ {}
+ };
+
+-static const struct i2c_inst_data int3515_data[] = {
+- { "tps6598x", IRQ_RESOURCE_APIC, 0 },
+- { "tps6598x", IRQ_RESOURCE_APIC, 1 },
+- { "tps6598x", IRQ_RESOURCE_APIC, 2 },
+- { "tps6598x", IRQ_RESOURCE_APIC, 3 },
+- {}
+-};
++/*
++ * Device with _HID INT3515 (TI PD controllers) has some unresolved interrupt
++ * issues. The most common problem seen is interrupt flood.
++ *
++ * There are at least two known causes. Firstly, on some boards, the
++ * I2CSerialBus resource index does not match the Interrupt resource, i.e. they
++ * are not one-to-one mapped like in the array below. Secondly, on some boards
++ * the IRQ line from the PD controller is not actually connected at all. But the
++ * interrupt flood is also seen on some boards where those are not a problem, so
++ * there are some other problems as well.
++ *
++ * Because of the issues with the interrupt, the device is disabled for now. If
++ * you wish to debug the issues, uncomment the below, and add an entry for the
++ * INT3515 device to the i2c_multi_instance_ids table.
++ *
++ * static const struct i2c_inst_data int3515_data[] = {
++ * { "tps6598x", IRQ_RESOURCE_APIC, 0 },
++ * { "tps6598x", IRQ_RESOURCE_APIC, 1 },
++ * { "tps6598x", IRQ_RESOURCE_APIC, 2 },
++ * { "tps6598x", IRQ_RESOURCE_APIC, 3 },
++ * { }
++ * };
++ */
+
+ /*
+ * Note new device-ids must also be added to i2c_multi_instantiate_ids in
+@@ -181,7 +197,6 @@ static const struct i2c_inst_data int351
+ static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = {
+ { "BSG1160", (unsigned long)bsg1160_data },
+ { "BSG2150", (unsigned long)bsg2150_data },
+- { "INT3515", (unsigned long)int3515_data },
+ { }
+ };
+ MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids);
--- /dev/null
+From f419e5940f1d9892ea6f45acdaca572b9e73ff39 Mon Sep 17 00:00:00 2001
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Date: Thu, 7 Jan 2021 22:44:38 +0800
+Subject: platform/x86: ideapad-laptop: Disable touchpad_switch for ELAN0634
+
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+
+commit f419e5940f1d9892ea6f45acdaca572b9e73ff39 upstream.
+
+Newer ideapads (e.g.: Yoga 14s, 720S 14) come with ELAN0634 touchpad do not
+use EC to switch touchpad.
+
+Reading VPCCMD_R_TOUCHPAD will return zero thus touchpad may be blocked
+unexpectedly.
+Writing VPCCMD_W_TOUCHPAD may cause a spurious key press.
+
+Add has_touchpad_switch to workaround these machines.
+
+Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Cc: stable@vger.kernel.org # 5.4+
+--
+v2: Specify touchpad to ELAN0634
+v3: Stupid missing ! in v2
+v4: Correct acpi_dev_present usage (Hans)
+Link: https://lore.kernel.org/r/20210107144438.12605-1-jiaxun.yang@flygoat.com
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/ideapad-laptop.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/platform/x86/ideapad-laptop.c
++++ b/drivers/platform/x86/ideapad-laptop.c
+@@ -92,6 +92,7 @@ struct ideapad_private {
+ struct dentry *debug;
+ unsigned long cfg;
+ bool has_hw_rfkill_switch;
++ bool has_touchpad_switch;
+ const char *fnesc_guid;
+ };
+
+@@ -535,7 +536,9 @@ static umode_t ideapad_is_visible(struct
+ } else if (attr == &dev_attr_fn_lock.attr) {
+ supported = acpi_has_method(priv->adev->handle, "HALS") &&
+ acpi_has_method(priv->adev->handle, "SALS");
+- } else
++ } else if (attr == &dev_attr_touchpad.attr)
++ supported = priv->has_touchpad_switch;
++ else
+ supported = true;
+
+ return supported ? attr->mode : 0;
+@@ -867,6 +870,9 @@ static void ideapad_sync_touchpad_state(
+ {
+ unsigned long value;
+
++ if (!priv->has_touchpad_switch)
++ return;
++
+ /* Without reading from EC touchpad LED doesn't switch state */
+ if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) {
+ /* Some IdeaPads don't really turn off touchpad - they only
+@@ -989,6 +995,9 @@ static int ideapad_acpi_add(struct platf
+ priv->platform_device = pdev;
+ priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
+
++ /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
++ priv->has_touchpad_switch = !acpi_dev_present("ELAN0634", NULL, -1);
++
+ ret = ideapad_sysfs_init(priv);
+ if (ret)
+ return ret;
+@@ -1006,6 +1015,10 @@ static int ideapad_acpi_add(struct platf
+ if (!priv->has_hw_rfkill_switch)
+ write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1);
+
++ /* The same for Touchpad */
++ if (!priv->has_touchpad_switch)
++ write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1);
++
+ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
+ if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
+ ideapad_register_rfkill(priv, i);
--- /dev/null
+From f0e386ee0c0b71ea6f7238506a4d0965a2dbef11 Mon Sep 17 00:00:00 2001
+From: John Ogness <john.ogness@linutronix.de>
+Date: Thu, 14 Jan 2021 18:10:12 +0106
+Subject: printk: fix buffer overflow potential for print_text()
+
+From: John Ogness <john.ogness@linutronix.de>
+
+commit f0e386ee0c0b71ea6f7238506a4d0965a2dbef11 upstream.
+
+Before the commit 896fbe20b4e2333fb55 ("printk: use the lockless
+ringbuffer"), msg_print_text() would only write up to size-1 bytes
+into the provided buffer. Some callers expect this behavior and
+append a terminator to returned string. In particular:
+
+arch/powerpc/xmon/xmon.c:dump_log_buf()
+arch/um/kernel/kmsg_dump.c:kmsg_dumper_stdout()
+
+msg_print_text() has been replaced by record_print_text(), which
+currently fills the full size of the buffer. This causes a
+buffer overflow for the above callers.
+
+Change record_print_text() so that it will only use size-1 bytes
+for text data. Also, for paranoia sakes, add a terminator after
+the text data.
+
+And finally, document this behavior so that it is clear that only
+size-1 bytes are used and a terminator is added.
+
+Fixes: 896fbe20b4e2333fb55 ("printk: use the lockless ringbuffer")
+Cc: stable@vger.kernel.org # 5.10+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Reviewed-by: Petr Mladek <pmladek@suse.com>
+Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+Link: https://lore.kernel.org/r/20210114170412.4819-1-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/printk/printk.c | 36 +++++++++++++++++++++++++++---------
+ 1 file changed, 27 insertions(+), 9 deletions(-)
+
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -1338,11 +1338,16 @@ static size_t info_print_prefix(const st
+ * done:
+ *
+ * - Add prefix for each line.
++ * - Drop truncated lines that no longer fit into the buffer.
+ * - Add the trailing newline that has been removed in vprintk_store().
+- * - Drop truncated lines that do not longer fit into the buffer.
++ * - Add a string terminator.
++ *
++ * Since the produced string is always terminated, the maximum possible
++ * return value is @r->text_buf_size - 1;
+ *
+ * Return: The length of the updated/prepared text, including the added
+- * prefixes and the newline. The dropped line(s) are not counted.
++ * prefixes and the newline. The terminator is not counted. The dropped
++ * line(s) are not counted.
+ */
+ static size_t record_print_text(struct printk_record *r, bool syslog,
+ bool time)
+@@ -1385,26 +1390,31 @@ static size_t record_print_text(struct p
+
+ /*
+ * Truncate the text if there is not enough space to add the
+- * prefix and a trailing newline.
++ * prefix and a trailing newline and a terminator.
+ */
+- if (len + prefix_len + text_len + 1 > buf_size) {
++ if (len + prefix_len + text_len + 1 + 1 > buf_size) {
+ /* Drop even the current line if no space. */
+- if (len + prefix_len + line_len + 1 > buf_size)
++ if (len + prefix_len + line_len + 1 + 1 > buf_size)
+ break;
+
+- text_len = buf_size - len - prefix_len - 1;
++ text_len = buf_size - len - prefix_len - 1 - 1;
+ truncated = true;
+ }
+
+ memmove(text + prefix_len, text, text_len);
+ memcpy(text, prefix, prefix_len);
+
++ /*
++ * Increment the prepared length to include the text and
++ * prefix that were just moved+copied. Also increment for the
++ * newline at the end of this line. If this is the last line,
++ * there is no newline, but it will be added immediately below.
++ */
+ len += prefix_len + line_len + 1;
+-
+ if (text_len == line_len) {
+ /*
+- * Add the trailing newline removed in
+- * vprintk_store().
++ * This is the last line. Add the trailing newline
++ * removed in vprintk_store().
+ */
+ text[prefix_len + line_len] = '\n';
+ break;
+@@ -1429,6 +1439,14 @@ static size_t record_print_text(struct p
+ text_len -= line_len + 1;
+ }
+
++ /*
++ * If a buffer was provided, it will be terminated. Space for the
++ * string terminator is guaranteed to be available. The terminator is
++ * not counted in the return value.
++ */
++ if (buf_size > 0)
++ text[len] = 0;
++
+ return len;
+ }
+
--- /dev/null
+From 780e1384687d6ecdee9ca789a1027610484ac8a2 Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Date: Wed, 13 Jan 2021 11:45:08 +0900
+Subject: scsi: target: tcmu: Fix use-after-free of se_cmd->priv
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+commit 780e1384687d6ecdee9ca789a1027610484ac8a2 upstream.
+
+Commit a35129024e88 ("scsi: target: tcmu: Use priv pointer in se_cmd")
+modified tcmu_free_cmd() to set NULL to priv pointer in se_cmd. However,
+se_cmd can be already freed by work queue triggered in
+target_complete_cmd(). This caused BUG KASAN use-after-free [1].
+
+To fix the bug, do not touch priv pointer in tcmu_free_cmd(). Instead, set
+NULL to priv pointer before target_complete_cmd() calls. Also, to avoid
+unnecessary priv pointer change in tcmu_queue_cmd(), modify priv pointer in
+the function only when tcmu_free_cmd() is not called.
+
+[1]
+BUG: KASAN: use-after-free in tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+Write of size 8 at addr ffff88814cf79a40 by task cmdproc-uio0/14842
+
+CPU: 2 PID: 14842 Comm: cmdproc-uio0 Not tainted 5.11.0-rc2 #1
+Hardware name: Supermicro Super Server/X10SRL-F, BIOS 3.2 11/22/2019
+Call Trace:
+ dump_stack+0x9a/0xcc
+ ? tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+ print_address_description.constprop.0+0x18/0x130
+ ? tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+ ? tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+ kasan_report.cold+0x7f/0x10e
+ ? tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+ tcmu_handle_completions+0x1172/0x1770 [target_core_user]
+ ? queue_tmr_ring+0x5d0/0x5d0 [target_core_user]
+ tcmu_irqcontrol+0x28/0x60 [target_core_user]
+ uio_write+0x155/0x230
+ ? uio_vma_fault+0x460/0x460
+ ? security_file_permission+0x4f/0x440
+ vfs_write+0x1ce/0x860
+ ksys_write+0xe9/0x1b0
+ ? __ia32_sys_read+0xb0/0xb0
+ ? syscall_enter_from_user_mode+0x27/0x70
+ ? trace_hardirqs_on+0x1c/0x110
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x7fcf8b61905f
+Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 b9 fc ff ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 0c fd ff ff 48
+RSP: 002b:00007fcf7b3e6c30 EFLAGS: 00000293 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcf8b61905f
+RDX: 0000000000000004 RSI: 00007fcf7b3e6c78 RDI: 000000000000000c
+RBP: 00007fcf7b3e6c80 R08: 0000000000000000 R09: 00007fcf7b3e6aa8
+R10: 000000000b01c000 R11: 0000000000000293 R12: 00007ffe0c32a52e
+R13: 00007ffe0c32a52f R14: 0000000000000000 R15: 00007fcf7b3e7640
+
+Allocated by task 383:
+ kasan_save_stack+0x1b/0x40
+ ____kasan_kmalloc.constprop.0+0x84/0xa0
+ kmem_cache_alloc+0x142/0x330
+ tcm_loop_queuecommand+0x2a/0x4e0 [tcm_loop]
+ scsi_queue_rq+0x12ec/0x2d20
+ blk_mq_dispatch_rq_list+0x30a/0x1db0
+ __blk_mq_do_dispatch_sched+0x326/0x830
+ __blk_mq_sched_dispatch_requests+0x2c8/0x3f0
+ blk_mq_sched_dispatch_requests+0xca/0x120
+ __blk_mq_run_hw_queue+0x93/0xe0
+ process_one_work+0x7b6/0x1290
+ worker_thread+0x590/0xf80
+ kthread+0x362/0x430
+ ret_from_fork+0x22/0x30
+
+Freed by task 11655:
+ kasan_save_stack+0x1b/0x40
+ kasan_set_track+0x1c/0x30
+ kasan_set_free_info+0x20/0x30
+ ____kasan_slab_free+0xec/0x120
+ slab_free_freelist_hook+0x53/0x160
+ kmem_cache_free+0xf4/0x5c0
+ target_release_cmd_kref+0x3ea/0x9e0 [target_core_mod]
+ transport_generic_free_cmd+0x28b/0x2f0 [target_core_mod]
+ target_complete_ok_work+0x250/0xac0 [target_core_mod]
+ process_one_work+0x7b6/0x1290
+ worker_thread+0x590/0xf80
+ kthread+0x362/0x430
+ ret_from_fork+0x22/0x30
+
+Last potentially related work creation:
+ kasan_save_stack+0x1b/0x40
+ kasan_record_aux_stack+0xa3/0xb0
+ insert_work+0x48/0x2e0
+ __queue_work+0x4e8/0xdf0
+ queue_work_on+0x78/0x80
+ tcmu_handle_completions+0xad0/0x1770 [target_core_user]
+ tcmu_irqcontrol+0x28/0x60 [target_core_user]
+ uio_write+0x155/0x230
+ vfs_write+0x1ce/0x860
+ ksys_write+0xe9/0x1b0
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Second to last potentially related work creation:
+ kasan_save_stack+0x1b/0x40
+ kasan_record_aux_stack+0xa3/0xb0
+ insert_work+0x48/0x2e0
+ __queue_work+0x4e8/0xdf0
+ queue_work_on+0x78/0x80
+ tcm_loop_queuecommand+0x1c3/0x4e0 [tcm_loop]
+ scsi_queue_rq+0x12ec/0x2d20
+ blk_mq_dispatch_rq_list+0x30a/0x1db0
+ __blk_mq_do_dispatch_sched+0x326/0x830
+ __blk_mq_sched_dispatch_requests+0x2c8/0x3f0
+ blk_mq_sched_dispatch_requests+0xca/0x120
+ __blk_mq_run_hw_queue+0x93/0xe0
+ process_one_work+0x7b6/0x1290
+ worker_thread+0x590/0xf80
+ kthread+0x362/0x430
+ ret_from_fork+0x22/0x30
+
+The buggy address belongs to the object at ffff88814cf79800 which belongs
+to the cache tcm_loop_cmd_cache of size 896.
+
+Link: https://lore.kernel.org/r/20210113024508.1264992-1-shinichiro.kawasaki@wdc.com
+Fixes: a35129024e88 ("scsi: target: tcmu: Use priv pointer in se_cmd")
+Cc: stable@vger.kernel.org # v5.9+
+Acked-by: Bodo Stroesser <bostroesser@gmail.com>
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_user.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/target/target_core_user.c
++++ b/drivers/target/target_core_user.c
+@@ -562,8 +562,6 @@ tcmu_get_block_page(struct tcmu_dev *ude
+
+ static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd)
+ {
+- if (tcmu_cmd->se_cmd)
+- tcmu_cmd->se_cmd->priv = NULL;
+ kfree(tcmu_cmd->dbi);
+ kmem_cache_free(tcmu_cmd_cache, tcmu_cmd);
+ }
+@@ -1188,11 +1186,12 @@ tcmu_queue_cmd(struct se_cmd *se_cmd)
+ return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+ mutex_lock(&udev->cmdr_lock);
+- se_cmd->priv = tcmu_cmd;
+ if (!(se_cmd->transport_state & CMD_T_ABORTED))
+ ret = queue_cmd_ring(tcmu_cmd, &scsi_ret);
+ if (ret < 0)
+ tcmu_free_cmd(tcmu_cmd);
++ else
++ se_cmd->priv = tcmu_cmd;
+ mutex_unlock(&udev->cmdr_lock);
+ return scsi_ret;
+ }
+@@ -1255,6 +1254,7 @@ tcmu_tmr_notify(struct se_device *se_dev
+
+ list_del_init(&cmd->queue_entry);
+ tcmu_free_cmd(cmd);
++ se_cmd->priv = NULL;
+ target_complete_cmd(se_cmd, SAM_STAT_TASK_ABORTED);
+ unqueued = true;
+ }
+@@ -1346,6 +1346,7 @@ static void tcmu_handle_completion(struc
+ }
+
+ done:
++ se_cmd->priv = NULL;
+ if (read_len_valid) {
+ pr_debug("read_len = %d\n", read_len);
+ target_complete_cmd_with_length(cmd->se_cmd,
+@@ -1492,6 +1493,7 @@ static void tcmu_check_expired_queue_cmd
+ se_cmd = cmd->se_cmd;
+ tcmu_free_cmd(cmd);
+
++ se_cmd->priv = NULL;
+ target_complete_cmd(se_cmd, SAM_STAT_TASK_SET_FULL);
+ }
+
+@@ -1606,6 +1608,7 @@ static void run_qfull_queue(struct tcmu_
+ * removed then LIO core will do the right thing and
+ * fail the retry.
+ */
++ tcmu_cmd->se_cmd->priv = NULL;
+ target_complete_cmd(tcmu_cmd->se_cmd, SAM_STAT_BUSY);
+ tcmu_free_cmd(tcmu_cmd);
+ continue;
+@@ -1619,6 +1622,7 @@ static void run_qfull_queue(struct tcmu_
+ * Ignore scsi_ret for now. target_complete_cmd
+ * drops it.
+ */
++ tcmu_cmd->se_cmd->priv = NULL;
+ target_complete_cmd(tcmu_cmd->se_cmd,
+ SAM_STAT_CHECK_CONDITION);
+ tcmu_free_cmd(tcmu_cmd);
+@@ -2226,6 +2230,7 @@ static void tcmu_reset_ring(struct tcmu_
+ if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) {
+ WARN_ON(!cmd->se_cmd);
+ list_del_init(&cmd->queue_entry);
++ cmd->se_cmd->priv = NULL;
+ if (err_level == 1) {
+ /*
+ * Userspace was not able to start the