From d36fa3ee65545ac96cf0e8e64672d2872729ec6d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 May 2021 10:29:36 +0200 Subject: [PATCH] 5.12-stable patches added patches: ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch ext4-always-panic-when-errors-panic-is-specified.patch ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch ext4-annotate-data-race-in-start_this_handle.patch ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch ext4-fix-error-code-in-ext4_commit_super.patch ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch ext4-fix-occasional-generic-418-failure.patch io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch io_uring-fix-shared-sqpoll-cancellation-hangs.patch io_uring-fix-work_exit-sqpoll-cancellations.patch io_uring-remove-extra-sqpoll-submission-halting.patch kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch media-coda-fix-macroblocks-count-control-usage.patch media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch media-dvb-usb-fix-use-after-free-access.patch media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch media-staging-intel-ipu3-fix-set_fmt-error-handling.patch media-v4l2-ctrls-fix-reference-to-freed-memory.patch media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch media-venus-pm_helpers-set-opp-clock-name-for-v1.patch media-venus-venc_ctrls-change-default-header-mode.patch pci-dwc-move-iatu-detection-earlier.patch rsi-use-resume_noirq-for-sdio.patch tty-fix-memory-leak-in-vc_deallocate.patch usb-dwc2-fix-session-request-interrupt-handler.patch usb-dwc3-core-do-core-softreset-when-switch-mode.patch usb-dwc3-gadget-fix-start_transfer-link-state-check.patch usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch usb-gadget-fix-double-free-of-device-descriptor-pointers.patch usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch --- ...et-and-cleared-on-inline-directories.patch | 49 +++ ...panic-when-errors-panic-is-specified.patch | 66 ++++ ...-race-in-jbd2_journal_dirty_metadata.patch | 48 +++ ...otate-data-race-in-start_this_handle.patch | 39 +++ ...set-sb_active-in-ext4_orphan_cleanup.patch | 49 +++ ...tive-report-of-incorrect-used-inodes.patch | 96 +++++ ...-fix-error-code-in-ext4_commit_super.patch | 38 ++ ...eturn-code-in-ext4_fc_perform_commit.patch | 37 ++ ...-save-negative-errno-into-superblock.patch | 35 ++ ...4-fix-occasional-generic-418-failure.patch | 80 +++++ ...t-io_uring-in-io_uring_cancel_sqpoll.patch | 43 +++ ...fix-shared-sqpoll-cancellation-hangs.patch | 132 +++++++ ...g-fix-work_exit-sqpoll-cancellations.patch | 78 +++++ ...move-extra-sqpoll-submission-halting.patch | 51 +++ ...en-the-content-of-.config-is-changed.patch | 88 +++++ ...-fix-macroblocks-count-control-usage.patch | 40 +++ ...leak-at-error-in-dvb_usb_device_init.patch | 120 +++++++ ...ia-dvb-usb-fix-use-after-free-access.patch | 76 ++++ ...memory-leak-in-dvb_media_device_free.patch | 37 ++ ...ntel-ipu3-fix-memory-leak-in-imu_fmt.patch | 49 +++ ...u3-fix-race-condition-during-set_fmt.patch | 105 ++++++ ...ntel-ipu3-fix-set_fmt-error-handling.patch | 57 +++ ...-ctrls-fix-reference-to-freed-memory.patch | 330 ++++++++++++++++++ ...t-plane-actual-info-property-from-v1.patch | 62 ++++ ...-for-instance-after-hfi-platform-get.patch | 43 +++ ...parser-don-t-initialize-parser-on-v1.patch | 39 +++ ...pm_helpers-set-opp-clock-name-for-v1.patch | 65 ++++ ...enc_ctrls-change-default-header-mode.patch | 34 ++ .../pci-dwc-move-iatu-detection-earlier.patch | 100 ++++++ .../rsi-use-resume_noirq-for-sdio.patch | 46 +++ queue-5.12/series | 38 ++ ...tty-fix-memory-leak-in-vc_deallocate.patch | 34 ++ ...ix-session-request-interrupt-handler.patch | 47 +++ ...e-do-core-softreset-when-switch-mode.patch | 155 ++++++++ ...-fix-start_transfer-link-state-check.patch | 63 ++++ ...et-remove-fs-binterval_m1-limitation.patch | 44 +++ ...et-dummy_hcd-fix-gpf-in-gadget_setup.patch | 90 +++++ ...e-free-of-device-descriptor-pointers.patch | 44 +++ ...ing-table-fix-for-multiple-languages.patch | 44 +++ 39 files changed, 2691 insertions(+) create mode 100644 queue-5.12/ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch create mode 100644 queue-5.12/ext4-always-panic-when-errors-panic-is-specified.patch create mode 100644 queue-5.12/ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch create mode 100644 queue-5.12/ext4-annotate-data-race-in-start_this_handle.patch create mode 100644 queue-5.12/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch create mode 100644 queue-5.12/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch create mode 100644 queue-5.12/ext4-fix-error-code-in-ext4_commit_super.patch create mode 100644 queue-5.12/ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch create mode 100644 queue-5.12/ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch create mode 100644 queue-5.12/ext4-fix-occasional-generic-418-failure.patch create mode 100644 queue-5.12/io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch create mode 100644 queue-5.12/io_uring-fix-shared-sqpoll-cancellation-hangs.patch create mode 100644 queue-5.12/io_uring-fix-work_exit-sqpoll-cancellations.patch create mode 100644 queue-5.12/io_uring-remove-extra-sqpoll-submission-halting.patch create mode 100644 queue-5.12/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch create mode 100644 queue-5.12/media-coda-fix-macroblocks-count-control-usage.patch create mode 100644 queue-5.12/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch create mode 100644 queue-5.12/media-dvb-usb-fix-use-after-free-access.patch create mode 100644 queue-5.12/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch create mode 100644 queue-5.12/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch create mode 100644 queue-5.12/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch create mode 100644 queue-5.12/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch create mode 100644 queue-5.12/media-v4l2-ctrls-fix-reference-to-freed-memory.patch create mode 100644 queue-5.12/media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch create mode 100644 queue-5.12/media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch create mode 100644 queue-5.12/media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch create mode 100644 queue-5.12/media-venus-pm_helpers-set-opp-clock-name-for-v1.patch create mode 100644 queue-5.12/media-venus-venc_ctrls-change-default-header-mode.patch create mode 100644 queue-5.12/pci-dwc-move-iatu-detection-earlier.patch create mode 100644 queue-5.12/rsi-use-resume_noirq-for-sdio.patch create mode 100644 queue-5.12/tty-fix-memory-leak-in-vc_deallocate.patch create mode 100644 queue-5.12/usb-dwc2-fix-session-request-interrupt-handler.patch create mode 100644 queue-5.12/usb-dwc3-core-do-core-softreset-when-switch-mode.patch create mode 100644 queue-5.12/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch create mode 100644 queue-5.12/usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch create mode 100644 queue-5.12/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch create mode 100644 queue-5.12/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch create mode 100644 queue-5.12/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch diff --git a/queue-5.12/ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch b/queue-5.12/ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch new file mode 100644 index 00000000000..98e3ddcbd58 --- /dev/null +++ b/queue-5.12/ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch @@ -0,0 +1,49 @@ +From 4811d9929cdae4238baf5b2522247bd2f9fa7b50 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 12 Apr 2021 17:19:00 -0400 +Subject: ext4: allow the dax flag to be set and cleared on inline directories + +From: Theodore Ts'o + +commit 4811d9929cdae4238baf5b2522247bd2f9fa7b50 upstream. + +This is needed to allow generic/607 to pass for file systems with the +inline data_feature enabled, and it allows the use of file systems +where the directories use inline_data, while the files are accessed +via DAX. + +Cc: stable@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ialloc.c | 3 ++- + fs/ext4/ioctl.c | 6 ++++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1292,7 +1292,8 @@ got: + + ei->i_extra_isize = sbi->s_want_extra_isize; + ei->i_inline_off = 0; +- if (ext4_has_feature_inline_data(sb)) ++ if (ext4_has_feature_inline_data(sb) && ++ (!(ei->i_flags & EXT4_DAX_FL) || S_ISDIR(mode))) + ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); + ret = inode; + err = dquot_alloc_inode(inode); +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -315,6 +315,12 @@ static void ext4_dax_dontcache(struct in + static bool dax_compatible(struct inode *inode, unsigned int oldflags, + unsigned int flags) + { ++ /* Allow the DAX flag to be changed on inline directories */ ++ if (S_ISDIR(inode->i_mode)) { ++ flags &= ~EXT4_INLINE_DATA_FL; ++ oldflags &= ~EXT4_INLINE_DATA_FL; ++ } ++ + if (flags & EXT4_DAX_FL) { + if ((oldflags & EXT4_DAX_MUT_EXCL) || + ext4_test_inode_state(inode, diff --git a/queue-5.12/ext4-always-panic-when-errors-panic-is-specified.patch b/queue-5.12/ext4-always-panic-when-errors-panic-is-specified.patch new file mode 100644 index 00000000000..6d71ac91c8c --- /dev/null +++ b/queue-5.12/ext4-always-panic-when-errors-panic-is-specified.patch @@ -0,0 +1,66 @@ +From ac2f7ca51b0929461ea49918f27c11b680f28995 Mon Sep 17 00:00:00 2001 +From: Ye Bin +Date: Thu, 1 Apr 2021 16:19:03 +0800 +Subject: ext4: always panic when errors=panic is specified + +From: Ye Bin + +commit ac2f7ca51b0929461ea49918f27c11b680f28995 upstream. + +Before commit 014c9caa29d3 ("ext4: make ext4_abort() use +__ext4_error()"), the following series of commands would trigger a +panic: + +1. mount /dev/sda -o ro,errors=panic test +2. mount /dev/sda -o remount,abort test + +After commit 014c9caa29d3, remounting a file system using the test +mount option "abort" will no longer trigger a panic. This commit will +restore the behaviour immediately before commit 014c9caa29d3. +(However, note that the Linux kernel's behavior has not been +consistent; some previous kernel versions, including 5.4 and 4.19 +similarly did not panic after using the mount option "abort".) + +This also makes a change to long-standing behaviour; namely, the +following series commands will now cause a panic, when previously it +did not: + +1. mount /dev/sda -o ro,errors=panic test +2. echo test > /sys/fs/ext4/sda/trigger_fs_error + +However, this makes ext4's behaviour much more consistent, so this is +a good thing. + +Cc: stable@kernel.org +Fixes: 014c9caa29d3 ("ext4: make ext4_abort() use __ext4_error()") +Signed-off-by: Ye Bin +Link: https://lore.kernel.org/r/20210401081903.3421208-1-yebin10@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -667,9 +667,6 @@ static void ext4_handle_error(struct sup + ext4_commit_super(sb); + } + +- if (sb_rdonly(sb) || continue_fs) +- return; +- + /* + * We force ERRORS_RO behavior when system is rebooting. Otherwise we + * could panic during 'reboot -f' as the underlying device got already +@@ -679,6 +676,10 @@ static void ext4_handle_error(struct sup + panic("EXT4-fs (device %s): panic forced after error\n", + sb->s_id); + } ++ ++ if (sb_rdonly(sb) || continue_fs) ++ return; ++ + ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); + /* + * Make sure updated value of ->s_mount_flags will be visible before diff --git a/queue-5.12/ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch b/queue-5.12/ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch new file mode 100644 index 00000000000..66b5ba47b3c --- /dev/null +++ b/queue-5.12/ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch @@ -0,0 +1,48 @@ +From 83fe6b18b8d04c6c849379005e1679bac9752466 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 6 Apr 2021 18:18:00 +0200 +Subject: ext4: annotate data race in jbd2_journal_dirty_metadata() + +From: Jan Kara + +commit 83fe6b18b8d04c6c849379005e1679bac9752466 upstream. + +Assertion checks in jbd2_journal_dirty_metadata() are known to be racy +but we don't want to be grabbing locks just for them. We thus recheck +them under b_state_lock only if it looks like they would fail. Annotate +the checks with data_race(). + +Cc: stable@kernel.org +Reported-by: Hao Sun +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20210406161804.20150-2-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/transaction.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1479,8 +1479,8 @@ int jbd2_journal_dirty_metadata(handle_t + * crucial to catch bugs so let's do a reliable check until the + * lockless handling is fully proven. + */ +- if (jh->b_transaction != transaction && +- jh->b_next_transaction != transaction) { ++ if (data_race(jh->b_transaction != transaction && ++ jh->b_next_transaction != transaction)) { + spin_lock(&jh->b_state_lock); + J_ASSERT_JH(jh, jh->b_transaction == transaction || + jh->b_next_transaction == transaction); +@@ -1488,8 +1488,8 @@ int jbd2_journal_dirty_metadata(handle_t + } + if (jh->b_modified == 1) { + /* If it's in our transaction it must be in BJ_Metadata list. */ +- if (jh->b_transaction == transaction && +- jh->b_jlist != BJ_Metadata) { ++ if (data_race(jh->b_transaction == transaction && ++ jh->b_jlist != BJ_Metadata)) { + spin_lock(&jh->b_state_lock); + if (jh->b_transaction == transaction && + jh->b_jlist != BJ_Metadata) diff --git a/queue-5.12/ext4-annotate-data-race-in-start_this_handle.patch b/queue-5.12/ext4-annotate-data-race-in-start_this_handle.patch new file mode 100644 index 00000000000..60010ce2199 --- /dev/null +++ b/queue-5.12/ext4-annotate-data-race-in-start_this_handle.patch @@ -0,0 +1,39 @@ +From 3b1833e92baba135923af4a07e73fe6e54be5a2f Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 6 Apr 2021 18:17:59 +0200 +Subject: ext4: annotate data race in start_this_handle() + +From: Jan Kara + +commit 3b1833e92baba135923af4a07e73fe6e54be5a2f upstream. + +Access to journal->j_running_transaction is not protected by appropriate +lock and thus is racy. We are well aware of that and the code handles +the race properly. Just add a comment and data_race() annotation. + +Cc: stable@kernel.org +Reported-by: syzbot+30774a6acf6a2cf6d535@syzkaller.appspotmail.com +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20210406161804.20150-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/jbd2/transaction.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -349,7 +349,12 @@ static int start_this_handle(journal_t * + } + + alloc_transaction: +- if (!journal->j_running_transaction) { ++ /* ++ * This check is racy but it is just an optimization of allocating new ++ * transaction early if there are high chances we'll need it. If we ++ * guess wrong, we'll retry or free unused transaction. ++ */ ++ if (!data_race(journal->j_running_transaction)) { + /* + * If __GFP_FS is not present, then we may be being called from + * inside the fs writeback layer, so we MUST NOT fail. diff --git a/queue-5.12/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch b/queue-5.12/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch new file mode 100644 index 00000000000..7ca4ebcf4e8 --- /dev/null +++ b/queue-5.12/ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch @@ -0,0 +1,49 @@ +From 72ffb49a7b623c92a37657eda7cc46a06d3e8398 Mon Sep 17 00:00:00 2001 +From: Zhang Yi +Date: Wed, 31 Mar 2021 11:31:38 +0800 +Subject: ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() + +From: Zhang Yi + +commit 72ffb49a7b623c92a37657eda7cc46a06d3e8398 upstream. + +When CONFIG_QUOTA is enabled, if we failed to mount the filesystem due +to some error happens behind ext4_orphan_cleanup(), it will end up +triggering a after free issue of super_block. The problem is that +ext4_orphan_cleanup() will set SB_ACTIVE flag if CONFIG_QUOTA is +enabled, after we cleanup the truncated inodes, the last iput() will put +them into the lru list, and these inodes' pages may probably dirty and +will be write back by the writeback thread, so it could be raced by +freeing super_block in the error path of mount_bdev(). + +After check the setting of SB_ACTIVE flag in ext4_orphan_cleanup(), it +was used to ensure updating the quota file properly, but evict inode and +trash data immediately in the last iput does not affect the quotafile, +so setting the SB_ACTIVE flag seems not required[1]. Fix this issue by +just remove the SB_ACTIVE setting. + +[1] https://lore.kernel.org/linux-ext4/99cce8ca-e4a0-7301-840f-2ace67c551f3@huawei.com/T/#m04990cfbc4f44592421736b504afcc346b2a7c00 + +Cc: stable@kernel.org +Signed-off-by: Zhang Yi +Tested-by: Jan Kara +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20210331033138.918975-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3023,9 +3023,6 @@ static void ext4_orphan_cleanup(struct s + sb->s_flags &= ~SB_RDONLY; + } + #ifdef CONFIG_QUOTA +- /* Needed for iput() to work correctly and not trash data */ +- sb->s_flags |= SB_ACTIVE; +- + /* + * Turn on quotas which were not enabled for read-only mounts if + * filesystem has quota feature, so that they are updated correctly. diff --git a/queue-5.12/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch b/queue-5.12/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch new file mode 100644 index 00000000000..7f4f5005c37 --- /dev/null +++ b/queue-5.12/ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch @@ -0,0 +1,96 @@ +From a149d2a5cabbf6507a7832a1c4fd2593c55fd450 Mon Sep 17 00:00:00 2001 +From: Zhang Yi +Date: Wed, 31 Mar 2021 20:15:16 +0800 +Subject: ext4: fix check to prevent false positive report of incorrect used inodes + +From: Zhang Yi + +commit a149d2a5cabbf6507a7832a1c4fd2593c55fd450 upstream. + +Commit <50122847007> ("ext4: fix check to prevent initializing reserved +inodes") check the block group zero and prevent initializing reserved +inodes. But in some special cases, the reserved inode may not all belong +to the group zero, it may exist into the second group if we format +filesystem below. + + mkfs.ext4 -b 4096 -g 8192 -N 1024 -I 4096 /dev/sda + +So, it will end up triggering a false positive report of a corrupted +file system. This patch fix it by avoid check reserved inodes if no free +inode blocks will be zeroed. + +Cc: stable@kernel.org +Fixes: 50122847007 ("ext4: fix check to prevent initializing reserved inodes") +Signed-off-by: Zhang Yi +Suggested-by: Jan Kara +Link: https://lore.kernel.org/r/20210331121516.2243099-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ialloc.c | 48 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1513,6 +1513,7 @@ int ext4_init_inode_table(struct super_b + handle_t *handle; + ext4_fsblk_t blk; + int num, ret = 0, used_blks = 0; ++ unsigned long used_inos = 0; + + /* This should not happen, but just to be sure check this */ + if (sb_rdonly(sb)) { +@@ -1543,22 +1544,37 @@ int ext4_init_inode_table(struct super_b + * used inodes so we need to skip blocks with used inodes in + * inode table. + */ +- if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) +- used_blks = DIV_ROUND_UP((EXT4_INODES_PER_GROUP(sb) - +- ext4_itable_unused_count(sb, gdp)), +- sbi->s_inodes_per_block); +- +- if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) || +- ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) - +- ext4_itable_unused_count(sb, gdp)) < +- EXT4_FIRST_INO(sb)))) { +- ext4_error(sb, "Something is wrong with group %u: " +- "used itable blocks: %d; " +- "itable unused count: %u", +- group, used_blks, +- ext4_itable_unused_count(sb, gdp)); +- ret = 1; +- goto err_out; ++ if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) { ++ used_inos = EXT4_INODES_PER_GROUP(sb) - ++ ext4_itable_unused_count(sb, gdp); ++ used_blks = DIV_ROUND_UP(used_inos, sbi->s_inodes_per_block); ++ ++ /* Bogus inode unused count? */ ++ if (used_blks < 0 || used_blks > sbi->s_itb_per_group) { ++ ext4_error(sb, "Something is wrong with group %u: " ++ "used itable blocks: %d; " ++ "itable unused count: %u", ++ group, used_blks, ++ ext4_itable_unused_count(sb, gdp)); ++ ret = 1; ++ goto err_out; ++ } ++ ++ used_inos += group * EXT4_INODES_PER_GROUP(sb); ++ /* ++ * Are there some uninitialized inodes in the inode table ++ * before the first normal inode? ++ */ ++ if ((used_blks != sbi->s_itb_per_group) && ++ (used_inos < EXT4_FIRST_INO(sb))) { ++ ext4_error(sb, "Something is wrong with group %u: " ++ "itable unused count: %u; " ++ "itables initialized count: %ld", ++ group, ext4_itable_unused_count(sb, gdp), ++ used_inos); ++ ret = 1; ++ goto err_out; ++ } + } + + blk = ext4_inode_table(sb, gdp) + used_blks; diff --git a/queue-5.12/ext4-fix-error-code-in-ext4_commit_super.patch b/queue-5.12/ext4-fix-error-code-in-ext4_commit_super.patch new file mode 100644 index 00000000000..78bd28356b8 --- /dev/null +++ b/queue-5.12/ext4-fix-error-code-in-ext4_commit_super.patch @@ -0,0 +1,38 @@ +From f88f1466e2a2e5ca17dfada436d3efa1b03a3972 Mon Sep 17 00:00:00 2001 +From: Fengnan Chang +Date: Fri, 2 Apr 2021 18:16:31 +0800 +Subject: ext4: fix error code in ext4_commit_super + +From: Fengnan Chang + +commit f88f1466e2a2e5ca17dfada436d3efa1b03a3972 upstream. + +We should set the error code when ext4_commit_super check argument failed. +Found in code review. +Fixes: c4be0c1dc4cdc ("filesystem freeze: add error handling of write_super_lockfs/unlockfs"). + +Cc: stable@kernel.org +Signed-off-by: Fengnan Chang +Reviewed-by: Andreas Dilger +Link: https://lore.kernel.org/r/20210402101631.561-1-changfengnan@vivo.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -5559,8 +5559,10 @@ static int ext4_commit_super(struct supe + struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; + int error = 0; + +- if (!sbh || block_device_ejected(sb)) +- return error; ++ if (!sbh) ++ return -EINVAL; ++ if (block_device_ejected(sb)) ++ return -ENODEV; + + ext4_update_super(sb); + diff --git a/queue-5.12/ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch b/queue-5.12/ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch new file mode 100644 index 00000000000..02530f5fc71 --- /dev/null +++ b/queue-5.12/ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch @@ -0,0 +1,37 @@ +From e1262cd2e68a0870fb9fc95eb202d22e8f0074b7 Mon Sep 17 00:00:00 2001 +From: Xu Yihang +Date: Thu, 8 Apr 2021 15:00:33 +0800 +Subject: ext4: fix error return code in ext4_fc_perform_commit() + +From: Xu Yihang + +commit e1262cd2e68a0870fb9fc95eb202d22e8f0074b7 upstream. + +In case of if not ext4_fc_add_tlv branch, an error return code is missing. + +Cc: stable@kernel.org +Fixes: aa75f4d3daae ("ext4: main fast-commit commit path") +Reported-by: Hulk Robot +Signed-off-by: Xu Yihang +Reviewed-by: Harshad Shirwadkar +Link: https://lore.kernel.org/r/20210408070033.123047-1-xuyihang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/fast_commit.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1088,8 +1088,10 @@ static int ext4_fc_perform_commit(journa + head.fc_tid = cpu_to_le32( + sbi->s_journal->j_running_transaction->t_tid); + if (!ext4_fc_add_tlv(sb, EXT4_FC_TAG_HEAD, sizeof(head), +- (u8 *)&head, &crc)) ++ (u8 *)&head, &crc)) { ++ ret = -ENOSPC; + goto out; ++ } + } + + spin_lock(&sbi->s_fc_lock); diff --git a/queue-5.12/ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch b/queue-5.12/ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch new file mode 100644 index 00000000000..93213099f21 --- /dev/null +++ b/queue-5.12/ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch @@ -0,0 +1,35 @@ +From 6810fad956df9e5467e8e8a5ac66fda0836c71fa Mon Sep 17 00:00:00 2001 +From: Ye Bin +Date: Tue, 6 Apr 2021 10:53:31 +0800 +Subject: ext4: fix ext4_error_err save negative errno into superblock + +From: Ye Bin + +commit 6810fad956df9e5467e8e8a5ac66fda0836c71fa upstream. + +Fix As write_mmp_block() so that it returns -EIO instead of 1, so that +the correct error gets saved into the superblock. + +Cc: stable@kernel.org +Fixes: 54d3adbc29f0 ("ext4: save all error info in save_error_info() and drop ext4_set_errno()") +Reported-by: Liu Zhi Qiang +Signed-off-by: Ye Bin +Reviewed-by: Andreas Dilger +Link: https://lore.kernel.org/r/20210406025331.148343-1-yebin10@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/mmp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/mmp.c ++++ b/fs/ext4/mmp.c +@@ -56,7 +56,7 @@ static int write_mmp_block(struct super_ + wait_on_buffer(bh); + sb_end_write(sb); + if (unlikely(!buffer_uptodate(bh))) +- return 1; ++ return -EIO; + + return 0; + } diff --git a/queue-5.12/ext4-fix-occasional-generic-418-failure.patch b/queue-5.12/ext4-fix-occasional-generic-418-failure.patch new file mode 100644 index 00000000000..445c4163f87 --- /dev/null +++ b/queue-5.12/ext4-fix-occasional-generic-418-failure.patch @@ -0,0 +1,80 @@ +From 5899593f51e63dde2f07c67358bd65a641585abb Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 15 Apr 2021 17:54:17 +0200 +Subject: ext4: Fix occasional generic/418 failure + +From: Jan Kara + +commit 5899593f51e63dde2f07c67358bd65a641585abb upstream. + +Eric has noticed that after pagecache read rework, generic/418 is +occasionally failing for ext4 when blocksize < pagesize. In fact, the +pagecache rework just made hard to hit race in ext4 more likely. The +problem is that since ext4 conversion of direct IO writes to iomap +framework (commit 378f32bab371), we update inode size after direct IO +write only after invalidating page cache. Thus if buffered read sneaks +at unfortunate moment like: + +CPU1 - write at offset 1k CPU2 - read from offset 0 +iomap_dio_rw(..., IOMAP_DIO_FORCE_WAIT); + ext4_readpage(); +ext4_handle_inode_extension() + +the read will zero out tail of the page as it still sees smaller inode +size and thus page cache becomes inconsistent with on-disk contents with +all the consequences. + +Fix the problem by moving inode size update into end_io handler which +gets called before the page cache is invalidated. + +Reported-and-tested-by: Eric Whitney +Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure") +CC: stable@vger.kernel.org +Signed-off-by: Jan Kara +Acked-by: Dave Chinner +Link: https://lore.kernel.org/r/20210415155417.4734-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/file.c | 25 +++++++++++++++++++++---- + 1 file changed, 21 insertions(+), 4 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -371,15 +371,32 @@ truncate: + static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size, + int error, unsigned int flags) + { +- loff_t offset = iocb->ki_pos; ++ loff_t pos = iocb->ki_pos; + struct inode *inode = file_inode(iocb->ki_filp); + + if (error) + return error; + +- if (size && flags & IOMAP_DIO_UNWRITTEN) +- return ext4_convert_unwritten_extents(NULL, inode, +- offset, size); ++ if (size && flags & IOMAP_DIO_UNWRITTEN) { ++ error = ext4_convert_unwritten_extents(NULL, inode, pos, size); ++ if (error < 0) ++ return error; ++ } ++ /* ++ * If we are extending the file, we have to update i_size here before ++ * page cache gets invalidated in iomap_dio_rw(). Otherwise racing ++ * buffered reads could zero out too much from page cache pages. Update ++ * of on-disk size will happen later in ext4_dio_write_iter() where ++ * we have enough information to also perform orphan list handling etc. ++ * Note that we perform all extending writes synchronously under ++ * i_rwsem held exclusively so i_size update is safe here in that case. ++ * If the write was not extending, we cannot see pos > i_size here ++ * because operations reducing i_size like truncate wait for all ++ * outstanding DIO before updating i_size. ++ */ ++ pos += size; ++ if (pos > i_size_read(inode)) ++ i_size_write(inode, pos); + + return 0; + } diff --git a/queue-5.12/io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch b/queue-5.12/io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch new file mode 100644 index 00000000000..cc4d38e8efb --- /dev/null +++ b/queue-5.12/io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch @@ -0,0 +1,43 @@ +From 6d042ffb598ed83e7d5623cc961d249def5b9829 Mon Sep 17 00:00:00 2001 +From: Palash Oswal +Date: Tue, 27 Apr 2021 18:21:49 +0530 +Subject: io_uring: Check current->io_uring in io_uring_cancel_sqpoll + +From: Palash Oswal + +commit 6d042ffb598ed83e7d5623cc961d249def5b9829 upstream. + +syzkaller identified KASAN: null-ptr-deref Write in +io_uring_cancel_sqpoll. + +io_uring_cancel_sqpoll is called by io_sq_thread before calling +io_uring_alloc_task_context. This leads to current->io_uring being NULL. +io_uring_cancel_sqpoll should not have to deal with threads where +current->io_uring is NULL. + +In order to cast a wider safety net, perform input sanitisation directly +in io_uring_cancel_sqpoll and return for NULL value of current->io_uring. +This is safe since if current->io_uring isn't set, then there's no way +for the task to have submitted any requests. + +Reported-by: syzbot+be51ca5a4d97f017cd50@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Palash Oswal +Link: https://lore.kernel.org/r/20210427125148.21816-1-hello@oswalpalash.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -9005,6 +9005,8 @@ static void io_uring_cancel_sqpoll(struc + s64 inflight; + DEFINE_WAIT(wait); + ++ if (!current->io_uring) ++ return; + WARN_ON_ONCE(!sqd || sqd->thread != current); + + atomic_inc(&tctx->in_idle); diff --git a/queue-5.12/io_uring-fix-shared-sqpoll-cancellation-hangs.patch b/queue-5.12/io_uring-fix-shared-sqpoll-cancellation-hangs.patch new file mode 100644 index 00000000000..7a225b35419 --- /dev/null +++ b/queue-5.12/io_uring-fix-shared-sqpoll-cancellation-hangs.patch @@ -0,0 +1,132 @@ +From 734551df6f9bedfbefcd113ede665945e9de0b99 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Sun, 18 Apr 2021 14:52:09 +0100 +Subject: io_uring: fix shared sqpoll cancellation hangs + +From: Pavel Begunkov + +commit 734551df6f9bedfbefcd113ede665945e9de0b99 upstream. + +[ 736.982891] INFO: task iou-sqp-4294:4295 blocked for more than 122 seconds. +[ 736.982897] Call Trace: +[ 736.982901] schedule+0x68/0xe0 +[ 736.982903] io_uring_cancel_sqpoll+0xdb/0x110 +[ 736.982908] io_sqpoll_cancel_cb+0x24/0x30 +[ 736.982911] io_run_task_work_head+0x28/0x50 +[ 736.982913] io_sq_thread+0x4e3/0x720 + +We call io_uring_cancel_sqpoll() one by one for each ctx either in +sq_thread() itself or via task works, and it's intended to cancel all +requests of a specified context. However the function uses per-task +counters to track the number of inflight requests, so it counts more +requests than available via currect io_uring ctx and goes to sleep for +them to appear (e.g. from IRQ), that will never happen. + +Cancel a bit more than before, i.e. all ctxs that share sqpoll +and continue to use shared counters. Don't forget that we should not +remove ctx from the list before running that task_work sqpoll-cancel, +otherwise the function wouldn't be able to find the context and will +hang. + +Reported-by: Joakim Hassila +Reported-by: Jens Axboe +Fixes: 37d1e2e3642e2 ("io_uring: move SQPOLL thread io-wq forked worker") +Cc: stable@vger.kernel.org +Signed-off-by: Pavel Begunkov +Link: https://lore.kernel.org/r/1bded7e6c6b32e0bae25fce36be2868e46b116a0.1618752958.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -1008,7 +1008,7 @@ static void io_uring_del_task_file(unsig + static void io_uring_try_cancel_requests(struct io_ring_ctx *ctx, + struct task_struct *task, + struct files_struct *files); +-static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx); ++static void io_uring_cancel_sqpoll(struct io_sq_data *sqd); + static void destroy_fixed_rsrc_ref_node(struct fixed_rsrc_ref_node *ref_node); + static struct fixed_rsrc_ref_node *alloc_fixed_rsrc_ref_node( + struct io_ring_ctx *ctx); +@@ -6836,15 +6836,14 @@ static int io_sq_thread(void *data) + timeout = jiffies + sqd->sq_thread_idle; + } + +- list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) +- io_uring_cancel_sqpoll(ctx); ++ io_uring_cancel_sqpoll(sqd); + sqd->thread = NULL; + list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) + io_ring_set_wakeup_flag(ctx); +- mutex_unlock(&sqd->lock); +- + io_run_task_work(); + io_run_task_work_head(&sqd->park_task_work); ++ mutex_unlock(&sqd->lock); ++ + complete(&sqd->exited); + do_exit(0); + } +@@ -8931,11 +8930,11 @@ static s64 tctx_inflight(struct io_uring + static void io_sqpoll_cancel_cb(struct callback_head *cb) + { + struct io_tctx_exit *work = container_of(cb, struct io_tctx_exit, task_work); +- struct io_ring_ctx *ctx = work->ctx; +- struct io_sq_data *sqd = ctx->sq_data; ++ struct io_sq_data *sqd = work->ctx->sq_data; + + if (sqd->thread) +- io_uring_cancel_sqpoll(ctx); ++ io_uring_cancel_sqpoll(sqd); ++ list_del_init(&work->ctx->sqd_list); + complete(&work->completion); + } + +@@ -8946,7 +8945,6 @@ static void io_sqpoll_cancel_sync(struct + struct task_struct *task; + + io_sq_thread_park(sqd); +- list_del_init(&ctx->sqd_list); + io_sqd_update_thread_idle(sqd); + task = sqd->thread; + if (task) { +@@ -8954,6 +8952,8 @@ static void io_sqpoll_cancel_sync(struct + init_task_work(&work.task_work, io_sqpoll_cancel_cb); + io_task_work_add_head(&sqd->park_task_work, &work.task_work); + wake_up_process(task); ++ } else { ++ list_del_init(&ctx->sqd_list); + } + io_sq_thread_unpark(sqd); + +@@ -8987,14 +8987,14 @@ void __io_uring_files_cancel(struct file + } + + /* should only be called by SQPOLL task */ +-static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx) ++static void io_uring_cancel_sqpoll(struct io_sq_data *sqd) + { +- struct io_sq_data *sqd = ctx->sq_data; + struct io_uring_task *tctx = current->io_uring; ++ struct io_ring_ctx *ctx; + s64 inflight; + DEFINE_WAIT(wait); + +- WARN_ON_ONCE(!sqd || ctx->sq_data->thread != current); ++ WARN_ON_ONCE(!sqd || sqd->thread != current); + + atomic_inc(&tctx->in_idle); + do { +@@ -9002,7 +9002,8 @@ static void io_uring_cancel_sqpoll(struc + inflight = tctx_inflight(tctx); + if (!inflight) + break; +- io_uring_try_cancel_requests(ctx, current, NULL); ++ list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) ++ io_uring_try_cancel_requests(ctx, current, NULL); + + prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE); + /* diff --git a/queue-5.12/io_uring-fix-work_exit-sqpoll-cancellations.patch b/queue-5.12/io_uring-fix-work_exit-sqpoll-cancellations.patch new file mode 100644 index 00000000000..acbdcfed95b --- /dev/null +++ b/queue-5.12/io_uring-fix-work_exit-sqpoll-cancellations.patch @@ -0,0 +1,78 @@ +From 28090c133869b461c5366195a856d73469ab87d9 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Sun, 25 Apr 2021 23:34:45 +0100 +Subject: io_uring: fix work_exit sqpoll cancellations + +From: Pavel Begunkov + +commit 28090c133869b461c5366195a856d73469ab87d9 upstream. + +After closing an SQPOLL ring, io_ring_exit_work() kicks in and starts +doing cancellations via io_uring_try_cancel_requests(). It will go +through io_uring_try_cancel_iowq(), which uses ctx->tctx_list, but as +SQPOLL task don't have a ctx note, its io-wq won't be reachable and so +is left not cancelled. + +It will eventually cancelled when one of the tasks dies, but if a thread +group survives for long and changes rings, it will spawn lots of +unreclaimed resources and live locked works. + +Cancel SQPOLL task's io-wq separately in io_ring_exit_work(). + +Cc: stable@vger.kernel.org +Signed-off-by: Pavel Begunkov +Link: https://lore.kernel.org/r/a71a7fe345135d684025bb529d5cb1d8d6b46e10.1619389911.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -8571,6 +8571,13 @@ static void io_tctx_exit_cb(struct callb + complete(&work->completion); + } + ++static bool io_cancel_ctx_cb(struct io_wq_work *work, void *data) ++{ ++ struct io_kiocb *req = container_of(work, struct io_kiocb, work); ++ ++ return req->ctx == data; ++} ++ + static void io_ring_exit_work(struct work_struct *work) + { + struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, exit_work); +@@ -8587,6 +8594,17 @@ static void io_ring_exit_work(struct wor + */ + do { + io_uring_try_cancel_requests(ctx, NULL, NULL); ++ if (ctx->sq_data) { ++ struct io_sq_data *sqd = ctx->sq_data; ++ struct task_struct *tsk; ++ ++ io_sq_thread_park(sqd); ++ tsk = sqd->thread; ++ if (tsk && tsk->io_uring && tsk->io_uring->io_wq) ++ io_wq_cancel_cb(tsk->io_uring->io_wq, ++ io_cancel_ctx_cb, ctx, true); ++ io_sq_thread_unpark(sqd); ++ } + + WARN_ON_ONCE(time_after(jiffies, timeout)); + } while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)); +@@ -8731,13 +8749,6 @@ static bool io_cancel_defer_files(struct + return true; + } + +-static bool io_cancel_ctx_cb(struct io_wq_work *work, void *data) +-{ +- struct io_kiocb *req = container_of(work, struct io_kiocb, work); +- +- return req->ctx == data; +-} +- + static bool io_uring_try_cancel_iowq(struct io_ring_ctx *ctx) + { + struct io_tctx_node *node; diff --git a/queue-5.12/io_uring-remove-extra-sqpoll-submission-halting.patch b/queue-5.12/io_uring-remove-extra-sqpoll-submission-halting.patch new file mode 100644 index 00000000000..a2c1523c7d4 --- /dev/null +++ b/queue-5.12/io_uring-remove-extra-sqpoll-submission-halting.patch @@ -0,0 +1,51 @@ +From 3b763ba1c77da5806e4fdc5684285814fe970c98 Mon Sep 17 00:00:00 2001 +From: Pavel Begunkov +Date: Sun, 18 Apr 2021 14:52:08 +0100 +Subject: io_uring: remove extra sqpoll submission halting + +From: Pavel Begunkov + +commit 3b763ba1c77da5806e4fdc5684285814fe970c98 upstream. + +SQPOLL task won't submit requests for a context that is currently dying, +so no need to remove ctx from sqd_list prior the main loop of +io_ring_exit_work(). Kill it, will be removed by io_sq_thread_finish() +and only brings confusion and lockups. + +Cc: stable@vger.kernel.org +Signed-off-by: Pavel Begunkov +Link: https://lore.kernel.org/r/f220c2b786ba0f9499bebc9f3cd9714d29efb6a5.1618752958.git.asml.silence@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + fs/io_uring.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -6710,6 +6710,10 @@ static int __io_sq_thread(struct io_ring + if (!list_empty(&ctx->iopoll_list)) + io_do_iopoll(ctx, &nr_events, 0); + ++ /* ++ * Don't submit if refs are dying, good for io_uring_register(), ++ * but also it is relied upon by io_ring_exit_work() ++ */ + if (to_submit && likely(!percpu_ref_is_dying(&ctx->refs)) && + !(ctx->flags & IORING_SETUP_R_DISABLED)) + ret = io_submit_sqes(ctx, to_submit); +@@ -8576,14 +8580,6 @@ static void io_ring_exit_work(struct wor + struct io_tctx_node *node; + int ret; + +- /* prevent SQPOLL from submitting new requests */ +- if (ctx->sq_data) { +- io_sq_thread_park(ctx->sq_data); +- list_del_init(&ctx->sqd_list); +- io_sqd_update_thread_idle(ctx->sq_data); +- io_sq_thread_unpark(ctx->sq_data); +- } +- + /* + * If we're doing polled IO and end up having requests being + * submitted async (out-of-line), then completions can come in while diff --git a/queue-5.12/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch b/queue-5.12/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch new file mode 100644 index 00000000000..70165ef3b31 --- /dev/null +++ b/queue-5.12/kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch @@ -0,0 +1,88 @@ +From 46b41d5dd8019b264717978c39c43313a524d033 Mon Sep 17 00:00:00 2001 +From: Masahiro Yamada +Date: Sun, 25 Apr 2021 15:24:07 +0900 +Subject: kbuild: update config_data.gz only when the content of .config is changed + +From: Masahiro Yamada + +commit 46b41d5dd8019b264717978c39c43313a524d033 upstream. + +If the timestamp of the .config file is updated, config_data.gz is +regenerated, then vmlinux is re-linked. This occurs even if the content +of the .config has not changed at all. + +This issue was mitigated by commit 67424f61f813 ("kconfig: do not write +.config if the content is the same"); Kconfig does not update the +.config when it ends up with the identical configuration. + +The issue is remaining when the .config is created by *_defconfig with +some config fragment(s) applied on top. + +This is typical for powerpc and mips, where several *_defconfig targets +are constructed by using merge_config.sh. + +One workaround is to have the copy of the .config. The filechk rule +updates the copy, kernel/config_data, by checking the content instead +of the timestamp. + +With this commit, the second run with the same configuration avoids +the needless rebuilds. + + $ make ARCH=mips defconfig all + [ snip ] + $ make ARCH=mips defconfig all + *** Default configuration is based on target '32r2el_defconfig' + Using ./arch/mips/configs/generic_defconfig as base + Merging arch/mips/configs/generic/32r2.config + Merging arch/mips/configs/generic/el.config + Merging ./arch/mips/configs/generic/board-boston.config + Merging ./arch/mips/configs/generic/board-ni169445.config + Merging ./arch/mips/configs/generic/board-ocelot.config + Merging ./arch/mips/configs/generic/board-ranchu.config + Merging ./arch/mips/configs/generic/board-sead-3.config + Merging ./arch/mips/configs/generic/board-xilfpga.config + # + # configuration written to .config + # + SYNC include/config/auto.conf + CALL scripts/checksyscalls.sh + CALL scripts/atomic/check-atomics.sh + CHK include/generated/compile.h + CHK include/generated/autoksyms.h + +Reported-by: Elliot Berman +Signed-off-by: Masahiro Yamada +Signed-off-by: Greg Kroah-Hartman +--- + kernel/.gitignore | 1 + + kernel/Makefile | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/kernel/.gitignore ++++ b/kernel/.gitignore +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only ++/config_data + kheaders.md5 + timeconst.h + hz.bc +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -138,10 +138,15 @@ obj-$(CONFIG_SCF_TORTURE_TEST) += scftor + + $(obj)/configs.o: $(obj)/config_data.gz + +-targets += config_data.gz +-$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE ++targets += config_data config_data.gz ++$(obj)/config_data.gz: $(obj)/config_data FORCE + $(call if_changed,gzip) + ++filechk_cat = cat $< ++ ++$(obj)/config_data: $(KCONFIG_CONFIG) FORCE ++ $(call filechk,cat) ++ + $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz + + quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz diff --git a/queue-5.12/media-coda-fix-macroblocks-count-control-usage.patch b/queue-5.12/media-coda-fix-macroblocks-count-control-usage.patch new file mode 100644 index 00000000000..95f24d6173d --- /dev/null +++ b/queue-5.12/media-coda-fix-macroblocks-count-control-usage.patch @@ -0,0 +1,40 @@ +From 0b276e470a4d43e1365d3eb53c608a3d208cabd4 Mon Sep 17 00:00:00 2001 +From: Marco Felsch +Date: Fri, 5 Mar 2021 09:23:54 +0100 +Subject: media: coda: fix macroblocks count control usage + +From: Marco Felsch + +commit 0b276e470a4d43e1365d3eb53c608a3d208cabd4 upstream. + +Commit b2d3bef1aa78 ("media: coda: Add a V4L2 user for control error +macroblocks count") add the control for the decoder devices. But +during streamon() this ioctl gets called for all (encoder and decoder) +devices and on encoder devices this causes a null pointer exception. + +Fix this by setting the control only if it is really accessible. + +Fixes: b2d3bef1aa78 ("media: coda: Add a V4L2 user for control error macroblocks count") +Signed-off-by: Marco Felsch +Cc: +Reviewed-by: Philipp Zabel +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/coda/coda-common.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/media/platform/coda/coda-common.c ++++ b/drivers/media/platform/coda/coda-common.c +@@ -2062,7 +2062,9 @@ static int coda_start_streaming(struct v + if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) + ctx->params.gop_size = 1; + ctx->gopcounter = ctx->params.gop_size - 1; +- v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0); ++ /* Only decoders have this control */ ++ if (ctx->mb_err_cnt_ctrl) ++ v4l2_ctrl_s_ctrl(ctx->mb_err_cnt_ctrl, 0); + + ret = ctx->ops->start_streaming(ctx); + if (ctx->inst_type == CODA_INST_DECODER) { diff --git a/queue-5.12/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch b/queue-5.12/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch new file mode 100644 index 00000000000..8c6ee88e244 --- /dev/null +++ b/queue-5.12/media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch @@ -0,0 +1,120 @@ +From 13a79f14ab285120bc4977e00a7c731e8143f548 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 1 Feb 2021 09:32:46 +0100 +Subject: media: dvb-usb: Fix memory leak at error in dvb_usb_device_init() + +From: Takashi Iwai + +commit 13a79f14ab285120bc4977e00a7c731e8143f548 upstream. + +dvb_usb_device_init() allocates a dvb_usb_device object, but it +doesn't release the object by itself even at errors. The object is +released in the callee side (dvb_usb_init()) in some error cases via +dvb_usb_exit() call, but it also missed the object free in other error +paths. And, the caller (it's only dvb_usb_device_init()) doesn't seem +caring the resource management as well, hence those memories are +leaked. + +This patch assures releasing the memory at the error path in +dvb_usb_device_init(). Now dvb_usb_init() frees the resources it +allocated but leaves the passed dvb_usb_device object intact. In +turn, the dvb_usb_device object is released in dvb_usb_device_init() +instead. +We could use dvb_usb_exit() function for releasing everything in the +callee (as it was used for some error cases in the original code), but +releasing the passed object in the callee is non-intuitive and +error-prone. So I took this approach (which is more standard in Linus +kernel code) although it ended with a bit more open codes. + +Along with the change, the patch makes sure that USB intfdata is reset +and don't return the bogus pointer to the caller of +dvb_usb_device_init() at the error path, too. + +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb/dvb-usb-init.c | 47 ++++++++++++++++++++----------- + 1 file changed, 31 insertions(+), 16 deletions(-) + +--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c +@@ -170,22 +170,20 @@ static int dvb_usb_init(struct dvb_usb_d + + if (d->props.priv_init != NULL) { + ret = d->props.priv_init(d); +- if (ret != 0) { +- kfree(d->priv); +- d->priv = NULL; +- return ret; +- } ++ if (ret != 0) ++ goto err_priv_init; + } + } + + /* check the capabilities and set appropriate variables */ + dvb_usb_device_power_ctrl(d, 1); + +- if ((ret = dvb_usb_i2c_init(d)) || +- (ret = dvb_usb_adapter_init(d, adapter_nums))) { +- dvb_usb_exit(d); +- return ret; +- } ++ ret = dvb_usb_i2c_init(d); ++ if (ret) ++ goto err_i2c_init; ++ ret = dvb_usb_adapter_init(d, adapter_nums); ++ if (ret) ++ goto err_adapter_init; + + if ((ret = dvb_usb_remote_init(d))) + err("could not initialize remote control."); +@@ -193,6 +191,17 @@ static int dvb_usb_init(struct dvb_usb_d + dvb_usb_device_power_ctrl(d, 0); + + return 0; ++ ++err_adapter_init: ++ dvb_usb_adapter_exit(d); ++err_i2c_init: ++ dvb_usb_i2c_exit(d); ++ if (d->priv && d->props.priv_destroy) ++ d->props.priv_destroy(d); ++err_priv_init: ++ kfree(d->priv); ++ d->priv = NULL; ++ return ret; + } + + /* determine the name and the state of the just found USB device */ +@@ -296,15 +305,21 @@ int dvb_usb_device_init(struct usb_inter + + usb_set_intfdata(intf, d); + +- if (du != NULL) ++ ret = dvb_usb_init(d, adapter_nums); ++ if (ret) { ++ info("%s error while loading driver (%d)", desc->name, ret); ++ goto error; ++ } ++ ++ if (du) + *du = d; + +- ret = dvb_usb_init(d, adapter_nums); ++ info("%s successfully initialized and connected.", desc->name); ++ return 0; + +- if (ret == 0) +- info("%s successfully initialized and connected.", desc->name); +- else +- info("%s error while loading driver (%d)", desc->name, ret); ++ error: ++ usb_set_intfdata(intf, NULL); ++ kfree(d); + return ret; + } + EXPORT_SYMBOL(dvb_usb_device_init); diff --git a/queue-5.12/media-dvb-usb-fix-use-after-free-access.patch b/queue-5.12/media-dvb-usb-fix-use-after-free-access.patch new file mode 100644 index 00000000000..0790a7b120b --- /dev/null +++ b/queue-5.12/media-dvb-usb-fix-use-after-free-access.patch @@ -0,0 +1,76 @@ +From c49206786ee252f28b7d4d155d1fff96f145a05d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 1 Feb 2021 09:32:47 +0100 +Subject: media: dvb-usb: Fix use-after-free access + +From: Takashi Iwai + +commit c49206786ee252f28b7d4d155d1fff96f145a05d upstream. + +dvb_usb_device_init() copies the properties to the own data, so that +the callers can release the original properties later (as done in the +commit 299c7007e936 ("media: dw2102: Fix memleak on sequence of +probes")). However, it also stores dev->desc pointer that is a +reference to the original properties data. Since dev->desc is +referred later, it may result in use-after-free, in the worst case, +leading to a kernel Oops as reported. + +This patch addresses the problem by allocating and copying the +properties at first, then get the desc from the copied properties. + +Reported-and-tested-by: Stefan Seyfried +BugLink: http://bugzilla.opensuse.org/show_bug.cgi?id=1181104 + +Reviewed-by: Robert Foss +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb/dvb-usb-init.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c +@@ -267,27 +267,30 @@ int dvb_usb_device_init(struct usb_inter + if (du != NULL) + *du = NULL; + +- if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { ++ d = kzalloc(sizeof(*d), GFP_KERNEL); ++ if (!d) { ++ err("no memory for 'struct dvb_usb_device'"); ++ return -ENOMEM; ++ } ++ ++ memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); ++ ++ desc = dvb_usb_find_device(udev, &d->props, &cold); ++ if (!desc) { + deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); +- return -ENODEV; ++ ret = -ENODEV; ++ goto error; + } + + if (cold) { + info("found a '%s' in cold state, will try to load a firmware", desc->name); + ret = dvb_usb_download_firmware(udev, props); + if (!props->no_reconnect || ret != 0) +- return ret; ++ goto error; + } + + info("found a '%s' in warm state.", desc->name); +- d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); +- if (d == NULL) { +- err("no memory for 'struct dvb_usb_device'"); +- return -ENOMEM; +- } +- + d->udev = udev; +- memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); + d->desc = desc; + d->owner = owner; + diff --git a/queue-5.12/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch b/queue-5.12/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch new file mode 100644 index 00000000000..01dc1dd77f0 --- /dev/null +++ b/queue-5.12/media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch @@ -0,0 +1,37 @@ +From bf9a40ae8d722f281a2721779595d6df1c33a0bf Mon Sep 17 00:00:00 2001 +From: Peilin Ye +Date: Fri, 11 Dec 2020 09:30:39 +0100 +Subject: media: dvbdev: Fix memory leak in dvb_media_device_free() + +From: Peilin Ye + +commit bf9a40ae8d722f281a2721779595d6df1c33a0bf upstream. + +dvb_media_device_free() is leaking memory. Free `dvbdev->adapter->conn` +before setting it to NULL, as documented in include/media/media-device.h: +"The media_entity instance itself must be freed explicitly by the driver +if required." + +Link: https://syzkaller.appspot.com/bug?id=9bbe4b842c98f0ed05c5eed77a226e9de33bf298 + +Link: https://lore.kernel.org/linux-media/20201211083039.521617-1-yepeilin.cs@gmail.com +Cc: stable@vger.kernel.org +Fixes: 0230d60e4661 ("[media] dvbdev: Add RF connector if needed") +Reported-by: syzbot+7f09440acc069a0d38ac@syzkaller.appspotmail.com +Signed-off-by: Peilin Ye +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/dvb-core/dvbdev.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -241,6 +241,7 @@ static void dvb_media_device_free(struct + + if (dvbdev->adapter->conn) { + media_device_unregister_entity(dvbdev->adapter->conn); ++ kfree(dvbdev->adapter->conn); + dvbdev->adapter->conn = NULL; + kfree(dvbdev->adapter->conn_pads); + dvbdev->adapter->conn_pads = NULL; diff --git a/queue-5.12/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch b/queue-5.12/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch new file mode 100644 index 00000000000..1093fc405cb --- /dev/null +++ b/queue-5.12/media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch @@ -0,0 +1,49 @@ +From 3630901933afba1d16c462b04d569b7576339223 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Mon, 15 Mar 2021 13:34:05 +0100 +Subject: media: staging/intel-ipu3: Fix memory leak in imu_fmt + +From: Ricardo Ribalda + +commit 3630901933afba1d16c462b04d569b7576339223 upstream. + +We are losing the reference to an allocated memory if try. Change the +order of the check to avoid that. + +Cc: stable@vger.kernel.org +Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -693,6 +693,13 @@ static int imgu_fmt(struct imgu_device * + if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) + continue; + ++ /* CSS expects some format on OUT queue */ ++ if (i != IPU3_CSS_QUEUE_OUT && ++ !imgu_pipe->nodes[inode].enabled) { ++ fmts[i] = NULL; ++ continue; ++ } ++ + if (try) { + fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, + sizeof(struct v4l2_pix_format_mplane), +@@ -705,10 +712,6 @@ static int imgu_fmt(struct imgu_device * + fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; + } + +- /* CSS expects some format on OUT queue */ +- if (i != IPU3_CSS_QUEUE_OUT && +- !imgu_pipe->nodes[inode].enabled) +- fmts[i] = NULL; + } + + if (!try) { diff --git a/queue-5.12/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch b/queue-5.12/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch new file mode 100644 index 00000000000..c366455dfb6 --- /dev/null +++ b/queue-5.12/media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch @@ -0,0 +1,105 @@ +From dccfe2548746ca9cca3a20401ece4cf255d1f171 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Fri, 9 Apr 2021 10:41:35 +0200 +Subject: media: staging/intel-ipu3: Fix race condition during set_fmt + +From: Ricardo Ribalda + +commit dccfe2548746ca9cca3a20401ece4cf255d1f171 upstream. + +Do not modify imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, until the +format has been correctly validated. + +Otherwise, even if we use a backup variable, there is a period of time +where imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp might have an invalid +value that can be used by other functions. + +Cc: stable@vger.kernel.org +Fixes: ad91849996f9 ("media: staging/intel-ipu3: Fix set_fmt error handling") +Reviewed-by: Tomasz Figa +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 30 ++++++++++++++---------------- + 1 file changed, 14 insertions(+), 16 deletions(-) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -669,7 +669,6 @@ static int imgu_fmt(struct imgu_device * + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; +- struct v4l2_pix_format_mplane fmt_backup; + + dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); + +@@ -687,6 +686,7 @@ static int imgu_fmt(struct imgu_device * + + dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id); + ++ css_q = imgu_node_to_queue(node); + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + unsigned int inode = imgu_map_node(imgu, i); + +@@ -701,6 +701,11 @@ static int imgu_fmt(struct imgu_device * + continue; + } + ++ if (i == css_q) { ++ fmts[i] = &f->fmt.pix_mp; ++ continue; ++ } ++ + if (try) { + fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, + sizeof(struct v4l2_pix_format_mplane), +@@ -729,39 +734,32 @@ static int imgu_fmt(struct imgu_device * + rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height; + } + +- /* +- * imgu doesn't set the node to the value given by user +- * before we return success from this function, so set it here. +- */ +- css_q = imgu_node_to_queue(node); + if (!fmts[css_q]) { + ret = -EINVAL; + goto out; + } +- fmt_backup = *fmts[css_q]; +- *fmts[css_q] = f->fmt.pix_mp; + + if (try) + ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); + else + ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); + +- if (try || ret < 0) +- *fmts[css_q] = fmt_backup; +- + /* ret is the binary number in the firmware blob */ + if (ret < 0) + goto out; + +- if (try) +- f->fmt.pix_mp = *fmts[css_q]; +- else +- f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; ++ /* ++ * imgu doesn't set the node to the value given by user ++ * before we return success from this function, so set it here. ++ */ ++ if (!try) ++ imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp; + + out: + if (try) { + for (i = 0; i < IPU3_CSS_QUEUES; i++) +- kfree(fmts[i]); ++ if (i != css_q) ++ kfree(fmts[i]); + } + + return ret; diff --git a/queue-5.12/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch b/queue-5.12/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch new file mode 100644 index 00000000000..572ae766642 --- /dev/null +++ b/queue-5.12/media-staging-intel-ipu3-fix-set_fmt-error-handling.patch @@ -0,0 +1,57 @@ +From ad91849996f9dd79741a961fd03585a683b08356 Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Wed, 10 Mar 2021 01:16:46 +0100 +Subject: media: staging/intel-ipu3: Fix set_fmt error handling + +From: Ricardo Ribalda + +commit ad91849996f9dd79741a961fd03585a683b08356 upstream. + +If there in an error during a set_fmt, do not overwrite the previous +sizes with the invalid config. + +Without this patch, v4l2-compliance ends up allocating 4GiB of RAM and +causing the following OOPs + +[ 38.662975] ipu3-imgu 0000:00:05.0: swiotlb buffer is full (sz: 4096 bytes) +[ 38.662980] DMA: Out of SW-IOMMU space for 4096 bytes at device 0000:00:05.0 +[ 38.663010] general protection fault: 0000 [#1] PREEMPT SMP + +Cc: stable@vger.kernel.org +Fixes: 6d5f26f2e045 ("media: staging/intel-ipu3-v4l: reduce kernel stack usage") +Signed-off-by: Ricardo Ribalda +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/media/ipu3/ipu3-v4l2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/staging/media/ipu3/ipu3-v4l2.c ++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c +@@ -669,6 +669,7 @@ static int imgu_fmt(struct imgu_device * + struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; ++ struct v4l2_pix_format_mplane fmt_backup; + + dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); + +@@ -737,6 +738,7 @@ static int imgu_fmt(struct imgu_device * + ret = -EINVAL; + goto out; + } ++ fmt_backup = *fmts[css_q]; + *fmts[css_q] = f->fmt.pix_mp; + + if (try) +@@ -744,6 +746,9 @@ static int imgu_fmt(struct imgu_device * + else + ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); + ++ if (try || ret < 0) ++ *fmts[css_q] = fmt_backup; ++ + /* ret is the binary number in the firmware blob */ + if (ret < 0) + goto out; diff --git a/queue-5.12/media-v4l2-ctrls-fix-reference-to-freed-memory.patch b/queue-5.12/media-v4l2-ctrls-fix-reference-to-freed-memory.patch new file mode 100644 index 00000000000..3dde09d0c6b --- /dev/null +++ b/queue-5.12/media-v4l2-ctrls-fix-reference-to-freed-memory.patch @@ -0,0 +1,330 @@ +From ac34b79da14d67a9b494f6125186becbd067e225 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 12 Apr 2021 13:51:23 +0200 +Subject: media: v4l2-ctrls: fix reference to freed memory + +From: Hans Verkuil + +commit ac34b79da14d67a9b494f6125186becbd067e225 upstream. + +When controls are used together with the Request API, then for +each request a v4l2_ctrl_handler struct is allocated. This contains +the controls that can be set in a request. If a control is *not* set in +the request, then the value used in the most recent previous request +must be used, or the current value if it is not found in any outstanding +requests. + +The framework tried to find such a previous request and it would set +the 'req' pointer in struct v4l2_ctrl_ref to the v4l2_ctrl_ref of the +control in such a previous request. So far, so good. However, when that +previous request was applied to the hardware, returned to userspace, and +then userspace would re-init or free that request, any 'ref' pointer in +still-queued requests would suddenly point to freed memory. + +This was not noticed before since the drivers that use this expected +that each request would always have the controls set, so there was +never any need to find a control in older requests. This requirement +was relaxed, and now this bug surfaced. + +It was also made worse by changeset +2fae4d6aabc8 ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req") +which increased the chance of this happening. + +The use of the 'req' pointer in v4l2_ctrl_ref was very fragile, so +drop this entirely. Instead add a valid_p_req bool to indicate that +p_req contains a valid value for this control. And if it is false, +then just use the current value of the control. + +Note that VIDIOC_G_EXT_CTRLS will always return -EACCES when attempting +to get a control from a request until the request is completed. And in +that case, all controls in the request will have the control value set +(i.e. valid_p_req is true). This means that the whole 'find the most +recent previous request containing a control' idea is pointless, and +the code can be simplified considerably. + +The v4l2_g_ext_ctrls_common() function was refactored a bit to make +it more understandable. It also avoids updating volatile controls +in a completed request since that was already done when the request +was completed. + +Signed-off-by: Hans Verkuil +Fixes: 2fae4d6aabc8 ("media: v4l2-ctrls: v4l2_ctrl_request_complete() should always set ref->req") +Fixes: 6fa6f831f095 ("media: v4l2-ctrls: add core request support") +Cc: # for v5.9 and up +Tested-by: Alexandre Courbot +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/v4l2-core/v4l2-ctrls.c | 137 ++++++++++++++++------------------- + include/media/v4l2-ctrls.h | 12 +-- + 2 files changed, 70 insertions(+), 79 deletions(-) + +--- a/drivers/media/v4l2-core/v4l2-ctrls.c ++++ b/drivers/media/v4l2-core/v4l2-ctrls.c +@@ -2397,7 +2397,16 @@ static void new_to_req(struct v4l2_ctrl_ + if (!ref) + return; + ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); +- ref->req = ref; ++ ref->valid_p_req = true; ++} ++ ++/* Copy the current value to the request value */ ++static void cur_to_req(struct v4l2_ctrl_ref *ref) ++{ ++ if (!ref) ++ return; ++ ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); ++ ref->valid_p_req = true; + } + + /* Copy the request value to the new value */ +@@ -2405,8 +2414,8 @@ static void req_to_new(struct v4l2_ctrl_ + { + if (!ref) + return; +- if (ref->req) +- ptr_to_ptr(ref->ctrl, ref->req->p_req, ref->ctrl->p_new); ++ if (ref->valid_p_req) ++ ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); + else + ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); + } +@@ -3573,39 +3582,8 @@ static void v4l2_ctrl_request_queue(stru + struct v4l2_ctrl_handler *hdl = + container_of(obj, struct v4l2_ctrl_handler, req_obj); + struct v4l2_ctrl_handler *main_hdl = obj->priv; +- struct v4l2_ctrl_handler *prev_hdl = NULL; +- struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL; + + mutex_lock(main_hdl->lock); +- if (list_empty(&main_hdl->requests_queued)) +- goto queue; +- +- prev_hdl = list_last_entry(&main_hdl->requests_queued, +- struct v4l2_ctrl_handler, requests_queued); +- /* +- * Note: prev_hdl and hdl must contain the same list of control +- * references, so if any differences are detected then that is a +- * driver bug and the WARN_ON is triggered. +- */ +- mutex_lock(prev_hdl->lock); +- ref_ctrl_prev = list_first_entry(&prev_hdl->ctrl_refs, +- struct v4l2_ctrl_ref, node); +- list_for_each_entry(ref_ctrl, &hdl->ctrl_refs, node) { +- if (ref_ctrl->req) +- continue; +- while (ref_ctrl_prev->ctrl->id < ref_ctrl->ctrl->id) { +- /* Should never happen, but just in case... */ +- if (list_is_last(&ref_ctrl_prev->node, +- &prev_hdl->ctrl_refs)) +- break; +- ref_ctrl_prev = list_next_entry(ref_ctrl_prev, node); +- } +- if (WARN_ON(ref_ctrl_prev->ctrl->id != ref_ctrl->ctrl->id)) +- break; +- ref_ctrl->req = ref_ctrl_prev->req; +- } +- mutex_unlock(prev_hdl->lock); +-queue: + list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); + hdl->request_is_queued = true; + mutex_unlock(main_hdl->lock); +@@ -3662,7 +3640,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v + { + struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); + +- return (ref && ref->req == ref) ? ref->ctrl : NULL; ++ return (ref && ref->valid_p_req) ? ref->ctrl : NULL; + } + EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); + +@@ -3848,7 +3826,13 @@ static int class_check(struct v4l2_ctrl_ + return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; + } + +-/* Get extended controls. Allocates the helpers array if needed. */ ++/* ++ * Get extended controls. Allocates the helpers array if needed. ++ * ++ * Note that v4l2_g_ext_ctrls_common() with 'which' set to ++ * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was ++ * completed, and in that case valid_p_req is true for all controls. ++ */ + static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *cs, + struct video_device *vdev) +@@ -3857,9 +3841,10 @@ static int v4l2_g_ext_ctrls_common(struc + struct v4l2_ctrl_helper *helpers = helper; + int ret; + int i, j; +- bool def_value; ++ bool is_default, is_request; + +- def_value = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); ++ is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); ++ is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); + + cs->error_idx = cs->count; + cs->which = V4L2_CTRL_ID2WHICH(cs->which); +@@ -3885,11 +3870,9 @@ static int v4l2_g_ext_ctrls_common(struc + ret = -EACCES; + + for (i = 0; !ret && i < cs->count; i++) { +- int (*ctrl_to_user)(struct v4l2_ext_control *c, +- struct v4l2_ctrl *ctrl); + struct v4l2_ctrl *master; +- +- ctrl_to_user = def_value ? def_to_user : cur_to_user; ++ bool is_volatile = false; ++ u32 idx = i; + + if (helpers[i].mref == NULL) + continue; +@@ -3899,31 +3882,48 @@ static int v4l2_g_ext_ctrls_common(struc + + v4l2_ctrl_lock(master); + +- /* g_volatile_ctrl will update the new control values */ +- if (!def_value && ++ /* ++ * g_volatile_ctrl will update the new control values. ++ * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and ++ * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests ++ * it is v4l2_ctrl_request_complete() that copies the ++ * volatile controls at the time of request completion ++ * to the request, so you don't want to do that again. ++ */ ++ if (!is_default && !is_request && + ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || + (master->has_volatiles && !is_cur_manual(master)))) { + for (j = 0; j < master->ncontrols; j++) + cur_to_new(master->cluster[j]); + ret = call_op(master, g_volatile_ctrl); +- ctrl_to_user = new_to_user; ++ is_volatile = true; + } +- /* If OK, then copy the current (for non-volatile controls) +- or the new (for volatile controls) control values to the +- caller */ +- if (!ret) { +- u32 idx = i; + +- do { +- if (helpers[idx].ref->req) +- ret = req_to_user(cs->controls + idx, +- helpers[idx].ref->req); +- else +- ret = ctrl_to_user(cs->controls + idx, +- helpers[idx].ref->ctrl); +- idx = helpers[idx].next; +- } while (!ret && idx); ++ if (ret) { ++ v4l2_ctrl_unlock(master); ++ break; + } ++ ++ /* ++ * Copy the default value (if is_default is true), the ++ * request value (if is_request is true and p_req is valid), ++ * the new volatile value (if is_volatile is true) or the ++ * current value. ++ */ ++ do { ++ struct v4l2_ctrl_ref *ref = helpers[idx].ref; ++ ++ if (is_default) ++ ret = def_to_user(cs->controls + idx, ref->ctrl); ++ else if (is_request && ref->valid_p_req) ++ ret = req_to_user(cs->controls + idx, ref); ++ else if (is_volatile) ++ ret = new_to_user(cs->controls + idx, ref->ctrl); ++ else ++ ret = cur_to_user(cs->controls + idx, ref->ctrl); ++ idx = helpers[idx].next; ++ } while (!ret && idx); ++ + v4l2_ctrl_unlock(master); + } + +@@ -4566,8 +4566,6 @@ void v4l2_ctrl_request_complete(struct m + unsigned int i; + + if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { +- ref->req = ref; +- + v4l2_ctrl_lock(master); + /* g_volatile_ctrl will update the current control values */ + for (i = 0; i < master->ncontrols; i++) +@@ -4577,21 +4575,12 @@ void v4l2_ctrl_request_complete(struct m + v4l2_ctrl_unlock(master); + continue; + } +- if (ref->req == ref) ++ if (ref->valid_p_req) + continue; + ++ /* Copy the current control value into the request */ + v4l2_ctrl_lock(ctrl); +- if (ref->req) { +- ptr_to_ptr(ctrl, ref->req->p_req, ref->p_req); +- } else { +- ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req); +- /* +- * Set ref->req to ensure that when userspace wants to +- * obtain the controls of this request it will take +- * this value and not the current value of the control. +- */ +- ref->req = ref; +- } ++ cur_to_req(ref); + v4l2_ctrl_unlock(ctrl); + } + +@@ -4655,7 +4644,7 @@ int v4l2_ctrl_request_setup(struct media + struct v4l2_ctrl_ref *r = + find_ref(hdl, master->cluster[i]->id); + +- if (r->req && r == r->req) { ++ if (r->valid_p_req) { + have_new_data = true; + break; + } +--- a/include/media/v4l2-ctrls.h ++++ b/include/media/v4l2-ctrls.h +@@ -301,12 +301,14 @@ struct v4l2_ctrl { + * the control has been applied. This prevents applying controls + * from a cluster with multiple controls twice (when the first + * control of a cluster is applied, they all are). +- * @req: If set, this refers to another request that sets this control. ++ * @valid_p_req: If set, then p_req contains the control value for the request. + * @p_req: If the control handler containing this control reference + * is bound to a media request, then this points to the +- * value of the control that should be applied when the request ++ * value of the control that must be applied when the request + * is executed, or to the value of the control at the time +- * that the request was completed. ++ * that the request was completed. If @valid_p_req is false, ++ * then this control was never set for this request and the ++ * control will not be updated when this request is applied. + * + * Each control handler has a list of these refs. The list_head is used to + * keep a sorted-by-control-ID list of all controls, while the next pointer +@@ -319,7 +321,7 @@ struct v4l2_ctrl_ref { + struct v4l2_ctrl_helper *helper; + bool from_other_dev; + bool req_done; +- struct v4l2_ctrl_ref *req; ++ bool valid_p_req; + union v4l2_ctrl_ptr p_req; + }; + +@@ -346,7 +348,7 @@ struct v4l2_ctrl_ref { + * @error: The error code of the first failed control addition. + * @request_is_queued: True if the request was queued. + * @requests: List to keep track of open control handler request objects. +- * For the parent control handler (@req_obj.req == NULL) this ++ * For the parent control handler (@req_obj.ops == NULL) this + * is the list header. When the parent control handler is + * removed, it has to unbind and put all these requests since + * they refer to the parent. diff --git a/queue-5.12/media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch b/queue-5.12/media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch new file mode 100644 index 00000000000..9a14de3f0bc --- /dev/null +++ b/queue-5.12/media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch @@ -0,0 +1,62 @@ +From 15447d18b1b877d9c6f979bd00088e470a4e0e9f Mon Sep 17 00:00:00 2001 +From: Stanimir Varbanov +Date: Sat, 6 Mar 2021 13:16:41 +0100 +Subject: media: venus: hfi_cmds: Support plane-actual-info property from v1 + +From: Stanimir Varbanov + +commit 15447d18b1b877d9c6f979bd00088e470a4e0e9f upstream. + +The property is supported from v1 and upwards. So move it to +set_property_1x. + +Fixes: 01e869e78756 ("media: venus: venc: fix handlig of S_SELECTION and G_SELECTION") +Cc: stable@vger.kernel.org # v5.12 +Signed-off-by: Stanimir Varbanov +Tested-by: Bryan O'Donoghue +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/qcom/venus/hfi_cmds.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/media/platform/qcom/venus/hfi_cmds.c ++++ b/drivers/media/platform/qcom/venus/hfi_cmds.c +@@ -1039,6 +1039,18 @@ static int pkt_session_set_property_1x(s + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hierp); + break; + } ++ case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: { ++ struct hfi_uncompressed_plane_actual_info *in = pdata; ++ struct hfi_uncompressed_plane_actual_info *info = prop_data; ++ ++ info->buffer_type = in->buffer_type; ++ info->num_planes = in->num_planes; ++ info->plane_format[0] = in->plane_format[0]; ++ if (in->num_planes > 1) ++ info->plane_format[1] = in->plane_format[1]; ++ pkt->shdr.hdr.size += sizeof(u32) + sizeof(*info); ++ break; ++ } + + /* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */ + case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: +@@ -1205,18 +1217,6 @@ pkt_session_set_property_4xx(struct hfi_ + pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu); + break; + } +- case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: { +- struct hfi_uncompressed_plane_actual_info *in = pdata; +- struct hfi_uncompressed_plane_actual_info *info = prop_data; +- +- info->buffer_type = in->buffer_type; +- info->num_planes = in->num_planes; +- info->plane_format[0] = in->plane_format[0]; +- if (in->num_planes > 1) +- info->plane_format[1] = in->plane_format[1]; +- pkt->shdr.hdr.size += sizeof(u32) + sizeof(*info); +- break; +- } + case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: + case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: + case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE: diff --git a/queue-5.12/media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch b/queue-5.12/media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch new file mode 100644 index 00000000000..3abbf25fd17 --- /dev/null +++ b/queue-5.12/media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch @@ -0,0 +1,43 @@ +From 9b5d8fd580caa898c6e1b8605c774f2517f786ab Mon Sep 17 00:00:00 2001 +From: Stanimir Varbanov +Date: Sun, 7 Mar 2021 12:17:27 +0100 +Subject: media: venus: hfi_parser: Check for instance after hfi platform get + +From: Stanimir Varbanov + +commit 9b5d8fd580caa898c6e1b8605c774f2517f786ab upstream. + +The inst function argument is != NULL only for Venus v1 and +we did not migrate v1 to a hfi_platform abstraction yet. So +check for instance != NULL only after hfi_platform_get returns +no error. + +Fixes: e29929266be1 ("media: venus: Get codecs and capabilities from hfi platform") +Cc: stable@vger.kernel.org # v5.12 +Signed-off-by: Stanimir Varbanov +Tested-by: Bryan O'Donoghue +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/qcom/venus/hfi_parser.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/media/platform/qcom/venus/hfi_parser.c ++++ b/drivers/media/platform/qcom/venus/hfi_parser.c +@@ -235,13 +235,13 @@ static int hfi_platform_parser(struct ve + u32 enc_codecs, dec_codecs, count = 0; + unsigned int entries; + +- if (inst) +- return 0; +- + plat = hfi_platform_get(core->res->hfi_version); + if (!plat) + return -EINVAL; + ++ if (inst) ++ return 0; ++ + if (plat->codecs) + plat->codecs(&enc_codecs, &dec_codecs, &count); + diff --git a/queue-5.12/media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch b/queue-5.12/media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch new file mode 100644 index 00000000000..c2cfd8f3e3a --- /dev/null +++ b/queue-5.12/media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch @@ -0,0 +1,39 @@ +From 834124c596e2dddbbdba06620835710ccca32fd0 Mon Sep 17 00:00:00 2001 +From: Stanimir Varbanov +Date: Sun, 7 Mar 2021 12:16:03 +0100 +Subject: media: venus: hfi_parser: Don't initialize parser on v1 + +From: Stanimir Varbanov + +commit 834124c596e2dddbbdba06620835710ccca32fd0 upstream. + +The Venus v1 behaves differently comparing with the other Venus +version in respect to capability parsing and when they are send +to the driver. So we don't need to initialize hfi parser for +multiple invocations like what we do for > v1 Venus versions. + +Fixes: 10865c98986b ("media: venus: parser: Prepare parser for multiple invocations") +Cc: stable@vger.kernel.org # v5.10+ +Signed-off-by: Stanimir Varbanov +Tested-by: Bryan O'Donoghue +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/qcom/venus/hfi_parser.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/media/platform/qcom/venus/hfi_parser.c ++++ b/drivers/media/platform/qcom/venus/hfi_parser.c +@@ -277,8 +277,10 @@ u32 hfi_parser(struct venus_core *core, + + parser_init(inst, &codecs, &domain); + +- core->codecs_count = 0; +- memset(core->caps, 0, sizeof(core->caps)); ++ if (core->res->hfi_version > HFI_VERSION_1XX) { ++ core->codecs_count = 0; ++ memset(core->caps, 0, sizeof(core->caps)); ++ } + + while (words_count) { + data = word + 1; diff --git a/queue-5.12/media-venus-pm_helpers-set-opp-clock-name-for-v1.patch b/queue-5.12/media-venus-pm_helpers-set-opp-clock-name-for-v1.patch new file mode 100644 index 00000000000..63dde040ced --- /dev/null +++ b/queue-5.12/media-venus-pm_helpers-set-opp-clock-name-for-v1.patch @@ -0,0 +1,65 @@ +From 3215887167af7db9af9fa23d61321ebfbd6ed6d3 Mon Sep 17 00:00:00 2001 +From: Stanimir Varbanov +Date: Thu, 25 Feb 2021 15:28:57 +0100 +Subject: media: venus: pm_helpers: Set opp clock name for v1 + +From: Stanimir Varbanov + +commit 3215887167af7db9af9fa23d61321ebfbd6ed6d3 upstream. + +The rate of the core clock is set through devm_pm_opp_set_rate and +to avoid errors from it we have to set the name of the clock via +dev_pm_opp_set_clkname. + +Fixes: 9a538b83612c ("media: venus: core: Add support for opp tables/perf voting") +Cc: stable@vger.kernel.org # v5.10+ +Signed-off-by: Stanimir Varbanov +Tested-by: Bryan O'Donoghue +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/qcom/venus/pm_helpers.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/drivers/media/platform/qcom/venus/pm_helpers.c ++++ b/drivers/media/platform/qcom/venus/pm_helpers.c +@@ -279,7 +279,22 @@ set_freq: + + static int core_get_v1(struct venus_core *core) + { +- return core_clks_get(core); ++ int ret; ++ ++ ret = core_clks_get(core); ++ if (ret) ++ return ret; ++ ++ core->opp_table = dev_pm_opp_set_clkname(core->dev, "core"); ++ if (IS_ERR(core->opp_table)) ++ return PTR_ERR(core->opp_table); ++ ++ return 0; ++} ++ ++static void core_put_v1(struct venus_core *core) ++{ ++ dev_pm_opp_put_clkname(core->opp_table); + } + + static int core_power_v1(struct venus_core *core, int on) +@@ -296,6 +311,7 @@ static int core_power_v1(struct venus_co + + static const struct venus_pm_ops pm_ops_v1 = { + .core_get = core_get_v1, ++ .core_put = core_put_v1, + .core_power = core_power_v1, + .load_scale = load_scale_v1, + }; +@@ -368,6 +384,7 @@ static int venc_power_v3(struct device * + + static const struct venus_pm_ops pm_ops_v3 = { + .core_get = core_get_v1, ++ .core_put = core_put_v1, + .core_power = core_power_v1, + .vdec_get = vdec_get_v3, + .vdec_power = vdec_power_v3, diff --git a/queue-5.12/media-venus-venc_ctrls-change-default-header-mode.patch b/queue-5.12/media-venus-venc_ctrls-change-default-header-mode.patch new file mode 100644 index 00000000000..5c6b351324d --- /dev/null +++ b/queue-5.12/media-venus-venc_ctrls-change-default-header-mode.patch @@ -0,0 +1,34 @@ +From 39a6b9185d305d236bff625509ee63801b50301b Mon Sep 17 00:00:00 2001 +From: Stanimir Varbanov +Date: Sat, 6 Mar 2021 13:13:46 +0100 +Subject: media: venus: venc_ctrls: Change default header mode + +From: Stanimir Varbanov + +commit 39a6b9185d305d236bff625509ee63801b50301b upstream. + +It is observed that on Venus v1 the default header-mode is producing +a bitstream which is not playble. Change the default header-mode to +joined with 1st frame. + +Fixes: 002c22bd360e ("media: venus: venc: set inband mode property to FW.") +Cc: stable@vger.kernel.org # v5.12 +Signed-off-by: Stanimir Varbanov +Tested-by: Bryan O'Donoghue +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/qcom/venus/venc_ctrls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/qcom/venus/venc_ctrls.c ++++ b/drivers/media/platform/qcom/venus/venc_ctrls.c +@@ -359,7 +359,7 @@ int venc_ctrl_init(struct venus_inst *in + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, + ~((1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) | + (1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)), +- V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); ++ V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME); + + v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, + V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, diff --git a/queue-5.12/pci-dwc-move-iatu-detection-earlier.patch b/queue-5.12/pci-dwc-move-iatu-detection-earlier.patch new file mode 100644 index 00000000000..bd5b93d1b0d --- /dev/null +++ b/queue-5.12/pci-dwc-move-iatu-detection-earlier.patch @@ -0,0 +1,100 @@ +From 8bcca26585585ae4b44d25d30f351ad0afa4976b Mon Sep 17 00:00:00 2001 +From: Hou Zhiqiang +Date: Tue, 13 Apr 2021 17:22:19 +0300 +Subject: PCI: dwc: Move iATU detection earlier + +From: Hou Zhiqiang + +commit 8bcca26585585ae4b44d25d30f351ad0afa4976b upstream. + +dw_pcie_ep_init() depends on the detected iATU region numbers to allocate +the in/outbound window management bitmap. It fails after 281f1f99cf3a +("PCI: dwc: Detect number of iATU windows"). + +Move the iATU region detection into a new function, move the detection to +the very beginning of dw_pcie_host_init() and dw_pcie_ep_init(). Also +remove it from the dw_pcie_setup(), since it's more like a software +initialization step than hardware setup. + +Link: https://lore.kernel.org/r/20210125044803.4310-1-Zhiqiang.Hou@nxp.com +Link: https://lore.kernel.org/linux-pci/20210407131255.702054-1-dmitry.baryshkov@linaro.org +Link: https://lore.kernel.org/r/20210413142219.2301430-1-dmitry.baryshkov@linaro.org +Fixes: 281f1f99cf3a ("PCI: dwc: Detect number of iATU windows") +Tested-by: Kunihiko Hayashi +Tested-by: Marek Szyprowski +Tested-by: Manivannan Sadhasivam +Signed-off-by: Hou Zhiqiang +[DB: moved dw_pcie_iatu_detect to happen after host_init callback] +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Cc: stable@vger.kernel.org # v5.11+ +Cc: Marek Szyprowski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pcie-designware-ep.c | 2 ++ + drivers/pci/controller/dwc/pcie-designware-host.c | 1 + + drivers/pci/controller/dwc/pcie-designware.c | 11 ++++++++--- + drivers/pci/controller/dwc/pcie-designware.h | 1 + + 4 files changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -705,6 +705,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *e + } + } + ++ dw_pcie_iatu_detect(pci); ++ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); + if (!res) + return -EINVAL; +--- a/drivers/pci/controller/dwc/pcie-designware-host.c ++++ b/drivers/pci/controller/dwc/pcie-designware-host.c +@@ -398,6 +398,7 @@ int dw_pcie_host_init(struct pcie_port * + if (ret) + goto err_free_msi; + } ++ dw_pcie_iatu_detect(pci); + + dw_pcie_setup_rc(pp); + dw_pcie_msi_init(pp); +--- a/drivers/pci/controller/dwc/pcie-designware.c ++++ b/drivers/pci/controller/dwc/pcie-designware.c +@@ -660,11 +660,9 @@ static void dw_pcie_iatu_detect_regions( + pci->num_ob_windows = ob; + } + +-void dw_pcie_setup(struct dw_pcie *pci) ++void dw_pcie_iatu_detect(struct dw_pcie *pci) + { +- u32 val; + struct device *dev = pci->dev; +- struct device_node *np = dev->of_node; + struct platform_device *pdev = to_platform_device(dev); + + if (pci->version >= 0x480A || (!pci->version && +@@ -693,6 +691,13 @@ void dw_pcie_setup(struct dw_pcie *pci) + + dev_info(pci->dev, "Detected iATU regions: %u outbound, %u inbound", + pci->num_ob_windows, pci->num_ib_windows); ++} ++ ++void dw_pcie_setup(struct dw_pcie *pci) ++{ ++ u32 val; ++ struct device *dev = pci->dev; ++ struct device_node *np = dev->of_node; + + if (pci->link_gen > 0) + dw_pcie_link_set_max_speed(pci, pci->link_gen); +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -306,6 +306,7 @@ int dw_pcie_prog_inbound_atu(struct dw_p + void dw_pcie_disable_atu(struct dw_pcie *pci, int index, + enum dw_pcie_region_type type); + void dw_pcie_setup(struct dw_pcie *pci); ++void dw_pcie_iatu_detect(struct dw_pcie *pci); + + static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) + { diff --git a/queue-5.12/rsi-use-resume_noirq-for-sdio.patch b/queue-5.12/rsi-use-resume_noirq-for-sdio.patch new file mode 100644 index 00000000000..8d732ebb5ee --- /dev/null +++ b/queue-5.12/rsi-use-resume_noirq-for-sdio.patch @@ -0,0 +1,46 @@ +From c434e5e48dc4e626364491455f97e2db0aa137b1 Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Sun, 28 Mar 2021 00:59:32 +0100 +Subject: rsi: Use resume_noirq for SDIO + +From: Marek Vasut + +commit c434e5e48dc4e626364491455f97e2db0aa137b1 upstream. + +The rsi_resume() does access the bus to enable interrupts on the RSI +SDIO WiFi card, however when calling sdio_claim_host() in the resume +path, it is possible the bus is already claimed and sdio_claim_host() +spins indefinitelly. Enable the SDIO card interrupts in resume_noirq +instead to prevent anything else from claiming the SDIO bus first. + +Fixes: 20db07332736 ("rsi: sdio suspend and resume support") +Signed-off-by: Marek Vasut +Cc: Amitkumar Karwar +Cc: Angus Ainslie +Cc: David S. Miller +Cc: Jakub Kicinski +Cc: Kalle Valo +Cc: Karun Eagalapati +Cc: Martin Kepplinger +Cc: Sebastian Krzyszkowiak +Cc: Siva Rebbagondla +Cc: netdev@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20210327235932.175896-1-marex@denx.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c ++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c +@@ -1513,7 +1513,7 @@ static int rsi_restore(struct device *de + } + static const struct dev_pm_ops rsi_pm_ops = { + .suspend = rsi_suspend, +- .resume = rsi_resume, ++ .resume_noirq = rsi_resume, + .freeze = rsi_freeze, + .thaw = rsi_thaw, + .restore = rsi_restore, diff --git a/queue-5.12/series b/queue-5.12/series index 2f6d3b4d7c3..a583018d50d 100644 --- a/queue-5.12/series +++ b/queue-5.12/series @@ -332,3 +332,41 @@ smb3-do-not-attempt-multichannel-to-server-which-does-not-support-it.patch revert-337f13046ff0-futex-allow-futex_clock_realtime-with-futex_wait-op.patch futex-do-not-apply-time-namespace-adjustment-on-futex_lock_pi.patch x86-cpu-initialize-msr_tsc_aux-if-rdtscp-or-rdpid-is-supported.patch +kbuild-update-config_data.gz-only-when-the-content-of-.config-is-changed.patch +ext4-annotate-data-race-in-start_this_handle.patch +ext4-annotate-data-race-in-jbd2_journal_dirty_metadata.patch +ext4-fix-check-to-prevent-false-positive-report-of-incorrect-used-inodes.patch +ext4-do-not-set-sb_active-in-ext4_orphan_cleanup.patch +ext4-always-panic-when-errors-panic-is-specified.patch +ext4-fix-error-code-in-ext4_commit_super.patch +ext4-fix-ext4_error_err-save-negative-errno-into-superblock.patch +ext4-fix-error-return-code-in-ext4_fc_perform_commit.patch +ext4-allow-the-dax-flag-to-be-set-and-cleared-on-inline-directories.patch +ext4-fix-occasional-generic-418-failure.patch +media-dvbdev-fix-memory-leak-in-dvb_media_device_free.patch +media-dvb-usb-fix-use-after-free-access.patch +media-dvb-usb-fix-memory-leak-at-error-in-dvb_usb_device_init.patch +media-staging-intel-ipu3-fix-memory-leak-in-imu_fmt.patch +media-staging-intel-ipu3-fix-set_fmt-error-handling.patch +media-staging-intel-ipu3-fix-race-condition-during-set_fmt.patch +media-v4l2-ctrls-fix-reference-to-freed-memory.patch +media-coda-fix-macroblocks-count-control-usage.patch +media-venus-pm_helpers-set-opp-clock-name-for-v1.patch +media-venus-venc_ctrls-change-default-header-mode.patch +media-venus-hfi_cmds-support-plane-actual-info-property-from-v1.patch +media-venus-hfi_parser-don-t-initialize-parser-on-v1.patch +media-venus-hfi_parser-check-for-instance-after-hfi-platform-get.patch +io_uring-remove-extra-sqpoll-submission-halting.patch +io_uring-fix-shared-sqpoll-cancellation-hangs.patch +io_uring-fix-work_exit-sqpoll-cancellations.patch +io_uring-check-current-io_uring-in-io_uring_cancel_sqpoll.patch +usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch +usb-gadget-fix-double-free-of-device-descriptor-pointers.patch +usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch +usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch +usb-dwc3-gadget-fix-start_transfer-link-state-check.patch +usb-dwc3-core-do-core-softreset-when-switch-mode.patch +usb-dwc2-fix-session-request-interrupt-handler.patch +pci-dwc-move-iatu-detection-earlier.patch +tty-fix-memory-leak-in-vc_deallocate.patch +rsi-use-resume_noirq-for-sdio.patch diff --git a/queue-5.12/tty-fix-memory-leak-in-vc_deallocate.patch b/queue-5.12/tty-fix-memory-leak-in-vc_deallocate.patch new file mode 100644 index 00000000000..80a93c2471a --- /dev/null +++ b/queue-5.12/tty-fix-memory-leak-in-vc_deallocate.patch @@ -0,0 +1,34 @@ +From 211b4d42b70f1c1660feaa968dac0efc2a96ac4d Mon Sep 17 00:00:00 2001 +From: Pavel Skripkin +Date: Sun, 28 Mar 2021 00:44:43 +0300 +Subject: tty: fix memory leak in vc_deallocate + +From: Pavel Skripkin + +commit 211b4d42b70f1c1660feaa968dac0efc2a96ac4d upstream. + +syzbot reported memory leak in tty/vt. +The problem was in VT_DISALLOCATE ioctl cmd. +After allocating unimap with PIO_UNIMAP it wasn't +freed via VT_DISALLOCATE, but vc_cons[currcons].d was +zeroed. + +Reported-by: syzbot+bcc922b19ccc64240b42@syzkaller.appspotmail.com +Signed-off-by: Pavel Skripkin +Cc: stable +Link: https://lore.kernel.org/r/20210327214443.21548-1-paskripkin@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/vt/vt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1381,6 +1381,7 @@ struct vc_data *vc_deallocate(unsigned i + atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); + vcs_remove_sysfs(currcons); + visual_deinit(vc); ++ con_free_unimap(vc); + put_pid(vc->vt_pid); + vc_uniscr_set(vc, NULL); + kfree(vc->vc_screenbuf); diff --git a/queue-5.12/usb-dwc2-fix-session-request-interrupt-handler.patch b/queue-5.12/usb-dwc2-fix-session-request-interrupt-handler.patch new file mode 100644 index 00000000000..b9c1ac263dc --- /dev/null +++ b/queue-5.12/usb-dwc2-fix-session-request-interrupt-handler.patch @@ -0,0 +1,47 @@ +From 42b32b164acecd850edef010915a02418345a033 Mon Sep 17 00:00:00 2001 +From: Artur Petrosyan +Date: Thu, 8 Apr 2021 13:45:49 +0400 +Subject: usb: dwc2: Fix session request interrupt handler + +From: Artur Petrosyan + +commit 42b32b164acecd850edef010915a02418345a033 upstream. + +According to programming guide in host mode, port +power must be turned on in session request +interrupt handlers. + +Fixes: 21795c826a45 ("usb: dwc2: exit hibernation on session request") +Cc: +Acked-by: Minas Harutyunyan +Signed-off-by: Artur Petrosyan +Link: https://lore.kernel.org/r/20210408094550.75484A0094@mailhost.synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/core_intr.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -307,6 +307,7 @@ static void dwc2_handle_conn_id_status_c + static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) + { + int ret; ++ u32 hprt0; + + /* Clear interrupt */ + dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS); +@@ -327,6 +328,13 @@ static void dwc2_handle_session_req_intr + * established + */ + dwc2_hsotg_disconnect(hsotg); ++ } else { ++ /* Turn on the port power bit. */ ++ hprt0 = dwc2_read_hprt0(hsotg); ++ hprt0 |= HPRT0_PWR; ++ dwc2_writel(hsotg, hprt0, HPRT0); ++ /* Connect hcd after port power is set. */ ++ dwc2_hcd_connect(hsotg); + } + } + diff --git a/queue-5.12/usb-dwc3-core-do-core-softreset-when-switch-mode.patch b/queue-5.12/usb-dwc3-core-do-core-softreset-when-switch-mode.patch new file mode 100644 index 00000000000..974394417da --- /dev/null +++ b/queue-5.12/usb-dwc3-core-do-core-softreset-when-switch-mode.patch @@ -0,0 +1,155 @@ +From f88359e1588b85cf0e8209ab7d6620085f3441d9 Mon Sep 17 00:00:00 2001 +From: Yu Chen +Date: Thu, 15 Apr 2021 15:20:30 -0700 +Subject: usb: dwc3: core: Do core softreset when switch mode + +From: Yu Chen + +commit f88359e1588b85cf0e8209ab7d6620085f3441d9 upstream. + +From: John Stultz + +According to the programming guide, to switch mode for DRD controller, +the driver needs to do the following. + +To switch from device to host: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(host mode) +3. Reset the host with USBCMD.HCRESET +4. Then follow up with the initializing host registers sequence + +To switch from host to device: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(device mode) +3. Reset the device with DCTL.CSftRst +4. Then follow up with the initializing registers sequence + +Currently we're missing step 1) to do GCTL.CoreSoftReset and step 3) of +switching from host to device. John Stult reported a lockup issue seen +with HiKey960 platform without these steps[1]. Similar issue is observed +with Ferry's testing platform[2]. + +So, apply the required steps along with some fixes to Yu Chen's and John +Stultz's version. The main fixes to their versions are the missing wait +for clocks synchronization before clearing GCTL.CoreSoftReset and only +apply DCTL.CSftRst when switching from host to device. + +[1] https://lore.kernel.org/linux-usb/20210108015115.27920-1-john.stultz@linaro.org/ +[2] https://lore.kernel.org/linux-usb/0ba7a6ba-e6a7-9cd4-0695-64fc927e01f1@gmail.com/ + +Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") +Cc: Andy Shevchenko +Cc: Ferry Toth +Cc: Wesley Cheng +Cc: +Tested-by: John Stultz +Tested-by: Wesley Cheng +Signed-off-by: Yu Chen +Signed-off-by: John Stultz +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/374440f8dcd4f06c02c2caf4b1efde86774e02d9.1618521663.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++ + drivers/usb/dwc3/core.h | 5 +++++ + 2 files changed, 32 insertions(+) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -114,6 +114,8 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u + dwc->current_dr_role = mode; + } + ++static int dwc3_core_soft_reset(struct dwc3 *dwc); ++ + static void __dwc3_set_mode(struct work_struct *work) + { + struct dwc3 *dwc = work_to_dwc(work); +@@ -121,6 +123,8 @@ static void __dwc3_set_mode(struct work_ + int ret; + u32 reg; + ++ mutex_lock(&dwc->mutex); ++ + pm_runtime_get_sync(dwc->dev); + + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) +@@ -154,6 +158,25 @@ static void __dwc3_set_mode(struct work_ + break; + } + ++ /* For DRD host or device mode only */ ++ if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg |= DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ ++ /* ++ * Wait for internal clocks to synchronized. DWC_usb31 and ++ * DWC_usb32 may need at least 50ms (less for DWC_usb3). To ++ * keep it consistent across different IPs, let's wait up to ++ * 100ms before clearing GCTL.CORESOFTRESET. ++ */ ++ msleep(100); ++ ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg &= ~DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ } ++ + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_set_prtcap(dwc, dwc->desired_dr_role); +@@ -178,6 +201,8 @@ static void __dwc3_set_mode(struct work_ + } + break; + case DWC3_GCTL_PRTCAP_DEVICE: ++ dwc3_core_soft_reset(dwc); ++ + dwc3_event_buffers_setup(dwc); + + if (dwc->usb2_phy) +@@ -200,6 +225,7 @@ static void __dwc3_set_mode(struct work_ + out: + pm_runtime_mark_last_busy(dwc->dev); + pm_runtime_put_autosuspend(dwc->dev); ++ mutex_unlock(&dwc->mutex); + } + + void dwc3_set_mode(struct dwc3 *dwc, u32 mode) +@@ -1545,6 +1571,7 @@ static int dwc3_probe(struct platform_de + dwc3_cache_hwparams(dwc); + + spin_lock_init(&dwc->lock); ++ mutex_init(&dwc->mutex); + + pm_runtime_set_active(dev); + pm_runtime_use_autosuspend(dev); +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -13,6 +13,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -946,6 +947,7 @@ struct dwc3_scratchpad_array { + * @scratch_addr: dma address of scratchbuf + * @ep0_in_setup: one control transfer is completed and enter setup phase + * @lock: for synchronizing ++ * @mutex: for mode switching + * @dev: pointer to our struct device + * @sysdev: pointer to the DMA-capable device + * @xhci: pointer to our xHCI child +@@ -1086,6 +1088,9 @@ struct dwc3 { + /* device lock */ + spinlock_t lock; + ++ /* mode switching lock */ ++ struct mutex mutex; ++ + struct device *dev; + struct device *sysdev; + diff --git a/queue-5.12/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch b/queue-5.12/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch new file mode 100644 index 00000000000..3a260e7b674 --- /dev/null +++ b/queue-5.12/usb-dwc3-gadget-fix-start_transfer-link-state-check.patch @@ -0,0 +1,63 @@ +From c560e76319a94a3b9285bc426c609903408e4826 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Mon, 19 Apr 2021 19:11:12 -0700 +Subject: usb: dwc3: gadget: Fix START_TRANSFER link state check + +From: Thinh Nguyen + +commit c560e76319a94a3b9285bc426c609903408e4826 upstream. + +The START_TRANSFER command needs to be executed while in ON/U0 link +state (with an exception during register initialization). Don't use +dwc->link_state to check this since the driver only tracks the link +state when the link state change interrupt is enabled. Check the link +state from DSTS register instead. + +Note that often the host already brings the device out of low power +before it sends/requests the next transfer. So, the user won't see any +issue when the device starts transfer then. This issue is more +noticeable in cases when the device delays starting transfer, which can +happen during delayed control status after the host put the device in +low power. + +Fixes: 799e9dc82968 ("usb: dwc3: gadget: conditionally disable Link State change events") +Cc: +Acked-by: Felipe Balbi +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/bcefaa9ecbc3e1936858c0baa14de6612960e909.1618884221.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -308,13 +308,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ + } + + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { +- int needs_wakeup; ++ int link_state; + +- needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 || +- dwc->link_state == DWC3_LINK_STATE_U2 || +- dwc->link_state == DWC3_LINK_STATE_U3); +- +- if (unlikely(needs_wakeup)) { ++ link_state = dwc3_gadget_get_link_state(dwc); ++ if (link_state == DWC3_LINK_STATE_U1 || ++ link_state == DWC3_LINK_STATE_U2 || ++ link_state == DWC3_LINK_STATE_U3) { + ret = __dwc3_gadget_wakeup(dwc); + dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", + ret); +@@ -1975,6 +1974,8 @@ static int __dwc3_gadget_wakeup(struct d + case DWC3_LINK_STATE_RESET: + case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */ + case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ ++ case DWC3_LINK_STATE_U2: /* in HS, means Sleep (L1) */ ++ case DWC3_LINK_STATE_U1: + case DWC3_LINK_STATE_RESUME: + break; + default: diff --git a/queue-5.12/usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch b/queue-5.12/usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch new file mode 100644 index 00000000000..3f1911f9ff4 --- /dev/null +++ b/queue-5.12/usb-dwc3-gadget-remove-fs-binterval_m1-limitation.patch @@ -0,0 +1,44 @@ +From 3232a3ce55edfc0d7f8904543b4088a5339c2b2b Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Thu, 15 Apr 2021 00:41:58 -0700 +Subject: usb: dwc3: gadget: Remove FS bInterval_m1 limitation + +From: Thinh Nguyen + +commit 3232a3ce55edfc0d7f8904543b4088a5339c2b2b upstream. + +The programming guide incorrectly stated that the DCFG.bInterval_m1 must +be set to 0 when operating in fullspeed. There's no such limitation for +all IPs. See DWC_usb3x programming guide section 3.2.2.1. + +Fixes: a1679af85b2a ("usb: dwc3: gadget: Fix setting of DEPCFG.bInterval_m1") +Cc: +Acked-by: Felipe Balbi +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/5d4139ae89d810eb0a2d8577fb096fc88e87bfab.1618472454.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/gadget.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -608,12 +608,14 @@ static int dwc3_gadget_set_ep_config(str + u8 bInterval_m1; + + /* +- * Valid range for DEPCFG.bInterval_m1 is from 0 to 13, and it +- * must be set to 0 when the controller operates in full-speed. ++ * Valid range for DEPCFG.bInterval_m1 is from 0 to 13. ++ * ++ * NOTE: The programming guide incorrectly stated bInterval_m1 ++ * must be set to 0 when operating in fullspeed. Internally the ++ * controller does not have this limitation. See DWC_usb3x ++ * programming guide section 3.2.2.1. + */ + bInterval_m1 = min_t(u8, desc->bInterval - 1, 13); +- if (dwc->gadget->speed == USB_SPEED_FULL) +- bInterval_m1 = 0; + + if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT && + dwc->gadget->speed == USB_SPEED_FULL) diff --git a/queue-5.12/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch b/queue-5.12/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch new file mode 100644 index 00000000000..613d3915bba --- /dev/null +++ b/queue-5.12/usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch @@ -0,0 +1,90 @@ +From 4a5d797a9f9c4f18585544237216d7812686a71f Mon Sep 17 00:00:00 2001 +From: Anirudh Rayabharam +Date: Mon, 19 Apr 2021 09:07:08 +0530 +Subject: usb: gadget: dummy_hcd: fix gpf in gadget_setup + +From: Anirudh Rayabharam + +commit 4a5d797a9f9c4f18585544237216d7812686a71f upstream. + +Fix a general protection fault reported by syzbot due to a race between +gadget_setup() and gadget_unbind() in raw_gadget. + +The gadget core is supposed to guarantee that there won't be any more +callbacks to the gadget driver once the driver's unbind routine is +called. That guarantee is enforced in usb_gadget_remove_driver as +follows: + + usb_gadget_disconnect(udc->gadget); + if (udc->gadget->irq) + synchronize_irq(udc->gadget->irq); + udc->driver->unbind(udc->gadget); + usb_gadget_udc_stop(udc); + +usb_gadget_disconnect turns off the pullup resistor, telling the host +that the gadget is no longer connected and preventing the transmission +of any more USB packets. Any packets that have already been received +are sure to processed by the UDC driver's interrupt handler by the time +synchronize_irq returns. + +But this doesn't work with dummy_hcd, because dummy_hcd doesn't use +interrupts; it uses a timer instead. It does have code to emulate the +effect of synchronize_irq, but that code doesn't get invoked at the +right time -- it currently runs in usb_gadget_udc_stop, after the unbind +callback instead of before. Indeed, there's no way for +usb_gadget_remove_driver to invoke this code before the unbind callback. + +To fix this, move the synchronize_irq() emulation code to dummy_pullup +so that it runs before unbind. Also, add a comment explaining why it is +necessary to have it there. + +Reported-by: syzbot+eb4674092e6cc8d9e0bd@syzkaller.appspotmail.com +Suggested-by: Alan Stern +Acked-by: Alan Stern +Signed-off-by: Anirudh Rayabharam +Link: https://lore.kernel.org/r/20210419033713.3021-1-mail@anirudhrb.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/dummy_hcd.c | 23 +++++++++++++++-------- + 1 file changed, 15 insertions(+), 8 deletions(-) + +--- a/drivers/usb/gadget/udc/dummy_hcd.c ++++ b/drivers/usb/gadget/udc/dummy_hcd.c +@@ -903,6 +903,21 @@ static int dummy_pullup(struct usb_gadge + spin_lock_irqsave(&dum->lock, flags); + dum->pullup = (value != 0); + set_link_state(dum_hcd); ++ if (value == 0) { ++ /* ++ * Emulate synchronize_irq(): wait for callbacks to finish. ++ * This seems to be the best place to emulate the call to ++ * synchronize_irq() that's in usb_gadget_remove_driver(). ++ * Doing it in dummy_udc_stop() would be too late since it ++ * is called after the unbind callback and unbind shouldn't ++ * be invoked until all the other callbacks are finished. ++ */ ++ while (dum->callback_usage > 0) { ++ spin_unlock_irqrestore(&dum->lock, flags); ++ usleep_range(1000, 2000); ++ spin_lock_irqsave(&dum->lock, flags); ++ } ++ } + spin_unlock_irqrestore(&dum->lock, flags); + + usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); +@@ -1004,14 +1019,6 @@ static int dummy_udc_stop(struct usb_gad + spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); +- +- /* emulate synchronize_irq(): wait for callbacks to finish */ +- while (dum->callback_usage > 0) { +- spin_unlock_irq(&dum->lock); +- usleep_range(1000, 2000); +- spin_lock_irq(&dum->lock); +- } +- + dum->driver = NULL; + spin_unlock_irq(&dum->lock); + diff --git a/queue-5.12/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch b/queue-5.12/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch new file mode 100644 index 00000000000..091cdd2401a --- /dev/null +++ b/queue-5.12/usb-gadget-fix-double-free-of-device-descriptor-pointers.patch @@ -0,0 +1,44 @@ +From 43c4cab006f55b6ca549dd1214e22f5965a8675f Mon Sep 17 00:00:00 2001 +From: Hemant Kumar +Date: Wed, 21 Apr 2021 12:47:32 -0700 +Subject: usb: gadget: Fix double free of device descriptor pointers + +From: Hemant Kumar + +commit 43c4cab006f55b6ca549dd1214e22f5965a8675f upstream. + +Upon driver unbind usb_free_all_descriptors() function frees all +speed descriptor pointers without setting them to NULL. In case +gadget speed changes (i.e from super speed plus to super speed) +after driver unbind only upto super speed descriptor pointers get +populated. Super speed plus desc still holds the stale (already +freed) pointer. Fix this issue by setting all descriptor pointers +to NULL after freeing them in usb_free_all_descriptors(). + +Fixes: f5c61225cf29 ("usb: gadget: Update function for SuperSpeedPlus") +cc: stable@vger.kernel.org +Reviewed-by: Peter Chen +Signed-off-by: Hemant Kumar +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/1619034452-17334-1-git-send-email-wcheng@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/config.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/gadget/config.c ++++ b/drivers/usb/gadget/config.c +@@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors + void usb_free_all_descriptors(struct usb_function *f) + { + usb_free_descriptors(f->fs_descriptors); ++ f->fs_descriptors = NULL; + usb_free_descriptors(f->hs_descriptors); ++ f->hs_descriptors = NULL; + usb_free_descriptors(f->ss_descriptors); ++ f->ss_descriptors = NULL; + usb_free_descriptors(f->ssp_descriptors); ++ f->ssp_descriptors = NULL; + } + EXPORT_SYMBOL_GPL(usb_free_all_descriptors); + diff --git a/queue-5.12/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch b/queue-5.12/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch new file mode 100644 index 00000000000..110487e1c49 --- /dev/null +++ b/queue-5.12/usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch @@ -0,0 +1,44 @@ +From 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e Mon Sep 17 00:00:00 2001 +From: Dean Anderson +Date: Wed, 17 Mar 2021 15:41:09 -0700 +Subject: usb: gadget/function/f_fs string table fix for multiple languages + +From: Dean Anderson + +commit 55b74ce7d2ce0b0058f3e08cab185a0afacfe39e upstream. + +Fixes bug with the handling of more than one language in +the string table in f_fs.c. +str_count was not reset for subsequent language codes. +str_count-- "rolls under" and processes u32 max strings on +the processing of the second language entry. +The existing bug can be reproduced by adding a second language table +to the structure "strings" in tools/usb/ffs-test.c. + +Signed-off-by: Dean Anderson +Link: https://lore.kernel.org/r/20210317224109.21534-1-dean@sensoray.com +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_fs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -2640,6 +2640,7 @@ static int __ffs_data_got_strings(struct + + do { /* lang_count > 0 so we can use do-while */ + unsigned needed = needed_count; ++ u32 str_per_lang = str_count; + + if (len < 3) + goto error_free; +@@ -2675,7 +2676,7 @@ static int __ffs_data_got_strings(struct + + data += length + 1; + len -= length + 1; +- } while (--str_count); ++ } while (--str_per_lang); + + s->id = 0; /* terminator */ + s->s = NULL; -- 2.47.3