--- /dev/null
+From d7d8535f377e9ba87edbf7fbbd634ac942f3f54f Mon Sep 17 00:00:00 2001
+From: Ming Lei <ming.lei@redhat.com>
+Date: Mon, 17 Aug 2020 18:01:15 +0800
+Subject: blk-mq: order adding requests to hctx->dispatch and checking SCHED_RESTART
+
+From: Ming Lei <ming.lei@redhat.com>
+
+commit d7d8535f377e9ba87edbf7fbbd634ac942f3f54f upstream.
+
+SCHED_RESTART code path is relied to re-run queue for dispatch requests
+in hctx->dispatch. Meantime the SCHED_RSTART flag is checked when adding
+requests to hctx->dispatch.
+
+memory barriers have to be used for ordering the following two pair of OPs:
+
+1) adding requests to hctx->dispatch and checking SCHED_RESTART in
+blk_mq_dispatch_rq_list()
+
+2) clearing SCHED_RESTART and checking if there is request in hctx->dispatch
+in blk_mq_sched_restart().
+
+Without the added memory barrier, either:
+
+1) blk_mq_sched_restart() may miss requests added to hctx->dispatch meantime
+blk_mq_dispatch_rq_list() observes SCHED_RESTART, and not run queue in
+dispatch side
+
+or
+
+2) blk_mq_dispatch_rq_list still sees SCHED_RESTART, and not run queue
+in dispatch side, meantime checking if there is request in
+hctx->dispatch from blk_mq_sched_restart() is missed.
+
+IO hang in ltp/fs_fill test is reported by kernel test robot:
+
+ https://lkml.org/lkml/2020/7/26/77
+
+Turns out it is caused by the above out-of-order OPs. And the IO hang
+can't be observed any more after applying this patch.
+
+Fixes: bd166ef183c2 ("blk-mq-sched: add framework for MQ capable IO schedulers")
+Reported-by: kernel test robot <rong.a.chen@intel.com>
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: David Jeffery <djeffery@redhat.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq-sched.c | 9 +++++++++
+ block/blk-mq.c | 9 +++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/block/blk-mq-sched.c
++++ b/block/blk-mq-sched.c
+@@ -69,6 +69,15 @@ void blk_mq_sched_restart(struct blk_mq_
+ return;
+ clear_bit(BLK_MQ_S_SCHED_RESTART, &hctx->state);
+
++ /*
++ * Order clearing SCHED_RESTART and list_empty_careful(&hctx->dispatch)
++ * in blk_mq_run_hw_queue(). Its pair is the barrier in
++ * blk_mq_dispatch_rq_list(). So dispatch code won't see SCHED_RESTART,
++ * meantime new request added to hctx->dispatch is missed to check in
++ * blk_mq_run_hw_queue().
++ */
++ smp_mb();
++
+ blk_mq_run_hw_queue(hctx, true);
+ }
+
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1222,6 +1222,15 @@ bool blk_mq_dispatch_rq_list(struct requ
+ spin_unlock(&hctx->lock);
+
+ /*
++ * Order adding requests to hctx->dispatch and checking
++ * SCHED_RESTART flag. The pair of this smp_mb() is the one
++ * in blk_mq_sched_restart(). Avoid restart code path to
++ * miss the new added requests to hctx->dispatch, meantime
++ * SCHED_RESTART is observed here.
++ */
++ smp_mb();
++
++ /*
+ * If SCHED_RESTART was set by the caller of this function and
+ * it is no longer set that means that it was cleared by another
+ * thread and hence that a queue rerun is needed.
--- /dev/null
+From bcb21c8cc9947286211327d663ace69f07d37a76 Mon Sep 17 00:00:00 2001
+From: Ming Lei <ming.lei@redhat.com>
+Date: Mon, 17 Aug 2020 18:01:30 +0800
+Subject: block: loop: set discard granularity and alignment for block device backed loop
+
+From: Ming Lei <ming.lei@redhat.com>
+
+commit bcb21c8cc9947286211327d663ace69f07d37a76 upstream.
+
+In case of block device backend, if the backend supports write zeros, the
+loop device will set queue flag of QUEUE_FLAG_DISCARD. However,
+limits.discard_granularity isn't setup, and this way is wrong,
+see the following description in Documentation/ABI/testing/sysfs-block:
+
+ A discard_granularity of 0 means that the device does not support
+ discard functionality.
+
+Especially 9b15d109a6b2 ("block: improve discard bio alignment in
+__blkdev_issue_discard()") starts to take q->limits.discard_granularity
+for computing max discard sectors. And zero discard granularity may cause
+kernel oops, or fail discard request even though the loop queue claims
+discard support via QUEUE_FLAG_DISCARD.
+
+Fix the issue by setup discard granularity and alignment.
+
+Fixes: c52abf563049 ("loop: Better discard support for block devices")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Coly Li <colyli@suse.de>
+Cc: Hannes Reinecke <hare@suse.com>
+Cc: Xiao Ni <xni@redhat.com>
+Cc: Martin K. Petersen <martin.petersen@oracle.com>
+Cc: Evan Green <evgreen@chromium.org>
+Cc: Gwendal Grignou <gwendal@chromium.org>
+Cc: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Cc: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/loop.c | 33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -864,6 +864,7 @@ static void loop_config_discard(struct l
+ struct file *file = lo->lo_backing_file;
+ struct inode *inode = file->f_mapping->host;
+ struct request_queue *q = lo->lo_queue;
++ u32 granularity, max_discard_sectors;
+
+ /*
+ * If the backing device is a block device, mirror its zeroing
+@@ -876,11 +877,10 @@ static void loop_config_discard(struct l
+ struct request_queue *backingq;
+
+ backingq = bdev_get_queue(inode->i_bdev);
+- blk_queue_max_discard_sectors(q,
+- backingq->limits.max_write_zeroes_sectors);
+
+- blk_queue_max_write_zeroes_sectors(q,
+- backingq->limits.max_write_zeroes_sectors);
++ max_discard_sectors = backingq->limits.max_write_zeroes_sectors;
++ granularity = backingq->limits.discard_granularity ?:
++ queue_physical_block_size(backingq);
+
+ /*
+ * We use punch hole to reclaim the free space used by the
+@@ -889,23 +889,26 @@ static void loop_config_discard(struct l
+ * useful information.
+ */
+ } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) {
+- q->limits.discard_granularity = 0;
+- q->limits.discard_alignment = 0;
+- blk_queue_max_discard_sectors(q, 0);
+- blk_queue_max_write_zeroes_sectors(q, 0);
++ max_discard_sectors = 0;
++ granularity = 0;
+
+ } else {
+- q->limits.discard_granularity = inode->i_sb->s_blocksize;
+- q->limits.discard_alignment = 0;
+-
+- blk_queue_max_discard_sectors(q, UINT_MAX >> 9);
+- blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9);
++ max_discard_sectors = UINT_MAX >> 9;
++ granularity = inode->i_sb->s_blocksize;
+ }
+
+- if (q->limits.max_write_zeroes_sectors)
++ if (max_discard_sectors) {
++ q->limits.discard_granularity = granularity;
++ blk_queue_max_discard_sectors(q, max_discard_sectors);
++ blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
+ blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
+- else
++ } else {
++ q->limits.discard_granularity = 0;
++ blk_queue_max_discard_sectors(q, 0);
++ blk_queue_max_write_zeroes_sectors(q, 0);
+ blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
++ }
++ q->limits.discard_alignment = 0;
+ }
+
+ static void loop_unprepare_queue(struct loop_device *lo)
--- /dev/null
+From bbc37d6e475eee8ffa2156ec813efc6bbb43c06d Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Fri, 14 Aug 2020 11:04:09 +0100
+Subject: btrfs: fix space cache memory leak after transaction abort
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit bbc37d6e475eee8ffa2156ec813efc6bbb43c06d upstream.
+
+If a transaction aborts it can cause a memory leak of the pages array of
+a block group's io_ctl structure. The following steps explain how that can
+happen:
+
+1) Transaction N is committing, currently in state TRANS_STATE_UNBLOCKED
+ and it's about to start writing out dirty extent buffers;
+
+2) Transaction N + 1 already started and another task, task A, just called
+ btrfs_commit_transaction() on it;
+
+3) Block group B was dirtied (extents allocated from it) by transaction
+ N + 1, so when task A calls btrfs_start_dirty_block_groups(), at the
+ very beginning of the transaction commit, it starts writeback for the
+ block group's space cache by calling btrfs_write_out_cache(), which
+ allocates the pages array for the block group's io_ctl with a call to
+ io_ctl_init(). Block group A is added to the io_list of transaction
+ N + 1 by btrfs_start_dirty_block_groups();
+
+4) While transaction N's commit is writing out the extent buffers, it gets
+ an IO error and aborts transaction N, also setting the file system to
+ RO mode;
+
+5) Task A has already returned from btrfs_start_dirty_block_groups(), is at
+ btrfs_commit_transaction() and has set transaction N + 1 state to
+ TRANS_STATE_COMMIT_START. Immediately after that it checks that the
+ filesystem was turned to RO mode, due to transaction N's abort, and
+ jumps to the "cleanup_transaction" label. After that we end up at
+ btrfs_cleanup_one_transaction() which calls btrfs_cleanup_dirty_bgs().
+ That helper finds block group B in the transaction's io_list but it
+ never releases the pages array of the block group's io_ctl, resulting in
+ a memory leak.
+
+In fact at the point when we are at btrfs_cleanup_dirty_bgs(), the pages
+array points to pages that were already released by us at
+__btrfs_write_out_cache() through the call to io_ctl_drop_pages(). We end
+up freeing the pages array only after waiting for the ordered extent to
+complete through btrfs_wait_cache_io(), which calls io_ctl_free() to do
+that. But in the transaction abort case we don't wait for the space cache's
+ordered extent to complete through a call to btrfs_wait_cache_io(), so
+that's why we end up with a memory leak - we wait for the ordered extent
+to complete indirectly by shutting down the work queues and waiting for
+any jobs in them to complete before returning from close_ctree().
+
+We can solve the leak simply by freeing the pages array right after
+releasing the pages (with the call to io_ctl_drop_pages()) at
+__btrfs_write_out_cache(), since we will never use it anymore after that
+and the pages array points to already released pages at that point, which
+is currently not a problem since no one will use it after that, but not a
+good practice anyway since it can easily lead to use-after-free issues.
+
+So fix this by freeing the pages array right after releasing the pages at
+__btrfs_write_out_cache().
+
+This issue can often be reproduced with test case generic/475 from fstests
+and kmemleak can detect it and reports it with the following trace:
+
+unreferenced object 0xffff9bbf009fa600 (size 512):
+ comm "fsstress", pid 38807, jiffies 4298504428 (age 22.028s)
+ hex dump (first 32 bytes):
+ 00 a0 7c 4d 3d ed ff ff 40 a0 7c 4d 3d ed ff ff ..|M=...@.|M=...
+ 80 a0 7c 4d 3d ed ff ff c0 a0 7c 4d 3d ed ff ff ..|M=.....|M=...
+ backtrace:
+ [<00000000f4b5cfe2>] __kmalloc+0x1a8/0x3e0
+ [<0000000028665e7f>] io_ctl_init+0xa7/0x120 [btrfs]
+ [<00000000a1f95b2d>] __btrfs_write_out_cache+0x86/0x4a0 [btrfs]
+ [<00000000207ea1b0>] btrfs_write_out_cache+0x7f/0xf0 [btrfs]
+ [<00000000af21f534>] btrfs_start_dirty_block_groups+0x27b/0x580 [btrfs]
+ [<00000000c3c23d44>] btrfs_commit_transaction+0xa6f/0xe70 [btrfs]
+ [<000000009588930c>] create_subvol+0x581/0x9a0 [btrfs]
+ [<000000009ef2fd7f>] btrfs_mksubvol+0x3fb/0x4a0 [btrfs]
+ [<00000000474e5187>] __btrfs_ioctl_snap_create+0x119/0x1a0 [btrfs]
+ [<00000000708ee349>] btrfs_ioctl_snap_create_v2+0xb0/0xf0 [btrfs]
+ [<00000000ea60106f>] btrfs_ioctl+0x12c/0x3130 [btrfs]
+ [<000000005c923d6d>] __x64_sys_ioctl+0x83/0xb0
+ [<0000000043ace2c9>] do_syscall_64+0x33/0x80
+ [<00000000904efbce>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+CC: stable@vger.kernel.org # 4.9+
+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/disk-io.c | 1 +
+ fs/btrfs/free-space-cache.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -4444,6 +4444,7 @@ static void btrfs_cleanup_bg_io(struct b
+ cache->io_ctl.inode = NULL;
+ iput(inode);
+ }
++ ASSERT(cache->io_ctl.pages == NULL);
+ btrfs_put_block_group(cache);
+ }
+
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -1167,7 +1167,6 @@ static int __btrfs_wait_cache_io(struct
+ ret = update_cache_item(trans, root, inode, path, offset,
+ io_ctl->entries, io_ctl->bitmaps);
+ out:
+- io_ctl_free(io_ctl);
+ if (ret) {
+ invalidate_inode_pages2(inode->i_mapping);
+ BTRFS_I(inode)->generation = 0;
+@@ -1332,6 +1331,7 @@ static int __btrfs_write_out_cache(struc
+ * them out later
+ */
+ io_ctl_drop_pages(io_ctl);
++ io_ctl_free(io_ctl);
+
+ unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0,
+ i_size_read(inode) - 1, &cached_state);
--- /dev/null
+From 282dd7d7718444679b046b769d872b188818ca35 Mon Sep 17 00:00:00 2001
+From: Marcos Paulo de Souza <mpdesouza@suse.com>
+Date: Mon, 3 Aug 2020 16:55:01 -0300
+Subject: btrfs: reset compression level for lzo on remount
+
+From: Marcos Paulo de Souza <mpdesouza@suse.com>
+
+commit 282dd7d7718444679b046b769d872b188818ca35 upstream.
+
+Currently a user can set mount "-o compress" which will set the
+compression algorithm to zlib, and use the default compress level for
+zlib (3):
+
+ relatime,compress=zlib:3,space_cache
+
+If the user remounts the fs using "-o compress=lzo", then the old
+compress_level is used:
+
+ relatime,compress=lzo:3,space_cache
+
+But lzo does not expose any tunable compression level. The same happens
+if we set any compress argument with different level, also with zstd.
+
+Fix this by resetting the compress_level when compress=lzo is
+specified. With the fix applied, lzo is shown without compress level:
+
+ relatime,compress=lzo,space_cache
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.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/super.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -539,6 +539,7 @@ int btrfs_parse_options(struct btrfs_fs_
+ } else if (strncmp(args[0].from, "lzo", 3) == 0) {
+ compress_type = "lzo";
+ info->compress_type = BTRFS_COMPRESS_LZO;
++ info->compress_level = 0;
+ btrfs_set_opt(info->mount_opt, COMPRESS);
+ btrfs_clear_opt(info->mount_opt, NODATACOW);
+ btrfs_clear_opt(info->mount_opt, NODATASUM);
--- /dev/null
+From 39b3cffb8cf3111738ea993e2757ab382253d86a Mon Sep 17 00:00:00 2001
+From: George Kennedy <george.kennedy@oracle.com>
+Date: Fri, 31 Jul 2020 12:33:11 -0400
+Subject: fbcon: prevent user font height or width change from causing potential out-of-bounds access
+
+From: George Kennedy <george.kennedy@oracle.com>
+
+commit 39b3cffb8cf3111738ea993e2757ab382253d86a upstream.
+
+Add a check to fbcon_resize() to ensure that a possible change to user font
+height or user font width will not allow a font data out-of-bounds access.
+NOTE: must use original charcount in calculation as font charcount can
+change and cannot be used to determine the font data allocated size.
+
+Signed-off-by: George Kennedy <george.kennedy@oracle.com>
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+38a3699c7eaf165b97a6@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/1596213192-6635-1-git-send-email-george.kennedy@oracle.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/fbdev/core/fbcon.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2152,6 +2152,9 @@ static void updatescrollmode(struct disp
+ }
+ }
+
++#define PITCH(w) (((w) + 7) >> 3)
++#define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */
++
+ static int fbcon_resize(struct vc_data *vc, unsigned int width,
+ unsigned int height, unsigned int user)
+ {
+@@ -2161,6 +2164,24 @@ static int fbcon_resize(struct vc_data *
+ struct fb_var_screeninfo var = info->var;
+ int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
+
++ if (ops->p && ops->p->userfont && FNTSIZE(vc->vc_font.data)) {
++ int size;
++ int pitch = PITCH(vc->vc_font.width);
++
++ /*
++ * If user font, ensure that a possible change to user font
++ * height or width will not allow a font data out-of-bounds access.
++ * NOTE: must use original charcount in calculation as font
++ * charcount can change and cannot be used to determine the
++ * font data allocated size.
++ */
++ if (pitch <= 0)
++ return -EINVAL;
++ size = CALC_FONTSZ(vc->vc_font.height, pitch, FNTCHARCNT(vc->vc_font.data));
++ if (size > FNTSIZE(vc->vc_font.data))
++ return -EINVAL;
++ }
++
+ virt_w = FBCON_SWAP(ops->rotate, width, height);
+ virt_h = FBCON_SWAP(ops->rotate, height, width);
+ virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
+@@ -2623,7 +2644,7 @@ static int fbcon_set_font(struct vc_data
+ int size;
+ int i, csum;
+ u8 *new_data, *data = font->data;
+- int pitch = (font->width+7) >> 3;
++ int pitch = PITCH(font->width);
+
+ /* Is there a reason why fbconsole couldn't handle any charcount >256?
+ * If not this check should be changed to charcount < 256 */
+@@ -2639,7 +2660,7 @@ static int fbcon_set_font(struct vc_data
+ if (fbcon_invalid_charcount(info, charcount))
+ return -EINVAL;
+
+- size = h * pitch * charcount;
++ size = CALC_FONTSZ(h, pitch, charcount);
+
+ new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
+
--- /dev/null
+From eef4016243e94c438f177ca8226876eb873b9c75 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 11 Aug 2020 15:39:58 +0200
+Subject: HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit eef4016243e94c438f177ca8226876eb873b9c75 upstream.
+
+Before this commit i2c_hid_parse() consists of the following steps:
+
+1. Send power on cmd
+2. usleep_range(1000, 5000)
+3. Send reset cmd
+4. Wait for reset to complete (device interrupt, or msleep(100))
+5. Send power on cmd
+6. Try to read HID descriptor
+
+Notice how there is an usleep_range(1000, 5000) after the first power-on
+command, but not after the second power-on command.
+
+Testing has shown that at least on the BMAX Y13 laptop's i2c-hid touchpad,
+not having a delay after the second power-on command causes the HID
+descriptor to read as all zeros.
+
+In case we hit this on other devices too, the descriptor being all zeros
+can be recognized by the following message being logged many, many times:
+
+hid-generic 0018:0911:5288.0002: unknown main item tag 0x0
+
+At the same time as the BMAX Y13's touchpad issue was debugged,
+Kai-Heng was working on debugging some issues with Goodix i2c-hid
+touchpads. It turns out that these need a delay after a PWR_ON command
+too, otherwise they stop working after a suspend/resume cycle.
+According to Goodix a delay of minimal 60ms is needed.
+
+Having multiple cases where we need a delay after sending the power-on
+command, seems to indicate that we should always sleep after the power-on
+command.
+
+This commit fixes the mentioned issues by moving the existing 1ms sleep to
+the i2c_hid_set_power() function and changing it to a 60ms sleep.
+
+Cc: stable@vger.kernel.org
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208247
+Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Reported-and-tested-by: Andrea Borgia <andrea@borgia.bo.it>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/i2c-hid/i2c-hid-core.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+--- a/drivers/hid/i2c-hid/i2c-hid-core.c
++++ b/drivers/hid/i2c-hid/i2c-hid-core.c
+@@ -444,6 +444,19 @@ static int i2c_hid_set_power(struct i2c_
+ dev_err(&client->dev, "failed to change power setting.\n");
+
+ set_pwr_exit:
++
++ /*
++ * The HID over I2C specification states that if a DEVICE needs time
++ * after the PWR_ON request, it should utilise CLOCK stretching.
++ * However, it has been observered that the Windows driver provides a
++ * 1ms sleep between the PWR_ON and RESET requests.
++ * According to Goodix Windows even waits 60 ms after (other?)
++ * PWR_ON requests. Testing has confirmed that several devices
++ * will not work properly without a delay after a PWR_ON request.
++ */
++ if (!ret && power_state == I2C_HID_PWR_ON)
++ msleep(60);
++
+ return ret;
+ }
+
+@@ -465,15 +478,6 @@ static int i2c_hid_hwreset(struct i2c_cl
+ if (ret)
+ goto out_unlock;
+
+- /*
+- * The HID over I2C specification states that if a DEVICE needs time
+- * after the PWR_ON request, it should utilise CLOCK stretching.
+- * However, it has been observered that the Windows driver provides a
+- * 1ms sleep between the PWR_ON and RESET requests and that some devices
+- * rely on this.
+- */
+- usleep_range(1000, 5000);
+-
+ i2c_hid_dbg(ihid, "resetting...\n");
+
+ ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0);
--- /dev/null
+From 205d300aea75623e1ae4aa43e0d265ab9cf195fd Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Date: Mon, 17 Aug 2020 11:26:46 +0900
+Subject: serial: 8250: change lock order in serial8250_do_startup()
+
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+
+commit 205d300aea75623e1ae4aa43e0d265ab9cf195fd upstream.
+
+We have a number of "uart.port->desc.lock vs desc.lock->uart.port"
+lockdep reports coming from 8250 driver; this causes a bit of trouble
+to people, so let's fix it.
+
+The problem is reverse lock order in two different call paths:
+
+chain #1:
+
+ serial8250_do_startup()
+ spin_lock_irqsave(&port->lock);
+ disable_irq_nosync(port->irq);
+ raw_spin_lock_irqsave(&desc->lock)
+
+chain #2:
+
+ __report_bad_irq()
+ raw_spin_lock_irqsave(&desc->lock)
+ for_each_action_of_desc()
+ printk()
+ spin_lock_irqsave(&port->lock);
+
+Fix this by changing the order of locks in serial8250_do_startup():
+ do disable_irq_nosync() first, which grabs desc->lock, and grab
+ uart->port after that, so that chain #1 and chain #2 have same lock
+ order.
+
+Full lockdep splat:
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.4.39 #55 Not tainted
+ ======================================================
+
+ swapper/0/0 is trying to acquire lock:
+ ffffffffab65b6c0 (console_owner){-...}, at: console_lock_spinning_enable+0x31/0x57
+
+ but task is already holding lock:
+ ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #2 (&irq_desc_lock_class){-.-.}:
+ _raw_spin_lock_irqsave+0x61/0x8d
+ __irq_get_desc_lock+0x65/0x89
+ __disable_irq_nosync+0x3b/0x93
+ serial8250_do_startup+0x451/0x75c
+ uart_startup+0x1b4/0x2ff
+ uart_port_activate+0x73/0xa0
+ tty_port_open+0xae/0x10a
+ uart_open+0x1b/0x26
+ tty_open+0x24d/0x3a0
+ chrdev_open+0xd5/0x1cc
+ do_dentry_open+0x299/0x3c8
+ path_openat+0x434/0x1100
+ do_filp_open+0x9b/0x10a
+ do_sys_open+0x15f/0x3d7
+ kernel_init_freeable+0x157/0x1dd
+ kernel_init+0xe/0x105
+ ret_from_fork+0x27/0x50
+
+ -> #1 (&port_lock_key){-.-.}:
+ _raw_spin_lock_irqsave+0x61/0x8d
+ serial8250_console_write+0xa7/0x2a0
+ console_unlock+0x3b7/0x528
+ vprintk_emit+0x111/0x17f
+ printk+0x59/0x73
+ register_console+0x336/0x3a4
+ uart_add_one_port+0x51b/0x5be
+ serial8250_register_8250_port+0x454/0x55e
+ dw8250_probe+0x4dc/0x5b9
+ platform_drv_probe+0x67/0x8b
+ really_probe+0x14a/0x422
+ driver_probe_device+0x66/0x130
+ device_driver_attach+0x42/0x5b
+ __driver_attach+0xca/0x139
+ bus_for_each_dev+0x97/0xc9
+ bus_add_driver+0x12b/0x228
+ driver_register+0x64/0xed
+ do_one_initcall+0x20c/0x4a6
+ do_initcall_level+0xb5/0xc5
+ do_basic_setup+0x4c/0x58
+ kernel_init_freeable+0x13f/0x1dd
+ kernel_init+0xe/0x105
+ ret_from_fork+0x27/0x50
+
+ -> #0 (console_owner){-...}:
+ __lock_acquire+0x118d/0x2714
+ lock_acquire+0x203/0x258
+ console_lock_spinning_enable+0x51/0x57
+ console_unlock+0x25d/0x528
+ vprintk_emit+0x111/0x17f
+ printk+0x59/0x73
+ __report_bad_irq+0xa3/0xba
+ note_interrupt+0x19a/0x1d6
+ handle_irq_event_percpu+0x57/0x79
+ handle_irq_event+0x36/0x55
+ handle_fasteoi_irq+0xc2/0x18a
+ do_IRQ+0xb3/0x157
+ ret_from_intr+0x0/0x1d
+ cpuidle_enter_state+0x12f/0x1fd
+ cpuidle_enter+0x2e/0x3d
+ do_idle+0x1ce/0x2ce
+ cpu_startup_entry+0x1d/0x1f
+ start_kernel+0x406/0x46a
+ secondary_startup_64+0xa4/0xb0
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ console_owner --> &port_lock_key --> &irq_desc_lock_class
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(&irq_desc_lock_class);
+ lock(&port_lock_key);
+ lock(&irq_desc_lock_class);
+ lock(console_owner);
+
+ *** DEADLOCK ***
+
+ 2 locks held by swapper/0/0:
+ #0: ffff88810a8e34c0 (&irq_desc_lock_class){-.-.}, at: __report_bad_irq+0x5b/0xba
+ #1: ffffffffab65b5c0 (console_lock){+.+.}, at: console_trylock_spinning+0x20/0x181
+
+ stack backtrace:
+ CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.39 #55
+ Hardware name: XXXXXX
+ Call Trace:
+ <IRQ>
+ dump_stack+0xbf/0x133
+ ? print_circular_bug+0xd6/0xe9
+ check_noncircular+0x1b9/0x1c3
+ __lock_acquire+0x118d/0x2714
+ lock_acquire+0x203/0x258
+ ? console_lock_spinning_enable+0x31/0x57
+ console_lock_spinning_enable+0x51/0x57
+ ? console_lock_spinning_enable+0x31/0x57
+ console_unlock+0x25d/0x528
+ ? console_trylock+0x18/0x4e
+ vprintk_emit+0x111/0x17f
+ ? lock_acquire+0x203/0x258
+ printk+0x59/0x73
+ __report_bad_irq+0xa3/0xba
+ note_interrupt+0x19a/0x1d6
+ handle_irq_event_percpu+0x57/0x79
+ handle_irq_event+0x36/0x55
+ handle_fasteoi_irq+0xc2/0x18a
+ do_IRQ+0xb3/0x157
+ common_interrupt+0xf/0xf
+ </IRQ>
+
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Fixes: 768aec0b5bcc ("serial: 8250: fix shared interrupts issues with SMP and RT kernels")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Reported-by: Raul Rangel <rrangel@google.com>
+BugLink: https://bugs.chromium.org/p/chromium/issues/detail?id=1114800
+Link: https://lore.kernel.org/lkml/CAHQZ30BnfX+gxjPm1DUd5psOTqbyDh4EJE=2=VAMW_VDafctkA@mail.gmail.com/T/#u
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200817022646.1484638-1-sergey.senozhatsky@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_port.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -2259,6 +2259,10 @@ int serial8250_do_startup(struct uart_po
+
+ if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
+ unsigned char iir1;
++
++ if (port->irqflags & IRQF_SHARED)
++ disable_irq_nosync(port->irq);
++
+ /*
+ * Test for UARTs that do not reassert THRE when the
+ * transmitter is idle and the interrupt has already
+@@ -2268,8 +2272,6 @@ int serial8250_do_startup(struct uart_po
+ * allow register changes to become visible.
+ */
+ spin_lock_irqsave(&port->lock, flags);
+- if (up->port.irqflags & IRQF_SHARED)
+- disable_irq_nosync(port->irq);
+
+ wait_for_xmitr(up, UART_LSR_THRE);
+ serial_port_out_sync(port, UART_IER, UART_IER_THRI);
+@@ -2281,9 +2283,10 @@ int serial8250_do_startup(struct uart_po
+ iir = serial_port_in(port, UART_IIR);
+ serial_port_out(port, UART_IER, 0);
+
++ spin_unlock_irqrestore(&port->lock, flags);
++
+ if (port->irqflags & IRQF_SHARED)
+ enable_irq(port->irq);
+- spin_unlock_irqrestore(&port->lock, flags);
+
+ /*
+ * If the interrupt is not reasserted, or we otherwise
--- /dev/null
+From c6b9e95dde7b54e6a53c47241201ab5a4035c320 Mon Sep 17 00:00:00 2001
+From: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Date: Thu, 13 Aug 2020 12:52:55 -0400
+Subject: serial: 8250_exar: Fix number of ports for Commtech PCIe cards
+
+From: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+
+commit c6b9e95dde7b54e6a53c47241201ab5a4035c320 upstream.
+
+The following in 8250_exar.c line 589 is used to determine the number
+of ports for each Exar board:
+
+nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
+
+If the number of ports a card has is not explicitly specified, it defaults
+to the rightmost 4 bits of the PCI device ID. This is prone to error since
+not all PCI device IDs contain a number which corresponds to the number of
+ports that card provides.
+
+This particular case involves COMMTECH_4222PCIE, COMMTECH_4224PCIE and
+COMMTECH_4228PCIE cards with device IDs 0x0022, 0x0020 and 0x0021.
+Currently the multiport cards receive 2, 0 and 1 port instead of 2, 4 and
+8 ports respectively.
+
+To fix this, each Commtech Fastcom PCIe card is given a struct where the
+number of ports is explicitly specified. This ensures 'board->num_ports'
+is used instead of the default 'pcidev->device & 0x0f'.
+
+Fixes: d0aeaa83f0b0 ("serial: exar: split out the exar code from 8250_pci")
+Signed-off-by: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Tested-by: Valmer Huhn <valmer.huhn@concurrent-rt.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200813165255.GC345440@icarus.concurrent-rt.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_exar.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_exar.c
++++ b/drivers/tty/serial/8250/8250_exar.c
+@@ -638,6 +638,24 @@ static const struct exar8250_board pbn_e
+ .exit = pci_xr17v35x_exit,
+ };
+
++static const struct exar8250_board pbn_fastcom35x_2 = {
++ .num_ports = 2,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
++static const struct exar8250_board pbn_fastcom35x_4 = {
++ .num_ports = 4,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
++static const struct exar8250_board pbn_fastcom35x_8 = {
++ .num_ports = 8,
++ .setup = pci_xr17v35x_setup,
++ .exit = pci_xr17v35x_exit,
++};
++
+ static const struct exar8250_board pbn_exar_XR17V4358 = {
+ .num_ports = 12,
+ .setup = pci_xr17v35x_setup,
+@@ -708,9 +726,9 @@ static const struct pci_device_id exar_p
+ EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x),
+ EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358),
+ EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358),
+- EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x),
+- EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x),
+- EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x),
++ EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_fastcom35x_2),
++ EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_fastcom35x_4),
++ EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_fastcom35x_8),
+
+ EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2),
+ EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4),
--- /dev/null
+From 89efbe70b27dd325d8a8c177743a26b885f7faec Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 13 Aug 2020 12:59:54 +0200
+Subject: serial: pl011: Don't leak amba_ports entry on driver register error
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 89efbe70b27dd325d8a8c177743a26b885f7faec upstream.
+
+pl011_probe() calls pl011_setup_port() to reserve an amba_ports[] entry,
+then calls pl011_register_port() to register the uart driver with the
+tty layer.
+
+If registration of the uart driver fails, the amba_ports[] entry is not
+released. If this happens 14 times (value of UART_NR macro), then all
+amba_ports[] entries will have been leaked and driver probing is no
+longer possible. (To be fair, that can only happen if the DeviceTree
+doesn't contain alias IDs since they cause the same entry to be used for
+a given port.) Fix it.
+
+Fixes: ef2889f7ffee ("serial: pl011: Move uart_register_driver call to device")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.15+
+Cc: Tushar Behera <tushar.behera@linaro.org>
+Link: https://lore.kernel.org/r/138f8c15afb2f184d8102583f8301575566064a6.1597316167.git.lukas@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/amba-pl011.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -2593,7 +2593,7 @@ static int pl011_setup_port(struct devic
+
+ static int pl011_register_port(struct uart_amba_port *uap)
+ {
+- int ret;
++ int ret, i;
+
+ /* Ensure interrupts from this UART are masked and cleared */
+ pl011_write(0, uap, REG_IMSC);
+@@ -2604,6 +2604,9 @@ static int pl011_register_port(struct ua
+ if (ret < 0) {
+ dev_err(uap->port.dev,
+ "Failed to register AMBA-PL011 driver\n");
++ for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
++ if (amba_ports[i] == uap)
++ amba_ports[i] = NULL;
+ return ret;
+ }
+ }
--- /dev/null
+From 27afac93e3bd7fa89749cf11da5d86ac9cde4dba Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 13 Aug 2020 12:52:40 +0200
+Subject: serial: pl011: Fix oops on -EPROBE_DEFER
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 27afac93e3bd7fa89749cf11da5d86ac9cde4dba upstream.
+
+If probing of a pl011 gets deferred until after free_initmem(), an oops
+ensues because pl011_console_match() is called which has been freed.
+
+Fix by removing the __init attribute from the function and those it
+calls.
+
+Commit 10879ae5f12e ("serial: pl011: add console matching function")
+introduced pl011_console_match() not just for early consoles but
+regular preferred consoles, such as those added by acpi_parse_spcr().
+Regular consoles may be registered after free_initmem() for various
+reasons, one being deferred probing, another being dynamic enablement
+of serial ports using a DeviceTree overlay.
+
+Thus, pl011_console_match() must not be declared __init and the
+functions it calls mustn't either.
+
+Stack trace for posterity:
+
+Unable to handle kernel paging request at virtual address 80c38b58
+Internal error: Oops: 8000000d [#1] PREEMPT SMP ARM
+PC is at pl011_console_match+0x0/0xfc
+LR is at register_console+0x150/0x468
+[<80187004>] (register_console)
+[<805a8184>] (uart_add_one_port)
+[<805b2b68>] (pl011_register_port)
+[<805b3ce4>] (pl011_probe)
+[<80569214>] (amba_probe)
+[<805ca088>] (really_probe)
+[<805ca2ec>] (driver_probe_device)
+[<805ca5b0>] (__device_attach_driver)
+[<805c8060>] (bus_for_each_drv)
+[<805c9dfc>] (__device_attach)
+[<805ca630>] (device_initial_probe)
+[<805c90a8>] (bus_probe_device)
+[<805c95a8>] (deferred_probe_work_func)
+
+Fixes: 10879ae5f12e ("serial: pl011: add console matching function")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v4.10+
+Cc: Aleksey Makarov <amakarov@marvell.com>
+Cc: Peter Hurley <peter@hurleysoftware.com>
+Cc: Russell King <linux@armlinux.org.uk>
+Cc: Christopher Covington <cov@codeaurora.org>
+Link: https://lore.kernel.org/r/f827ff09da55b8c57d316a1b008a137677b58921.1597315557.git.lukas@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/amba-pl011.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -2252,9 +2252,8 @@ pl011_console_write(struct console *co,
+ clk_disable(uap->clk);
+ }
+
+-static void __init
+-pl011_console_get_options(struct uart_amba_port *uap, int *baud,
+- int *parity, int *bits)
++static void pl011_console_get_options(struct uart_amba_port *uap, int *baud,
++ int *parity, int *bits)
+ {
+ if (pl011_read(uap, REG_CR) & UART01x_CR_UARTEN) {
+ unsigned int lcr_h, ibrd, fbrd;
+@@ -2287,7 +2286,7 @@ pl011_console_get_options(struct uart_am
+ }
+ }
+
+-static int __init pl011_console_setup(struct console *co, char *options)
++static int pl011_console_setup(struct console *co, char *options)
+ {
+ struct uart_amba_port *uap;
+ int baud = 38400;
+@@ -2355,8 +2354,8 @@ static int __init pl011_console_setup(st
+ *
+ * Returns 0 if console matches; otherwise non-zero to use default matching
+ */
+-static int __init pl011_console_match(struct console *co, char *name, int idx,
+- char *options)
++static int pl011_console_match(struct console *co, char *name, int idx,
++ char *options)
+ {
+ unsigned char iotype;
+ resource_size_t addr;
--- /dev/null
+From 8c6c378b0cbe0c9f1390986b5f8ffb5f6ff7593b Mon Sep 17 00:00:00 2001
+From: Tamseel Shams <m.shams@samsung.com>
+Date: Mon, 10 Aug 2020 08:30:21 +0530
+Subject: serial: samsung: Removes the IRQ not found warning
+
+From: Tamseel Shams <m.shams@samsung.com>
+
+commit 8c6c378b0cbe0c9f1390986b5f8ffb5f6ff7593b upstream.
+
+In few older Samsung SoCs like s3c2410, s3c2412
+and s3c2440, UART IP is having 2 interrupt lines.
+However, in other SoCs like s3c6400, s5pv210,
+exynos5433, and exynos4210 UART is having only 1
+interrupt line. Due to this, "platform_get_irq(platdev, 1)"
+call in the driver gives the following false-positive error:
+"IRQ index 1 not found" on newer SoC's.
+
+This patch adds the condition to check for Tx interrupt
+only for the those SoC's which have 2 interrupt lines.
+
+Tested-by: Alim Akhtar <alim.akhtar@samsung.com>
+Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
+Signed-off-by: Tamseel Shams <m.shams@samsung.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200810030021.45348-1-m.shams@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/samsung.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serial/samsung.c
++++ b/drivers/tty/serial/samsung.c
+@@ -1755,9 +1755,11 @@ static int s3c24xx_serial_init_port(stru
+ ourport->tx_irq = ret + 1;
+ }
+
+- ret = platform_get_irq(platdev, 1);
+- if (ret > 0)
+- ourport->tx_irq = ret;
++ if (!s3c24xx_serial_has_interrupt_mask(port)) {
++ ret = platform_get_irq(platdev, 1);
++ if (ret > 0)
++ ourport->tx_irq = ret;
++ }
+ /*
+ * DMA is currently supported only on DT platforms, if DMA properties
+ * are specified.
macvlan-validate-setting-of-multiple-remote-source-m.patch
net-gianfar-add-of_node_put-before-goto-statement.patch
powerpc-perf-fix-soft-lockups-due-to-missed-interrup.patch
+block-loop-set-discard-granularity-and-alignment-for-block-device-backed-loop.patch
+hid-i2c-hid-always-sleep-60ms-after-i2c_hid_pwr_on-commands.patch
+blk-mq-order-adding-requests-to-hctx-dispatch-and-checking-sched_restart.patch
+btrfs-reset-compression-level-for-lzo-on-remount.patch
+btrfs-fix-space-cache-memory-leak-after-transaction-abort.patch
+fbcon-prevent-user-font-height-or-width-change-from-causing-potential-out-of-bounds-access.patch
+usb-lvtest-return-proper-error-code-in-probe.patch
+vt-defer-kfree-of-vc_screenbuf-in-vc_do_resize.patch
+vt_ioctl-change-vt_resizex-ioctl-to-check-for-error-return-from-vc_resize.patch
+serial-samsung-removes-the-irq-not-found-warning.patch
+serial-pl011-fix-oops-on-eprobe_defer.patch
+serial-pl011-don-t-leak-amba_ports-entry-on-driver-register-error.patch
+serial-8250_exar-fix-number-of-ports-for-commtech-pcie-cards.patch
+serial-8250-change-lock-order-in-serial8250_do_startup.patch
+writeback-protect-inode-i_io_list-with-inode-i_lock.patch
+writeback-avoid-skipping-inode-writeback.patch
+writeback-fix-sync-livelock-due-to-b_dirty_time-processing.patch
+xen-uses-irqdesc-irq_data_common-handler_data-to-store-a-per-interrupt-xen-data-pointer-which-contains-xen-specific-information.patch
+usb-host-xhci-fix-ep-context-print-mismatch-in-debugfs.patch
+xhci-do-warm-reset-when-both-cas-and-xdev_resume-are-set.patch
+xhci-always-restore-ep_soft_clear_toggle-even-if-ep-reset-failed.patch
--- /dev/null
+From 0077b1b2c8d9ad5f7a08b62fb8524cdb9938388f Mon Sep 17 00:00:00 2001
+From: Li Jun <jun.li@nxp.com>
+Date: Fri, 21 Aug 2020 12:15:47 +0300
+Subject: usb: host: xhci: fix ep context print mismatch in debugfs
+
+From: Li Jun <jun.li@nxp.com>
+
+commit 0077b1b2c8d9ad5f7a08b62fb8524cdb9938388f upstream.
+
+dci is 0 based and xhci_get_ep_ctx() will do ep index increment to get
+the ep context.
+
+[rename dci to ep_index -Mathias]
+Cc: stable <stable@vger.kernel.org> # v4.15+
+Fixes: 02b6fdc2a153 ("usb: xhci: Add debugfs interface for xHCI driver")
+Signed-off-by: Li Jun <jun.li@nxp.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-debugfs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-debugfs.c
++++ b/drivers/usb/host/xhci-debugfs.c
+@@ -273,7 +273,7 @@ static int xhci_slot_context_show(struct
+
+ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
+ {
+- int dci;
++ int ep_index;
+ dma_addr_t dma;
+ struct xhci_hcd *xhci;
+ struct xhci_ep_ctx *ep_ctx;
+@@ -282,9 +282,9 @@ static int xhci_endpoint_context_show(st
+
+ xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
+
+- for (dci = 1; dci < 32; dci++) {
+- ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci);
+- dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params);
++ for (ep_index = 0; ep_index < 31; ep_index++) {
++ ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
++ dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params);
+ seq_printf(s, "%pad: %s\n", &dma,
+ xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
+ le32_to_cpu(ep_ctx->ep_info2),
--- /dev/null
+From 531412492ce93ea29b9ca3b4eb5e3ed771f851dd Mon Sep 17 00:00:00 2001
+From: Evgeny Novikov <novikov@ispras.ru>
+Date: Wed, 5 Aug 2020 12:06:43 +0300
+Subject: USB: lvtest: return proper error code in probe
+
+From: Evgeny Novikov <novikov@ispras.ru>
+
+commit 531412492ce93ea29b9ca3b4eb5e3ed771f851dd upstream.
+
+lvs_rh_probe() can return some nonnegative value from usb_control_msg()
+when it is less than "USB_DT_HUB_NONVAR_SIZE + 2" that is considered as
+a failure. Make lvs_rh_probe() return -EINVAL in this case.
+
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Evgeny Novikov <novikov@ispras.ru>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200805090643.3432-1-novikov@ispras.ru
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/misc/lvstest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/misc/lvstest.c
++++ b/drivers/usb/misc/lvstest.c
+@@ -429,7 +429,7 @@ static int lvs_rh_probe(struct usb_inter
+ USB_DT_SS_HUB_SIZE, USB_CTRL_GET_TIMEOUT);
+ if (ret < (USB_DT_HUB_NONVAR_SIZE + 2)) {
+ dev_err(&hdev->dev, "wrong root hub descriptor read %d\n", ret);
+- return ret;
++ return ret < 0 ? ret : -EINVAL;
+ }
+
+ /* submit urb to poll interrupt endpoint */
--- /dev/null
+From f8d1653daec02315e06d30246cff4af72e76e54e Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Wed, 29 Jul 2020 23:57:01 +0900
+Subject: vt: defer kfree() of vc_screenbuf in vc_do_resize()
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit f8d1653daec02315e06d30246cff4af72e76e54e upstream.
+
+syzbot is reporting UAF bug in set_origin() from vc_do_resize() [1], for
+vc_do_resize() calls kfree(vc->vc_screenbuf) before calling set_origin().
+
+Unfortunately, in set_origin(), vc->vc_sw->con_set_origin() might access
+vc->vc_pos when scroll is involved in order to manipulate cursor, but
+vc->vc_pos refers already released vc->vc_screenbuf until vc->vc_pos gets
+updated based on the result of vc->vc_sw->con_set_origin().
+
+Preserving old buffer and tolerating outdated vc members until set_origin()
+completes would be easier than preventing vc->vc_sw->con_set_origin() from
+accessing outdated vc members.
+
+[1] https://syzkaller.appspot.com/bug?id=6649da2081e2ebdc65c0642c214b27fe91099db3
+
+Reported-by: syzbot <syzbot+9116ecc1978ca3a12f43@syzkaller.appspotmail.com>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/1596034621-4714-1-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -1199,7 +1199,7 @@ static int vc_do_resize(struct tty_struc
+ unsigned int old_rows, old_row_size, first_copied_row;
+ unsigned int new_cols, new_rows, new_row_size, new_screen_size;
+ unsigned int user;
+- unsigned short *newscreen;
++ unsigned short *oldscreen, *newscreen;
+ struct uni_screen *new_uniscr = NULL;
+
+ WARN_CONSOLE_UNLOCKED();
+@@ -1297,10 +1297,11 @@ static int vc_do_resize(struct tty_struc
+ if (new_scr_end > new_origin)
+ scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
+ new_scr_end - new_origin);
+- kfree(vc->vc_screenbuf);
++ oldscreen = vc->vc_screenbuf;
+ vc->vc_screenbuf = newscreen;
+ vc->vc_screenbuf_size = new_screen_size;
+ set_origin(vc);
++ kfree(oldscreen);
+
+ /* do part of a reset_terminal() */
+ vc->vc_top = 0;
--- /dev/null
+From bc5269ca765057a1b762e79a1cfd267cd7bf1c46 Mon Sep 17 00:00:00 2001
+From: George Kennedy <george.kennedy@oracle.com>
+Date: Fri, 31 Jul 2020 12:33:12 -0400
+Subject: vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize()
+
+From: George Kennedy <george.kennedy@oracle.com>
+
+commit bc5269ca765057a1b762e79a1cfd267cd7bf1c46 upstream.
+
+vc_resize() can return with an error after failure. Change VT_RESIZEX ioctl
+to save struct vc_data values that are modified and restore the original
+values in case of error.
+
+Signed-off-by: George Kennedy <george.kennedy@oracle.com>
+Cc: stable <stable@vger.kernel.org>
+Reported-by: syzbot+38a3699c7eaf165b97a6@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/r/1596213192-6635-2-git-send-email-george.kennedy@oracle.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/vt/vt_ioctl.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/vt/vt_ioctl.c
++++ b/drivers/tty/vt/vt_ioctl.c
+@@ -893,12 +893,22 @@ int vt_ioctl(struct tty_struct *tty,
+ console_lock();
+ vcp = vc_cons[i].d;
+ if (vcp) {
++ int ret;
++ int save_scan_lines = vcp->vc_scan_lines;
++ int save_font_height = vcp->vc_font.height;
++
+ if (v.v_vlin)
+ vcp->vc_scan_lines = v.v_vlin;
+ if (v.v_clin)
+ vcp->vc_font.height = v.v_clin;
+ vcp->vc_resize_user = 1;
+- vc_resize(vcp, v.v_cols, v.v_rows);
++ ret = vc_resize(vcp, v.v_cols, v.v_rows);
++ if (ret) {
++ vcp->vc_scan_lines = save_scan_lines;
++ vcp->vc_font.height = save_font_height;
++ console_unlock();
++ return ret;
++ }
+ }
+ console_unlock();
+ }
--- /dev/null
+From 5afced3bf28100d81fb2fe7e98918632a08feaf5 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 29 May 2020 15:05:22 +0200
+Subject: writeback: Avoid skipping inode writeback
+
+From: Jan Kara <jack@suse.cz>
+
+commit 5afced3bf28100d81fb2fe7e98918632a08feaf5 upstream.
+
+Inode's i_io_list list head is used to attach inode to several different
+lists - wb->{b_dirty, b_dirty_time, b_io, b_more_io}. When flush worker
+prepares a list of inodes to writeback e.g. for sync(2), it moves inodes
+to b_io list. Thus it is critical for sync(2) data integrity guarantees
+that inode is not requeued to any other writeback list when inode is
+queued for processing by flush worker. That's the reason why
+writeback_single_inode() does not touch i_io_list (unless the inode is
+completely clean) and why __mark_inode_dirty() does not touch i_io_list
+if I_SYNC flag is set.
+
+However there are two flaws in the current logic:
+
+1) When inode has only I_DIRTY_TIME set but it is already queued in b_io
+list due to sync(2), concurrent __mark_inode_dirty(inode, I_DIRTY_SYNC)
+can still move inode back to b_dirty list resulting in skipping
+writeback of inode time stamps during sync(2).
+
+2) When inode is on b_dirty_time list and writeback_single_inode() races
+with __mark_inode_dirty() like:
+
+writeback_single_inode() __mark_inode_dirty(inode, I_DIRTY_PAGES)
+ inode->i_state |= I_SYNC
+ __writeback_single_inode()
+ inode->i_state |= I_DIRTY_PAGES;
+ if (inode->i_state & I_SYNC)
+ bail
+ if (!(inode->i_state & I_DIRTY_ALL))
+ - not true so nothing done
+
+We end up with I_DIRTY_PAGES inode on b_dirty_time list and thus
+standard background writeback will not writeback this inode leading to
+possible dirty throttling stalls etc. (thanks to Martijn Coenen for this
+analysis).
+
+Fix these problems by tracking whether inode is queued in b_io or
+b_more_io lists in a new I_SYNC_QUEUED flag. When this flag is set, we
+know flush worker has queued inode and we should not touch i_io_list.
+On the other hand we also know that once flush worker is done with the
+inode it will requeue the inode to appropriate dirty list. When
+I_SYNC_QUEUED is not set, __mark_inode_dirty() can (and must) move inode
+to appropriate dirty list.
+
+Reported-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Martijn Coenen <maco@android.com>
+Tested-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 17 ++++++++++++-----
+ include/linux/fs.h | 8 ++++++--
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -162,6 +162,7 @@ static void inode_io_list_del_locked(str
+ assert_spin_locked(&wb->list_lock);
+ assert_spin_locked(&inode->i_lock);
+
++ inode->i_state &= ~I_SYNC_QUEUED;
+ list_del_init(&inode->i_io_list);
+ wb_io_lists_depopulated(wb);
+ }
+@@ -1106,6 +1107,7 @@ static void redirty_tail_locked(struct i
+ inode->dirtied_when = jiffies;
+ }
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty);
++ inode->i_state &= ~I_SYNC_QUEUED;
+ }
+
+ static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
+@@ -1181,8 +1183,11 @@ static int move_expired_inodes(struct li
+ break;
+ list_move(&inode->i_io_list, &tmp);
+ moved++;
++ spin_lock(&inode->i_lock);
+ if (flags & EXPIRE_DIRTY_ATIME)
+- set_bit(__I_DIRTY_TIME_EXPIRED, &inode->i_state);
++ inode->i_state |= I_DIRTY_TIME_EXPIRED;
++ inode->i_state |= I_SYNC_QUEUED;
++ spin_unlock(&inode->i_lock);
+ if (sb_is_blkdev_sb(inode->i_sb))
+ continue;
+ if (sb && sb != inode->i_sb)
+@@ -1357,6 +1362,7 @@ static void requeue_inode(struct inode *
+ } else if (inode->i_state & I_DIRTY_TIME) {
+ inode->dirtied_when = jiffies;
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++ inode->i_state &= ~I_SYNC_QUEUED;
+ } else {
+ /* The inode is clean. Remove from writeback lists. */
+ inode_io_list_del_locked(inode, wb);
+@@ -2220,11 +2226,12 @@ void __mark_inode_dirty(struct inode *in
+ inode->i_state |= flags;
+
+ /*
+- * If the inode is being synced, just update its dirty state.
+- * The unlocker will place the inode on the appropriate
+- * superblock list, based upon its state.
++ * If the inode is queued for writeback by flush worker, just
++ * update its dirty state. Once the flush worker is done with
++ * the inode it will place it on the appropriate superblock
++ * list, based upon its state.
+ */
+- if (inode->i_state & I_SYNC)
++ if (inode->i_state & I_SYNC_QUEUED)
+ goto out_unlock_inode;
+
+ /*
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2050,6 +2050,10 @@ static inline void init_sync_kiocb(struc
+ *
+ * I_CREATING New object's inode in the middle of setting up.
+ *
++ * I_SYNC_QUEUED Inode is queued in b_io or b_more_io writeback lists.
++ * Used to detect that mark_inode_dirty() should not move
++ * inode between dirty lists.
++ *
+ * Q: What is the difference between I_WILL_FREE and I_FREEING?
+ */
+ #define I_DIRTY_SYNC (1 << 0)
+@@ -2067,11 +2071,11 @@ static inline void init_sync_kiocb(struc
+ #define I_DIO_WAKEUP (1 << __I_DIO_WAKEUP)
+ #define I_LINKABLE (1 << 10)
+ #define I_DIRTY_TIME (1 << 11)
+-#define __I_DIRTY_TIME_EXPIRED 12
+-#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
++#define I_DIRTY_TIME_EXPIRED (1 << 12)
+ #define I_WB_SWITCH (1 << 13)
+ #define I_OVL_INUSE (1 << 14)
+ #define I_CREATING (1 << 15)
++#define I_SYNC_QUEUED (1 << 17)
+
+ #define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
+ #define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
--- /dev/null
+From f9cae926f35e8230330f28c7b743ad088611a8de Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Fri, 29 May 2020 16:08:58 +0200
+Subject: writeback: Fix sync livelock due to b_dirty_time processing
+
+From: Jan Kara <jack@suse.cz>
+
+commit f9cae926f35e8230330f28c7b743ad088611a8de upstream.
+
+When we are processing writeback for sync(2), move_expired_inodes()
+didn't set any inode expiry value (older_than_this). This can result in
+writeback never completing if there's steady stream of inodes added to
+b_dirty_time list as writeback rechecks dirty lists after each writeback
+round whether there's more work to be done. Fix the problem by using
+sync(2) start time is inode expiry value when processing b_dirty_time
+list similarly as for ordinarily dirtied inodes. This requires some
+refactoring of older_than_this handling which simplifies the code
+noticeably as a bonus.
+
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+CC: stable@vger.kernel.org
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 44 +++++++++++++++------------------------
+ include/trace/events/writeback.h | 13 +++++------
+ 2 files changed, 23 insertions(+), 34 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -45,7 +45,6 @@ struct wb_completion {
+ struct wb_writeback_work {
+ long nr_pages;
+ struct super_block *sb;
+- unsigned long *older_than_this;
+ enum writeback_sync_modes sync_mode;
+ unsigned int tagged_writepages:1;
+ unsigned int for_kupdate:1;
+@@ -1153,16 +1152,13 @@ static bool inode_dirtied_after(struct i
+ #define EXPIRE_DIRTY_ATIME 0x0001
+
+ /*
+- * Move expired (dirtied before work->older_than_this) dirty inodes from
++ * Move expired (dirtied before dirtied_before) dirty inodes from
+ * @delaying_queue to @dispatch_queue.
+ */
+ static int move_expired_inodes(struct list_head *delaying_queue,
+ struct list_head *dispatch_queue,
+- int flags,
+- struct wb_writeback_work *work)
++ int flags, unsigned long dirtied_before)
+ {
+- unsigned long *older_than_this = NULL;
+- unsigned long expire_time;
+ LIST_HEAD(tmp);
+ struct list_head *pos, *node;
+ struct super_block *sb = NULL;
+@@ -1170,16 +1166,9 @@ static int move_expired_inodes(struct li
+ int do_sb_sort = 0;
+ int moved = 0;
+
+- if ((flags & EXPIRE_DIRTY_ATIME) == 0)
+- older_than_this = work->older_than_this;
+- else if (!work->for_sync) {
+- expire_time = jiffies - (dirtytime_expire_interval * HZ);
+- older_than_this = &expire_time;
+- }
+ while (!list_empty(delaying_queue)) {
+ inode = wb_inode(delaying_queue->prev);
+- if (older_than_this &&
+- inode_dirtied_after(inode, *older_than_this))
++ if (inode_dirtied_after(inode, dirtied_before))
+ break;
+ list_move(&inode->i_io_list, &tmp);
+ moved++;
+@@ -1225,18 +1214,22 @@ out:
+ * |
+ * +--> dequeue for IO
+ */
+-static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work)
++static void queue_io(struct bdi_writeback *wb, struct wb_writeback_work *work,
++ unsigned long dirtied_before)
+ {
+ int moved;
++ unsigned long time_expire_jif = dirtied_before;
+
+ assert_spin_locked(&wb->list_lock);
+ list_splice_init(&wb->b_more_io, &wb->b_io);
+- moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, work);
++ moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, dirtied_before);
++ if (!work->for_sync)
++ time_expire_jif = jiffies - dirtytime_expire_interval * HZ;
+ moved += move_expired_inodes(&wb->b_dirty_time, &wb->b_io,
+- EXPIRE_DIRTY_ATIME, work);
++ EXPIRE_DIRTY_ATIME, time_expire_jif);
+ if (moved)
+ wb_io_lists_populated(wb);
+- trace_writeback_queue_io(wb, work, moved);
++ trace_writeback_queue_io(wb, work, dirtied_before, moved);
+ }
+
+ static int write_inode(struct inode *inode, struct writeback_control *wbc)
+@@ -1748,7 +1741,7 @@ static long writeback_inodes_wb(struct b
+ blk_start_plug(&plug);
+ spin_lock(&wb->list_lock);
+ if (list_empty(&wb->b_io))
+- queue_io(wb, &work);
++ queue_io(wb, &work, jiffies);
+ __writeback_inodes_wb(wb, &work);
+ spin_unlock(&wb->list_lock);
+ blk_finish_plug(&plug);
+@@ -1768,7 +1761,7 @@ static long writeback_inodes_wb(struct b
+ * takes longer than a dirty_writeback_interval interval, then leave a
+ * one-second gap.
+ *
+- * older_than_this takes precedence over nr_to_write. So we'll only write back
++ * dirtied_before takes precedence over nr_to_write. So we'll only write back
+ * all dirty pages if they are all attached to "old" mappings.
+ */
+ static long wb_writeback(struct bdi_writeback *wb,
+@@ -1776,14 +1769,11 @@ static long wb_writeback(struct bdi_writ
+ {
+ unsigned long wb_start = jiffies;
+ long nr_pages = work->nr_pages;
+- unsigned long oldest_jif;
++ unsigned long dirtied_before = jiffies;
+ struct inode *inode;
+ long progress;
+ struct blk_plug plug;
+
+- oldest_jif = jiffies;
+- work->older_than_this = &oldest_jif;
+-
+ blk_start_plug(&plug);
+ spin_lock(&wb->list_lock);
+ for (;;) {
+@@ -1817,14 +1807,14 @@ static long wb_writeback(struct bdi_writ
+ * safe.
+ */
+ if (work->for_kupdate) {
+- oldest_jif = jiffies -
++ dirtied_before = jiffies -
+ msecs_to_jiffies(dirty_expire_interval * 10);
+ } else if (work->for_background)
+- oldest_jif = jiffies;
++ dirtied_before = jiffies;
+
+ trace_writeback_start(wb, work);
+ if (list_empty(&wb->b_io))
+- queue_io(wb, work);
++ queue_io(wb, work, dirtied_before);
+ if (work->sb)
+ progress = writeback_sb_inodes(work->sb, wb, work);
+ else
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -360,8 +360,9 @@ DEFINE_WBC_EVENT(wbc_writepage);
+ TRACE_EVENT(writeback_queue_io,
+ TP_PROTO(struct bdi_writeback *wb,
+ struct wb_writeback_work *work,
++ unsigned long dirtied_before,
+ int moved),
+- TP_ARGS(wb, work, moved),
++ TP_ARGS(wb, work, dirtied_before, moved),
+ TP_STRUCT__entry(
+ __array(char, name, 32)
+ __field(unsigned long, older)
+@@ -371,19 +372,17 @@ TRACE_EVENT(writeback_queue_io,
+ __field(unsigned int, cgroup_ino)
+ ),
+ TP_fast_assign(
+- unsigned long *older_than_this = work->older_than_this;
+ strncpy(__entry->name, dev_name(wb->bdi->dev), 32);
+- __entry->older = older_than_this ? *older_than_this : 0;
+- __entry->age = older_than_this ?
+- (jiffies - *older_than_this) * 1000 / HZ : -1;
++ __entry->older = dirtied_before;
++ __entry->age = (jiffies - dirtied_before) * 1000 / HZ;
+ __entry->moved = moved;
+ __entry->reason = work->reason;
+ __entry->cgroup_ino = __trace_wb_assign_cgroup(wb);
+ ),
+ TP_printk("bdi %s: older=%lu age=%ld enqueue=%d reason=%s cgroup_ino=%u",
+ __entry->name,
+- __entry->older, /* older_than_this in jiffies */
+- __entry->age, /* older_than_this in relative milliseconds */
++ __entry->older, /* dirtied_before in jiffies */
++ __entry->age, /* dirtied_before in relative milliseconds */
+ __entry->moved,
+ __print_symbolic(__entry->reason, WB_WORK_REASON),
+ __entry->cgroup_ino
--- /dev/null
+From b35250c0816c7cf7d0a8de92f5fafb6a7508a708 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 10 Jun 2020 17:36:03 +0200
+Subject: writeback: Protect inode->i_io_list with inode->i_lock
+
+From: Jan Kara <jack@suse.cz>
+
+commit b35250c0816c7cf7d0a8de92f5fafb6a7508a708 upstream.
+
+Currently, operations on inode->i_io_list are protected by
+wb->list_lock. In the following patches we'll need to maintain
+consistency between inode->i_state and inode->i_io_list so change the
+code so that inode->i_lock protects also all inode's i_io_list handling.
+
+Reviewed-by: Martijn Coenen <maco@android.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+CC: stable@vger.kernel.org # Prerequisite for "writeback: Avoid skipping inode writeback"
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fs-writeback.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -160,6 +160,7 @@ static void inode_io_list_del_locked(str
+ struct bdi_writeback *wb)
+ {
+ assert_spin_locked(&wb->list_lock);
++ assert_spin_locked(&inode->i_lock);
+
+ list_del_init(&inode->i_io_list);
+ wb_io_lists_depopulated(wb);
+@@ -1042,7 +1043,9 @@ void inode_io_list_del(struct inode *ino
+ struct bdi_writeback *wb;
+
+ wb = inode_to_wb_and_lock_list(inode);
++ spin_lock(&inode->i_lock);
+ inode_io_list_del_locked(inode, wb);
++ spin_unlock(&inode->i_lock);
+ spin_unlock(&wb->list_lock);
+ }
+
+@@ -1091,8 +1094,10 @@ void sb_clear_inode_writeback(struct ino
+ * the case then the inode must have been redirtied while it was being written
+ * out and we don't reset its dirtied_when.
+ */
+-static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
++static void redirty_tail_locked(struct inode *inode, struct bdi_writeback *wb)
+ {
++ assert_spin_locked(&inode->i_lock);
++
+ if (!list_empty(&wb->b_dirty)) {
+ struct inode *tail;
+
+@@ -1103,6 +1108,13 @@ static void redirty_tail(struct inode *i
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty);
+ }
+
++static void redirty_tail(struct inode *inode, struct bdi_writeback *wb)
++{
++ spin_lock(&inode->i_lock);
++ redirty_tail_locked(inode, wb);
++ spin_unlock(&inode->i_lock);
++}
++
+ /*
+ * requeue inode for re-scanning after bdi->b_io list is exhausted.
+ */
+@@ -1313,7 +1325,7 @@ static void requeue_inode(struct inode *
+ * writeback is not making progress due to locked
+ * buffers. Skip this inode for now.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ return;
+ }
+
+@@ -1333,7 +1345,7 @@ static void requeue_inode(struct inode *
+ * retrying writeback of the dirty page/inode
+ * that cannot be performed immediately.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ }
+ } else if (inode->i_state & I_DIRTY) {
+ /*
+@@ -1341,7 +1353,7 @@ static void requeue_inode(struct inode *
+ * such as delayed allocation during submission or metadata
+ * updates after data IO completion.
+ */
+- redirty_tail(inode, wb);
++ redirty_tail_locked(inode, wb);
+ } else if (inode->i_state & I_DIRTY_TIME) {
+ inode->dirtied_when = jiffies;
+ inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
+@@ -1588,8 +1600,8 @@ static long writeback_sb_inodes(struct s
+ */
+ spin_lock(&inode->i_lock);
+ if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
++ redirty_tail_locked(inode, wb);
+ spin_unlock(&inode->i_lock);
+- redirty_tail(inode, wb);
+ continue;
+ }
+ if ((inode->i_state & I_SYNC) && wbc.sync_mode != WB_SYNC_ALL) {
--- /dev/null
+From c330fb1ddc0a922f044989492b7fcca77ee1db46 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 25 Aug 2020 17:22:58 +0200
+Subject: XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN data pointer which contains XEN specific information.
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit c330fb1ddc0a922f044989492b7fcca77ee1db46 upstream.
+
+handler data is meant for interrupt handlers and not for storing irq chip
+specific information as some devices require handler data to store internal
+per interrupt information, e.g. pinctrl/GPIO chained interrupt handlers.
+
+This obviously creates a conflict of interests and crashes the machine
+because the XEN pointer is overwritten by the driver pointer.
+
+As the XEN data is not handler specific it should be stored in
+irqdesc::irq_data::chip_data instead.
+
+A simple sed s/irq_[sg]et_handler_data/irq_[sg]et_chip_data/ cures that.
+
+Cc: stable@vger.kernel.org
+Reported-by: Roman Shaposhnik <roman@zededa.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Roman Shaposhnik <roman@zededa.com>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://lore.kernel.org/r/87lfi2yckt.fsf@nanos.tec.linutronix.de
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/events/events_base.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -154,7 +154,7 @@ int get_evtchn_to_irq(unsigned evtchn)
+ /* Get info for IRQ */
+ struct irq_info *info_for_irq(unsigned irq)
+ {
+- return irq_get_handler_data(irq);
++ return irq_get_chip_data(irq);
+ }
+
+ /* Constructors for packed IRQ information. */
+@@ -375,7 +375,7 @@ static void xen_irq_init(unsigned irq)
+ info->type = IRQT_UNBOUND;
+ info->refcnt = -1;
+
+- irq_set_handler_data(irq, info);
++ irq_set_chip_data(irq, info);
+
+ list_add_tail(&info->list, &xen_irq_list_head);
+ }
+@@ -424,14 +424,14 @@ static int __must_check xen_allocate_irq
+
+ static void xen_free_irq(unsigned irq)
+ {
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (WARN_ON(!info))
+ return;
+
+ list_del(&info->list);
+
+- irq_set_handler_data(irq, NULL);
++ irq_set_chip_data(irq, NULL);
+
+ WARN_ON(info->refcnt > 0);
+
+@@ -601,7 +601,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
+ static void __unbind_from_irq(unsigned int irq)
+ {
+ int evtchn = evtchn_from_irq(irq);
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (info->refcnt > 0) {
+ info->refcnt--;
+@@ -1105,7 +1105,7 @@ int bind_ipi_to_irqhandler(enum ipi_vect
+
+ void unbind_from_irqhandler(unsigned int irq, void *dev_id)
+ {
+- struct irq_info *info = irq_get_handler_data(irq);
++ struct irq_info *info = irq_get_chip_data(irq);
+
+ if (WARN_ON(!info))
+ return;
+@@ -1139,7 +1139,7 @@ int evtchn_make_refcounted(unsigned int
+ if (irq == -1)
+ return -ENOENT;
+
+- info = irq_get_handler_data(irq);
++ info = irq_get_chip_data(irq);
+
+ if (!info)
+ return -ENOENT;
+@@ -1167,7 +1167,7 @@ int evtchn_get(unsigned int evtchn)
+ if (irq == -1)
+ goto done;
+
+- info = irq_get_handler_data(irq);
++ info = irq_get_chip_data(irq);
+
+ if (!info)
+ goto done;
--- /dev/null
+From f1ec7ae6c9f8c016db320e204cb519a1da1581b8 Mon Sep 17 00:00:00 2001
+From: Ding Hui <dinghui@sangfor.com.cn>
+Date: Fri, 21 Aug 2020 12:15:49 +0300
+Subject: xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed
+
+From: Ding Hui <dinghui@sangfor.com.cn>
+
+commit f1ec7ae6c9f8c016db320e204cb519a1da1581b8 upstream.
+
+Some device drivers call libusb_clear_halt when target ep queue
+is not empty. (eg. spice client connected to qemu for usb redir)
+
+Before commit f5249461b504 ("xhci: Clear the host side toggle
+manually when endpoint is soft reset"), that works well.
+But now, we got the error log:
+
+ EP not empty, refuse reset
+
+xhci_endpoint_reset failed and left ep_state's EP_SOFT_CLEAR_TOGGLE
+bit still set
+
+So all the subsequent urb sumbits to the ep will fail with the
+warn log:
+
+ Can't enqueue URB while manually clearing toggle
+
+We need to clear ep_state EP_SOFT_CLEAR_TOGGLE bit after
+xhci_endpoint_reset, even if it failed.
+
+Fixes: f5249461b504 ("xhci: Clear the host side toggle manually when endpoint is soft reset")
+Cc: stable <stable@vger.kernel.org> # v4.17+
+Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-4-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3154,10 +3154,11 @@ static void xhci_endpoint_reset(struct u
+
+ wait_for_completion(cfg_cmd->completion);
+
+- ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
+ xhci_free_command(xhci, cfg_cmd);
+ cleanup:
+ xhci_free_command(xhci, stop_cmd);
++ if (ep->ep_state & EP_SOFT_CLEAR_TOGGLE)
++ ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
+ }
+
+ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
--- /dev/null
+From 904df64a5f4d5ebd670801d869ca0a6d6a6e8df6 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 21 Aug 2020 12:15:48 +0300
+Subject: xhci: Do warm-reset when both CAS and XDEV_RESUME are set
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 904df64a5f4d5ebd670801d869ca0a6d6a6e8df6 upstream.
+
+Sometimes re-plugging a USB device during system sleep renders the device
+useless:
+[ 173.418345] xhci_hcd 0000:00:14.0: Get port status 2-4 read: 0x14203e2, return 0x10262
+...
+[ 176.496485] usb 2-4: Waited 2000ms for CONNECT
+[ 176.496781] usb usb2-port4: status 0000.0262 after resume, -19
+[ 176.497103] usb 2-4: can't resume, status -19
+[ 176.497438] usb usb2-port4: logical disconnect
+
+Because PLS equals to XDEV_RESUME, xHCI driver reports U3 to usbcore,
+despite of CAS bit is flagged.
+
+So proritize CAS over XDEV_RESUME to let usbcore handle warm-reset for
+the port.
+
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20200821091549.20556-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -736,15 +736,6 @@ static void xhci_hub_report_usb3_link_st
+ {
+ u32 pls = status_reg & PORT_PLS_MASK;
+
+- /* resume state is a xHCI internal state.
+- * Do not report it to usb core, instead, pretend to be U3,
+- * thus usb core knows it's not ready for transfer
+- */
+- if (pls == XDEV_RESUME) {
+- *status |= USB_SS_PORT_LS_U3;
+- return;
+- }
+-
+ /* When the CAS bit is set then warm reset
+ * should be performed on port
+ */
+@@ -767,6 +758,16 @@ static void xhci_hub_report_usb3_link_st
+ pls |= USB_PORT_STAT_CONNECTION;
+ } else {
+ /*
++ * Resume state is an xHCI internal state. Do not report it to
++ * usb core, instead, pretend to be U3, thus usb core knows
++ * it's not ready for transfer.
++ */
++ if (pls == XDEV_RESUME) {
++ *status |= USB_SS_PORT_LS_U3;
++ return;
++ }
++
++ /*
+ * If CAS bit isn't set but the Port is already at
+ * Compliance Mode, fake a connection so the USB core
+ * notices the Compliance state and resets the port.