From: Greg Kroah-Hartman Date: Sat, 9 Nov 2024 15:08:45 +0000 (+0100) Subject: 6.11-stable patches X-Git-Tag: v5.15.172~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04409f3c261352e8e594f0c2aa80dc8b1f160b89;p=thirdparty%2Fkernel%2Fstable-queue.git 6.11-stable patches added patches: alsa-usb-audio-add-quirk-for-hp-320-fhd-webcam.patch dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch dm-cache-fix-flushing-uninitialized-delayed_work-on-cache_ctr-error.patch dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch dm-fix-a-crash-if-blk_alloc_disk-fails.patch dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch drm-amd-display-fix-brightness-level-not-retained-over-reboot.patch drm-amd-display-parse-umc_info-or-vram_info-based-on-asic.patch drm-amd-pm-always-pick-the-pptable-from-ifwi.patch drm-amd-pm-correct-the-workload-setting.patch drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch drm-amdgpu-adjust-debugfs-eviction-and-ib-access-permissions.patch drm-amdgpu-adjust-debugfs-register-access-permissions.patch drm-amdgpu-fix-dpx-valid-mode-check-on-gc-9.4.3.patch drm-amdgpu-prevent-null-pointer-dereference-if-atif-is-not-supported.patch drm-imagination-add-a-per-file-pvr-context-list.patch drm-imagination-break-an-object-reference-loop.patch drm-panthor-be-stricter-about-io-mapping-flags.patch drm-panthor-lock-xarray-when-getting-entries-for-the-vm.patch keys-trusted-dcp-fix-null-dereference-in-aead-crypto-operation.patch mptcp-no-admin-perm-to-list-endpoints.patch pwm-imx-tpm-use-correct-modulo-value-for-epwm-mode.patch rpmsg-glink-handle-rejected-intent-request-better.patch thermal-drivers-qcom-lmh-remove-false-lockdep-backtrace.patch tpm-lock-tpm-chip-in-tpm_pm_suspend-first.patch --- diff --git a/queue-6.11/alsa-usb-audio-add-quirk-for-hp-320-fhd-webcam.patch b/queue-6.11/alsa-usb-audio-add-quirk-for-hp-320-fhd-webcam.patch new file mode 100644 index 00000000000..cf6dab89834 --- /dev/null +++ b/queue-6.11/alsa-usb-audio-add-quirk-for-hp-320-fhd-webcam.patch @@ -0,0 +1,45 @@ +From dabc44c28f118910dea96244d903f0c270225669 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 5 Nov 2024 13:02:17 +0100 +Subject: ALSA: usb-audio: Add quirk for HP 320 FHD Webcam + +From: Takashi Iwai + +commit dabc44c28f118910dea96244d903f0c270225669 upstream. + +HP 320 FHD Webcam (03f0:654a) seems to have flaky firmware like other +webcam devices that don't like the frequency inquiries. Also, Mic +Capture Volume has an invalid resolution, hence fix it to be 16 (as a +blind shot). + +Link: https://bugzilla.suse.com/show_bug.cgi?id=1232768 +Cc: +Link: https://patch.msgid.link/20241105120220.5740-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer.c | 1 + + sound/usb/quirks.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1205,6 +1205,7 @@ static void volume_control_quirks(struct + } + break; + case USB_ID(0x1bcf, 0x2283): /* NexiGo N930AF FHD Webcam */ ++ case USB_ID(0x03f0, 0x654a): /* HP 320 FHD Webcam */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + usb_audio_info(chip, + "set resolution quirk: cval->res = 16\n"); +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2114,6 +2114,8 @@ struct usb_audio_quirk_flags_table { + + static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + /* Device matches */ ++ DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */ ++ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */ diff --git a/queue-6.11/dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch b/queue-6.11/dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch new file mode 100644 index 00000000000..49538b59267 --- /dev/null +++ b/queue-6.11/dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch @@ -0,0 +1,100 @@ +From 235d2e739fcbe964c9ce179b4c991025662dcdb6 Mon Sep 17 00:00:00 2001 +From: Ming-Hung Tsai +Date: Tue, 22 Oct 2024 15:12:22 +0800 +Subject: dm cache: correct the number of origin blocks to match the target length + +From: Ming-Hung Tsai + +commit 235d2e739fcbe964c9ce179b4c991025662dcdb6 upstream. + +When creating a cache device, the actual size of the cache origin might +be greater than the specified cache target length. In such case, the +number of origin blocks should match the cache target length, not the +full size of the origin device, since access beyond the cache target is +not possible. This issue occurs when reducing the origin device size +using lvm, as lvreduce preloads the new cache table before resuming the +cache origin, which can result in incorrect sizes for the discard bitset +and smq hotspot blocks. + +Reproduce steps: + +1. create a cache device consists of 4096 origin blocks + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc 262144" +dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct +dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" + +2. reduce the cache origin to 2048 oblocks, in lvreduce's approach + +dmsetup reload corig --table "0 262144 linear /dev/sdc 262144" +dmsetup reload cache --table "0 262144 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" +dmsetup suspend cache +dmsetup suspend corig +dmsetup suspend cdata +dmsetup suspend cmeta +dmsetup resume corig +dmsetup resume cdata +dmsetup resume cmeta +dmsetup resume cache + +3. shutdown the cache, and check the number of discard blocks in + superblock. The value is expected to be 2048, but actually is 4096. + +dmsetup remove cache corig cdata cmeta +dd if=/dev/sdc bs=1c count=8 skip=224 2>/dev/null | hexdump -e '1/8 "%u\n"' + +Fix by correcting the origin_blocks initialization in cache_create and +removing the unused origin_sectors from struct cache_args accordingly. + +Signed-off-by: Ming-Hung Tsai +Fixes: c6b4fcbad044 ("dm: add cache target") +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-cache-target.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2003,7 +2003,6 @@ struct cache_args { + sector_t cache_sectors; + + struct dm_dev *origin_dev; +- sector_t origin_sectors; + + uint32_t block_size; + +@@ -2084,6 +2083,7 @@ static int parse_cache_dev(struct cache_ + static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, + char **error) + { ++ sector_t origin_sectors; + int r; + + if (!at_least_one_arg(as, error)) +@@ -2096,8 +2096,8 @@ static int parse_origin_dev(struct cache + return r; + } + +- ca->origin_sectors = get_dev_size(ca->origin_dev); +- if (ca->ti->len > ca->origin_sectors) { ++ origin_sectors = get_dev_size(ca->origin_dev); ++ if (ca->ti->len > origin_sectors) { + *error = "Device size larger than cached device"; + return -EINVAL; + } +@@ -2407,7 +2407,7 @@ static int cache_create(struct cache_arg + + ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL; + +- origin_blocks = cache->origin_sectors = ca->origin_sectors; ++ origin_blocks = cache->origin_sectors = ti->len; + origin_blocks = block_div(origin_blocks, ca->block_size); + cache->origin_blocks = to_oblock(origin_blocks); + diff --git a/queue-6.11/dm-cache-fix-flushing-uninitialized-delayed_work-on-cache_ctr-error.patch b/queue-6.11/dm-cache-fix-flushing-uninitialized-delayed_work-on-cache_ctr-error.patch new file mode 100644 index 00000000000..4e0f1edf13b --- /dev/null +++ b/queue-6.11/dm-cache-fix-flushing-uninitialized-delayed_work-on-cache_ctr-error.patch @@ -0,0 +1,107 @@ +From 135496c208ba26fd68cdef10b64ed7a91ac9a7ff Mon Sep 17 00:00:00 2001 +From: Ming-Hung Tsai +Date: Tue, 22 Oct 2024 15:12:49 +0800 +Subject: dm cache: fix flushing uninitialized delayed_work on cache_ctr error + +From: Ming-Hung Tsai + +commit 135496c208ba26fd68cdef10b64ed7a91ac9a7ff upstream. + +An unexpected WARN_ON from flush_work() may occur when cache creation +fails, caused by destroying the uninitialized delayed_work waker in the +error path of cache_create(). For example, the warning appears on the +superblock checksum error. + +Reproduce steps: + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc 262144" +dd if=/dev/urandom of=/dev/mapper/cmeta bs=4k count=1 oflag=direct +dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" + +Kernel logs: + +(snip) +WARNING: CPU: 0 PID: 84 at kernel/workqueue.c:4178 __flush_work+0x5d4/0x890 + +Fix by pulling out the cancel_delayed_work_sync() from the constructor's +error path. This patch doesn't affect the use-after-free fix for +concurrent dm_resume and dm_destroy (commit 6a459d8edbdb ("dm cache: Fix +UAF in destroy()")) as cache_dtr is not changed. + +Signed-off-by: Ming-Hung Tsai +Fixes: 6a459d8edbdb ("dm cache: Fix UAF in destroy()") +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-cache-target.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -1905,16 +1905,13 @@ static void check_migrations(struct work + * This function gets called on the error paths of the constructor, so we + * have to cope with a partially initialised struct. + */ +-static void destroy(struct cache *cache) ++static void __destroy(struct cache *cache) + { +- unsigned int i; +- + mempool_exit(&cache->migration_pool); + + if (cache->prison) + dm_bio_prison_destroy_v2(cache->prison); + +- cancel_delayed_work_sync(&cache->waker); + if (cache->wq) + destroy_workqueue(cache->wq); + +@@ -1942,13 +1939,22 @@ static void destroy(struct cache *cache) + if (cache->policy) + dm_cache_policy_destroy(cache->policy); + ++ bioset_exit(&cache->bs); ++ ++ kfree(cache); ++} ++ ++static void destroy(struct cache *cache) ++{ ++ unsigned int i; ++ ++ cancel_delayed_work_sync(&cache->waker); ++ + for (i = 0; i < cache->nr_ctr_args ; i++) + kfree(cache->ctr_args[i]); + kfree(cache->ctr_args); + +- bioset_exit(&cache->bs); +- +- kfree(cache); ++ __destroy(cache); + } + + static void cache_dtr(struct dm_target *ti) +@@ -2561,7 +2567,7 @@ static int cache_create(struct cache_arg + *result = cache; + return 0; + bad: +- destroy(cache); ++ __destroy(cache); + return r; + } + +@@ -2612,7 +2618,7 @@ static int cache_ctr(struct dm_target *t + + r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3); + if (r) { +- destroy(cache); ++ __destroy(cache); + goto out; + } + diff --git a/queue-6.11/dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch b/queue-6.11/dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch new file mode 100644 index 00000000000..a055f934557 --- /dev/null +++ b/queue-6.11/dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch @@ -0,0 +1,80 @@ +From 792227719725497ce10a8039803bec13f89f8910 Mon Sep 17 00:00:00 2001 +From: Ming-Hung Tsai +Date: Tue, 22 Oct 2024 15:13:16 +0800 +Subject: dm cache: fix out-of-bounds access to the dirty bitset when resizing + +From: Ming-Hung Tsai + +commit 792227719725497ce10a8039803bec13f89f8910 upstream. + +dm-cache checks the dirty bits of the cache blocks to be dropped when +shrinking the fast device, but an index bug in bitset iteration causes +out-of-bounds access. + +Reproduce steps: + +1. create a cache device of 1024 cache blocks (128 bytes dirty bitset) + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 131072 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc 262144" +dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct +dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" + +2. shrink the fast device to 512 cache blocks, triggering out-of-bounds + access to the dirty bitset (offset 0x80) + +dmsetup suspend cache +dmsetup reload cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup resume cdata +dmsetup resume cache + +KASAN reports: + + BUG: KASAN: vmalloc-out-of-bounds in cache_preresume+0x269/0x7b0 + Read of size 8 at addr ffffc900000f3080 by task dmsetup/131 + + (...snip...) + The buggy address belongs to the virtual mapping at + [ffffc900000f3000, ffffc900000f5000) created by: + cache_ctr+0x176a/0x35f0 + + (...snip...) + Memory state around the buggy address: + ffffc900000f2f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + ffffc900000f3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + >ffffc900000f3080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + ^ + ffffc900000f3100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + ffffc900000f3180: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + +Fix by making the index post-incremented. + +Signed-off-by: Ming-Hung Tsai +Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-cache-target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2912,13 +2912,13 @@ static bool can_resize(struct cache *cac + * We can't drop a dirty block when shrinking the cache. + */ + while (from_cblock(new_size) < from_cblock(cache->cache_size)) { +- new_size = to_cblock(from_cblock(new_size) + 1); + if (is_dirty(cache, new_size)) { + DMERR("%s: unable to shrink cache; cache block %llu is dirty", + cache_device_name(cache), + (unsigned long long) from_cblock(new_size)); + return false; + } ++ new_size = to_cblock(from_cblock(new_size) + 1); + } + + return true; diff --git a/queue-6.11/dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch b/queue-6.11/dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch new file mode 100644 index 00000000000..c993874fea9 --- /dev/null +++ b/queue-6.11/dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch @@ -0,0 +1,137 @@ +From c0ade5d98979585d4f5a93e4514c2e9a65afa08d Mon Sep 17 00:00:00 2001 +From: Ming-Hung Tsai +Date: Tue, 22 Oct 2024 15:13:54 +0800 +Subject: dm cache: fix potential out-of-bounds access on the first resume + +From: Ming-Hung Tsai + +commit c0ade5d98979585d4f5a93e4514c2e9a65afa08d upstream. + +Out-of-bounds access occurs if the fast device is expanded unexpectedly +before the first-time resume of the cache table. This happens because +expanding the fast device requires reloading the cache table for +cache_create to allocate new in-core data structures that fit the new +size, and the check in cache_preresume is not performed during the +first resume, leading to the issue. + +Reproduce steps: + +1. prepare component devices: + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc 262144" +dd if=/dev/zero of=/dev/mapper/cmeta bs=4k count=1 oflag=direct + +2. load a cache table of 512 cache blocks, and deliberately expand the + fast device before resuming the cache, making the in-core data + structures inadequate. + +dmsetup create cache --notable +dmsetup reload cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" +dmsetup reload cdata --table "0 131072 linear /dev/sdc 8192" +dmsetup resume cdata +dmsetup resume cache + +3. suspend the cache to write out the in-core dirty bitset and hint + array, leading to out-of-bounds access to the dirty bitset at offset + 0x40: + +dmsetup suspend cache + +KASAN reports: + + BUG: KASAN: vmalloc-out-of-bounds in is_dirty_callback+0x2b/0x80 + Read of size 8 at addr ffffc90000085040 by task dmsetup/90 + + (...snip...) + The buggy address belongs to the virtual mapping at + [ffffc90000085000, ffffc90000087000) created by: + cache_ctr+0x176a/0x35f0 + + (...snip...) + Memory state around the buggy address: + ffffc90000084f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + ffffc90000084f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + >ffffc90000085000: 00 00 00 00 00 00 00 00 f8 f8 f8 f8 f8 f8 f8 f8 + ^ + ffffc90000085080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + ffffc90000085100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 + +Fix by checking the size change on the first resume. + +Signed-off-by: Ming-Hung Tsai +Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-cache-target.c | 37 ++++++++++++++++--------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2901,24 +2901,24 @@ static dm_cblock_t get_cache_dev_size(st + static bool can_resize(struct cache *cache, dm_cblock_t new_size) + { + if (from_cblock(new_size) > from_cblock(cache->cache_size)) { +- if (cache->sized) { +- DMERR("%s: unable to extend cache due to missing cache table reload", +- cache_device_name(cache)); +- return false; +- } ++ DMERR("%s: unable to extend cache due to missing cache table reload", ++ cache_device_name(cache)); ++ return false; + } + + /* + * We can't drop a dirty block when shrinking the cache. + */ +- new_size = to_cblock(find_next_bit(cache->dirty_bitset, +- from_cblock(cache->cache_size), +- from_cblock(new_size))); +- if (new_size != cache->cache_size) { +- DMERR("%s: unable to shrink cache; cache block %llu is dirty", +- cache_device_name(cache), +- (unsigned long long) from_cblock(new_size)); +- return false; ++ if (cache->loaded_mappings) { ++ new_size = to_cblock(find_next_bit(cache->dirty_bitset, ++ from_cblock(cache->cache_size), ++ from_cblock(new_size))); ++ if (new_size != cache->cache_size) { ++ DMERR("%s: unable to shrink cache; cache block %llu is dirty", ++ cache_device_name(cache), ++ (unsigned long long) from_cblock(new_size)); ++ return false; ++ } + } + + return true; +@@ -2949,20 +2949,15 @@ static int cache_preresume(struct dm_tar + /* + * Check to see if the cache has resized. + */ +- if (!cache->sized) { +- r = resize_cache_dev(cache, csize); +- if (r) +- return r; +- +- cache->sized = true; +- +- } else if (csize != cache->cache_size) { ++ if (!cache->sized || csize != cache->cache_size) { + if (!can_resize(cache, csize)) + return -EINVAL; + + r = resize_cache_dev(cache, csize); + if (r) + return r; ++ ++ cache->sized = true; + } + + if (!cache->loaded_mappings) { diff --git a/queue-6.11/dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch b/queue-6.11/dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch new file mode 100644 index 00000000000..facd55039c7 --- /dev/null +++ b/queue-6.11/dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch @@ -0,0 +1,49 @@ +From f484697e619a83ecc370443a34746379ad99d204 Mon Sep 17 00:00:00 2001 +From: Ming-Hung Tsai +Date: Tue, 22 Oct 2024 15:13:39 +0800 +Subject: dm cache: optimize dirty bit checking with find_next_bit when resizing + +From: Ming-Hung Tsai + +commit f484697e619a83ecc370443a34746379ad99d204 upstream. + +When shrinking the fast device, dm-cache iteratively searches for a +dirty bit among the cache blocks to be dropped, which is less efficient. +Use find_next_bit instead, as it is twice as fast as the iterative +approach with test_bit. + +Signed-off-by: Ming-Hung Tsai +Fixes: f494a9c6b1b6 ("dm cache: cache shrinking support") +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Acked-by: Joe Thornber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-cache-target.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2911,14 +2911,14 @@ static bool can_resize(struct cache *cac + /* + * We can't drop a dirty block when shrinking the cache. + */ +- while (from_cblock(new_size) < from_cblock(cache->cache_size)) { +- if (is_dirty(cache, new_size)) { +- DMERR("%s: unable to shrink cache; cache block %llu is dirty", +- cache_device_name(cache), +- (unsigned long long) from_cblock(new_size)); +- return false; +- } +- new_size = to_cblock(from_cblock(new_size) + 1); ++ new_size = to_cblock(find_next_bit(cache->dirty_bitset, ++ from_cblock(cache->cache_size), ++ from_cblock(new_size))); ++ if (new_size != cache->cache_size) { ++ DMERR("%s: unable to shrink cache; cache block %llu is dirty", ++ cache_device_name(cache), ++ (unsigned long long) from_cblock(new_size)); ++ return false; + } + + return true; diff --git a/queue-6.11/dm-fix-a-crash-if-blk_alloc_disk-fails.patch b/queue-6.11/dm-fix-a-crash-if-blk_alloc_disk-fails.patch new file mode 100644 index 00000000000..c0b7a707db9 --- /dev/null +++ b/queue-6.11/dm-fix-a-crash-if-blk_alloc_disk-fails.patch @@ -0,0 +1,38 @@ +From fed13a5478680614ba97fc87e71f16e2e197912e Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 7 Oct 2024 13:38:12 +0200 +Subject: dm: fix a crash if blk_alloc_disk fails + +From: Mikulas Patocka + +commit fed13a5478680614ba97fc87e71f16e2e197912e upstream. + +If blk_alloc_disk fails, the variable md->disk is set to an error value. +cleanup_mapped_device will see that md->disk is non-NULL and it will +attempt to access it, causing a crash on this statement +"md->disk->private_data = NULL;". + +Signed-off-by: Mikulas Patocka +Reported-by: Chenyuan Yang +Closes: https://marc.info/?l=dm-devel&m=172824125004329&w=2 +Cc: stable@vger.kernel.org +Reviewed-by: Nitesh Shetty +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -2290,8 +2290,10 @@ static struct mapped_device *alloc_dev(i + * override accordingly. + */ + md->disk = blk_alloc_disk(NULL, md->numa_node_id); +- if (IS_ERR(md->disk)) ++ if (IS_ERR(md->disk)) { ++ md->disk = NULL; + goto bad; ++ } + md->queue = md->disk->queue; + + init_waitqueue_head(&md->wait); diff --git a/queue-6.11/dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch b/queue-6.11/dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch new file mode 100644 index 00000000000..a62061e2237 --- /dev/null +++ b/queue-6.11/dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch @@ -0,0 +1,41 @@ +From 5a4510c762fc04c74cff264cd4d9e9f5bf364bae Mon Sep 17 00:00:00 2001 +From: Zichen Xie +Date: Mon, 21 Oct 2024 14:54:45 -0500 +Subject: dm-unstriped: cast an operand to sector_t to prevent potential uint32_t overflow + +From: Zichen Xie + +commit 5a4510c762fc04c74cff264cd4d9e9f5bf364bae upstream. + +This was found by a static analyzer. +There may be a potential integer overflow issue in +unstripe_ctr(). uc->unstripe_offset and uc->unstripe_width are +defined as "sector_t"(uint64_t), while uc->unstripe, +uc->chunk_size and uc->stripes are all defined as "uint32_t". +The result of the calculation will be limited to "uint32_t" +without correct casting. +So, we recommend adding an extra cast to prevent potential +integer overflow. + +Fixes: 18a5bf270532 ("dm: add unstriped target") +Signed-off-by: Zichen Xie +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-unstripe.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/md/dm-unstripe.c ++++ b/drivers/md/dm-unstripe.c +@@ -85,8 +85,8 @@ static int unstripe_ctr(struct dm_target + } + uc->physical_start = start; + +- uc->unstripe_offset = uc->unstripe * uc->chunk_size; +- uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size; ++ uc->unstripe_offset = (sector_t)uc->unstripe * uc->chunk_size; ++ uc->unstripe_width = (sector_t)(uc->stripes - 1) * uc->chunk_size; + uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0; + + tmp_len = ti->len; diff --git a/queue-6.11/drm-amd-display-fix-brightness-level-not-retained-over-reboot.patch b/queue-6.11/drm-amd-display-fix-brightness-level-not-retained-over-reboot.patch new file mode 100644 index 00000000000..b70668e1fb6 --- /dev/null +++ b/queue-6.11/drm-amd-display-fix-brightness-level-not-retained-over-reboot.patch @@ -0,0 +1,74 @@ +From 4f26c95ffc21a91281429ed60180619bae19ae92 Mon Sep 17 00:00:00 2001 +From: Tom Chung +Date: Wed, 9 Oct 2024 17:09:38 +0800 +Subject: drm/amd/display: Fix brightness level not retained over reboot + +From: Tom Chung + +commit 4f26c95ffc21a91281429ed60180619bae19ae92 upstream. + +[Why] +During boot up and resume the DC layer will reset the panel +brightness to fix a flicker issue. + +It will cause the dm->actual_brightness is not the current panel +brightness level. (the dm->brightness is the correct panel level) + +[How] +Set the backlight level after do the set mode. + +Cc: Mario Limonciello +Cc: Alex Deucher +Fixes: d9e865826c20 ("drm/amd/display: Simplify brightness initialization") +Reported-by: Mark Herbert +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3655 +Reviewed-by: Sun peng Li +Signed-off-by: Tom Chung +Signed-off-by: Zaeem Mohamed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit 7875afafba84817b791be6d2282b836695146060) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -9384,6 +9384,7 @@ static void amdgpu_dm_commit_streams(str + bool mode_set_reset_required = false; + u32 i; + struct dc_commit_streams_params params = {dc_state->streams, dc_state->stream_count}; ++ bool set_backlight_level = false; + + /* Disable writeback */ + for_each_old_connector_in_state(state, connector, old_con_state, i) { +@@ -9503,6 +9504,7 @@ static void amdgpu_dm_commit_streams(str + acrtc->hw_mode = new_crtc_state->mode; + crtc->hwmode = new_crtc_state->mode; + mode_set_reset_required = true; ++ set_backlight_level = true; + } else if (modereset_required(new_crtc_state)) { + drm_dbg_atomic(dev, + "Atomic commit: RESET. crtc id %d:[%p]\n", +@@ -9554,6 +9556,19 @@ static void amdgpu_dm_commit_streams(str + acrtc->otg_inst = status->primary_otg_inst; + } + } ++ ++ /* During boot up and resume the DC layer will reset the panel brightness ++ * to fix a flicker issue. ++ * It will cause the dm->actual_brightness is not the current panel brightness ++ * level. (the dm->brightness is the correct panel level) ++ * So we set the backlight level with dm->brightness value after set mode ++ */ ++ if (set_backlight_level) { ++ for (i = 0; i < dm->num_of_edps; i++) { ++ if (dm->backlight_dev[i]) ++ amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]); ++ } ++ } + } + + static void dm_set_writeback(struct amdgpu_display_manager *dm, diff --git a/queue-6.11/drm-amd-display-parse-umc_info-or-vram_info-based-on-asic.patch b/queue-6.11/drm-amd-display-parse-umc_info-or-vram_info-based-on-asic.patch new file mode 100644 index 00000000000..438b93abdd1 --- /dev/null +++ b/queue-6.11/drm-amd-display-parse-umc_info-or-vram_info-based-on-asic.patch @@ -0,0 +1,46 @@ +From 694c79769cb384bca8b1ec1d1e84156e726bd106 Mon Sep 17 00:00:00 2001 +From: Aurabindo Pillai +Date: Fri, 18 Oct 2024 10:52:16 -0400 +Subject: drm/amd/display: parse umc_info or vram_info based on ASIC + +From: Aurabindo Pillai + +commit 694c79769cb384bca8b1ec1d1e84156e726bd106 upstream. + +An upstream bug report suggests that there are production dGPUs that are +older than DCN401 but still have a umc_info in VBIOS tables with the +same version as expected for a DCN401 product. Hence, reading this +tables should be guarded with a version check. + +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3678 +Reviewed-by: Dillon Varone +Signed-off-by: Aurabindo Pillai +Signed-off-by: Zaeem Mohamed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit 2551b4a321a68134360b860113dd460133e856e5) +Fixes: 00c391102abc ("drm/amd/display: Add misc DC changes for DCN401") +Cc: stable@vger.kernel.org # 6.11.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 0d8498ab9b23..be8fbb04ad98 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -3127,7 +3127,9 @@ static enum bp_result bios_parser_get_vram_info( + struct atom_data_revision revision; + + // vram info moved to umc_info for DCN4x +- if (info && DATA_TABLES(umc_info)) { ++ if (dcb->ctx->dce_version >= DCN_VERSION_4_01 && ++ dcb->ctx->dce_version < DCN_VERSION_MAX && ++ info && DATA_TABLES(umc_info)) { + header = GET_IMAGE(struct atom_common_table_header, + DATA_TABLES(umc_info)); + +-- +2.47.0 + diff --git a/queue-6.11/drm-amd-pm-always-pick-the-pptable-from-ifwi.patch b/queue-6.11/drm-amd-pm-always-pick-the-pptable-from-ifwi.patch new file mode 100644 index 00000000000..8256b9af14b --- /dev/null +++ b/queue-6.11/drm-amd-pm-always-pick-the-pptable-from-ifwi.patch @@ -0,0 +1,121 @@ +From 1356bfc54c8d4c8e7c9fb8553dc8c28e9714b07b Mon Sep 17 00:00:00 2001 +From: Kenneth Feng +Date: Fri, 1 Nov 2024 11:55:25 +0800 +Subject: drm/amd/pm: always pick the pptable from IFWI + +From: Kenneth Feng + +commit 1356bfc54c8d4c8e7c9fb8553dc8c28e9714b07b upstream. + +always pick the pptable from IFWI on smu v14.0.2/3 + +Signed-off-by: Kenneth Feng +Reviewed-by: Yang Wang +Signed-off-by: Alex Deucher +(cherry picked from commit 136ce12bd5907388cb4e9aa63ee5c9c8c441640b) +Cc: stable@vger.kernel.org # 6.11.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 65 ------------------- + 1 file changed, 1 insertion(+), 64 deletions(-) + +--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +@@ -354,54 +354,6 @@ static int smu_v14_0_2_store_powerplay_t + return 0; + } + +-#ifndef atom_smc_dpm_info_table_14_0_0 +-struct atom_smc_dpm_info_table_14_0_0 { +- struct atom_common_table_header table_header; +- BoardTable_t BoardTable; +-}; +-#endif +- +-static int smu_v14_0_2_append_powerplay_table(struct smu_context *smu) +-{ +- struct smu_table_context *table_context = &smu->smu_table; +- PPTable_t *smc_pptable = table_context->driver_pptable; +- struct atom_smc_dpm_info_table_14_0_0 *smc_dpm_table; +- BoardTable_t *BoardTable = &smc_pptable->BoardTable; +- int index, ret; +- +- index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, +- smc_dpm_info); +- +- ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL, +- (uint8_t **)&smc_dpm_table); +- if (ret) +- return ret; +- +- memcpy(BoardTable, &smc_dpm_table->BoardTable, sizeof(BoardTable_t)); +- +- return 0; +-} +- +-#if 0 +-static int smu_v14_0_2_get_pptable_from_pmfw(struct smu_context *smu, +- void **table, +- uint32_t *size) +-{ +- struct smu_table_context *smu_table = &smu->smu_table; +- void *combo_pptable = smu_table->combo_pptable; +- int ret = 0; +- +- ret = smu_cmn_get_combo_pptable(smu); +- if (ret) +- return ret; +- +- *table = combo_pptable; +- *size = sizeof(struct smu_14_0_powerplay_table); +- +- return 0; +-} +-#endif +- + static int smu_v14_0_2_get_pptable_from_pmfw(struct smu_context *smu, + void **table, + uint32_t *size) +@@ -423,16 +375,12 @@ static int smu_v14_0_2_get_pptable_from_ + static int smu_v14_0_2_setup_pptable(struct smu_context *smu) + { + struct smu_table_context *smu_table = &smu->smu_table; +- struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if (amdgpu_sriov_vf(smu->adev)) + return 0; + +- if (!adev->scpm_enabled) +- ret = smu_v14_0_setup_pptable(smu); +- else +- ret = smu_v14_0_2_get_pptable_from_pmfw(smu, ++ ret = smu_v14_0_2_get_pptable_from_pmfw(smu, + &smu_table->power_play_table, + &smu_table->power_play_table_size); + if (ret) +@@ -442,16 +390,6 @@ static int smu_v14_0_2_setup_pptable(str + if (ret) + return ret; + +- /* +- * With SCPM enabled, the operation below will be handled +- * by PSP. Driver involvment is unnecessary and useless. +- */ +- if (!adev->scpm_enabled) { +- ret = smu_v14_0_2_append_powerplay_table(smu); +- if (ret) +- return ret; +- } +- + ret = smu_v14_0_2_check_powerplay_table(smu); + if (ret) + return ret; +@@ -1938,7 +1876,6 @@ static const struct pptable_funcs smu_v1 + .check_fw_status = smu_v14_0_check_fw_status, + .setup_pptable = smu_v14_0_2_setup_pptable, + .check_fw_version = smu_v14_0_check_fw_version, +- .write_pptable = smu_cmn_write_pptable, + .set_driver_table_location = smu_v14_0_set_driver_table_location, + .system_features_control = smu_v14_0_system_features_control, + .set_allowed_mask = smu_v14_0_set_allowed_mask, diff --git a/queue-6.11/drm-amd-pm-correct-the-workload-setting.patch b/queue-6.11/drm-amd-pm-correct-the-workload-setting.patch new file mode 100644 index 00000000000..78cf488845c --- /dev/null +++ b/queue-6.11/drm-amd-pm-correct-the-workload-setting.patch @@ -0,0 +1,369 @@ +From 74e1006430a5377228e49310f6d915628609929e Mon Sep 17 00:00:00 2001 +From: Kenneth Feng +Date: Wed, 30 Oct 2024 13:22:44 +0800 +Subject: drm/amd/pm: correct the workload setting + +From: Kenneth Feng + +commit 74e1006430a5377228e49310f6d915628609929e upstream. + +Correct the workload setting in order not to mix the setting +with the end user. Update the workload mask accordingly. + +v2: changes as below: +1. the end user can not erase the workload from driver except default workload. +2. always shows the real highest priority workoad to the end user. +3. the real workload mask is combined with driver workload mask and end user workload mask. + +v3: apply this to the other ASICs as well. +v4: simplify the code +v5: refine the code based on the review comments. + +Signed-off-by: Kenneth Feng +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 8cc438be5d49b8326b2fcade0bdb7e6a97df9e0b) +Cc: stable@vger.kernel.org # 6.11.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 49 +++++++++++----- + drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 4 - + drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 5 - + drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 5 + + drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 5 + + drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 4 - + drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 4 - + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 20 ++++-- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 5 - + drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 9 +- + drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 8 ++ + drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 2 + 12 files changed, 84 insertions(+), 36 deletions(-) + +--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +@@ -1259,26 +1259,33 @@ static int smu_sw_init(void *handle) + smu->watermarks_bitmap = 0; + smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; + smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; ++ smu->user_dpm_profile.user_workload_mask = 0; + + atomic_set(&smu->smu_power.power_gate.vcn_gated, 1); + atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1); + atomic_set(&smu->smu_power.power_gate.vpe_gated, 1); + atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1); + +- smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; +- smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1; +- smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2; +- smu->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 3; +- smu->workload_prority[PP_SMC_POWER_PROFILE_VR] = 4; +- smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; +- smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_VIDEO] = 3; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_VR] = 4; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_COMPUTE] = 5; ++ smu->workload_priority[PP_SMC_POWER_PROFILE_CUSTOM] = 6; + + if (smu->is_apu || +- !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) +- smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; +- else +- smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; ++ !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D)) { ++ smu->driver_workload_mask = ++ 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; ++ } else { ++ smu->driver_workload_mask = ++ 1 << smu->workload_priority[PP_SMC_POWER_PROFILE_FULLSCREEN3D]; ++ smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_FULLSCREEN3D; ++ } + ++ smu->workload_mask = smu->driver_workload_mask | ++ smu->user_dpm_profile.user_workload_mask; + smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; + smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D; + smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING; +@@ -2348,17 +2355,20 @@ static int smu_switch_power_profile(void + return -EINVAL; + + if (!en) { +- smu->workload_mask &= ~(1 << smu->workload_prority[type]); ++ smu->driver_workload_mask &= ~(1 << smu->workload_priority[type]); + index = fls(smu->workload_mask); + index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; + workload[0] = smu->workload_setting[index]; + } else { +- smu->workload_mask |= (1 << smu->workload_prority[type]); ++ smu->driver_workload_mask |= (1 << smu->workload_priority[type]); + index = fls(smu->workload_mask); + index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; + workload[0] = smu->workload_setting[index]; + } + ++ smu->workload_mask = smu->driver_workload_mask | ++ smu->user_dpm_profile.user_workload_mask; ++ + if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && + smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) + smu_bump_power_profile_mode(smu, workload, 0); +@@ -3049,12 +3059,23 @@ static int smu_set_power_profile_mode(vo + uint32_t param_size) + { + struct smu_context *smu = handle; ++ int ret; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || + !smu->ppt_funcs->set_power_profile_mode) + return -EOPNOTSUPP; + +- return smu_bump_power_profile_mode(smu, param, param_size); ++ if (smu->user_dpm_profile.user_workload_mask & ++ (1 << smu->workload_priority[param[param_size]])) ++ return 0; ++ ++ smu->user_dpm_profile.user_workload_mask = ++ (1 << smu->workload_priority[param[param_size]]); ++ smu->workload_mask = smu->user_dpm_profile.user_workload_mask | ++ smu->driver_workload_mask; ++ ret = smu_bump_power_profile_mode(smu, param, param_size); ++ ++ return ret; + } + + static int smu_get_fan_control_mode(void *handle, u32 *fan_mode) +--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +@@ -240,6 +240,7 @@ struct smu_user_dpm_profile { + /* user clock state information */ + uint32_t clk_mask[SMU_CLK_COUNT]; + uint32_t clk_dependency; ++ uint32_t user_workload_mask; + }; + + #define SMU_TABLE_INIT(tables, table_id, s, a, d) \ +@@ -557,7 +558,8 @@ struct smu_context { + bool disable_uclk_switch; + + uint32_t workload_mask; +- uint32_t workload_prority[WORKLOAD_POLICY_MAX]; ++ uint32_t driver_workload_mask; ++ uint32_t workload_priority[WORKLOAD_POLICY_MAX]; + uint32_t workload_setting[WORKLOAD_POLICY_MAX]; + uint32_t power_profile_mode; + uint32_t default_power_profile_mode; +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +@@ -1455,7 +1455,6 @@ static int arcturus_set_power_profile_mo + return -EINVAL; + } + +- + if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && + (smu->smc_fw_version >= 0x360d00)) { + if (size != 10) +@@ -1523,14 +1522,14 @@ static int arcturus_set_power_profile_mo + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetWorkloadMask, +- 1 << workload_type, ++ smu->workload_mask, + NULL); + if (ret) { + dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type); + return ret; + } + +- smu->power_profile_mode = profile_mode; ++ smu_cmn_assign_power_profile(smu); + + return 0; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +@@ -2081,10 +2081,13 @@ static int navi10_set_power_profile_mode + smu->power_profile_mode); + if (workload_type < 0) + return -EINVAL; ++ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, +- 1 << workload_type, NULL); ++ smu->workload_mask, NULL); + if (ret) + dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__); ++ else ++ smu_cmn_assign_power_profile(smu); + + return ret; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +@@ -1786,10 +1786,13 @@ static int sienna_cichlid_set_power_prof + smu->power_profile_mode); + if (workload_type < 0) + return -EINVAL; ++ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, +- 1 << workload_type, NULL); ++ smu->workload_mask, NULL); + if (ret) + dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__); ++ else ++ smu_cmn_assign_power_profile(smu); + + return ret; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +@@ -1079,7 +1079,7 @@ static int vangogh_set_power_profile_mod + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify, +- 1 << workload_type, ++ smu->workload_mask, + NULL); + if (ret) { + dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", +@@ -1087,7 +1087,7 @@ static int vangogh_set_power_profile_mod + return ret; + } + +- smu->power_profile_mode = profile_mode; ++ smu_cmn_assign_power_profile(smu); + + return 0; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +@@ -890,14 +890,14 @@ static int renoir_set_power_profile_mode + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify, +- 1 << workload_type, ++ smu->workload_mask, + NULL); + if (ret) { + dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", workload_type); + return ret; + } + +- smu->power_profile_mode = profile_mode; ++ smu_cmn_assign_power_profile(smu); + + return 0; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +@@ -2485,7 +2485,7 @@ static int smu_v13_0_0_set_power_profile + DpmActivityMonitorCoeffInt_t *activity_monitor = + &(activity_monitor_external.DpmActivityMonitorCoeffInt); + int workload_type, ret = 0; +- u32 workload_mask, selected_workload_mask; ++ u32 workload_mask; + + smu->power_profile_mode = input[size]; + +@@ -2552,7 +2552,7 @@ static int smu_v13_0_0_set_power_profile + if (workload_type < 0) + return -EINVAL; + +- selected_workload_mask = workload_mask = 1 << workload_type; ++ workload_mask = 1 << workload_type; + + /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ + if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && +@@ -2567,12 +2567,22 @@ static int smu_v13_0_0_set_power_profile + workload_mask |= 1 << workload_type; + } + ++ smu->workload_mask |= workload_mask; + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetWorkloadMask, +- workload_mask, ++ smu->workload_mask, + NULL); +- if (!ret) +- smu->workload_mask = selected_workload_mask; ++ if (!ret) { ++ smu_cmn_assign_power_profile(smu); ++ if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) { ++ workload_type = smu_cmn_to_asic_specific_index(smu, ++ CMN2ASIC_MAPPING_WORKLOAD, ++ PP_SMC_POWER_PROFILE_FULLSCREEN3D); ++ smu->power_profile_mode = smu->workload_mask & (1 << workload_type) ++ ? PP_SMC_POWER_PROFILE_FULLSCREEN3D ++ : PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; ++ } ++ } + + return ret; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +@@ -2499,13 +2499,14 @@ static int smu_v13_0_7_set_power_profile + smu->power_profile_mode); + if (workload_type < 0) + return -EINVAL; ++ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, +- 1 << workload_type, NULL); ++ smu->workload_mask, NULL); + + if (ret) + dev_err(smu->adev->dev, "[%s] Failed to set work load mask!", __func__); + else +- smu->workload_mask = (1 << workload_type); ++ smu_cmn_assign_power_profile(smu); + + return ret; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +@@ -1508,12 +1508,11 @@ static int smu_v14_0_2_set_power_profile + if (workload_type < 0) + return -EINVAL; + +- ret = smu_cmn_send_smc_msg_with_param(smu, +- SMU_MSG_SetWorkloadMask, +- 1 << workload_type, +- NULL); ++ ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, ++ smu->workload_mask, NULL); ++ + if (!ret) +- smu->workload_mask = 1 << workload_type; ++ smu_cmn_assign_power_profile(smu); + + return ret; + } +--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +@@ -1138,6 +1138,14 @@ int smu_cmn_set_mp1_state(struct smu_con + return ret; + } + ++void smu_cmn_assign_power_profile(struct smu_context *smu) ++{ ++ uint32_t index; ++ index = fls(smu->workload_mask); ++ index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; ++ smu->power_profile_mode = smu->workload_setting[index]; ++} ++ + bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev) + { + struct pci_dev *p = NULL; +--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +@@ -130,6 +130,8 @@ void smu_cmn_init_soft_gpu_metrics(void + int smu_cmn_set_mp1_state(struct smu_context *smu, + enum pp_mp1_state mp1_state); + ++void smu_cmn_assign_power_profile(struct smu_context *smu); ++ + /* + * Helper function to make sysfs_emit_at() happy. Align buf to + * the current page boundary and record the offset. diff --git a/queue-6.11/drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch b/queue-6.11/drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch new file mode 100644 index 00000000000..d7fd0f5fa0a --- /dev/null +++ b/queue-6.11/drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch @@ -0,0 +1,31 @@ +From 4d75b9468021c73108b4439794d69e892b1d24e3 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 23 Oct 2024 16:52:08 -0400 +Subject: drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read() + +From: Alex Deucher + +commit 4d75b9468021c73108b4439794d69e892b1d24e3 upstream. + +Avoid a possible buffer overflow if size is larger than 4K. + +Reviewed-by: Yang Wang +Signed-off-by: Alex Deucher +(cherry picked from commit f5d873f5825b40d886d03bd2aede91d4cf002434) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -402,7 +402,7 @@ static ssize_t amdgpu_debugfs_gprwave_re + int r; + uint32_t *data, x; + +- if (size & 0x3 || *pos & 0x3) ++ if (size > 4096 || size & 0x3 || *pos & 0x3) + return -EINVAL; + + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); diff --git a/queue-6.11/drm-amdgpu-adjust-debugfs-eviction-and-ib-access-permissions.patch b/queue-6.11/drm-amdgpu-adjust-debugfs-eviction-and-ib-access-permissions.patch new file mode 100644 index 00000000000..45aedf37887 --- /dev/null +++ b/queue-6.11/drm-amdgpu-adjust-debugfs-eviction-and-ib-access-permissions.patch @@ -0,0 +1,37 @@ +From f790a2c494c4ef587eeeb9fca20124de76a1646f Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 23 Oct 2024 16:39:36 -0400 +Subject: drm/amdgpu: Adjust debugfs eviction and IB access permissions + +From: Alex Deucher + +commit f790a2c494c4ef587eeeb9fca20124de76a1646f upstream. + +Users should not be able to run these. + +Reviewed-by: Yang Wang +Signed-off-by: Alex Deucher +(cherry picked from commit 7ba9395430f611cfc101b1c2687732baafa239d5) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -2194,11 +2194,11 @@ int amdgpu_debugfs_init(struct amdgpu_de + amdgpu_securedisplay_debugfs_init(adev); + amdgpu_fw_attestation_debugfs_init(adev); + +- debugfs_create_file("amdgpu_evict_vram", 0444, root, adev, ++ debugfs_create_file("amdgpu_evict_vram", 0400, root, adev, + &amdgpu_evict_vram_fops); +- debugfs_create_file("amdgpu_evict_gtt", 0444, root, adev, ++ debugfs_create_file("amdgpu_evict_gtt", 0400, root, adev, + &amdgpu_evict_gtt_fops); +- debugfs_create_file("amdgpu_test_ib", 0444, root, adev, ++ debugfs_create_file("amdgpu_test_ib", 0400, root, adev, + &amdgpu_debugfs_test_ib_fops); + debugfs_create_file("amdgpu_vm_info", 0444, root, adev, + &amdgpu_debugfs_vm_info_fops); diff --git a/queue-6.11/drm-amdgpu-adjust-debugfs-register-access-permissions.patch b/queue-6.11/drm-amdgpu-adjust-debugfs-register-access-permissions.patch new file mode 100644 index 00000000000..c0eba715144 --- /dev/null +++ b/queue-6.11/drm-amdgpu-adjust-debugfs-register-access-permissions.patch @@ -0,0 +1,31 @@ +From b46dadf7e3cfe26d0b109c9c3d81b278d6c75361 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 23 Oct 2024 16:37:52 -0400 +Subject: drm/amdgpu: Adjust debugfs register access permissions + +From: Alex Deucher + +commit b46dadf7e3cfe26d0b109c9c3d81b278d6c75361 upstream. + +Regular users shouldn't have read access. + +Reviewed-by: Yang Wang +Signed-off-by: Alex Deucher +(cherry picked from commit c0cfd2e652553d607b910be47d0cc5a7f3a78641) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +@@ -1648,7 +1648,7 @@ int amdgpu_debugfs_regs_init(struct amdg + + for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { + ent = debugfs_create_file(debugfs_regs_names[i], +- S_IFREG | 0444, root, ++ S_IFREG | 0400, root, + adev, debugfs_regs[i]); + if (!i && !IS_ERR_OR_NULL(ent)) + i_size_write(ent->d_inode, adev->rmmio_size); diff --git a/queue-6.11/drm-amdgpu-fix-dpx-valid-mode-check-on-gc-9.4.3.patch b/queue-6.11/drm-amdgpu-fix-dpx-valid-mode-check-on-gc-9.4.3.patch new file mode 100644 index 00000000000..3b28ce784e7 --- /dev/null +++ b/queue-6.11/drm-amdgpu-fix-dpx-valid-mode-check-on-gc-9.4.3.patch @@ -0,0 +1,34 @@ +From 3ce3f85787352fa48fc02ef6cbd7a5e5aba93347 Mon Sep 17 00:00:00 2001 +From: Lijo Lazar +Date: Mon, 4 Nov 2024 10:36:13 +0530 +Subject: drm/amdgpu: Fix DPX valid mode check on GC 9.4.3 + +From: Lijo Lazar + +commit 3ce3f85787352fa48fc02ef6cbd7a5e5aba93347 upstream. + +For DPX mode, the number of memory partitions supported should be less +than or equal to 2. + +Fixes: 1589c82a1085 ("drm/amdgpu: Check memory ranges for valid xcp mode") +Signed-off-by: Lijo Lazar +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +(cherry picked from commit 990c4f580742de7bb78fa57420ffd182fc3ab4cd) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c ++++ b/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +@@ -484,7 +484,7 @@ static bool __aqua_vanjaram_is_valid_mod + case AMDGPU_SPX_PARTITION_MODE: + return adev->gmc.num_mem_partitions == 1 && num_xcc > 0; + case AMDGPU_DPX_PARTITION_MODE: +- return adev->gmc.num_mem_partitions != 8 && (num_xcc % 4) == 0; ++ return adev->gmc.num_mem_partitions <= 2 && (num_xcc % 4) == 0; + case AMDGPU_TPX_PARTITION_MODE: + return (adev->gmc.num_mem_partitions == 1 || + adev->gmc.num_mem_partitions == 3) && diff --git a/queue-6.11/drm-amdgpu-prevent-null-pointer-dereference-if-atif-is-not-supported.patch b/queue-6.11/drm-amdgpu-prevent-null-pointer-dereference-if-atif-is-not-supported.patch new file mode 100644 index 00000000000..57b3801156c --- /dev/null +++ b/queue-6.11/drm-amdgpu-prevent-null-pointer-dereference-if-atif-is-not-supported.patch @@ -0,0 +1,46 @@ +From a6dd15981c03f2cdc9a351a278f09b5479d53d2e Mon Sep 17 00:00:00 2001 +From: Antonio Quartulli +Date: Thu, 31 Oct 2024 16:28:48 +0100 +Subject: drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported + +From: Antonio Quartulli + +commit a6dd15981c03f2cdc9a351a278f09b5479d53d2e upstream. + +acpi_evaluate_object() may return AE_NOT_FOUND (failure), which +would result in dereferencing buffer.pointer (obj) while being NULL. + +Although this case may be unrealistic for the current code, it is +still better to protect against possible bugs. + +Bail out also when status is AE_NOT_FOUND. + +This fixes 1 FORWARD_NULL issue reported by Coverity +Report: CID 1600951: Null pointer dereferences (FORWARD_NULL) + +Signed-off-by: Antonio Quartulli +Fixes: c9b7c809b89f ("drm/amd: Guard against bad data for ATIF ACPI method") +Reviewed-by: Mario Limonciello +Link: https://lore.kernel.org/r/20241031152848.4716-1-antonio@mandelbit.com +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +(cherry picked from commit 91c9e221fe2553edf2db71627d8453f083de87a1) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +@@ -172,8 +172,8 @@ static union acpi_object *amdgpu_atif_ca + &buffer); + obj = (union acpi_object *)buffer.pointer; + +- /* Fail if calling the method fails and ATIF is supported */ +- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ++ /* Fail if calling the method fails */ ++ if (ACPI_FAILURE(status)) { + DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", + acpi_format_exception(status)); + kfree(obj); diff --git a/queue-6.11/drm-imagination-add-a-per-file-pvr-context-list.patch b/queue-6.11/drm-imagination-add-a-per-file-pvr-context-list.patch new file mode 100644 index 00000000000..927f7a71570 --- /dev/null +++ b/queue-6.11/drm-imagination-add-a-per-file-pvr-context-list.patch @@ -0,0 +1,140 @@ +From b0ef514bc6bbdeb8cc7492c0f473e14cb06b14d4 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Fri, 18 Oct 2024 15:41:36 +0000 +Subject: drm/imagination: Add a per-file PVR context list + +From: Brendan King + +commit b0ef514bc6bbdeb8cc7492c0f473e14cb06b14d4 upstream. + +This adds a linked list of VM contexts which is needed for the next patch +to be able to correctly track VM contexts for destruction on file close. + +It is only safe for VM contexts to be removed from the list and destroyed +when not in interrupt context. + +Signed-off-by: Brendan King +Signed-off-by: Matt Coster +Reviewed-by: Frank Binns +Cc: stable@vger.kernel.org +Link: https://patchwork.freedesktop.org/patch/msgid/e57128ea-f0ce-4e93-a9d4-3f033a8b06fa@imgtec.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/imagination/pvr_context.c | 14 ++++++++++++++ + drivers/gpu/drm/imagination/pvr_context.h | 3 +++ + drivers/gpu/drm/imagination/pvr_device.h | 10 ++++++++++ + drivers/gpu/drm/imagination/pvr_drv.c | 3 +++ + 4 files changed, 30 insertions(+) + +--- a/drivers/gpu/drm/imagination/pvr_context.c ++++ b/drivers/gpu/drm/imagination/pvr_context.c +@@ -17,10 +17,14 @@ + + #include + #include ++ ++#include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -354,6 +358,10 @@ int pvr_context_create(struct pvr_file * + return err; + } + ++ spin_lock(&pvr_dev->ctx_list_lock); ++ list_add_tail(&ctx->file_link, &pvr_file->contexts); ++ spin_unlock(&pvr_dev->ctx_list_lock); ++ + return 0; + + err_destroy_fw_obj: +@@ -380,6 +388,11 @@ pvr_context_release(struct kref *ref_cou + container_of(ref_count, struct pvr_context, ref_count); + struct pvr_device *pvr_dev = ctx->pvr_dev; + ++ WARN_ON(in_interrupt()); ++ spin_lock(&pvr_dev->ctx_list_lock); ++ list_del(&ctx->file_link); ++ spin_unlock(&pvr_dev->ctx_list_lock); ++ + xa_erase(&pvr_dev->ctx_ids, ctx->ctx_id); + pvr_context_destroy_queues(ctx); + pvr_fw_object_destroy(ctx->fw_obj); +@@ -451,6 +464,7 @@ void pvr_destroy_contexts_for_file(struc + void pvr_context_device_init(struct pvr_device *pvr_dev) + { + xa_init_flags(&pvr_dev->ctx_ids, XA_FLAGS_ALLOC1); ++ spin_lock_init(&pvr_dev->ctx_list_lock); + } + + /** +--- a/drivers/gpu/drm/imagination/pvr_context.h ++++ b/drivers/gpu/drm/imagination/pvr_context.h +@@ -85,6 +85,9 @@ struct pvr_context { + /** @compute: Transfer queue. */ + struct pvr_queue *transfer; + } queues; ++ ++ /** @file_link: pvr_file PVR context list link. */ ++ struct list_head file_link; + }; + + static __always_inline struct pvr_queue * +--- a/drivers/gpu/drm/imagination/pvr_device.h ++++ b/drivers/gpu/drm/imagination/pvr_device.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -293,6 +294,12 @@ struct pvr_device { + + /** @sched_wq: Workqueue for schedulers. */ + struct workqueue_struct *sched_wq; ++ ++ /** ++ * @ctx_list_lock: Lock to be held when accessing the context list in ++ * struct pvr_file. ++ */ ++ spinlock_t ctx_list_lock; + }; + + /** +@@ -344,6 +351,9 @@ struct pvr_file { + * This array is used to allocate handles returned to userspace. + */ + struct xarray vm_ctx_handles; ++ ++ /** @contexts: PVR context list. */ ++ struct list_head contexts; + }; + + /** +--- a/drivers/gpu/drm/imagination/pvr_drv.c ++++ b/drivers/gpu/drm/imagination/pvr_drv.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1326,6 +1327,8 @@ pvr_drm_driver_open(struct drm_device *d + */ + pvr_file->pvr_dev = pvr_dev; + ++ INIT_LIST_HEAD(&pvr_file->contexts); ++ + xa_init_flags(&pvr_file->ctx_handles, XA_FLAGS_ALLOC1); + xa_init_flags(&pvr_file->free_list_handles, XA_FLAGS_ALLOC1); + xa_init_flags(&pvr_file->hwrt_handles, XA_FLAGS_ALLOC1); diff --git a/queue-6.11/drm-imagination-break-an-object-reference-loop.patch b/queue-6.11/drm-imagination-break-an-object-reference-loop.patch new file mode 100644 index 00000000000..ec5be90a704 --- /dev/null +++ b/queue-6.11/drm-imagination-break-an-object-reference-loop.patch @@ -0,0 +1,167 @@ +From b04ce1e718bd55302b52d05d6873e233cb3ec7a1 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Fri, 18 Oct 2024 15:41:40 +0000 +Subject: drm/imagination: Break an object reference loop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Brendan King + +commit b04ce1e718bd55302b52d05d6873e233cb3ec7a1 upstream. + +When remaining resources are being cleaned up on driver close, +outstanding VM mappings may result in resources being leaked, due +to an object reference loop, as shown below, with each object (or +set of objects) referencing the object below it: + + PVR GEM Object + GPU scheduler "finished" fence + GPU scheduler “scheduled” fence + PVR driver “done” fence + PVR Context + PVR VM Context + PVR VM Mappings + PVR GEM Object + +The reference that the PVR VM Context has on the VM mappings is a +soft one, in the sense that the freeing of outstanding VM mappings +is done as part of VM context destruction; no reference counts are +involved, as is the case for all the other references in the loop. + +To break the reference loop during cleanup, free the outstanding +VM mappings before destroying the PVR Context associated with the +VM context. + +Signed-off-by: Brendan King +Signed-off-by: Matt Coster +Reviewed-by: Frank Binns +Cc: stable@vger.kernel.org +Link: https://patchwork.freedesktop.org/patch/msgid/8a25924f-1bb7-4d9a-a346-58e871dfb1d1@imgtec.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/imagination/pvr_context.c | 19 +++++++++++++++++++ + drivers/gpu/drm/imagination/pvr_context.h | 18 ++++++++++++++++++ + drivers/gpu/drm/imagination/pvr_vm.c | 22 ++++++++++++++++++---- + drivers/gpu/drm/imagination/pvr_vm.h | 1 + + 4 files changed, 56 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/imagination/pvr_context.c ++++ b/drivers/gpu/drm/imagination/pvr_context.c +@@ -450,11 +450,30 @@ pvr_context_destroy(struct pvr_file *pvr + */ + void pvr_destroy_contexts_for_file(struct pvr_file *pvr_file) + { ++ struct pvr_device *pvr_dev = pvr_file->pvr_dev; + struct pvr_context *ctx; + unsigned long handle; + + xa_for_each(&pvr_file->ctx_handles, handle, ctx) + pvr_context_destroy(pvr_file, handle); ++ ++ spin_lock(&pvr_dev->ctx_list_lock); ++ ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link); ++ ++ while (!list_entry_is_head(ctx, &pvr_file->contexts, file_link)) { ++ list_del_init(&ctx->file_link); ++ ++ if (pvr_context_get_if_referenced(ctx)) { ++ spin_unlock(&pvr_dev->ctx_list_lock); ++ ++ pvr_vm_unmap_all(ctx->vm_ctx); ++ ++ pvr_context_put(ctx); ++ spin_lock(&pvr_dev->ctx_list_lock); ++ } ++ ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link); ++ } ++ spin_unlock(&pvr_dev->ctx_list_lock); + } + + /** +--- a/drivers/gpu/drm/imagination/pvr_context.h ++++ b/drivers/gpu/drm/imagination/pvr_context.h +@@ -127,6 +127,24 @@ pvr_context_get(struct pvr_context *ctx) + } + + /** ++ * pvr_context_get_if_referenced() - Take an additional reference on a still ++ * referenced context. ++ * @ctx: Context pointer. ++ * ++ * Call pvr_context_put() to release. ++ * ++ * Returns: ++ * * True on success, or ++ * * false if no context pointer passed, or the context wasn't still ++ * * referenced. ++ */ ++static __always_inline bool ++pvr_context_get_if_referenced(struct pvr_context *ctx) ++{ ++ return ctx != NULL && kref_get_unless_zero(&ctx->ref_count) != 0; ++} ++ ++/** + * pvr_context_lookup() - Lookup context pointer from handle and file. + * @pvr_file: Pointer to pvr_file structure. + * @handle: Context handle. +--- a/drivers/gpu/drm/imagination/pvr_vm.c ++++ b/drivers/gpu/drm/imagination/pvr_vm.c +@@ -14,6 +14,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -597,12 +598,26 @@ err_free: + } + + /** +- * pvr_vm_context_release() - Teardown a VM context. +- * @ref_count: Pointer to reference counter of the VM context. ++ * pvr_vm_unmap_all() - Unmap all mappings associated with a VM context. ++ * @vm_ctx: Target VM context. + * + * This function ensures that no mappings are left dangling by unmapping them + * all in order of ascending device-virtual address. + */ ++void ++pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx) ++{ ++ WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start, ++ vm_ctx->gpuvm_mgr.mm_range)); ++} ++ ++/** ++ * pvr_vm_context_release() - Teardown a VM context. ++ * @ref_count: Pointer to reference counter of the VM context. ++ * ++ * This function also ensures that no mappings are left dangling by calling ++ * pvr_vm_unmap_all. ++ */ + static void + pvr_vm_context_release(struct kref *ref_count) + { +@@ -612,8 +627,7 @@ pvr_vm_context_release(struct kref *ref_ + if (vm_ctx->fw_mem_ctx_obj) + pvr_fw_object_destroy(vm_ctx->fw_mem_ctx_obj); + +- WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start, +- vm_ctx->gpuvm_mgr.mm_range)); ++ pvr_vm_unmap_all(vm_ctx); + + pvr_mmu_context_destroy(vm_ctx->mmu_ctx); + drm_gem_private_object_fini(&vm_ctx->dummy_gem); +--- a/drivers/gpu/drm/imagination/pvr_vm.h ++++ b/drivers/gpu/drm/imagination/pvr_vm.h +@@ -39,6 +39,7 @@ int pvr_vm_map(struct pvr_vm_context *vm + struct pvr_gem_object *pvr_obj, u64 pvr_obj_offset, + u64 device_addr, u64 size); + int pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size); ++void pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx); + + dma_addr_t pvr_vm_get_page_table_root_addr(struct pvr_vm_context *vm_ctx); + struct dma_resv *pvr_vm_get_dma_resv(struct pvr_vm_context *vm_ctx); diff --git a/queue-6.11/drm-panthor-be-stricter-about-io-mapping-flags.patch b/queue-6.11/drm-panthor-be-stricter-about-io-mapping-flags.patch new file mode 100644 index 00000000000..bfa7f65ac0e --- /dev/null +++ b/queue-6.11/drm-panthor-be-stricter-about-io-mapping-flags.patch @@ -0,0 +1,82 @@ +From f432a1621f049bb207e78363d9d0e3c6fa2da5db Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Tue, 5 Nov 2024 00:17:13 +0100 +Subject: drm/panthor: Be stricter about IO mapping flags + +From: Jann Horn + +commit f432a1621f049bb207e78363d9d0e3c6fa2da5db upstream. + +The current panthor_device_mmap_io() implementation has two issues: + +1. For mapping DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET, + panthor_device_mmap_io() bails if VM_WRITE is set, but does not clear + VM_MAYWRITE. That means userspace can use mprotect() to make the mapping + writable later on. This is a classic Linux driver gotcha. + I don't think this actually has any impact in practice: + When the GPU is powered, writes to the FLUSH_ID seem to be ignored; and + when the GPU is not powered, the dummy_latest_flush page provided by the + driver is deliberately designed to not do any flushes, so the only thing + writing to the dummy_latest_flush could achieve would be to make *more* + flushes happen. + +2. panthor_device_mmap_io() does not block MAP_PRIVATE mappings (which are + mappings without the VM_SHARED flag). + MAP_PRIVATE in combination with VM_MAYWRITE indicates that the VMA has + copy-on-write semantics, which for VM_PFNMAP are semi-supported but + fairly cursed. + In particular, in such a mapping, the driver can only install PTEs + during mmap() by calling remap_pfn_range() (because remap_pfn_range() + wants to **store the physical address of the mapped physical memory into + the vm_pgoff of the VMA**); installing PTEs later on with a fault + handler (as panthor does) is not supported in private mappings, and so + if you try to fault in such a mapping, vmf_insert_pfn_prot() splats when + it hits a BUG() check. + +Fix it by clearing the VM_MAYWRITE flag (userspace writing to the FLUSH_ID +doesn't make sense) and requiring VM_SHARED (copy-on-write semantics for +the FLUSH_ID don't make sense). + +Reproducers for both scenarios are in the notes of my patch on the mailing +list; I tested that these bugs exist on a Rock 5B machine. + +Note that I only compile-tested the patch, I haven't tested it; I don't +have a working kernel build setup for the test machine yet. Please test it +before applying it. + +Cc: stable@vger.kernel.org +Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block") +Signed-off-by: Jann Horn +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20241105-panthor-flush-page-fixes-v1-1-829aaf37db93@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/panthor/panthor_device.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c +index 4082c8f2951d..6fbff516c1c1 100644 +--- a/drivers/gpu/drm/panthor/panthor_device.c ++++ b/drivers/gpu/drm/panthor/panthor_device.c +@@ -390,11 +390,15 @@ int panthor_device_mmap_io(struct panthor_device *ptdev, struct vm_area_struct * + { + u64 offset = (u64)vma->vm_pgoff << PAGE_SHIFT; + ++ if ((vma->vm_flags & VM_SHARED) == 0) ++ return -EINVAL; ++ + switch (offset) { + case DRM_PANTHOR_USER_FLUSH_ID_MMIO_OFFSET: + if (vma->vm_end - vma->vm_start != PAGE_SIZE || + (vma->vm_flags & (VM_WRITE | VM_EXEC))) + return -EINVAL; ++ vm_flags_clear(vma, VM_MAYWRITE); + + break; + +-- +2.47.0 + diff --git a/queue-6.11/drm-panthor-lock-xarray-when-getting-entries-for-the-vm.patch b/queue-6.11/drm-panthor-lock-xarray-when-getting-entries-for-the-vm.patch new file mode 100644 index 00000000000..dc592acae77 --- /dev/null +++ b/queue-6.11/drm-panthor-lock-xarray-when-getting-entries-for-the-vm.patch @@ -0,0 +1,42 @@ +From 444fa5b100e5c90550d6bccfe4476efb0391b3ca Mon Sep 17 00:00:00 2001 +From: Liviu Dudau +Date: Wed, 6 Nov 2024 18:58:06 +0000 +Subject: drm/panthor: Lock XArray when getting entries for the VM + +From: Liviu Dudau + +commit 444fa5b100e5c90550d6bccfe4476efb0391b3ca upstream. + +Similar to commit cac075706f29 ("drm/panthor: Fix race when converting +group handle to group object") we need to use the XArray's internal +locking when retrieving a vm pointer from there. + +v2: Removed part of the patch that was trying to protect fetching +the heap pointer from XArray, as that operation is protected by +the @pool->lock. + +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Reported-by: Jann Horn +Cc: stable@vger.kernel.org +Signed-off-by: Liviu Dudau +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20241106185806.389089-1-liviu.dudau@arm.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1580,7 +1580,9 @@ panthor_vm_pool_get_vm(struct panthor_vm + { + struct panthor_vm *vm; + ++ xa_lock(&pool->xa); + vm = panthor_vm_get(xa_load(&pool->xa, handle)); ++ xa_unlock(&pool->xa); + + return vm; + } diff --git a/queue-6.11/keys-trusted-dcp-fix-null-dereference-in-aead-crypto-operation.patch b/queue-6.11/keys-trusted-dcp-fix-null-dereference-in-aead-crypto-operation.patch new file mode 100644 index 00000000000..5e171e3d6b9 --- /dev/null +++ b/queue-6.11/keys-trusted-dcp-fix-null-dereference-in-aead-crypto-operation.patch @@ -0,0 +1,64 @@ +From 04de7589e0a95167d803ecadd115235ba2c14997 Mon Sep 17 00:00:00 2001 +From: David Gstir +Date: Tue, 29 Oct 2024 12:34:01 +0100 +Subject: KEYS: trusted: dcp: fix NULL dereference in AEAD crypto operation + +From: David Gstir + +commit 04de7589e0a95167d803ecadd115235ba2c14997 upstream. + +When sealing or unsealing a key blob we currently do not wait for +the AEAD cipher operation to finish and simply return after submitting +the request. If there is some load on the system we can exit before +the cipher operation is done and the buffer we read from/write to +is already removed from the stack. This will e.g. result in NULL +pointer dereference errors in the DCP driver during blob creation. + +Fix this by waiting for the AEAD cipher operation to finish before +resuming the seal and unseal calls. + +Cc: stable@vger.kernel.org # v6.10+ +Fixes: 0e28bf61a5f9 ("KEYS: trusted: dcp: fix leak of blob encryption key") +Reported-by: Parthiban N +Closes: https://lore.kernel.org/keyrings/254d3bb1-6dbc-48b4-9c08-77df04baee2f@linumiz.com/ +Signed-off-by: David Gstir +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + security/keys/trusted-keys/trusted_dcp.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/security/keys/trusted-keys/trusted_dcp.c ++++ b/security/keys/trusted-keys/trusted_dcp.c +@@ -133,6 +133,7 @@ static int do_aead_crypto(u8 *in, u8 *ou + struct scatterlist src_sg, dst_sg; + struct crypto_aead *aead; + int ret; ++ DECLARE_CRYPTO_WAIT(wait); + + aead = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(aead)) { +@@ -163,8 +164,8 @@ static int do_aead_crypto(u8 *in, u8 *ou + } + + aead_request_set_crypt(aead_req, &src_sg, &dst_sg, len, nonce); +- aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, +- NULL); ++ aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, ++ crypto_req_done, &wait); + aead_request_set_ad(aead_req, 0); + + if (crypto_aead_setkey(aead, key, AES_KEYSIZE_128)) { +@@ -174,9 +175,9 @@ static int do_aead_crypto(u8 *in, u8 *ou + } + + if (do_encrypt) +- ret = crypto_aead_encrypt(aead_req); ++ ret = crypto_wait_req(crypto_aead_encrypt(aead_req), &wait); + else +- ret = crypto_aead_decrypt(aead_req); ++ ret = crypto_wait_req(crypto_aead_decrypt(aead_req), &wait); + + free_req: + aead_request_free(aead_req); diff --git a/queue-6.11/mptcp-no-admin-perm-to-list-endpoints.patch b/queue-6.11/mptcp-no-admin-perm-to-list-endpoints.patch new file mode 100644 index 00000000000..cbcb752129c --- /dev/null +++ b/queue-6.11/mptcp-no-admin-perm-to-list-endpoints.patch @@ -0,0 +1,58 @@ +From cfbbd4859882a5469f6f4945937a074ee78c4b46 Mon Sep 17 00:00:00 2001 +From: "Matthieu Baerts (NGI0)" +Date: Mon, 4 Nov 2024 13:31:41 +0100 +Subject: mptcp: no admin perm to list endpoints + +From: Matthieu Baerts (NGI0) + +commit cfbbd4859882a5469f6f4945937a074ee78c4b46 upstream. + +During the switch to YNL, the command to list all endpoints has been +accidentally restricted to users with admin permissions. + +It looks like there are no reasons to have this restriction which makes +it harder for a user to quickly check if the endpoint list has been +correctly populated by an automated tool. Best to go back to the +previous behaviour then. + +mptcp_pm_gen.c has been modified using ynl-gen-c.py: + + $ ./tools/net/ynl/ynl-gen-c.py --mode kernel \ + --spec Documentation/netlink/specs/mptcp_pm.yaml --source \ + -o net/mptcp/mptcp_pm_gen.c + +The header file doesn't need to be regenerated. + +Fixes: 1d0507f46843 ("net: mptcp: convert netlink from small_ops to ops") +Cc: stable@vger.kernel.org +Reviewed-by: Davide Caratti +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20241104-net-mptcp-misc-6-12-v1-1-c13f2ff1656f@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/netlink/specs/mptcp_pm.yaml | 1 - + net/mptcp/mptcp_pm_gen.c | 1 - + 2 files changed, 2 deletions(-) + +--- a/Documentation/netlink/specs/mptcp_pm.yaml ++++ b/Documentation/netlink/specs/mptcp_pm.yaml +@@ -293,7 +293,6 @@ operations: + doc: Get endpoint information + attribute-set: attr + dont-validate: [ strict ] +- flags: [ uns-admin-perm ] + do: &get-addr-attrs + request: + attributes: +--- a/net/mptcp/mptcp_pm_gen.c ++++ b/net/mptcp/mptcp_pm_gen.c +@@ -112,7 +112,6 @@ const struct genl_ops mptcp_pm_nl_ops[11 + .dumpit = mptcp_pm_nl_get_addr_dumpit, + .policy = mptcp_pm_get_addr_nl_policy, + .maxattr = MPTCP_PM_ATTR_TOKEN, +- .flags = GENL_UNS_ADMIN_PERM, + }, + { + .cmd = MPTCP_PM_CMD_FLUSH_ADDRS, diff --git a/queue-6.11/pwm-imx-tpm-use-correct-modulo-value-for-epwm-mode.patch b/queue-6.11/pwm-imx-tpm-use-correct-modulo-value-for-epwm-mode.patch new file mode 100644 index 00000000000..92822d58946 --- /dev/null +++ b/queue-6.11/pwm-imx-tpm-use-correct-modulo-value-for-epwm-mode.patch @@ -0,0 +1,44 @@ +From cc6a931d1f3b412263d515fd93b21fc0ca5147fe Mon Sep 17 00:00:00 2001 +From: Erik Schumacher +Date: Fri, 25 Oct 2024 08:37:00 +0000 +Subject: pwm: imx-tpm: Use correct MODULO value for EPWM mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Erik Schumacher + +commit cc6a931d1f3b412263d515fd93b21fc0ca5147fe upstream. + +The modulo register defines the period of the edge-aligned PWM mode +(which is the only mode implemented). The reference manual states: +"The EPWM period is determined by (MOD + 0001h) ..." So the value that +is written to the MOD register must therefore be one less than the +calculated period length. Return -EINVAL if the calculated length is +already zero. +A correct MODULO value is particularly relevant if the PWM has to output +a high frequency due to a low period value. + +Fixes: 738a1cfec2ed ("pwm: Add i.MX TPM PWM driver support") +Cc: stable@vger.kernel.org +Signed-off-by: Erik Schumacher +Link: https://lore.kernel.org/r/1a3890966d68b9f800d457cbf095746627495e18.camel@iris-sensing.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pwm/pwm-imx-tpm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pwm/pwm-imx-tpm.c ++++ b/drivers/pwm/pwm-imx-tpm.c +@@ -106,7 +106,9 @@ static int pwm_imx_tpm_round_state(struc + p->prescale = prescale; + + period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale; +- p->mod = period_count; ++ if (period_count == 0) ++ return -EINVAL; ++ p->mod = period_count - 1; + + /* calculate real period HW can support */ + tmp = (u64)period_count << prescale; diff --git a/queue-6.11/rpmsg-glink-handle-rejected-intent-request-better.patch b/queue-6.11/rpmsg-glink-handle-rejected-intent-request-better.patch new file mode 100644 index 00000000000..d6378c60790 --- /dev/null +++ b/queue-6.11/rpmsg-glink-handle-rejected-intent-request-better.patch @@ -0,0 +1,99 @@ +From a387e73fedd6307c0e194deaa53c42b153ff0bd6 Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Wed, 23 Oct 2024 17:24:32 +0000 +Subject: rpmsg: glink: Handle rejected intent request better + +From: Bjorn Andersson + +commit a387e73fedd6307c0e194deaa53c42b153ff0bd6 upstream. + +GLINK operates using pre-allocated buffers, aka intents, where incoming +messages are aggregated before being passed up the stack. In the case +that no suitable intents have been announced by the receiver, the sender +can request an intent to be allocated. + +The initial implementation of the response to such request dealt +with two outcomes; granted allocations, and all other cases being +considered -ECANCELLED (likely from "cancelling the operation as the +remote is going down"). + +But on some channels intent allocation is not supported, instead the +remote will pre-allocate and announce a fixed number of intents for the +sender to use. If for such channels an rpmsg_send() is being invoked +before any channels have been announced, an intent request will be +issued and as this comes back rejected the call fails with -ECANCELED. + +Given that this is reported in the same way as the remote being shut +down, there's no way for the client to differentiate the two cases. + +In line with the original GLINK design, change the return value to +-EAGAIN for the case where the remote rejects an intent allocation +request. + +It's tempting to handle this case in the GLINK core, as we expect +intents to show up in this case. But there's no way to distinguish +between this case and a rejection for a too big allocation, nor is it +possible to predict if a currently used (and seemingly suitable) intent +will be returned for reuse or not. As such, returning the error to the +client and allow it to react seems to be the only sensible solution. + +In addition to this, commit 'c05dfce0b89e ("rpmsg: glink: Wait for +intent, not just request ack")' changed the logic such that the code +always wait for an intent request response and an intent. This works out +in most cases, but in the event that an intent request is rejected and no +further intent arrives (e.g. client asks for a too big intent), the code +will stall for 10 seconds and then return -ETIMEDOUT; instead of a more +suitable error. + +This change also resulted in intent requests racing with the shutdown of +the remote would be exposed to this same problem, unless some intent +happens to arrive. A patch for this was developed and posted by Sarannya +S [1], and has been incorporated here. + +To summarize, the intent request can end in 4 ways: +- Timeout, no response arrived => return -ETIMEDOUT +- Abort TX, the edge is going away => return -ECANCELLED +- Intent request was rejected => return -EAGAIN +- Intent request was accepted, and an intent arrived => return 0 + +This patch was developed with input from Sarannya S, Deepak Kumar Singh, +and Chris Lew. + +[1] https://lore.kernel.org/all/20240925072328.1163183-1-quic_deesin@quicinc.com/ + +Fixes: c05dfce0b89e ("rpmsg: glink: Wait for intent, not just request ack") +Cc: stable@vger.kernel.org +Tested-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Reviewed-by: Chris Lew +Link: https://lore.kernel.org/r/20241023-pmic-glink-ecancelled-v2-1-ebc268129407@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/rpmsg/qcom_glink_native.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/rpmsg/qcom_glink_native.c ++++ b/drivers/rpmsg/qcom_glink_native.c +@@ -1354,14 +1354,18 @@ static int qcom_glink_request_intent(str + goto unlock; + + ret = wait_event_timeout(channel->intent_req_wq, +- READ_ONCE(channel->intent_req_result) >= 0 && +- READ_ONCE(channel->intent_received), ++ READ_ONCE(channel->intent_req_result) == 0 || ++ (READ_ONCE(channel->intent_req_result) > 0 && ++ READ_ONCE(channel->intent_received)) || ++ glink->abort_tx, + 10 * HZ); + if (!ret) { + dev_err(glink->dev, "intent request timed out\n"); + ret = -ETIMEDOUT; ++ } else if (glink->abort_tx) { ++ ret = -ECANCELED; + } else { +- ret = READ_ONCE(channel->intent_req_result) ? 0 : -ECANCELED; ++ ret = READ_ONCE(channel->intent_req_result) ? 0 : -EAGAIN; + } + + unlock: diff --git a/queue-6.11/series b/queue-6.11/series index ed42b929885..424a4cd280b 100644 --- a/queue-6.11/series +++ b/queue-6.11/series @@ -93,3 +93,30 @@ ksmbd-fix-slab-use-after-free-in-smb3_preauth_hash_rsp.patch drm-xe-fix-possible-exec-queue-leak-in-exec-ioctl.patch drm-xe-drop-vm-dma-resv-lock-on-xe_sync_in_fence_get-failure-in-exec-ioctl.patch drm-xe-set-mask-bits-for-ccs_mode-register.patch +pwm-imx-tpm-use-correct-modulo-value-for-epwm-mode.patch +tpm-lock-tpm-chip-in-tpm_pm_suspend-first.patch +rpmsg-glink-handle-rejected-intent-request-better.patch +drm-amd-pm-always-pick-the-pptable-from-ifwi.patch +drm-amd-display-fix-brightness-level-not-retained-over-reboot.patch +drm-imagination-add-a-per-file-pvr-context-list.patch +drm-imagination-break-an-object-reference-loop.patch +drm-amd-pm-correct-the-workload-setting.patch +drm-amd-display-parse-umc_info-or-vram_info-based-on-asic.patch +drm-panthor-lock-xarray-when-getting-entries-for-the-vm.patch +drm-panthor-be-stricter-about-io-mapping-flags.patch +drm-amdgpu-adjust-debugfs-eviction-and-ib-access-permissions.patch +drm-amdgpu-add-missing-size-check-in-amdgpu_debugfs_gprwave_read.patch +drm-amdgpu-adjust-debugfs-register-access-permissions.patch +drm-amdgpu-fix-dpx-valid-mode-check-on-gc-9.4.3.patch +drm-amdgpu-prevent-null-pointer-dereference-if-atif-is-not-supported.patch +thermal-drivers-qcom-lmh-remove-false-lockdep-backtrace.patch +keys-trusted-dcp-fix-null-dereference-in-aead-crypto-operation.patch +dm-cache-correct-the-number-of-origin-blocks-to-match-the-target-length.patch +dm-cache-fix-flushing-uninitialized-delayed_work-on-cache_ctr-error.patch +dm-cache-fix-out-of-bounds-access-to-the-dirty-bitset-when-resizing.patch +dm-cache-optimize-dirty-bit-checking-with-find_next_bit-when-resizing.patch +dm-cache-fix-potential-out-of-bounds-access-on-the-first-resume.patch +dm-unstriped-cast-an-operand-to-sector_t-to-prevent-potential-uint32_t-overflow.patch +dm-fix-a-crash-if-blk_alloc_disk-fails.patch +mptcp-no-admin-perm-to-list-endpoints.patch +alsa-usb-audio-add-quirk-for-hp-320-fhd-webcam.patch diff --git a/queue-6.11/thermal-drivers-qcom-lmh-remove-false-lockdep-backtrace.patch b/queue-6.11/thermal-drivers-qcom-lmh-remove-false-lockdep-backtrace.patch new file mode 100644 index 00000000000..4af5abdb635 --- /dev/null +++ b/queue-6.11/thermal-drivers-qcom-lmh-remove-false-lockdep-backtrace.patch @@ -0,0 +1,86 @@ +From f16beaaee248eaa37ad40b5905924fcf70ae02e3 Mon Sep 17 00:00:00 2001 +From: Dmitry Baryshkov +Date: Fri, 11 Oct 2024 08:48:39 +0300 +Subject: thermal/drivers/qcom/lmh: Remove false lockdep backtrace + +From: Dmitry Baryshkov + +commit f16beaaee248eaa37ad40b5905924fcf70ae02e3 upstream. + +Annotate LMH IRQs with lockdep classes so that the lockdep doesn't +report possible recursive locking issue between LMH and GIC interrupts. + +For the reference: + + CPU0 + ---- + lock(&irq_desc_lock_class); + lock(&irq_desc_lock_class); + + *** DEADLOCK *** + +Call trace: + dump_backtrace+0x98/0xf0 + show_stack+0x18/0x24 + dump_stack_lvl+0x90/0xd0 + dump_stack+0x18/0x24 + print_deadlock_bug+0x258/0x348 + __lock_acquire+0x1078/0x1f44 + lock_acquire+0x1fc/0x32c + _raw_spin_lock_irqsave+0x60/0x88 + __irq_get_desc_lock+0x58/0x98 + enable_irq+0x38/0xa0 + lmh_enable_interrupt+0x2c/0x38 + irq_enable+0x40/0x8c + __irq_startup+0x78/0xa4 + irq_startup+0x78/0x168 + __enable_irq+0x70/0x7c + enable_irq+0x4c/0xa0 + qcom_cpufreq_ready+0x20/0x2c + cpufreq_online+0x2a8/0x988 + cpufreq_add_dev+0x80/0x98 + subsys_interface_register+0x104/0x134 + cpufreq_register_driver+0x150/0x234 + qcom_cpufreq_hw_driver_probe+0x2a8/0x388 + platform_probe+0x68/0xc0 + really_probe+0xbc/0x298 + __driver_probe_device+0x78/0x12c + driver_probe_device+0x3c/0x160 + __device_attach_driver+0xb8/0x138 + bus_for_each_drv+0x84/0xe0 + __device_attach+0x9c/0x188 + device_initial_probe+0x14/0x20 + bus_probe_device+0xac/0xb0 + deferred_probe_work_func+0x8c/0xc8 + process_one_work+0x20c/0x62c + worker_thread+0x1bc/0x36c + kthread+0x120/0x124 + ret_from_fork+0x10/0x20 + +Fixes: 53bca371cdf7 ("thermal/drivers/qcom: Add support for LMh driver") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20241011-lmh-lockdep-v1-1-495cbbe6fef1@linaro.org +Signed-off-by: Daniel Lezcano +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thermal/qcom/lmh.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/thermal/qcom/lmh.c ++++ b/drivers/thermal/qcom/lmh.c +@@ -73,7 +73,14 @@ static struct irq_chip lmh_irq_chip = { + static int lmh_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) + { + struct lmh_hw_data *lmh_data = d->host_data; ++ static struct lock_class_key lmh_lock_key; ++ static struct lock_class_key lmh_request_key; + ++ /* ++ * This lock class tells lockdep that GPIO irqs are in a different ++ * category than their parents, so it won't report false recursion. ++ */ ++ irq_set_lockdep_class(irq, &lmh_lock_key, &lmh_request_key); + irq_set_chip_and_handler(irq, &lmh_irq_chip, handle_simple_irq); + irq_set_chip_data(irq, lmh_data); + diff --git a/queue-6.11/tpm-lock-tpm-chip-in-tpm_pm_suspend-first.patch b/queue-6.11/tpm-lock-tpm-chip-in-tpm_pm_suspend-first.patch new file mode 100644 index 00000000000..f4c82942ad5 --- /dev/null +++ b/queue-6.11/tpm-lock-tpm-chip-in-tpm_pm_suspend-first.patch @@ -0,0 +1,110 @@ +From 9265fed6db601ee2ec47577815387458ef4f047a Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Thu, 31 Oct 2024 02:16:09 +0200 +Subject: tpm: Lock TPM chip in tpm_pm_suspend() first + +From: Jarkko Sakkinen + +commit 9265fed6db601ee2ec47577815387458ef4f047a upstream. + +Setting TPM_CHIP_FLAG_SUSPENDED in the end of tpm_pm_suspend() can be racy +according, as this leaves window for tpm_hwrng_read() to be called while +the operation is in progress. The recent bug report gives also evidence of +this behaviour. + +Aadress this by locking the TPM chip before checking any chip->flags both +in tpm_pm_suspend() and tpm_hwrng_read(). Move TPM_CHIP_FLAG_SUSPENDED +check inside tpm_get_random() so that it will be always checked only when +the lock is reserved. + +Cc: stable@vger.kernel.org # v6.4+ +Fixes: 99d464506255 ("tpm: Prevent hwrng from activating during resume") +Reported-by: Mike Seo +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219383 +Reviewed-by: Jerry Snitselaar +Tested-by: Mike Seo +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/tpm/tpm-chip.c | 4 ---- + drivers/char/tpm/tpm-interface.c | 32 ++++++++++++++++++++++---------- + 2 files changed, 22 insertions(+), 14 deletions(-) + +--- a/drivers/char/tpm/tpm-chip.c ++++ b/drivers/char/tpm/tpm-chip.c +@@ -525,10 +525,6 @@ static int tpm_hwrng_read(struct hwrng * + { + struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); + +- /* Give back zero bytes, as TPM chip has not yet fully resumed: */ +- if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) +- return 0; +- + return tpm_get_random(chip, data, max); + } + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -370,6 +370,13 @@ int tpm_pm_suspend(struct device *dev) + if (!chip) + return -ENODEV; + ++ rc = tpm_try_get_ops(chip); ++ if (rc) { ++ /* Can be safely set out of locks, as no action cannot race: */ ++ chip->flags |= TPM_CHIP_FLAG_SUSPENDED; ++ goto out; ++ } ++ + if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) + goto suspended; + +@@ -377,21 +384,19 @@ int tpm_pm_suspend(struct device *dev) + !pm_suspend_via_firmware()) + goto suspended; + +- rc = tpm_try_get_ops(chip); +- if (!rc) { +- if (chip->flags & TPM_CHIP_FLAG_TPM2) { +- tpm2_end_auth_session(chip); +- tpm2_shutdown(chip, TPM2_SU_STATE); +- } else { +- rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); +- } +- +- tpm_put_ops(chip); ++ if (chip->flags & TPM_CHIP_FLAG_TPM2) { ++ tpm2_end_auth_session(chip); ++ tpm2_shutdown(chip, TPM2_SU_STATE); ++ goto suspended; + } + ++ rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); ++ + suspended: + chip->flags |= TPM_CHIP_FLAG_SUSPENDED; ++ tpm_put_ops(chip); + ++out: + if (rc) + dev_err(dev, "Ignoring error %d while suspending\n", rc); + return 0; +@@ -440,11 +445,18 @@ int tpm_get_random(struct tpm_chip *chip + if (!chip) + return -ENODEV; + ++ /* Give back zero bytes, as TPM chip has not yet fully resumed: */ ++ if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) { ++ rc = 0; ++ goto out; ++ } ++ + if (chip->flags & TPM_CHIP_FLAG_TPM2) + rc = tpm2_get_random(chip, out, max); + else + rc = tpm1_get_random(chip, out, max); + ++out: + tpm_put_ops(chip); + return rc; + }