From 437fabc4682d26deb59372ec52cea3055e678585 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 7 Feb 2026 16:02:19 +0100 Subject: [PATCH] 6.12-stable patches added patches: alsa-aloop-fix-racy-access-at-pcm-trigger.patch arm-9468-1-fix-memset64-on-big-endian.patch ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch gve-correct-ethtool-rx_dropped-calculation.patch gve-fix-stats-report-corruption-on-queue-count-change.patch mm-shmem-prevent-infinite-loop-on-truncate-race.patch mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch x86-kfence-fix-booting-on-32bit-non-pae-systems.patch x86-vmware-fix-hypercall-clobbers.patch --- ...aloop-fix-racy-access-at-pcm-trigger.patch | 117 +++++++++++ ...rm-9468-1-fix-memset64-on-big-endian.patch | 40 ++++ ...r-dereference-in-ceph_mds_auth_match.patch | 182 ++++++++++++++++++ ...-pointer-for-kfree-in-parse_longname.patch | 67 +++++++ ...rrect-ethtool-rx_dropped-calculation.patch | 111 +++++++++++ ...ort-corruption-on-queue-count-change.patch | 131 +++++++++++++ ...event-infinite-loop-on-truncate-race.patch | 84 ++++++++ ...ee_hook-for-memcg_alloc_abort_single.patch | 99 ++++++++++ ...try-fix-swapped-arrays-in-pss-output.patch | 54 ++++++ ...m-gpu-hang-due-to-wrong-adb400-reset.patch | 67 +++++++ ...ix-out-of-range-access-of-bc-domains.patch | 32 +++ ...pc-power-domain-on-for-system-wakeup.patch | 109 +++++++++++ ...hy-power-domain-on-for-system-wakeup.patch | 52 +++++ ...ror-in-clamping-to-the-highest-state.patch | 40 ++++ ...exclusive-lock-is-ensured-to-be-held.patch | 94 +++++++++ ...-aspm-is-enabled-from-pcie-subsystem.patch | 46 +++++ queue-6.12/series | 18 ++ ...fix-booting-on-32bit-non-pae-systems.patch | 68 +++++++ .../x86-vmware-fix-hypercall-clobbers.patch | 75 ++++++++ 19 files changed, 1486 insertions(+) create mode 100644 queue-6.12/alsa-aloop-fix-racy-access-at-pcm-trigger.patch create mode 100644 queue-6.12/arm-9468-1-fix-memset64-on-big-endian.patch create mode 100644 queue-6.12/ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch create mode 100644 queue-6.12/ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch create mode 100644 queue-6.12/gve-correct-ethtool-rx_dropped-calculation.patch create mode 100644 queue-6.12/gve-fix-stats-report-corruption-on-queue-count-change.patch create mode 100644 queue-6.12/mm-shmem-prevent-infinite-loop-on-truncate-race.patch create mode 100644 queue-6.12/mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch create mode 100644 queue-6.12/platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch create mode 100644 queue-6.12/pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch create mode 100644 queue-6.12/pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch create mode 100644 queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch create mode 100644 queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch create mode 100644 queue-6.12/pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch create mode 100644 queue-6.12/rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch create mode 100644 queue-6.12/revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch create mode 100644 queue-6.12/x86-kfence-fix-booting-on-32bit-non-pae-systems.patch create mode 100644 queue-6.12/x86-vmware-fix-hypercall-clobbers.patch diff --git a/queue-6.12/alsa-aloop-fix-racy-access-at-pcm-trigger.patch b/queue-6.12/alsa-aloop-fix-racy-access-at-pcm-trigger.patch new file mode 100644 index 0000000000..b89d05d87e --- /dev/null +++ b/queue-6.12/alsa-aloop-fix-racy-access-at-pcm-trigger.patch @@ -0,0 +1,117 @@ +From 826af7fa62e347464b1b4e0ba2fe19a92438084f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 3 Feb 2026 15:09:59 +0100 +Subject: ALSA: aloop: Fix racy access at PCM trigger + +From: Takashi Iwai + +commit 826af7fa62e347464b1b4e0ba2fe19a92438084f upstream. + +The PCM trigger callback of aloop driver tries to check the PCM state +and stop the stream of the tied substream in the corresponding cable. +Since both check and stop operations are performed outside the cable +lock, this may result in UAF when a program attempts to trigger +frequently while opening/closing the tied stream, as spotted by +fuzzers. + +For addressing the UAF, this patch changes two things: +- It covers the most of code in loopback_check_format() with + cable->lock spinlock, and add the proper NULL checks. This avoids + already some racy accesses. +- In addition, now we try to check the state of the capture PCM stream + that may be stopped in this function, which was the major pain point + leading to UAF. + +Reported-by: syzbot+5f8f3acdee1ec7a7ef7b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/69783ba1.050a0220.c9109.0011.GAE@google.com +Cc: +Link: https://patch.msgid.link/20260203141003.116584-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/drivers/aloop.c | 62 +++++++++++++++++++++++++++++--------------------- + 1 file changed, 36 insertions(+), 26 deletions(-) + +--- a/sound/drivers/aloop.c ++++ b/sound/drivers/aloop.c +@@ -335,37 +335,43 @@ static bool is_access_interleaved(snd_pc + + static int loopback_check_format(struct loopback_cable *cable, int stream) + { ++ struct loopback_pcm *dpcm_play, *dpcm_capt; + struct snd_pcm_runtime *runtime, *cruntime; + struct loopback_setup *setup; + struct snd_card *card; ++ bool stop_capture = false; + int check; + +- if (cable->valid != CABLE_VALID_BOTH) { +- if (stream == SNDRV_PCM_STREAM_PLAYBACK) +- goto __notify; +- return 0; +- } +- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> +- substream->runtime; +- cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> +- substream->runtime; +- check = runtime->format != cruntime->format || +- runtime->rate != cruntime->rate || +- runtime->channels != cruntime->channels || +- is_access_interleaved(runtime->access) != +- is_access_interleaved(cruntime->access); +- if (!check) +- return 0; +- if (stream == SNDRV_PCM_STREAM_CAPTURE) { +- return -EIO; +- } else { +- snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> +- substream, SNDRV_PCM_STATE_DRAINING); +- __notify: +- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> +- substream->runtime; +- setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]); +- card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card; ++ scoped_guard(spinlock_irqsave, &cable->lock) { ++ dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; ++ dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE]; ++ ++ if (cable->valid != CABLE_VALID_BOTH) { ++ if (stream == SNDRV_PCM_STREAM_CAPTURE || !dpcm_play) ++ return 0; ++ } else { ++ if (!dpcm_play || !dpcm_capt) ++ return -EIO; ++ runtime = dpcm_play->substream->runtime; ++ cruntime = dpcm_capt->substream->runtime; ++ if (!runtime || !cruntime) ++ return -EIO; ++ check = runtime->format != cruntime->format || ++ runtime->rate != cruntime->rate || ++ runtime->channels != cruntime->channels || ++ is_access_interleaved(runtime->access) != ++ is_access_interleaved(cruntime->access); ++ if (!check) ++ return 0; ++ if (stream == SNDRV_PCM_STREAM_CAPTURE) ++ return -EIO; ++ else if (cruntime->state == SNDRV_PCM_STATE_RUNNING) ++ stop_capture = true; ++ } ++ ++ setup = get_setup(dpcm_play); ++ card = dpcm_play->loopback->card; ++ runtime = dpcm_play->substream->runtime; + if (setup->format != runtime->format) { + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, + &setup->format_id); +@@ -388,6 +394,10 @@ static int loopback_check_format(struct + setup->access = runtime->access; + } + } ++ ++ if (stop_capture) ++ snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING); ++ + return 0; + } + diff --git a/queue-6.12/arm-9468-1-fix-memset64-on-big-endian.patch b/queue-6.12/arm-9468-1-fix-memset64-on-big-endian.patch new file mode 100644 index 0000000000..665d71ad3f --- /dev/null +++ b/queue-6.12/arm-9468-1-fix-memset64-on-big-endian.patch @@ -0,0 +1,40 @@ +From 23ea2a4c72323feb6e3e025e8a6f18336513d5ad Mon Sep 17 00:00:00 2001 +From: Thomas Weissschuh +Date: Wed, 7 Jan 2026 11:01:49 +0100 +Subject: ARM: 9468/1: fix memset64() on big-endian +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weissschuh + +commit 23ea2a4c72323feb6e3e025e8a6f18336513d5ad upstream. + +On big-endian systems the 32-bit low and high halves need to be swapped +for the underlying assembly implementation to work correctly. + +Fixes: fd1d362600e2 ("ARM: implement memset32 & memset64") +Cc: stable@vger.kernel.org +Signed-off-by: Thomas Weißschuh +Reviewed-by: Matthew Wilcox (Oracle) +Reviewed-by: Arnd Bergmann +Signed-off-by: Russell King (Oracle) +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/include/asm/string.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/arch/arm/include/asm/string.h ++++ b/arch/arm/include/asm/string.h +@@ -42,7 +42,10 @@ static inline void *memset32(uint32_t *p + extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); + static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) + { +- return __memset64(p, v, n * 8, v >> 32); ++ if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) ++ return __memset64(p, v, n * 8, v >> 32); ++ else ++ return __memset64(p, v >> 32, n * 8, v); + } + + /* diff --git a/queue-6.12/ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch b/queue-6.12/ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch new file mode 100644 index 0000000000..1795a3a35a --- /dev/null +++ b/queue-6.12/ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch @@ -0,0 +1,182 @@ +From 7987cce375ac8ce98e170a77aa2399f2cf6eb99f Mon Sep 17 00:00:00 2001 +From: Viacheslav Dubeyko +Date: Tue, 3 Feb 2026 14:54:46 -0800 +Subject: ceph: fix NULL pointer dereference in ceph_mds_auth_match() + +From: Viacheslav Dubeyko + +commit 7987cce375ac8ce98e170a77aa2399f2cf6eb99f upstream. + +The CephFS kernel client has regression starting from 6.18-rc1. +We have issue in ceph_mds_auth_match() if fs_name == NULL: + + const char fs_name = mdsc->fsc->mount_options->mds_namespace; + ... + if (auth->match.fs_name && strcmp(auth->match.fs_name, fs_name)) { + / fsname mismatch, try next one */ + return 0; + } + +Patrick Donnelly suggested that: In summary, we should definitely start +decoding `fs_name` from the MDSMap and do strict authorizations checks +against it. Note that the `-o mds_namespace=foo` should only be used for +selecting the file system to mount and nothing else. It's possible +no mds_namespace is specified but the kernel will mount the only +file system that exists which may have name "foo". + +This patch reworks ceph_mdsmap_decode() and namespace_equals() with +the goal of supporting the suggested concept. Now struct ceph_mdsmap +contains m_fs_name field that receives copy of extracted FS name +by ceph_extract_encoded_string(). For the case of "old" CephFS file +systems, it is used "cephfs" name. + +[ idryomov: replace redundant %*pE with %s in ceph_mdsmap_decode(), + get rid of a series of strlen() calls in ceph_namespace_match(), + drop changes to namespace_equals() body to avoid treating empty + mds_namespace as equal, drop changes to ceph_mdsc_handle_fsmap() + as namespace_equals() isn't an equivalent substitution there ] + +Cc: stable@vger.kernel.org +Fixes: 22c73d52a6d0 ("ceph: fix multifs mds auth caps issue") +Link: https://tracker.ceph.com/issues/73886 +Signed-off-by: Viacheslav Dubeyko +Reviewed-by: Patrick Donnelly +Tested-by: Patrick Donnelly +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/mds_client.c | 5 +++-- + fs/ceph/mdsmap.c | 26 +++++++++++++++++++------- + fs/ceph/mdsmap.h | 1 + + fs/ceph/super.h | 16 ++++++++++++++-- + include/linux/ceph/ceph_fs.h | 6 ++++++ + 5 files changed, 43 insertions(+), 11 deletions(-) + +--- a/fs/ceph/mds_client.c ++++ b/fs/ceph/mds_client.c +@@ -5652,7 +5652,7 @@ static int ceph_mds_auth_match(struct ce + u32 caller_uid = from_kuid(&init_user_ns, cred->fsuid); + u32 caller_gid = from_kgid(&init_user_ns, cred->fsgid); + struct ceph_client *cl = mdsc->fsc->client; +- const char *fs_name = mdsc->fsc->mount_options->mds_namespace; ++ const char *fs_name = mdsc->mdsmap->m_fs_name; + const char *spath = mdsc->fsc->mount_options->server_path; + bool gid_matched = false; + u32 gid, tlen, len; +@@ -5660,7 +5660,8 @@ static int ceph_mds_auth_match(struct ce + + doutc(cl, "fsname check fs_name=%s match.fs_name=%s\n", + fs_name, auth->match.fs_name ? auth->match.fs_name : ""); +- if (auth->match.fs_name && strcmp(auth->match.fs_name, fs_name)) { ++ ++ if (!ceph_namespace_match(auth->match.fs_name, fs_name)) { + /* fsname mismatch, try next one */ + return 0; + } +--- a/fs/ceph/mdsmap.c ++++ b/fs/ceph/mdsmap.c +@@ -353,22 +353,33 @@ struct ceph_mdsmap *ceph_mdsmap_decode(s + __decode_and_drop_type(p, end, u8, bad_ext); + } + if (mdsmap_ev >= 8) { +- u32 fsname_len; ++ size_t fsname_len; ++ + /* enabled */ + ceph_decode_8_safe(p, end, m->m_enabled, bad_ext); ++ + /* fs_name */ +- ceph_decode_32_safe(p, end, fsname_len, bad_ext); ++ m->m_fs_name = ceph_extract_encoded_string(p, end, ++ &fsname_len, ++ GFP_NOFS); ++ if (IS_ERR(m->m_fs_name)) { ++ m->m_fs_name = NULL; ++ goto nomem; ++ } + + /* validate fsname against mds_namespace */ +- if (!namespace_equals(mdsc->fsc->mount_options, *p, ++ if (!namespace_equals(mdsc->fsc->mount_options, m->m_fs_name, + fsname_len)) { +- pr_warn_client(cl, "fsname %*pE doesn't match mds_namespace %s\n", +- (int)fsname_len, (char *)*p, ++ pr_warn_client(cl, "fsname %s doesn't match mds_namespace %s\n", ++ m->m_fs_name, + mdsc->fsc->mount_options->mds_namespace); + goto bad; + } +- /* skip fsname after validation */ +- ceph_decode_skip_n(p, end, fsname_len, bad); ++ } else { ++ m->m_enabled = false; ++ m->m_fs_name = kstrdup(CEPH_OLD_FS_NAME, GFP_NOFS); ++ if (!m->m_fs_name) ++ goto nomem; + } + /* damaged */ + if (mdsmap_ev >= 9) { +@@ -430,6 +441,7 @@ void ceph_mdsmap_destroy(struct ceph_mds + kfree(m->m_info); + } + kfree(m->m_data_pg_pools); ++ kfree(m->m_fs_name); + kfree(m); + } + +--- a/fs/ceph/mdsmap.h ++++ b/fs/ceph/mdsmap.h +@@ -45,6 +45,7 @@ struct ceph_mdsmap { + bool m_enabled; + bool m_damaged; + int m_num_laggy; ++ char *m_fs_name; + }; + + static inline struct ceph_entity_addr * +--- a/fs/ceph/super.h ++++ b/fs/ceph/super.h +@@ -104,14 +104,26 @@ struct ceph_mount_options { + struct fscrypt_dummy_policy dummy_enc_policy; + }; + ++#define CEPH_NAMESPACE_WILDCARD "*" ++ ++static inline bool ceph_namespace_match(const char *pattern, ++ const char *target) ++{ ++ if (!pattern || !pattern[0] || ++ !strcmp(pattern, CEPH_NAMESPACE_WILDCARD)) ++ return true; ++ ++ return !strcmp(pattern, target); ++} ++ + /* + * Check if the mds namespace in ceph_mount_options matches + * the passed in namespace string. First time match (when + * ->mds_namespace is NULL) is treated specially, since + * ->mds_namespace needs to be initialized by the caller. + */ +-static inline int namespace_equals(struct ceph_mount_options *fsopt, +- const char *namespace, size_t len) ++static inline bool namespace_equals(struct ceph_mount_options *fsopt, ++ const char *namespace, size_t len) + { + return !(fsopt->mds_namespace && + (strlen(fsopt->mds_namespace) != len || +--- a/include/linux/ceph/ceph_fs.h ++++ b/include/linux/ceph/ceph_fs.h +@@ -31,6 +31,12 @@ + #define CEPH_INO_CEPH 2 /* hidden .ceph dir */ + #define CEPH_INO_GLOBAL_SNAPREALM 3 /* global dummy snaprealm */ + ++/* ++ * name for "old" CephFS file systems, ++ * see ceph.git e2b151d009640114b2565c901d6f41f6cd5ec652 ++ */ ++#define CEPH_OLD_FS_NAME "cephfs" ++ + /* arbitrary limit on max # of monitors (cluster of 3 is typical) */ + #define CEPH_MAX_MON 31 + diff --git a/queue-6.12/ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch b/queue-6.12/ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch new file mode 100644 index 0000000000..87297b171a --- /dev/null +++ b/queue-6.12/ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch @@ -0,0 +1,67 @@ +From bc8dedae022ce3058659c3addef3ec4b41d15e00 Mon Sep 17 00:00:00 2001 +From: Daniel Vogelbacher +Date: Sun, 1 Feb 2026 09:34:01 +0100 +Subject: ceph: fix oops due to invalid pointer for kfree() in parse_longname() + +From: Daniel Vogelbacher + +commit bc8dedae022ce3058659c3addef3ec4b41d15e00 upstream. + +This fixes a kernel oops when reading ceph snapshot directories (.snap), +for example by simply running `ls /mnt/my_ceph/.snap`. + +The variable str is guarded by __free(kfree), but advanced by one for +skipping the initial '_' in snapshot names. Thus, kfree() is called +with an invalid pointer. This patch removes the need for advancing the +pointer so kfree() is called with correct memory pointer. + +Steps to reproduce: + +1. Create snapshots on a cephfs volume (I've 63 snaps in my testcase) + +2. Add cephfs mount to fstab +$ echo "samba-fileserver@.files=/volumes/datapool/stuff/3461082b-ecc9-4e82-8549-3fd2590d3fb6 /mnt/test/stuff ceph acl,noatime,_netdev 0 0" >> /etc/fstab + +3. Reboot the system +$ systemctl reboot + +4. Check if it's really mounted +$ mount | grep stuff + +5. List snapshots (expected 63 snapshots on my system) +$ ls /mnt/test/stuff/.snap + +Now ls hangs forever and the kernel log shows the oops. + +Cc: stable@vger.kernel.org +Fixes: 101841c38346 ("[ceph] parse_longname(): strrchr() expects NUL-terminated string") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220807 +Suggested-by: Helge Deller +Signed-off-by: Daniel Vogelbacher +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ceph/crypto.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/fs/ceph/crypto.c ++++ b/fs/ceph/crypto.c +@@ -217,12 +217,13 @@ static struct inode *parse_longname(cons + struct ceph_vino vino = { .snap = CEPH_NOSNAP }; + char *name_end, *inode_number; + int ret = -EIO; +- /* NUL-terminate */ +- char *str __free(kfree) = kmemdup_nul(name, *name_len, GFP_KERNEL); ++ /* Snapshot name must start with an underscore */ ++ if (*name_len <= 0 || name[0] != '_') ++ return ERR_PTR(-EIO); ++ /* Skip initial '_' and NUL-terminate */ ++ char *str __free(kfree) = kmemdup_nul(name + 1, *name_len - 1, GFP_KERNEL); + if (!str) + return ERR_PTR(-ENOMEM); +- /* Skip initial '_' */ +- str++; + name_end = strrchr(str, '_'); + if (!name_end) { + doutc(cl, "failed to parse long snapshot name: %s\n", str); diff --git a/queue-6.12/gve-correct-ethtool-rx_dropped-calculation.patch b/queue-6.12/gve-correct-ethtool-rx_dropped-calculation.patch new file mode 100644 index 0000000000..efe8610382 --- /dev/null +++ b/queue-6.12/gve-correct-ethtool-rx_dropped-calculation.patch @@ -0,0 +1,111 @@ +From c7db85d579a1dccb624235534508c75fbf2dfe46 Mon Sep 17 00:00:00 2001 +From: Max Yuan +Date: Mon, 2 Feb 2026 19:39:25 +0000 +Subject: gve: Correct ethtool rx_dropped calculation + +From: Max Yuan + +commit c7db85d579a1dccb624235534508c75fbf2dfe46 upstream. + +The gve driver's "rx_dropped" statistic, exposed via `ethtool -S`, +incorrectly includes `rx_buf_alloc_fail` counts. These failures +represent an inability to allocate receive buffers, not true packet +drops where a received packet is discarded. This misrepresentation can +lead to inaccurate diagnostics. + +This patch rectifies the ethtool "rx_dropped" calculation. It removes +`rx_buf_alloc_fail` from the total and adds `xdp_tx_errors` and +`xdp_redirect_errors`, which represent legitimate packet drops within +the XDP path. + +Cc: stable@vger.kernel.org +Fixes: 433e274b8f7b ("gve: Add stats for gve.") +Signed-off-by: Max Yuan +Reviewed-by: Jordan Rhee +Reviewed-by: Joshua Washington +Reviewed-by: Matt Olson +Signed-off-by: Harshitha Ramamurthy +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260202193925.3106272-3-hramamurthy@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/google/gve/gve_ethtool.c | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/google/gve/gve_ethtool.c ++++ b/drivers/net/ethernet/google/gve/gve_ethtool.c +@@ -152,10 +152,11 @@ gve_get_ethtool_stats(struct net_device + u64 tmp_rx_pkts, tmp_rx_hsplit_pkt, tmp_rx_bytes, tmp_rx_hsplit_bytes, + tmp_rx_skb_alloc_fail, tmp_rx_buf_alloc_fail, + tmp_rx_desc_err_dropped_pkt, tmp_rx_hsplit_unsplit_pkt, +- tmp_tx_pkts, tmp_tx_bytes; ++ tmp_tx_pkts, tmp_tx_bytes, ++ tmp_xdp_tx_errors, tmp_xdp_redirect_errors; + u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_hsplit_unsplit_pkt, + rx_pkts, rx_hsplit_pkt, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, +- tx_dropped; ++ tx_dropped, xdp_tx_errors, xdp_redirect_errors; + int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx; + int stats_idx, stats_region_len, nic_stats_len; + struct stats *report_stats; +@@ -199,6 +200,7 @@ gve_get_ethtool_stats(struct net_device + for (rx_pkts = 0, rx_bytes = 0, rx_hsplit_pkt = 0, + rx_skb_alloc_fail = 0, rx_buf_alloc_fail = 0, + rx_desc_err_dropped_pkt = 0, rx_hsplit_unsplit_pkt = 0, ++ xdp_tx_errors = 0, xdp_redirect_errors = 0, + ring = 0; + ring < priv->rx_cfg.num_queues; ring++) { + if (priv->rx) { +@@ -216,6 +218,9 @@ gve_get_ethtool_stats(struct net_device + rx->rx_desc_err_dropped_pkt; + tmp_rx_hsplit_unsplit_pkt = + rx->rx_hsplit_unsplit_pkt; ++ tmp_xdp_tx_errors = rx->xdp_tx_errors; ++ tmp_xdp_redirect_errors = ++ rx->xdp_redirect_errors; + } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + rx_pkts += tmp_rx_pkts; +@@ -225,6 +230,8 @@ gve_get_ethtool_stats(struct net_device + rx_buf_alloc_fail += tmp_rx_buf_alloc_fail; + rx_desc_err_dropped_pkt += tmp_rx_desc_err_dropped_pkt; + rx_hsplit_unsplit_pkt += tmp_rx_hsplit_unsplit_pkt; ++ xdp_tx_errors += tmp_xdp_tx_errors; ++ xdp_redirect_errors += tmp_xdp_redirect_errors; + } + } + for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0; +@@ -250,8 +257,8 @@ gve_get_ethtool_stats(struct net_device + data[i++] = rx_bytes; + data[i++] = tx_bytes; + /* total rx dropped packets */ +- data[i++] = rx_skb_alloc_fail + rx_buf_alloc_fail + +- rx_desc_err_dropped_pkt; ++ data[i++] = rx_skb_alloc_fail + rx_desc_err_dropped_pkt + ++ xdp_tx_errors + xdp_redirect_errors; + data[i++] = tx_dropped; + data[i++] = priv->tx_timeo_cnt; + data[i++] = rx_skb_alloc_fail; +@@ -330,6 +337,9 @@ gve_get_ethtool_stats(struct net_device + tmp_rx_buf_alloc_fail = rx->rx_buf_alloc_fail; + tmp_rx_desc_err_dropped_pkt = + rx->rx_desc_err_dropped_pkt; ++ tmp_xdp_tx_errors = rx->xdp_tx_errors; ++ tmp_xdp_redirect_errors = ++ rx->xdp_redirect_errors; + } while (u64_stats_fetch_retry(&priv->rx[ring].statss, + start)); + data[i++] = tmp_rx_bytes; +@@ -340,8 +350,9 @@ gve_get_ethtool_stats(struct net_device + data[i++] = rx->rx_frag_alloc_cnt; + /* rx dropped packets */ + data[i++] = tmp_rx_skb_alloc_fail + +- tmp_rx_buf_alloc_fail + +- tmp_rx_desc_err_dropped_pkt; ++ tmp_rx_desc_err_dropped_pkt + ++ tmp_xdp_tx_errors + ++ tmp_xdp_redirect_errors; + data[i++] = rx->rx_copybreak_pkt; + data[i++] = rx->rx_copied_pkt; + /* stats from NIC */ diff --git a/queue-6.12/gve-fix-stats-report-corruption-on-queue-count-change.patch b/queue-6.12/gve-fix-stats-report-corruption-on-queue-count-change.patch new file mode 100644 index 0000000000..41530b7459 --- /dev/null +++ b/queue-6.12/gve-fix-stats-report-corruption-on-queue-count-change.patch @@ -0,0 +1,131 @@ +From 7b9ebcce0296e104a0d82a6b09d68564806158ff Mon Sep 17 00:00:00 2001 +From: Debarghya Kundu +Date: Mon, 2 Feb 2026 19:39:24 +0000 +Subject: gve: Fix stats report corruption on queue count change + +From: Debarghya Kundu + +commit 7b9ebcce0296e104a0d82a6b09d68564806158ff upstream. + +The driver and the NIC share a region in memory for stats reporting. +The NIC calculates its offset into this region based on the total size +of the stats region and the size of the NIC's stats. + +When the number of queues is changed, the driver's stats region is +resized. If the queue count is increased, the NIC can write past +the end of the allocated stats region, causing memory corruption. +If the queue count is decreased, there is a gap between the driver +and NIC stats, leading to incorrect stats reporting. + +This change fixes the issue by allocating stats region with maximum +size, and the offset calculation for NIC stats is changed to match +with the calculation of the NIC. + +Cc: stable@vger.kernel.org +Fixes: 24aeb56f2d38 ("gve: Add Gvnic stats AQ command and ethtool show/set-priv-flags.") +Signed-off-by: Debarghya Kundu +Reviewed-by: Joshua Washington +Signed-off-by: Harshitha Ramamurthy +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/20260202193925.3106272-2-hramamurthy@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/google/gve/gve_ethtool.c | 54 ++++++++++++++++---------- + drivers/net/ethernet/google/gve/gve_main.c | 4 - + 2 files changed, 36 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/google/gve/gve_ethtool.c ++++ b/drivers/net/ethernet/google/gve/gve_ethtool.c +@@ -156,7 +156,8 @@ gve_get_ethtool_stats(struct net_device + u64 rx_buf_alloc_fail, rx_desc_err_dropped_pkt, rx_hsplit_unsplit_pkt, + rx_pkts, rx_hsplit_pkt, rx_skb_alloc_fail, rx_bytes, tx_pkts, tx_bytes, + tx_dropped; +- int stats_idx, base_stats_idx, max_stats_idx; ++ int rx_base_stats_idx, max_rx_stats_idx, max_tx_stats_idx; ++ int stats_idx, stats_region_len, nic_stats_len; + struct stats *report_stats; + int *rx_qid_to_stats_idx; + int *tx_qid_to_stats_idx; +@@ -265,20 +266,38 @@ gve_get_ethtool_stats(struct net_device + data[i++] = priv->stats_report_trigger_cnt; + i = GVE_MAIN_STATS_LEN; + +- /* For rx cross-reporting stats, start from nic rx stats in report */ +- base_stats_idx = GVE_TX_STATS_REPORT_NUM * num_tx_queues + +- GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues; +- /* The boundary between driver stats and NIC stats shifts if there are +- * stopped queues. +- */ +- base_stats_idx += NIC_RX_STATS_REPORT_NUM * num_stopped_rxqs + +- NIC_TX_STATS_REPORT_NUM * num_stopped_txqs; +- max_stats_idx = NIC_RX_STATS_REPORT_NUM * +- (priv->rx_cfg.num_queues - num_stopped_rxqs) + +- base_stats_idx; ++ rx_base_stats_idx = 0; ++ max_rx_stats_idx = 0; ++ max_tx_stats_idx = 0; ++ stats_region_len = priv->stats_report_len - ++ sizeof(struct gve_stats_report); ++ nic_stats_len = (NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues + ++ NIC_TX_STATS_REPORT_NUM * num_tx_queues) * sizeof(struct stats); ++ if (unlikely((stats_region_len - ++ nic_stats_len) % sizeof(struct stats))) { ++ net_err_ratelimited("Starting index of NIC stats should be multiple of stats size"); ++ } else { ++ /* For rx cross-reporting stats, ++ * start from nic rx stats in report ++ */ ++ rx_base_stats_idx = (stats_region_len - nic_stats_len) / ++ sizeof(struct stats); ++ /* The boundary between driver stats and NIC stats ++ * shifts if there are stopped queues ++ */ ++ rx_base_stats_idx += NIC_RX_STATS_REPORT_NUM * ++ num_stopped_rxqs + NIC_TX_STATS_REPORT_NUM * ++ num_stopped_txqs; ++ max_rx_stats_idx = NIC_RX_STATS_REPORT_NUM * ++ (priv->rx_cfg.num_queues - num_stopped_rxqs) + ++ rx_base_stats_idx; ++ max_tx_stats_idx = NIC_TX_STATS_REPORT_NUM * ++ (num_tx_queues - num_stopped_txqs) + ++ max_rx_stats_idx; ++ } + /* Preprocess the stats report for rx, map queue id to start index */ + skip_nic_stats = false; +- for (stats_idx = base_stats_idx; stats_idx < max_stats_idx; ++ for (stats_idx = rx_base_stats_idx; stats_idx < max_rx_stats_idx; + stats_idx += NIC_RX_STATS_REPORT_NUM) { + u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name); + u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id); +@@ -354,14 +373,9 @@ gve_get_ethtool_stats(struct net_device + i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS; + } + +- /* For tx cross-reporting stats, start from nic tx stats in report */ +- base_stats_idx = max_stats_idx; +- max_stats_idx = NIC_TX_STATS_REPORT_NUM * +- (num_tx_queues - num_stopped_txqs) + +- max_stats_idx; +- /* Preprocess the stats report for tx, map queue id to start index */ + skip_nic_stats = false; +- for (stats_idx = base_stats_idx; stats_idx < max_stats_idx; ++ /* NIC TX stats start right after NIC RX stats */ ++ for (stats_idx = max_rx_stats_idx; stats_idx < max_tx_stats_idx; + stats_idx += NIC_TX_STATS_REPORT_NUM) { + u32 stat_name = be32_to_cpu(report_stats[stats_idx].stat_name); + u32 queue_id = be32_to_cpu(report_stats[stats_idx].queue_id); +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -244,9 +244,9 @@ static int gve_alloc_stats_report(struct + int tx_stats_num, rx_stats_num; + + tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) * +- gve_num_tx_queues(priv); ++ priv->tx_cfg.max_queues; + rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) * +- priv->rx_cfg.num_queues; ++ priv->rx_cfg.max_queues; + priv->stats_report_len = struct_size(priv->stats_report, stats, + size_add(tx_stats_num, rx_stats_num)); + priv->stats_report = diff --git a/queue-6.12/mm-shmem-prevent-infinite-loop-on-truncate-race.patch b/queue-6.12/mm-shmem-prevent-infinite-loop-on-truncate-race.patch new file mode 100644 index 0000000000..6606224329 --- /dev/null +++ b/queue-6.12/mm-shmem-prevent-infinite-loop-on-truncate-race.patch @@ -0,0 +1,84 @@ +From 2030dddf95451b4e7a389f052091e7c4b7b274c6 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Thu, 29 Jan 2026 00:19:23 +0800 +Subject: mm, shmem: prevent infinite loop on truncate race + +From: Kairui Song + +commit 2030dddf95451b4e7a389f052091e7c4b7b274c6 upstream. + +When truncating a large swap entry, shmem_free_swap() returns 0 when the +entry's index doesn't match the given index due to lookup alignment. The +failure fallback path checks if the entry crosses the end border and +aborts when it happens, so truncate won't erase an unexpected entry or +range. But one scenario was ignored. + +When `index` points to the middle of a large swap entry, and the large +swap entry doesn't go across the end border, find_get_entries() will +return that large swap entry as the first item in the batch with +`indices[0]` equal to `index`. The entry's base index will be smaller +than `indices[0]`, so shmem_free_swap() will fail and return 0 due to the +"base < index" check. The code will then call shmem_confirm_swap(), get +the order, check if it crosses the END boundary (which it doesn't), and +retry with the same index. + +The next iteration will find the same entry again at the same index with +same indices, leading to an infinite loop. + +Fix this by retrying with a round-down index, and abort if the index is +smaller than the truncate range. + +Link: https://lkml.kernel.org/r/aXo6ltB5iqAKJzY8@KASONG-MC4 +Fixes: 809bc86517cc ("mm: shmem: support large folio swap out") +Fixes: 8a1968bd997f ("mm/shmem, swap: fix race of truncate and swap entry split") +Signed-off-by: Kairui Song +Reported-by: Chris Mason +Closes: https://lore.kernel.org/linux-mm/20260128130336.727049-1-clm@meta.com/ +Reviewed-by: Baolin Wang +Cc: Baoquan He +Cc: Barry Song +Cc: Chris Li +Cc: Hugh Dickins +Cc: Kemeng Shi +Cc: Nhat Pham +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/shmem.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -1109,17 +1109,22 @@ whole_folios: + swaps_freed = shmem_free_swap(mapping, indices[i], + end - 1, folio); + if (!swaps_freed) { +- /* +- * If found a large swap entry cross the end border, +- * skip it as the truncate_inode_partial_folio above +- * should have at least zerod its content once. +- */ ++ pgoff_t base = indices[i]; ++ + order = shmem_confirm_swap(mapping, indices[i], + radix_to_swp_entry(folio)); +- if (order > 0 && indices[i] + (1 << order) > end) +- continue; +- /* Swap was replaced by page: retry */ +- index = indices[i]; ++ /* ++ * If found a large swap entry cross the end or start ++ * border, skip it as the truncate_inode_partial_folio ++ * above should have at least zerod its content once. ++ */ ++ if (order > 0) { ++ base = round_down(base, 1 << order); ++ if (base < start || base + (1 << order) > end) ++ continue; ++ } ++ /* Swap was replaced by page or extended, retry */ ++ index = base; + break; + } + nr_swaps_freed += swaps_freed; diff --git a/queue-6.12/mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch b/queue-6.12/mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch new file mode 100644 index 0000000000..066ee69140 --- /dev/null +++ b/queue-6.12/mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch @@ -0,0 +1,99 @@ +From e6c53ead2d8fa73206e0a63e9cd9aea6bc929837 Mon Sep 17 00:00:00 2001 +From: Hao Ge +Date: Wed, 4 Feb 2026 18:14:01 +0800 +Subject: mm/slab: Add alloc_tagging_slab_free_hook for memcg_alloc_abort_single + +From: Hao Ge + +commit e6c53ead2d8fa73206e0a63e9cd9aea6bc929837 upstream. + +When CONFIG_MEM_ALLOC_PROFILING_DEBUG is enabled, the following warning +may be noticed: + +[ 3959.023862] ------------[ cut here ]------------ +[ 3959.023891] alloc_tag was not cleared (got tag for lib/xarray.c:378) +[ 3959.023947] WARNING: ./include/linux/alloc_tag.h:155 at alloc_tag_add+0x128/0x178, CPU#6: mkfs.ntfs/113998 +[ 3959.023978] Modules linked in: dns_resolver tun brd overlay exfat btrfs blake2b libblake2b xor xor_neon raid6_pq loop sctp ip6_udp_tunnel udp_tunnel ext4 crc16 mbcache jbd2 rfkill sunrpc vfat fat sg fuse nfnetlink sr_mod virtio_gpu cdrom drm_client_lib virtio_dma_buf drm_shmem_helper drm_kms_helper ghash_ce drm sm4 backlight virtio_net net_failover virtio_scsi failover virtio_console virtio_blk virtio_mmio dm_mirror dm_region_hash dm_log dm_multipath dm_mod i2c_dev aes_neon_bs aes_ce_blk [last unloaded: hwpoison_inject] +[ 3959.024170] CPU: 6 UID: 0 PID: 113998 Comm: mkfs.ntfs Kdump: loaded Tainted: G W 6.19.0-rc7+ #7 PREEMPT(voluntary) +[ 3959.024182] Tainted: [W]=WARN +[ 3959.024186] Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022 +[ 3959.024192] pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 3959.024199] pc : alloc_tag_add+0x128/0x178 +[ 3959.024207] lr : alloc_tag_add+0x128/0x178 +[ 3959.024214] sp : ffff80008b696d60 +[ 3959.024219] x29: ffff80008b696d60 x28: 0000000000000000 x27: 0000000000000240 +[ 3959.024232] x26: 0000000000000000 x25: 0000000000000240 x24: ffff800085d17860 +[ 3959.024245] x23: 0000000000402800 x22: ffff0000c0012dc0 x21: 00000000000002d0 +[ 3959.024257] x20: ffff0000e6ef3318 x19: ffff800085ae0410 x18: 0000000000000000 +[ 3959.024269] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 +[ 3959.024281] x14: 0000000000000000 x13: 0000000000000001 x12: ffff600064101293 +[ 3959.024292] x11: 1fffe00064101292 x10: ffff600064101292 x9 : dfff800000000000 +[ 3959.024305] x8 : 00009fff9befed6e x7 : ffff000320809493 x6 : 0000000000000001 +[ 3959.024316] x5 : ffff000320809490 x4 : ffff600064101293 x3 : ffff800080691838 +[ 3959.024328] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000d5bcd640 +[ 3959.024340] Call trace: +[ 3959.024346] alloc_tag_add+0x128/0x178 (P) +[ 3959.024355] __alloc_tagging_slab_alloc_hook+0x11c/0x1a8 +[ 3959.024362] kmem_cache_alloc_lru_noprof+0x1b8/0x5e8 +[ 3959.024369] xas_alloc+0x304/0x4f0 +[ 3959.024381] xas_create+0x1e0/0x4a0 +[ 3959.024388] xas_store+0x68/0xda8 +[ 3959.024395] __filemap_add_folio+0x5b0/0xbd8 +[ 3959.024409] filemap_add_folio+0x16c/0x7e0 +[ 3959.024416] __filemap_get_folio_mpol+0x2dc/0x9e8 +[ 3959.024424] iomap_get_folio+0xfc/0x180 +[ 3959.024435] __iomap_get_folio+0x2f8/0x4b8 +[ 3959.024441] iomap_write_begin+0x198/0xc18 +[ 3959.024448] iomap_write_iter+0x2ec/0x8f8 +[ 3959.024454] iomap_file_buffered_write+0x19c/0x290 +[ 3959.024461] blkdev_write_iter+0x38c/0x978 +[ 3959.024470] vfs_write+0x4d4/0x928 +[ 3959.024482] ksys_write+0xfc/0x1f8 +[ 3959.024489] __arm64_sys_write+0x74/0xb0 +[ 3959.024496] invoke_syscall+0xd4/0x258 +[ 3959.024507] el0_svc_common.constprop.0+0xb4/0x240 +[ 3959.024514] do_el0_svc+0x48/0x68 +[ 3959.024520] el0_svc+0x40/0xf8 +[ 3959.024526] el0t_64_sync_handler+0xa0/0xe8 +[ 3959.024533] el0t_64_sync+0x1ac/0x1b0 +[ 3959.024540] ---[ end trace 0000000000000000 ]--- + +When __memcg_slab_post_alloc_hook() fails, there are two different +free paths depending on whether size == 1 or size != 1. In the +kmem_cache_free_bulk() path, we do call alloc_tagging_slab_free_hook(). +However, in memcg_alloc_abort_single() we don't, the above warning will be +triggered on the next allocation. + +Therefore, add alloc_tagging_slab_free_hook() to the +memcg_alloc_abort_single() path. + +Fixes: 9f9796b413d3 ("mm, slab: move memcg charging to post-alloc hook") +Cc: stable@vger.kernel.org +Suggested-by: Hao Li +Signed-off-by: Hao Ge +Reviewed-by: Hao Li +Reviewed-by: Suren Baghdasaryan +Reviewed-by: Harry Yoo +Link: https://patch.msgid.link/20260204101401.202762-1-hao.ge@linux.dev +Signed-off-by: Vlastimil Babka +Signed-off-by: Greg Kroah-Hartman +--- + mm/slub.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -4657,8 +4657,12 @@ void slab_free(struct kmem_cache *s, str + static noinline + void memcg_alloc_abort_single(struct kmem_cache *s, void *object) + { ++ struct slab *slab = virt_to_slab(object); ++ ++ alloc_tagging_slab_free_hook(s, slab, &object, 1); ++ + if (likely(slab_free_hook(s, object, slab_want_init_on_free(s), false))) +- do_slab_free(s, virt_to_slab(object), object, object, 1, _RET_IP_); ++ do_slab_free(s, slab, object, object, 1, _RET_IP_); + } + #endif + diff --git a/queue-6.12/platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch b/queue-6.12/platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch new file mode 100644 index 0000000000..c47d1f9e60 --- /dev/null +++ b/queue-6.12/platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch @@ -0,0 +1,54 @@ +From 25e9e322d2ab5c03602eff4fbf4f7c40019d8de2 Mon Sep 17 00:00:00 2001 +From: Kaushlendra Kumar +Date: Wed, 24 Dec 2025 08:50:53 +0530 +Subject: platform/x86: intel_telemetry: Fix swapped arrays in PSS output +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kaushlendra Kumar + +commit 25e9e322d2ab5c03602eff4fbf4f7c40019d8de2 upstream. + +The LTR blocking statistics and wakeup event counters are incorrectly +cross-referenced during debugfs output rendering. The code populates +pss_ltr_blkd[] with LTR blocking data and pss_s0ix_wakeup[] with wakeup +data, but the display loops reference the wrong arrays. + +This causes the "LTR Blocking Status" section to print wakeup events +and the "Wakes Status" section to print LTR blockers, misleading power +management analysis and S0ix residency debugging. + +Fix by aligning array usage with the intended output section labels. + +Fixes: 87bee290998d ("platform:x86: Add Intel Telemetry Debugfs interfaces") +Cc: stable@vger.kernel.org +Signed-off-by: Kaushlendra Kumar +Link: https://patch.msgid.link/20251224032053.3915900-1-kaushlendra.kumar@intel.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/x86/intel/telemetry/debugfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/platform/x86/intel/telemetry/debugfs.c ++++ b/drivers/platform/x86/intel/telemetry/debugfs.c +@@ -449,7 +449,7 @@ static int telem_pss_states_show(struct + for (index = 0; index < debugfs_conf->pss_ltr_evts; index++) { + seq_printf(s, "%-32s\t%u\n", + debugfs_conf->pss_ltr_data[index].name, +- pss_s0ix_wakeup[index]); ++ pss_ltr_blkd[index]); + } + + seq_puts(s, "\n--------------------------------------\n"); +@@ -459,7 +459,7 @@ static int telem_pss_states_show(struct + for (index = 0; index < debugfs_conf->pss_wakeup_evts; index++) { + seq_printf(s, "%-32s\t%u\n", + debugfs_conf->pss_wakeup[index].name, +- pss_ltr_blkd[index]); ++ pss_s0ix_wakeup[index]); + } + + return 0; diff --git a/queue-6.12/pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch b/queue-6.12/pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch new file mode 100644 index 0000000000..60b971a6c9 --- /dev/null +++ b/queue-6.12/pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch @@ -0,0 +1,67 @@ +From ae0a24c5a8dcea20bf8e344eadf6593e6d1959c3 Mon Sep 17 00:00:00 2001 +From: Jacky Bai +Date: Fri, 23 Jan 2026 10:51:26 +0800 +Subject: pmdomain: imx: gpcv2: Fix the imx8mm gpu hang due to wrong adb400 reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jacky Bai + +commit ae0a24c5a8dcea20bf8e344eadf6593e6d1959c3 upstream. + +On i.MX8MM, the GPUMIX, GPU2D, and GPU3D blocks share a common reset +domain. Due to this hardware limitation, powering off/on GPU2D or GPU3D +also triggers a reset of the GPUMIX domain, including its ADB400 port. +However, the ADB400 interface must always be placed into power‑down mode +before being reset. + +Currently the GPUMIX and GPU2D/3D power domains rely on runtime PM to +handle dependency ordering. In some corner cases, the GPUMIX power off +sequence is skipped, leaving the ADB400 port active when GPU2D/3D reset. +This causes the GPUMIX ADB400 port to be reset while still active, +leading to unpredictable bus behavior and GPU hangs. + +To avoid this, refine the power‑domain control logic so that the GPUMIX +ADB400 port is explicitly powered down and powered up as part of the GPU +power domain on/off sequence. This ensures proper ordering and prevents +incorrect ADB400 reset. + +Suggested-by: Lucas Stach +Signed-off-by: Jacky Bai +Reviewed-by: Lucas Stach +Tested-by: Philipp Zabel +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pmdomain/imx/gpcv2.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/pmdomain/imx/gpcv2.c ++++ b/drivers/pmdomain/imx/gpcv2.c +@@ -165,13 +165,11 @@ + #define IMX8M_VPU_HSK_PWRDNREQN BIT(5) + #define IMX8M_DISP_HSK_PWRDNREQN BIT(4) + +-#define IMX8MM_GPUMIX_HSK_PWRDNACKN BIT(29) +-#define IMX8MM_GPU_HSK_PWRDNACKN (BIT(27) | BIT(28)) ++#define IMX8MM_GPU_HSK_PWRDNACKN GENMASK(29, 27) + #define IMX8MM_VPUMIX_HSK_PWRDNACKN BIT(26) + #define IMX8MM_DISPMIX_HSK_PWRDNACKN BIT(25) + #define IMX8MM_HSIO_HSK_PWRDNACKN (BIT(23) | BIT(24)) +-#define IMX8MM_GPUMIX_HSK_PWRDNREQN BIT(11) +-#define IMX8MM_GPU_HSK_PWRDNREQN (BIT(9) | BIT(10)) ++#define IMX8MM_GPU_HSK_PWRDNREQN GENMASK(11, 9) + #define IMX8MM_VPUMIX_HSK_PWRDNREQN BIT(8) + #define IMX8MM_DISPMIX_HSK_PWRDNREQN BIT(7) + #define IMX8MM_HSIO_HSK_PWRDNREQN (BIT(5) | BIT(6)) +@@ -794,8 +792,6 @@ static const struct imx_pgc_domain imx8m + .bits = { + .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ, + .map = IMX8MM_GPUMIX_A53_DOMAIN, +- .hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN, +- .hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN, + }, + .pgc = BIT(IMX8MM_PGC_GPUMIX), + .keep_clocks = true, diff --git a/queue-6.12/pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch b/queue-6.12/pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch new file mode 100644 index 0000000000..3ba1429042 --- /dev/null +++ b/queue-6.12/pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch @@ -0,0 +1,32 @@ +From 6bd8b4a92a901fae1a422e6f914801063c345e8d Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Fri, 30 Jan 2026 13:11:07 +0800 +Subject: pmdomain: imx8m-blk-ctrl: fix out-of-range access of bc->domains + +From: Xu Yang + +commit 6bd8b4a92a901fae1a422e6f914801063c345e8d upstream. + +Fix out-of-range access of bc->domains in imx8m_blk_ctrl_remove(). + +Fixes: 2684ac05a8c4 ("soc: imx: add i.MX8M blk-ctrl driver") +Cc: stable@kernel.org +Signed-off-by: Xu Yang +Reviewed-by: Daniel Baluta +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pmdomain/imx/imx8m-blk-ctrl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c ++++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c +@@ -340,7 +340,7 @@ static void imx8m_blk_ctrl_remove(struct + + of_genpd_del_provider(pdev->dev.of_node); + +- for (i = 0; bc->onecell_data.num_domains; i++) { ++ for (i = 0; i < bc->onecell_data.num_domains; i++) { + struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; + + pm_genpd_remove(&domain->genpd); diff --git a/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch b/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch new file mode 100644 index 0000000000..1c0d9a8ad9 --- /dev/null +++ b/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch @@ -0,0 +1,109 @@ +From e9ab2b83893dd03cf04d98faded81190e635233f Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Wed, 4 Feb 2026 19:11:41 +0800 +Subject: pmdomain: imx8mp-blk-ctrl: Keep gpc power domain on for system wakeup + +From: Xu Yang + +commit e9ab2b83893dd03cf04d98faded81190e635233f upstream. + +Current design will power off all dependent GPC power domains in +imx8mp_blk_ctrl_suspend(), even though the user device has enabled +wakeup capability. The result is that wakeup function never works +for such device. + +An example will be USB wakeup on i.MX8MP. PHY device '382f0040.usb-phy' +is attached to power domain 'hsioblk-usb-phy2' which is spawned by hsio +block control. A virtual power domain device 'genpd:3:32f10000.blk-ctrl' +is created to build connection with 'hsioblk-usb-phy2' and it depends on +GPC power domain 'usb-otg2'. If device '382f0040.usb-phy' enable wakeup, +only power domain 'hsioblk-usb-phy2' keeps on during system suspend, +power domain 'usb-otg2' is off all the time. So the wakeup event can't +happen. + +In order to further establish a connection between the power domains +related to GPC and block control during system suspend, register a genpd +power on/off notifier for the power_dev. This allows us to prevent the GPC +power domain from being powered off, in case the block control power +domain is kept on to serve system wakeup. + +Suggested-by: Ulf Hansson +Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") +Cc: stable@vger.kernel.org +Signed-off-by: Xu Yang +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c ++++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +@@ -65,6 +65,7 @@ struct imx8mp_blk_ctrl_domain { + struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; + struct device *power_dev; + struct imx8mp_blk_ctrl *bc; ++ struct notifier_block power_nb; + int num_paths; + int id; + }; +@@ -594,6 +595,20 @@ static int imx8mp_blk_ctrl_power_off(str + return 0; + } + ++static int imx8mp_blk_ctrl_gpc_notifier(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ struct imx8mp_blk_ctrl_domain *domain = ++ container_of(nb, struct imx8mp_blk_ctrl_domain, power_nb); ++ ++ if (action == GENPD_NOTIFY_PRE_OFF) { ++ if (domain->genpd.status == GENPD_STATE_ON) ++ return NOTIFY_BAD; ++ } ++ ++ return NOTIFY_OK; ++} ++ + static struct lock_class_key blk_ctrl_genpd_lock_class; + + static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) +@@ -698,6 +713,14 @@ static int imx8mp_blk_ctrl_probe(struct + goto cleanup_pds; + } + ++ domain->power_nb.notifier_call = imx8mp_blk_ctrl_gpc_notifier; ++ ret = dev_pm_genpd_add_notifier(domain->power_dev, &domain->power_nb); ++ if (ret) { ++ dev_err_probe(dev, ret, "failed to add power notifier\n"); ++ dev_pm_domain_detach(domain->power_dev, true); ++ goto cleanup_pds; ++ } ++ + domain->genpd.name = data->name; + domain->genpd.power_on = imx8mp_blk_ctrl_power_on; + domain->genpd.power_off = imx8mp_blk_ctrl_power_off; +@@ -707,6 +730,7 @@ static int imx8mp_blk_ctrl_probe(struct + ret = pm_genpd_init(&domain->genpd, NULL, true); + if (ret) { + dev_err_probe(dev, ret, "failed to init power domain\n"); ++ dev_pm_genpd_remove_notifier(domain->power_dev); + dev_pm_domain_detach(domain->power_dev, true); + goto cleanup_pds; + } +@@ -755,6 +779,7 @@ cleanup_provider: + cleanup_pds: + for (i--; i >= 0; i--) { + pm_genpd_remove(&bc->domains[i].genpd); ++ dev_pm_genpd_remove_notifier(bc->domains[i].power_dev); + dev_pm_domain_detach(bc->domains[i].power_dev, true); + } + +@@ -774,6 +799,7 @@ static void imx8mp_blk_ctrl_remove(struc + struct imx8mp_blk_ctrl_domain *domain = &bc->domains[i]; + + pm_genpd_remove(&domain->genpd); ++ dev_pm_genpd_remove_notifier(domain->power_dev); + dev_pm_domain_detach(domain->power_dev, true); + } + diff --git a/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch b/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch new file mode 100644 index 0000000000..d865b8664d --- /dev/null +++ b/queue-6.12/pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch @@ -0,0 +1,52 @@ +From e2c4c5b2bbd4f688a0f9f6da26cdf6d723c53478 Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Wed, 4 Feb 2026 19:11:42 +0800 +Subject: pmdomain: imx8mp-blk-ctrl: Keep usb phy power domain on for system wakeup + +From: Xu Yang + +commit e2c4c5b2bbd4f688a0f9f6da26cdf6d723c53478 upstream. + +USB system wakeup need its PHY on, so add the GENPD_FLAG_ACTIVE_WAKEUP +flags to USB PHY genpd configuration. + +Signed-off-by: Xu Yang +Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pmdomain/imx/imx8mp-blk-ctrl.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/pmdomain/imx/imx8mp-blk-ctrl.c ++++ b/drivers/pmdomain/imx/imx8mp-blk-ctrl.c +@@ -53,6 +53,7 @@ struct imx8mp_blk_ctrl_domain_data { + const char * const *path_names; + int num_paths; + const char *gpc_name; ++ const unsigned int flags; + }; + + #define DOMAIN_MAX_CLKS 3 +@@ -265,10 +266,12 @@ static const struct imx8mp_blk_ctrl_doma + [IMX8MP_HSIOBLK_PD_USB_PHY1] = { + .name = "hsioblk-usb-phy1", + .gpc_name = "usb-phy1", ++ .flags = GENPD_FLAG_ACTIVE_WAKEUP, + }, + [IMX8MP_HSIOBLK_PD_USB_PHY2] = { + .name = "hsioblk-usb-phy2", + .gpc_name = "usb-phy2", ++ .flags = GENPD_FLAG_ACTIVE_WAKEUP, + }, + [IMX8MP_HSIOBLK_PD_PCIE] = { + .name = "hsioblk-pcie", +@@ -724,6 +727,7 @@ static int imx8mp_blk_ctrl_probe(struct + domain->genpd.name = data->name; + domain->genpd.power_on = imx8mp_blk_ctrl_power_on; + domain->genpd.power_off = imx8mp_blk_ctrl_power_off; ++ domain->genpd.flags = data->flags; + domain->bc = bc; + domain->id = i; + diff --git a/queue-6.12/pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch b/queue-6.12/pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch new file mode 100644 index 0000000000..f72a0e7989 --- /dev/null +++ b/queue-6.12/pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch @@ -0,0 +1,40 @@ +From 8aa6f7697f5981d336cac7af6ddd182a03c6da01 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 22 Jan 2026 18:20:12 +0100 +Subject: pmdomain: qcom: rpmpd: fix off-by-one error in clamping to the highest state + +From: Gabor Juhos + +commit 8aa6f7697f5981d336cac7af6ddd182a03c6da01 upstream. + +As it is indicated by the comment, the rpmpd_aggregate_corner() function +tries to clamp the state to the highest corner/level supported by the +given power domain, however the calculation of the highest state contains +an off-by-one error. + +The 'max_state' member of the 'rpmpd' structure indicates the highest +corner/level, and as such it does not needs to be decremented. + +Change the code to use the 'max_state' value directly to avoid the error. + +Fixes: 98c8b3efacae ("soc: qcom: rpmpd: Add sync_state") +Signed-off-by: Gabor Juhos +Reviewed-by: Konrad Dybcio +Cc: stable@vger.kernel.org +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pmdomain/qcom/rpmpd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pmdomain/qcom/rpmpd.c ++++ b/drivers/pmdomain/qcom/rpmpd.c +@@ -1001,7 +1001,7 @@ static int rpmpd_aggregate_corner(struct + + /* Clamp to the highest corner/level if sync_state isn't done yet */ + if (!pd->state_synced) +- this_active_corner = this_sleep_corner = pd->max_state - 1; ++ this_active_corner = this_sleep_corner = pd->max_state; + else + to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner); + diff --git a/queue-6.12/rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch b/queue-6.12/rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch new file mode 100644 index 0000000000..4ab5532ca0 --- /dev/null +++ b/queue-6.12/rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch @@ -0,0 +1,94 @@ +From bd3884a204c3b507e6baa9a4091aa927f9af5404 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Wed, 7 Jan 2026 22:37:55 +0100 +Subject: rbd: check for EOD after exclusive lock is ensured to be held + +From: Ilya Dryomov + +commit bd3884a204c3b507e6baa9a4091aa927f9af5404 upstream. + +Similar to commit 870611e4877e ("rbd: get snapshot context after +exclusive lock is ensured to be held"), move the "beyond EOD" check +into the image request state machine so that it's performed after +exclusive lock is ensured to be held. This avoids various race +conditions which can arise when the image is shrunk under I/O (in +practice, mostly readahead). In one such scenario + + rbd_assert(objno < rbd_dev->object_map_size); + +can be triggered if a close-to-EOD read gets queued right before the +shrink is initiated and the EOD check is performed against an outdated +mapping_size. After the resize is done on the server side and exclusive +lock is (re)acquired bringing along the new (now shrunk) object map, the +read starts going through the state machine and rbd_obj_may_exist() gets +invoked on an object that is out of bounds of rbd_dev->object_map array. + +Cc: stable@vger.kernel.org +Signed-off-by: Ilya Dryomov +Reviewed-by: Dongsheng Yang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rbd.c | 33 +++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -3495,11 +3495,29 @@ static void rbd_img_object_requests(stru + rbd_assert(!need_exclusive_lock(img_req) || + __rbd_is_lock_owner(rbd_dev)); + +- if (rbd_img_is_write(img_req)) { +- rbd_assert(!img_req->snapc); ++ if (test_bit(IMG_REQ_CHILD, &img_req->flags)) { ++ rbd_assert(!rbd_img_is_write(img_req)); ++ } else { ++ struct request *rq = blk_mq_rq_from_pdu(img_req); ++ u64 off = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; ++ u64 len = blk_rq_bytes(rq); ++ u64 mapping_size; ++ + down_read(&rbd_dev->header_rwsem); +- img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); ++ mapping_size = rbd_dev->mapping.size; ++ if (rbd_img_is_write(img_req)) { ++ rbd_assert(!img_req->snapc); ++ img_req->snapc = ++ ceph_get_snap_context(rbd_dev->header.snapc); ++ } + up_read(&rbd_dev->header_rwsem); ++ ++ if (unlikely(off + len > mapping_size)) { ++ rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", ++ off, len, mapping_size); ++ img_req->pending.result = -EIO; ++ return; ++ } + } + + for_each_obj_request(img_req, obj_req) { +@@ -4725,7 +4743,6 @@ static void rbd_queue_workfn(struct work + struct request *rq = blk_mq_rq_from_pdu(img_request); + u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; + u64 length = blk_rq_bytes(rq); +- u64 mapping_size; + int result; + + /* Ignore/skip any zero-length requests */ +@@ -4738,17 +4755,9 @@ static void rbd_queue_workfn(struct work + blk_mq_start_request(rq); + + down_read(&rbd_dev->header_rwsem); +- mapping_size = rbd_dev->mapping.size; + rbd_img_capture_header(img_request); + up_read(&rbd_dev->header_rwsem); + +- if (offset + length > mapping_size) { +- rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset, +- length, mapping_size); +- result = -EIO; +- goto err_img_request; +- } +- + dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, + img_request, obj_op_name(op_type), offset, length); + diff --git a/queue-6.12/revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch b/queue-6.12/revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch new file mode 100644 index 0000000000..23ebb1e708 --- /dev/null +++ b/queue-6.12/revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch @@ -0,0 +1,46 @@ +From 243b467dea1735fed904c2e54d248a46fa417a2d Mon Sep 17 00:00:00 2001 +From: Bert Karwatzki +Date: Sun, 1 Feb 2026 01:24:45 +0100 +Subject: Revert "drm/amd: Check if ASPM is enabled from PCIe subsystem" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bert Karwatzki + +commit 243b467dea1735fed904c2e54d248a46fa417a2d upstream. + +This reverts commit 7294863a6f01248d72b61d38478978d638641bee. + +This commit was erroneously applied again after commit 0ab5d711ec74 +("drm/amd: Refactor `amdgpu_aspm` to be evaluated per device") +removed it, leading to very hard to debug crashes, when used with a system with two +AMD GPUs of which only one supports ASPM. + +Link: https://lore.kernel.org/linux-acpi/20251006120944.7880-1-spasswolf@web.de/ +Link: https://github.com/acpica/acpica/issues/1060 +Fixes: 0ab5d711ec74 ("drm/amd: Refactor `amdgpu_aspm` to be evaluated per device") +Signed-off-by: Bert Karwatzki +Reviewed-by: Christian König +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Mario Limonciello +Signed-off-by: Alex Deucher +(cherry picked from commit 97a9689300eb2b393ba5efc17c8e5db835917080) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2273,9 +2273,6 @@ static int amdgpu_pci_probe(struct pci_d + return -ENODEV; + } + +- if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev)) +- amdgpu_aspm = 0; +- + if (amdgpu_virtual_display || + amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK)) + supports_atomic = true; diff --git a/queue-6.12/series b/queue-6.12/series index 6bd96d575e..b253c8b27c 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -1 +1,19 @@ nvmet-tcp-add-bounds-checks-in-nvmet_tcp_build_pdu_iovec.patch +x86-vmware-fix-hypercall-clobbers.patch +x86-kfence-fix-booting-on-32bit-non-pae-systems.patch +platform-x86-intel_telemetry-fix-swapped-arrays-in-pss-output.patch +alsa-aloop-fix-racy-access-at-pcm-trigger.patch +pmdomain-qcom-rpmpd-fix-off-by-one-error-in-clamping-to-the-highest-state.patch +pmdomain-imx8mp-blk-ctrl-keep-gpc-power-domain-on-for-system-wakeup.patch +pmdomain-imx-gpcv2-fix-the-imx8mm-gpu-hang-due-to-wrong-adb400-reset.patch +pmdomain-imx8mp-blk-ctrl-keep-usb-phy-power-domain-on-for-system-wakeup.patch +pmdomain-imx8m-blk-ctrl-fix-out-of-range-access-of-bc-domains.patch +mm-slab-add-alloc_tagging_slab_free_hook-for-memcg_alloc_abort_single.patch +ceph-fix-null-pointer-dereference-in-ceph_mds_auth_match.patch +rbd-check-for-eod-after-exclusive-lock-is-ensured-to-be-held.patch +arm-9468-1-fix-memset64-on-big-endian.patch +ceph-fix-oops-due-to-invalid-pointer-for-kfree-in-parse_longname.patch +gve-fix-stats-report-corruption-on-queue-count-change.patch +gve-correct-ethtool-rx_dropped-calculation.patch +mm-shmem-prevent-infinite-loop-on-truncate-race.patch +revert-drm-amd-check-if-aspm-is-enabled-from-pcie-subsystem.patch diff --git a/queue-6.12/x86-kfence-fix-booting-on-32bit-non-pae-systems.patch b/queue-6.12/x86-kfence-fix-booting-on-32bit-non-pae-systems.patch new file mode 100644 index 0000000000..a4cebf6c45 --- /dev/null +++ b/queue-6.12/x86-kfence-fix-booting-on-32bit-non-pae-systems.patch @@ -0,0 +1,68 @@ +From 16459fe7e0ca6520a6e8f603de4ccd52b90fd765 Mon Sep 17 00:00:00 2001 +From: Andrew Cooper +Date: Mon, 26 Jan 2026 21:10:46 +0000 +Subject: x86/kfence: fix booting on 32bit non-PAE systems + +From: Andrew Cooper + +commit 16459fe7e0ca6520a6e8f603de4ccd52b90fd765 upstream. + +The original patch inverted the PTE unconditionally to avoid +L1TF-vulnerable PTEs, but Linux doesn't make this adjustment in 2-level +paging. + +Adjust the logic to use the flip_protnone_guard() helper, which is a nop +on 2-level paging but inverts the address bits in all other paging modes. + +This doesn't matter for the Xen aspect of the original change. Linux no +longer supports running 32bit PV under Xen, and Xen doesn't support +running any 32bit PV guests without using PAE paging. + +Link: https://lkml.kernel.org/r/20260126211046.2096622-1-andrew.cooper3@citrix.com +Fixes: b505f1944535 ("x86/kfence: avoid writing L1TF-vulnerable PTEs") +Reported-by: Ryusuke Konishi +Closes: https://lore.kernel.org/lkml/CAKFNMokwjw68ubYQM9WkzOuH51wLznHpEOMSqtMoV1Rn9JV_gw@mail.gmail.com/ +Signed-off-by: Andrew Cooper +Tested-by: Ryusuke Konishi +Tested-by: Borislav Petkov (AMD) +Cc: Alexander Potapenko +Cc: Marco Elver +Cc: Dmitry Vyukov +Cc: Thomas Gleixner +Cc: Ingo Molnar +Cc: Dave Hansen +Cc: "H. Peter Anvin" +Cc: Jann Horn +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/kfence.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/arch/x86/include/asm/kfence.h ++++ b/arch/x86/include/asm/kfence.h +@@ -42,7 +42,7 @@ static inline bool kfence_protect_page(u + { + unsigned int level; + pte_t *pte = lookup_address(addr, &level); +- pteval_t val; ++ pteval_t val, new; + + if (WARN_ON(!pte || level != PG_LEVEL_4K)) + return false; +@@ -57,11 +57,12 @@ static inline bool kfence_protect_page(u + return true; + + /* +- * Otherwise, invert the entire PTE. This avoids writing out an ++ * Otherwise, flip the Present bit, taking care to avoid writing an + * L1TF-vulnerable PTE (not present, without the high address bits + * set). + */ +- set_pte(pte, __pte(~val)); ++ new = val ^ _PAGE_PRESENT; ++ set_pte(pte, __pte(flip_protnone_guard(val, new, PTE_PFN_MASK))); + + /* + * If the page was protected (non-present) and we're making it diff --git a/queue-6.12/x86-vmware-fix-hypercall-clobbers.patch b/queue-6.12/x86-vmware-fix-hypercall-clobbers.patch new file mode 100644 index 0000000000..66dcbe0abe --- /dev/null +++ b/queue-6.12/x86-vmware-fix-hypercall-clobbers.patch @@ -0,0 +1,75 @@ +From 2687c848e57820651b9f69d30c4710f4219f7dbf Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Fri, 6 Feb 2026 14:24:55 -0800 +Subject: x86/vmware: Fix hypercall clobbers + +From: Josh Poimboeuf + +commit 2687c848e57820651b9f69d30c4710f4219f7dbf upstream. + +Fedora QA reported the following panic: + + BUG: unable to handle page fault for address: 0000000040003e54 + #PF: supervisor write access in kernel mode + #PF: error_code(0x0002) - not-present page + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20251119-3.fc43 11/19/2025 + RIP: 0010:vmware_hypercall4.constprop.0+0x52/0x90 + .. + Call Trace: + vmmouse_report_events+0x13e/0x1b0 + psmouse_handle_byte+0x15/0x60 + ps2_interrupt+0x8a/0xd0 + ... + +because the QEMU VMware mouse emulation is buggy, and clears the top 32 +bits of %rdi that the kernel kept a pointer in. + +The QEMU vmmouse driver saves and restores the register state in a +"uint32_t data[6];" and as a result restores the state with the high +bits all cleared. + +RDI originally contained the value of a valid kernel stack address +(0xff5eeb3240003e54). After the vmware hypercall it now contains +0x40003e54, and we get a page fault as a result when it is dereferenced. + +The proper fix would be in QEMU, but this works around the issue in the +kernel to keep old setups working, when old kernels had not happened to +keep any state in %rdi over the hypercall. + +In theory this same issue exists for all the hypercalls in the vmmouse +driver; in practice it has only been seen with vmware_hypercall3() and +vmware_hypercall4(). For now, just mark RDI/RSI as clobbered for those +two calls. This should have a minimal effect on code generation overall +as it should be rare for the compiler to want to make RDI/RSI live +across hypercalls. + +Reported-by: Justin Forbes +Link: https://lore.kernel.org/all/99a9c69a-fc1a-43b7-8d1e-c42d6493b41f@broadcom.com/ +Signed-off-by: Josh Poimboeuf +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/vmware.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/include/asm/vmware.h ++++ b/arch/x86/include/asm/vmware.h +@@ -140,7 +140,7 @@ unsigned long vmware_hypercall3(unsigned + "b" (in1), + "c" (cmd), + "d" (0) +- : "cc", "memory"); ++ : "di", "si", "cc", "memory"); + return out0; + } + +@@ -165,7 +165,7 @@ unsigned long vmware_hypercall4(unsigned + "b" (in1), + "c" (cmd), + "d" (0) +- : "cc", "memory"); ++ : "di", "si", "cc", "memory"); + return out0; + } + -- 2.47.3