From: Greg Kroah-Hartman Date: Tue, 7 Apr 2026 15:20:33 +0000 (+0200) Subject: 6.19-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=330db5065c4ba67193d109ac27284d480957abc1;p=thirdparty%2Fkernel%2Fstable-queue.git 6.19-stable patches added patches: alsa-caiaq-fix-stack-out-of-bounds-read-in-init_card.patch alsa-ctxfi-check-the-error-for-index-mapping.patch alsa-ctxfi-don-t-enumerate-spdif1-at-daio-initialization.patch alsa-ctxfi-fix-missing-spdifi1-index-handling.patch alsa-hda-realtek-add-quirk-for-acer-swift-sfg14-73.patch alsa-hda-realtek-add-quirk-for-asus-rog-strix-scar-15.patch alsa-hda-realtek-add-quirk-for-hp-victus-15-fb0xxx.patch alsa-hda-realtek-change-quirk-for-hp-omnibook-7-laptop-16-bh0xxx.patch bluetooth-hci_event-move-wake-reason-storage-into-validated-event-handlers.patch bluetooth-hci_sync-fix-stack-buffer-overflow-in-hci_le_big_create_sync.patch bluetooth-smp-derive-legacy-responder-stk-authentication-from-mitm-state.patch bluetooth-smp-force-responder-mitm-requirements-before-building-the-pairing-response.patch drm-amd-display-fix-null-pointer-dereference-in-dcn401_init_hw.patch drm-amdgpu-change-amdgpu_va_reserved_trap_size-to-64kb.patch drm-amdgpu-fix-the-idr-allocation-flags.patch drm-amdgpu-fix-wait-after-reset-sequence-in-s4.patch drm-amdgpu-pm-drop-smu-driver-if-version-not-matched-messages.patch drm-amdgpu-validate-doorbell_offset-in-user-queue-creation.patch drm-ast-dp501-fix-initialization-of-scu2c.patch drm-i915-cdclk-do-the-full-cdclk-dance-for-min_voltage_level-changes.patch drm-i915-dp-use-crtc_state-enhanced_framing-properly-on-ivb-hsw-cpu-edp.patch drm-i915-dsi-don-t-do-dsc-horizontal-timing-adjustments-in-command-mode.patch gpib-fix-use-after-free-in-io-ioctl-handlers.patch hwmon-occ-fix-division-by-zero-in-occ_show_power_1.patch iio-adc-ti-adc161s626-fix-buffer-read-on-big-endian.patch iio-adc-ti-adc161s626-use-dma-safe-memory-for-spi_read.patch iio-adc-ti-ads1119-fix-unbalanced-pm-reference-count-in-ds1119_single_conversion.patch iio-adc-ti-ads1119-reinit-completion-before-wait_for_completion_timeout.patch iio-adc-ti-ads1119-replace-irqf_oneshot-with-irqf_no_thread.patch iio-add-iio_declare_quaternion-macro.patch iio-orientation-hid-sensor-rotation-add-timestamp-hack-to-not-break-userspace.patch iio-orientation-hid-sensor-rotation-fix-quaternion-alignment.patch io_uring-net-fix-slab-out-of-bounds-read-in-io_bundle_nbufs.patch iommu-do-not-call-drivers-for-empty-gathers.patch ksmbd-fix-oob-write-in-query_info-for-compound-requests.patch lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch mips-fix-the-gcc-version-check-for-__multi3-workaround.patch mips-mm-allocate-tlb_vpn-array-atomically.patch mips-mm-rewrite-tlb-uniquification-for-the-hidden-bit-feature.patch mips-sibyte-bring-back-cache-initialisation.patch sched_ext-fix-inconsistent-numa-node-lookup-in-scx_select_cpu_dfl.patch sched_ext-fix-scx_kick_wait-deadlock-by-deferring-wait-to-balance-callback.patch usb-core-add-no_lpm-quirk-for-razer-kiyo-pro-webcam.patch usb-serial-io_edgeport-add-support-for-blackbox-ic135a.patch usb-serial-option-add-meig-smart-srm825wn.patch usb-serial-option-add-support-for-rolling-wireless-rw135r-gl.patch x86-kexec-disable-kcov-instrumentation-after-load_segments.patch --- diff --git a/queue-6.19/alsa-caiaq-fix-stack-out-of-bounds-read-in-init_card.patch b/queue-6.19/alsa-caiaq-fix-stack-out-of-bounds-read-in-init_card.patch new file mode 100644 index 0000000000..363a3648e0 --- /dev/null +++ b/queue-6.19/alsa-caiaq-fix-stack-out-of-bounds-read-in-init_card.patch @@ -0,0 +1,59 @@ +From 45424e871abf2a152e247a9cff78359f18dd95c0 Mon Sep 17 00:00:00 2001 +From: Berk Cem Goksel +Date: Sun, 29 Mar 2026 16:38:25 +0300 +Subject: ALSA: caiaq: fix stack out-of-bounds read in init_card + +From: Berk Cem Goksel + +commit 45424e871abf2a152e247a9cff78359f18dd95c0 upstream. + +The loop creates a whitespace-stripped copy of the card shortname +where `len < sizeof(card->id)` is used for the bounds check. Since +sizeof(card->id) is 16 and the local id buffer is also 16 bytes, +writing 16 non-space characters fills the entire buffer, +overwriting the terminating nullbyte. + +When this non-null-terminated string is later passed to +snd_card_set_id() -> copy_valid_id_string(), the function scans +forward with `while (*nid && ...)` and reads past the end of the +stack buffer, reading the contents of the stack. + +A USB device with a product name containing many non-ASCII, non-space +characters (e.g. multibyte UTF-8) will reliably trigger this as follows: + + BUG: KASAN: stack-out-of-bounds in copy_valid_id_string + sound/core/init.c:696 [inline] + BUG: KASAN: stack-out-of-bounds in snd_card_set_id_no_lock+0x698/0x74c + sound/core/init.c:718 + +The off-by-one has been present since commit bafeee5b1f8d ("ALSA: +snd_usb_caiaq: give better shortname") from June 2009 (v2.6.31-rc1), +which first introduced this whitespace-stripping loop. The original +code never accounted for the null terminator when bounding the copy. + +Fix this by changing the loop bound to `sizeof(card->id) - 1`, +ensuring at least one byte remains as the null terminator. + +Fixes: bafeee5b1f8d ("ALSA: snd_usb_caiaq: give better shortname") +Cc: stable@vger.kernel.org +Cc: Andrey Konovalov +Reported-by: Berk Cem Goksel +Signed-off-by: Berk Cem Goksel +Link: https://patch.msgid.link/20260329133825.581585-1-berkcgoksel@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/caiaq/device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/usb/caiaq/device.c ++++ b/sound/usb/caiaq/device.c +@@ -488,7 +488,7 @@ static int init_card(struct snd_usb_caia + memset(id, 0, sizeof(id)); + + for (c = card->shortname, len = 0; +- *c && len < sizeof(card->id); c++) ++ *c && len < sizeof(card->id) - 1; c++) + if (*c != ' ') + id[len++] = *c; + diff --git a/queue-6.19/alsa-ctxfi-check-the-error-for-index-mapping.patch b/queue-6.19/alsa-ctxfi-check-the-error-for-index-mapping.patch new file mode 100644 index 0000000000..6d753c2b86 --- /dev/null +++ b/queue-6.19/alsa-ctxfi-check-the-error-for-index-mapping.patch @@ -0,0 +1,195 @@ +From 277c6960d4ddb94d16198afd70c92c3d4593d131 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 29 Mar 2026 11:12:38 +0200 +Subject: ALSA: ctxfi: Check the error for index mapping + +From: Takashi Iwai + +commit 277c6960d4ddb94d16198afd70c92c3d4593d131 upstream. + +The ctxfi driver blindly assumed a proper value returned from +daio_device_index(), but it's not always true. Add a proper error +check to deal with the error from the function. + +Cc: +Link: https://lore.kernel.org/87cy149n6k.wl-tiwai@suse.de +Link: https://patch.msgid.link/20260329091240.420194-2-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/ctxfi/ctdaio.c | 81 +++++++++++++++++++++++++++++------------------ + 1 file changed, 50 insertions(+), 31 deletions(-) + +--- a/sound/pci/ctxfi/ctdaio.c ++++ b/sound/pci/ctxfi/ctdaio.c +@@ -99,7 +99,7 @@ static const struct rsc_ops daio_in_rsc_ + .output_slot = daio_index, + }; + +-static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw) ++static int daio_device_index(enum DAIOTYP type, struct hw *hw) + { + switch (hw->chip_type) { + case ATC20K1: +@@ -112,7 +112,9 @@ static unsigned int daio_device_index(en + case LINEO3: return 5; + case LINEO4: return 6; + case LINEIM: return 7; +- default: return -EINVAL; ++ default: ++ pr_err("ctxfi: Invalid type %d for hw20k1\n", type); ++ return -EINVAL; + } + case ATC20K2: + switch (type) { +@@ -125,9 +127,12 @@ static unsigned int daio_device_index(en + case LINEIM: return 4; + case MIC: return 5; + case RCA: return 3; +- default: return -EINVAL; ++ default: ++ pr_err("ctxfi: Invalid type %d for hw20k2\n", type); ++ return -EINVAL; + } + default: ++ pr_err("ctxfi: Invalid chip type %d\n", hw->chip_type); + return -EINVAL; + } + } +@@ -148,8 +153,11 @@ static int dao_spdif_set_spos(struct dao + + static int dao_commit_write(struct dao *dao) + { +- dao->hw->dao_commit_write(dao->hw, +- daio_device_index(dao->daio.type, dao->hw), dao->ctrl_blk); ++ int idx = daio_device_index(dao->daio.type, dao->hw); ++ ++ if (idx < 0) ++ return idx; ++ dao->hw->dao_commit_write(dao->hw, idx, dao->ctrl_blk); + return 0; + } + +@@ -287,8 +295,11 @@ static int dai_set_enb_srt(struct dai *d + + static int dai_commit_write(struct dai *dai) + { +- dai->hw->dai_commit_write(dai->hw, +- daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk); ++ int idx = daio_device_index(dai->daio.type, dai->hw); ++ ++ if (idx < 0) ++ return idx; ++ dai->hw->dai_commit_write(dai->hw, idx, dai->ctrl_blk); + return 0; + } + +@@ -367,7 +378,7 @@ static int dao_rsc_init(struct dao *dao, + { + struct hw *hw = mgr->mgr.hw; + unsigned int conf; +- int err; ++ int idx, err; + + err = daio_rsc_init(&dao->daio, desc, mgr->mgr.hw); + if (err) +@@ -386,15 +397,18 @@ static int dao_rsc_init(struct dao *dao, + if (err) + goto error2; + +- hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, +- daio_device_index(dao->daio.type, hw)); ++ idx = daio_device_index(dao->daio.type, hw); ++ if (idx < 0) { ++ err = idx; ++ goto error2; ++ } ++ ++ hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx); + hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); + + conf = (desc->msr & 0x7) | (desc->passthru << 3); +- hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, +- daio_device_index(dao->daio.type, hw), conf); +- hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, +- daio_device_index(dao->daio.type, hw)); ++ hw->daio_mgr_dao_init(hw, mgr->mgr.ctrl_blk, idx, conf); ++ hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx); + hw->daio_mgr_commit_write(hw, mgr->mgr.ctrl_blk); + + return 0; +@@ -443,7 +457,7 @@ static int dai_rsc_init(struct dai *dai, + const struct daio_desc *desc, + struct daio_mgr *mgr) + { +- int err; ++ int idx, err; + struct hw *hw = mgr->mgr.hw; + unsigned int rsr, msr; + +@@ -457,6 +471,12 @@ static int dai_rsc_init(struct dai *dai, + if (err) + goto error1; + ++ idx = daio_device_index(dai->daio.type, dai->hw); ++ if (idx < 0) { ++ err = idx; ++ goto error1; ++ } ++ + for (rsr = 0, msr = desc->msr; msr > 1; msr >>= 1) + rsr++; + +@@ -465,8 +485,7 @@ static int dai_rsc_init(struct dai *dai, + /* default to disabling control of a SRC */ + hw->dai_srt_set_ec(dai->ctrl_blk, 0); + hw->dai_srt_set_et(dai->ctrl_blk, 0); /* default to disabling SRT */ +- hw->dai_commit_write(hw, +- daio_device_index(dai->daio.type, dai->hw), dai->ctrl_blk); ++ hw->dai_commit_write(hw, idx, dai->ctrl_blk); + + return 0; + +@@ -581,28 +600,28 @@ static int put_daio_rsc(struct daio_mgr + static int daio_mgr_enb_daio(struct daio_mgr *mgr, struct daio *daio) + { + struct hw *hw = mgr->mgr.hw; ++ int idx = daio_device_index(daio->type, hw); + +- if (daio->output) { +- hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, +- daio_device_index(daio->type, hw)); +- } else { +- hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk, +- daio_device_index(daio->type, hw)); +- } ++ if (idx < 0) ++ return idx; ++ if (daio->output) ++ hw->daio_mgr_enb_dao(mgr->mgr.ctrl_blk, idx); ++ else ++ hw->daio_mgr_enb_dai(mgr->mgr.ctrl_blk, idx); + return 0; + } + + static int daio_mgr_dsb_daio(struct daio_mgr *mgr, struct daio *daio) + { + struct hw *hw = mgr->mgr.hw; ++ int idx = daio_device_index(daio->type, hw); + +- if (daio->output) { +- hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, +- daio_device_index(daio->type, hw)); +- } else { +- hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk, +- daio_device_index(daio->type, hw)); +- } ++ if (idx < 0) ++ return idx; ++ if (daio->output) ++ hw->daio_mgr_dsb_dao(mgr->mgr.ctrl_blk, idx); ++ else ++ hw->daio_mgr_dsb_dai(mgr->mgr.ctrl_blk, idx); + return 0; + } + diff --git a/queue-6.19/alsa-ctxfi-don-t-enumerate-spdif1-at-daio-initialization.patch b/queue-6.19/alsa-ctxfi-don-t-enumerate-spdif1-at-daio-initialization.patch new file mode 100644 index 0000000000..63b451282d --- /dev/null +++ b/queue-6.19/alsa-ctxfi-don-t-enumerate-spdif1-at-daio-initialization.patch @@ -0,0 +1,54 @@ +From 75dc1980cf48826287e43dc7a49e310c6691f97e Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 31 Mar 2026 10:12:17 +0200 +Subject: ALSA: ctxfi: Don't enumerate SPDIF1 at DAIO initialization + +From: Takashi Iwai + +commit 75dc1980cf48826287e43dc7a49e310c6691f97e upstream. + +The recent refactoring of xfi driver changed the assignment of +atc->daios[] at atc_get_resources(); now it loops over all enum +DAIOTYP entries while it looped formerly only a part of them. +The problem is that the last entry, SPDIF1, is a special type that +is used only for hw20k1 CTSB073X model (as a replacement of SPDIFIO), +and there is no corresponding definition for hw20k2. Due to the lack +of the info, it caused a kernel crash on hw20k2, which was already +worked around by the commit b045ab3dff97 ("ALSA: ctxfi: Fix missing +SPDIFI1 index handling"). + +This patch addresses the root cause of the regression above properly, +simply by skipping the incorrect SPDIF1 type in the parser loop. + +For making the change clearer, the code is slightly arranged, too. + +Fixes: a2dbaeb5c61e ("ALSA: ctxfi: Refactor resource alloc for sparse mappings") +Cc: +Link: https://bugzilla.suse.com/show_bug.cgi?id=1259925 +Link: https://patch.msgid.link/20260331081227.216134-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/ctxfi/ctatc.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/sound/pci/ctxfi/ctatc.c ++++ b/sound/pci/ctxfi/ctatc.c +@@ -1427,10 +1427,14 @@ static int atc_get_resources(struct ct_a + daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; + da_desc.msr = atc->msr; + for (i = 0; i < NUM_DAIOTYP; i++) { +- if (((i == MIC) && !cap.dedicated_mic) || ((i == RCA) && !cap.dedicated_rca)) ++ if (((i == MIC) && !cap.dedicated_mic) || ++ ((i == RCA) && !cap.dedicated_rca) || ++ i == SPDIFI1) + continue; +- da_desc.type = (atc->model != CTSB073X) ? i : +- ((i == SPDIFIO) ? SPDIFI1 : i); ++ if (atc->model == CTSB073X && i == SPDIFIO) ++ da_desc.type = SPDIFI1; ++ else ++ da_desc.type = i; + da_desc.output = (i < LINEIM) || (i == RCA); + err = daio_mgr->get_daio(daio_mgr, &da_desc, + (struct daio **)&atc->daios[i]); diff --git a/queue-6.19/alsa-ctxfi-fix-missing-spdifi1-index-handling.patch b/queue-6.19/alsa-ctxfi-fix-missing-spdifi1-index-handling.patch new file mode 100644 index 0000000000..75a4d4ae7a --- /dev/null +++ b/queue-6.19/alsa-ctxfi-fix-missing-spdifi1-index-handling.patch @@ -0,0 +1,34 @@ +From b045ab3dff97edae6d538eeff900a34c098761f8 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Sun, 29 Mar 2026 11:12:37 +0200 +Subject: ALSA: ctxfi: Fix missing SPDIFI1 index handling + +From: Takashi Iwai + +commit b045ab3dff97edae6d538eeff900a34c098761f8 upstream. + +SPDIF1 DAIO type isn't properly handled in daio_device_index() for +hw20k2, and it returned -EINVAL, which ended up with the out-of-bounds +array access. Follow the hw20k1 pattern and return the proper index +for this type, too. + +Reported-and-tested-by: Karsten Hohmeier +Closes: https://lore.kernel.org/20260315155004.15633-1-linux@hohmatik.de +Cc: +Link: https://patch.msgid.link/20260329091240.420194-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/pci/ctxfi/ctdaio.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/pci/ctxfi/ctdaio.c ++++ b/sound/pci/ctxfi/ctdaio.c +@@ -120,6 +120,7 @@ static int daio_device_index(enum DAIOTY + switch (type) { + case SPDIFOO: return 0; + case SPDIFIO: return 0; ++ case SPDIFI1: return 1; + case LINEO1: return 4; + case LINEO2: return 7; + case LINEO3: return 5; diff --git a/queue-6.19/alsa-hda-realtek-add-quirk-for-acer-swift-sfg14-73.patch b/queue-6.19/alsa-hda-realtek-add-quirk-for-acer-swift-sfg14-73.patch new file mode 100644 index 0000000000..e88ef2ec40 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-quirk-for-acer-swift-sfg14-73.patch @@ -0,0 +1,31 @@ +From dd9b99b822684f421f9b7e1e5a69d791ffc1d48f Mon Sep 17 00:00:00 2001 +From: Zhang Heng +Date: Tue, 31 Mar 2026 17:46:14 +0800 +Subject: ALSA: hda/realtek: add quirk for Acer Swift SFG14-73 + +From: Zhang Heng + +commit dd9b99b822684f421f9b7e1e5a69d791ffc1d48f upstream. + +fix mute/micmute LEDs and headset microphone for Acer Swift SFG14-73. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220279 +Cc: stable@vger.kernel.org +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260331094614.186063-1-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -6685,6 +6685,7 @@ static const struct hda_quirk alc269_fix + SND_PCI_QUIRK(0x1025, 0x1597, "Acer Nitro 5 AN517-55", ALC2XX_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x169a, "Acer Swift SFG16", ALC256_FIXUP_ACER_SFG16_MICMUTE_LED), + SND_PCI_QUIRK(0x1025, 0x171e, "Acer Nitro ANV15-51", ALC245_FIXUP_ACER_MICMUTE_LED), ++ SND_PCI_QUIRK(0x1025, 0x173a, "Acer Swift SFG14-73", ALC245_FIXUP_ACER_MICMUTE_LED), + SND_PCI_QUIRK(0x1025, 0x1826, "Acer Helios ZPC", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1025, 0x182c, "Acer Helios ZPD", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1025, 0x1844, "Acer Helios ZPS", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), diff --git a/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-rog-strix-scar-15.patch b/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-rog-strix-scar-15.patch new file mode 100644 index 0000000000..5d195ab5b2 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-quirk-for-asus-rog-strix-scar-15.patch @@ -0,0 +1,32 @@ +From f1af71d568e55536d9297bfa7907ad497108cf30 Mon Sep 17 00:00:00 2001 +From: Zhang Heng +Date: Mon, 30 Mar 2026 15:53:34 +0800 +Subject: ALSA: hda/realtek: Add quirk for ASUS ROG Strix SCAR 15 + +From: Zhang Heng + +commit f1af71d568e55536d9297bfa7907ad497108cf30 upstream. + +ASUS ROG Strix SCAR 15, like the Strix G15, requires the +ALC285_FIXUP_ASUS_G533Z_PINS quirk to work properly. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=221247 +Cc: +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260330075334.50962-2-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7238,6 +7238,7 @@ static const struct hda_quirk alc269_fix + SND_PCI_QUIRK(0x1043, 0x1533, "ASUS GV302XA/XJ/XQ/XU/XV/XI", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x1043, 0x1573, "ASUS GZ301VV/VQ/VU/VJ/VA/VC/VE/VVC/VQC/VUC/VJC/VEC/VCC", ALC285_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x1584, "ASUS UM3406GA ", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x1043, 0x1602, "ASUS ROG Strix SCAR 15", ALC285_FIXUP_ASUS_G533Z_PINS), + SND_PCI_QUIRK(0x1043, 0x1652, "ASUS ROG Zephyrus Do 15 SE", ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x1662, "ASUS GV301QH", ALC294_FIXUP_ASUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC), diff --git a/queue-6.19/alsa-hda-realtek-add-quirk-for-hp-victus-15-fb0xxx.patch b/queue-6.19/alsa-hda-realtek-add-quirk-for-hp-victus-15-fb0xxx.patch new file mode 100644 index 0000000000..7b3ae7c8e2 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-add-quirk-for-hp-victus-15-fb0xxx.patch @@ -0,0 +1,35 @@ +From 1fbf85dbf02c96c318e056fb5b8fc614758fee3c Mon Sep 17 00:00:00 2001 +From: Sourav Nayak +Date: Fri, 27 Mar 2026 19:58:05 +0530 +Subject: ALSA: hda/realtek: add quirk for HP Victus 15-fb0xxx + +From: Sourav Nayak + +commit 1fbf85dbf02c96c318e056fb5b8fc614758fee3c upstream. + +This adds a mute led quirck for HP Victus 15-fb0xxx (103c:8a3d) model + +- As it used 0x8(full bright)/0x7f(little dim) for mute led on and other + values as 0ff (0x0, 0x4, ...) + +- So, use ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT insted for safer approach + +Cc: +Signed-off-by: Sourav Nayak +Link: https://patch.msgid.link/20260327142805.17139-1-nonameblank007@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -6981,6 +6981,7 @@ static const struct hda_quirk alc269_fix + SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), ++ SND_PCI_QUIRK(0x103c, 0x8a3d, "HP Victus 15-fb0xxx (MB 8A3D)", ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a4f, "HP Victus 15-fa0xxx (MB 8A4F)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4), + SND_PCI_QUIRK(0x103c, 0x8a74, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), diff --git a/queue-6.19/alsa-hda-realtek-change-quirk-for-hp-omnibook-7-laptop-16-bh0xxx.patch b/queue-6.19/alsa-hda-realtek-change-quirk-for-hp-omnibook-7-laptop-16-bh0xxx.patch new file mode 100644 index 0000000000..9ada2a2bb9 --- /dev/null +++ b/queue-6.19/alsa-hda-realtek-change-quirk-for-hp-omnibook-7-laptop-16-bh0xxx.patch @@ -0,0 +1,55 @@ +From 73ff3916d803f7ca3a4325af649e46ff89d6c3a7 Mon Sep 17 00:00:00 2001 +From: Zhang Heng +Date: Fri, 27 Mar 2026 18:12:15 +0800 +Subject: ALSA: hda/realtek: change quirk for HP OmniBook 7 Laptop 16-bh0xxx + +From: Zhang Heng + +commit 73ff3916d803f7ca3a4325af649e46ff89d6c3a7 upstream. + +HP OmniBook 7 Laptop 16-bh0xxx has the same PCI subsystem ID 0x103c8e60, +and the ALC245 on it needs this quirk to control the mute LED. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=221214 +Cc: +Tested-by: Artem S. Tashkinov +Signed-off-by: Zhang Heng +Link: https://patch.msgid.link/20260327101215.481108-1-zhangheng@kylinos.cn +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman +--- + sound/hda/codecs/realtek/alc269.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -4102,6 +4102,7 @@ enum { + ALC233_FIXUP_LENOVO_GPIO2_MIC_HOTKEY, + ALC245_FIXUP_BASS_HP_DAC, + ALC245_FIXUP_ACER_MICMUTE_LED, ++ ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED, + }; + + /* A special fixup for Lenovo C940 and Yoga Duet 7; +@@ -6631,6 +6632,12 @@ static const struct hda_fixup alc269_fix + .v.func = alc285_fixup_hp_coef_micmute_led, + .chained = true, + .chain_id = ALC2XX_FIXUP_HEADSET_MIC, ++ }, ++ [ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc245_fixup_hp_mute_led_coefbit, ++ .chained = true, ++ .chain_id = ALC287_FIXUP_CS35L41_I2C_2, + } + }; + +@@ -7156,7 +7163,7 @@ static const struct hda_quirk alc269_fix + SND_PCI_QUIRK(0x103c, 0x8e37, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e3a, "HP Agusta", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e3b, "HP Agusta", ALC287_FIXUP_CS35L41_I2C_2), +- SND_PCI_QUIRK(0x103c, 0x8e60, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x103c, 0x8e60, "HP OmniBook 7 Laptop 16-bh0xxx", ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8e61, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e62, "HP Trekker ", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8e8a, "HP NexusX", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), diff --git a/queue-6.19/bluetooth-hci_event-move-wake-reason-storage-into-validated-event-handlers.patch b/queue-6.19/bluetooth-hci_event-move-wake-reason-storage-into-validated-event-handlers.patch new file mode 100644 index 0000000000..2811e6fc11 --- /dev/null +++ b/queue-6.19/bluetooth-hci_event-move-wake-reason-storage-into-validated-event-handlers.patch @@ -0,0 +1,239 @@ +From 2b2bf47cd75518c36fa2d41380e4a40641cc89cd Mon Sep 17 00:00:00 2001 +From: Oleh Konko +Date: Thu, 26 Mar 2026 17:31:24 +0000 +Subject: Bluetooth: hci_event: move wake reason storage into validated event handlers + +From: Oleh Konko + +commit 2b2bf47cd75518c36fa2d41380e4a40641cc89cd upstream. + +hci_store_wake_reason() is called from hci_event_packet() immediately +after stripping the HCI event header but before hci_event_func() +enforces the per-event minimum payload length from hci_ev_table. +This means a short HCI event frame can reach bacpy() before any bounds +check runs. + +Rather than duplicating skb parsing and per-event length checks inside +hci_store_wake_reason(), move wake-address storage into the individual +event handlers after their existing event-length validation has +succeeded. Convert hci_store_wake_reason() into a small helper that only +stores an already-validated bdaddr while the caller holds hci_dev_lock(). +Use the same helper after hci_event_func() with a NULL address to +preserve the existing unexpected-wake fallback semantics when no +validated event handler records a wake address. + +Annotate the helper with __must_hold(&hdev->lock) and add +lockdep_assert_held(&hdev->lock) so future call paths keep the lock +contract explicit. + +Call the helper from hci_conn_request_evt(), hci_conn_complete_evt(), +hci_sync_conn_complete_evt(), le_conn_complete_evt(), +hci_le_adv_report_evt(), hci_le_ext_adv_report_evt(), +hci_le_direct_adv_report_evt(), hci_le_pa_sync_established_evt(), and +hci_le_past_received_evt(). + +Fixes: 2f20216c1d6f ("Bluetooth: Emit controller suspend and resume events") +Cc: stable@vger.kernel.org +Signed-off-by: Oleh Konko +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_event.c | 94 +++++++++++++++++----------------------------- + 1 file changed, 35 insertions(+), 59 deletions(-) + +--- a/net/bluetooth/hci_event.c ++++ b/net/bluetooth/hci_event.c +@@ -80,6 +80,10 @@ static void *hci_le_ev_skb_pull(struct h + return data; + } + ++static void hci_store_wake_reason(struct hci_dev *hdev, ++ const bdaddr_t *bdaddr, u8 addr_type) ++ __must_hold(&hdev->lock); ++ + static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data, + struct sk_buff *skb) + { +@@ -3111,6 +3115,7 @@ static void hci_conn_complete_evt(struct + bt_dev_dbg(hdev, "status 0x%2.2x", status); + + hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR); + + /* Check for existing connection: + * +@@ -3274,6 +3279,10 @@ static void hci_conn_request_evt(struct + + bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type); + ++ hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR); ++ hci_dev_unlock(hdev); ++ + /* Reject incoming connection from device with same BD ADDR against + * CVE-2020-26555 + */ +@@ -5021,6 +5030,7 @@ static void hci_sync_conn_complete_evt(s + bt_dev_dbg(hdev, "status 0x%2.2x", status); + + hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, &ev->bdaddr, BDADDR_BREDR); + + conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); + if (!conn) { +@@ -5713,6 +5723,7 @@ static void le_conn_complete_evt(struct + int err; + + hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, bdaddr, bdaddr_type); + + /* All controllers implicitly stop advertising in the event of a + * connection, so ensure that the state bit is cleared. +@@ -6005,6 +6016,7 @@ static void hci_le_past_received_evt(str + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + + hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, &ev->bdaddr, ev->bdaddr_type); + + hci_dev_clear_flag(hdev, HCI_PA_SYNC); + +@@ -6403,6 +6415,8 @@ static void hci_le_adv_report_evt(struct + info->length + 1)) + break; + ++ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type); ++ + if (info->length <= max_adv_len(hdev)) { + rssi = info->data[info->length]; + process_adv_report(hdev, info->type, &info->bdaddr, +@@ -6491,6 +6505,8 @@ static void hci_le_ext_adv_report_evt(st + info->length)) + break; + ++ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type); ++ + evt_type = __le16_to_cpu(info->type) & LE_EXT_ADV_EVT_TYPE_MASK; + legacy_evt_type = ext_evt_type_to_legacy(hdev, evt_type); + +@@ -6536,6 +6552,7 @@ static void hci_le_pa_sync_established_e + bt_dev_dbg(hdev, "status 0x%2.2x", ev->status); + + hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, &ev->bdaddr, ev->bdaddr_type); + + hci_dev_clear_flag(hdev, HCI_PA_SYNC); + +@@ -6841,6 +6858,8 @@ static void hci_le_direct_adv_report_evt + for (i = 0; i < ev->num; i++) { + struct hci_ev_le_direct_adv_info *info = &ev->info[i]; + ++ hci_store_wake_reason(hdev, &info->bdaddr, info->bdaddr_type); ++ + process_adv_report(hdev, info->type, &info->bdaddr, + info->bdaddr_type, &info->direct_addr, + info->direct_addr_type, HCI_ADV_PHY_1M, 0, +@@ -7509,73 +7528,29 @@ static bool hci_get_cmd_complete(struct + return true; + } + +-static void hci_store_wake_reason(struct hci_dev *hdev, u8 event, +- struct sk_buff *skb) ++static void hci_store_wake_reason(struct hci_dev *hdev, ++ const bdaddr_t *bdaddr, u8 addr_type) ++ __must_hold(&hdev->lock) + { +- struct hci_ev_le_advertising_info *adv; +- struct hci_ev_le_direct_adv_info *direct_adv; +- struct hci_ev_le_ext_adv_info *ext_adv; +- const struct hci_ev_conn_complete *conn_complete = (void *)skb->data; +- const struct hci_ev_conn_request *conn_request = (void *)skb->data; +- +- hci_dev_lock(hdev); ++ lockdep_assert_held(&hdev->lock); + + /* If we are currently suspended and this is the first BT event seen, + * save the wake reason associated with the event. + */ + if (!hdev->suspended || hdev->wake_reason) +- goto unlock; ++ return; ++ ++ if (!bdaddr) { ++ hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED; ++ return; ++ } + + /* Default to remote wake. Values for wake_reason are documented in the + * Bluez mgmt api docs. + */ + hdev->wake_reason = MGMT_WAKE_REASON_REMOTE_WAKE; +- +- /* Once configured for remote wakeup, we should only wake up for +- * reconnections. It's useful to see which device is waking us up so +- * keep track of the bdaddr of the connection event that woke us up. +- */ +- if (event == HCI_EV_CONN_REQUEST) { +- bacpy(&hdev->wake_addr, &conn_request->bdaddr); +- hdev->wake_addr_type = BDADDR_BREDR; +- } else if (event == HCI_EV_CONN_COMPLETE) { +- bacpy(&hdev->wake_addr, &conn_complete->bdaddr); +- hdev->wake_addr_type = BDADDR_BREDR; +- } else if (event == HCI_EV_LE_META) { +- struct hci_ev_le_meta *le_ev = (void *)skb->data; +- u8 subevent = le_ev->subevent; +- u8 *ptr = &skb->data[sizeof(*le_ev)]; +- u8 num_reports = *ptr; +- +- if ((subevent == HCI_EV_LE_ADVERTISING_REPORT || +- subevent == HCI_EV_LE_DIRECT_ADV_REPORT || +- subevent == HCI_EV_LE_EXT_ADV_REPORT) && +- num_reports) { +- adv = (void *)(ptr + 1); +- direct_adv = (void *)(ptr + 1); +- ext_adv = (void *)(ptr + 1); +- +- switch (subevent) { +- case HCI_EV_LE_ADVERTISING_REPORT: +- bacpy(&hdev->wake_addr, &adv->bdaddr); +- hdev->wake_addr_type = adv->bdaddr_type; +- break; +- case HCI_EV_LE_DIRECT_ADV_REPORT: +- bacpy(&hdev->wake_addr, &direct_adv->bdaddr); +- hdev->wake_addr_type = direct_adv->bdaddr_type; +- break; +- case HCI_EV_LE_EXT_ADV_REPORT: +- bacpy(&hdev->wake_addr, &ext_adv->bdaddr); +- hdev->wake_addr_type = ext_adv->bdaddr_type; +- break; +- } +- } +- } else { +- hdev->wake_reason = MGMT_WAKE_REASON_UNEXPECTED; +- } +- +-unlock: +- hci_dev_unlock(hdev); ++ bacpy(&hdev->wake_addr, bdaddr); ++ hdev->wake_addr_type = addr_type; + } + + #define HCI_EV_VL(_op, _func, _min_len, _max_len) \ +@@ -7822,14 +7797,15 @@ void hci_event_packet(struct hci_dev *hd + + skb_pull(skb, HCI_EVENT_HDR_SIZE); + +- /* Store wake reason if we're suspended */ +- hci_store_wake_reason(hdev, event, skb); +- + bt_dev_dbg(hdev, "event 0x%2.2x", event); + + hci_event_func(hdev, event, skb, &opcode, &status, &req_complete, + &req_complete_skb); + ++ hci_dev_lock(hdev); ++ hci_store_wake_reason(hdev, NULL, 0); ++ hci_dev_unlock(hdev); ++ + if (req_complete) { + req_complete(hdev, status, opcode); + } else if (req_complete_skb) { diff --git a/queue-6.19/bluetooth-hci_sync-fix-stack-buffer-overflow-in-hci_le_big_create_sync.patch b/queue-6.19/bluetooth-hci_sync-fix-stack-buffer-overflow-in-hci_le_big_create_sync.patch new file mode 100644 index 0000000000..2eb3787e85 --- /dev/null +++ b/queue-6.19/bluetooth-hci_sync-fix-stack-buffer-overflow-in-hci_le_big_create_sync.patch @@ -0,0 +1,54 @@ +From bc39a094730ce062fa034a529c93147c096cb488 Mon Sep 17 00:00:00 2001 +From: hkbinbin +Date: Tue, 31 Mar 2026 05:39:16 +0000 +Subject: Bluetooth: hci_sync: fix stack buffer overflow in hci_le_big_create_sync +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: hkbinbin + +commit bc39a094730ce062fa034a529c93147c096cb488 upstream. + +hci_le_big_create_sync() uses DEFINE_FLEX to allocate a +struct hci_cp_le_big_create_sync on the stack with room for 0x11 (17) +BIS entries. However, conn->num_bis can hold up to HCI_MAX_ISO_BIS (31) +entries — validated against ISO_MAX_NUM_BIS (0x1f) in the caller +hci_conn_big_create_sync(). When conn->num_bis is between 18 and 31, +the memcpy that copies conn->bis into cp->bis writes up to 14 bytes +past the stack buffer, corrupting adjacent stack memory. + +This is trivially reproducible: binding an ISO socket with +bc_num_bis = ISO_MAX_NUM_BIS (31) and calling listen() will +eventually trigger hci_le_big_create_sync() from the HCI command +sync worker, causing a KASAN-detectable stack-out-of-bounds write: + + BUG: KASAN: stack-out-of-bounds in hci_le_big_create_sync+0x256/0x3b0 + Write of size 31 at addr ffffc90000487b48 by task kworker/u9:0/71 + +Fix this by changing the DEFINE_FLEX count from the incorrect 0x11 to +HCI_MAX_ISO_BIS, which matches the maximum number of BIS entries that +conn->bis can actually carry. + +Fixes: 42ecf1947135 ("Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending") +Cc: stable@vger.kernel.org +Signed-off-by: hkbinbin +Reviewed-by: Paul Menzel +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_sync.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -7210,7 +7210,8 @@ static void create_big_complete(struct h + + static int hci_le_big_create_sync(struct hci_dev *hdev, void *data) + { +- DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11); ++ DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, ++ HCI_MAX_ISO_BIS); + struct hci_conn *conn = data; + struct bt_iso_qos *qos = &conn->iso_qos; + int err; diff --git a/queue-6.19/bluetooth-smp-derive-legacy-responder-stk-authentication-from-mitm-state.patch b/queue-6.19/bluetooth-smp-derive-legacy-responder-stk-authentication-from-mitm-state.patch new file mode 100644 index 0000000000..687fdb23d7 --- /dev/null +++ b/queue-6.19/bluetooth-smp-derive-legacy-responder-stk-authentication-from-mitm-state.patch @@ -0,0 +1,45 @@ +From 20756fec2f0108cb88e815941f1ffff88dc286fe Mon Sep 17 00:00:00 2001 +From: Oleh Konko +Date: Tue, 31 Mar 2026 11:52:13 +0000 +Subject: Bluetooth: SMP: derive legacy responder STK authentication from MITM state + +From: Oleh Konko + +commit 20756fec2f0108cb88e815941f1ffff88dc286fe upstream. + +The legacy responder path in smp_random() currently labels the stored +STK as authenticated whenever pending_sec_level is BT_SECURITY_HIGH. +That reflects what the local service requested, not what the pairing +flow actually achieved. + +For Just Works/Confirm legacy pairing, SMP_FLAG_MITM_AUTH stays clear +and the resulting STK should remain unauthenticated even if the local +side requested HIGH security. Use the established MITM state when +storing the responder STK so the key metadata matches the pairing result. + +This also keeps the legacy path aligned with the Secure Connections code, +which already treats JUST_WORKS/JUST_CFM as unauthenticated. + +Fixes: fff3490f4781 ("Bluetooth: Fix setting correct authentication information for SMP STK") +Cc: stable@vger.kernel.org +Signed-off-by: Oleh Konko +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/smp.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -1018,10 +1018,7 @@ static u8 smp_random(struct smp_chan *sm + + smp_s1(smp->tk, smp->prnd, smp->rrnd, stk); + +- if (hcon->pending_sec_level == BT_SECURITY_HIGH) +- auth = 1; +- else +- auth = 0; ++ auth = test_bit(SMP_FLAG_MITM_AUTH, &smp->flags) ? 1 : 0; + + /* Even though there's no _RESPONDER suffix this is the + * responder STK we're adding for later lookup (the initiator diff --git a/queue-6.19/bluetooth-smp-force-responder-mitm-requirements-before-building-the-pairing-response.patch b/queue-6.19/bluetooth-smp-force-responder-mitm-requirements-before-building-the-pairing-response.patch new file mode 100644 index 0000000000..a917ce8216 --- /dev/null +++ b/queue-6.19/bluetooth-smp-force-responder-mitm-requirements-before-building-the-pairing-response.patch @@ -0,0 +1,55 @@ +From d05111bfe37bfd8bd4d2dfe6675d6bdeef43f7c7 Mon Sep 17 00:00:00 2001 +From: Oleh Konko +Date: Tue, 31 Mar 2026 11:52:12 +0000 +Subject: Bluetooth: SMP: force responder MITM requirements before building the pairing response + +From: Oleh Konko + +commit d05111bfe37bfd8bd4d2dfe6675d6bdeef43f7c7 upstream. + +smp_cmd_pairing_req() currently builds the pairing response from the +initiator auth_req before enforcing the local BT_SECURITY_HIGH +requirement. If the initiator omits SMP_AUTH_MITM, the response can +also omit it even though the local side still requires MITM. + +tk_request() then sees an auth value without SMP_AUTH_MITM and may +select JUST_CFM, making method selection inconsistent with the pairing +policy the responder already enforces. + +When the local side requires HIGH security, first verify that MITM can +be achieved from the IO capabilities and then force SMP_AUTH_MITM in the +response in both rsp.auth_req and auth. This keeps the responder auth bits +and later method selection aligned. + +Fixes: 2b64d153a0cc ("Bluetooth: Add MITM mechanism to LE-SMP") +Cc: stable@vger.kernel.org +Suggested-by: Luiz Augusto von Dentz +Signed-off-by: Oleh Konko +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/smp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -1823,7 +1823,7 @@ static u8 smp_cmd_pairing_req(struct l2c + if (sec_level > conn->hcon->pending_sec_level) + conn->hcon->pending_sec_level = sec_level; + +- /* If we need MITM check that it can be achieved */ ++ /* If we need MITM check that it can be achieved. */ + if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { + u8 method; + +@@ -1831,6 +1831,10 @@ static u8 smp_cmd_pairing_req(struct l2c + req->io_capability); + if (method == JUST_WORKS || method == JUST_CFM) + return SMP_AUTH_REQUIREMENTS; ++ ++ /* Force MITM bit if it isn't set by the initiator. */ ++ auth |= SMP_AUTH_MITM; ++ rsp.auth_req |= SMP_AUTH_MITM; + } + + key_size = min(req->max_key_size, rsp.max_key_size); diff --git a/queue-6.19/drm-amd-display-fix-null-pointer-dereference-in-dcn401_init_hw.patch b/queue-6.19/drm-amd-display-fix-null-pointer-dereference-in-dcn401_init_hw.patch new file mode 100644 index 0000000000..d7b0bff822 --- /dev/null +++ b/queue-6.19/drm-amd-display-fix-null-pointer-dereference-in-dcn401_init_hw.patch @@ -0,0 +1,79 @@ +From e927b36ae18b66b49219eaa9f46edc7b4fdbb25e Mon Sep 17 00:00:00 2001 +From: Srinivasan Shanmugam +Date: Sat, 21 Mar 2026 17:25:14 +0530 +Subject: drm/amd/display: Fix NULL pointer dereference in dcn401_init_hw() + +From: Srinivasan Shanmugam + +commit e927b36ae18b66b49219eaa9f46edc7b4fdbb25e upstream. + +dcn401_init_hw() assumes that update_bw_bounding_box() is valid when +entering the update path. However, the existing condition: + + ((!fams2_enable && update_bw_bounding_box) || freq_changed) + +does not guarantee this, as the freq_changed branch can evaluate to true +independently of the callback pointer. + +This can result in calling update_bw_bounding_box() when it is NULL. + +Fix this by separating the update condition from the pointer checks and +ensuring the callback, dc->clk_mgr, and bw_params are validated before +use. + +Fixes the below: +../dc/hwss/dcn401/dcn401_hwseq.c:367 dcn401_init_hw() error: we previously assumed 'dc->res_pool->funcs->update_bw_bounding_box' could be null (see line 362) + +Fixes: ca0fb243c3bb ("drm/amd/display: Underflow Seen on DCN401 eGPU") +Cc: Daniel Sa +Cc: Alvin Lee +Cc: Roman Li +Cc: Alex Hung +Cc: Tom Chung +Cc: Dan Carpenter +Cc: Aurabindo Pillai +Signed-off-by: Srinivasan Shanmugam +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +(cherry picked from commit 86117c5ab42f21562fedb0a64bffea3ee5fcd477) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 17 +++++++++----- + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +@@ -146,6 +146,7 @@ void dcn401_init_hw(struct dc *dc) + int edp_num; + uint32_t backlight = MAX_BACKLIGHT_LEVEL; + uint32_t user_level = MAX_BACKLIGHT_LEVEL; ++ bool dchub_ref_freq_changed; + int current_dchub_ref_freq = 0; + + if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) { +@@ -359,14 +360,18 @@ void dcn401_init_hw(struct dc *dc) + dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr; + dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0; + dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver; ++ ++ /* sw and fw FAMS versions must match for support */ + dc->debug.fams2_config.bits.enable &= +- dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; // sw & fw fams versions must match for support +- if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box) +- || res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) { ++ dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; ++ dchub_ref_freq_changed = ++ res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq; ++ if ((!dc->debug.fams2_config.bits.enable || dchub_ref_freq_changed) && ++ dc->res_pool->funcs->update_bw_bounding_box && ++ dc->clk_mgr && dc->clk_mgr->bw_params) { + /* update bounding box if FAMS2 disabled, or if dchub clk has changed */ +- if (dc->clk_mgr) +- dc->res_pool->funcs->update_bw_bounding_box(dc, +- dc->clk_mgr->bw_params); ++ dc->res_pool->funcs->update_bw_bounding_box(dc, ++ dc->clk_mgr->bw_params); + } + } + } diff --git a/queue-6.19/drm-amdgpu-change-amdgpu_va_reserved_trap_size-to-64kb.patch b/queue-6.19/drm-amdgpu-change-amdgpu_va_reserved_trap_size-to-64kb.patch new file mode 100644 index 0000000000..cc59dcb824 --- /dev/null +++ b/queue-6.19/drm-amdgpu-change-amdgpu_va_reserved_trap_size-to-64kb.patch @@ -0,0 +1,112 @@ +From 4487571ef17a30d274600b3bd6965f497a881299 Mon Sep 17 00:00:00 2001 +From: Donet Tom +Date: Thu, 26 Mar 2026 17:51:28 +0530 +Subject: drm/amdgpu: Change AMDGPU_VA_RESERVED_TRAP_SIZE to 64KB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Donet Tom + +commit 4487571ef17a30d274600b3bd6965f497a881299 upstream. + +Currently, AMDGPU_VA_RESERVED_TRAP_SIZE is hardcoded to 8KB, while +KFD_CWSR_TBA_TMA_SIZE is defined as 2 * PAGE_SIZE. On systems with +4K pages, both values match (8KB), so allocation and reserved space +are consistent. + +However, on 64K page-size systems, KFD_CWSR_TBA_TMA_SIZE becomes 128KB, +while the reserved trap area remains 8KB. This mismatch causes the +kernel to crash when running rocminfo or rccl unit tests. + +Kernel attempted to read user page (2) - exploit attempt? (uid: 1001) +BUG: Kernel NULL pointer dereference on read at 0x00000002 +Faulting instruction address: 0xc0000000002c8a64 +Oops: Kernel access of bad area, sig: 11 [#1] +LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries +CPU: 34 UID: 1001 PID: 9379 Comm: rocminfo Tainted: G E +6.19.0-rc4-amdgpu-00320-gf23176405700 #56 VOLUNTARY +Tainted: [E]=UNSIGNED_MODULE +Hardware name: IBM,9105-42A POWER10 (architected) 0x800200 0xf000006 +of:IBM,FW1060.30 (ML1060_896) hv:phyp pSeries +NIP: c0000000002c8a64 LR: c00000000125dbc8 CTR: c00000000125e730 +REGS: c0000001e0957580 TRAP: 0300 Tainted: G E +MSR: 8000000000009033 CR: 24008268 +XER: 00000036 +CFAR: c00000000125dbc4 DAR: 0000000000000002 DSISR: 40000000 +IRQMASK: 1 +GPR00: c00000000125d908 c0000001e0957820 c0000000016e8100 +c00000013d814540 +GPR04: 0000000000000002 c00000013d814550 0000000000000045 +0000000000000000 +GPR08: c00000013444d000 c00000013d814538 c00000013d814538 +0000000084002268 +GPR12: c00000000125e730 c000007e2ffd5f00 ffffffffffffffff +0000000000020000 +GPR16: 0000000000000000 0000000000000002 c00000015f653000 +0000000000000000 +GPR20: c000000138662400 c00000013d814540 0000000000000000 +c00000013d814500 +GPR24: 0000000000000000 0000000000000002 c0000001e0957888 +c0000001e0957878 +GPR28: c00000013d814548 0000000000000000 c00000013d814540 +c0000001e0957888 +NIP [c0000000002c8a64] __mutex_add_waiter+0x24/0xc0 +LR [c00000000125dbc8] __mutex_lock.constprop.0+0x318/0xd00 +Call Trace: +0xc0000001e0957890 (unreliable) +__mutex_lock.constprop.0+0x58/0xd00 +amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x6fc/0xb60 [amdgpu] +kfd_process_alloc_gpuvm+0x54/0x1f0 [amdgpu] +kfd_process_device_init_cwsr_dgpu+0xa4/0x1a0 [amdgpu] +kfd_process_device_init_vm+0xd8/0x2e0 [amdgpu] +kfd_ioctl_acquire_vm+0xd0/0x130 [amdgpu] +kfd_ioctl+0x514/0x670 [amdgpu] +sys_ioctl+0x134/0x180 +system_call_exception+0x114/0x300 +system_call_vectored_common+0x15c/0x2ec + +This patch changes AMDGPU_VA_RESERVED_TRAP_SIZE to 64 KB and +KFD_CWSR_TBA_TMA_SIZE to the AMD GPU page size. This means we reserve +64 KB for the trap in the address space, but only allocate 8 KB within +it. With this approach, the allocation size never exceeds the reserved +area. + +Fixes: 34a1de0f7935 ("drm/amdkfd: Relocate TBA/TMA to opposite side of VM hole") +Reviewed-by: Christian König +Suggested-by: Felix Kuehling +Suggested-by: Christian König +Signed-off-by: Donet Tom +Signed-off-by: Alex Deucher +(cherry picked from commit 31b8de5e55666f26ea7ece5f412b83eab3f56dbb) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 2 +- + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +@@ -172,7 +172,7 @@ struct amdgpu_bo_vm; + #define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20) + #define AMDGPU_VA_RESERVED_SEQ64_START(adev) (AMDGPU_VA_RESERVED_CSA_START(adev) \ + - AMDGPU_VA_RESERVED_SEQ64_SIZE) +-#define AMDGPU_VA_RESERVED_TRAP_SIZE (2ULL << 12) ++#define AMDGPU_VA_RESERVED_TRAP_SIZE (1ULL << 16) + #define AMDGPU_VA_RESERVED_TRAP_START(adev) (AMDGPU_VA_RESERVED_SEQ64_START(adev) \ + - AMDGPU_VA_RESERVED_TRAP_SIZE) + #define AMDGPU_VA_RESERVED_BOTTOM (1ULL << 16) +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -102,8 +102,8 @@ + * The first chunk is the TBA used for the CWSR ISA code. The second + * chunk is used as TMA for user-mode trap handler setup in daisy-chain mode. + */ +-#define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2) +-#define KFD_CWSR_TMA_OFFSET (PAGE_SIZE + 2048) ++#define KFD_CWSR_TBA_TMA_SIZE (AMDGPU_GPU_PAGE_SIZE * 2) ++#define KFD_CWSR_TMA_OFFSET (AMDGPU_GPU_PAGE_SIZE + 2048) + + #define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ + (KFD_MAX_NUM_OF_PROCESSES * \ diff --git a/queue-6.19/drm-amdgpu-fix-the-idr-allocation-flags.patch b/queue-6.19/drm-amdgpu-fix-the-idr-allocation-flags.patch new file mode 100644 index 0000000000..356b91e10a --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-the-idr-allocation-flags.patch @@ -0,0 +1,56 @@ +From 62f553d60a801384336f5867967c26ddf3b17038 Mon Sep 17 00:00:00 2001 +From: Prike Liang +Date: Mon, 23 Mar 2026 16:07:02 +0800 +Subject: drm/amdgpu: fix the idr allocation flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Prike Liang + +commit 62f553d60a801384336f5867967c26ddf3b17038 upstream. + +Fix the IDR allocation flags by using atomic GFP +flags in non‑sleepable contexts to avoid the __might_sleep() +complaint. + + 268.290239] [drm] Initialized amdgpu 3.64.0 for 0000:03:00.0 on minor 0 +[ 268.294900] BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:323 +[ 268.295355] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1744, name: modprobe +[ 268.295705] preempt_count: 1, expected: 0 +[ 268.295886] RCU nest depth: 0, expected: 0 +[ 268.296072] 2 locks held by modprobe/1744: +[ 268.296077] #0: ffff8c3a44abd1b8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xe4/0x210 +[ 268.296100] #1: ffffffffc1a6ea78 (amdgpu_pasid_idr_lock){+.+.}-{3:3}, at: amdgpu_pasid_alloc+0x26/0xe0 [amdgpu] +[ 268.296494] CPU: 12 UID: 0 PID: 1744 Comm: modprobe Tainted: G U OE 6.19.0-custom #16 PREEMPT(voluntary) +[ 268.296498] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE +[ 268.296499] Hardware name: AMD Majolica-RN/Majolica-RN, BIOS RMJ1009A 06/13/2021 +[ 268.296501] Call Trace: + +Fixes: 8f1de51f49be ("drm/amdgpu: prevent immediate PASID reuse case") +Tested-by: Borislav Petkov (AMD) +Signed-off-by: Prike Liang +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +(cherry picked from commit ea56aa2625708eaf96f310032391ff37746310ef) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +@@ -68,8 +68,11 @@ int amdgpu_pasid_alloc(unsigned int bits + return -EINVAL; + + spin_lock(&amdgpu_pasid_idr_lock); ++ /* TODO: Need to replace the idr with an xarry, and then ++ * handle the internal locking with ATOMIC safe paths. ++ */ + pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1, +- 1U << bits, GFP_KERNEL); ++ 1U << bits, GFP_ATOMIC); + spin_unlock(&amdgpu_pasid_idr_lock); + + if (pasid >= 0) diff --git a/queue-6.19/drm-amdgpu-fix-wait-after-reset-sequence-in-s4.patch b/queue-6.19/drm-amdgpu-fix-wait-after-reset-sequence-in-s4.patch new file mode 100644 index 0000000000..af97ce27db --- /dev/null +++ b/queue-6.19/drm-amdgpu-fix-wait-after-reset-sequence-in-s4.patch @@ -0,0 +1,54 @@ +From daf470b8882b6f7f53cbfe9ec2b93a1b21528cdc Mon Sep 17 00:00:00 2001 +From: Lijo Lazar +Date: Fri, 27 Mar 2026 14:29:17 +0530 +Subject: drm/amdgpu: Fix wait after reset sequence in S4 + +From: Lijo Lazar + +commit daf470b8882b6f7f53cbfe9ec2b93a1b21528cdc upstream. + +For a mode-1 reset done at the end of S4 on PSPv11 dGPUs, only check if +TOS is unloaded. + +Fixes: 32f73741d6ee ("drm/amdgpu: Wait for bootloader after PSPv11 reset") +Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/4853 +Signed-off-by: Lijo Lazar +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 2fb4883b884a437d760bd7bdf7695a7e5a60bba3) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 8 ++++++-- + drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 3 ++- + 2 files changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2703,8 +2703,12 @@ static int amdgpu_pmops_freeze(struct de + if (r) + return r; + +- if (amdgpu_acpi_should_gpu_reset(adev)) +- return amdgpu_asic_reset(adev); ++ if (amdgpu_acpi_should_gpu_reset(adev)) { ++ amdgpu_device_lock_reset_domain(adev->reset_domain); ++ r = amdgpu_asic_reset(adev); ++ amdgpu_device_unlock_reset_domain(adev->reset_domain); ++ return r; ++ } + return 0; + } + +--- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +@@ -170,7 +170,8 @@ static int psp_v11_0_wait_for_bootloader + int retry_loop; + + /* For a reset done at the end of S3, only wait for TOS to be unloaded */ +- if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev)) ++ if ((adev->in_s4 || adev->in_s3) && !(adev->flags & AMD_IS_APU) && ++ amdgpu_in_reset(adev)) + return psp_v11_wait_for_tos_unload(psp); + + for (retry_loop = 0; retry_loop < 20; retry_loop++) { diff --git a/queue-6.19/drm-amdgpu-pm-drop-smu-driver-if-version-not-matched-messages.patch b/queue-6.19/drm-amdgpu-pm-drop-smu-driver-if-version-not-matched-messages.patch new file mode 100644 index 0000000000..cdb43007f4 --- /dev/null +++ b/queue-6.19/drm-amdgpu-pm-drop-smu-driver-if-version-not-matched-messages.patch @@ -0,0 +1,55 @@ +From a3ffaa5b397f4df9d6ac16b10583e9df8e6fa471 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 17 Mar 2026 16:34:41 -0400 +Subject: drm/amdgpu/pm: drop SMU driver if version not matched messages + +From: Alex Deucher + +commit a3ffaa5b397f4df9d6ac16b10583e9df8e6fa471 upstream. + +It just leads to user confusion. + +Cc: Yang Wang +Cc: Lijo Lazar +Reviewed-by: Yang Wang +Reviewed-by: Lijo Lazar +Signed-off-by: Alex Deucher +(cherry picked from commit e471627d56272a791972f25e467348b611c31713) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 1 - + drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 1 - + drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c | 1 - + 3 files changed, 3 deletions(-) + +--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +@@ -262,7 +262,6 @@ int smu_v11_0_check_fw_version(struct sm + "smu fw program = %d, version = 0x%08x (%d.%d.%d)\n", + smu->smc_driver_if_version, if_version, + smu_program, smu_version, smu_major, smu_minor, smu_debug); +- dev_info(smu->adev->dev, "SMU driver if version not matched\n"); + } + + return ret; +--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c +@@ -101,7 +101,6 @@ int smu_v12_0_check_fw_version(struct sm + "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", + smu->smc_driver_if_version, if_version, + smu_program, smu_version, smu_major, smu_minor, smu_debug); +- dev_info(smu->adev->dev, "SMU driver if version not matched\n"); + } + + return ret; +--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c +@@ -284,7 +284,6 @@ int smu_v14_0_check_fw_version(struct sm + "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", + smu->smc_driver_if_version, if_version, + smu_program, smu_version, smu_major, smu_minor, smu_debug); +- dev_info(adev->dev, "SMU driver if version not matched\n"); + } + + return ret; diff --git a/queue-6.19/drm-amdgpu-validate-doorbell_offset-in-user-queue-creation.patch b/queue-6.19/drm-amdgpu-validate-doorbell_offset-in-user-queue-creation.patch new file mode 100644 index 0000000000..95aa8bc6d1 --- /dev/null +++ b/queue-6.19/drm-amdgpu-validate-doorbell_offset-in-user-queue-creation.patch @@ -0,0 +1,45 @@ +From a018d1819f158991b7308e4f74609c6c029b670c Mon Sep 17 00:00:00 2001 +From: Junrui Luo +Date: Tue, 24 Mar 2026 17:39:02 +0800 +Subject: drm/amdgpu: validate doorbell_offset in user queue creation + +From: Junrui Luo + +commit a018d1819f158991b7308e4f74609c6c029b670c upstream. + +amdgpu_userq_get_doorbell_index() passes the user-provided +doorbell_offset to amdgpu_doorbell_index_on_bar() without bounds +checking. An arbitrarily large doorbell_offset can cause the +calculated doorbell index to fall outside the allocated doorbell BO, +potentially corrupting kernel doorbell space. + +Validate that doorbell_offset falls within the doorbell BO before +computing the BAR index, using u64 arithmetic to prevent overflow. + +Fixes: f09c1e6077ab ("drm/amdgpu: generate doorbell index for userqueue") +Reported-by: Yuhao Jiang +Signed-off-by: Junrui Luo +Signed-off-by: Alex Deucher +(cherry picked from commit de1ef4ffd70e1d15f0bf584fd22b1f28cbd5e2ec) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +@@ -550,6 +550,13 @@ amdgpu_userq_get_doorbell_index(struct a + goto unpin_bo; + } + ++ /* Validate doorbell_offset is within the doorbell BO */ ++ if ((u64)db_info->doorbell_offset * db_size + db_size > ++ amdgpu_bo_size(db_obj->obj)) { ++ r = -EINVAL; ++ goto unpin_bo; ++ } ++ + index = amdgpu_doorbell_index_on_bar(uq_mgr->adev, db_obj->obj, + db_info->doorbell_offset, db_size); + drm_dbg_driver(adev_to_drm(uq_mgr->adev), diff --git a/queue-6.19/drm-ast-dp501-fix-initialization-of-scu2c.patch b/queue-6.19/drm-ast-dp501-fix-initialization-of-scu2c.patch new file mode 100644 index 0000000000..66a7923d07 --- /dev/null +++ b/queue-6.19/drm-ast-dp501-fix-initialization-of-scu2c.patch @@ -0,0 +1,41 @@ +From 2f42c1a6161646cbd29b443459fd635d29eda634 Mon Sep 17 00:00:00 2001 +From: Thomas Zimmermann +Date: Fri, 27 Mar 2026 14:32:53 +0100 +Subject: drm/ast: dp501: Fix initialization of SCU2C + +From: Thomas Zimmermann + +commit 2f42c1a6161646cbd29b443459fd635d29eda634 upstream. + +Ast's DP501 initialization reads the register SCU2C at offset 0x1202c +and tries to set it to source data from VGA. But writes the update to +offset 0x0, with unknown results. Write the result to SCU instead. + +The bug only happens in ast_init_analog(). There's similar code in +ast_init_dvo(), which works correctly. + +Signed-off-by: Thomas Zimmermann +Fixes: 83c6620bae3f ("drm/ast: initial DP501 support (v0.2)") +Reviewed-by: Jocelyn Falempe +Cc: Dave Airlie +Cc: Thomas Zimmermann +Cc: Jocelyn Falempe +Cc: dri-devel@lists.freedesktop.org +Cc: # v3.16+ +Link: https://patch.msgid.link/20260327133532.79696-2-tzimmermann@suse.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/ast/ast_dp501.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/ast/ast_dp501.c ++++ b/drivers/gpu/drm/ast/ast_dp501.c +@@ -436,7 +436,7 @@ static void ast_init_analog(struct ast_d + /* Finally, clear bits [17:16] of SCU2c */ + data = ast_read32(ast, 0x1202c); + data &= 0xfffcffff; +- ast_write32(ast, 0, data); ++ ast_write32(ast, 0x1202c, data); + + /* Disable DVO */ + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); diff --git a/queue-6.19/drm-i915-cdclk-do-the-full-cdclk-dance-for-min_voltage_level-changes.patch b/queue-6.19/drm-i915-cdclk-do-the-full-cdclk-dance-for-min_voltage_level-changes.patch new file mode 100644 index 0000000000..5f8b825ff0 --- /dev/null +++ b/queue-6.19/drm-i915-cdclk-do-the-full-cdclk-dance-for-min_voltage_level-changes.patch @@ -0,0 +1,116 @@ +From e08e0754e690e4909cab83ac43fd2c93c6200514 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 25 Mar 2026 15:58:44 +0200 +Subject: drm/i915/cdclk: Do the full CDCLK dance for min_voltage_level changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit e08e0754e690e4909cab83ac43fd2c93c6200514 upstream. + +Apparently I forgot about the pipe min_voltage_level when I +decoupled the CDCLK calculations from modesets. Even if the +CDCLK frequency doesn't need changing we may still need to +bump the voltage level to accommodate an increase in the +port clock frequency. + +Currently, even if there is a full modeset, we won't notice the +need to go through the full CDCLK calculations/programming, +unless the set of enabled/active pipes changes, or the +pipe/dbuf min CDCLK changes. + +Duplicate the same logic we use the pipe's min CDCLK frequency +to also deal with its min voltage level. + +Note that the 'allow_voltage_level_decrease' stuff isn't +really useful here since the min voltage level can only +change during a full modeset. But I think sticking to the +same approach in the three similar parts (pipe min cdclk, +pipe min voltage level, dbuf min cdclk) is a good idea. + +Cc: stable@vger.kernel.org +Tested-by: Mikhail Rudenko +Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15826 +Fixes: ba91b9eecb47 ("drm/i915/cdclk: Decouple cdclk from state->modeset") +Signed-off-by: Ville Syrjälä +Link: https://patch.msgid.link/20260325135849.12603-2-ville.syrjala@linux.intel.com +Reviewed-by: Michał Grzelak +(cherry picked from commit 0f21a14987ebae3c05ad1184ea872e7b7a7b8695) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + +--- a/drivers/gpu/drm/i915/display/intel_cdclk.c ++++ b/drivers/gpu/drm/i915/display/intel_cdclk.c +@@ -2930,6 +2930,53 @@ static int intel_cdclk_update_crtc_min_c + return 0; + } + ++static int intel_cdclk_update_crtc_min_voltage_level(struct intel_atomic_state *state, ++ struct intel_crtc *crtc, ++ u8 old_min_voltage_level, ++ u8 new_min_voltage_level, ++ bool *need_cdclk_calc) ++{ ++ struct intel_display *display = to_intel_display(state); ++ struct intel_cdclk_state *cdclk_state; ++ bool allow_voltage_level_decrease = intel_any_crtc_needs_modeset(state); ++ int ret; ++ ++ if (new_min_voltage_level == old_min_voltage_level) ++ return 0; ++ ++ if (!allow_voltage_level_decrease && ++ new_min_voltage_level < old_min_voltage_level) ++ return 0; ++ ++ cdclk_state = intel_atomic_get_cdclk_state(state); ++ if (IS_ERR(cdclk_state)) ++ return PTR_ERR(cdclk_state); ++ ++ old_min_voltage_level = cdclk_state->min_voltage_level[crtc->pipe]; ++ ++ if (new_min_voltage_level == old_min_voltage_level) ++ return 0; ++ ++ if (!allow_voltage_level_decrease && ++ new_min_voltage_level < old_min_voltage_level) ++ return 0; ++ ++ cdclk_state->min_voltage_level[crtc->pipe] = new_min_voltage_level; ++ ++ ret = intel_atomic_lock_global_state(&cdclk_state->base); ++ if (ret) ++ return ret; ++ ++ *need_cdclk_calc = true; ++ ++ drm_dbg_kms(display->drm, ++ "[CRTC:%d:%s] min voltage level: %d -> %d\n", ++ crtc->base.base.id, crtc->base.name, ++ old_min_voltage_level, new_min_voltage_level); ++ ++ return 0; ++} ++ + int intel_cdclk_update_dbuf_bw_min_cdclk(struct intel_atomic_state *state, + int old_min_cdclk, int new_min_cdclk, + bool *need_cdclk_calc) +@@ -3345,6 +3392,13 @@ static int intel_crtcs_calc_min_cdclk(st + need_cdclk_calc); + if (ret) + return ret; ++ ++ ret = intel_cdclk_update_crtc_min_voltage_level(state, crtc, ++ old_crtc_state->min_voltage_level, ++ new_crtc_state->min_voltage_level, ++ need_cdclk_calc); ++ if (ret) ++ return ret; + } + + return 0; diff --git a/queue-6.19/drm-i915-dp-use-crtc_state-enhanced_framing-properly-on-ivb-hsw-cpu-edp.patch b/queue-6.19/drm-i915-dp-use-crtc_state-enhanced_framing-properly-on-ivb-hsw-cpu-edp.patch new file mode 100644 index 0000000000..93c622bee7 --- /dev/null +++ b/queue-6.19/drm-i915-dp-use-crtc_state-enhanced_framing-properly-on-ivb-hsw-cpu-edp.patch @@ -0,0 +1,40 @@ +From 9c9a57e4e337f94e23ddf69263fd0685c91155fb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Wed, 25 Mar 2026 15:58:45 +0200 +Subject: drm/i915/dp: Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 9c9a57e4e337f94e23ddf69263fd0685c91155fb upstream. + +Looks like I missed the drm_dp_enhanced_frame_cap() in the ivb/hsw CPU +eDP code when I introduced crtc_state->enhanced_framing. Fix it up so +that the state we program to the hardware is guaranteed to match what +we computed earlier. + +Cc: stable@vger.kernel.org +Fixes: 3072a24c778a ("drm/i915: Introduce crtc_state->enhanced_framing") +Signed-off-by: Ville Syrjälä +Link: https://patch.msgid.link/20260325135849.12603-3-ville.syrjala@linux.intel.com +Reviewed-by: Michał Grzelak +(cherry picked from commit 799fe8dc2af52f35c78c4ac97f8e34994dfd8760) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/i915/display/g4x_dp.c ++++ b/drivers/gpu/drm/i915/display/g4x_dp.c +@@ -137,7 +137,7 @@ static void intel_dp_prepare(struct inte + intel_dp->DP |= DP_SYNC_VS_HIGH; + intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; + +- if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) ++ if (pipe_config->enhanced_framing) + intel_dp->DP |= DP_ENHANCED_FRAMING; + + intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe); diff --git a/queue-6.19/drm-i915-dsi-don-t-do-dsc-horizontal-timing-adjustments-in-command-mode.patch b/queue-6.19/drm-i915-dsi-don-t-do-dsc-horizontal-timing-adjustments-in-command-mode.patch new file mode 100644 index 0000000000..d81ee913c5 --- /dev/null +++ b/queue-6.19/drm-i915-dsi-don-t-do-dsc-horizontal-timing-adjustments-in-command-mode.patch @@ -0,0 +1,59 @@ +From 4dfce79e098915d8e5fc2b9e1d980bc3251dd32c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Thu, 26 Mar 2026 13:18:10 +0200 +Subject: drm/i915/dsi: Don't do DSC horizontal timing adjustments in command mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit 4dfce79e098915d8e5fc2b9e1d980bc3251dd32c upstream. + +Stop adjusting the horizontal timing values based on the +compression ratio in command mode. Bspec seems to be telling +us to do this only in video mode, and this is also how the +Windows driver does things. + +This should also fix a div-by-zero on some machines because +the adjusted htotal ends up being so small that we end up with +line_time_us==0 when trying to determine the vtotal value in +command mode. + +Note that this doesn't actually make the display on the +Huawei Matebook E work, but at least the kernel no longer +explodes when the driver loads. + +Cc: stable@vger.kernel.org +Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12045 +Signed-off-by: Ville Syrjälä +Link: https://patch.msgid.link/20260326111814.9800-2-ville.syrjala@linux.intel.com +Fixes: 53693f02d80e ("drm/i915/dsi: account for DSC in horizontal timings") +Reviewed-by: Jani Nikula +(cherry picked from commit 0b475e91ecc2313207196c6d7fd5c53e1a878525) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/display/icl_dsi.c ++++ b/drivers/gpu/drm/i915/display/icl_dsi.c +@@ -889,7 +889,7 @@ gen11_dsi_set_transcoder_timings(struct + * non-compressed link speeds, and simplifies down to the ratio between + * compressed and non-compressed bpp. + */ +- if (crtc_state->dsc.compression_enable) { ++ if (is_vid_mode(intel_dsi) && crtc_state->dsc.compression_enable) { + mul = fxp_q4_to_int(crtc_state->dsc.compressed_bpp_x16); + div = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + } +@@ -1503,7 +1503,7 @@ static void gen11_dsi_get_timings(struct + struct drm_display_mode *adjusted_mode = + &pipe_config->hw.adjusted_mode; + +- if (pipe_config->dsc.compressed_bpp_x16) { ++ if (is_vid_mode(intel_dsi) && pipe_config->dsc.compressed_bpp_x16) { + int div = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16); + int mul = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); + diff --git a/queue-6.19/gpib-fix-use-after-free-in-io-ioctl-handlers.patch b/queue-6.19/gpib-fix-use-after-free-in-io-ioctl-handlers.patch new file mode 100644 index 0000000000..94634024d5 --- /dev/null +++ b/queue-6.19/gpib-fix-use-after-free-in-io-ioctl-handlers.patch @@ -0,0 +1,272 @@ +From d1857f8296dceb75d00ab857fc3c61bc00c7f5c6 Mon Sep 17 00:00:00 2001 +From: Adam Crosser +Date: Tue, 17 Mar 2026 19:25:28 +0700 +Subject: gpib: fix use-after-free in IO ioctl handlers + +From: Adam Crosser + +commit d1857f8296dceb75d00ab857fc3c61bc00c7f5c6 upstream. + +The IBRD, IBWRT, IBCMD, and IBWAIT ioctl handlers use a gpib_descriptor +pointer after board->big_gpib_mutex has been released. A concurrent +IBCLOSEDEV ioctl can free the descriptor via close_dev_ioctl() during +this window, causing a use-after-free. + +The IO handlers (read_ioctl, write_ioctl, command_ioctl) explicitly +release big_gpib_mutex before calling their handler. wait_ioctl() is +called with big_gpib_mutex held, but ibwait() releases it internally +when wait_mask is non-zero. In all four cases, the descriptor pointer +obtained from handle_to_descriptor() becomes unprotected. + +Fix this by introducing a kernel-only descriptor_busy reference count +in struct gpib_descriptor. Each handler atomically increments +descriptor_busy under file_priv->descriptors_mutex before releasing the +lock, and decrements it when done. close_dev_ioctl() checks +descriptor_busy under the same lock and rejects the close with -EBUSY +if the count is non-zero. + +A reference count rather than a simple flag is necessary because +multiple handlers can operate on the same descriptor concurrently +(e.g. IBRD and IBWAIT on the same handle from different threads). + +A separate counter is needed because io_in_progress can be cleared from +unprivileged userspace via the IBWAIT ioctl (through general_ibstatus() +with set_mask containing CMPL), which would allow an attacker to bypass +a check based solely on io_in_progress. The new descriptor_busy +counter is only modified by the kernel IO paths. + +The lock ordering is consistent (big_gpib_mutex -> descriptors_mutex) +and the handlers only hold descriptors_mutex briefly during the lookup, +so there is no deadlock risk and no impact on IO throughput. + +Signed-off-by: Adam Crosser +Cc: stable +Reviewed-by: Dave Penkler +Tested-by: Dave Penkler +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpib/common/gpib_os.c | 96 ++++++++++++++++++++++++++++---------- + drivers/gpib/include/gpib_types.h | 8 +++ + 2 files changed, 81 insertions(+), 23 deletions(-) + +--- a/drivers/gpib/common/gpib_os.c ++++ b/drivers/gpib/common/gpib_os.c +@@ -888,10 +888,6 @@ static int read_ioctl(struct gpib_file_p + if (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count) + return -EINVAL; + +- desc = handle_to_descriptor(file_priv, read_cmd.handle); +- if (!desc) +- return -EINVAL; +- + if (WARN_ON_ONCE(sizeof(userbuf) > sizeof(read_cmd.buffer_ptr))) + return -EFAULT; + +@@ -904,6 +900,17 @@ static int read_ioctl(struct gpib_file_p + if (!access_ok(userbuf, remain)) + return -EFAULT; + ++ /* Lock descriptors to prevent concurrent close from freeing descriptor */ ++ if (mutex_lock_interruptible(&file_priv->descriptors_mutex)) ++ return -ERESTARTSYS; ++ desc = handle_to_descriptor(file_priv, read_cmd.handle); ++ if (!desc) { ++ mutex_unlock(&file_priv->descriptors_mutex); ++ return -EINVAL; ++ } ++ atomic_inc(&desc->descriptor_busy); ++ mutex_unlock(&file_priv->descriptors_mutex); ++ + atomic_set(&desc->io_in_progress, 1); + + /* Read buffer loads till we fill the user supplied buffer */ +@@ -937,6 +944,7 @@ static int read_ioctl(struct gpib_file_p + retval = copy_to_user((void __user *)arg, &read_cmd, sizeof(read_cmd)); + + atomic_set(&desc->io_in_progress, 0); ++ atomic_dec(&desc->descriptor_busy); + + wake_up_interruptible(&board->wait); + if (retval) +@@ -964,10 +972,6 @@ static int command_ioctl(struct gpib_fil + if (cmd.completed_transfer_count > cmd.requested_transfer_count) + return -EINVAL; + +- desc = handle_to_descriptor(file_priv, cmd.handle); +- if (!desc) +- return -EINVAL; +- + userbuf = (u8 __user *)(unsigned long)cmd.buffer_ptr; + userbuf += cmd.completed_transfer_count; + +@@ -980,6 +984,17 @@ static int command_ioctl(struct gpib_fil + if (!access_ok(userbuf, remain)) + return -EFAULT; + ++ /* Lock descriptors to prevent concurrent close from freeing descriptor */ ++ if (mutex_lock_interruptible(&file_priv->descriptors_mutex)) ++ return -ERESTARTSYS; ++ desc = handle_to_descriptor(file_priv, cmd.handle); ++ if (!desc) { ++ mutex_unlock(&file_priv->descriptors_mutex); ++ return -EINVAL; ++ } ++ atomic_inc(&desc->descriptor_busy); ++ mutex_unlock(&file_priv->descriptors_mutex); ++ + /* + * Write buffer loads till we empty the user supplied buffer. + * Call drivers at least once, even if remain is zero, in +@@ -1003,6 +1018,7 @@ static int command_ioctl(struct gpib_fil + userbuf += bytes_written; + if (retval < 0) { + atomic_set(&desc->io_in_progress, 0); ++ atomic_dec(&desc->descriptor_busy); + + wake_up_interruptible(&board->wait); + break; +@@ -1022,6 +1038,7 @@ static int command_ioctl(struct gpib_fil + */ + if (!no_clear_io_in_prog || fault) + atomic_set(&desc->io_in_progress, 0); ++ atomic_dec(&desc->descriptor_busy); + + wake_up_interruptible(&board->wait); + if (fault) +@@ -1047,10 +1064,6 @@ static int write_ioctl(struct gpib_file_ + if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count) + return -EINVAL; + +- desc = handle_to_descriptor(file_priv, write_cmd.handle); +- if (!desc) +- return -EINVAL; +- + userbuf = (u8 __user *)(unsigned long)write_cmd.buffer_ptr; + userbuf += write_cmd.completed_transfer_count; + +@@ -1060,6 +1073,17 @@ static int write_ioctl(struct gpib_file_ + if (!access_ok(userbuf, remain)) + return -EFAULT; + ++ /* Lock descriptors to prevent concurrent close from freeing descriptor */ ++ if (mutex_lock_interruptible(&file_priv->descriptors_mutex)) ++ return -ERESTARTSYS; ++ desc = handle_to_descriptor(file_priv, write_cmd.handle); ++ if (!desc) { ++ mutex_unlock(&file_priv->descriptors_mutex); ++ return -EINVAL; ++ } ++ atomic_inc(&desc->descriptor_busy); ++ mutex_unlock(&file_priv->descriptors_mutex); ++ + atomic_set(&desc->io_in_progress, 1); + + /* Write buffer loads till we empty the user supplied buffer */ +@@ -1094,6 +1118,7 @@ static int write_ioctl(struct gpib_file_ + fault = copy_to_user((void __user *)arg, &write_cmd, sizeof(write_cmd)); + + atomic_set(&desc->io_in_progress, 0); ++ atomic_dec(&desc->descriptor_busy); + + wake_up_interruptible(&board->wait); + if (fault) +@@ -1276,6 +1301,9 @@ static int close_dev_ioctl(struct file * + { + struct gpib_close_dev_ioctl cmd; + struct gpib_file_private *file_priv = filep->private_data; ++ struct gpib_descriptor *desc; ++ unsigned int pad; ++ int sad; + int retval; + + retval = copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)); +@@ -1284,19 +1312,27 @@ static int close_dev_ioctl(struct file * + + if (cmd.handle >= GPIB_MAX_NUM_DESCRIPTORS) + return -EINVAL; +- if (!file_priv->descriptors[cmd.handle]) +- return -EINVAL; +- +- retval = decrement_open_device_count(board, &board->device_list, +- file_priv->descriptors[cmd.handle]->pad, +- file_priv->descriptors[cmd.handle]->sad); +- if (retval < 0) +- return retval; + +- kfree(file_priv->descriptors[cmd.handle]); ++ mutex_lock(&file_priv->descriptors_mutex); ++ desc = file_priv->descriptors[cmd.handle]; ++ if (!desc) { ++ mutex_unlock(&file_priv->descriptors_mutex); ++ return -EINVAL; ++ } ++ if (atomic_read(&desc->descriptor_busy)) { ++ mutex_unlock(&file_priv->descriptors_mutex); ++ return -EBUSY; ++ } ++ /* Remove from table while holding lock to prevent new IO from starting */ + file_priv->descriptors[cmd.handle] = NULL; ++ pad = desc->pad; ++ sad = desc->sad; ++ mutex_unlock(&file_priv->descriptors_mutex); + +- return 0; ++ retval = decrement_open_device_count(board, &board->device_list, pad, sad); ++ ++ kfree(desc); ++ return retval; + } + + static int serial_poll_ioctl(struct gpib_board *board, unsigned long arg) +@@ -1331,12 +1367,25 @@ static int wait_ioctl(struct gpib_file_p + if (retval) + return -EFAULT; + ++ /* ++ * Lock descriptors to prevent concurrent close from freeing ++ * descriptor. ibwait() releases big_gpib_mutex when wait_mask ++ * is non-zero, so desc must be pinned with descriptor_busy. ++ */ ++ mutex_lock(&file_priv->descriptors_mutex); + desc = handle_to_descriptor(file_priv, wait_cmd.handle); +- if (!desc) ++ if (!desc) { ++ mutex_unlock(&file_priv->descriptors_mutex); + return -EINVAL; ++ } ++ atomic_inc(&desc->descriptor_busy); ++ mutex_unlock(&file_priv->descriptors_mutex); + + retval = ibwait(board, wait_cmd.wait_mask, wait_cmd.clear_mask, + wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc); ++ ++ atomic_dec(&desc->descriptor_busy); ++ + if (retval < 0) + return retval; + +@@ -2035,6 +2084,7 @@ void init_gpib_descriptor(struct gpib_de + desc->is_board = 0; + desc->autopoll_enabled = 0; + atomic_set(&desc->io_in_progress, 0); ++ atomic_set(&desc->descriptor_busy, 0); + } + + int gpib_register_driver(struct gpib_interface *interface, struct module *provider_module) +--- a/drivers/gpib/include/gpib_types.h ++++ b/drivers/gpib/include/gpib_types.h +@@ -364,6 +364,14 @@ struct gpib_descriptor { + unsigned int pad; /* primary gpib address */ + int sad; /* secondary gpib address (negative means disabled) */ + atomic_t io_in_progress; ++ /* ++ * Kernel-only reference count to prevent descriptor from being ++ * freed while IO handlers hold a pointer to it. Incremented ++ * before each IO operation, decremented when done. Unlike ++ * io_in_progress, this cannot be modified from userspace via ++ * general_ibstatus(). ++ */ ++ atomic_t descriptor_busy; + unsigned is_board : 1; + unsigned autopoll_enabled : 1; + }; diff --git a/queue-6.19/hwmon-occ-fix-division-by-zero-in-occ_show_power_1.patch b/queue-6.19/hwmon-occ-fix-division-by-zero-in-occ_show_power_1.patch new file mode 100644 index 0000000000..8d5b694695 --- /dev/null +++ b/queue-6.19/hwmon-occ-fix-division-by-zero-in-occ_show_power_1.patch @@ -0,0 +1,76 @@ +From 39e2a5bf970402a8530a319cf06122e216ba57b8 Mon Sep 17 00:00:00 2001 +From: Sanman Pradhan +Date: Thu, 26 Mar 2026 22:45:23 +0000 +Subject: hwmon: (occ) Fix division by zero in occ_show_power_1() + +From: Sanman Pradhan + +commit 39e2a5bf970402a8530a319cf06122e216ba57b8 upstream. + +In occ_show_power_1() case 1, the accumulator is divided by +update_tag without checking for zero. If no samples have been +collected yet (e.g. during early boot when the sensor block is +included but hasn't been updated), update_tag is zero, causing +a kernel divide-by-zero crash. + +The 2019 fix in commit 211186cae14d ("hwmon: (occ) Fix division by +zero issue") only addressed occ_get_powr_avg() used by +occ_show_power_2() and occ_show_power_a0(). This separate code +path in occ_show_power_1() was missed. + +Fix this by reusing the existing occ_get_powr_avg() helper, which +already handles the zero-sample case and uses mul_u64_u32_div() +to multiply before dividing for better precision. Move the helper +above occ_show_power_1() so it is visible at the call site. + +Fixes: c10e753d43eb ("hwmon (occ): Add sensor types and versions") +Cc: stable@vger.kernel.org +Signed-off-by: Sanman Pradhan +Link: https://lore.kernel.org/r/20260326224510.294619-2-sanman.pradhan@hpe.com +[groeck: Fix alignment problems reported by checkpatch] +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/occ/common.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +--- a/drivers/hwmon/occ/common.c ++++ b/drivers/hwmon/occ/common.c +@@ -420,6 +420,12 @@ static ssize_t occ_show_freq_2(struct de + return sysfs_emit(buf, "%u\n", val); + } + ++static u64 occ_get_powr_avg(u64 accum, u32 samples) ++{ ++ return (samples == 0) ? 0 : ++ mul_u64_u32_div(accum, 1000000UL, samples); ++} ++ + static ssize_t occ_show_power_1(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -441,9 +447,8 @@ static ssize_t occ_show_power_1(struct d + val = get_unaligned_be16(&power->sensor_id); + break; + case 1: +- val = get_unaligned_be32(&power->accumulator) / +- get_unaligned_be32(&power->update_tag); +- val *= 1000000ULL; ++ val = occ_get_powr_avg(get_unaligned_be32(&power->accumulator), ++ get_unaligned_be32(&power->update_tag)); + break; + case 2: + val = (u64)get_unaligned_be32(&power->update_tag) * +@@ -459,12 +464,6 @@ static ssize_t occ_show_power_1(struct d + return sysfs_emit(buf, "%llu\n", val); + } + +-static u64 occ_get_powr_avg(u64 accum, u32 samples) +-{ +- return (samples == 0) ? 0 : +- mul_u64_u32_div(accum, 1000000UL, samples); +-} +- + static ssize_t occ_show_power_2(struct device *dev, + struct device_attribute *attr, char *buf) + { diff --git a/queue-6.19/iio-adc-ti-adc161s626-fix-buffer-read-on-big-endian.patch b/queue-6.19/iio-adc-ti-adc161s626-fix-buffer-read-on-big-endian.patch new file mode 100644 index 0000000000..0d56835492 --- /dev/null +++ b/queue-6.19/iio-adc-ti-adc161s626-fix-buffer-read-on-big-endian.patch @@ -0,0 +1,72 @@ +From 24869650dff34a6fc8fd1cc91b2058a72f9abc95 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sat, 14 Mar 2026 18:13:31 -0500 +Subject: iio: adc: ti-adc161s626: fix buffer read on big-endian + +From: David Lechner + +commit 24869650dff34a6fc8fd1cc91b2058a72f9abc95 upstream. + +Rework ti_adc_trigger_handler() to properly handle data on big-endian +architectures. The scan data format is 16-bit CPU-endian, so we can't +cast it to a int * on big-endian and expect it to work. Instead, we +introduce a local int variable to read the data into, and then copy it +to the buffer. + +Since the buffer isn't passed to any SPI functions, we don't need it to +be DMA-safe. So we can drop it from the driver data struct and just +use stack memory for the scan data. + +Since there is only one data value (plus timestamp), we don't need an +array and can just declare a struct with the correct data type instead. + +Also fix alignment of iio_get_time_ns() to ( while we are touching this. + +Fixes: 4d671b71beef ("iio: adc: ti-adc161s626: add support for TI 1-channel differential ADCs") +Signed-off-by: David Lechner +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-adc161s626.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/iio/adc/ti-adc161s626.c ++++ b/drivers/iio/adc/ti-adc161s626.c +@@ -70,8 +70,6 @@ struct ti_adc_data { + + u8 read_size; + u8 shift; +- +- u8 buffer[16] __aligned(IIO_DMA_MINALIGN); + }; + + static int ti_adc_read_measurement(struct ti_adc_data *data, +@@ -114,15 +112,20 @@ static irqreturn_t ti_adc_trigger_handle + struct iio_poll_func *pf = private; + struct iio_dev *indio_dev = pf->indio_dev; + struct ti_adc_data *data = iio_priv(indio_dev); +- int ret; ++ struct { ++ s16 data; ++ aligned_s64 timestamp; ++ } scan = { }; ++ int ret, val; ++ ++ ret = ti_adc_read_measurement(data, &indio_dev->channels[0], &val); ++ if (ret) ++ goto exit_notify_done; + +- ret = ti_adc_read_measurement(data, &indio_dev->channels[0], +- (int *) &data->buffer); +- if (!ret) +- iio_push_to_buffers_with_timestamp(indio_dev, +- data->buffer, +- iio_get_time_ns(indio_dev)); ++ scan.data = val; ++ iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); + ++ exit_notify_done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; diff --git a/queue-6.19/iio-adc-ti-adc161s626-use-dma-safe-memory-for-spi_read.patch b/queue-6.19/iio-adc-ti-adc161s626-use-dma-safe-memory-for-spi_read.patch new file mode 100644 index 0000000000..474d40a7c9 --- /dev/null +++ b/queue-6.19/iio-adc-ti-adc161s626-use-dma-safe-memory-for-spi_read.patch @@ -0,0 +1,76 @@ +From 768461517a28d80fe81ea4d5d03a90cd184ea6ad Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sat, 14 Mar 2026 18:13:32 -0500 +Subject: iio: adc: ti-adc161s626: use DMA-safe memory for spi_read() + +From: David Lechner + +commit 768461517a28d80fe81ea4d5d03a90cd184ea6ad upstream. + +Add a DMA-safe buffer and use it for spi_read() instead of a stack +memory. All SPI buffers must be DMA-safe. + +Since we only need up to 3 bytes, we just use a u8[] instead of __be16 +and __be32 and change the conversion functions appropriately. + +Fixes: 4d671b71beef ("iio: adc: ti-adc161s626: add support for TI 1-channel differential ADCs") +Signed-off-by: David Lechner +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-adc161s626.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/drivers/iio/adc/ti-adc161s626.c ++++ b/drivers/iio/adc/ti-adc161s626.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -70,6 +71,7 @@ struct ti_adc_data { + + u8 read_size; + u8 shift; ++ u8 buf[3] __aligned(IIO_DMA_MINALIGN); + }; + + static int ti_adc_read_measurement(struct ti_adc_data *data, +@@ -78,26 +80,20 @@ static int ti_adc_read_measurement(struc + int ret; + + switch (data->read_size) { +- case 2: { +- __be16 buf; +- +- ret = spi_read(data->spi, (void *) &buf, 2); ++ case 2: ++ ret = spi_read(data->spi, data->buf, 2); + if (ret) + return ret; + +- *val = be16_to_cpu(buf); ++ *val = get_unaligned_be16(data->buf); + break; +- } +- case 3: { +- __be32 buf; +- +- ret = spi_read(data->spi, (void *) &buf, 3); ++ case 3: ++ ret = spi_read(data->spi, data->buf, 3); + if (ret) + return ret; + +- *val = be32_to_cpu(buf) >> 8; ++ *val = get_unaligned_be24(data->buf); + break; +- } + default: + return -EINVAL; + } diff --git a/queue-6.19/iio-adc-ti-ads1119-fix-unbalanced-pm-reference-count-in-ds1119_single_conversion.patch b/queue-6.19/iio-adc-ti-ads1119-fix-unbalanced-pm-reference-count-in-ds1119_single_conversion.patch new file mode 100644 index 0000000000..75e481c3bc --- /dev/null +++ b/queue-6.19/iio-adc-ti-ads1119-fix-unbalanced-pm-reference-count-in-ds1119_single_conversion.patch @@ -0,0 +1,41 @@ +From 48a5c36577ebe0144f8ede70e59b59ea18b75089 Mon Sep 17 00:00:00 2001 +From: Felix Gu +Date: Sat, 28 Feb 2026 01:48:19 +0800 +Subject: iio: adc: ti-ads1119: Fix unbalanced pm reference count in ds1119_single_conversion() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Gu + +commit 48a5c36577ebe0144f8ede70e59b59ea18b75089 upstream. + +In ads1119_single_conversion(), if pm_runtime_resume_and_get() fails, +the code jumps to the pdown label, which calls +pm_runtime_put_autosuspend(). + +Since pm_runtime_resume_and_get() automatically decrements the usage +counter on failure, the subsequent call to pm_runtime_put_autosuspend() +causes an unbalanced reference counter. + +Fixes: a9306887eba4 ("iio: adc: ti-ads1119: Add driver") +Signed-off-by: Felix Gu +Reviewed-by: João Paulo Gonçalves +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-ads1119.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/adc/ti-ads1119.c ++++ b/drivers/iio/adc/ti-ads1119.c +@@ -274,7 +274,7 @@ static int ads1119_single_conversion(str + + ret = pm_runtime_resume_and_get(dev); + if (ret) +- goto pdown; ++ return ret; + + ret = ads1119_configure_channel(st, mux, gain, datarate); + if (ret) diff --git a/queue-6.19/iio-adc-ti-ads1119-reinit-completion-before-wait_for_completion_timeout.patch b/queue-6.19/iio-adc-ti-ads1119-reinit-completion-before-wait_for_completion_timeout.patch new file mode 100644 index 0000000000..a33ee5fe9d --- /dev/null +++ b/queue-6.19/iio-adc-ti-ads1119-reinit-completion-before-wait_for_completion_timeout.patch @@ -0,0 +1,35 @@ +From 2f168094177f8553a36046afce139001801ca917 Mon Sep 17 00:00:00 2001 +From: Felix Gu +Date: Tue, 3 Mar 2026 21:47:33 +0800 +Subject: iio: adc: ti-ads1119: Reinit completion before wait_for_completion_timeout() + +From: Felix Gu + +commit 2f168094177f8553a36046afce139001801ca917 upstream. + +The completion is not reinit before wait_for_completion_timeout(), +so wait_for_completion_timeout() will return immediately after +the first successful completion. + +Fixes: a9306887eba4 ("iio: adc: ti-ads1119: Add driver") +Signed-off-by: Felix Gu +Reviewed-by: Francesco Dolcini +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-ads1119.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/iio/adc/ti-ads1119.c ++++ b/drivers/iio/adc/ti-ads1119.c +@@ -280,6 +280,9 @@ static int ads1119_single_conversion(str + if (ret) + goto pdown; + ++ if (st->client->irq) ++ reinit_completion(&st->completion); ++ + ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC); + if (ret) + goto pdown; diff --git a/queue-6.19/iio-adc-ti-ads1119-replace-irqf_oneshot-with-irqf_no_thread.patch b/queue-6.19/iio-adc-ti-ads1119-replace-irqf_oneshot-with-irqf_no_thread.patch new file mode 100644 index 0000000000..e0c93cc98d --- /dev/null +++ b/queue-6.19/iio-adc-ti-ads1119-replace-irqf_oneshot-with-irqf_no_thread.patch @@ -0,0 +1,43 @@ +From 36f6d4db3c5cb0f58fb02b1f54f9e86522d2f918 Mon Sep 17 00:00:00 2001 +From: Felix Gu +Date: Tue, 3 Mar 2026 00:00:04 +0800 +Subject: iio: adc: ti-ads1119: Replace IRQF_ONESHOT with IRQF_NO_THREAD + +From: Felix Gu + +commit 36f6d4db3c5cb0f58fb02b1f54f9e86522d2f918 upstream. + +As there is no threaded handler, replace devm_request_threaded_irq() +with devm_request_irq(), and as the handler calls iio_trigger_poll() +which may not be called from a threaded handler replace IRQF_ONESHOT +with IRQF_NO_THREAD. + +Since commit aef30c8d569c ("genirq: Warn about using IRQF_ONESHOT +without a threaded handler"), the IRQ core checks IRQF_ONESHOT flag +in IRQ request and gives a warning if there is no threaded handler. + +Fixes: a9306887eba4 ("iio: adc: ti-ads1119: Add driver") +Signed-off-by: Felix Gu +Reviewed-by: David Lechner +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ti-ads1119.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/iio/adc/ti-ads1119.c ++++ b/drivers/iio/adc/ti-ads1119.c +@@ -738,10 +738,8 @@ static int ads1119_probe(struct i2c_clie + return dev_err_probe(dev, ret, "Failed to setup IIO buffer\n"); + + if (client->irq > 0) { +- ret = devm_request_threaded_irq(dev, client->irq, +- ads1119_irq_handler, +- NULL, IRQF_ONESHOT, +- "ads1119", indio_dev); ++ ret = devm_request_irq(dev, client->irq, ads1119_irq_handler, ++ IRQF_NO_THREAD, "ads1119", indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "Failed to allocate irq\n"); diff --git a/queue-6.19/iio-add-iio_declare_quaternion-macro.patch b/queue-6.19/iio-add-iio_declare_quaternion-macro.patch new file mode 100644 index 0000000000..5de2031b87 --- /dev/null +++ b/queue-6.19/iio-add-iio_declare_quaternion-macro.patch @@ -0,0 +1,49 @@ +From 56bd57e7b161f75535df91b229b0b2c64c6e5581 Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sat, 28 Feb 2026 14:02:22 -0600 +Subject: iio: add IIO_DECLARE_QUATERNION() macro + +From: David Lechner + +commit 56bd57e7b161f75535df91b229b0b2c64c6e5581 upstream. + +Add a new IIO_DECLARE_QUATERNION() macro that is used to declare the +field in an IIO buffer struct that contains a quaternion vector. + +Quaternions are currently the only IIO data type that uses the .repeat +feature of struct iio_scan_type. This has an implicit rule that the +element in the buffer must be aligned to the entire size of the repeated +element. This macro will make that requirement explicit. Since this is +the only user, we just call the macro IIO_DECLARE_QUATERNION() instead +of something more generic. + +Signed-off-by: David Lechner +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/iio/iio.h | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/include/linux/iio/iio.h ++++ b/include/linux/iio/iio.h +@@ -816,6 +816,18 @@ static inline void *iio_device_get_drvda + #define IIO_DECLARE_DMA_BUFFER_WITH_TS(type, name, count) \ + __IIO_DECLARE_BUFFER_WITH_TS(type, name, count) __aligned(IIO_DMA_MINALIGN) + ++/** ++ * IIO_DECLARE_QUATERNION() - Declare a quaternion element ++ * @type: element type of the individual vectors ++ * @name: identifier name ++ * ++ * Quaternions are a vector composed of 4 elements (W, X, Y, Z). Use this macro ++ * to declare a quaternion element in a struct to ensure proper alignment in ++ * an IIO buffer. ++ */ ++#define IIO_DECLARE_QUATERNION(type, name) \ ++ type name[4] __aligned(sizeof(type) * 4) ++ + struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv); + + /* The information at the returned address is guaranteed to be cacheline aligned */ diff --git a/queue-6.19/iio-orientation-hid-sensor-rotation-add-timestamp-hack-to-not-break-userspace.patch b/queue-6.19/iio-orientation-hid-sensor-rotation-add-timestamp-hack-to-not-break-userspace.patch new file mode 100644 index 0000000000..906a4dc246 --- /dev/null +++ b/queue-6.19/iio-orientation-hid-sensor-rotation-add-timestamp-hack-to-not-break-userspace.patch @@ -0,0 +1,79 @@ +From 79a86a6cc3669416a21fef32d0767d39ba84b3aa Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sat, 7 Mar 2026 19:44:09 -0600 +Subject: iio: orientation: hid-sensor-rotation: add timestamp hack to not break userspace +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: David Lechner + +commit 79a86a6cc3669416a21fef32d0767d39ba84b3aa upstream. + +Add a hack to push two timestamps in the hid-sensor-rotation scan data +to avoid breaking userspace applications that depend on the timestamp +being at the incorrect location in the scan data due to unintentional +misalignment in older kernels. + +When this driver was written, the timestamp was in the correct location +because of the way iio_compute_scan_bytes() was implemented at the time. +(Samples were 24 bytes each.) Then commit 883f61653069 ("iio: buffer: +align the size of scan bytes to size of the largest element") changed +the computed scan_bytes to be a different size (32 bytes), which caused +iio_push_to_buffers_with_timestamp() to place the timestamp at an +incorrect offset. + +There have been long periods of time (6 years each) where the timestamp +was in either location, so to not break either case, we open-code the +timestamps to be pushed to both locations in the scan data. + +Reported-by: Jonathan Cameron +Closes: https://lore.kernel.org/linux-iio/20260215162351.79f40b32@jic23-huawei/ +Fixes: 883f61653069 ("iio: buffer: align the size of scan bytes to size of the largest element") +Signed-off-by: David Lechner +Reviewed-by: Nuno Sá +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/orientation/hid-sensor-rotation.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +--- a/drivers/iio/orientation/hid-sensor-rotation.c ++++ b/drivers/iio/orientation/hid-sensor-rotation.c +@@ -20,7 +20,12 @@ struct dev_rot_state { + struct hid_sensor_hub_attribute_info quaternion; + struct { + IIO_DECLARE_QUATERNION(s32, sampled_vals); +- aligned_s64 timestamp; ++ /* ++ * ABI regression avoidance: There are two copies of the same ++ * timestamp in case of userspace depending on broken alignment ++ * from older kernels. ++ */ ++ aligned_s64 timestamp[2]; + } scan; + int scale_pre_decml; + int scale_post_decml; +@@ -154,8 +159,19 @@ static int dev_rot_proc_event(struct hid + if (!rot_state->timestamp) + rot_state->timestamp = iio_get_time_ns(indio_dev); + +- iio_push_to_buffers_with_timestamp(indio_dev, &rot_state->scan, +- rot_state->timestamp); ++ /* ++ * ABI regression avoidance: IIO previously had an incorrect ++ * implementation of iio_push_to_buffers_with_timestamp() that ++ * put the timestamp in the last 8 bytes of the buffer, which ++ * was incorrect according to the IIO ABI. To avoid breaking ++ * userspace that may be depending on this broken behavior, we ++ * put the timestamp in both the correct place [0] and the old ++ * incorrect place [1]. ++ */ ++ rot_state->scan.timestamp[0] = rot_state->timestamp; ++ rot_state->scan.timestamp[1] = rot_state->timestamp; ++ ++ iio_push_to_buffers(indio_dev, &rot_state->scan); + + rot_state->timestamp = 0; + } diff --git a/queue-6.19/iio-orientation-hid-sensor-rotation-fix-quaternion-alignment.patch b/queue-6.19/iio-orientation-hid-sensor-rotation-fix-quaternion-alignment.patch new file mode 100644 index 0000000000..4cd27f7557 --- /dev/null +++ b/queue-6.19/iio-orientation-hid-sensor-rotation-fix-quaternion-alignment.patch @@ -0,0 +1,39 @@ +From 50d4cc74b8a720a9682a9c94f7e62a5de6b2ed3a Mon Sep 17 00:00:00 2001 +From: David Lechner +Date: Sat, 28 Feb 2026 14:02:23 -0600 +Subject: iio: orientation: hid-sensor-rotation: fix quaternion alignment + +From: David Lechner + +commit 50d4cc74b8a720a9682a9c94f7e62a5de6b2ed3a upstream. + +Restore the alignment of sampled_vals to 16 bytes by using +IIO_DECLARE_QUATERNION(). This field contains a quaternion value which +has scan_type.repeat = 4 and storagebits = 32. So the alignment must +be 16 bytes to match the assumptions of iio_storage_bytes_for_si() and +also to not break userspace. + +Reported-by: Lixu Zhang +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221077 +Fixes: b31a74075cb4 ("iio: orientation: hid-sensor-rotation: remove unnecessary alignment") +Tested-by: Lixu Zhang +Signed-off-by: David Lechner +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/orientation/hid-sensor-rotation.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/orientation/hid-sensor-rotation.c ++++ b/drivers/iio/orientation/hid-sensor-rotation.c +@@ -19,7 +19,7 @@ struct dev_rot_state { + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info quaternion; + struct { +- s32 sampled_vals[4]; ++ IIO_DECLARE_QUATERNION(s32, sampled_vals); + aligned_s64 timestamp; + } scan; + int scale_pre_decml; diff --git a/queue-6.19/io_uring-net-fix-slab-out-of-bounds-read-in-io_bundle_nbufs.patch b/queue-6.19/io_uring-net-fix-slab-out-of-bounds-read-in-io_bundle_nbufs.patch new file mode 100644 index 0000000000..9f96017be4 --- /dev/null +++ b/queue-6.19/io_uring-net-fix-slab-out-of-bounds-read-in-io_bundle_nbufs.patch @@ -0,0 +1,69 @@ +From b948f9d5d3057b01188e36664e7c7604d1c8ecb5 Mon Sep 17 00:00:00 2001 +From: Junxi Qian +Date: Sun, 29 Mar 2026 23:39:09 +0800 +Subject: io_uring/net: fix slab-out-of-bounds read in io_bundle_nbufs() + +From: Junxi Qian + +commit b948f9d5d3057b01188e36664e7c7604d1c8ecb5 upstream. + +sqe->len is __u32 but gets stored into sr->len which is int. When +userspace passes sqe->len values exceeding INT_MAX (e.g. 0xFFFFFFFF), +sr->len overflows to a negative value. This negative value propagates +through the bundle recv/send path: + + 1. io_recv(): sel.val = sr->len (ssize_t gets -1) + 2. io_recv_buf_select(): arg.max_len = sel->val (size_t gets + 0xFFFFFFFFFFFFFFFF) + 3. io_ring_buffers_peek(): buf->len is not clamped because max_len + is astronomically large + 4. iov[].iov_len = 0xFFFFFFFF flows into io_bundle_nbufs() + 5. io_bundle_nbufs(): min_t(int, 0xFFFFFFFF, ret) yields -1, + causing ret to increase instead of decrease, creating an + infinite loop that reads past the allocated iov[] array + +This results in a slab-out-of-bounds read in io_bundle_nbufs() from +the kmalloc-64 slab, as nbufs increments past the allocated iovec +entries. + + BUG: KASAN: slab-out-of-bounds in io_bundle_nbufs+0x128/0x160 + Read of size 8 at addr ffff888100ae05c8 by task exp/145 + Call Trace: + io_bundle_nbufs+0x128/0x160 + io_recv_finish+0x117/0xe20 + io_recv+0x2db/0x1160 + +Fix this by rejecting negative sr->len values early in both +io_sendmsg_prep() and io_recvmsg_prep(). Since sqe->len is __u32, +any value > INT_MAX indicates overflow and is not a valid length. + +Fixes: a05d1f625c7a ("io_uring/net: support bundles for send") +Cc: stable@vger.kernel.org +Signed-off-by: Junxi Qian +Link: https://patch.msgid.link/20260329153909.279046-1-qjx1298677004@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + io_uring/net.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/io_uring/net.c ++++ b/io_uring/net.c +@@ -421,6 +421,8 @@ int io_sendmsg_prep(struct io_kiocb *req + + sr->done_io = 0; + sr->len = READ_ONCE(sqe->len); ++ if (unlikely(sr->len < 0)) ++ return -EINVAL; + sr->flags = READ_ONCE(sqe->ioprio); + if (sr->flags & ~SENDMSG_FLAGS) + return -EINVAL; +@@ -791,6 +793,8 @@ int io_recvmsg_prep(struct io_kiocb *req + + sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); + sr->len = READ_ONCE(sqe->len); ++ if (unlikely(sr->len < 0)) ++ return -EINVAL; + sr->flags = READ_ONCE(sqe->ioprio); + if (sr->flags & ~RECVMSG_FLAGS) + return -EINVAL; diff --git a/queue-6.19/iommu-do-not-call-drivers-for-empty-gathers.patch b/queue-6.19/iommu-do-not-call-drivers-for-empty-gathers.patch new file mode 100644 index 0000000000..86ae89a940 --- /dev/null +++ b/queue-6.19/iommu-do-not-call-drivers-for-empty-gathers.patch @@ -0,0 +1,54 @@ +From 90c5def10bea574b101b7a520c015ca81742183f Mon Sep 17 00:00:00 2001 +From: Jason Gunthorpe +Date: Mon, 2 Mar 2026 18:22:52 -0400 +Subject: iommu: Do not call drivers for empty gathers + +From: Jason Gunthorpe + +commit 90c5def10bea574b101b7a520c015ca81742183f upstream. + +An empty gather is coded with start=U64_MAX, end=0 and several drivers go +on to convert that to a size with: + + end - start + 1 + +Which gives 2 for an empty gather. This then causes Weird Stuff to +happen (for example an UBSAN splat in VT-d) that is hopefully harmless, +but maybe not. + +Prevent drivers from being called right in iommu_iotlb_sync(). + +Auditing shows that AMD, Intel, Mediatek and RSIC-V drivers all do things +on these empty gathers. + +Further, there are several callers that can trigger empty gathers, +especially in unusual conditions. For example iommu_map_nosync() will call +a 0 size unmap on some error paths. Also in VFIO, iommupt and other +places. + +Cc: stable@vger.kernel.org +Reported-by: Janusz Krzysztofik +Closes: https://lore.kernel.org/r/11145826.aFP6jjVeTY@jkrzyszt-mobl2.ger.corp.intel.com +Signed-off-by: Jason Gunthorpe +Reviewed-by: Lu Baolu +Reviewed-by: Samiullah Khawaja +Reviewed-by: Robin Murphy +Reviewed-by: Vasant Hegde +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/iommu.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -979,7 +979,8 @@ static inline void iommu_flush_iotlb_all + static inline void iommu_iotlb_sync(struct iommu_domain *domain, + struct iommu_iotlb_gather *iotlb_gather) + { +- if (domain->ops->iotlb_sync) ++ if (domain->ops->iotlb_sync && ++ likely(iotlb_gather->start < iotlb_gather->end)) + domain->ops->iotlb_sync(domain, iotlb_gather); + + iommu_iotlb_gather_init(iotlb_gather); diff --git a/queue-6.19/ksmbd-fix-oob-write-in-query_info-for-compound-requests.patch b/queue-6.19/ksmbd-fix-oob-write-in-query_info-for-compound-requests.patch new file mode 100644 index 0000000000..4d2a5465e7 --- /dev/null +++ b/queue-6.19/ksmbd-fix-oob-write-in-query_info-for-compound-requests.patch @@ -0,0 +1,328 @@ +From fda9522ed6afaec45cabc198d8492270c394c7bc Mon Sep 17 00:00:00 2001 +From: Asim Viladi Oglu Manizada +Date: Wed, 25 Mar 2026 09:14:22 +0900 +Subject: ksmbd: fix OOB write in QUERY_INFO for compound requests + +From: Asim Viladi Oglu Manizada + +commit fda9522ed6afaec45cabc198d8492270c394c7bc upstream. + +When a compound request such as READ + QUERY_INFO(Security) is received, +and the first command (READ) consumes most of the response buffer, +ksmbd could write beyond the allocated buffer while building a security +descriptor. + +The root cause was that smb2_get_info_sec() checked buffer space using +ppntsd_size from xattr, while build_sec_desc() often synthesized a +significantly larger descriptor from POSIX ACLs. + +This patch introduces smb_acl_sec_desc_scratch_len() to accurately +compute the final descriptor size beforehand, performs proper buffer +checking with smb2_calc_max_out_buf_len(), and uses exact-sized +allocation + iov pinning. + +Cc: stable@vger.kernel.org +Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound") +Signed-off-by: Asim Viladi Oglu Manizada +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/smb2pdu.c | 121 +++++++++++++++++++++++++++++++++++------------- + fs/smb/server/smbacl.c | 43 +++++++++++++++++ + fs/smb/server/smbacl.h | 2 + 3 files changed, 134 insertions(+), 32 deletions(-) + +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -3401,20 +3401,24 @@ int smb2_open(struct ksmbd_work *work) + KSMBD_SHARE_FLAG_ACL_XATTR)) { + struct smb_fattr fattr; + struct smb_ntsd *pntsd; +- int pntsd_size, ace_num = 0; ++ int pntsd_size; ++ size_t scratch_len; + + ksmbd_acls_fattr(&fattr, idmap, inode); +- if (fattr.cf_acls) +- ace_num = fattr.cf_acls->a_count; +- if (fattr.cf_dacls) +- ace_num += fattr.cf_dacls->a_count; +- +- pntsd = kmalloc(sizeof(struct smb_ntsd) + +- sizeof(struct smb_sid) * 3 + +- sizeof(struct smb_acl) + +- sizeof(struct smb_ace) * ace_num * 2, +- KSMBD_DEFAULT_GFP); ++ scratch_len = smb_acl_sec_desc_scratch_len(&fattr, ++ NULL, 0, ++ OWNER_SECINFO | GROUP_SECINFO | ++ DACL_SECINFO); ++ if (!scratch_len || scratch_len == SIZE_MAX) { ++ rc = -EFBIG; ++ posix_acl_release(fattr.cf_acls); ++ posix_acl_release(fattr.cf_dacls); ++ goto err_out; ++ } ++ ++ pntsd = kvzalloc(scratch_len, KSMBD_DEFAULT_GFP); + if (!pntsd) { ++ rc = -ENOMEM; + posix_acl_release(fattr.cf_acls); + posix_acl_release(fattr.cf_dacls); + goto err_out; +@@ -3429,7 +3433,7 @@ int smb2_open(struct ksmbd_work *work) + posix_acl_release(fattr.cf_acls); + posix_acl_release(fattr.cf_dacls); + if (rc) { +- kfree(pntsd); ++ kvfree(pntsd); + goto err_out; + } + +@@ -3439,7 +3443,7 @@ int smb2_open(struct ksmbd_work *work) + pntsd, + pntsd_size, + false); +- kfree(pntsd); ++ kvfree(pntsd); + if (rc) + pr_err("failed to store ntacl in xattr : %d\n", + rc); +@@ -5371,8 +5375,9 @@ static int smb2_get_info_file(struct ksm + if (test_share_config_flag(work->tcon->share_conf, + KSMBD_SHARE_FLAG_PIPE)) { + /* smb2 info file called for pipe */ +- return smb2_get_info_file_pipe(work->sess, req, rsp, ++ rc = smb2_get_info_file_pipe(work->sess, req, rsp, + work->response_buf); ++ goto iov_pin_out; + } + + if (work->next_smb2_rcv_hdr_off) { +@@ -5472,6 +5477,12 @@ static int smb2_get_info_file(struct ksm + rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + rsp, work->response_buf); + ksmbd_fd_put(work, fp); ++ ++iov_pin_out: ++ if (!rc) ++ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, ++ offsetof(struct smb2_query_info_rsp, Buffer) + ++ le32_to_cpu(rsp->OutputBufferLength)); + return rc; + } + +@@ -5698,6 +5709,11 @@ static int smb2_get_info_filesystem(stru + rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), + rsp, work->response_buf); + path_put(&path); ++ ++ if (!rc) ++ rc = ksmbd_iov_pin_rsp(work, (void *)rsp, ++ offsetof(struct smb2_query_info_rsp, Buffer) + ++ le32_to_cpu(rsp->OutputBufferLength)); + return rc; + } + +@@ -5707,13 +5723,14 @@ static int smb2_get_info_sec(struct ksmb + { + struct ksmbd_file *fp; + struct mnt_idmap *idmap; +- struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd = NULL; ++ struct smb_ntsd *pntsd = NULL, *ppntsd = NULL; + struct smb_fattr fattr = {{0}}; + struct inode *inode; + __u32 secdesclen = 0; + unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID; + int addition_info = le32_to_cpu(req->AdditionalInformation); +- int rc = 0, ppntsd_size = 0; ++ int rc = 0, ppntsd_size = 0, max_len; ++ size_t scratch_len = 0; + + if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | + PROTECTED_DACL_SECINFO | +@@ -5721,6 +5738,11 @@ static int smb2_get_info_sec(struct ksmb + ksmbd_debug(SMB, "Unsupported addition info: 0x%x)\n", + addition_info); + ++ pntsd = kzalloc(ALIGN(sizeof(struct smb_ntsd), 8), ++ KSMBD_DEFAULT_GFP); ++ if (!pntsd) ++ return -ENOMEM; ++ + pntsd->revision = cpu_to_le16(1); + pntsd->type = cpu_to_le16(SELF_RELATIVE | DACL_PROTECTED); + pntsd->osidoffset = 0; +@@ -5729,9 +5751,7 @@ static int smb2_get_info_sec(struct ksmb + pntsd->dacloffset = 0; + + secdesclen = sizeof(struct smb_ntsd); +- rsp->OutputBufferLength = cpu_to_le32(secdesclen); +- +- return 0; ++ goto iov_pin; + } + + if (work->next_smb2_rcv_hdr_off) { +@@ -5763,18 +5783,58 @@ static int smb2_get_info_sec(struct ksmb + &ppntsd); + + /* Check if sd buffer size exceeds response buffer size */ +- if (smb2_resp_buf_len(work, 8) > ppntsd_size) +- rc = build_sec_desc(idmap, pntsd, ppntsd, ppntsd_size, +- addition_info, &secdesclen, &fattr); ++ max_len = smb2_calc_max_out_buf_len(work, ++ offsetof(struct smb2_query_info_rsp, Buffer), ++ le32_to_cpu(req->OutputBufferLength)); ++ if (max_len < 0) { ++ rc = -EINVAL; ++ goto release_acl; ++ } ++ ++ scratch_len = smb_acl_sec_desc_scratch_len(&fattr, ppntsd, ++ ppntsd_size, addition_info); ++ if (!scratch_len || scratch_len == SIZE_MAX) { ++ rc = -EFBIG; ++ goto release_acl; ++ } ++ ++ pntsd = kvzalloc(scratch_len, KSMBD_DEFAULT_GFP); ++ if (!pntsd) { ++ rc = -ENOMEM; ++ goto release_acl; ++ } ++ ++ rc = build_sec_desc(idmap, pntsd, ppntsd, ppntsd_size, ++ addition_info, &secdesclen, &fattr); ++ ++release_acl: + posix_acl_release(fattr.cf_acls); + posix_acl_release(fattr.cf_dacls); + kfree(ppntsd); + ksmbd_fd_put(work, fp); ++ ++ if (!rc && ALIGN(secdesclen, 8) > scratch_len) ++ rc = -EFBIG; + if (rc) +- return rc; ++ goto err_out; + ++iov_pin: + rsp->OutputBufferLength = cpu_to_le32(secdesclen); +- return 0; ++ rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength), ++ rsp, work->response_buf); ++ if (rc) ++ goto err_out; ++ ++ rc = ksmbd_iov_pin_rsp_read(work, (void *)rsp, ++ offsetof(struct smb2_query_info_rsp, Buffer), ++ pntsd, secdesclen); ++err_out: ++ if (rc) { ++ rsp->OutputBufferLength = 0; ++ kvfree(pntsd); ++ } ++ ++ return rc; + } + + /** +@@ -5798,6 +5858,9 @@ int smb2_query_info(struct ksmbd_work *w + goto err_out; + } + ++ rsp->StructureSize = cpu_to_le16(9); ++ rsp->OutputBufferOffset = cpu_to_le16(72); ++ + switch (req->InfoType) { + case SMB2_O_INFO_FILE: + ksmbd_debug(SMB, "GOT SMB2_O_INFO_FILE\n"); +@@ -5818,14 +5881,6 @@ int smb2_query_info(struct ksmbd_work *w + } + ksmbd_revert_fsids(work); + +- if (!rc) { +- rsp->StructureSize = cpu_to_le16(9); +- rsp->OutputBufferOffset = cpu_to_le16(72); +- rc = ksmbd_iov_pin_rsp(work, (void *)rsp, +- offsetof(struct smb2_query_info_rsp, Buffer) + +- le32_to_cpu(rsp->OutputBufferLength)); +- } +- + err_out: + if (rc < 0) { + if (rc == -EACCES) +@@ -5836,6 +5891,8 @@ err_out: + rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR; + else if (rc == -ENOMEM) + rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; ++ else if (rc == -EINVAL && rsp->hdr.Status == 0) ++ rsp->hdr.Status = STATUS_INVALID_PARAMETER; + else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0) + rsp->hdr.Status = STATUS_INVALID_INFO_CLASS; + smb2_set_err_rsp(work); +--- a/fs/smb/server/smbacl.c ++++ b/fs/smb/server/smbacl.c +@@ -915,6 +915,49 @@ int parse_sec_desc(struct mnt_idmap *idm + return 0; + } + ++size_t smb_acl_sec_desc_scratch_len(struct smb_fattr *fattr, ++ struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info) ++{ ++ size_t len = sizeof(struct smb_ntsd); ++ size_t tmp; ++ ++ if (addition_info & OWNER_SECINFO) ++ len += sizeof(struct smb_sid); ++ if (addition_info & GROUP_SECINFO) ++ len += sizeof(struct smb_sid); ++ if (!(addition_info & DACL_SECINFO)) ++ return len; ++ ++ len += sizeof(struct smb_acl); ++ if (ppntsd && ppntsd_size > 0) { ++ unsigned int dacl_offset = le32_to_cpu(ppntsd->dacloffset); ++ ++ if (dacl_offset < ppntsd_size && ++ check_add_overflow(len, ppntsd_size - dacl_offset, &len)) ++ return 0; ++ } ++ ++ if (fattr->cf_acls) { ++ if (check_mul_overflow((size_t)fattr->cf_acls->a_count, ++ 2 * sizeof(struct smb_ace), &tmp) || ++ check_add_overflow(len, tmp, &len)) ++ return 0; ++ } else { ++ /* default/minimum DACL */ ++ if (check_add_overflow(len, 5 * sizeof(struct smb_ace), &len)) ++ return 0; ++ } ++ ++ if (fattr->cf_dacls) { ++ if (check_mul_overflow((size_t)fattr->cf_dacls->a_count, ++ sizeof(struct smb_ace), &tmp) || ++ check_add_overflow(len, tmp, &len)) ++ return 0; ++ } ++ ++ return len; ++} ++ + /* Convert permission bits from mode to equivalent CIFS ACL */ + int build_sec_desc(struct mnt_idmap *idmap, + struct smb_ntsd *pntsd, struct smb_ntsd *ppntsd, +--- a/fs/smb/server/smbacl.h ++++ b/fs/smb/server/smbacl.h +@@ -101,6 +101,8 @@ int set_info_sec(struct ksmbd_conn *conn + bool type_check, bool get_write); + void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); + void ksmbd_init_domain(u32 *sub_auth); ++size_t smb_acl_sec_desc_scratch_len(struct smb_fattr *fattr, ++ struct smb_ntsd *ppntsd, int ppntsd_size, int addition_info); + + static inline uid_t posix_acl_uid_translate(struct mnt_idmap *idmap, + struct posix_acl_entry *pace) diff --git a/queue-6.19/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch b/queue-6.19/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch new file mode 100644 index 0000000000..f4743cc27a --- /dev/null +++ b/queue-6.19/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch @@ -0,0 +1,49 @@ +From e5046823f8fa3677341b541a25af2fcb99a5b1e0 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 25 Mar 2026 20:29:20 -0700 +Subject: lib/crypto: chacha: Zeroize permuted_state before it leaves scope + +From: Eric Biggers + +commit e5046823f8fa3677341b541a25af2fcb99a5b1e0 upstream. + +Since the ChaCha permutation is invertible, the local variable +'permuted_state' is sufficient to compute the original 'state', and thus +the key, even after the permutation has been done. + +While the kernel is quite inconsistent about zeroizing secrets on the +stack (and some prominent userspace crypto libraries don't bother at all +since it's not guaranteed to work anyway), the kernel does try to do it +as a best practice, especially in cases involving the RNG. + +Thus, explicitly zeroize 'permuted_state' before it goes out of scope. + +Fixes: c08d0e647305 ("crypto: chacha20 - Add a generic ChaCha20 stream cipher implementation") +Cc: stable@vger.kernel.org +Acked-by: Ard Biesheuvel +Link: https://lore.kernel.org/r/20260326032920.39408-1-ebiggers@kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + lib/crypto/chacha-block-generic.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/lib/crypto/chacha-block-generic.c ++++ b/lib/crypto/chacha-block-generic.c +@@ -87,6 +87,8 @@ void chacha_block_generic(struct chacha_ + &out[i * sizeof(u32)]); + + state->x[12]++; ++ ++ chacha_zeroize_state(&permuted_state); + } + EXPORT_SYMBOL(chacha_block_generic); + +@@ -110,5 +112,7 @@ void hchacha_block_generic(const struct + + memcpy(&out[0], &permuted_state.x[0], 16); + memcpy(&out[4], &permuted_state.x[12], 16); ++ ++ chacha_zeroize_state(&permuted_state); + } + EXPORT_SYMBOL(hchacha_block_generic); diff --git a/queue-6.19/mips-fix-the-gcc-version-check-for-__multi3-workaround.patch b/queue-6.19/mips-fix-the-gcc-version-check-for-__multi3-workaround.patch new file mode 100644 index 0000000000..79dca823dc --- /dev/null +++ b/queue-6.19/mips-fix-the-gcc-version-check-for-__multi3-workaround.patch @@ -0,0 +1,57 @@ +From ec8bf18814915460d9c617b556bf024efef26613 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Mon, 30 Mar 2026 02:54:09 +0100 +Subject: MIPS: Fix the GCC version check for `__multi3' workaround + +From: Maciej W. Rozycki + +commit ec8bf18814915460d9c617b556bf024efef26613 upstream. + +It was only GCC 10 that fixed a MIPS64r6 code generation issue with a +`__multi3' libcall inefficiently produced to perform 64-bit widening +multiplication while suitable machine instructions exist to do such a +calculation. The fix went in with GCC commit 48b2123f6336 ("re PR +target/82981 (unnecessary __multi3 call for mips64r6 linux kernel)"). + +Adjust our code accordingly, removing build failures such as: + +mips64-linux-ld: lib/math/div64.o: in function `mul_u64_add_u64_div_u64': +div64.c:(.text+0x84): undefined reference to `__multi3' + +with the GCC versions affected. + +Fixes: ebabcf17bcd7 ("MIPS: Implement __multi3 for GCC7 MIPS64r6 builds") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202601140146.hMLODc6v-lkp@intel.com/ +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v4.15+ +Reviewed-by: David Laight +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/lib/multi3.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/lib/multi3.c ++++ b/arch/mips/lib/multi3.c +@@ -4,12 +4,12 @@ + #include "libgcc.h" + + /* +- * GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for ++ * GCC 9 & older can suboptimally generate __multi3 calls for mips64r6, so for + * that specific case only we implement that intrinsic here. + * + * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981 + */ +-#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8) ++#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 10) + + /* multiply 64-bit values, low 64-bits returned */ + static inline long long notrace dmulu(long long a, long long b) +@@ -51,4 +51,4 @@ ti_type notrace __multi3(ti_type a, ti_t + } + EXPORT_SYMBOL(__multi3); + +-#endif /* 64BIT && CPU_MIPSR6 && GCC7 */ ++#endif /* 64BIT && CPU_MIPSR6 && GCC9 */ diff --git a/queue-6.19/mips-mm-allocate-tlb_vpn-array-atomically.patch b/queue-6.19/mips-mm-allocate-tlb_vpn-array-atomically.patch new file mode 100644 index 0000000000..675adb0181 --- /dev/null +++ b/queue-6.19/mips-mm-allocate-tlb_vpn-array-atomically.patch @@ -0,0 +1,64 @@ +From 01cc50ea5167bb14117257ec084637abe9e5f691 Mon Sep 17 00:00:00 2001 +From: Stefan Wiehler +Date: Tue, 10 Mar 2026 11:40:24 +0100 +Subject: mips: mm: Allocate tlb_vpn array atomically + +From: Stefan Wiehler + +commit 01cc50ea5167bb14117257ec084637abe9e5f691 upstream. + +Found by DEBUG_ATOMIC_SLEEP: + + BUG: sleeping function called from invalid context at /include/linux/sched/mm.h:306 + in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/1 + preempt_count: 1, expected: 0 + RCU nest depth: 0, expected: 0 + no locks held by swapper/1/0. + irq event stamp: 0 + hardirqs last enabled at (0): [<0000000000000000>] 0x0 + hardirqs last disabled at (0): [] copy_process+0x75c/0x1b68 + softirqs last enabled at (0): [] copy_process+0x75c/0x1b68 + softirqs last disabled at (0): [<0000000000000000>] 0x0 + CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.6.119-d79e757675ec-fct #1 + Stack : 800000000290bad8 0000000000000000 0000000000000008 800000000290bae8 + 800000000290bae8 800000000290bc78 0000000000000000 0000000000000000 + ffffffff80c80000 0000000000000001 ffffffff80d8dee8 ffffffff810d09c0 + 784bb2a7ec10647d 0000000000000010 ffffffff80a6fd60 8000000001d8a9c0 + 0000000000000000 0000000000000000 ffffffff80d90000 0000000000000000 + ffffffff80c9e0e8 0000000007ffffff 0000000000000cc0 0000000000000400 + ffffffffffffffff 0000000000000001 0000000000000002 ffffffffc0149ed8 + fffffffffffffffe 8000000002908000 800000000290bae0 ffffffff80a81b74 + ffffffff80129fb0 0000000000000000 0000000000000000 0000000000000000 + 0000000000000000 0000000000000000 ffffffff80129fd0 0000000000000000 + ... + Call Trace: + [] show_stack+0x60/0x158 + [] dump_stack_lvl+0x88/0xbc + [] __might_resched+0x268/0x288 + [] __kmem_cache_alloc_node+0x2e0/0x330 + [] __kmalloc+0x58/0xd0 + [] r4k_tlb_uniquify+0x7c/0x428 + [] tlb_init+0x7c/0x110 + [] per_cpu_trap_init+0x16c/0x1d0 + [] start_secondary+0x28/0x128 + +Fixes: 231ac951faba ("MIPS: mm: kmalloc tlb_vpn array to avoid stack overflow") +Signed-off-by: Stefan Wiehler +Cc: stable@vger.kernel.org +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/mm/tlb-r4k.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/mm/tlb-r4k.c ++++ b/arch/mips/mm/tlb-r4k.c +@@ -751,7 +751,7 @@ static void __ref r4k_tlb_uniquify(void) + + tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); + tlb_vpns = (use_slab ? +- kmalloc(tlb_vpn_size, GFP_KERNEL) : ++ kmalloc(tlb_vpn_size, GFP_ATOMIC) : + memblock_alloc_raw(tlb_vpn_size, sizeof(*tlb_vpns))); + if (WARN_ON(!tlb_vpns)) + return; /* Pray local_flush_tlb_all() is good enough. */ diff --git a/queue-6.19/mips-mm-rewrite-tlb-uniquification-for-the-hidden-bit-feature.patch b/queue-6.19/mips-mm-rewrite-tlb-uniquification-for-the-hidden-bit-feature.patch new file mode 100644 index 0000000000..561c9125c1 --- /dev/null +++ b/queue-6.19/mips-mm-rewrite-tlb-uniquification-for-the-hidden-bit-feature.patch @@ -0,0 +1,373 @@ +From 540760b77b8fc49d39d1b2b76196e5ec57711a32 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Fri, 27 Mar 2026 18:57:30 +0000 +Subject: MIPS: mm: Rewrite TLB uniquification for the hidden bit feature + +From: Maciej W. Rozycki + +commit 540760b77b8fc49d39d1b2b76196e5ec57711a32 upstream. + +Before the introduction of the EHINV feature, which lets software mark +TLB entries invalid, certain older implementations of the MIPS ISA were +equipped with an analogous bit, as a vendor extension, which however is +hidden from software and only ever set at reset, and then any software +write clears it, making the intended TLB entry valid. + +This feature makes it unsafe to read a TLB entry with TLBR, modify the +page mask, and write the entry back with TLBWI, because this operation +will implicitly clear the hidden bit and this may create a duplicate +entry, as with the presence of the hidden bit there is no guarantee all +the entries across the TLB are unique each. + +Usually the firmware has already uniquified TLB entries before handing +control over, in which case we only need to guarantee at bootstrap no +clash will happen with the VPN2 values chosen in local_flush_tlb_all(). + +However with systems such as Mikrotik RB532 we get handed the TLB as at +reset, with the hidden bit set across the entries and possibly duplicate +entries present. This then causes a machine check exception when page +sizes are reset in r4k_tlb_uniquify() and prevents the system from +booting. + +Rewrite the algorithm used in r4k_tlb_uniquify() then such as to avoid +the reuse of ASID/VPN values across the TLB. Get rid of global entries +first as they may be blocking the entire address space, e.g. 16 256MiB +pages will exhaust the whole address space of a 32-bit CPU and a single +big page can exhaust the 32-bit compatibility space on a 64-bit CPU. + +Details of the algorithm chosen are given across the code itself. + +Fixes: 9f048fa48740 ("MIPS: mm: Prevent a TLB shutdown on initial uniquification") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v6.18+ +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/mm/tlb-r4k.c | 282 +++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 228 insertions(+), 54 deletions(-) + +--- a/arch/mips/mm/tlb-r4k.c ++++ b/arch/mips/mm/tlb-r4k.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -24,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -511,12 +513,229 @@ static int __init set_ntlb(char *str) + __setup("ntlb=", set_ntlb); + + +-/* Comparison function for EntryHi VPN fields. */ +-static int r4k_vpn_cmp(const void *a, const void *b) ++/* The start bit position of VPN2 and Mask in EntryHi/PageMask registers. */ ++#define VPN2_SHIFT 13 ++ ++/* Read full EntryHi even with CONFIG_32BIT. */ ++static inline unsigned long long read_c0_entryhi_native(void) ++{ ++ return cpu_has_64bits ? read_c0_entryhi_64() : read_c0_entryhi(); ++} ++ ++/* Write full EntryHi even with CONFIG_32BIT. */ ++static inline void write_c0_entryhi_native(unsigned long long v) ++{ ++ if (cpu_has_64bits) ++ write_c0_entryhi_64(v); ++ else ++ write_c0_entryhi(v); ++} ++ ++/* TLB entry state for uniquification. */ ++struct tlbent { ++ unsigned long long wired:1; ++ unsigned long long global:1; ++ unsigned long long asid:10; ++ unsigned long long vpn:51; ++ unsigned long long pagesz:5; ++ unsigned long long index:14; ++}; ++ ++/* ++ * Comparison function for TLB entry sorting. Place wired entries first, ++ * then global entries, then order by the increasing VPN/ASID and the ++ * decreasing page size. This lets us avoid clashes with wired entries ++ * easily and get entries for larger pages out of the way first. ++ * ++ * We could group bits so as to reduce the number of comparisons, but this ++ * is seldom executed and not performance-critical, so prefer legibility. ++ */ ++static int r4k_entry_cmp(const void *a, const void *b) + { +- long v = *(unsigned long *)a - *(unsigned long *)b; +- int s = sizeof(long) > sizeof(int) ? sizeof(long) * 8 - 1: 0; +- return s ? (v != 0) | v >> s : v; ++ struct tlbent ea = *(struct tlbent *)a, eb = *(struct tlbent *)b; ++ ++ if (ea.wired > eb.wired) ++ return -1; ++ else if (ea.wired < eb.wired) ++ return 1; ++ else if (ea.global > eb.global) ++ return -1; ++ else if (ea.global < eb.global) ++ return 1; ++ else if (ea.vpn < eb.vpn) ++ return -1; ++ else if (ea.vpn > eb.vpn) ++ return 1; ++ else if (ea.asid < eb.asid) ++ return -1; ++ else if (ea.asid > eb.asid) ++ return 1; ++ else if (ea.pagesz > eb.pagesz) ++ return -1; ++ else if (ea.pagesz < eb.pagesz) ++ return 1; ++ else ++ return 0; ++} ++ ++/* ++ * Fetch all the TLB entries. Mask individual VPN values retrieved with ++ * the corresponding page mask and ignoring any 1KiB extension as we'll ++ * be using 4KiB pages for uniquification. ++ */ ++static void __ref r4k_tlb_uniquify_read(struct tlbent *tlb_vpns, int tlbsize) ++{ ++ int start = num_wired_entries(); ++ unsigned long long vpn_mask; ++ bool global; ++ int i; ++ ++ vpn_mask = GENMASK(current_cpu_data.vmbits - 1, VPN2_SHIFT); ++ vpn_mask |= cpu_has_64bits ? 3ULL << 62 : 1 << 31; ++ ++ for (i = 0; i < tlbsize; i++) { ++ unsigned long long entryhi, vpn, mask, asid; ++ unsigned int pagesz; ++ ++ write_c0_index(i); ++ mtc0_tlbr_hazard(); ++ tlb_read(); ++ tlb_read_hazard(); ++ ++ global = !!(read_c0_entrylo0() & ENTRYLO_G); ++ entryhi = read_c0_entryhi_native(); ++ mask = read_c0_pagemask(); ++ ++ asid = entryhi & cpu_asid_mask(¤t_cpu_data); ++ vpn = (entryhi & vpn_mask & ~mask) >> VPN2_SHIFT; ++ pagesz = ilog2((mask >> VPN2_SHIFT) + 1); ++ ++ tlb_vpns[i].global = global; ++ tlb_vpns[i].asid = global ? 0 : asid; ++ tlb_vpns[i].vpn = vpn; ++ tlb_vpns[i].pagesz = pagesz; ++ tlb_vpns[i].wired = i < start; ++ tlb_vpns[i].index = i; ++ } ++} ++ ++/* ++ * Write unique values to all but the wired TLB entries each, using ++ * the 4KiB page size. This size might not be supported with R6, but ++ * EHINV is mandatory for R6, so we won't ever be called in that case. ++ * ++ * A sorted table is supplied with any wired entries at the beginning, ++ * followed by any global entries, and then finally regular entries. ++ * We start at the VPN and ASID values of zero and only assign user ++ * addresses, therefore guaranteeing no clash with addresses produced ++ * by UNIQUE_ENTRYHI. We avoid any VPN values used by wired or global ++ * entries, by increasing the VPN value beyond the span of such entry. ++ * ++ * When a VPN/ASID clash is found with a regular entry we increment the ++ * ASID instead until no VPN/ASID clash has been found or the ASID space ++ * has been exhausted, in which case we increase the VPN value beyond ++ * the span of the largest clashing entry. ++ * ++ * We do not need to be concerned about FTLB or MMID configurations as ++ * those are required to implement the EHINV feature. ++ */ ++static void __ref r4k_tlb_uniquify_write(struct tlbent *tlb_vpns, int tlbsize) ++{ ++ unsigned long long asid, vpn, vpn_size, pagesz; ++ int widx, gidx, idx, sidx, lidx, i; ++ ++ vpn_size = 1ULL << (current_cpu_data.vmbits - VPN2_SHIFT); ++ pagesz = ilog2((PM_4K >> VPN2_SHIFT) + 1); ++ ++ write_c0_pagemask(PM_4K); ++ write_c0_entrylo0(0); ++ write_c0_entrylo1(0); ++ ++ asid = 0; ++ vpn = 0; ++ widx = 0; ++ gidx = 0; ++ for (sidx = 0; sidx < tlbsize && tlb_vpns[sidx].wired; sidx++) ++ ; ++ for (lidx = sidx; lidx < tlbsize && tlb_vpns[lidx].global; lidx++) ++ ; ++ idx = gidx = sidx + 1; ++ for (i = sidx; i < tlbsize; i++) { ++ unsigned long long entryhi, vpn_pagesz = 0; ++ ++ while (1) { ++ if (WARN_ON(vpn >= vpn_size)) { ++ dump_tlb_all(); ++ /* Pray local_flush_tlb_all() will cope. */ ++ return; ++ } ++ ++ /* VPN must be below the next wired entry. */ ++ if (widx < sidx && vpn >= tlb_vpns[widx].vpn) { ++ vpn = max(vpn, ++ (tlb_vpns[widx].vpn + ++ (1ULL << tlb_vpns[widx].pagesz))); ++ asid = 0; ++ widx++; ++ continue; ++ } ++ /* VPN must be below the next global entry. */ ++ if (gidx < lidx && vpn >= tlb_vpns[gidx].vpn) { ++ vpn = max(vpn, ++ (tlb_vpns[gidx].vpn + ++ (1ULL << tlb_vpns[gidx].pagesz))); ++ asid = 0; ++ gidx++; ++ continue; ++ } ++ /* Try to find a free ASID so as to conserve VPNs. */ ++ if (idx < tlbsize && vpn == tlb_vpns[idx].vpn && ++ asid == tlb_vpns[idx].asid) { ++ unsigned long long idx_pagesz; ++ ++ idx_pagesz = tlb_vpns[idx].pagesz; ++ vpn_pagesz = max(vpn_pagesz, idx_pagesz); ++ do ++ idx++; ++ while (idx < tlbsize && ++ vpn == tlb_vpns[idx].vpn && ++ asid == tlb_vpns[idx].asid); ++ asid++; ++ if (asid > cpu_asid_mask(¤t_cpu_data)) { ++ vpn += vpn_pagesz; ++ asid = 0; ++ vpn_pagesz = 0; ++ } ++ continue; ++ } ++ /* VPN mustn't be above the next regular entry. */ ++ if (idx < tlbsize && vpn > tlb_vpns[idx].vpn) { ++ vpn = max(vpn, ++ (tlb_vpns[idx].vpn + ++ (1ULL << tlb_vpns[idx].pagesz))); ++ asid = 0; ++ idx++; ++ continue; ++ } ++ break; ++ } ++ ++ entryhi = (vpn << VPN2_SHIFT) | asid; ++ write_c0_entryhi_native(entryhi); ++ write_c0_index(tlb_vpns[i].index); ++ mtc0_tlbw_hazard(); ++ tlb_write_indexed(); ++ ++ tlb_vpns[i].asid = asid; ++ tlb_vpns[i].vpn = vpn; ++ tlb_vpns[i].pagesz = pagesz; ++ ++ asid++; ++ if (asid > cpu_asid_mask(¤t_cpu_data)) { ++ vpn += 1ULL << pagesz; ++ asid = 0; ++ } ++ } + } + + /* +@@ -527,14 +746,8 @@ static void __ref r4k_tlb_uniquify(void) + { + int tlbsize = current_cpu_data.tlbsize; + bool use_slab = slab_is_available(); +- int start = num_wired_entries(); + phys_addr_t tlb_vpn_size; +- unsigned long *tlb_vpns; +- unsigned long vpn_mask; +- int cnt, ent, idx, i; +- +- vpn_mask = GENMASK(cpu_vmbits - 1, 13); +- vpn_mask |= IS_ENABLED(CONFIG_64BIT) ? 3ULL << 62 : 1 << 31; ++ struct tlbent *tlb_vpns; + + tlb_vpn_size = tlbsize * sizeof(*tlb_vpns); + tlb_vpns = (use_slab ? +@@ -545,52 +758,13 @@ static void __ref r4k_tlb_uniquify(void) + + htw_stop(); + +- for (i = start, cnt = 0; i < tlbsize; i++, cnt++) { +- unsigned long vpn; ++ r4k_tlb_uniquify_read(tlb_vpns, tlbsize); + +- write_c0_index(i); +- mtc0_tlbr_hazard(); +- tlb_read(); +- tlb_read_hazard(); +- vpn = read_c0_entryhi(); +- vpn &= vpn_mask & PAGE_MASK; +- tlb_vpns[cnt] = vpn; +- +- /* Prevent any large pages from overlapping regular ones. */ +- write_c0_pagemask(read_c0_pagemask() & PM_DEFAULT_MASK); +- mtc0_tlbw_hazard(); +- tlb_write_indexed(); +- tlbw_use_hazard(); +- } ++ sort(tlb_vpns, tlbsize, sizeof(*tlb_vpns), r4k_entry_cmp, NULL); + +- sort(tlb_vpns, cnt, sizeof(tlb_vpns[0]), r4k_vpn_cmp, NULL); ++ r4k_tlb_uniquify_write(tlb_vpns, tlbsize); + + write_c0_pagemask(PM_DEFAULT_MASK); +- write_c0_entrylo0(0); +- write_c0_entrylo1(0); +- +- idx = 0; +- ent = tlbsize; +- for (i = start; i < tlbsize; i++) +- while (1) { +- unsigned long entryhi, vpn; +- +- entryhi = UNIQUE_ENTRYHI(ent); +- vpn = entryhi & vpn_mask & PAGE_MASK; +- +- if (idx >= cnt || vpn < tlb_vpns[idx]) { +- write_c0_entryhi(entryhi); +- write_c0_index(i); +- mtc0_tlbw_hazard(); +- tlb_write_indexed(); +- ent++; +- break; +- } else if (vpn == tlb_vpns[idx]) { +- ent++; +- } else { +- idx++; +- } +- } + + tlbw_use_hazard(); + htw_start(); diff --git a/queue-6.19/mips-sibyte-bring-back-cache-initialisation.patch b/queue-6.19/mips-sibyte-bring-back-cache-initialisation.patch new file mode 100644 index 0000000000..1a1049c1b9 --- /dev/null +++ b/queue-6.19/mips-sibyte-bring-back-cache-initialisation.patch @@ -0,0 +1,45 @@ +From d62cf1511743526f530a4c169424e50c757f5a5e Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Fri, 27 Mar 2026 11:38:06 +0000 +Subject: MIPS: SiByte: Bring back cache initialisation + +From: Maciej W. Rozycki + +commit d62cf1511743526f530a4c169424e50c757f5a5e upstream. + +Bring back cache initialisation for Broadcom SiByte SB1 cores, which has +been removed causing the kernel to hang at bootstrap right after: + +Dentry cache hash table entries: 524288 (order: 8, 4194304 bytes, linear) +Inode-cache hash table entries: 262144 (order: 7, 2097152 bytes, linear) + +The cause of the problem is R4k cache handlers are also used by Broadcom +SiByte SB1 cores, however with a different cache error exception handler +and therefore not using CPU_R4K_CACHE_TLB: + +obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o +obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o + +(from arch/mips/mm/Makefile). + +Fixes: bbe4f634f48c ("mips: fix r3k_cache_init build regression") +Signed-off-by: Maciej W. Rozycki +Cc: stable@vger.kernel.org # v6.8+ +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/mm/cache.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/mm/cache.c ++++ b/arch/mips/mm/cache.c +@@ -207,7 +207,8 @@ void cpu_cache_init(void) + { + if (IS_ENABLED(CONFIG_CPU_R3000) && cpu_has_3k_cache) + r3k_cache_init(); +- if (IS_ENABLED(CONFIG_CPU_R4K_CACHE_TLB) && cpu_has_4k_cache) ++ if ((IS_ENABLED(CONFIG_CPU_R4K_CACHE_TLB) || ++ IS_ENABLED(CONFIG_CPU_SB1)) && cpu_has_4k_cache) + r4k_cache_init(); + + if (IS_ENABLED(CONFIG_CPU_CAVIUM_OCTEON) && cpu_has_octeon_cache) diff --git a/queue-6.19/sched_ext-fix-inconsistent-numa-node-lookup-in-scx_select_cpu_dfl.patch b/queue-6.19/sched_ext-fix-inconsistent-numa-node-lookup-in-scx_select_cpu_dfl.patch new file mode 100644 index 0000000000..275d4fccc2 --- /dev/null +++ b/queue-6.19/sched_ext-fix-inconsistent-numa-node-lookup-in-scx_select_cpu_dfl.patch @@ -0,0 +1,39 @@ +From db08b1940f4beb25460b4a4e9da3446454f2e8fe Mon Sep 17 00:00:00 2001 +From: Cheng-Yang Chou +Date: Sat, 21 Mar 2026 18:54:58 +0800 +Subject: sched_ext: Fix inconsistent NUMA node lookup in scx_select_cpu_dfl() + +From: Cheng-Yang Chou + +commit db08b1940f4beb25460b4a4e9da3446454f2e8fe upstream. + +In the WAKE_SYNC path of scx_select_cpu_dfl(), waker_node was computed +with cpu_to_node(), while node (for prev_cpu) was computed with +scx_cpu_node_if_enabled(). When scx_builtin_idle_per_node is disabled, +idle_cpumask(waker_node) is called with a real node ID even though +per-node idle tracking is disabled, resulting in undefined behavior. + +Fix by using scx_cpu_node_if_enabled() for waker_node as well, ensuring +both variables are computed consistently. + +Fixes: 48849271e6611 ("sched_ext: idle: Per-node idle cpumasks") +Cc: stable@vger.kernel.org # v6.15+ +Signed-off-by: Cheng-Yang Chou +Reviewed-by: Andrea Righi +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/ext_idle.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/sched/ext_idle.c ++++ b/kernel/sched/ext_idle.c +@@ -543,7 +543,7 @@ s32 scx_select_cpu_dfl(struct task_struc + * piled up on it even if there is an idle core elsewhere on + * the system. + */ +- waker_node = cpu_to_node(cpu); ++ waker_node = scx_cpu_node_if_enabled(cpu); + if (!(current->flags & PF_EXITING) && + cpu_rq(cpu)->scx.local_dsq.nr == 0 && + (!(flags & SCX_PICK_IDLE_IN_NODE) || (waker_node == node)) && diff --git a/queue-6.19/sched_ext-fix-scx_kick_wait-deadlock-by-deferring-wait-to-balance-callback.patch b/queue-6.19/sched_ext-fix-scx_kick_wait-deadlock-by-deferring-wait-to-balance-callback.patch new file mode 100644 index 0000000000..34e6fa34ec --- /dev/null +++ b/queue-6.19/sched_ext-fix-scx_kick_wait-deadlock-by-deferring-wait-to-balance-callback.patch @@ -0,0 +1,207 @@ +From 415cb193bb9736f0e830286c72a6fa8eb2a9cc5c Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Sat, 28 Mar 2026 14:18:55 -1000 +Subject: sched_ext: Fix SCX_KICK_WAIT deadlock by deferring wait to balance callback + +From: Tejun Heo + +commit 415cb193bb9736f0e830286c72a6fa8eb2a9cc5c upstream. + +SCX_KICK_WAIT busy-waits in kick_cpus_irq_workfn() using +smp_cond_load_acquire() until the target CPU's kick_sync advances. Because +the irq_work runs in hardirq context, the waiting CPU cannot reschedule and +its own kick_sync never advances. If multiple CPUs form a wait cycle, all +CPUs deadlock. + +Replace the busy-wait in kick_cpus_irq_workfn() with resched_curr() to +force the CPU through do_pick_task_scx(), which queues a balance callback +to perform the wait. The balance callback drops the rq lock and enables +IRQs following the sched_core_balance() pattern, so the CPU can process +IPIs while waiting. The local CPU's kick_sync is advanced on entry to +do_pick_task_scx() and continuously during the wait, ensuring any CPU that +starts waiting for us sees the advancement and cannot form cyclic +dependencies. + +Fixes: 90e55164dad4 ("sched_ext: Implement SCX_KICK_WAIT") +Cc: stable@vger.kernel.org # v6.12+ +Reported-by: Christian Loehle +Link: https://lore.kernel.org/r/20260316100249.1651641-1-christian.loehle@arm.com +Signed-off-by: Tejun Heo +Tested-by: Christian Loehle +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/ext.c | 95 +++++++++++++++++++++++++++++++++++++-------------- + kernel/sched/sched.h | 3 + + 2 files changed, 73 insertions(+), 25 deletions(-) + +--- a/kernel/sched/ext.c ++++ b/kernel/sched/ext.c +@@ -2394,7 +2394,7 @@ static void put_prev_task_scx(struct rq + { + struct scx_sched *sch = scx_root; + +- /* see kick_cpus_irq_workfn() */ ++ /* see kick_sync_wait_bal_cb() */ + smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); + + update_curr_scx(rq); +@@ -2437,6 +2437,48 @@ switch_class: + switch_class(rq, next); + } + ++static void kick_sync_wait_bal_cb(struct rq *rq) ++{ ++ struct scx_kick_syncs __rcu *ks = __this_cpu_read(scx_kick_syncs); ++ unsigned long *ksyncs = rcu_dereference_sched(ks)->syncs; ++ bool waited; ++ s32 cpu; ++ ++ /* ++ * Drop rq lock and enable IRQs while waiting. IRQs must be enabled ++ * — a target CPU may be waiting for us to process an IPI (e.g. TLB ++ * flush) while we wait for its kick_sync to advance. ++ * ++ * Also, keep advancing our own kick_sync so that new kick_sync waits ++ * targeting us, which can start after we drop the lock, cannot form ++ * cyclic dependencies. ++ */ ++retry: ++ waited = false; ++ for_each_cpu(cpu, rq->scx.cpus_to_sync) { ++ /* ++ * smp_load_acquire() pairs with smp_store_release() on ++ * kick_sync updates on the target CPUs. ++ */ ++ if (cpu == cpu_of(rq) || ++ smp_load_acquire(&cpu_rq(cpu)->scx.kick_sync) != ksyncs[cpu]) { ++ cpumask_clear_cpu(cpu, rq->scx.cpus_to_sync); ++ continue; ++ } ++ ++ raw_spin_rq_unlock_irq(rq); ++ while (READ_ONCE(cpu_rq(cpu)->scx.kick_sync) == ksyncs[cpu]) { ++ smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); ++ cpu_relax(); ++ } ++ raw_spin_rq_lock_irq(rq); ++ waited = true; ++ } ++ ++ if (waited) ++ goto retry; ++} ++ + static struct task_struct *first_local_task(struct rq *rq) + { + return list_first_entry_or_null(&rq->scx.local_dsq.list, +@@ -2450,7 +2492,7 @@ do_pick_task_scx(struct rq *rq, struct r + bool keep_prev; + struct task_struct *p; + +- /* see kick_cpus_irq_workfn() */ ++ /* see kick_sync_wait_bal_cb() */ + smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); + + rq_modified_clear(rq); +@@ -2461,6 +2503,17 @@ do_pick_task_scx(struct rq *rq, struct r + maybe_queue_balance_callback(rq); + + /* ++ * Defer to a balance callback which can drop rq lock and enable ++ * IRQs. Waiting directly in the pick path would deadlock against ++ * CPUs sending us IPIs (e.g. TLB flushes) while we wait for them. ++ */ ++ if (unlikely(rq->scx.kick_sync_pending)) { ++ rq->scx.kick_sync_pending = false; ++ queue_balance_callback(rq, &rq->scx.kick_sync_bal_cb, ++ kick_sync_wait_bal_cb); ++ } ++ ++ /* + * If any higher-priority sched class enqueued a runnable task on + * this rq during balance_one(), abort and return RETRY_TASK, so + * that the scheduler loop can restart. +@@ -4673,6 +4726,9 @@ static void scx_dump_state(struct scx_ex + if (!cpumask_empty(rq->scx.cpus_to_wait)) + dump_line(&ns, " cpus_to_wait : %*pb", + cpumask_pr_args(rq->scx.cpus_to_wait)); ++ if (!cpumask_empty(rq->scx.cpus_to_sync)) ++ dump_line(&ns, " cpus_to_sync : %*pb", ++ cpumask_pr_args(rq->scx.cpus_to_sync)); + + used = seq_buf_used(&ns); + if (SCX_HAS_OP(sch, dump_cpu)) { +@@ -5571,11 +5627,11 @@ static bool kick_one_cpu(s32 cpu, struct + + if (cpumask_test_cpu(cpu, this_scx->cpus_to_wait)) { + if (cur_class == &ext_sched_class) { ++ cpumask_set_cpu(cpu, this_scx->cpus_to_sync); + ksyncs[cpu] = rq->scx.kick_sync; + should_wait = true; +- } else { +- cpumask_clear_cpu(cpu, this_scx->cpus_to_wait); + } ++ cpumask_clear_cpu(cpu, this_scx->cpus_to_wait); + } + + resched_curr(rq); +@@ -5630,27 +5686,15 @@ static void kick_cpus_irq_workfn(struct + cpumask_clear_cpu(cpu, this_scx->cpus_to_kick_if_idle); + } + +- if (!should_wait) +- return; +- +- for_each_cpu(cpu, this_scx->cpus_to_wait) { +- unsigned long *wait_kick_sync = &cpu_rq(cpu)->scx.kick_sync; +- +- /* +- * Busy-wait until the task running at the time of kicking is no +- * longer running. This can be used to implement e.g. core +- * scheduling. +- * +- * smp_cond_load_acquire() pairs with store_releases in +- * pick_task_scx() and put_prev_task_scx(). The former breaks +- * the wait if SCX's scheduling path is entered even if the same +- * task is picked subsequently. The latter is necessary to break +- * the wait when $cpu is taken by a higher sched class. +- */ +- if (cpu != cpu_of(this_rq)) +- smp_cond_load_acquire(wait_kick_sync, VAL != ksyncs[cpu]); +- +- cpumask_clear_cpu(cpu, this_scx->cpus_to_wait); ++ /* ++ * Can't wait in hardirq — kick_sync can't advance, deadlocking if ++ * CPUs wait for each other. Defer to kick_sync_wait_bal_cb(). ++ */ ++ if (should_wait) { ++ raw_spin_rq_lock(this_rq); ++ this_scx->kick_sync_pending = true; ++ resched_curr(this_rq); ++ raw_spin_rq_unlock(this_rq); + } + } + +@@ -5755,6 +5799,7 @@ void __init init_sched_ext_class(void) + BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_kick_if_idle, GFP_KERNEL, n)); + BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_preempt, GFP_KERNEL, n)); + BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_wait, GFP_KERNEL, n)); ++ BUG_ON(!zalloc_cpumask_var_node(&rq->scx.cpus_to_sync, GFP_KERNEL, n)); + rq->scx.deferred_irq_work = IRQ_WORK_INIT_HARD(deferred_irq_workfn); + rq->scx.kick_cpus_irq_work = IRQ_WORK_INIT_HARD(kick_cpus_irq_workfn); + +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -803,9 +803,12 @@ struct scx_rq { + cpumask_var_t cpus_to_kick_if_idle; + cpumask_var_t cpus_to_preempt; + cpumask_var_t cpus_to_wait; ++ cpumask_var_t cpus_to_sync; ++ bool kick_sync_pending; + unsigned long kick_sync; + local_t reenq_local_deferred; + struct balance_callback deferred_bal_cb; ++ struct balance_callback kick_sync_bal_cb; + struct irq_work deferred_irq_work; + struct irq_work kick_cpus_irq_work; + struct scx_dispatch_q bypass_dsq; diff --git a/queue-6.19/series b/queue-6.19/series index 5fe108c871..ed8999e0a5 100644 --- a/queue-6.19/series +++ b/queue-6.19/series @@ -162,3 +162,50 @@ drm-ioc32-stop-speculation-on-the-drm_compat_ioctl-path.patch rust_binder-use-assertsync-for-binder_vm_ops.patch wifi-wilc1000-fix-u8-overflow-in-ssid-scan-buffer-size-calculation.patch wifi-iwlwifi-mvm-fix-potential-out-of-bounds-read-in-iwl_mvm_nd_match_info_handler.patch +usb-serial-option-add-meig-smart-srm825wn.patch +drm-amd-display-fix-null-pointer-dereference-in-dcn401_init_hw.patch +sched_ext-fix-inconsistent-numa-node-lookup-in-scx_select_cpu_dfl.patch +lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch +sched_ext-fix-scx_kick_wait-deadlock-by-deferring-wait-to-balance-callback.patch +alsa-caiaq-fix-stack-out-of-bounds-read-in-init_card.patch +alsa-ctxfi-check-the-error-for-index-mapping.patch +alsa-ctxfi-fix-missing-spdifi1-index-handling.patch +alsa-ctxfi-don-t-enumerate-spdif1-at-daio-initialization.patch +alsa-hda-realtek-add-quirk-for-acer-swift-sfg14-73.patch +alsa-hda-realtek-add-quirk-for-asus-rog-strix-scar-15.patch +alsa-hda-realtek-add-quirk-for-hp-victus-15-fb0xxx.patch +alsa-hda-realtek-change-quirk-for-hp-omnibook-7-laptop-16-bh0xxx.patch +io_uring-net-fix-slab-out-of-bounds-read-in-io_bundle_nbufs.patch +bluetooth-smp-derive-legacy-responder-stk-authentication-from-mitm-state.patch +bluetooth-smp-force-responder-mitm-requirements-before-building-the-pairing-response.patch +bluetooth-hci_sync-fix-stack-buffer-overflow-in-hci_le_big_create_sync.patch +bluetooth-hci_event-move-wake-reason-storage-into-validated-event-handlers.patch +ksmbd-fix-oob-write-in-query_info-for-compound-requests.patch +mips-mm-rewrite-tlb-uniquification-for-the-hidden-bit-feature.patch +mips-sibyte-bring-back-cache-initialisation.patch +mips-fix-the-gcc-version-check-for-__multi3-workaround.patch +iommu-do-not-call-drivers-for-empty-gathers.patch +hwmon-occ-fix-division-by-zero-in-occ_show_power_1.patch +mips-mm-allocate-tlb_vpn-array-atomically.patch +x86-kexec-disable-kcov-instrumentation-after-load_segments.patch +drm-amdgpu-fix-the-idr-allocation-flags.patch +gpib-fix-use-after-free-in-io-ioctl-handlers.patch +iio-add-iio_declare_quaternion-macro.patch +iio-orientation-hid-sensor-rotation-fix-quaternion-alignment.patch +iio-orientation-hid-sensor-rotation-add-timestamp-hack-to-not-break-userspace.patch +iio-adc-ti-adc161s626-fix-buffer-read-on-big-endian.patch +iio-adc-ti-adc161s626-use-dma-safe-memory-for-spi_read.patch +iio-adc-ti-ads1119-fix-unbalanced-pm-reference-count-in-ds1119_single_conversion.patch +iio-adc-ti-ads1119-reinit-completion-before-wait_for_completion_timeout.patch +iio-adc-ti-ads1119-replace-irqf_oneshot-with-irqf_no_thread.patch +drm-ast-dp501-fix-initialization-of-scu2c.patch +drm-i915-dsi-don-t-do-dsc-horizontal-timing-adjustments-in-command-mode.patch +drm-i915-dp-use-crtc_state-enhanced_framing-properly-on-ivb-hsw-cpu-edp.patch +drm-i915-cdclk-do-the-full-cdclk-dance-for-min_voltage_level-changes.patch +drm-amdgpu-fix-wait-after-reset-sequence-in-s4.patch +drm-amdgpu-validate-doorbell_offset-in-user-queue-creation.patch +drm-amdgpu-change-amdgpu_va_reserved_trap_size-to-64kb.patch +drm-amdgpu-pm-drop-smu-driver-if-version-not-matched-messages.patch +usb-serial-io_edgeport-add-support-for-blackbox-ic135a.patch +usb-serial-option-add-support-for-rolling-wireless-rw135r-gl.patch +usb-core-add-no_lpm-quirk-for-razer-kiyo-pro-webcam.patch diff --git a/queue-6.19/usb-core-add-no_lpm-quirk-for-razer-kiyo-pro-webcam.patch b/queue-6.19/usb-core-add-no_lpm-quirk-for-razer-kiyo-pro-webcam.patch new file mode 100644 index 0000000000..9695425f52 --- /dev/null +++ b/queue-6.19/usb-core-add-no_lpm-quirk-for-razer-kiyo-pro-webcam.patch @@ -0,0 +1,50 @@ +From 8b7a42ecdcdeb55580d9345412f7f8fc5aca3f6c Mon Sep 17 00:00:00 2001 +From: JP Hein +Date: Mon, 30 Mar 2026 17:38:04 -0700 +Subject: USB: core: add NO_LPM quirk for Razer Kiyo Pro webcam + +From: JP Hein + +commit 8b7a42ecdcdeb55580d9345412f7f8fc5aca3f6c upstream. + +The Razer Kiyo Pro (1532:0e05) is a USB 3.0 UVC webcam whose firmware +does not handle USB Link Power Management transitions reliably. When LPM +is active, the device can enter a state where it fails to respond to +control transfers, producing EPIPE (-32) errors on UVC probe control +SET_CUR requests. In the worst case, the stalled endpoint triggers an +xHCI stop-endpoint command that times out, causing the host controller +to be declared dead and every USB device on the bus to be disconnected. + +This has been reported as Ubuntu Launchpad Bug #2061177. The failure +mode is: + + 1. UVC probe control SET_CUR returns -32 (EPIPE) + 2. xHCI host not responding to stop endpoint command + 3. xHCI host controller not responding, assume dead + 4. All USB devices on the affected xHCI controller disconnect + +Disabling LPM prevents the firmware from entering the problematic low- +power states that precede the stall. This is the same approach used for +other webcams with similar firmware issues (e.g., Logitech HD Webcam C270). + +Cc: stable +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2061177 +Signed-off-by: JP Hein +Link: https://patch.msgid.link/20260331003806.212565-2-jp@jphein.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -493,6 +493,8 @@ static const struct usb_device_id usb_qu + /* Razer - Razer Blade Keyboard */ + { USB_DEVICE(0x1532, 0x0116), .driver_info = + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, ++ /* Razer - Razer Kiyo Pro Webcam */ ++ { USB_DEVICE(0x1532, 0x0e05), .driver_info = USB_QUIRK_NO_LPM }, + + /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ + { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/queue-6.19/usb-serial-io_edgeport-add-support-for-blackbox-ic135a.patch b/queue-6.19/usb-serial-io_edgeport-add-support-for-blackbox-ic135a.patch new file mode 100644 index 0000000000..585ac45ecd --- /dev/null +++ b/queue-6.19/usb-serial-io_edgeport-add-support-for-blackbox-ic135a.patch @@ -0,0 +1,57 @@ +From 0e01c3416eb863ee7f156a9d7e7421ec0a9f68a0 Mon Sep 17 00:00:00 2001 +From: Frej Drejhammar +Date: Sun, 22 Feb 2026 18:00:42 +0100 +Subject: USB: serial: io_edgeport: add support for Blackbox IC135A + +From: Frej Drejhammar + +commit 0e01c3416eb863ee7f156a9d7e7421ec0a9f68a0 upstream. + +The Blackbox 724-746-5500 USB Director USB-RS-232 HUB, part number +IC135A, is a rebadged Edgeport/4 with its own USB device id. + +Signed-off-by: Frej Drejhammar +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/io_edgeport.c | 3 +++ + drivers/usb/serial/io_usbvend.h | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -73,6 +73,7 @@ static const struct usb_device_id edgepo + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_22I) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_4) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_COMPATIBLE) }, ++ { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BLACKBOX_IC135A) }, + { } + }; + +@@ -121,6 +122,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, ++ { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BLACKBOX_IC135A) }, + { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, + { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, + { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, +@@ -470,6 +472,7 @@ static void get_product_info(struct edge + case ION_DEVICE_ID_EDGEPORT_2_DIN: + case ION_DEVICE_ID_EDGEPORT_4_DIN: + case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU: ++ case ION_DEVICE_ID_BLACKBOX_IC135A: + product_info->IsRS232 = 1; + break; + +--- a/drivers/usb/serial/io_usbvend.h ++++ b/drivers/usb/serial/io_usbvend.h +@@ -211,6 +211,7 @@ + + // + // Definitions for other product IDs ++#define ION_DEVICE_ID_BLACKBOX_IC135A 0x0801 // OEM device (rebranded Edgeport/4) + #define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device + #define ION_DEVICE_ID_E5805A 0x1A01 // OEM device (rebranded Edgeport/4) + diff --git a/queue-6.19/usb-serial-option-add-meig-smart-srm825wn.patch b/queue-6.19/usb-serial-option-add-meig-smart-srm825wn.patch new file mode 100644 index 0000000000..eb16abeaef --- /dev/null +++ b/queue-6.19/usb-serial-option-add-meig-smart-srm825wn.patch @@ -0,0 +1,67 @@ +From e8d0ed37bd51da52da6225d278e330c2f18a6198 Mon Sep 17 00:00:00 2001 +From: Ernestas Kulik +Date: Tue, 24 Mar 2026 13:07:16 +0200 +Subject: USB: serial: option: add MeiG Smart SRM825WN + +From: Ernestas Kulik + +commit e8d0ed37bd51da52da6225d278e330c2f18a6198 upstream. + +Add support for the SDX62-based MeiG Smart SRM825WN module. + +If#= 0: RNDIS +If#= 1: RNDIS +If#= 2: Diag +If#= 3: AT +If#= 4: AT +If#= 5: NMEA + +T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 19 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2dee ProdID=4d38 Rev= 5.04 +S: Manufacturer=MEIG +S: Product=LTE-A Module +S: SerialNumber=da47a175 +C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA +A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03 +I:* If#= 0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host +E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host +E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option +E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: Ernestas Kulik +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2441,6 +2441,9 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM825WN (Diag) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825WN (AT) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825WN (NMEA) */ + { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ + { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ diff --git a/queue-6.19/usb-serial-option-add-support-for-rolling-wireless-rw135r-gl.patch b/queue-6.19/usb-serial-option-add-support-for-rolling-wireless-rw135r-gl.patch new file mode 100644 index 0000000000..c172187166 --- /dev/null +++ b/queue-6.19/usb-serial-option-add-support-for-rolling-wireless-rw135r-gl.patch @@ -0,0 +1,49 @@ +From 01e8d0f742222f1e68f48180d5480097adf7ae9f Mon Sep 17 00:00:00 2001 +From: Wanquan Zhong +Date: Mon, 16 Mar 2026 19:55:12 +0800 +Subject: USB: serial: option: add support for Rolling Wireless RW135R-GL + +From: Wanquan Zhong + +commit 01e8d0f742222f1e68f48180d5480097adf7ae9f upstream. + +Add VID/PID 33f8:1003 for the Rolling Wireless RW135R-GL M.2 module, +which is used in laptop debug cards with MBIM interface for +Linux/Chrome OS. The device supports mbim, pipe functionalities. + +Here are the outputs of usb-devices: +T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 +D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 +P: Vendor=33f8 ProdID=1003 Rev=05.15 +S: Manufacturer=Rolling Wireless S.a.r.l. +S: Product=Rolling RW135R-GL Module +S: SerialNumber=12345678 +C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=896mA +I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim +E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim +E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option +E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms + +Signed-off-by: Wanquan Zhong +Cc: stable@vger.kernel.org +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/serial/option.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -2464,6 +2464,7 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0302, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */ + .driver_info = RSVD(5) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff) }, /* Rolling RW135R-GL (laptop MBIM) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */ + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x40) }, diff --git a/queue-6.19/x86-kexec-disable-kcov-instrumentation-after-load_segments.patch b/queue-6.19/x86-kexec-disable-kcov-instrumentation-after-load_segments.patch new file mode 100644 index 0000000000..551c960959 --- /dev/null +++ b/queue-6.19/x86-kexec-disable-kcov-instrumentation-after-load_segments.patch @@ -0,0 +1,84 @@ +From 917e3ad3321e75ca0223d5ccf26ceda116aa51e1 Mon Sep 17 00:00:00 2001 +From: Aleksandr Nogikh +Date: Wed, 25 Mar 2026 16:48:24 +0100 +Subject: x86/kexec: Disable KCOV instrumentation after load_segments() + +From: Aleksandr Nogikh + +commit 917e3ad3321e75ca0223d5ccf26ceda116aa51e1 upstream. + +The load_segments() function changes segment registers, invalidating GS base +(which KCOV relies on for per-cpu data). When CONFIG_KCOV is enabled, any +subsequent instrumented C code call (e.g. native_gdt_invalidate()) begins +crashing the kernel in an endless loop. + +To reproduce the problem, it's sufficient to do kexec on a KCOV-instrumented +kernel: + + $ kexec -l /boot/otherKernel + $ kexec -e + +The real-world context for this problem is enabling crash dump collection in +syzkaller. For this, the tool loads a panic kernel before fuzzing and then +calls makedumpfile after the panic. This workflow requires both CONFIG_KEXEC +and CONFIG_KCOV to be enabled simultaneously. + +Adding safeguards directly to the KCOV fast-path (__sanitizer_cov_trace_pc()) +is also undesirable as it would introduce an extra performance overhead. + +Disabling instrumentation for the individual functions would be too fragile, +so disable KCOV instrumentation for the entire machine_kexec_64.c and +physaddr.c. If coverage-guided fuzzing ever needs these components in the +future, other approaches should be considered. + +The problem is not relevant for 32 bit kernels as CONFIG_KCOV is not supported +there. + + [ bp: Space out comment for better readability. ] + +Fixes: 0d345996e4cb ("x86/kernel: increase kcov coverage under arch/x86/kernel folder") +Signed-off-by: Aleksandr Nogikh +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Dmitry Vyukov +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260325154825.551191-1-nogikh@google.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/Makefile | 14 ++++++++++++++ + arch/x86/mm/Makefile | 2 ++ + 2 files changed, 16 insertions(+) + +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -44,6 +44,20 @@ KCOV_INSTRUMENT_unwind_orc.o := n + KCOV_INSTRUMENT_unwind_frame.o := n + KCOV_INSTRUMENT_unwind_guess.o := n + ++# Disable KCOV to prevent crashes during kexec: load_segments() invalidates ++# the GS base, which KCOV relies on for per-CPU data. ++# ++# As KCOV and KEXEC compatibility should be preserved (e.g. syzkaller is ++# using it to collect crash dumps during kernel fuzzing), disabling ++# KCOV for KEXEC kernels is not an option. Selectively disabling KCOV ++# instrumentation for individual affected functions can be fragile, while ++# adding more checks to KCOV would slow it down. ++# ++# As a compromise solution, disable KCOV instrumentation for the whole ++# source code file. If its coverage is ever needed, other approaches ++# should be considered. ++KCOV_INSTRUMENT_machine_kexec_64.o := n ++ + CFLAGS_head32.o := -fno-stack-protector + CFLAGS_head64.o := -fno-stack-protector + CFLAGS_irq.o := -I $(src)/../include/asm/trace +--- a/arch/x86/mm/Makefile ++++ b/arch/x86/mm/Makefile +@@ -4,6 +4,8 @@ KCOV_INSTRUMENT_tlb.o := n + KCOV_INSTRUMENT_mem_encrypt.o := n + KCOV_INSTRUMENT_mem_encrypt_amd.o := n + KCOV_INSTRUMENT_pgprot.o := n ++# See the "Disable KCOV" comment in arch/x86/kernel/Makefile. ++KCOV_INSTRUMENT_physaddr.o := n + + KASAN_SANITIZE_mem_encrypt.o := n + KASAN_SANITIZE_mem_encrypt_amd.o := n