--- /dev/null
+From fa63c0039787b8fbacf4d6a51e3ff44288f5b90b Mon Sep 17 00:00:00 2001
+From: Faiz Abbas <faiz_abbas@ti.com>
+Date: Tue, 28 Jan 2020 19:17:59 +0530
+Subject: arm: dts: dra76x: Fix mmc3 max-frequency
+
+From: Faiz Abbas <faiz_abbas@ti.com>
+
+commit fa63c0039787b8fbacf4d6a51e3ff44288f5b90b upstream.
+
+dra76x is not affected by i887 which requires mmc3 node to be limited to
+a max frequency of 64 MHz. Fix this by overwriting the correct value in
+the the dra76 specific dtsi.
+
+Fixes: 895bd4b3e5ec ("ARM: dts: Add support for dra76-evm")
+Cc: stable@vger.kernel.org
+Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/dra76x.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm/boot/dts/dra76x.dtsi
++++ b/arch/arm/boot/dts/dra76x.dtsi
+@@ -86,3 +86,8 @@
+ &usb4_tm {
+ status = "disabled";
+ };
++
++&mmc3 {
++ /* dra76x is not affected by i887 */
++ max-frequency = <96000000>;
++};
--- /dev/null
+From 8c867387160e89c9ffd12459f38e56844312a7a7 Mon Sep 17 00:00:00 2001
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+Date: Thu, 27 Feb 2020 04:20:14 +0800
+Subject: arm64: dts: socfpga: agilex: Fix gmac compatible
+
+From: Ley Foon Tan <ley.foon.tan@intel.com>
+
+commit 8c867387160e89c9ffd12459f38e56844312a7a7 upstream.
+
+Fix gmac compatible string to "altr,socfpga-stmmac-a10-s10". Gmac for
+Agilex should use same compatible as Stratix 10.
+
+Fixes: 4b36daf9ada3 ("arm64: dts: agilex: Add initial support for Intel's Agilex SoCFPGA")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
+Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
++++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
+@@ -82,7 +82,7 @@
+ ranges = <0 0 0 0xffffffff>;
+
+ gmac0: ethernet@ff800000 {
+- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff800000 0x2000>;
+ interrupts = <0 90 4>;
+ interrupt-names = "macirq";
+@@ -97,7 +97,7 @@
+ };
+
+ gmac1: ethernet@ff802000 {
+- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff802000 0x2000>;
+ interrupts = <0 91 4>;
+ interrupt-names = "macirq";
+@@ -112,7 +112,7 @@
+ };
+
+ gmac2: ethernet@ff804000 {
+- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac";
+ reg = <0xff804000 0x2000>;
+ interrupts = <0 92 4>;
+ interrupt-names = "macirq";
--- /dev/null
+From e7a04894c766daa4248cb736efee93550f2d5872 Mon Sep 17 00:00:00 2001
+From: Omar Sandoval <osandov@fb.com>
+Date: Mon, 2 Mar 2020 14:02:49 -0800
+Subject: btrfs: fix RAID direct I/O reads with alternate csums
+
+From: Omar Sandoval <osandov@fb.com>
+
+commit e7a04894c766daa4248cb736efee93550f2d5872 upstream.
+
+btrfs_lookup_and_bind_dio_csum() does pointer arithmetic which assumes
+32-bit checksums. If using a larger checksum, this leads to spurious
+failures when a direct I/O read crosses a stripe. This is easy
+to reproduce:
+
+ # mkfs.btrfs -f --checksum blake2 -d raid0 /dev/vdc /dev/vdd
+ ...
+ # mount /dev/vdc /mnt
+ # cd /mnt
+ # dd if=/dev/urandom of=foo bs=1M count=1 status=none
+ # dd if=foo of=/dev/null bs=1M iflag=direct status=none
+ dd: error reading 'foo': Input/output error
+ # dmesg | tail -1
+ [ 135.821568] BTRFS warning (device vdc): csum failed root 5 ino 257 off 421888 ...
+
+Fix it by using the actual checksum size.
+
+Fixes: 1e25a2e3ca0d ("btrfs: don't assume ordered sums to be 4 bytes")
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Omar Sandoval <osandov@fb.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/inode.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8426,6 +8426,7 @@ static inline blk_status_t btrfs_lookup_
+ {
+ struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
+ struct btrfs_io_bio *orig_io_bio = btrfs_io_bio(dip->orig_bio);
++ u16 csum_size;
+ blk_status_t ret;
+
+ /*
+@@ -8445,7 +8446,8 @@ static inline blk_status_t btrfs_lookup_
+
+ file_offset -= dip->logical_offset;
+ file_offset >>= inode->i_sb->s_blocksize_bits;
+- io_bio->csum = (u8 *)(((u32 *)orig_io_bio->csum) + file_offset);
++ csum_size = btrfs_super_csum_size(btrfs_sb(inode->i_sb)->super_copy);
++ io_bio->csum = orig_io_bio->csum + csum_size * file_offset;
+
+ return 0;
+ }
--- /dev/null
+From bc87302a093f0eab45cd4e250c2021299f712ec6 Mon Sep 17 00:00:00 2001
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Date: Thu, 5 Mar 2020 22:28:36 -0800
+Subject: fat: fix uninit-memory access for partial initialized inode
+
+From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+
+commit bc87302a093f0eab45cd4e250c2021299f712ec6 upstream.
+
+When get an error in the middle of reading an inode, some fields in the
+inode might be still not initialized. And then the evict_inode path may
+access those fields via iput().
+
+To fix, this makes sure that inode fields are initialized.
+
+Reported-by: syzbot+9d82b8de2992579da5d0@syzkaller.appspotmail.com
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
+Cc: <stable@vger.kernel.org>
+Link: http://lkml.kernel.org/r/871rqnreqx.fsf@mail.parknet.co.jp
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fat/inode.c | 19 +++++++------------
+ 1 file changed, 7 insertions(+), 12 deletions(-)
+
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -749,6 +749,13 @@ static struct inode *fat_alloc_inode(str
+ return NULL;
+
+ init_rwsem(&ei->truncate_lock);
++ /* Zeroing to allow iput() even if partial initialized inode. */
++ ei->mmu_private = 0;
++ ei->i_start = 0;
++ ei->i_logstart = 0;
++ ei->i_attrs = 0;
++ ei->i_pos = 0;
++
+ return &ei->vfs_inode;
+ }
+
+@@ -1373,16 +1380,6 @@ out:
+ return 0;
+ }
+
+-static void fat_dummy_inode_init(struct inode *inode)
+-{
+- /* Initialize this dummy inode to work as no-op. */
+- MSDOS_I(inode)->mmu_private = 0;
+- MSDOS_I(inode)->i_start = 0;
+- MSDOS_I(inode)->i_logstart = 0;
+- MSDOS_I(inode)->i_attrs = 0;
+- MSDOS_I(inode)->i_pos = 0;
+-}
+-
+ static int fat_read_root(struct inode *inode)
+ {
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+@@ -1843,13 +1840,11 @@ int fat_fill_super(struct super_block *s
+ fat_inode = new_inode(sb);
+ if (!fat_inode)
+ goto out_fail;
+- fat_dummy_inode_init(fat_inode);
+ sbi->fat_inode = fat_inode;
+
+ fsinfo_inode = new_inode(sb);
+ if (!fsinfo_inode)
+ goto out_fail;
+- fat_dummy_inode_init(fsinfo_inode);
+ fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
+ sbi->fsinfo_inode = fsinfo_inode;
+ insert_inode_hash(fsinfo_inode);
--- /dev/null
+From 6d390e4b5d48ec03bb87e63cf0a2bff5f4e116da Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Wed, 4 Mar 2020 15:25:56 +0800
+Subject: locks: fix a potential use-after-free problem when wakeup a waiter
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: yangerkun <yangerkun@huawei.com>
+
+commit 6d390e4b5d48ec03bb87e63cf0a2bff5f4e116da upstream.
+
+'16306a61d3b7 ("fs/locks: always delete_block after waiting.")' add the
+logic to check waiter->fl_blocker without blocked_lock_lock. And it will
+trigger a UAF when we try to wakeup some waiter:
+
+Thread 1 has create a write flock a on file, and now thread 2 try to
+unlock and delete flock a, thread 3 try to add flock b on the same file.
+
+Thread2 Thread3
+ flock syscall(create flock b)
+ ...flock_lock_inode_wait
+ flock_lock_inode(will insert
+ our fl_blocked_member list
+ to flock a's fl_blocked_requests)
+ sleep
+flock syscall(unlock)
+...flock_lock_inode_wait
+ locks_delete_lock_ctx
+ ...__locks_wake_up_blocks
+ __locks_delete_blocks(
+ b->fl_blocker = NULL)
+ ...
+ break by a signal
+ locks_delete_block
+ b->fl_blocker == NULL &&
+ list_empty(&b->fl_blocked_requests)
+ success, return directly
+ locks_free_lock b
+ wake_up(&b->fl_waiter)
+ trigger UAF
+
+Fix it by remove this logic, and this patch may also fix CVE-2019-19769.
+
+Cc: stable@vger.kernel.org
+Fixes: 16306a61d3b7 ("fs/locks: always delete_block after waiting.")
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/locks.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -753,20 +753,6 @@ int locks_delete_block(struct file_lock
+ {
+ int status = -ENOENT;
+
+- /*
+- * If fl_blocker is NULL, it won't be set again as this thread
+- * "owns" the lock and is the only one that might try to claim
+- * the lock. So it is safe to test fl_blocker locklessly.
+- * Also if fl_blocker is NULL, this waiter is not listed on
+- * fl_blocked_requests for some lock, so no other request can
+- * be added to the list of fl_blocked_requests for this
+- * request. So if fl_blocker is NULL, it is safe to
+- * locklessly check if fl_blocked_requests is empty. If both
+- * of these checks succeed, there is no need to take the lock.
+- */
+- if (waiter->fl_blocker == NULL &&
+- list_empty(&waiter->fl_blocked_requests))
+- return status;
+ spin_lock(&blocked_lock_lock);
+ if (waiter->fl_blocker)
+ status = 0;
--- /dev/null
+From 8a8683ad9ba48b4b52a57f013513d1635c1ca5c4 Mon Sep 17 00:00:00 2001
+From: Huang Ying <ying.huang@intel.com>
+Date: Thu, 5 Mar 2020 22:28:29 -0800
+Subject: mm: fix possible PMD dirty bit lost in set_pmd_migration_entry()
+
+From: Huang Ying <ying.huang@intel.com>
+
+commit 8a8683ad9ba48b4b52a57f013513d1635c1ca5c4 upstream.
+
+In set_pmd_migration_entry(), pmdp_invalidate() is used to change PMD
+atomically. But the PMD is read before that with an ordinary memory
+reading. If the THP (transparent huge page) is written between the PMD
+reading and pmdp_invalidate(), the PMD dirty bit may be lost, and cause
+data corruption. The race window is quite small, but still possible in
+theory, so need to be fixed.
+
+The race is fixed via using the return value of pmdp_invalidate() to get
+the original content of PMD, which is a read/modify/write atomic
+operation. So no THP writing can occur in between.
+
+The race has been introduced when the THP migration support is added in
+the commit 616b8371539a ("mm: thp: enable thp migration in generic path").
+But this fix depends on the commit d52605d7cb30 ("mm: do not lose dirty
+and accessed bits in pmdp_invalidate()"). So it's easy to be backported
+after v4.16. But the race window is really small, so it may be fine not
+to backport the fix at all.
+
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
+Reviewed-by: Zi Yan <ziy@nvidia.com>
+Reviewed-by: William Kucharski <william.kucharski@oracle.com>
+Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: <stable@vger.kernel.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Link: http://lkml.kernel.org/r/20200220075220.2327056-1-ying.huang@intel.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/huge_memory.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -3032,8 +3032,7 @@ void set_pmd_migration_entry(struct page
+ return;
+
+ flush_cache_range(vma, address, address + HPAGE_PMD_SIZE);
+- pmdval = *pvmw->pmd;
+- pmdp_invalidate(vma, address, pvmw->pmd);
++ pmdval = pmdp_invalidate(vma, address, pvmw->pmd);
+ if (pmd_dirty(pmdval))
+ set_page_dirty(page);
+ entry = make_migration_entry(page, pmd_write(pmdval));
--- /dev/null
+From c87cbc1f007c4b46165f05ceca04e1973cda0b9c Mon Sep 17 00:00:00 2001
+From: Vlastimil Babka <vbabka@suse.cz>
+Date: Thu, 5 Mar 2020 22:28:42 -0800
+Subject: mm, hotplug: fix page online with DEBUG_PAGEALLOC compiled but not enabled
+
+From: Vlastimil Babka <vbabka@suse.cz>
+
+commit c87cbc1f007c4b46165f05ceca04e1973cda0b9c upstream.
+
+Commit cd02cf1aceea ("mm/hotplug: fix an imbalance with DEBUG_PAGEALLOC")
+fixed memory hotplug with debug_pagealloc enabled, where onlining a page
+goes through page freeing, which removes the direct mapping. Some arches
+don't like when the page is not mapped in the first place, so
+generic_online_page() maps it first. This is somewhat wasteful, but
+better than special casing page freeing fast paths.
+
+The commit however missed that DEBUG_PAGEALLOC configured doesn't mean
+it's actually enabled. One has to test debug_pagealloc_enabled() since
+031bc5743f15 ("mm/debug-pagealloc: make debug-pagealloc boottime
+configurable"), or alternatively debug_pagealloc_enabled_static() since
+8e57f8acbbd1 ("mm, debug_pagealloc: don't rely on static keys too early"),
+but this is not done.
+
+As a result, a s390 kernel with DEBUG_PAGEALLOC configured but not enabled
+will crash:
+
+Unable to handle kernel pointer dereference in virtual kernel address space
+Failing address: 0000000000000000 TEID: 0000000000000483
+Fault in home space mode while using kernel ASCE.
+AS:0000001ece13400b R2:000003fff7fd000b R3:000003fff7fcc007 S:000003fff7fd7000 P:000000000000013d
+Oops: 0004 ilc:2 [#1] SMP
+CPU: 1 PID: 26015 Comm: chmem Kdump: loaded Tainted: GX 5.3.18-5-default #1 SLE15-SP2 (unreleased)
+Krnl PSW : 0704e00180000000 0000001ecd281b9e (__kernel_map_pages+0x166/0x188)
+R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
+Krnl GPRS: 0000000000000000 0000000000000800 0000400b00000000 0000000000000100
+0000000000000001 0000000000000000 0000000000000002 0000000000000100
+0000001ece139230 0000001ecdd98d40 0000400b00000100 0000000000000000
+000003ffa17e4000 001fffe0114f7d08 0000001ecd4d93ea 001fffe0114f7b20
+Krnl Code: 0000001ecd281b8e: ec17ffff00d8 ahik %r1,%r7,-1
+0000001ecd281b94: ec111dbc0355 risbg %r1,%r1,29,188,3
+>0000001ecd281b9e: 94fb5006 ni 6(%r5),251
+0000001ecd281ba2: 41505008 la %r5,8(%r5)
+0000001ecd281ba6: ec51fffc6064 cgrj %r5,%r1,6,1ecd281b9e
+0000001ecd281bac: 1a07 ar %r0,%r7
+0000001ecd281bae: ec03ff584076 crj %r0,%r3,4,1ecd281a5e
+Call Trace:
+[<0000001ecd281b9e>] __kernel_map_pages+0x166/0x188
+[<0000001ecd4d9516>] online_pages_range+0xf6/0x128
+[<0000001ecd2a8186>] walk_system_ram_range+0x7e/0xd8
+[<0000001ecda28aae>] online_pages+0x2fe/0x3f0
+[<0000001ecd7d02a6>] memory_subsys_online+0x8e/0xc0
+[<0000001ecd7add42>] device_online+0x5a/0xc8
+[<0000001ecd7d0430>] state_store+0x88/0x118
+[<0000001ecd5b9f62>] kernfs_fop_write+0xc2/0x200
+[<0000001ecd5064b6>] vfs_write+0x176/0x1e0
+[<0000001ecd50676a>] ksys_write+0xa2/0x100
+[<0000001ecda315d4>] system_call+0xd8/0x2c8
+
+Fix this by checking debug_pagealloc_enabled_static() before calling
+kernel_map_pages(). Backports for kernel before 5.5 should use
+debug_pagealloc_enabled() instead. Also add comments.
+
+Fixes: cd02cf1aceea ("mm/hotplug: fix an imbalance with DEBUG_PAGEALLOC")
+Reported-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Cc: <stable@vger.kernel.org>
+Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
+Cc: Qian Cai <cai@lca.pw>
+Link: http://lkml.kernel.org/r/20200224094651.18257-1-vbabka@suse.cz
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/mm.h | 4 ++++
+ mm/memory_hotplug.c | 8 +++++++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2695,6 +2695,10 @@ static inline bool debug_pagealloc_enabl
+ #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP)
+ extern void __kernel_map_pages(struct page *page, int numpages, int enable);
+
++/*
++ * When called in DEBUG_PAGEALLOC context, the call should most likely be
++ * guarded by debug_pagealloc_enabled() or debug_pagealloc_enabled_static()
++ */
+ static inline void
+ kernel_map_pages(struct page *page, int numpages, int enable)
+ {
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -598,7 +598,13 @@ EXPORT_SYMBOL_GPL(__online_page_free);
+
+ static void generic_online_page(struct page *page, unsigned int order)
+ {
+- kernel_map_pages(page, 1 << order, 1);
++ /*
++ * Freeing the page with debug_pagealloc enabled will try to unmap it,
++ * so we should map it first. This is better than introducing a special
++ * case in page freeing fast path.
++ */
++ if (debug_pagealloc_enabled_static())
++ kernel_map_pages(page, 1 << order, 1);
+ __free_pages_core(page, order);
+ totalram_pages_add(1UL << order);
+ #ifdef CONFIG_HIGHMEM
--- /dev/null
+From 8b272b3cbbb50a6a8e62d8a15affd473a788e184 Mon Sep 17 00:00:00 2001
+From: Mel Gorman <mgorman@techsingularity.net>
+Date: Thu, 5 Mar 2020 22:28:26 -0800
+Subject: mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking page tables prot_numa
+
+From: Mel Gorman <mgorman@techsingularity.net>
+
+commit 8b272b3cbbb50a6a8e62d8a15affd473a788e184 upstream.
+
+: A user reported a bug against a distribution kernel while running a
+: proprietary workload described as "memory intensive that is not swapping"
+: that is expected to apply to mainline kernels. The workload is
+: read/write/modifying ranges of memory and checking the contents. They
+: reported that within a few hours that a bad PMD would be reported followed
+: by a memory corruption where expected data was all zeros. A partial
+: report of the bad PMD looked like
+:
+: [ 5195.338482] ../mm/pgtable-generic.c:33: bad pmd ffff8888157ba008(000002e0396009e2)
+: [ 5195.341184] ------------[ cut here ]------------
+: [ 5195.356880] kernel BUG at ../mm/pgtable-generic.c:35!
+: ....
+: [ 5195.410033] Call Trace:
+: [ 5195.410471] [<ffffffff811bc75d>] change_protection_range+0x7dd/0x930
+: [ 5195.410716] [<ffffffff811d4be8>] change_prot_numa+0x18/0x30
+: [ 5195.410918] [<ffffffff810adefe>] task_numa_work+0x1fe/0x310
+: [ 5195.411200] [<ffffffff81098322>] task_work_run+0x72/0x90
+: [ 5195.411246] [<ffffffff81077139>] exit_to_usermode_loop+0x91/0xc2
+: [ 5195.411494] [<ffffffff81003a51>] prepare_exit_to_usermode+0x31/0x40
+: [ 5195.411739] [<ffffffff815e56af>] retint_user+0x8/0x10
+:
+: Decoding revealed that the PMD was a valid prot_numa PMD and the bad PMD
+: was a false detection. The bug does not trigger if automatic NUMA
+: balancing or transparent huge pages is disabled.
+:
+: The bug is due a race in change_pmd_range between a pmd_trans_huge and
+: pmd_nond_or_clear_bad check without any locks held. During the
+: pmd_trans_huge check, a parallel protection update under lock can have
+: cleared the PMD and filled it with a prot_numa entry between the transhuge
+: check and the pmd_none_or_clear_bad check.
+:
+: While this could be fixed with heavy locking, it's only necessary to make
+: a copy of the PMD on the stack during change_pmd_range and avoid races. A
+: new helper is created for this as the check if quite subtle and the
+: existing similar helpful is not suitable. This passed 154 hours of
+: testing (usually triggers between 20 minutes and 24 hours) without
+: detecting bad PMDs or corruption. A basic test of an autonuma-intensive
+: workload showed no significant change in behaviour.
+
+Although Mel withdrew the patch on the face of LKML comment
+https://lkml.org/lkml/2017/4/10/922 the race window aforementioned is
+still open, and we have reports of Linpack test reporting bad residuals
+after the bad PMD warning is observed. In addition to that, bad
+rss-counter and non-zero pgtables assertions are triggered on mm teardown
+for the task hitting the bad PMD.
+
+ host kernel: mm/pgtable-generic.c:40: bad pmd 00000000b3152f68(8000000d2d2008e7)
+ ....
+ host kernel: BUG: Bad rss-counter state mm:00000000b583043d idx:1 val:512
+ host kernel: BUG: non-zero pgtables_bytes on freeing mm: 4096
+
+The issue is observed on a v4.18-based distribution kernel, but the race
+window is expected to be applicable to mainline kernels, as well.
+
+[akpm@linux-foundation.org: fix comment typo, per Rafael]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Rafael Aquini <aquini@redhat.com>
+Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
+Cc: <stable@vger.kernel.org>
+Cc: Zi Yan <zi.yan@cs.rutgers.edu>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Cc: Michal Hocko <mhocko@suse.com>
+Link: http://lkml.kernel.org/r/20200216191800.22423-1-aquini@redhat.com
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/mprotect.c | 38 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 36 insertions(+), 2 deletions(-)
+
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -161,6 +161,31 @@ static unsigned long change_pte_range(st
+ return pages;
+ }
+
++/*
++ * Used when setting automatic NUMA hinting protection where it is
++ * critical that a numa hinting PMD is not confused with a bad PMD.
++ */
++static inline int pmd_none_or_clear_bad_unless_trans_huge(pmd_t *pmd)
++{
++ pmd_t pmdval = pmd_read_atomic(pmd);
++
++ /* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++ barrier();
++#endif
++
++ if (pmd_none(pmdval))
++ return 1;
++ if (pmd_trans_huge(pmdval))
++ return 0;
++ if (unlikely(pmd_bad(pmdval))) {
++ pmd_clear_bad(pmd);
++ return 1;
++ }
++
++ return 0;
++}
++
+ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
+ pud_t *pud, unsigned long addr, unsigned long end,
+ pgprot_t newprot, int dirty_accountable, int prot_numa)
+@@ -178,8 +203,17 @@ static inline unsigned long change_pmd_r
+ unsigned long this_pages;
+
+ next = pmd_addr_end(addr, end);
+- if (!is_swap_pmd(*pmd) && !pmd_trans_huge(*pmd) && !pmd_devmap(*pmd)
+- && pmd_none_or_clear_bad(pmd))
++
++ /*
++ * Automatic NUMA balancing walks the tables with mmap_sem
++ * held for read. It's possible a parallel update to occur
++ * between pmd_trans_huge() and a pmd_none_or_clear_bad()
++ * check leading to a false positive and clearing.
++ * Hence, it's necessary to atomically read the PMD value
++ * for all the checks.
++ */
++ if (!is_swap_pmd(*pmd) && !pmd_devmap(*pmd) &&
++ pmd_none_or_clear_bad_unless_trans_huge(pmd))
+ goto next;
+
+ /* invoke the mmu notifier if the pmd is populated */
--- /dev/null
+From 7589238a8cf37331607c3222a64ac3140b29532d Mon Sep 17 00:00:00 2001
+From: Brendan Higgins <brendanhiggins@google.com>
+Date: Thu, 27 Feb 2020 16:00:01 -0800
+Subject: Revert "software node: Simplify software_node_release() function"
+
+From: Brendan Higgins <brendanhiggins@google.com>
+
+commit 7589238a8cf37331607c3222a64ac3140b29532d upstream.
+
+This reverts commit 3df85a1ae51f6b256982fe9d17c2dc5bfb4cc402.
+
+The reverted commit says "It's possible to release the node ID
+immediately when fwnode_remove_software_node() is called, no need to
+wait for software_node_release() with that." However, releasing the node
+ID before waiting for software_node_release() to be called causes the
+node ID to be released before the kobject and the underlying sysfs
+entry; this means there is a period of time where a sysfs entry exists
+that is associated with an unallocated node ID.
+
+Once consequence of this is that there is a race condition where it is
+possible to call fwnode_create_software_node() with no parent node
+specified (NULL) and have it fail with -EEXIST because the node ID that
+was assigned is still associated with a stale sysfs entry that hasn't
+been cleaned up yet.
+
+Although it is difficult to reproduce this race condition under normal
+conditions, it can be deterministically reproduced with the following
+minconfig on UML:
+
+CONFIG_KUNIT_DRIVER_PE_TEST=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_KOBJECT_RELEASE=y
+CONFIG_KUNIT=y
+
+Running the tests with this configuration causes the following failure:
+
+<snip>
+kobject: 'node0' ((____ptrval____)): kobject_release, parent (____ptrval____) (delayed 400)
+ ok 1 - pe_test_uints
+sysfs: cannot create duplicate filename '/kernel/software_nodes/node0'
+CPU: 0 PID: 28 Comm: kunit_try_catch Not tainted 5.6.0-rc3-next-20200227 #14
+<snip>
+kobject_add_internal failed for node0 with -EEXIST, don't try to register things with the same name in the same directory.
+kobject: 'node0' ((____ptrval____)): kobject_release, parent (____ptrval____) (delayed 100)
+ # pe_test_uint_arrays: ASSERTION FAILED at drivers/base/test/property-entry-test.c:123
+ Expected node is not error, but is: -17
+ not ok 2 - pe_test_uint_arrays
+<snip>
+
+Reported-by: Heidi Fahim <heidifahim@google.com>
+Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Cc: 5.3+ <stable@vger.kernel.org> # 5.3+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/swnode.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/base/swnode.c
++++ b/drivers/base/swnode.c
+@@ -679,6 +679,13 @@ static void software_node_release(struct
+ {
+ struct swnode *swnode = kobj_to_swnode(kobj);
+
++ if (swnode->parent) {
++ ida_simple_remove(&swnode->parent->child_ids, swnode->id);
++ list_del(&swnode->entry);
++ } else {
++ ida_simple_remove(&swnode_root_ids, swnode->id);
++ }
++
+ if (swnode->allocated) {
+ property_entries_free(swnode->node->properties);
+ kfree(swnode->node);
+@@ -844,13 +851,6 @@ void fwnode_remove_software_node(struct
+ if (!swnode)
+ return;
+
+- if (swnode->parent) {
+- ida_simple_remove(&swnode->parent->child_ids, swnode->id);
+- list_del(&swnode->entry);
+- } else {
+- ida_simple_remove(&swnode_root_ids, swnode->id);
+- }
+-
+ kobject_put(&swnode->kobj);
+ }
+ EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
--- /dev/null
+From 10c5ccc3c6d32f3d7d6c07de1d3f0f4b52f3e3ab Mon Sep 17 00:00:00 2001
+From: Jay Dolan <jay.dolan@accesio.com>
+Date: Thu, 5 Mar 2020 06:05:04 -0800
+Subject: serial: 8250_exar: add support for ACCES cards
+
+From: Jay Dolan <jay.dolan@accesio.com>
+
+commit 10c5ccc3c6d32f3d7d6c07de1d3f0f4b52f3e3ab upstream.
+
+Add ACCES VIDs and PIDs that use the Exar chips
+
+Signed-off-by: Jay Dolan <jay.dolan@accesio.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200305140504.22237-1-jay.dolan@accesio.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_exar.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -25,6 +25,14 @@
+
+ #include "8250.h"
+
++#define PCI_DEVICE_ID_ACCES_COM_2S 0x1052
++#define PCI_DEVICE_ID_ACCES_COM_4S 0x105d
++#define PCI_DEVICE_ID_ACCES_COM_8S 0x106c
++#define PCI_DEVICE_ID_ACCES_COM232_8 0x10a8
++#define PCI_DEVICE_ID_ACCES_COM_2SM 0x10d2
++#define PCI_DEVICE_ID_ACCES_COM_4SM 0x10db
++#define PCI_DEVICE_ID_ACCES_COM_8SM 0x10ea
++
+ #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002
+ #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004
+ #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a
+@@ -658,6 +666,22 @@ static int __maybe_unused exar_resume(st
+
+ static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
+
++static const struct exar8250_board acces_com_2x = {
++ .num_ports = 2,
++ .setup = pci_xr17c154_setup,
++};
++
++static const struct exar8250_board acces_com_4x = {
++ .num_ports = 4,
++ .setup = pci_xr17c154_setup,
++};
++
++static const struct exar8250_board acces_com_8x = {
++ .num_ports = 8,
++ .setup = pci_xr17c154_setup,
++};
++
++
+ static const struct exar8250_board pbn_fastcom335_2 = {
+ .num_ports = 2,
+ .setup = pci_fastcom335_setup,
+@@ -726,6 +750,15 @@ static const struct exar8250_board pbn_e
+ }
+
+ static const struct pci_device_id exar_pci_tbl[] = {
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2S, acces_com_2x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4S, acces_com_4x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8S, acces_com_8x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM232_8, acces_com_8x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2SM, acces_com_2x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4SM, acces_com_4x),
++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8SM, acces_com_8x),
++
++
+ CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
+ CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
+ CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect),
alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch
cifs-don-t-leak-eagain-for-stat-during-reconnect.patch
cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch
+usb-storage-add-quirk-for-samsung-fit-flash.patch
+usb-quirks-add-no_lpm-quirk-for-logitech-screen-share.patch
+usb-dwc3-gadget-update-chain-bit-correctly-when-using-sg-list.patch
+usb-cdns3-gadget-link-trb-should-point-to-next-request.patch
+usb-cdns3-gadget-toggle-cycle-bit-before-reset-endpoint.patch
+usb-core-hub-fix-unhandled-return-by-employing-a-void-function.patch
+usb-core-hub-do-error-out-if-usb_autopm_get_interface-fails.patch
+usb-core-port-do-error-out-if-usb_autopm_get_interface-fails.patch
+vgacon-fix-a-uaf-in-vgacon_invert_region.patch
+locks-fix-a-potential-use-after-free-problem-when-wakeup-a-waiter.patch
+mm-numa-fix-bad-pmd-by-atomically-check-for-pmd_trans_huge-when-marking-page-tables-prot_numa.patch
+mm-fix-possible-pmd-dirty-bit-lost-in-set_pmd_migration_entry.patch
+mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch
+fat-fix-uninit-memory-access-for-partial-initialized-inode.patch
+revert-software-node-simplify-software_node_release-function.patch
+btrfs-fix-raid-direct-i-o-reads-with-alternate-csums.patch
+arm64-dts-socfpga-agilex-fix-gmac-compatible.patch
+arm-dts-dra76x-fix-mmc3-max-frequency.patch
+tty-serial-mvebu-uart-fix-a-wrong-return.patch
+tty-serial-fsl_lpuart-free-ids-allocated-by-ida.patch
+serial-8250_exar-add-support-for-acces-cards.patch
+vt-selection-close-sel_buffer-race.patch
+vt-selection-push-console-lock-down.patch
--- /dev/null
+From 2b2e71fe657510a6f71aa16ef0309fa6bc20ab3d Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Tue, 3 Mar 2020 18:42:59 +0100
+Subject: tty: serial: fsl_lpuart: free IDs allocated by IDA
+
+From: Michael Walle <michael@walle.cc>
+
+commit 2b2e71fe657510a6f71aa16ef0309fa6bc20ab3d upstream.
+
+Since commit 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node
+dependence") the port line number can also be allocated by IDA, but in
+case of an error the ID will no be removed again. More importantly, any
+ID will be freed in remove(), even if it wasn't allocated but instead
+fetched by of_alias_get_id(). If it was not allocated by IDA there will
+be a warning:
+ WARN(1, "ida_free called for id=%d which is not allocated.\n", id);
+
+Move the ID allocation more to the end of the probe() so that we still
+can use plain return in the first error cases.
+
+Fixes: 3bc3206e1c0f ("serial: fsl_lpuart: Remove the alias node dependence")
+Signed-off-by: Michael Walle <michael@walle.cc>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200303174306.6015-3-michael@walle.cc
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/fsl_lpuart.c | 39 ++++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -268,6 +268,7 @@ struct lpuart_port {
+ int rx_dma_rng_buf_len;
+ unsigned int dma_tx_nents;
+ wait_queue_head_t dma_wait;
++ bool id_allocated;
+ };
+
+ struct lpuart_soc_data {
+@@ -2382,19 +2383,6 @@ static int lpuart_probe(struct platform_
+ if (!sport)
+ return -ENOMEM;
+
+- ret = of_alias_get_id(np, "serial");
+- if (ret < 0) {
+- ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
+- if (ret < 0) {
+- dev_err(&pdev->dev, "port line is full, add device failed\n");
+- return ret;
+- }
+- }
+- if (ret >= ARRAY_SIZE(lpuart_ports)) {
+- dev_err(&pdev->dev, "serial%d out of range\n", ret);
+- return -EINVAL;
+- }
+- sport->port.line = ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ sport->port.membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(sport->port.membase))
+@@ -2435,9 +2423,25 @@ static int lpuart_probe(struct platform_
+ }
+ }
+
++ ret = of_alias_get_id(np, "serial");
++ if (ret < 0) {
++ ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "port line is full, add device failed\n");
++ return ret;
++ }
++ sport->id_allocated = true;
++ }
++ if (ret >= ARRAY_SIZE(lpuart_ports)) {
++ dev_err(&pdev->dev, "serial%d out of range\n", ret);
++ ret = -EINVAL;
++ goto failed_out_of_range;
++ }
++ sport->port.line = ret;
++
+ ret = lpuart_enable_clks(sport);
+ if (ret)
+- return ret;
++ goto failed_clock_enable;
+ sport->port.uartclk = lpuart_get_baud_clk_rate(sport);
+
+ lpuart_ports[sport->port.line] = sport;
+@@ -2487,6 +2491,10 @@ static int lpuart_probe(struct platform_
+ failed_attach_port:
+ failed_irq_request:
+ lpuart_disable_clks(sport);
++failed_clock_enable:
++failed_out_of_range:
++ if (sport->id_allocated)
++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
+ return ret;
+ }
+
+@@ -2496,7 +2504,8 @@ static int lpuart_remove(struct platform
+
+ uart_remove_one_port(&lpuart_reg, &sport->port);
+
+- ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
++ if (sport->id_allocated)
++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
+
+ lpuart_disable_clks(sport);
+
--- /dev/null
+From 4a3e208474204e879d22a310b244cb2f39e5b1f8 Mon Sep 17 00:00:00 2001
+From: tangbin <tangbin@cmss.chinamobile.com>
+Date: Thu, 5 Mar 2020 09:38:23 +0800
+Subject: tty:serial:mvebu-uart:fix a wrong return
+
+From: tangbin <tangbin@cmss.chinamobile.com>
+
+commit 4a3e208474204e879d22a310b244cb2f39e5b1f8 upstream.
+
+in this place, the function should return a
+negative value and the PTR_ERR already returns
+a negative,so return -PTR_ERR() is wrong.
+
+Signed-off-by: tangbin <tangbin@cmss.chinamobile.com>
+Cc: stable <stable@vger.kernel.org>
+Acked-by: Jiri Slaby <jslaby@suse.cz>
+Link: https://lore.kernel.org/r/20200305013823.20976-1-tangbin@cmss.chinamobile.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/mvebu-uart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/mvebu-uart.c
++++ b/drivers/tty/serial/mvebu-uart.c
+@@ -851,7 +851,7 @@ static int mvebu_uart_probe(struct platf
+
+ port->membase = devm_ioremap_resource(&pdev->dev, reg);
+ if (IS_ERR(port->membase))
+- return -PTR_ERR(port->membase);
++ return PTR_ERR(port->membase);
+
+ mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart),
+ GFP_KERNEL);
--- /dev/null
+From 8a7c47fb7285b23ca259c888016513d5566fa9e8 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Wed, 19 Feb 2020 22:14:54 +0800
+Subject: usb: cdns3: gadget: link trb should point to next request
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit 8a7c47fb7285b23ca259c888016513d5566fa9e8 upstream.
+
+It has marked the dequeue trb as link trb, but its next segment
+pointer is still itself, it causes the transfer can't go on. Fix
+it by set its pointer as the trb address for the next request.
+
+Fixes: f616c3bda47e ("usb: cdns3: Fix dequeue implementation")
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200219141455.23257-2-peter.chen@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/cdns3/gadget.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2107,7 +2107,7 @@ found:
+ /* Update ring only if removed request is on pending_req_list list */
+ if (req_on_hw_ring) {
+ link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma +
+- (priv_req->start_trb * TRB_SIZE));
++ ((priv_req->end_trb + 1) * TRB_SIZE));
+ link_trb->control = (link_trb->control & TRB_CYCLE) |
+ TRB_TYPE(TRB_LINK) | TRB_CHAIN;
+
--- /dev/null
+From 4bf2dd65135a2d7fe202f7c10d65b51bcf645ac6 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Wed, 19 Feb 2020 22:14:55 +0800
+Subject: usb: cdns3: gadget: toggle cycle bit before reset endpoint
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit 4bf2dd65135a2d7fe202f7c10d65b51bcf645ac6 upstream.
+
+If there are TRBs pending during reset endpoint operation, the
+DMA will advance after reset operation, but it isn't expected,
+since the data is not yet available (For OUT, the data is not
+yet available). After the data is ready, there won't be any
+interrupt since the EP_TRADDR already points to next TRB entry
+and doorbell is not set.
+
+To fix it, it toggles cycle bit before reset operation, and restores
+it after reset, it could avoid unexpected DMA advance due to
+cycle bit is for software during the endpoint reset operation.
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200219141455.23257-3-peter.chen@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/cdns3/gadget.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2152,11 +2152,21 @@ int __cdns3_gadget_ep_clear_halt(struct
+ {
+ struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
+ struct usb_request *request;
++ struct cdns3_request *priv_req;
++ struct cdns3_trb *trb = NULL;
+ int ret;
+ int val;
+
+ trace_cdns3_halt(priv_ep, 0, 0);
+
++ request = cdns3_next_request(&priv_ep->pending_req_list);
++ if (request) {
++ priv_req = to_cdns3_request(request);
++ trb = priv_req->trb;
++ if (trb)
++ trb->control = trb->control ^ TRB_CYCLE;
++ }
++
+ writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
+
+ /* wait for EPRST cleared */
+@@ -2167,10 +2177,11 @@ int __cdns3_gadget_ep_clear_halt(struct
+
+ priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING);
+
+- request = cdns3_next_request(&priv_ep->pending_req_list);
+-
+- if (request)
++ if (request) {
++ if (trb)
++ trb->control = trb->control ^ TRB_CYCLE;
+ cdns3_rearm_transfer(priv_ep, 1);
++ }
+
+ cdns3_start_all_request(priv_dev, priv_ep);
+ return ret;
--- /dev/null
+From 60e3f6e4ac5b0fda43dad01c32e09409ec710045 Mon Sep 17 00:00:00 2001
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+Date: Wed, 26 Feb 2020 18:50:35 +0100
+Subject: usb: core: hub: do error out if usb_autopm_get_interface() fails
+
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+
+commit 60e3f6e4ac5b0fda43dad01c32e09409ec710045 upstream.
+
+Reviewing a fresh portion of coverity defects in USB core
+(specifically CID 1458999), Alan Stern noted below in [1]:
+
+On Tue, Feb 25, 2020 at 02:39:23PM -0500, Alan Stern wrote:
+ > A revised search finds line 997 in drivers/usb/core/hub.c and lines
+ > 216, 269 in drivers/usb/core/port.c. (I didn't try looking in any
+ > other directories.) AFAICT all three of these should check the
+ > return value, although a error message in the kernel log probably
+ > isn't needed.
+
+Factor out the usb_remove_device() change into a standalone patch to
+allow conflict-free integration on top of the earliest stable branches.
+
+[1] https://lore.kernel.org/lkml/Pine.LNX.4.44L0.2002251419120.1485-100000@iolanthe.rowland.org
+
+Fixes: 253e05724f9230 ("USB: add a "remove hardware" sysfs attribute")
+Cc: stable@vger.kernel.org # v2.6.33+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200226175036.14946-2-erosca@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -987,13 +987,17 @@ int usb_remove_device(struct usb_device
+ {
+ struct usb_hub *hub;
+ struct usb_interface *intf;
++ int ret;
+
+ if (!udev->parent) /* Can't remove a root hub */
+ return -EINVAL;
+ hub = usb_hub_to_struct_hub(udev->parent);
+ intf = to_usb_interface(hub->intfdev);
+
+- usb_autopm_get_interface(intf);
++ ret = usb_autopm_get_interface(intf);
++ if (ret < 0)
++ return ret;
++
+ set_bit(udev->portnum, hub->removed_bits);
+ hub_port_logical_disconnect(hub, udev->portnum);
+ usb_autopm_put_interface(intf);
--- /dev/null
+From 63d6d7ed475c53dc1cabdfedf63de1fd8dcd72ee Mon Sep 17 00:00:00 2001
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+Date: Wed, 26 Feb 2020 18:50:34 +0100
+Subject: usb: core: hub: fix unhandled return by employing a void function
+
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+
+commit 63d6d7ed475c53dc1cabdfedf63de1fd8dcd72ee upstream.
+
+Address below Coverity complaint (Feb 25, 2020, 8:06 AM CET):
+
+---
+ drivers/usb/core/hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1865,7 +1865,7 @@ static int hub_probe(struct usb_interfac
+
+ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) {
+ hub->quirk_disable_autosuspend = 1;
+- usb_autopm_get_interface(intf);
++ usb_autopm_get_interface_no_resume(intf);
+ }
+
+ if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
--- /dev/null
+From 1f8b39bc99a31759e97a0428a5c3f64802c1e61d Mon Sep 17 00:00:00 2001
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+Date: Wed, 26 Feb 2020 18:50:36 +0100
+Subject: usb: core: port: do error out if usb_autopm_get_interface() fails
+
+From: Eugeniu Rosca <erosca@de.adit-jv.com>
+
+commit 1f8b39bc99a31759e97a0428a5c3f64802c1e61d upstream.
+
+Reviewing a fresh portion of coverity defects in USB core
+(specifically CID 1458999), Alan Stern noted below in [1]:
+
+On Tue, Feb 25, 2020 at 02:39:23PM -0500, Alan Stern wrote:
+ > A revised search finds line 997 in drivers/usb/core/hub.c and lines
+ > 216, 269 in drivers/usb/core/port.c. (I didn't try looking in any
+ > other directories.) AFAICT all three of these should check the
+ > return value, although a error message in the kernel log probably
+ > isn't needed.
+
+Factor out the usb_port_runtime_{resume,suspend}() changes into a
+standalone patch to allow conflict-free porting on top of stable v3.9+.
+
+[1] https://lore.kernel.org/lkml/Pine.LNX.4.44L0.2002251419120.1485-100000@iolanthe.rowland.org
+
+Fixes: 971fcd492cebf5 ("usb: add runtime pm support for usb port device")
+Cc: stable@vger.kernel.org # v3.9+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200226175036.14946-3-erosca@de.adit-jv.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/port.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/port.c
++++ b/drivers/usb/core/port.c
+@@ -213,7 +213,10 @@ static int usb_port_runtime_resume(struc
+ if (!port_dev->is_superspeed && peer)
+ pm_runtime_get_sync(&peer->dev);
+
+- usb_autopm_get_interface(intf);
++ retval = usb_autopm_get_interface(intf);
++ if (retval < 0)
++ return retval;
++
+ retval = usb_hub_set_port_power(hdev, hub, port1, true);
+ msleep(hub_power_on_good_delay(hub));
+ if (udev && !retval) {
+@@ -266,7 +269,10 @@ static int usb_port_runtime_suspend(stru
+ if (usb_port_block_power_off)
+ return -EBUSY;
+
+- usb_autopm_get_interface(intf);
++ retval = usb_autopm_get_interface(intf);
++ if (retval < 0)
++ return retval;
++
+ retval = usb_hub_set_port_power(hdev, hub, port1, false);
+ usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
+ if (!port_dev->is_superspeed)
--- /dev/null
+From dad2aff3e827b112f27fa5e6f2bf87a110067c3f Mon Sep 17 00:00:00 2001
+From: Pratham Pratap <prathampratap@codeaurora.org>
+Date: Mon, 2 Mar 2020 21:44:43 +0000
+Subject: usb: dwc3: gadget: Update chain bit correctly when using sg list
+
+From: Pratham Pratap <prathampratap@codeaurora.org>
+
+commit dad2aff3e827b112f27fa5e6f2bf87a110067c3f upstream.
+
+If scatter-gather operation is allowed, a large USB request is split
+into multiple TRBs. For preparing TRBs for sg list, driver iterates
+over the list and creates TRB for each sg and mark the chain bit to
+false for the last sg. The current IOMMU driver is clubbing the list
+of sgs which shares a page boundary into one and giving it to USB driver.
+With this the number of sgs mapped it not equal to the the number of sgs
+passed. Because of this USB driver is not marking the chain bit to false
+since it couldn't iterate to the last sg. This patch addresses this issue
+by marking the chain bit to false if it is the last mapped sg.
+
+At a practical level, this patch resolves USB transfer stalls
+seen with adb on dwc3 based db845c, pixel3 and other qcom
+hardware after functionfs gadget added scatter-gather support
+around v4.20.
+
+Credit also to Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
+who implemented a very similar fix to this issue.
+
+Cc: Felipe Balbi <balbi@kernel.org>
+Cc: Yang Fei <fei.yang@intel.com>
+Cc: Thinh Nguyen <thinhn@synopsys.com>
+Cc: Tejas Joglekar <tejas.joglekar@synopsys.com>
+Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Cc: Jack Pham <jackp@codeaurora.org>
+Cc: Todd Kjos <tkjos@google.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Linux USB List <linux-usb@vger.kernel.org>
+Cc: stable <stable@vger.kernel.org> #4.20+
+Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
+[jstultz: Slight tweak to remove sg_is_last() usage, reworked
+ commit message, minor comment tweak]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Link: https://lore.kernel.org/r/20200302214443.55783-1-john.stultz@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1068,7 +1068,14 @@ static void dwc3_prepare_one_trb_sg(stru
+ unsigned int rem = length % maxp;
+ unsigned chain = true;
+
+- if (sg_is_last(s))
++ /*
++ * IOMMU driver is coalescing the list of sgs which shares a
++ * page boundary into one and giving it to USB driver. With
++ * this the number of sgs mapped is not equal to the number of
++ * sgs passed. So mark the chain bit to false if it isthe last
++ * mapped sg.
++ */
++ if (i == remaining - 1)
+ chain = false;
+
+ if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {
--- /dev/null
+From b96ed52d781a2026d0c0daa5787c6f3d45415862 Mon Sep 17 00:00:00 2001
+From: Dan Lazewatsky <dlaz@chromium.org>
+Date: Wed, 26 Feb 2020 14:34:38 +0000
+Subject: usb: quirks: add NO_LPM quirk for Logitech Screen Share
+
+From: Dan Lazewatsky <dlaz@chromium.org>
+
+commit b96ed52d781a2026d0c0daa5787c6f3d45415862 upstream.
+
+LPM on the device appears to cause xHCI host controllers to claim
+that there isn't enough bandwidth to support additional devices.
+
+Signed-off-by: Dan Lazewatsky <dlaz@chromium.org>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
+Link: https://lore.kernel.org/r/20200226143438.1445-1-gustavo.padovan@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -231,6 +231,9 @@ static const struct usb_device_id usb_qu
+ /* Logitech PTZ Pro Camera */
+ { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
+
++ /* Logitech Screen Share */
++ { USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM },
++
+ /* Logitech Quickcam Fusion */
+ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
+
--- /dev/null
+From 86d92f5465958752481269348d474414dccb1552 Mon Sep 17 00:00:00 2001
+From: Jim Lin <jilin@nvidia.com>
+Date: Mon, 2 Mar 2020 22:21:35 +0800
+Subject: usb: storage: Add quirk for Samsung Fit flash
+
+From: Jim Lin <jilin@nvidia.com>
+
+commit 86d92f5465958752481269348d474414dccb1552 upstream.
+
+Current driver has 240 (USB2.0) and 2048 (USB3.0) as max_sectors,
+e.g., /sys/bus/scsi/devices/0:0:0:0/max_sectors
+
+If data access times out, driver error handling will issue a port
+reset.
+Sometimes Samsung Fit (090C:1000) flash disk will not respond to
+later Set Address or Get Descriptor command.
+
+Adding this quirk to limit max_sectors to 64 sectors to avoid issue
+occurring.
+
+Signed-off-by: Jim Lin <jilin@nvidia.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1583158895-31342-1-git-send-email-jilin@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/storage/unusual_devs.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1258,6 +1258,12 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9
+ USB_SC_RBC, USB_PR_BULK, NULL,
+ 0 ),
+
++UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100,
++ "Samsung",
++ "Flash Drive FIT",
++ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++ US_FL_MAX_SECTORS_64),
++
+ /* aeb */
+ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
+ "Feiya",
--- /dev/null
+From 513dc792d6060d5ef572e43852683097a8420f56 Mon Sep 17 00:00:00 2001
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Date: Wed, 4 Mar 2020 10:24:29 +0800
+Subject: vgacon: Fix a UAF in vgacon_invert_region
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+commit 513dc792d6060d5ef572e43852683097a8420f56 upstream.
+
+When syzkaller tests, there is a UAF:
+ BUG: KASan: use after free in vgacon_invert_region+0x9d/0x110 at addr
+ ffff880000100000
+ Read of size 2 by task syz-executor.1/16489
+ page:ffffea0000004000 count:0 mapcount:-127 mapping: (null)
+ index:0x0
+ page flags: 0xfffff00000000()
+ page dumped because: kasan: bad access detected
+ CPU: 1 PID: 16489 Comm: syz-executor.1 Not tainted
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
+ rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014
+ Call Trace:
+ [<ffffffffb119f309>] dump_stack+0x1e/0x20
+ [<ffffffffb04af957>] kasan_report+0x577/0x950
+ [<ffffffffb04ae652>] __asan_load2+0x62/0x80
+ [<ffffffffb090f26d>] vgacon_invert_region+0x9d/0x110
+ [<ffffffffb0a39d95>] invert_screen+0xe5/0x470
+ [<ffffffffb0a21dcb>] set_selection+0x44b/0x12f0
+ [<ffffffffb0a3bfae>] tioclinux+0xee/0x490
+ [<ffffffffb0a1d114>] vt_ioctl+0xff4/0x2670
+ [<ffffffffb0a0089a>] tty_ioctl+0x46a/0x1a10
+ [<ffffffffb052db3d>] do_vfs_ioctl+0x5bd/0xc40
+ [<ffffffffb052e2f2>] SyS_ioctl+0x132/0x170
+ [<ffffffffb11c9b1b>] system_call_fastpath+0x22/0x27
+ Memory state around the buggy address:
+ ffff8800000fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00
+ ffff8800000fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00
+ >ffff880000100000: ff ff ff ff ff ff ff ff ff ff ff ff ff
+ ff ff ff
+
+It can be reproduce in the linux mainline by the program:
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/ioctl.h>
+ #include <linux/vt.h>
+
+ struct tiocl_selection {
+ unsigned short xs; /* X start */
+ unsigned short ys; /* Y start */
+ unsigned short xe; /* X end */
+ unsigned short ye; /* Y end */
+ unsigned short sel_mode; /* selection mode */
+ };
+
+ #define TIOCL_SETSEL 2
+ struct tiocl {
+ unsigned char type;
+ unsigned char pad;
+ struct tiocl_selection sel;
+ };
+
+ int main()
+ {
+ int fd = 0;
+ const char *dev = "/dev/char/4:1";
+
+ struct vt_consize v = {0};
+ struct tiocl tioc = {0};
+
+ fd = open(dev, O_RDWR, 0);
+
+ v.v_rows = 3346;
+ ioctl(fd, VT_RESIZEX, &v);
+
+ tioc.type = TIOCL_SETSEL;
+ ioctl(fd, TIOCLINUX, &tioc);
+
+ return 0;
+ }
+
+When resize the screen, update the 'vc->vc_size_row' to the new_row_size,
+but when 'set_origin' in 'vgacon_set_origin', vgacon use 'vga_vram_base'
+for 'vc_origin' and 'vc_visible_origin', not 'vc_screenbuf'. It maybe
+smaller than 'vc_screenbuf'. When TIOCLINUX, use the new_row_size to calc
+the offset, it maybe larger than the vga_vram_size in vgacon driver, then
+bad access.
+Also, if set an larger screenbuf firstly, then set an more larger
+screenbuf, when copy old_origin to new_origin, a bad access may happen.
+
+So, If the screen size larger than vga_vram, resize screen should be
+failed. This alse fix CVE-2020-8649 and CVE-2020-8647.
+
+Linus pointed out that overflow checking seems absent. We're saved by
+the existing bounds checks in vc_do_resize() with rather strict
+limits:
+
+ if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
+ return -EINVAL;
+
+Fixes: 0aec4867dca14 ("[PATCH] SVGATextMode fix")
+Reference: CVE-2020-8647 and CVE-2020-8649
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+[danvet: augment commit message to point out overflow safety]
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20200304022429.37738-1-zhangxiaoxu5@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/console/vgacon.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/video/console/vgacon.c
++++ b/drivers/video/console/vgacon.c
+@@ -1316,6 +1316,9 @@ static int vgacon_font_get(struct vc_dat
+ static int vgacon_resize(struct vc_data *c, unsigned int width,
+ unsigned int height, unsigned int user)
+ {
++ if ((width << 1) * height > vga_vram_size)
++ return -EINVAL;
++
+ if (width % 2 || width > screen_info.orig_video_cols ||
+ height > (screen_info.orig_video_lines * vga_default_font_height)/
+ c->vc_font.height)
--- /dev/null
+From 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 10 Feb 2020 09:11:31 +0100
+Subject: vt: selection, close sel_buffer race
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 07e6124a1a46b4b5a9b3cacc0c306b50da87abf5 upstream.
+
+syzkaller reported this UAF:
+BUG: KASAN: use-after-free in n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741
+Read of size 1 at addr ffff8880089e40e9 by task syz-executor.1/13184
+
+CPU: 0 PID: 13184 Comm: syz-executor.1 Not tainted 5.4.7 #1
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
+Call Trace:
+...
+ kasan_report+0xe/0x20 mm/kasan/common.c:634
+ n_tty_receive_buf_common+0x2481/0x2940 drivers/tty/n_tty.c:1741
+ tty_ldisc_receive_buf+0xac/0x190 drivers/tty/tty_buffer.c:461
+ paste_selection+0x297/0x400 drivers/tty/vt/selection.c:372
+ tioclinux+0x20d/0x4e0 drivers/tty/vt/vt.c:3044
+ vt_ioctl+0x1bcf/0x28d0 drivers/tty/vt/vt_ioctl.c:364
+ tty_ioctl+0x525/0x15a0 drivers/tty/tty_io.c:2657
+ vfs_ioctl fs/ioctl.c:47 [inline]
+
+It is due to a race between parallel paste_selection (TIOCL_PASTESEL)
+and set_selection_user (TIOCL_SETSEL) invocations. One uses sel_buffer,
+while the other frees it and reallocates a new one for another
+selection. Add a mutex to close this race.
+
+The mutex takes care properly of sel_buffer and sel_buffer_lth only. The
+other selection global variables (like sel_start, sel_end, and sel_cons)
+are protected only in set_selection_user. The other functions need quite
+some more work to close the races of the variables there. This is going
+to happen later.
+
+This likely fixes (I am unsure as there is no reproducer provided) bug
+206361 too. It was marked as CVE-2020-8648.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reported-by: syzbot+59997e8d5cbdc486e6f6@syzkaller.appspotmail.com
+References: https://bugzilla.kernel.org/show_bug.cgi?id=206361
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200210081131.23572-2-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/selection.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/vt/selection.c
++++ b/drivers/tty/vt/selection.c
+@@ -16,6 +16,7 @@
+ #include <linux/tty.h>
+ #include <linux/sched.h>
+ #include <linux/mm.h>
++#include <linux/mutex.h>
+ #include <linux/slab.h>
+ #include <linux/types.h>
+
+@@ -45,6 +46,7 @@ static volatile int sel_start = -1; /*
+ static int sel_end;
+ static int sel_buffer_lth;
+ static char *sel_buffer;
++static DEFINE_MUTEX(sel_lock);
+
+ /* clear_selection, highlight and highlight_pointer can be called
+ from interrupt (via scrollback/front) */
+@@ -186,7 +188,7 @@ int set_selection_kernel(struct tiocl_se
+ char *bp, *obp;
+ int i, ps, pe, multiplier;
+ u32 c;
+- int mode;
++ int mode, ret = 0;
+
+ poke_blanked_console();
+
+@@ -212,6 +214,7 @@ int set_selection_kernel(struct tiocl_se
+ if (ps > pe) /* make sel_start <= sel_end */
+ swap(ps, pe);
+
++ mutex_lock(&sel_lock);
+ if (sel_cons != vc_cons[fg_console].d) {
+ clear_selection();
+ sel_cons = vc_cons[fg_console].d;
+@@ -257,9 +260,10 @@ int set_selection_kernel(struct tiocl_se
+ break;
+ case TIOCL_SELPOINTER:
+ highlight_pointer(pe);
+- return 0;
++ goto unlock;
+ default:
+- return -EINVAL;
++ ret = -EINVAL;
++ goto unlock;
+ }
+
+ /* remove the pointer */
+@@ -281,7 +285,7 @@ int set_selection_kernel(struct tiocl_se
+ else if (new_sel_start == sel_start)
+ {
+ if (new_sel_end == sel_end) /* no action required */
+- return 0;
++ goto unlock;
+ else if (new_sel_end > sel_end) /* extend to right */
+ highlight(sel_end + 2, new_sel_end);
+ else /* contract from right */
+@@ -309,7 +313,8 @@ int set_selection_kernel(struct tiocl_se
+ if (!bp) {
+ printk(KERN_WARNING "selection: kmalloc() failed\n");
+ clear_selection();
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto unlock;
+ }
+ kfree(sel_buffer);
+ sel_buffer = bp;
+@@ -334,7 +339,9 @@ int set_selection_kernel(struct tiocl_se
+ }
+ }
+ sel_buffer_lth = bp - sel_buffer;
+- return 0;
++unlock:
++ mutex_unlock(&sel_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL_GPL(set_selection_kernel);
+
+@@ -364,6 +371,7 @@ int paste_selection(struct tty_struct *t
+ tty_buffer_lock_exclusive(&vc->port);
+
+ add_wait_queue(&vc->paste_wait, &wait);
++ mutex_lock(&sel_lock);
+ while (sel_buffer && sel_buffer_lth > pasted) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (signal_pending(current)) {
+@@ -371,7 +379,9 @@ int paste_selection(struct tty_struct *t
+ break;
+ }
+ if (tty_throttled(tty)) {
++ mutex_unlock(&sel_lock);
+ schedule();
++ mutex_lock(&sel_lock);
+ continue;
+ }
+ __set_current_state(TASK_RUNNING);
+@@ -380,6 +390,7 @@ int paste_selection(struct tty_struct *t
+ count);
+ pasted += count;
+ }
++ mutex_unlock(&sel_lock);
+ remove_wait_queue(&vc->paste_wait, &wait);
+ __set_current_state(TASK_RUNNING);
+
--- /dev/null
+From 4b70dd57a15d2f4685ac6e38056bad93e81e982f Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Fri, 28 Feb 2020 12:54:05 +0100
+Subject: vt: selection, push console lock down
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 4b70dd57a15d2f4685ac6e38056bad93e81e982f upstream.
+
+We need to nest the console lock in sel_lock, so we have to push it down
+a bit. Fortunately, the callers of set_selection_* just lock the console
+lock around the function call. So moving it down is easy.
+
+In the next patch, we switch the order.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Fixes: 07e6124a1a46 ("vt: selection, close sel_buffer race")
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200228115406.5735-1-jslaby@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/speakup/selection.c | 2 --
+ drivers/tty/vt/selection.c | 13 ++++++++++++-
+ drivers/tty/vt/vt.c | 2 --
+ 3 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/speakup/selection.c
++++ b/drivers/staging/speakup/selection.c
+@@ -51,9 +51,7 @@ static void __speakup_set_selection(stru
+ goto unref;
+ }
+
+- console_lock();
+ set_selection_kernel(&sel, tty);
+- console_unlock();
+
+ unref:
+ tty_kref_put(tty);
+--- a/drivers/tty/vt/selection.c
++++ b/drivers/tty/vt/selection.c
+@@ -181,7 +181,7 @@ int set_selection_user(const struct tioc
+ return set_selection_kernel(&v, tty);
+ }
+
+-int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty)
++static int __set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty)
+ {
+ struct vc_data *vc = vc_cons[fg_console].d;
+ int new_sel_start, new_sel_end, spc;
+@@ -343,6 +343,17 @@ unlock:
+ mutex_unlock(&sel_lock);
+ return ret;
+ }
++
++int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty)
++{
++ int ret;
++
++ console_lock();
++ ret = __set_selection_kernel(v, tty);
++ console_unlock();
++
++ return ret;
++}
+ EXPORT_SYMBOL_GPL(set_selection_kernel);
+
+ /* Insert the contents of the selection buffer into the
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -3046,10 +3046,8 @@ int tioclinux(struct tty_struct *tty, un
+ switch (type)
+ {
+ case TIOCL_SETSEL:
+- console_lock();
+ ret = set_selection_user((struct tiocl_selection
+ __user *)(p+1), tty);
+- console_unlock();
+ break;
+ case TIOCL_PASTESEL:
+ ret = paste_selection(tty);