From: Sasha Levin Date: Thu, 22 May 2025 20:52:56 +0000 (-0400) Subject: Fixes for 6.6 X-Git-Tag: v6.12.31~97 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8cd6a86640686749735c7da764e27bdc1fc0772;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/__legitimize_mnt-check-for-mnt_sync_umount-should-be.patch b/queue-6.6/__legitimize_mnt-check-for-mnt_sync_umount-should-be.patch new file mode 100644 index 0000000000..ee3ecfb895 --- /dev/null +++ b/queue-6.6/__legitimize_mnt-check-for-mnt_sync_umount-should-be.patch @@ -0,0 +1,48 @@ +From 822f80151a63eea5d234b9b6120408e75d5c7a20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Apr 2025 15:41:51 -0400 +Subject: __legitimize_mnt(): check for MNT_SYNC_UMOUNT should be under + mount_lock + +From: Al Viro + +[ Upstream commit 250cf3693060a5f803c5f1ddc082bb06b16112a9 ] + +... or we risk stealing final mntput from sync umount - raising mnt_count +after umount(2) has verified that victim is not busy, but before it +has set MNT_SYNC_UMOUNT; in that case __legitimize_mnt() doesn't see +that it's safe to quietly undo mnt_count increment and leaves dropping +the reference to caller, where it'll be a full-blown mntput(). + +Check under mount_lock is needed; leaving the current one done before +taking that makes no sense - it's nowhere near common enough to bother +with. + +Reviewed-by: Christian Brauner +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/namespace.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 450f4198b8cdd..ef3b2ae2957ec 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -636,12 +636,8 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq) + smp_mb(); // see mntput_no_expire() and do_umount() + if (likely(!read_seqretry(&mount_lock, seq))) + return 0; +- if (bastard->mnt_flags & MNT_SYNC_UMOUNT) { +- mnt_add_count(mnt, -1); +- return 1; +- } + lock_mount_hash(); +- if (unlikely(bastard->mnt_flags & MNT_DOOMED)) { ++ if (unlikely(bastard->mnt_flags & (MNT_SYNC_UMOUNT | MNT_DOOMED))) { + mnt_add_count(mnt, -1); + unlock_mount_hash(); + return 1; +-- +2.39.5 + diff --git a/queue-6.6/accel-qaic-mask-out-sr-iov-pci-resources.patch b/queue-6.6/accel-qaic-mask-out-sr-iov-pci-resources.patch new file mode 100644 index 0000000000..8b36d5d908 --- /dev/null +++ b/queue-6.6/accel-qaic-mask-out-sr-iov-pci-resources.patch @@ -0,0 +1,42 @@ +From 55d2a63cc32263ca17ea2a04c61e1d48e6dbafc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2025 10:09:41 -0700 +Subject: accel/qaic: Mask out SR-IOV PCI resources + +From: Youssef Samir + +[ Upstream commit 8685520474bfc0fe4be83c3cbfe3fb3e1ca1514a ] + +During the initialization of the qaic device, pci_select_bars() is +used to fetch a bitmask of the BARs exposed by the device. On devices +that have Virtual Functions capabilities, the bitmask includes SR-IOV +BARs. + +Use a mask to filter out SR-IOV BARs if they exist. + +Signed-off-by: Youssef Samir +Reviewed-by: Jeffrey Hugo +Signed-off-by: Jeffrey Hugo +Reviewed-by: Lizhi Hou +Link: https://patchwork.freedesktop.org/patch/msgid/20250117170943.2643280-6-quic_jhugo@quicinc.com +Signed-off-by: Sasha Levin +--- + drivers/accel/qaic/qaic_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c +index b5de82e6eb4d5..e69bfb30b44e0 100644 +--- a/drivers/accel/qaic/qaic_drv.c ++++ b/drivers/accel/qaic/qaic_drv.c +@@ -400,7 +400,7 @@ static int init_pci(struct qaic_device *qdev, struct pci_dev *pdev) + int bars; + int ret; + +- bars = pci_select_bars(pdev, IORESOURCE_MEM); ++ bars = pci_select_bars(pdev, IORESOURCE_MEM) & 0x3f; + + /* make sure the device has the expected BARs */ + if (bars != (BIT(0) | BIT(2) | BIT(4))) { +-- +2.39.5 + diff --git a/queue-6.6/acpi-hed-always-initialize-before-evged.patch b/queue-6.6/acpi-hed-always-initialize-before-evged.patch new file mode 100644 index 0000000000..19218b06c2 --- /dev/null +++ b/queue-6.6/acpi-hed-always-initialize-before-evged.patch @@ -0,0 +1,67 @@ +From d1a2c7990d512e35a7c3132f2b6bee1f6543ff07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 14:34:08 +0800 +Subject: ACPI: HED: Always initialize before evged + +From: Xiaofei Tan + +[ Upstream commit cccf6ee090c8c133072d5d5b52ae25f3bc907a16 ] + +When the HED driver is built-in, it initializes after evged because they +both are at the same initcall level, so the initialization ordering +depends on the Makefile order. However, this prevents RAS records +coming in between the evged driver initialization and the HED driver +initialization from being handled. + +If the number of such RAS records is above the APEI HEST error source +number, the HEST resources may be exhausted, and that may affect +subsequent RAS error reporting. + +To fix this issue, change the initcall level of HED to subsys_initcall +and prevent the driver from being built as a module by changing ACPI_HED +in Kconfig from "tristate" to "bool". + +Signed-off-by: Xiaofei Tan +Link: https://patch.msgid.link/20250212063408.927666-1-tanxiaofei@huawei.com +[ rjw: Changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/Kconfig | 2 +- + drivers/acpi/hed.c | 7 ++++++- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig +index cee82b473dc50..648228831f5e8 100644 +--- a/drivers/acpi/Kconfig ++++ b/drivers/acpi/Kconfig +@@ -438,7 +438,7 @@ config ACPI_SBS + the modules will be called sbs and sbshc. + + config ACPI_HED +- tristate "Hardware Error Device" ++ bool "Hardware Error Device" + help + This driver supports the Hardware Error Device (PNP0C33), + which is used to report some hardware errors notified via +diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c +index 46c6f8c35b436..2e01eaa8d8cd5 100644 +--- a/drivers/acpi/hed.c ++++ b/drivers/acpi/hed.c +@@ -80,7 +80,12 @@ static struct acpi_driver acpi_hed_driver = { + .remove = acpi_hed_remove, + }, + }; +-module_acpi_driver(acpi_hed_driver); ++ ++static int __init acpi_hed_driver_init(void) ++{ ++ return acpi_bus_register_driver(&acpi_hed_driver); ++} ++subsys_initcall(acpi_hed_driver_init); + + MODULE_AUTHOR("Huang Ying"); + MODULE_DESCRIPTION("ACPI Hardware Error Device Driver"); +-- +2.39.5 + diff --git a/queue-6.6/acpi-pnp-add-intel-oc-watchdog-ids-to-non-pnp-device.patch b/queue-6.6/acpi-pnp-add-intel-oc-watchdog-ids-to-non-pnp-device.patch new file mode 100644 index 0000000000..38a6c7f376 --- /dev/null +++ b/queue-6.6/acpi-pnp-add-intel-oc-watchdog-ids-to-non-pnp-device.patch @@ -0,0 +1,46 @@ +From 7a8ae729f5f61150760fc30b4d9b326763e3540f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Mar 2025 10:55:07 +0000 +Subject: ACPI: PNP: Add Intel OC Watchdog IDs to non-PNP device list + +From: Diogo Ivo + +[ Upstream commit f06777cf2bbc21dd8c71d6e3906934e56b4e18e4 ] + +Intel Over-Clocking Watchdogs are described in ACPI tables by both the +generic PNP0C02 _CID and their ACPI _HID. The presence of the _CID then +causes the PNP scan handler to attach to the watchdog, preventing the +actual watchdog driver from binding. Address this by adding the ACPI +_HIDs to the list of non-PNP devices, so that the PNP scan handler is +bypassed. + +Note that these watchdogs can be described by multiple _HIDs for what +seems to be identical hardware. This commit is not a complete list of +all the possible watchdog ACPI _HIDs. + +Signed-off-by: Diogo Ivo +Link: https://patch.msgid.link/20250317-ivo-intel_oc_wdt-v3-2-32c396f4eefd@siemens.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpi_pnp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c +index 01abf26764b00..3f5a1840f5733 100644 +--- a/drivers/acpi/acpi_pnp.c ++++ b/drivers/acpi/acpi_pnp.c +@@ -355,8 +355,10 @@ static bool acpi_pnp_match(const char *idstr, const struct acpi_device_id **matc + * device represented by it. + */ + static const struct acpi_device_id acpi_nonpnp_device_ids[] = { ++ {"INT3F0D"}, + {"INTC1080"}, + {"INTC1081"}, ++ {"INTC1099"}, + {""}, + }; + +-- +2.39.5 + diff --git a/queue-6.6/alsa-hda-realtek-add-quirk-for-hp-spectre-x360-15-df.patch b/queue-6.6/alsa-hda-realtek-add-quirk-for-hp-spectre-x360-15-df.patch new file mode 100644 index 0000000000..3d83c93066 --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-add-quirk-for-hp-spectre-x360-15-df.patch @@ -0,0 +1,106 @@ +From ceec784b81b36c9561c71d04495033d323b361a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Apr 2025 10:10:34 +0200 +Subject: ALSA: hda/realtek: Add quirk for HP Spectre x360 15-df1xxx + +From: Takashi Iwai + +[ Upstream commit be0c40da888840fe91b45474cb70779e6cbaf7ca ] + +HP Spectre x360 15-df1xxx with SSID 13c:863e requires similar +workarounds that were applied to another HP Spectre x360 models; +it has a mute LED only, no micmute LEDs, and needs the speaker GPIO +seup. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220054 +Link: https://patch.msgid.link/20250427081035.11567-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 42 +++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index a13795e405a4d..77e9c7a928efe 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -6790,6 +6790,41 @@ static void alc285_fixup_hp_spectre_x360_eb1(struct hda_codec *codec, + } + } + ++/* GPIO1 = amplifier on/off */ ++static void alc285_fixup_hp_spectre_x360_df1(struct hda_codec *codec, ++ const struct hda_fixup *fix, ++ int action) ++{ ++ struct alc_spec *spec = codec->spec; ++ static const hda_nid_t conn[] = { 0x02 }; ++ static const struct hda_pintbl pincfgs[] = { ++ { 0x14, 0x90170110 }, /* front/high speakers */ ++ { 0x17, 0x90170130 }, /* back/bass speakers */ ++ { } ++ }; ++ ++ // enable mute led ++ alc285_fixup_hp_mute_led_coefbit(codec, fix, action); ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ /* needed for amp of back speakers */ ++ spec->gpio_mask |= 0x01; ++ spec->gpio_dir |= 0x01; ++ snd_hda_apply_pincfgs(codec, pincfgs); ++ /* share DAC to have unified volume control */ ++ snd_hda_override_conn_list(codec, 0x14, ARRAY_SIZE(conn), conn); ++ snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); ++ break; ++ case HDA_FIXUP_ACT_INIT: ++ /* need to toggle GPIO to enable the amp of back speakers */ ++ alc_update_gpio_data(codec, 0x01, true); ++ msleep(100); ++ alc_update_gpio_data(codec, 0x01, false); ++ break; ++ } ++} ++ + static void alc285_fixup_hp_spectre_x360(struct hda_codec *codec, + const struct hda_fixup *fix, int action) + { +@@ -7401,6 +7436,7 @@ enum { + ALC280_FIXUP_HP_9480M, + ALC245_FIXUP_HP_X360_AMP, + ALC285_FIXUP_HP_SPECTRE_X360_EB1, ++ ALC285_FIXUP_HP_SPECTRE_X360_DF1, + ALC285_FIXUP_HP_ENVY_X360, + ALC288_FIXUP_DELL_HEADSET_MODE, + ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, +@@ -9439,6 +9475,10 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_spectre_x360_eb1 + }, ++ [ALC285_FIXUP_HP_SPECTRE_X360_DF1] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc285_fixup_hp_spectre_x360_df1 ++ }, + [ALC285_FIXUP_HP_ENVY_X360] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_envy_x360, +@@ -10038,6 +10078,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x86c1, "HP Laptop 15-da3001TU", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), + SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO), + SND_PCI_QUIRK(0x103c, 0x86e7, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), ++ SND_PCI_QUIRK(0x103c, 0x863e, "HP Spectre x360 15-df1xxx", ALC285_FIXUP_HP_SPECTRE_X360_DF1), + SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), + SND_PCI_QUIRK(0x103c, 0x86f9, "HP Spectre x360 13-aw0xxx", ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), +@@ -10786,6 +10827,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { + {.id = ALC295_FIXUP_HP_OMEN, .name = "alc295-hp-omen"}, + {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, + {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, ++ {.id = ALC285_FIXUP_HP_SPECTRE_X360_DF1, .name = "alc285-hp-spectre-x360-df1"}, + {.id = ALC285_FIXUP_HP_ENVY_X360, .name = "alc285-hp-envy-x360"}, + {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, + {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"}, +-- +2.39.5 + diff --git a/queue-6.6/alsa-hda-realtek-enable-pc-beep-passthrough-for-hp-e.patch b/queue-6.6/alsa-hda-realtek-enable-pc-beep-passthrough-for-hp-e.patch new file mode 100644 index 0000000000..8993f4e1cd --- /dev/null +++ b/queue-6.6/alsa-hda-realtek-enable-pc-beep-passthrough-for-hp-e.patch @@ -0,0 +1,177 @@ +From 9b4067ebbf5d58814eb5996f9f9ffa8bcc93405d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Feb 2025 22:31:03 +0100 +Subject: ALSA: hda/realtek: Enable PC beep passthrough for HP EliteBook 855 G7 + +From: Maciej S. Szmigiero + +[ Upstream commit aa85822c611aef7cd4dc17d27121d43e21bb82f0 ] + +PC speaker works well on this platform in BIOS and in Linux until sound +card drivers are loaded. Then it stops working. + +There seems to be a beep generator node at 0x1a in this CODEC +(ALC269_TYPE_ALC215) but it seems to be only connected to capture mixers +at nodes 0x22 and 0x23. +If I unmute the mixer input for 0x1a at node 0x23 and start recording +from its "ALC285 Analog" capture device I can clearly hear beeps in that +recording. + +So the beep generator is indeed working properly, however I wasn't able to +figure out any way to connect it to speakers. + +However, the bits in the "Passthrough Control" register (0x36) seems to +work at least partially: by zeroing "B" and "h" and setting "S" I can at +least make the PIT PC speaker output appear either in this laptop speakers +or headphones (depending on whether they are connected or not). + +There are some caveats, however: +* If the CODEC gets runtime-suspended the beeps stop so it needs HDA beep +device for keeping it awake during beeping. + +* If the beep generator node is generating any beep the PC beep passthrough +seems to be temporarily inhibited, so the HDA beep device has to be +prevented from using the actual beep generator node - but the beep device +is still necessary due to the previous point. + +* In contrast with other platforms here beep amplification has to be +disabled otherwise the beeps output are WAY louder than they were on pure +BIOS setup. + +Unless someone (from Realtek probably) knows how to make the beep generator +node output appear in speakers / headphones using PC beep passthrough seems +to be the only way to make PC speaker beeping actually work on this +platform. + +Signed-off-by: Maciej S. Szmigiero +Acked-by: kailang@realtek.com +Link: https://patch.msgid.link/7461f695b4daed80f2fc4b1463ead47f04f9ad05.1739741254.git.mail@maciej.szmigiero.name +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + include/sound/hda_codec.h | 1 + + sound/pci/hda/hda_beep.c | 15 +++++++++------ + sound/pci/hda/patch_realtek.c | 34 +++++++++++++++++++++++++++++++++- + 3 files changed, 43 insertions(+), 7 deletions(-) + +diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h +index 5497dc9c396a5..b58dc869cf77e 100644 +--- a/include/sound/hda_codec.h ++++ b/include/sound/hda_codec.h +@@ -196,6 +196,7 @@ struct hda_codec { + /* beep device */ + struct hda_beep *beep; + unsigned int beep_mode; ++ bool beep_just_power_on; + + /* widget capabilities cache */ + u32 *wcaps; +diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c +index e63621bcb2142..1a684e47d4d18 100644 +--- a/sound/pci/hda/hda_beep.c ++++ b/sound/pci/hda/hda_beep.c +@@ -31,8 +31,9 @@ static void generate_tone(struct hda_beep *beep, int tone) + beep->power_hook(beep, true); + beep->playing = 1; + } +- snd_hda_codec_write(codec, beep->nid, 0, +- AC_VERB_SET_BEEP_CONTROL, tone); ++ if (!codec->beep_just_power_on) ++ snd_hda_codec_write(codec, beep->nid, 0, ++ AC_VERB_SET_BEEP_CONTROL, tone); + if (!tone && beep->playing) { + beep->playing = 0; + if (beep->power_hook) +@@ -212,10 +213,12 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) + struct hda_beep *beep; + int err; + +- if (!snd_hda_get_bool_hint(codec, "beep")) +- return 0; /* disabled explicitly by hints */ +- if (codec->beep_mode == HDA_BEEP_MODE_OFF) +- return 0; /* disabled by module option */ ++ if (!codec->beep_just_power_on) { ++ if (!snd_hda_get_bool_hint(codec, "beep")) ++ return 0; /* disabled explicitly by hints */ ++ if (codec->beep_mode == HDA_BEEP_MODE_OFF) ++ return 0; /* disabled by module option */ ++ } + + beep = kzalloc(sizeof(*beep), GFP_KERNEL); + if (beep == NULL) +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 2f3f295f2b0cb..a13795e405a4d 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -24,6 +24,7 @@ + #include + #include "hda_local.h" + #include "hda_auto_parser.h" ++#include "hda_beep.h" + #include "hda_jack.h" + #include "hda_generic.h" + #include "hda_component.h" +@@ -6861,6 +6862,30 @@ static void alc285_fixup_hp_envy_x360(struct hda_codec *codec, + } + } + ++static void alc285_fixup_hp_beep(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) { ++ codec->beep_just_power_on = true; ++ } else if (action == HDA_FIXUP_ACT_INIT) { ++#ifdef CONFIG_SND_HDA_INPUT_BEEP ++ /* ++ * Just enable loopback to internal speaker and headphone jack. ++ * Disable amplification to get about the same beep volume as ++ * was on pure BIOS setup before loading the driver. ++ */ ++ alc_update_coef_idx(codec, 0x36, 0x7070, BIT(13)); ++ ++ snd_hda_enable_beep_device(codec, 1); ++ ++#if !IS_ENABLED(CONFIG_INPUT_PCSPKR) ++ dev_warn_once(hda_codec_dev(codec), ++ "enable CONFIG_INPUT_PCSPKR to get PC beeps\n"); ++#endif ++#endif ++ } ++} ++ + /* for hda_fixup_thinkpad_acpi() */ + #include "thinkpad_helper.c" + +@@ -7477,6 +7502,7 @@ enum { + ALC285_FIXUP_HP_GPIO_LED, + ALC285_FIXUP_HP_MUTE_LED, + ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED, ++ ALC285_FIXUP_HP_BEEP_MICMUTE_LED, + ALC236_FIXUP_HP_MUTE_LED_COEFBIT2, + ALC236_FIXUP_HP_GPIO_LED, + ALC236_FIXUP_HP_MUTE_LED, +@@ -9064,6 +9090,12 @@ static const struct hda_fixup alc269_fixups[] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_spectre_x360_mute_led, + }, ++ [ALC285_FIXUP_HP_BEEP_MICMUTE_LED] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc285_fixup_hp_beep, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_HP_MUTE_LED, ++ }, + [ALC236_FIXUP_HP_MUTE_LED_COEFBIT2] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_coefbit2, +@@ -10016,7 +10048,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8735, "HP ProBook 435 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), +- SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), ++ SND_PCI_QUIRK(0x103c, 0x8760, "HP EliteBook 8{4,5}5 G7", ALC285_FIXUP_HP_BEEP_MICMUTE_LED), + SND_PCI_QUIRK(0x103c, 0x876e, "HP ENVY x360 Convertible 13-ay0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS), + SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), + SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_LED), +-- +2.39.5 + diff --git a/queue-6.6/alsa-seq-improve-data-consistency-at-polling.patch b/queue-6.6/alsa-seq-improve-data-consistency-at-polling.patch new file mode 100644 index 0000000000..cb8097feac --- /dev/null +++ b/queue-6.6/alsa-seq-improve-data-consistency-at-polling.patch @@ -0,0 +1,70 @@ +From 2c53f8e49ba87cf1d5df19d4a4b7a3739a2ee5b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Mar 2025 09:42:42 +0100 +Subject: ALSA: seq: Improve data consistency at polling + +From: Takashi Iwai + +[ Upstream commit e3cd33ab17c33bd8f1a9df66ec83a15dd8f7afbb ] + +snd_seq_poll() calls snd_seq_write_pool_allocated() that reads out a +field in client->pool object, while it can be updated concurrently via +ioctls, as reported by syzbot. The data race itself is harmless, as +it's merely a poll() call, and the state is volatile. OTOH, the read +out of poll object info from the caller side is fragile, and we can +leave it better in snd_seq_pool_poll_wait() alone. + +A similar pattern is seen in snd_seq_kernel_client_write_poll(), too, +which is called from the OSS sequencer. + +This patch drops the pool checks from the caller side and add the +pool->lock in snd_seq_pool_poll_wait() for better data consistency. + +Reported-by: syzbot+2d373c9936c00d7e120c@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/67c88903.050a0220.15b4b9.0028.GAE@google.com +Link: https://patch.msgid.link/20250307084246.29271-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/seq/seq_clientmgr.c | 5 +---- + sound/core/seq/seq_memory.c | 1 + + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c +index 49f6763c3250d..31428cdc0f63d 100644 +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1169,8 +1169,7 @@ static __poll_t snd_seq_poll(struct file *file, poll_table * wait) + if (snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT) { + + /* check if data is available in the pool */ +- if (!snd_seq_write_pool_allocated(client) || +- snd_seq_pool_poll_wait(client->pool, file, wait)) ++ if (snd_seq_pool_poll_wait(client->pool, file, wait)) + mask |= EPOLLOUT | EPOLLWRNORM; + } + +@@ -2584,8 +2583,6 @@ int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table + if (client == NULL) + return -ENXIO; + +- if (! snd_seq_write_pool_allocated(client)) +- return 1; + if (snd_seq_pool_poll_wait(client->pool, file, wait)) + return 1; + return 0; +diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c +index b603bb93f8960..692860deec0c3 100644 +--- a/sound/core/seq/seq_memory.c ++++ b/sound/core/seq/seq_memory.c +@@ -429,6 +429,7 @@ int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, + poll_table *wait) + { + poll_wait(file, &pool->output_sleep, wait); ++ guard(spinlock_irq)(&pool->lock); + return snd_seq_output_ok(pool); + } + +-- +2.39.5 + diff --git a/queue-6.6/arch-powerpc-perf-check-the-instruction-type-before-.patch b/queue-6.6/arch-powerpc-perf-check-the-instruction-type-before-.patch new file mode 100644 index 0000000000..f2a2c9b963 --- /dev/null +++ b/queue-6.6/arch-powerpc-perf-check-the-instruction-type-before-.patch @@ -0,0 +1,137 @@ +From 2cdbc6b5295e617d29342725183291ece77fece9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Jan 2025 18:46:20 +0530 +Subject: arch/powerpc/perf: Check the instruction type before creating sample + with perf_mem_data_src + +From: Athira Rajeev + +[ Upstream commit 2ffb26afa64261139e608bf087a0c1fe24d76d4d ] + +perf mem report aborts as below sometimes (during some corner +case) in powerpc: + + # ./perf mem report 1>out + *** stack smashing detected ***: terminated + Aborted (core dumped) + +The backtrace is as below: + __pthread_kill_implementation () + raise () + abort () + __libc_message + __fortify_fail + __stack_chk_fail + hist_entry.lvl_snprintf + __sort__hpp_entry + __hist_entry__snprintf + hists.fprintf + cmd_report + cmd_mem + +Snippet of code which triggers the issue +from tools/perf/util/sort.c + + static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) + { + char out[64]; + + perf_mem__lvl_scnprintf(out, sizeof(out), he->mem_info); + return repsep_snprintf(bf, size, "%-*s", width, out); + } + +The value of "out" is filled from perf_mem_data_src value. +Debugging this further showed that for some corner cases, the +value of "data_src" was pointing to wrong value. This resulted +in bigger size of string and causing stack check fail. + +The perf mem data source values are captured in the sample via +isa207_get_mem_data_src function. The initial check is to fetch +the type of sampled instruction. If the type of instruction is +not valid (not a load/store instruction), the function returns. + +Since 'commit e16fd7f2cb1a ("perf: Use sample_flags for data_src")', +data_src field is not initialized by the perf_sample_data_init() +function. If the PMU driver doesn't set the data_src value to zero if +type is not valid, this will result in uninitailised value for data_src. +The uninitailised value of data_src resulted in stack check fail +followed by abort for "perf mem report". + +When requesting for data source information in the sample, the +instruction type is expected to be load or store instruction. +In ISA v3.0, due to hardware limitation, there are corner cases +where the instruction type other than load or store is observed. +In ISA v3.0 and before values "0" and "7" are considered reserved. +In ISA v3.1, value "7" has been used to indicate "larx/stcx". +Drop the sample if instruction type has reserved values for this +field with a ISA version check. Initialize data_src to zero in +isa207_get_mem_data_src if the instruction type is not load/store. + +Reported-by: Disha Goel +Signed-off-by: Athira Rajeev +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250121131621.39054-1-atrajeev@linux.vnet.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/perf/core-book3s.c | 20 ++++++++++++++++++++ + arch/powerpc/perf/isa207-common.c | 4 +++- + 2 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c +index 10b946e9c6e75..4bb84dc4393fc 100644 +--- a/arch/powerpc/perf/core-book3s.c ++++ b/arch/powerpc/perf/core-book3s.c +@@ -2229,6 +2229,10 @@ static struct pmu power_pmu = { + #define PERF_SAMPLE_ADDR_TYPE (PERF_SAMPLE_ADDR | \ + PERF_SAMPLE_PHYS_ADDR | \ + PERF_SAMPLE_DATA_PAGE_SIZE) ++ ++#define SIER_TYPE_SHIFT 15 ++#define SIER_TYPE_MASK (0x7ull << SIER_TYPE_SHIFT) ++ + /* + * A counter has overflowed; update its count and record + * things if requested. Note that interrupts are hard-disabled +@@ -2297,6 +2301,22 @@ static void record_and_restart(struct perf_event *event, unsigned long val, + is_kernel_addr(mfspr(SPRN_SIAR))) + record = 0; + ++ /* ++ * SIER[46-48] presents instruction type of the sampled instruction. ++ * In ISA v3.0 and before values "0" and "7" are considered reserved. ++ * In ISA v3.1, value "7" has been used to indicate "larx/stcx". ++ * Drop the sample if "type" has reserved values for this field with a ++ * ISA version check. ++ */ ++ if (event->attr.sample_type & PERF_SAMPLE_DATA_SRC && ++ ppmu->get_mem_data_src) { ++ val = (regs->dar & SIER_TYPE_MASK) >> SIER_TYPE_SHIFT; ++ if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) { ++ record = 0; ++ atomic64_inc(&event->lost_samples); ++ } ++ } ++ + /* + * Finally record data if requested. + */ +diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c +index 56301b2bc8ae8..031a2b63c171d 100644 +--- a/arch/powerpc/perf/isa207-common.c ++++ b/arch/powerpc/perf/isa207-common.c +@@ -321,8 +321,10 @@ void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags, + + sier = mfspr(SPRN_SIER); + val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; +- if (val != 1 && val != 2 && !(val == 7 && cpu_has_feature(CPU_FTR_ARCH_31))) ++ if (val != 1 && val != 2 && !(val == 7 && cpu_has_feature(CPU_FTR_ARCH_31))) { ++ dsrc->val = 0; + return; ++ } + + idx = (sier & ISA207_SIER_LDST_MASK) >> ISA207_SIER_LDST_SHIFT; + sub_idx = (sier & ISA207_SIER_DATA_SRC_MASK) >> ISA207_SIER_DATA_SRC_SHIFT; +-- +2.39.5 + diff --git a/queue-6.6/arm-at91-pm-fix-at91_suspend_finish-for-zq-calibrati.patch b/queue-6.6/arm-at91-pm-fix-at91_suspend_finish-for-zq-calibrati.patch new file mode 100644 index 0000000000..500c8d12cd --- /dev/null +++ b/queue-6.6/arm-at91-pm-fix-at91_suspend_finish-for-zq-calibrati.patch @@ -0,0 +1,90 @@ +From 0133c50e8482d94769e10af1dff495ea8d32d833 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 08:51:56 -0700 +Subject: ARM: at91: pm: fix at91_suspend_finish for ZQ calibration + +From: Li Bin + +[ Upstream commit bc4722c3598d0e2c2dbf9609a3d3198993093e2b ] + +For sama7g5 and sama7d65 backup mode, we encountered a "ZQ calibrate error" +during recalibrating the impedance in BootStrap. +We found that the impedance value saved in at91_suspend_finish() before +the DDR entered self-refresh mode did not match the resistor values. The +ZDATA field in the DDR3PHY_ZQ0CR0 register uses a modified gray code to +select the different impedance setting. +But these gray code are incorrect, a workaournd from design team fixed the +bug in the calibration logic. The ZDATA contains four independent impedance +elements, but the algorithm combined the four elements into one. The elements +were fixed using properly shifted offsets. + +Signed-off-by: Li Bin +[nicolas.ferre@microchip.com: fix indentation and combine 2 patches] +Signed-off-by: Nicolas Ferre +Tested-by: Ryan Wanner +Tested-by: Durai Manickam KR +Tested-by: Andrei Simion +Signed-off-by: Ryan Wanner +Link: https://lore.kernel.org/r/28b33f9bcd0ca60ceba032969fe054d38f2b9577.1740671156.git.Ryan.Wanner@microchip.com +Signed-off-by: Claudiu Beznea +Signed-off-by: Sasha Levin +--- + arch/arm/mach-at91/pm.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 22ecaf09d00f9..f635ad29511f6 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -538,11 +538,12 @@ extern u32 at91_pm_suspend_in_sram_sz; + + static int at91_suspend_finish(unsigned long val) + { +- unsigned char modified_gray_code[] = { +- 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05, 0x0c, 0x0d, +- 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09, 0x18, 0x19, 0x1a, 0x1b, +- 0x1e, 0x1f, 0x1c, 0x1d, 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, +- 0x10, 0x11, ++ /* SYNOPSYS workaround to fix a bug in the calibration logic */ ++ unsigned char modified_fix_code[] = { ++ 0x00, 0x01, 0x01, 0x06, 0x07, 0x0c, 0x06, 0x07, 0x0b, 0x18, ++ 0x0a, 0x0b, 0x0c, 0x0d, 0x0d, 0x0a, 0x13, 0x13, 0x12, 0x13, ++ 0x14, 0x15, 0x15, 0x12, 0x18, 0x19, 0x19, 0x1e, 0x1f, 0x14, ++ 0x1e, 0x1f, + }; + unsigned int tmp, index; + int i; +@@ -553,25 +554,25 @@ static int at91_suspend_finish(unsigned long val) + * restore the ZQ0SR0 with the value saved here. But the + * calibration is buggy and restoring some values from ZQ0SR0 + * is forbidden and risky thus we need to provide processed +- * values for these (modified gray code values). ++ * values for these. + */ + tmp = readl(soc_pm.data.ramc_phy + DDR3PHY_ZQ0SR0); + + /* Store pull-down output impedance select. */ + index = (tmp >> DDR3PHY_ZQ0SR0_PDO_OFF) & 0x1f; +- soc_pm.bu->ddr_phy_calibration[0] = modified_gray_code[index]; ++ soc_pm.bu->ddr_phy_calibration[0] = modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDO_OFF; + + /* Store pull-up output impedance select. */ + index = (tmp >> DDR3PHY_ZQ0SR0_PUO_OFF) & 0x1f; +- soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; ++ soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PUO_OFF; + + /* Store pull-down on-die termination impedance select. */ + index = (tmp >> DDR3PHY_ZQ0SR0_PDODT_OFF) & 0x1f; +- soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; ++ soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDODT_OFF; + + /* Store pull-up on-die termination impedance select. */ + index = (tmp >> DDR3PHY_ZQ0SRO_PUODT_OFF) & 0x1f; +- soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; ++ soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SRO_PUODT_OFF; + + /* + * The 1st 8 words of memory might get corrupted in the process +-- +2.39.5 + diff --git a/queue-6.6/arm-tegra-switch-dsi-b-clock-parent-to-plld-on-tegra.patch b/queue-6.6/arm-tegra-switch-dsi-b-clock-parent-to-plld-on-tegra.patch new file mode 100644 index 0000000000..2139f23b38 --- /dev/null +++ b/queue-6.6/arm-tegra-switch-dsi-b-clock-parent-to-plld-on-tegra.patch @@ -0,0 +1,36 @@ +From 6d93c7caf7ab48e6b1030c92b7ad31488520afd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 12:56:11 +0200 +Subject: ARM: tegra: Switch DSI-B clock parent to PLLD on Tegra114 + +From: Svyatoslav Ryhel + +[ Upstream commit 2b3db788f2f614b875b257cdb079adadedc060f3 ] + +PLLD is usually used as parent clock for internal video devices, like +DSI for example, while PLLD2 is used as parent for HDMI. + +Signed-off-by: Svyatoslav Ryhel +Link: https://lore.kernel.org/r/20250226105615.61087-3-clamor95@gmail.com +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/nvidia/tegra114.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/nvidia/tegra114.dtsi b/arch/arm/boot/dts/nvidia/tegra114.dtsi +index 86f14e2fd29f3..6c057b5069514 100644 +--- a/arch/arm/boot/dts/nvidia/tegra114.dtsi ++++ b/arch/arm/boot/dts/nvidia/tegra114.dtsi +@@ -139,7 +139,7 @@ dsib: dsi@54400000 { + reg = <0x54400000 0x00040000>; + clocks = <&tegra_car TEGRA114_CLK_DSIB>, + <&tegra_car TEGRA114_CLK_DSIBLP>, +- <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>; ++ <&tegra_car TEGRA114_CLK_PLL_D_OUT0>; + clock-names = "dsi", "lp", "parent"; + resets = <&tegra_car 82>; + reset-names = "dsi"; +-- +2.39.5 + diff --git a/queue-6.6/arm64-add-support-for-hip09-spectre-bhb-mitigation.patch b/queue-6.6/arm64-add-support-for-hip09-spectre-bhb-mitigation.patch new file mode 100644 index 0000000000..84aec5734e --- /dev/null +++ b/queue-6.6/arm64-add-support-for-hip09-spectre-bhb-mitigation.patch @@ -0,0 +1,58 @@ +From bfee44514d63e3414628a5a5a7b55235e0feb63d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Mar 2025 22:19:00 +0800 +Subject: arm64: Add support for HIP09 Spectre-BHB mitigation + +From: Jinqian Yang + +[ Upstream commit e18c09b204e81702ea63b9f1a81ab003b72e3174 ] + +The HIP09 processor is vulnerable to the Spectre-BHB (Branch History +Buffer) attack, which can be exploited to leak information through +branch prediction side channels. This commit adds the MIDR of HIP09 +to the list for software mitigation. + +Signed-off-by: Jinqian Yang +Link: https://lore.kernel.org/r/20250325141900.2057314-1-yangjinqian1@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/cputype.h | 2 ++ + arch/arm64/kernel/proton-pack.c | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h +index 8a6b7feca3e42..d92a0203e5a93 100644 +--- a/arch/arm64/include/asm/cputype.h ++++ b/arch/arm64/include/asm/cputype.h +@@ -132,6 +132,7 @@ + #define FUJITSU_CPU_PART_A64FX 0x001 + + #define HISI_CPU_PART_TSV110 0xD01 ++#define HISI_CPU_PART_HIP09 0xD02 + + #define APPLE_CPU_PART_M1_ICESTORM 0x022 + #define APPLE_CPU_PART_M1_FIRESTORM 0x023 +@@ -208,6 +209,7 @@ + #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) + #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) + #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) ++#define MIDR_HISI_HIP09 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP09) + #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) + #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) + #define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) +diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c +index 28c48bc9c0953..2c81e0efaf378 100644 +--- a/arch/arm64/kernel/proton-pack.c ++++ b/arch/arm64/kernel/proton-pack.c +@@ -904,6 +904,7 @@ static u8 spectre_bhb_loop_affected(void) + MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + MIDR_ALL_VERSIONS(MIDR_QCOM_KRYO_4XX_GOLD), ++ MIDR_ALL_VERSIONS(MIDR_HISI_HIP09), + {}, + }; + static const struct midr_range spectre_bhb_k11_list[] = { +-- +2.39.5 + diff --git a/queue-6.6/arm64-mm-check-pud_type_table-in-pud_bad.patch b/queue-6.6/arm64-mm-check-pud_type_table-in-pud_bad.patch new file mode 100644 index 0000000000..723df80ca1 --- /dev/null +++ b/queue-6.6/arm64-mm-check-pud_type_table-in-pud_bad.patch @@ -0,0 +1,49 @@ +From 2043e0395f1db3cccdf7d8c914956185e2614fdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Feb 2025 10:12:25 +0530 +Subject: arm64/mm: Check PUD_TYPE_TABLE in pud_bad() + +From: Ryan Roberts + +[ Upstream commit bfb1d2b9021c21891427acc86eb848ccedeb274e ] + +pud_bad() is currently defined in terms of pud_table(). Although for some +configs, pud_table() is hard-coded to true i.e. when using 64K base pages +or when page table levels are less than 3. + +pud_bad() is intended to check that the pud is configured correctly. Hence +let's open-code the same check that the full version of pud_table() uses +into pud_bad(). Then it always performs the check regardless of the config. + +Cc: Will Deacon +Cc: Ard Biesheuvel +Cc: Ryan Roberts +Cc: Mark Rutland +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Ryan Roberts +Signed-off-by: Anshuman Khandual +Link: https://lore.kernel.org/r/20250221044227.1145393-7-anshuman.khandual@arm.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/pgtable.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h +index 07bdf5dd8ebef..0212129b13d07 100644 +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -679,7 +679,8 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) + pr_err("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e)) + + #define pud_none(pud) (!pud_val(pud)) +-#define pud_bad(pud) (!pud_table(pud)) ++#define pud_bad(pud) ((pud_val(pud) & PUD_TYPE_MASK) != \ ++ PUD_TYPE_TABLE) + #define pud_present(pud) pte_present(pud_pte(pud)) + #define pud_leaf(pud) (pud_present(pud) && !pud_table(pud)) + #define pud_valid(pud) pte_valid(pud_pte(pud)) +-- +2.39.5 + diff --git a/queue-6.6/arm64-tegra-p2597-fix-gpio-for-vdd-1v8-dis-regulator.patch b/queue-6.6/arm64-tegra-p2597-fix-gpio-for-vdd-1v8-dis-regulator.patch new file mode 100644 index 0000000000..a7299bb24d --- /dev/null +++ b/queue-6.6/arm64-tegra-p2597-fix-gpio-for-vdd-1v8-dis-regulator.patch @@ -0,0 +1,37 @@ +From 1238c7bc064512a376ef384b342c0cf16e19dd1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 12:17:36 +0000 +Subject: arm64: tegra: p2597: Fix gpio for vdd-1v8-dis regulator + +From: Diogo Ivo + +[ Upstream commit f34621f31e3be81456c903287f7e4c0609829e29 ] + +According to the board schematics the enable pin of this regulator is +connected to gpio line #9 of the first instance of the TCA9539 +GPIO expander, so adjust it. + +Signed-off-by: Diogo Ivo +Link: https://lore.kernel.org/r/20250224-diogo-gpio_exp-v1-1-80fb84ac48c6@tecnico.ulisboa.pt +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +index b4a1108c2dd74..0639f5ce1bd9e 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +@@ -1635,7 +1635,7 @@ vdd_1v8_dis: regulator-vdd-1v8-dis { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +- gpio = <&exp1 14 GPIO_ACTIVE_HIGH>; ++ gpio = <&exp1 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_1v8>; + }; +-- +2.39.5 + diff --git a/queue-6.6/arm64-tegra-resize-aperture-for-the-igx-pcie-c5-slot.patch b/queue-6.6/arm64-tegra-resize-aperture-for-the-igx-pcie-c5-slot.patch new file mode 100644 index 0000000000..f66de50e6c --- /dev/null +++ b/queue-6.6/arm64-tegra-resize-aperture-for-the-igx-pcie-c5-slot.patch @@ -0,0 +1,48 @@ +From 24481eaec769675c3d98a5458f1e73968b233384 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jan 2025 15:19:03 +0000 +Subject: arm64: tegra: Resize aperture for the IGX PCIe C5 slot + +From: Jon Hunter + +[ Upstream commit 6d4bfe6d86af1ef52bdb4592c9afb2037f24f2c4 ] + +Some discrete graphics cards such as the NVIDIA RTX A6000 support +resizable BARs. When connecting an A6000 card to the NVIDIA IGX Orin +platform, resizing the BAR1 aperture to 8GB fails because the current +device-tree configuration for the PCIe C5 slot cannot support this. +Fix this by updating the device-tree 'reg' and 'ranges' properties for +the PCIe C5 slot to support this. + +Signed-off-by: Jon Hunter +Link: https://lore.kernel.org/r/20250116151903.476047-1-jonathanh@nvidia.com +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + .../boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts +index bac611d735c58..2fa48972b2a91 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts ++++ b/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts +@@ -102,6 +102,16 @@ pcie@14160000 { + }; + + pcie@141a0000 { ++ reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ ++ 0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */ ++ 0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ ++ 0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */ ++ 0x2e 0x20000000 0x0 0x10000000>; /* ECAM (256MB) */ ++ ++ ranges = <0x81000000 0x00 0x3a100000 0x00 0x3a100000 0x0 0x00100000 /* downstream I/O (1MB) */ ++ 0x82000000 0x00 0x40000000 0x2e 0x30000000 0x0 0x08000000 /* non-prefetchable memory (128MB) */ ++ 0xc3000000 0x28 0x00000000 0x28 0x00000000 0x6 0x20000000>; /* prefetchable memory (25088MB) */ ++ + status = "okay"; + vddio-pex-ctl-supply = <&vdd_1v8_ls>; + phys = <&p2u_nvhs_0>, <&p2u_nvhs_1>, <&p2u_nvhs_2>, +-- +2.39.5 + diff --git a/queue-6.6/arm64-zynqmp-add-clock-output-names-property-in-cloc.patch b/queue-6.6/arm64-zynqmp-add-clock-output-names-property-in-cloc.patch new file mode 100644 index 0000000000..924751e403 --- /dev/null +++ b/queue-6.6/arm64-zynqmp-add-clock-output-names-property-in-cloc.patch @@ -0,0 +1,80 @@ +From 66810bad516cb09ae9437b62e2c6ebf188248da7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 01:57:12 -0800 +Subject: arm64: zynqmp: add clock-output-names property in clock nodes + +From: Naman Trivedi + +[ Upstream commit 385a59e7f7fb3438466a0712cc14672c708bbd57 ] + +Add clock-output-names property to clock nodes, so that the resulting +clock name do not change when clock node name is changed. +Also, replace underscores with hyphens in the clock node names as per +dt-schema rule. + +Signed-off-by: Naman Trivedi +Acked-by: Senthil Nathan Thangaraj +Link: https://lore.kernel.org/r/20241122095712.1166883-1-naman.trivedimanojbhai@amd.com +Signed-off-by: Michal Simek +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi +index ccaca29200bb9..995bd8ce9d43a 100644 +--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi ++++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi +@@ -10,39 +10,44 @@ + + #include + / { +- pss_ref_clk: pss_ref_clk { ++ pss_ref_clk: pss-ref-clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; ++ clock-output-names = "pss_ref_clk"; + }; + +- video_clk: video_clk { ++ video_clk: video-clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; ++ clock-output-names = "video_clk"; + }; + +- pss_alt_ref_clk: pss_alt_ref_clk { ++ pss_alt_ref_clk: pss-alt-ref-clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; ++ clock-output-names = "pss_alt_ref_clk"; + }; + +- gt_crx_ref_clk: gt_crx_ref_clk { ++ gt_crx_ref_clk: gt-crx-ref-clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <108000000>; ++ clock-output-names = "gt_crx_ref_clk"; + }; + +- aux_ref_clk: aux_ref_clk { ++ aux_ref_clk: aux-ref-clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; ++ clock-output-names = "aux_ref_clk"; + }; + }; + +-- +2.39.5 + diff --git a/queue-6.6/asoc-codecs-pcm3168a-allow-for-24-bit-in-provider-mo.patch b/queue-6.6/asoc-codecs-pcm3168a-allow-for-24-bit-in-provider-mo.patch new file mode 100644 index 0000000000..5bb36fd28b --- /dev/null +++ b/queue-6.6/asoc-codecs-pcm3168a-allow-for-24-bit-in-provider-mo.patch @@ -0,0 +1,40 @@ +From 258033830fe85b1818a170d7f5a7befb87aee6e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Feb 2025 15:10:43 +0100 +Subject: ASoC: codecs: pcm3168a: Allow for 24-bit in provider mode + +From: Cezary Rojewski + +[ Upstream commit 7d92a38d67e5d937b64b20aa4fd14451ee1772f3 ] + +As per codec device specification, 24-bit is allowed in provider mode. +Update the code to reflect that. + +Signed-off-by: Cezary Rojewski +Link: https://patch.msgid.link/20250203141051.2361323-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/pcm3168a.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c +index 9d6431338fb71..329549936bd5c 100644 +--- a/sound/soc/codecs/pcm3168a.c ++++ b/sound/soc/codecs/pcm3168a.c +@@ -494,9 +494,9 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, + } + break; + case 24: +- if (provider_mode || (format == SND_SOC_DAIFMT_DSP_A) || +- (format == SND_SOC_DAIFMT_DSP_B)) { +- dev_err(component->dev, "24-bit slots not supported in provider mode, or consumer mode using DSP\n"); ++ if (!provider_mode && ((format == SND_SOC_DAIFMT_DSP_A) || ++ (format == SND_SOC_DAIFMT_DSP_B))) { ++ dev_err(component->dev, "24-bit slots not supported in consumer mode using DSP\n"); + return -EINVAL; + } + break; +-- +2.39.5 + diff --git a/queue-6.6/asoc-cs42l43-disable-headphone-clamps-during-type-de.patch b/queue-6.6/asoc-cs42l43-disable-headphone-clamps-during-type-de.patch new file mode 100644 index 0000000000..7573c58280 --- /dev/null +++ b/queue-6.6/asoc-cs42l43-disable-headphone-clamps-during-type-de.patch @@ -0,0 +1,50 @@ +From c7639f3a43009a3c26870cfd1e2b7b41d7128ed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 10:09:44 +0100 +Subject: ASoC: cs42l43: Disable headphone clamps during type detection + +From: Charles Keepax + +[ Upstream commit 70ad2e6bd180f94be030aef56e59693e36d945f3 ] + +The headphone clamps cause fairly loud pops during type detect +because they sink current from the detection process itself. Disable +the clamps whilst the type detect runs, to improve the detection +pop performance. + +Signed-off-by: Charles Keepax +Link: https://patch.msgid.link/20250423090944.1504538-1-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/cs42l43-jack.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c +index 0b8e88b19888e..6d8455c1bee6d 100644 +--- a/sound/soc/codecs/cs42l43-jack.c ++++ b/sound/soc/codecs/cs42l43-jack.c +@@ -642,6 +642,10 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv) + + reinit_completion(&priv->type_detect); + ++ regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL, ++ CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK, ++ CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK); ++ + cs42l43_start_hs_bias(priv, true); + regmap_update_bits(cs42l43->regmap, CS42L43_HS2, + CS42L43_HSDET_MODE_MASK, 0x3 << CS42L43_HSDET_MODE_SHIFT); +@@ -653,6 +657,9 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv) + CS42L43_HSDET_MODE_MASK, 0x2 << CS42L43_HSDET_MODE_SHIFT); + cs42l43_stop_hs_bias(priv); + ++ regmap_update_bits(cs42l43->regmap, CS42L43_STEREO_MIC_CLAMP_CTRL, ++ CS42L43_SMIC_HPAMP_CLAMP_DIS_FRC_VAL_MASK, 0); ++ + if (!time_left) + return -ETIMEDOUT; + +-- +2.39.5 + diff --git a/queue-6.6/asoc-imx-card-adjust-over-allocation-of-memory-in-im.patch b/queue-6.6/asoc-imx-card-adjust-over-allocation-of-memory-in-im.patch new file mode 100644 index 0000000000..97c01632b4 --- /dev/null +++ b/queue-6.6/asoc-imx-card-adjust-over-allocation-of-memory-in-im.patch @@ -0,0 +1,40 @@ +From 6872ccb9524fbbe820a4928a02886a8ea76ed284 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 6 Apr 2025 16:08:54 -0500 +Subject: ASoC: imx-card: Adjust over allocation of memory in + imx_card_parse_of() + +From: Chenyuan Yang + +[ Upstream commit a9a69c3b38c89d7992fb53db4abb19104b531d32 ] + +Incorrect types are used as sizeof() arguments in devm_kcalloc(). +It should be sizeof(dai_link_data) for link_data instead of +sizeof(snd_soc_dai_link). + +This is found by our static analysis tool. + +Signed-off-by: Chenyuan Yang +Link: https://patch.msgid.link/20250406210854.149316-1-chenyuan0y@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/imx-card.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c +index 7128bcf3a743e..bb304de5cc38a 100644 +--- a/sound/soc/fsl/imx-card.c ++++ b/sound/soc/fsl/imx-card.c +@@ -517,7 +517,7 @@ static int imx_card_parse_of(struct imx_card_data *data) + if (!card->dai_link) + return -ENOMEM; + +- data->link_data = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL); ++ data->link_data = devm_kcalloc(dev, num_links, sizeof(*link_data), GFP_KERNEL); + if (!data->link_data) + return -ENOMEM; + +-- +2.39.5 + diff --git a/queue-6.6/asoc-intel-bytcr_rt5640-add-dmi-quirk-for-acer-aspir.patch b/queue-6.6/asoc-intel-bytcr_rt5640-add-dmi-quirk-for-acer-aspir.patch new file mode 100644 index 0000000000..4f77a970c3 --- /dev/null +++ b/queue-6.6/asoc-intel-bytcr_rt5640-add-dmi-quirk-for-acer-aspir.patch @@ -0,0 +1,48 @@ +From 37863cbe135c936a6773c5ae1bf910cc568a4f97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 20 Apr 2025 10:56:59 +0200 +Subject: ASoC: Intel: bytcr_rt5640: Add DMI quirk for Acer Aspire SW3-013 + +From: Takashi Iwai + +[ Upstream commit a549b927ea3f5e50b1394209b64e6e17e31d4db8 ] + +Acer Aspire SW3-013 requires the very same quirk as other Acer Aspire +model for making it working. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220011 +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20250420085716.12095-1-tiwai@suse.de +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/boards/bytcr_rt5640.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c +index ce80adc30fe94..6a85e8fdcae64 100644 +--- a/sound/soc/intel/boards/bytcr_rt5640.c ++++ b/sound/soc/intel/boards/bytcr_rt5640.c +@@ -576,6 +576,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), + }, ++ { /* Acer Aspire SW3-013 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-013"), ++ }, ++ .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | ++ BYT_RT5640_JD_SRC_JD2_IN4N | ++ BYT_RT5640_OVCD_TH_2000UA | ++ BYT_RT5640_OVCD_SF_0P75 | ++ BYT_RT5640_DIFF_MIC | ++ BYT_RT5640_SSP0_AIF1 | ++ BYT_RT5640_MCLK_EN), ++ }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +-- +2.39.5 + diff --git a/queue-6.6/asoc-mediatek-mt6359-add-stub-for-mt6359_accdet_enab.patch b/queue-6.6/asoc-mediatek-mt6359-add-stub-for-mt6359_accdet_enab.patch new file mode 100644 index 0000000000..afd07a4f3e --- /dev/null +++ b/queue-6.6/asoc-mediatek-mt6359-add-stub-for-mt6359_accdet_enab.patch @@ -0,0 +1,48 @@ +From 3676e19ef08c735eb7de027a0308c439a92c5dd5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 16:52:17 -0300 +Subject: ASoC: mediatek: mt6359: Add stub for mt6359_accdet_enable_jack_detect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nícolas F. R. A. Prado + +[ Upstream commit 0116a7d84b32537a10d9bea1fd1bfc06577ef527 ] + +Add a stub for mt6359_accdet_enable_jack_detect() to prevent linker +failures in the machine sound drivers calling it when +CONFIG_SND_SOC_MT6359_ACCDET is not enabled. + +Suggested-by: AngeloGioacchino Del Regno +Signed-off-by: Nícolas F. R. A. Prado +Link: https://patch.msgid.link/20250306-mt8188-accdet-v3-3-7828e835ff4b@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/mt6359-accdet.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sound/soc/codecs/mt6359-accdet.h b/sound/soc/codecs/mt6359-accdet.h +index c234f2f4276a1..78ada3a5bfae5 100644 +--- a/sound/soc/codecs/mt6359-accdet.h ++++ b/sound/soc/codecs/mt6359-accdet.h +@@ -123,6 +123,15 @@ struct mt6359_accdet { + struct workqueue_struct *jd_workqueue; + }; + ++#if IS_ENABLED(CONFIG_SND_SOC_MT6359_ACCDET) + int mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack); ++#else ++static inline int ++mt6359_accdet_enable_jack_detect(struct snd_soc_component *component, ++ struct snd_soc_jack *jack) ++{ ++ return -EOPNOTSUPP; ++} ++#endif + #endif +-- +2.39.5 + diff --git a/queue-6.6/asoc-mediatek-mt8188-add-reference-for-dmic-clocks.patch b/queue-6.6/asoc-mediatek-mt8188-add-reference-for-dmic-clocks.patch new file mode 100644 index 0000000000..fd47e58f90 --- /dev/null +++ b/queue-6.6/asoc-mediatek-mt8188-add-reference-for-dmic-clocks.patch @@ -0,0 +1,68 @@ +From 957d71e66d7ac1c2167ac4f0483a1999f8609e0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 11:33:48 -0300 +Subject: ASoC: mediatek: mt8188: Add reference for dmic clocks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nícolas F. R. A. Prado + +[ Upstream commit bf1800073f4d55f08191b034c86b95881e99b6fd ] + +Add the names for the dmic clocks, aud_afe_dmic* and aud_dmic_hires*, so +they can be acquired and enabled by the platform driver. + +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20250225-genio700-dmic-v2-2-3076f5b50ef7@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 8 ++++++++ + sound/soc/mediatek/mt8188/mt8188-afe-clk.h | 8 ++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c +index e69c1bb2cb239..7f411b8577823 100644 +--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c ++++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c +@@ -58,7 +58,15 @@ static const char *aud_clks[MT8188_CLK_NUM] = { + [MT8188_CLK_AUD_ADC] = "aud_adc", + [MT8188_CLK_AUD_DAC_HIRES] = "aud_dac_hires", + [MT8188_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp", ++ [MT8188_CLK_AUD_AFE_DMIC1] = "aud_afe_dmic1", ++ [MT8188_CLK_AUD_AFE_DMIC2] = "aud_afe_dmic2", ++ [MT8188_CLK_AUD_AFE_DMIC3] = "aud_afe_dmic3", ++ [MT8188_CLK_AUD_AFE_DMIC4] = "aud_afe_dmic4", + [MT8188_CLK_AUD_ADC_HIRES] = "aud_adc_hires", ++ [MT8188_CLK_AUD_DMIC_HIRES1] = "aud_dmic_hires1", ++ [MT8188_CLK_AUD_DMIC_HIRES2] = "aud_dmic_hires2", ++ [MT8188_CLK_AUD_DMIC_HIRES3] = "aud_dmic_hires3", ++ [MT8188_CLK_AUD_DMIC_HIRES4] = "aud_dmic_hires4", + [MT8188_CLK_AUD_I2SIN] = "aud_i2sin", + [MT8188_CLK_AUD_TDM_IN] = "aud_tdm_in", + [MT8188_CLK_AUD_I2S_OUT] = "aud_i2s_out", +diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h +index ec53c171c170a..c6c78d684f3ee 100644 +--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h ++++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h +@@ -54,7 +54,15 @@ enum { + MT8188_CLK_AUD_ADC, + MT8188_CLK_AUD_DAC_HIRES, + MT8188_CLK_AUD_A1SYS_HP, ++ MT8188_CLK_AUD_AFE_DMIC1, ++ MT8188_CLK_AUD_AFE_DMIC2, ++ MT8188_CLK_AUD_AFE_DMIC3, ++ MT8188_CLK_AUD_AFE_DMIC4, + MT8188_CLK_AUD_ADC_HIRES, ++ MT8188_CLK_AUD_DMIC_HIRES1, ++ MT8188_CLK_AUD_DMIC_HIRES2, ++ MT8188_CLK_AUD_DMIC_HIRES3, ++ MT8188_CLK_AUD_DMIC_HIRES4, + MT8188_CLK_AUD_I2SIN, + MT8188_CLK_AUD_TDM_IN, + MT8188_CLK_AUD_I2S_OUT, +-- +2.39.5 + diff --git a/queue-6.6/asoc-mediatek-mt8188-treat-dmic_gainx_cur-as-non-vol.patch b/queue-6.6/asoc-mediatek-mt8188-treat-dmic_gainx_cur-as-non-vol.patch new file mode 100644 index 0000000000..c9665ca3fc --- /dev/null +++ b/queue-6.6/asoc-mediatek-mt8188-treat-dmic_gainx_cur-as-non-vol.patch @@ -0,0 +1,55 @@ +From 89b1f3a1a07993cb2a27da6f42da05ae3ba654dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 11:33:49 -0300 +Subject: ASoC: mediatek: mt8188: Treat DMIC_GAINx_CUR as non-volatile +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Nícolas F. R. A. Prado + +[ Upstream commit 7d87bde21c73731ddaf15e572020f80999c38ee3 ] + +The DMIC_GAINx_CUR registers contain the current (as in present) gain of +each DMIC. During capture, this gain will ramp up until a target value +is reached, and therefore the register is volatile since it is updated +automatically by hardware. + +However, after capture the register's value returns to the value that +was written to it. So reading these registers returns the current gain, +and writing configures the initial gain for every capture. + +>From an audio configuration perspective, reading the instantaneous gain +is not really useful. Instead, reading back the initial gain that was +configured is the desired behavior. For that reason, consider the +DMIC_GAINx_CUR registers as non-volatile, so the regmap's cache can be +used to retrieve the values, rather than requiring pm runtime resuming +the device. + +Signed-off-by: Nícolas F. R. A. Prado +Reviewed-by: AngeloGioacchino Del Regno +Link: https://patch.msgid.link/20250225-genio700-dmic-v2-3-3076f5b50ef7@collabora.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +index 11f30b183520f..4a304bffef8ba 100644 +--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c ++++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +@@ -2855,10 +2855,6 @@ static bool mt8188_is_volatile_reg(struct device *dev, unsigned int reg) + case AFE_DMIC3_SRC_DEBUG_MON0: + case AFE_DMIC3_UL_SRC_MON0: + case AFE_DMIC3_UL_SRC_MON1: +- case DMIC_GAIN1_CUR: +- case DMIC_GAIN2_CUR: +- case DMIC_GAIN3_CUR: +- case DMIC_GAIN4_CUR: + case ETDM_IN1_MONITOR: + case ETDM_IN2_MONITOR: + case ETDM_OUT1_MONITOR: +-- +2.39.5 + diff --git a/queue-6.6/asoc-ops-enforce-platform-maximum-on-initial-value.patch b/queue-6.6/asoc-ops-enforce-platform-maximum-on-initial-value.patch new file mode 100644 index 0000000000..fa95e24c3e --- /dev/null +++ b/queue-6.6/asoc-ops-enforce-platform-maximum-on-initial-value.patch @@ -0,0 +1,75 @@ +From d8229d452d59735e77ea2dc7018dcd95c5bb50f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Feb 2025 00:57:22 +0000 +Subject: ASoC: ops: Enforce platform maximum on initial value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin PoviÅ¡er + +[ Upstream commit 783db6851c1821d8b983ffb12b99c279ff64f2ee ] + +Lower the volume if it is violating the platform maximum at its initial +value (i.e. at the time of the 'snd_soc_limit_volume' call). + +Signed-off-by: Martin PoviÅ¡er +[Cherry picked from the Asahi kernel with fixups -- broonie] +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20250208-asoc-volume-limit-v1-1-b98fcf4cdbad@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-ops.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c +index b4cfc34d00ee6..eff1355cc3df0 100644 +--- a/sound/soc/soc-ops.c ++++ b/sound/soc/soc-ops.c +@@ -638,6 +638,33 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, + } + EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); + ++static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) ++{ ++ struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; ++ struct snd_ctl_elem_value uctl; ++ int ret; ++ ++ if (!mc->platform_max) ++ return 0; ++ ++ ret = kctl->get(kctl, &uctl); ++ if (ret < 0) ++ return ret; ++ ++ if (uctl.value.integer.value[0] > mc->platform_max) ++ uctl.value.integer.value[0] = mc->platform_max; ++ ++ if (snd_soc_volsw_is_stereo(mc) && ++ uctl.value.integer.value[1] > mc->platform_max) ++ uctl.value.integer.value[1] = mc->platform_max; ++ ++ ret = kctl->put(kctl, &uctl); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ + /** + * snd_soc_limit_volume - Set new limit to an existing volume control. + * +@@ -662,7 +689,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card, + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; + if (max <= mc->max - mc->min) { + mc->platform_max = max; +- ret = 0; ++ ret = snd_soc_clip_to_platform_max(kctl); + } + } + return ret; +-- +2.39.5 + diff --git a/queue-6.6/asoc-qcom-sm8250-explicitly-set-format-in-sm8250_be_.patch b/queue-6.6/asoc-qcom-sm8250-explicitly-set-format-in-sm8250_be_.patch new file mode 100644 index 0000000000..fb5f8f591a --- /dev/null +++ b/queue-6.6/asoc-qcom-sm8250-explicitly-set-format-in-sm8250_be_.patch @@ -0,0 +1,49 @@ +From 5cb3068115564d985957e2be3e875ed397fbdfab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Feb 2025 16:14:30 +0000 +Subject: ASoC: qcom: sm8250: explicitly set format in + sm8250_be_hw_params_fixup() + +From: Alexey Klimov + +[ Upstream commit 89be3c15a58b2ccf31e969223c8ac93ca8932d81 ] + +Setting format to s16le is required for compressed playback on compatible +soundcards. + +Cc: Srinivas Kandagatla +Signed-off-by: Alexey Klimov +Link: https://patch.msgid.link/20250228161430.373961-1-alexey.klimov@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/qcom/sm8250.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c +index 88a7169336d61..580eb20b0771a 100644 +--- a/sound/soc/qcom/sm8250.c ++++ b/sound/soc/qcom/sm8250.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -39,9 +40,11 @@ static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); ++ struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + rate->min = rate->max = 48000; + channels->min = channels->max = 2; ++ snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/asoc-rt722-sdca-add-some-missing-readable-registers.patch b/queue-6.6/asoc-rt722-sdca-add-some-missing-readable-registers.patch new file mode 100644 index 0000000000..ca18e18e9e --- /dev/null +++ b/queue-6.6/asoc-rt722-sdca-add-some-missing-readable-registers.patch @@ -0,0 +1,98 @@ +From f51a885a51b846d5643b1917ed894a5b322b7600 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jan 2025 15:44:07 +0000 +Subject: ASoC: rt722-sdca: Add some missing readable registers + +From: Charles Keepax + +[ Upstream commit f9a5c4b6afc79073491acdab7f1e943ee3a19fbb ] + +Add a few missing registers from the readable register callback. + +Suggested-by: Shuming Fan +Signed-off-by: Charles Keepax +Reviewed-by: Pierre-Louis Bossart +Link: https://patch.msgid.link/20250107154408.814455-6-ckeepax@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/rt722-sdca-sdw.c | 49 +++++++++++++++++++++++++++++-- + 1 file changed, 46 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c +index c382cb6be6025..c0bb1b4b2dcb5 100644 +--- a/sound/soc/codecs/rt722-sdca-sdw.c ++++ b/sound/soc/codecs/rt722-sdca-sdw.c +@@ -28,9 +28,50 @@ static bool rt722_sdca_readable_register(struct device *dev, unsigned int reg) + 0): + case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_GE49, RT722_SDCA_CTL_DETECTED_MODE, + 0): +- case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, +- 0) ... SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, +- RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU03, RT722_SDCA_CTL_SELECTED_MODE, ++ 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, ++ RT722_SDCA_CTL_FU_MUTE, CH_L) ... ++ SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU05, ++ RT722_SDCA_CTL_FU_MUTE, CH_R): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_XU0D, ++ RT722_SDCA_CTL_SELECTED_MODE, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, ++ RT722_SDCA_CTL_FU_MUTE, CH_L) ... ++ SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_USER_FU0F, ++ RT722_SDCA_CTL_FU_MUTE, CH_R): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE40, ++ RT722_SDCA_CTL_REQ_POWER_STATE, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_PDE12, ++ RT722_SDCA_CTL_REQ_POWER_STATE, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS01, ++ RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT722_SDCA_ENT_CS11, ++ RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, ++ RT722_SDCA_CTL_FU_MUTE, CH_01) ... ++ SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_USER_FU1E, ++ RT722_SDCA_CTL_FU_MUTE, CH_04): ++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_IT26, ++ RT722_SDCA_CTL_VENDOR_DEF, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_PDE2A, ++ RT722_SDCA_CTL_REQ_POWER_STATE, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT722_SDCA_ENT_CS1F, ++ RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, ++ RT722_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ... ++ SDW_SDCA_CTL(FUNC_NUM_HID, RT722_SDCA_ENT_HID01, ++ RT722_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, ++ RT722_SDCA_CTL_FU_MUTE, CH_L) ... ++ SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_USER_FU06, ++ RT722_SDCA_CTL_FU_MUTE, CH_R): ++ case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_OT23, ++ RT722_SDCA_CTL_VENDOR_DEF, CH_08): ++ case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_PDE23, ++ RT722_SDCA_CTL_REQ_POWER_STATE, 0): ++ case SDW_SDCA_CTL(FUNC_NUM_AMP, RT722_SDCA_ENT_CS31, ++ RT722_SDCA_CTL_SAMPLE_FREQ_INDEX, 0): + case RT722_BUF_ADDR_HID1 ... RT722_BUF_ADDR_HID2: + return true; + default: +@@ -74,6 +115,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re + case 0x5600000 ... 0x5600007: + case 0x5700000 ... 0x5700004: + case 0x5800000 ... 0x5800004: ++ case 0x5810000: + case 0x5b00003: + case 0x5c00011: + case 0x5d00006: +@@ -81,6 +123,7 @@ static bool rt722_sdca_mbq_readable_register(struct device *dev, unsigned int re + case 0x5f00030: + case 0x6100000 ... 0x6100051: + case 0x6100055 ... 0x6100057: ++ case 0x6100060: + case 0x6100062: + case 0x6100064 ... 0x6100065: + case 0x6100067: +-- +2.39.5 + diff --git a/queue-6.6/asoc-soc-dai-check-return-value-at-snd_soc_dai_set_t.patch b/queue-6.6/asoc-soc-dai-check-return-value-at-snd_soc_dai_set_t.patch new file mode 100644 index 0000000000..e0d78ad101 --- /dev/null +++ b/queue-6.6/asoc-soc-dai-check-return-value-at-snd_soc_dai_set_t.patch @@ -0,0 +1,54 @@ +From 7f4b21142926371cef869e6157e69ab9a27fd972 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 02:24:38 +0000 +Subject: ASoC: soc-dai: check return value at snd_soc_dai_set_tdm_slot() + +From: Kuninori Morimoto + +[ Upstream commit 7f1186a8d738661b941b298fd6d1d5725ed71428 ] + +snd_soc_dai_set_tdm_slot() calls .xlate_tdm_slot_mask() or +snd_soc_xlate_tdm_slot_mask(), but didn't check its return value. +Let's check it. + +This patch might break existing driver. In such case, let's makes +each func to void instead of int. + +Signed-off-by: Kuninori Morimoto +Link: https://patch.msgid.link/87o6z7yk61.wl-kuninori.morimoto.gx@renesas.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-dai.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c +index 9a828e55c4f9e..507743c87e402 100644 +--- a/sound/soc/soc-dai.c ++++ b/sound/soc/soc-dai.c +@@ -275,10 +275,11 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, + + if (dai->driver->ops && + dai->driver->ops->xlate_tdm_slot_mask) +- dai->driver->ops->xlate_tdm_slot_mask(slots, +- &tx_mask, &rx_mask); ++ ret = dai->driver->ops->xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); + else +- snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); ++ ret = snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); ++ if (ret) ++ goto err; + + for_each_pcm_streams(stream) + snd_soc_dai_tdm_mask_set(dai, stream, *tdm_mask[stream]); +@@ -287,6 +288,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, + dai->driver->ops->set_tdm_slot) + ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, + slots, slot_width); ++err: + return soc_dai_ret(dai, ret); + } + EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); +-- +2.39.5 + diff --git a/queue-6.6/asoc-sun4i-codec-support-hp-det-gpios-property.patch b/queue-6.6/asoc-sun4i-codec-support-hp-det-gpios-property.patch new file mode 100644 index 0000000000..18aeb95f51 --- /dev/null +++ b/queue-6.6/asoc-sun4i-codec-support-hp-det-gpios-property.patch @@ -0,0 +1,128 @@ +From c9db55070f0c220ea5706f0cbee66e73ed61e23c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Feb 2025 11:02:25 +1300 +Subject: ASoC: sun4i-codec: support hp-det-gpios property + +From: Ryan Walklin + +[ Upstream commit a149377c033afe6557c50892ebbfc0e8b7e2e253 ] + +Add support for GPIO headphone detection with the hp-det-gpios +property. In order for this to properly disable the path upon +removal of headphones, the output must be labelled Headphone which +is a common sink in the driver. + +Describe a headphone jack and detection GPIO in the driver, check for +a corresponding device tree node, and enable jack detection in a new +machine init function if described. + +Signed-off-by: Chris Morgan +Signed-off-by: Ryan Walklin + +-- +Changelog v1..v2: +- Separate DAPM changes into separate patch and add rationale. + +Tested-by: Philippe Simons +Link: https://patch.msgid.link/20250214220247.10810-4-ryan@testtoast.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sunxi/sun4i-codec.c | 53 +++++++++++++++++++++++++++++++++++ + 1 file changed, 53 insertions(+) + +diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c +index f0a5fd9011018..0d7758cc84c63 100644 +--- a/sound/soc/sunxi/sun4i-codec.c ++++ b/sound/soc/sunxi/sun4i-codec.c +@@ -25,6 +25,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -239,6 +240,7 @@ struct sun4i_codec { + struct clk *clk_module; + struct reset_control *rst; + struct gpio_desc *gpio_pa; ++ struct gpio_desc *gpio_hp; + + /* ADC_FIFOC register is at different offset on different SoCs */ + struct regmap_field *reg_adc_fifoc; +@@ -1277,6 +1279,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = { + .ops = &dummy_dai_ops, + }; + ++static struct snd_soc_jack sun4i_headphone_jack; ++ ++static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = { ++ { .pin = "Headphone", .mask = SND_JACK_HEADPHONE }, ++}; ++ ++static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = { ++ .name = "hp-det", ++ .report = SND_JACK_HEADPHONE, ++ .debounce_time = 150, ++}; ++ ++static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_card *card = rtd->card; ++ struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); ++ int ret; ++ ++ if (scodec->gpio_hp) { ++ ret = snd_soc_card_jack_new_pins(card, "Headphone Jack", ++ SND_JACK_HEADPHONE, ++ &sun4i_headphone_jack, ++ sun4i_headphone_jack_pins, ++ ARRAY_SIZE(sun4i_headphone_jack_pins)); ++ if (ret) { ++ dev_err(rtd->dev, ++ "Headphone jack creation failed: %d\n", ret); ++ return ret; ++ } ++ ++ sun4i_headphone_jack_gpio.desc = scodec->gpio_hp; ++ ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1, ++ &sun4i_headphone_jack_gpio); ++ ++ if (ret) { ++ dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ + static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, + int *num_links) + { +@@ -1302,6 +1347,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, + link->codecs->name = dev_name(dev); + link->platforms->name = dev_name(dev); + link->dai_fmt = SND_SOC_DAIFMT_I2S; ++ link->init = sun4i_codec_machine_init; + + *num_links = 1; + +@@ -1742,6 +1788,13 @@ static int sun4i_codec_probe(struct platform_device *pdev) + return ret; + } + ++ scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN); ++ if (IS_ERR(scodec->gpio_hp)) { ++ ret = PTR_ERR(scodec->gpio_hp); ++ dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n"); ++ return ret; ++ } ++ + /* reg_field setup */ + scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev, + scodec->regmap, +-- +2.39.5 + diff --git a/queue-6.6/asoc-tas2764-add-reg-defaults-for-tas2764_int_clk_cf.patch b/queue-6.6/asoc-tas2764-add-reg-defaults-for-tas2764_int_clk_cf.patch new file mode 100644 index 0000000000..a86fe0bb7f --- /dev/null +++ b/queue-6.6/asoc-tas2764-add-reg-defaults-for-tas2764_int_clk_cf.patch @@ -0,0 +1,33 @@ +From f2aa0051dfd4eb19b14a630f64ba5850fa15b6da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Feb 2025 01:03:27 +0000 +Subject: ASoC: tas2764: Add reg defaults for TAS2764_INT_CLK_CFG + +From: Hector Martin + +[ Upstream commit d64c4c3d1c578f98d70db1c5e2535b47adce9d07 ] + +Signed-off-by: Hector Martin +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-4-dbab892a69b5@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2764.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index e87a07eee9737..4e5381c07f504 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -636,6 +636,7 @@ static const struct reg_default tas2764_reg_defaults[] = { + { TAS2764_TDM_CFG2, 0x0a }, + { TAS2764_TDM_CFG3, 0x10 }, + { TAS2764_TDM_CFG5, 0x42 }, ++ { TAS2764_INT_CLK_CFG, 0x19 }, + }; + + static const struct regmap_range_cfg tas2764_regmap_ranges[] = { +-- +2.39.5 + diff --git a/queue-6.6/asoc-tas2764-mark-sw_reset-as-volatile.patch b/queue-6.6/asoc-tas2764-mark-sw_reset-as-volatile.patch new file mode 100644 index 0000000000..e67483c5ea --- /dev/null +++ b/queue-6.6/asoc-tas2764-mark-sw_reset-as-volatile.patch @@ -0,0 +1,35 @@ +From 2c1e98f0ad18e8ead4874d30e9b922aff8bbbae1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Feb 2025 01:03:26 +0000 +Subject: ASoC: tas2764: Mark SW_RESET as volatile + +From: Hector Martin + +[ Upstream commit f37f1748564ac51d32f7588bd7bfc99913ccab8e ] + +Since the bit is self-clearing. + +Signed-off-by: Hector Martin +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-3-dbab892a69b5@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2764.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index 4e5381c07f504..3f622d629f77a 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -654,6 +654,7 @@ static const struct regmap_range_cfg tas2764_regmap_ranges[] = { + static bool tas2764_volatile_register(struct device *dev, unsigned int reg) + { + switch (reg) { ++ case TAS2764_SW_RST: + case TAS2764_INT_LTCH0 ... TAS2764_INT_LTCH4: + case TAS2764_INT_CLK_CFG: + return true; +-- +2.39.5 + diff --git a/queue-6.6/asoc-tas2764-power-up-down-amp-on-mute-ops.patch b/queue-6.6/asoc-tas2764-power-up-down-amp-on-mute-ops.patch new file mode 100644 index 0000000000..73b2f4f375 --- /dev/null +++ b/queue-6.6/asoc-tas2764-power-up-down-amp-on-mute-ops.patch @@ -0,0 +1,108 @@ +From bdf160bd3bac0069ff6d1a4e58acd51f26def1eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Feb 2025 01:03:24 +0000 +Subject: ASoC: tas2764: Power up/down amp on mute ops + +From: Hector Martin + +[ Upstream commit 1c3b5f37409682184669457a5bdf761268eafbe5 ] + +The ASoC convention is that clocks are removed after codec mute, and +power up/down is more about top level power management. For these chips, +the "mute" state still expects a TDM clock, and yanking the clock in +this state will trigger clock errors. So, do the full +shutdown<->mute<->active transition on the mute operation, so the amp is +in software shutdown by the time the clocks are removed. + +This fixes TDM clock errors when streams are stopped. + +Signed-off-by: Hector Martin +Signed-off-by: Mark Brown +Link: https://patch.msgid.link/20250208-asoc-tas2764-v1-1-dbab892a69b5@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2764.c | 51 ++++++++++++++++---------------------- + 1 file changed, 21 insertions(+), 30 deletions(-) + +diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c +index 3f622d629f77a..72d6356b89814 100644 +--- a/sound/soc/codecs/tas2764.c ++++ b/sound/soc/codecs/tas2764.c +@@ -182,33 +182,6 @@ static SOC_ENUM_SINGLE_DECL( + static const struct snd_kcontrol_new tas2764_asi1_mux = + SOC_DAPM_ENUM("ASI1 Source", tas2764_ASI1_src_enum); + +-static int tas2764_dac_event(struct snd_soc_dapm_widget *w, +- struct snd_kcontrol *kcontrol, int event) +-{ +- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); +- struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component); +- int ret; +- +- switch (event) { +- case SND_SOC_DAPM_POST_PMU: +- tas2764->dac_powered = true; +- ret = tas2764_update_pwr_ctrl(tas2764); +- break; +- case SND_SOC_DAPM_PRE_PMD: +- tas2764->dac_powered = false; +- ret = tas2764_update_pwr_ctrl(tas2764); +- break; +- default: +- dev_err(tas2764->dev, "Unsupported event\n"); +- return -EINVAL; +- } +- +- if (ret < 0) +- return ret; +- +- return 0; +-} +- + static const struct snd_kcontrol_new isense_switch = + SOC_DAPM_SINGLE("Switch", TAS2764_PWR_CTRL, TAS2764_ISENSE_POWER_EN, 1, 1); + static const struct snd_kcontrol_new vsense_switch = +@@ -221,8 +194,7 @@ static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = { + 1, &isense_switch), + SND_SOC_DAPM_SWITCH("VSENSE", TAS2764_PWR_CTRL, TAS2764_VSENSE_POWER_EN, + 1, &vsense_switch), +- SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2764_dac_event, +- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), ++ SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_OUTPUT("OUT"), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON") +@@ -243,9 +215,28 @@ static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction) + { + struct tas2764_priv *tas2764 = + snd_soc_component_get_drvdata(dai->component); ++ int ret; ++ ++ if (!mute) { ++ tas2764->dac_powered = true; ++ ret = tas2764_update_pwr_ctrl(tas2764); ++ if (ret) ++ return ret; ++ } + + tas2764->unmuted = !mute; +- return tas2764_update_pwr_ctrl(tas2764); ++ ret = tas2764_update_pwr_ctrl(tas2764); ++ if (ret) ++ return ret; ++ ++ if (mute) { ++ tas2764->dac_powered = false; ++ ret = tas2764_update_pwr_ctrl(tas2764); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; + } + + static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth) +-- +2.39.5 + diff --git a/queue-6.6/auxdisplay-charlcd-partially-revert-move-hwidth-and-.patch b/queue-6.6/auxdisplay-charlcd-partially-revert-move-hwidth-and-.patch new file mode 100644 index 0000000000..7a2f03e016 --- /dev/null +++ b/queue-6.6/auxdisplay-charlcd-partially-revert-move-hwidth-and-.patch @@ -0,0 +1,117 @@ +From df42620985bc6dbb22db62b835e0e013ddc625c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 19:27:38 +0200 +Subject: auxdisplay: charlcd: Partially revert "Move hwidth and bwidth to + struct hd44780_common" + +From: Andy Shevchenko + +[ Upstream commit 09965a142078080fe7807bab0f6f1890cb5987a4 ] + +Commit 2545c1c948a6 ("auxdisplay: Move hwidth and bwidth to struct +hd44780_common") makes charlcd_alloc() argument-less effectively dropping +the single allocation for the struct charlcd_priv object along with +the driver specific one. Restore that behaviour here. + +Signed-off-by: Andy Shevchenko +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/auxdisplay/charlcd.c | 5 +++-- + drivers/auxdisplay/charlcd.h | 5 +++-- + drivers/auxdisplay/hd44780.c | 2 +- + drivers/auxdisplay/lcd2s.c | 2 +- + drivers/auxdisplay/panel.c | 2 +- + 5 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c +index 6d309e4971b61..e243291a7e77c 100644 +--- a/drivers/auxdisplay/charlcd.c ++++ b/drivers/auxdisplay/charlcd.c +@@ -594,18 +594,19 @@ static int charlcd_init(struct charlcd *lcd) + return 0; + } + +-struct charlcd *charlcd_alloc(void) ++struct charlcd *charlcd_alloc(unsigned int drvdata_size) + { + struct charlcd_priv *priv; + struct charlcd *lcd; + +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ priv = kzalloc(sizeof(*priv) + drvdata_size, GFP_KERNEL); + if (!priv) + return NULL; + + priv->esc_seq.len = -1; + + lcd = &priv->lcd; ++ lcd->drvdata = priv->drvdata; + + return lcd; + } +diff --git a/drivers/auxdisplay/charlcd.h b/drivers/auxdisplay/charlcd.h +index eed80063a6d20..4bbf106b2dd8a 100644 +--- a/drivers/auxdisplay/charlcd.h ++++ b/drivers/auxdisplay/charlcd.h +@@ -49,7 +49,7 @@ struct charlcd { + unsigned long y; + } addr; + +- void *drvdata; ++ void *drvdata; /* Set by charlcd_alloc() */ + }; + + /** +@@ -93,7 +93,8 @@ struct charlcd_ops { + }; + + void charlcd_backlight(struct charlcd *lcd, enum charlcd_onoff on); +-struct charlcd *charlcd_alloc(void); ++ ++struct charlcd *charlcd_alloc(unsigned int drvdata_size); + void charlcd_free(struct charlcd *lcd); + + int charlcd_register(struct charlcd *lcd); +diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c +index 8b690f59df27d..ebaf0ff518f4c 100644 +--- a/drivers/auxdisplay/hd44780.c ++++ b/drivers/auxdisplay/hd44780.c +@@ -226,7 +226,7 @@ static int hd44780_probe(struct platform_device *pdev) + if (!hdc) + return -ENOMEM; + +- lcd = charlcd_alloc(); ++ lcd = charlcd_alloc(0); + if (!lcd) + goto fail1; + +diff --git a/drivers/auxdisplay/lcd2s.c b/drivers/auxdisplay/lcd2s.c +index 6422be0dfe20e..0ecf6a9469f24 100644 +--- a/drivers/auxdisplay/lcd2s.c ++++ b/drivers/auxdisplay/lcd2s.c +@@ -307,7 +307,7 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c) + if (err < 0) + return err; + +- lcd = charlcd_alloc(); ++ lcd = charlcd_alloc(0); + if (!lcd) + return -ENOMEM; + +diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c +index eba04c0de7eb3..0f3999b665e70 100644 +--- a/drivers/auxdisplay/panel.c ++++ b/drivers/auxdisplay/panel.c +@@ -835,7 +835,7 @@ static void lcd_init(void) + if (!hdc) + return; + +- charlcd = charlcd_alloc(); ++ charlcd = charlcd_alloc(0); + if (!charlcd) { + kfree(hdc); + return; +-- +2.39.5 + diff --git a/queue-6.6/bonding-report-duplicate-mac-address-in-all-situatio.patch b/queue-6.6/bonding-report-duplicate-mac-address-in-all-situatio.patch new file mode 100644 index 0000000000..8342bedb4b --- /dev/null +++ b/queue-6.6/bonding-report-duplicate-mac-address-in-all-situatio.patch @@ -0,0 +1,47 @@ +From e6020f481a854cf3d7558e993aedd5833a75ccd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 03:39:14 +0000 +Subject: bonding: report duplicate MAC address in all situations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hangbin Liu + +[ Upstream commit 28d68d396a1cd21591e8c6d74afbde33a7ea107e ] + +Normally, a bond uses the MAC address of the first added slave as the bond’s +MAC address. And the bond will set active slave’s MAC address to bond’s +address if fail_over_mac is set to none (0) or follow (2). + +When the first slave is removed, the bond will still use the removed slave’s +MAC address, which can lead to a duplicate MAC address and potentially cause +issues with the switch. To avoid confusion, let's warn the user in all +situations, including when fail_over_mac is set to 2 or not in active-backup +mode. + +Signed-off-by: Hangbin Liu +Reviewed-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20250225033914.18617-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 7eb62fe55947f..56c241246d1af 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2469,7 +2469,7 @@ static int __bond_release_one(struct net_device *bond_dev, + + RCU_INIT_POINTER(bond->current_arp_slave, NULL); + +- if (!all && (!bond->params.fail_over_mac || ++ if (!all && (bond->params.fail_over_mac != BOND_FOM_ACTIVE || + BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)) { + if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && + bond_has_slaves(bond)) +-- +2.39.5 + diff --git a/queue-6.6/book3s64-radix-fix-compile-errors-when-config_arch_w.patch b/queue-6.6/book3s64-radix-fix-compile-errors-when-config_arch_w.patch new file mode 100644 index 0000000000..32b23482fe --- /dev/null +++ b/queue-6.6/book3s64-radix-fix-compile-errors-when-config_arch_w.patch @@ -0,0 +1,45 @@ +From 8ee4a3c22842a5a20d61fc60fa15fc563ffd6a96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 07:44:09 -0500 +Subject: book3s64/radix: Fix compile errors when + CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=n + +From: Ritesh Harjani (IBM) + +[ Upstream commit 29bdc1f1c1df80868fb35bc69d1f073183adc6de ] + +Fix compile errors when CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=n + +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Donet Tom +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/8231763344223c193e3452eab0ae8ea966aff466.1741609795.git.donettom@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/radix_pgtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c +index 28460e3340808..aff3b37e32d64 100644 +--- a/arch/powerpc/mm/book3s64/radix_pgtable.c ++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c +@@ -912,7 +912,7 @@ int __meminit radix__vmemmap_create_mapping(unsigned long start, + return 0; + } + +- ++#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP + bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) + { + if (radix_enabled()) +@@ -920,6 +920,7 @@ bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap) + + return false; + } ++#endif + + int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node, + unsigned long addr, unsigned long next) +-- +2.39.5 + diff --git a/queue-6.6/bpf-allow-pre-ordering-for-bpf-cgroup-progs.patch b/queue-6.6/bpf-allow-pre-ordering-for-bpf-cgroup-progs.patch new file mode 100644 index 0000000000..15423ad77f --- /dev/null +++ b/queue-6.6/bpf-allow-pre-ordering-for-bpf-cgroup-progs.patch @@ -0,0 +1,223 @@ +From 5d03a36a8da42bc3e736232734d80b64e7208171 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 15:01:16 -0800 +Subject: bpf: Allow pre-ordering for bpf cgroup progs + +From: Yonghong Song + +[ Upstream commit 4b82b181a26cff8bf7adc3a85a88d121d92edeaf ] + +Currently for bpf progs in a cgroup hierarchy, the effective prog array +is computed from bottom cgroup to upper cgroups (post-ordering). For +example, the following cgroup hierarchy + root cgroup: p1, p2 + subcgroup: p3, p4 +have BPF_F_ALLOW_MULTI for both cgroup levels. +The effective cgroup array ordering looks like + p3 p4 p1 p2 +and at run time, progs will execute based on that order. + +But in some cases, it is desirable to have root prog executes earlier than +children progs (pre-ordering). For example, + - prog p1 intends to collect original pkt dest addresses. + - prog p3 will modify original pkt dest addresses to a proxy address for + security reason. +The end result is that prog p1 gets proxy address which is not what it +wants. Putting p1 to every child cgroup is not desirable either as it +will duplicate itself in many child cgroups. And this is exactly a use case +we are encountering in Meta. + +To fix this issue, let us introduce a flag BPF_F_PREORDER. If the flag +is specified at attachment time, the prog has higher priority and the +ordering with that flag will be from top to bottom (pre-ordering). +For example, in the above example, + root cgroup: p1, p2 + subcgroup: p3, p4 +Let us say p2 and p4 are marked with BPF_F_PREORDER. The final +effective array ordering will be + p2 p4 p3 p1 + +Suggested-by: Andrii Nakryiko +Acked-by: Andrii Nakryiko +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20250224230116.283071-1-yonghong.song@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/bpf-cgroup.h | 1 + + include/uapi/linux/bpf.h | 1 + + kernel/bpf/cgroup.c | 33 +++++++++++++++++++++++++-------- + kernel/bpf/syscall.c | 3 ++- + tools/include/uapi/linux/bpf.h | 1 + + 5 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h +index d4f2c8706042c..2331cd8174fe3 100644 +--- a/include/linux/bpf-cgroup.h ++++ b/include/linux/bpf-cgroup.h +@@ -106,6 +106,7 @@ struct bpf_prog_list { + struct bpf_prog *prog; + struct bpf_cgroup_link *link; + struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]; ++ u32 flags; + }; + + int cgroup_bpf_inherit(struct cgroup *cgrp); +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 431bc700bcfb9..c7f904a72af21 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -1140,6 +1140,7 @@ enum bpf_perf_event_type { + #define BPF_F_BEFORE (1U << 3) + #define BPF_F_AFTER (1U << 4) + #define BPF_F_ID (1U << 5) ++#define BPF_F_PREORDER (1U << 6) + #define BPF_F_LINK BPF_F_LINK /* 1 << 13 */ + + /* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the +diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c +index cf2eb0895d403..684fb450ad086 100644 +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -369,7 +369,7 @@ static struct bpf_prog *prog_list_prog(struct bpf_prog_list *pl) + /* count number of elements in the list. + * it's slow but the list cannot be long + */ +-static u32 prog_list_length(struct hlist_head *head) ++static u32 prog_list_length(struct hlist_head *head, int *preorder_cnt) + { + struct bpf_prog_list *pl; + u32 cnt = 0; +@@ -377,6 +377,8 @@ static u32 prog_list_length(struct hlist_head *head) + hlist_for_each_entry(pl, head, node) { + if (!prog_list_prog(pl)) + continue; ++ if (preorder_cnt && (pl->flags & BPF_F_PREORDER)) ++ (*preorder_cnt)++; + cnt++; + } + return cnt; +@@ -400,7 +402,7 @@ static bool hierarchy_allows_attach(struct cgroup *cgrp, + + if (flags & BPF_F_ALLOW_MULTI) + return true; +- cnt = prog_list_length(&p->bpf.progs[atype]); ++ cnt = prog_list_length(&p->bpf.progs[atype], NULL); + WARN_ON_ONCE(cnt > 1); + if (cnt == 1) + return !!(flags & BPF_F_ALLOW_OVERRIDE); +@@ -423,12 +425,12 @@ static int compute_effective_progs(struct cgroup *cgrp, + struct bpf_prog_array *progs; + struct bpf_prog_list *pl; + struct cgroup *p = cgrp; +- int cnt = 0; ++ int i, j, cnt = 0, preorder_cnt = 0, fstart, bstart, init_bstart; + + /* count number of effective programs by walking parents */ + do { + if (cnt == 0 || (p->bpf.flags[atype] & BPF_F_ALLOW_MULTI)) +- cnt += prog_list_length(&p->bpf.progs[atype]); ++ cnt += prog_list_length(&p->bpf.progs[atype], &preorder_cnt); + p = cgroup_parent(p); + } while (p); + +@@ -439,20 +441,34 @@ static int compute_effective_progs(struct cgroup *cgrp, + /* populate the array with effective progs */ + cnt = 0; + p = cgrp; ++ fstart = preorder_cnt; ++ bstart = preorder_cnt - 1; + do { + if (cnt > 0 && !(p->bpf.flags[atype] & BPF_F_ALLOW_MULTI)) + continue; + ++ init_bstart = bstart; + hlist_for_each_entry(pl, &p->bpf.progs[atype], node) { + if (!prog_list_prog(pl)) + continue; + +- item = &progs->items[cnt]; ++ if (pl->flags & BPF_F_PREORDER) { ++ item = &progs->items[bstart]; ++ bstart--; ++ } else { ++ item = &progs->items[fstart]; ++ fstart++; ++ } + item->prog = prog_list_prog(pl); + bpf_cgroup_storages_assign(item->cgroup_storage, + pl->storage); + cnt++; + } ++ ++ /* reverse pre-ordering progs at this cgroup level */ ++ for (i = bstart + 1, j = init_bstart; i < j; i++, j--) ++ swap(progs->items[i], progs->items[j]); ++ + } while ((p = cgroup_parent(p))); + + *array = progs; +@@ -663,7 +679,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, + */ + return -EPERM; + +- if (prog_list_length(progs) >= BPF_CGROUP_MAX_PROGS) ++ if (prog_list_length(progs, NULL) >= BPF_CGROUP_MAX_PROGS) + return -E2BIG; + + pl = find_attach_entry(progs, prog, link, replace_prog, +@@ -698,6 +714,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, + + pl->prog = prog; + pl->link = link; ++ pl->flags = flags; + bpf_cgroup_storages_assign(pl->storage, storage); + cgrp->bpf.flags[atype] = saved_flags; + +@@ -1073,7 +1090,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, + lockdep_is_held(&cgroup_mutex)); + total_cnt += bpf_prog_array_length(effective); + } else { +- total_cnt += prog_list_length(&cgrp->bpf.progs[atype]); ++ total_cnt += prog_list_length(&cgrp->bpf.progs[atype], NULL); + } + } + +@@ -1105,7 +1122,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, + u32 id; + + progs = &cgrp->bpf.progs[atype]; +- cnt = min_t(int, prog_list_length(progs), total_cnt); ++ cnt = min_t(int, prog_list_length(progs, NULL), total_cnt); + i = 0; + hlist_for_each_entry(pl, progs, node) { + prog = prog_list_prog(pl); +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 5a8c5a4ef1134..b66349f892f25 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -3900,7 +3900,8 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog, + #define BPF_F_ATTACH_MASK_BASE \ + (BPF_F_ALLOW_OVERRIDE | \ + BPF_F_ALLOW_MULTI | \ +- BPF_F_REPLACE) ++ BPF_F_REPLACE | \ ++ BPF_F_PREORDER) + + #define BPF_F_ATTACH_MASK_MPROG \ + (BPF_F_REPLACE | \ +diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h +index 977ec094bc2a6..2a90f04a4160d 100644 +--- a/tools/include/uapi/linux/bpf.h ++++ b/tools/include/uapi/linux/bpf.h +@@ -1140,6 +1140,7 @@ enum bpf_perf_event_type { + #define BPF_F_BEFORE (1U << 3) + #define BPF_F_AFTER (1U << 4) + #define BPF_F_ID (1U << 5) ++#define BPF_F_PREORDER (1U << 6) + #define BPF_F_LINK BPF_F_LINK /* 1 << 13 */ + + /* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the +-- +2.39.5 + diff --git a/queue-6.6/bpf-don-t-do-clean_live_states-when-state-loop_entry.patch b/queue-6.6/bpf-don-t-do-clean_live_states-when-state-loop_entry.patch new file mode 100644 index 0000000000..665c6cbab1 --- /dev/null +++ b/queue-6.6/bpf-don-t-do-clean_live_states-when-state-loop_entry.patch @@ -0,0 +1,104 @@ +From 20079251800433dcfb241d6ab60b9a8c69a8f0ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Feb 2025 03:03:54 -0800 +Subject: bpf: don't do clean_live_states when state->loop_entry->branches > 0 + +From: Eduard Zingerman + +[ Upstream commit 9e63fdb0cbdf3268c86638a8274f4d5549a82820 ] + +verifier.c:is_state_visited() uses RANGE_WITHIN states comparison rules +for cached states that have loop_entry with non-zero branches count +(meaning that loop_entry's verification is not yet done). + +The RANGE_WITHIN rules in regsafe()/stacksafe() require register and +stack objects types to be identical in current and old states. + +verifier.c:clean_live_states() replaces registers and stack spills +with NOT_INIT/STACK_INVALID marks, if these registers/stack spills are +not read in any child state. This means that clean_live_states() works +against loop convergence logic under some conditions. See selftest in +the next patch for a specific example. + +Mitigate this by prohibiting clean_verifier_state() when +state->loop_entry->branches > 0. + +This undoes negative verification performance impact of the +copy_verifier_state() fix from the previous patch. +Below is comparison between master and current patch. + +selftests: + +File Program Insns (A) Insns (B) Insns (DIFF) States (A) States (B) States (DIFF) +---------------------------------- ---------------------------- --------- --------- --------------- ---------- ---------- -------------- +arena_htab.bpf.o arena_htab_llvm 717 423 -294 (-41.00%) 57 37 -20 (-35.09%) +arena_htab_asm.bpf.o arena_htab_asm 597 445 -152 (-25.46%) 47 37 -10 (-21.28%) +arena_list.bpf.o arena_list_add 1493 1822 +329 (+22.04%) 30 37 +7 (+23.33%) +arena_list.bpf.o arena_list_del 309 261 -48 (-15.53%) 23 15 -8 (-34.78%) +iters.bpf.o checkpoint_states_deletion 18125 22154 +4029 (+22.23%) 818 918 +100 (+12.22%) +iters.bpf.o iter_nested_deeply_iters 593 367 -226 (-38.11%) 67 43 -24 (-35.82%) +iters.bpf.o iter_nested_iters 813 772 -41 (-5.04%) 79 72 -7 (-8.86%) +iters.bpf.o iter_subprog_check_stacksafe 155 135 -20 (-12.90%) 15 14 -1 (-6.67%) +iters.bpf.o iter_subprog_iters 1094 808 -286 (-26.14%) 88 68 -20 (-22.73%) +iters.bpf.o loop_state_deps2 479 356 -123 (-25.68%) 46 35 -11 (-23.91%) +iters.bpf.o triple_continue 35 31 -4 (-11.43%) 3 3 +0 (+0.00%) +kmem_cache_iter.bpf.o open_coded_iter 63 59 -4 (-6.35%) 7 6 -1 (-14.29%) +mptcp_subflow.bpf.o _getsockopt_subflow 501 446 -55 (-10.98%) 25 23 -2 (-8.00%) +pyperf600_iter.bpf.o on_event 12339 6379 -5960 (-48.30%) 441 286 -155 (-35.15%) +verifier_bits_iter.bpf.o max_words 92 84 -8 (-8.70%) 8 7 -1 (-12.50%) +verifier_iterating_callbacks.bpf.o cond_break2 113 192 +79 (+69.91%) 12 21 +9 (+75.00%) + +sched_ext: + +File Program Insns (A) Insns (B) Insns (DIFF) States (A) States (B) States (DIFF) +----------------- ---------------------- --------- --------- ----------------- ---------- ---------- ---------------- +bpf.bpf.o layered_dispatch 11485 9039 -2446 (-21.30%) 848 662 -186 (-21.93%) +bpf.bpf.o layered_dump 7422 5022 -2400 (-32.34%) 681 298 -383 (-56.24%) +bpf.bpf.o layered_enqueue 16854 13753 -3101 (-18.40%) 1611 1308 -303 (-18.81%) +bpf.bpf.o layered_init 1000001 5549 -994452 (-99.45%) 84672 523 -84149 (-99.38%) +bpf.bpf.o layered_runnable 3149 1899 -1250 (-39.70%) 288 151 -137 (-47.57%) +bpf.bpf.o p2dq_init 2343 1936 -407 (-17.37%) 201 170 -31 (-15.42%) +bpf.bpf.o refresh_layer_cpumasks 16487 1285 -15202 (-92.21%) 1770 120 -1650 (-93.22%) +bpf.bpf.o rusty_select_cpu 1937 1386 -551 (-28.45%) 177 125 -52 (-29.38%) +scx_central.bpf.o central_dispatch 636 600 -36 (-5.66%) 63 59 -4 (-6.35%) +scx_central.bpf.o central_init 913 632 -281 (-30.78%) 48 39 -9 (-18.75%) +scx_nest.bpf.o nest_init 636 601 -35 (-5.50%) 60 58 -2 (-3.33%) +scx_pair.bpf.o pair_dispatch 1000001 1914 -998087 (-99.81%) 58169 142 -58027 (-99.76%) +scx_qmap.bpf.o qmap_dispatch 2393 2187 -206 (-8.61%) 196 174 -22 (-11.22%) +scx_qmap.bpf.o qmap_init 16367 22777 +6410 (+39.16%) 603 768 +165 (+27.36%) + +'layered_init' and 'pair_dispatch' hit 1M on master, but are verified +ok with this patch. + +Signed-off-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20250215110411.3236773-4-eddyz87@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 756e179a1efe3..1f9ae600e4455 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -16014,12 +16014,16 @@ static void clean_verifier_state(struct bpf_verifier_env *env, + static void clean_live_states(struct bpf_verifier_env *env, int insn, + struct bpf_verifier_state *cur) + { ++ struct bpf_verifier_state *loop_entry; + struct bpf_verifier_state_list *sl; + + sl = *explored_state(env, insn); + while (sl) { + if (sl->state.branches) + goto next; ++ loop_entry = get_loop_entry(&sl->state); ++ if (loop_entry && loop_entry->branches) ++ goto next; + if (sl->state.insn_idx != insn || + !same_callsites(&sl->state, cur)) + goto next; +-- +2.39.5 + diff --git a/queue-6.6/bpf-fix-possible-endless-loop-in-bpf-map-iteration.patch b/queue-6.6/bpf-fix-possible-endless-loop-in-bpf-map-iteration.patch new file mode 100644 index 0000000000..58b37b7103 --- /dev/null +++ b/queue-6.6/bpf-fix-possible-endless-loop-in-bpf-map-iteration.patch @@ -0,0 +1,37 @@ +From f62cf39b8f9e2102264bbdfb75cf37bb5f9d95de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 11:32:51 -0400 +Subject: bpf: fix possible endless loop in BPF map iteration + +From: Brandon Kammerdiener + +[ Upstream commit 75673fda0c557ae26078177dd14d4857afbf128d ] + +The _safe variant used here gets the next element before running the callback, +avoiding the endless loop condition. + +Signed-off-by: Brandon Kammerdiener +Link: https://lore.kernel.org/r/20250424153246.141677-2-brandon.kammerdiener@intel.com +Signed-off-by: Alexei Starovoitov +Acked-by: Hou Tao +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index fc34f72702cc4..8a3eadf17f785 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -2212,7 +2212,7 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_ + b = &htab->buckets[i]; + rcu_read_lock(); + head = &b->head; +- hlist_nulls_for_each_entry_rcu(elem, n, head, hash_node) { ++ hlist_nulls_for_each_entry_safe(elem, n, head, hash_node) { + key = elem->key; + if (is_percpu) { + /* current cpu value for percpu map */ +-- +2.39.5 + diff --git a/queue-6.6/bpf-prevent-unsafe-access-to-the-sock-fields-in-the-.patch b/queue-6.6/bpf-prevent-unsafe-access-to-the-sock-fields-in-the-.patch new file mode 100644 index 0000000000..076cd16a64 --- /dev/null +++ b/queue-6.6/bpf-prevent-unsafe-access-to-the-sock-fields-in-the-.patch @@ -0,0 +1,150 @@ +From ab98c942f5101bee496c595eb35962df46d3ef3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 15:29:31 +0800 +Subject: bpf: Prevent unsafe access to the sock fields in the BPF timestamping + callback + +From: Jason Xing + +[ Upstream commit fd93eaffb3f977b23bc0a48d4c8616e654fcf133 ] + +The subsequent patch will implement BPF TX timestamping. It will +call the sockops BPF program without holding the sock lock. + +This breaks the current assumption that all sock ops programs will +hold the sock lock. The sock's fields of the uapi's bpf_sock_ops +requires this assumption. + +To address this, a new "u8 is_locked_tcp_sock;" field is added. This +patch sets it in the current sock_ops callbacks. The "is_fullsock" +test is then replaced by the "is_locked_tcp_sock" test during +sock_ops_convert_ctx_access(). + +The new TX timestamping callbacks added in the subsequent patch will +not have this set. This will prevent unsafe access from the new +timestamping callbacks. + +Potentially, we could allow read-only access. However, this would +require identifying which callback is read-safe-only and also requires +additional BPF instruction rewrites in the covert_ctx. Since the BPF +program can always read everything from a socket (e.g., by using +bpf_core_cast), this patch keeps it simple and disables all read +and write access to any socket fields through the bpf_sock_ops +UAPI from the new TX timestamping callback. + +Moreover, note that some of the fields in bpf_sock_ops are specific +to tcp_sock, and sock_ops currently only supports tcp_sock. In +the future, UDP timestamping will be added, which will also break +this assumption. The same idea used in this patch will be reused. +Considering that the current sock_ops only supports tcp_sock, the +variable is named is_locked_"tcp"_sock. + +Signed-off-by: Jason Xing +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250220072940.99994-4-kerneljasonxing@gmail.com +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 1 + + include/net/tcp.h | 1 + + net/core/filter.c | 8 ++++---- + net/ipv4/tcp_input.c | 2 ++ + net/ipv4/tcp_output.c | 2 ++ + 5 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index adf65eacade06..f7d03676e16fa 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -1303,6 +1303,7 @@ struct bpf_sock_ops_kern { + void *skb_data_end; + u8 op; + u8 is_fullsock; ++ u8 is_locked_tcp_sock; + u8 remaining_opt_len; + u64 temp; /* temp and everything after is not + * initialized to 0 before calling +diff --git a/include/net/tcp.h b/include/net/tcp.h +index a6def0aab3ed3..658551a64e2a5 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -2462,6 +2462,7 @@ static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args) + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); + if (sk_fullsock(sk)) { + sock_ops.is_fullsock = 1; ++ sock_ops.is_locked_tcp_sock = 1; + sock_owned_by_me(sk); + } + +diff --git a/net/core/filter.c b/net/core/filter.c +index 5143c8a9e52ca..eff342e5fd8f5 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -10300,10 +10300,10 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, + } \ + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \ + struct bpf_sock_ops_kern, \ +- is_fullsock), \ ++ is_locked_tcp_sock), \ + fullsock_reg, si->src_reg, \ + offsetof(struct bpf_sock_ops_kern, \ +- is_fullsock)); \ ++ is_locked_tcp_sock)); \ + *insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp); \ + if (si->dst_reg == si->src_reg) \ + *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg, \ +@@ -10388,10 +10388,10 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, + temp)); \ + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \ + struct bpf_sock_ops_kern, \ +- is_fullsock), \ ++ is_locked_tcp_sock), \ + reg, si->dst_reg, \ + offsetof(struct bpf_sock_ops_kern, \ +- is_fullsock)); \ ++ is_locked_tcp_sock)); \ + *insn++ = BPF_JMP_IMM(BPF_JEQ, reg, 0, 2); \ + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \ + struct bpf_sock_ops_kern, sk),\ +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index a172248b66783..4bed6f9923059 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -168,6 +168,7 @@ static void bpf_skops_parse_hdr(struct sock *sk, struct sk_buff *skb) + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); + sock_ops.op = BPF_SOCK_OPS_PARSE_HDR_OPT_CB; + sock_ops.is_fullsock = 1; ++ sock_ops.is_locked_tcp_sock = 1; + sock_ops.sk = sk; + bpf_skops_init_skb(&sock_ops, skb, tcp_hdrlen(skb)); + +@@ -184,6 +185,7 @@ static void bpf_skops_established(struct sock *sk, int bpf_op, + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); + sock_ops.op = bpf_op; + sock_ops.is_fullsock = 1; ++ sock_ops.is_locked_tcp_sock = 1; + sock_ops.sk = sk; + /* sk with TCP_REPAIR_ON does not have skb in tcp_finish_connect */ + if (skb) +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 560273e7f7736..5d3d92e5bd42e 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -522,6 +522,7 @@ static void bpf_skops_hdr_opt_len(struct sock *sk, struct sk_buff *skb, + sock_owned_by_me(sk); + + sock_ops.is_fullsock = 1; ++ sock_ops.is_locked_tcp_sock = 1; + sock_ops.sk = sk; + } + +@@ -567,6 +568,7 @@ static void bpf_skops_write_hdr_opt(struct sock *sk, struct sk_buff *skb, + sock_owned_by_me(sk); + + sock_ops.is_fullsock = 1; ++ sock_ops.is_locked_tcp_sock = 1; + sock_ops.sk = sk; + } + +-- +2.39.5 + diff --git a/queue-6.6/bpf-return-prog-btf_id-without-capable-check.patch b/queue-6.6/bpf-return-prog-btf_id-without-capable-check.patch new file mode 100644 index 0000000000..71f5eb3ee4 --- /dev/null +++ b/queue-6.6/bpf-return-prog-btf_id-without-capable-check.patch @@ -0,0 +1,47 @@ +From 6116d4cfa748f23c96c2ec0dda323be78ffa824c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Mar 2025 17:40:37 +0000 +Subject: bpf: Return prog btf_id without capable check + +From: Mykyta Yatsenko + +[ Upstream commit 07651ccda9ff10a8ca427670cdd06ce2c8e4269c ] + +Return prog's btf_id from bpf_prog_get_info_by_fd regardless of capable +check. This patch enables scenario, when freplace program, running +from user namespace, requires to query target prog's btf. + +Signed-off-by: Mykyta Yatsenko +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Link: https://lore.kernel.org/bpf/20250317174039.161275-3-mykyta.yatsenko5@gmail.com +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index f089a61630111..5a8c5a4ef1134 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -4442,6 +4442,8 @@ static int bpf_prog_get_info_by_fd(struct file *file, + info.recursion_misses = stats.misses; + + info.verified_insns = prog->aux->verified_insns; ++ if (prog->aux->btf) ++ info.btf_id = btf_obj_id(prog->aux->btf); + + if (!bpf_capable()) { + info.jited_prog_len = 0; +@@ -4588,8 +4590,6 @@ static int bpf_prog_get_info_by_fd(struct file *file, + } + } + +- if (prog->aux->btf) +- info.btf_id = btf_obj_id(prog->aux->btf); + info.attach_btf_id = prog->aux->attach_btf_id; + if (attach_btf) + info.attach_btf_obj_id = btf_obj_id(attach_btf); +-- +2.39.5 + diff --git a/queue-6.6/bpftool-fix-readlink-usage-in-get_fd_type.patch b/queue-6.6/bpftool-fix-readlink-usage-in-get_fd_type.patch new file mode 100644 index 0000000000..812def5c23 --- /dev/null +++ b/queue-6.6/bpftool-fix-readlink-usage-in-get_fd_type.patch @@ -0,0 +1,49 @@ +From a81a7fc04a8930b01513529f8e826a44bcf6d222 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jan 2025 08:18:57 +0100 +Subject: bpftool: Fix readlink usage in get_fd_type + +From: Viktor Malik + +[ Upstream commit 0053f7d39d491b6138d7c526876d13885cbb65f1 ] + +The `readlink(path, buf, sizeof(buf))` call reads at most sizeof(buf) +bytes and *does not* append null-terminator to buf. With respect to +that, fix two pieces in get_fd_type: + +1. Change the truncation check to contain sizeof(buf) rather than + sizeof(path). +2. Append null-terminator to buf. + +Reported by Coverity. + +Signed-off-by: Viktor Malik +Signed-off-by: Andrii Nakryiko +Reviewed-by: Quentin Monnet +Link: https://lore.kernel.org/bpf/20250129071857.75182-1-vmalik@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/common.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c +index 9b75639434b81..0a764426d9358 100644 +--- a/tools/bpf/bpftool/common.c ++++ b/tools/bpf/bpftool/common.c +@@ -461,10 +461,11 @@ int get_fd_type(int fd) + p_err("can't read link type: %s", strerror(errno)); + return -1; + } +- if (n == sizeof(path)) { ++ if (n == sizeof(buf)) { + p_err("can't read link type: path too long!"); + return -1; + } ++ buf[n] = '\0'; + + if (strstr(buf, "bpf-map")) + return BPF_OBJ_MAP; +-- +2.39.5 + diff --git a/queue-6.6/bridge-mdb-allow-replace-of-a-host-joined-group.patch b/queue-6.6/bridge-mdb-allow-replace-of-a-host-joined-group.patch new file mode 100644 index 0000000000..3ca8c91d7b --- /dev/null +++ b/queue-6.6/bridge-mdb-allow-replace-of-a-host-joined-group.patch @@ -0,0 +1,67 @@ +From a0331c9fd7b9cd37407e02e95bbde73f3c0517ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 18:37:15 +0100 +Subject: bridge: mdb: Allow replace of a host-joined group + +From: Petr Machata + +[ Upstream commit d9e9f6d7b7d0c520bb87f19d2cbc57aeeb2091d5 ] + +Attempts to replace an MDB group membership of the host itself are +currently bounced: + + # ip link add name br up type bridge vlan_filtering 1 + # bridge mdb replace dev br port br grp 239.0.0.1 vid 2 + # bridge mdb replace dev br port br grp 239.0.0.1 vid 2 + Error: bridge: Group is already joined by host. + +A similar operation done on a member port would succeed. Ignore the check +for replacement of host group memberships as well. + +The bit of code that this enables is br_multicast_host_join(), which, for +already-joined groups only refreshes the MC group expiration timer, which +is desirable; and a userspace notification, also desirable. + +Change a selftest that exercises this code path from expecting a rejection +to expecting a pass. The rest of MDB selftests pass without modification. + +Signed-off-by: Petr Machata +Reviewed-by: Ido Schimmel +Acked-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/e5c5188b9787ae806609e7ca3aa2a0a501b9b5c4.1738685648.git.petrm@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/bridge/br_mdb.c | 2 +- + tools/testing/selftests/net/forwarding/bridge_mdb.sh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c +index 7305f5f8215ca..96bea0c8408fe 100644 +--- a/net/bridge/br_mdb.c ++++ b/net/bridge/br_mdb.c +@@ -1030,7 +1030,7 @@ static int br_mdb_add_group(const struct br_mdb_config *cfg, + + /* host join */ + if (!port) { +- if (mp->host_joined) { ++ if (mp->host_joined && !(cfg->nlflags & NLM_F_REPLACE)) { + NL_SET_ERR_MSG_MOD(extack, "Group is already joined by host"); + return -EEXIST; + } +diff --git a/tools/testing/selftests/net/forwarding/bridge_mdb.sh b/tools/testing/selftests/net/forwarding/bridge_mdb.sh +index a3678dfe5848a..c151374ddf040 100755 +--- a/tools/testing/selftests/net/forwarding/bridge_mdb.sh ++++ b/tools/testing/selftests/net/forwarding/bridge_mdb.sh +@@ -149,7 +149,7 @@ cfg_test_host_common() + check_err $? "Failed to add $name host entry" + + bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null +- check_fail $? "Managed to replace $name host entry" ++ check_err $? "Failed to replace $name host entry" + + bridge mdb del dev br0 port br0 grp $grp $state vid 10 + bridge mdb get dev br0 grp $grp vid 10 &> /dev/null +-- +2.39.5 + diff --git a/queue-6.6/btrfs-avoid-linker-error-in-btrfs_find_create_tree_b.patch b/queue-6.6/btrfs-avoid-linker-error-in-btrfs_find_create_tree_b.patch new file mode 100644 index 0000000000..49da533c21 --- /dev/null +++ b/queue-6.6/btrfs-avoid-linker-error-in-btrfs_find_create_tree_b.patch @@ -0,0 +1,61 @@ +From 3ef42fc0c60724d7b81cb49e8efe066f10d16e07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 10:58:46 +0000 +Subject: btrfs: avoid linker error in btrfs_find_create_tree_block() + +From: Mark Harmstone + +[ Upstream commit 7ef3cbf17d2734ca66c4ed8573be45f4e461e7ee ] + +The inline function btrfs_is_testing() is hardcoded to return 0 if +CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set. Currently we're relying on +the compiler optimizing out the call to alloc_test_extent_buffer() in +btrfs_find_create_tree_block(), as it's not been defined (it's behind an + #ifdef). + +Add a stub version of alloc_test_extent_buffer() to avoid linker errors +on non-standard optimization levels. This problem was seen on GCC 14 +with -O0 and is helps to see symbols that would be otherwise optimized +out. + +Reviewed-by: Qu Wenruo +Signed-off-by: Mark Harmstone +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/extent_io.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index b2ae50dcca0fe..ed08d8e5639f5 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -3565,10 +3565,10 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, + return eb; + } + +-#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS + struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, + u64 start) + { ++#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS + struct extent_buffer *eb, *exists = NULL; + int ret; + +@@ -3604,8 +3604,11 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, + free_eb: + btrfs_release_extent_buffer(eb); + return exists; +-} ++#else ++ /* Stub to avoid linker error when compiled with optimizations turned off. */ ++ return NULL; + #endif ++} + + static struct extent_buffer *grab_extent_buffer( + struct btrfs_fs_info *fs_info, struct page *page) +-- +2.39.5 + diff --git a/queue-6.6/btrfs-avoid-null-pointer-dereference-if-no-valid-csu.patch b/queue-6.6/btrfs-avoid-null-pointer-dereference-if-no-valid-csu.patch new file mode 100644 index 0000000000..1259b0c495 --- /dev/null +++ b/queue-6.6/btrfs-avoid-null-pointer-dereference-if-no-valid-csu.patch @@ -0,0 +1,73 @@ +From b042604eb487bb285d472067fa783824851b9468 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 15:17:50 +0930 +Subject: btrfs: avoid NULL pointer dereference if no valid csum tree + +From: Qu Wenruo + +[ Upstream commit f95d186255b319c48a365d47b69bd997fecb674e ] + +[BUG] +When trying read-only scrub on a btrfs with rescue=idatacsums mount +option, it will crash with the following call trace: + + BUG: kernel NULL pointer dereference, address: 0000000000000208 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + CPU: 1 UID: 0 PID: 835 Comm: btrfs Tainted: G O 6.15.0-rc3-custom+ #236 PREEMPT(full) + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 + RIP: 0010:btrfs_lookup_csums_bitmap+0x49/0x480 [btrfs] + Call Trace: + + scrub_find_fill_first_stripe+0x35b/0x3d0 [btrfs] + scrub_simple_mirror+0x175/0x290 [btrfs] + scrub_stripe+0x5f7/0x6f0 [btrfs] + scrub_chunk+0x9a/0x150 [btrfs] + scrub_enumerate_chunks+0x333/0x660 [btrfs] + btrfs_scrub_dev+0x23e/0x600 [btrfs] + btrfs_ioctl+0x1dcf/0x2f80 [btrfs] + __x64_sys_ioctl+0x97/0xc0 + do_syscall_64+0x4f/0x120 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +[CAUSE] +Mount option "rescue=idatacsums" will completely skip loading the csum +tree, so that any data read will not find any data csum thus we will +ignore data checksum verification. + +Normally call sites utilizing csum tree will check the fs state flag +NO_DATA_CSUMS bit, but unfortunately scrub does not check that bit at all. + +This results in scrub to call btrfs_search_slot() on a NULL pointer +and triggered above crash. + +[FIX] +Check both extent and csum tree root before doing any tree search. + +Reviewed-by: Johannes Thumshirn +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index 6be092bb814fd..da49bdb70375b 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -1538,8 +1538,8 @@ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg, + u64 extent_gen; + int ret; + +- if (unlikely(!extent_root)) { +- btrfs_err(fs_info, "no valid extent root for scrub"); ++ if (unlikely(!extent_root || !csum_root)) { ++ btrfs_err(fs_info, "no valid extent or csum root for scrub"); + return -EUCLEAN; + } + memset(stripe->sectors, 0, sizeof(struct scrub_sector_verification) * +-- +2.39.5 + diff --git a/queue-6.6/btrfs-correct-the-order-of-prelim_ref-arguments-in-b.patch b/queue-6.6/btrfs-correct-the-order-of-prelim_ref-arguments-in-b.patch new file mode 100644 index 0000000000..01ff2d40a9 --- /dev/null +++ b/queue-6.6/btrfs-correct-the-order-of-prelim_ref-arguments-in-b.patch @@ -0,0 +1,82 @@ +From 453697d0ebfb49668a614ef50700aeb768d00976 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 09:25:06 -0400 +Subject: btrfs: correct the order of prelim_ref arguments in btrfs__prelim_ref + +From: Goldwyn Rodrigues + +[ Upstream commit bc7e0975093567f51be8e1bdf4aa5900a3cf0b1e ] + +btrfs_prelim_ref() calls the old and new reference variables in the +incorrect order. This causes a NULL pointer dereference because oldref +is passed as NULL to trace_btrfs_prelim_ref_insert(). + +Note, trace_btrfs_prelim_ref_insert() is being called with newref as +oldref (and oldref as NULL) on purpose in order to print out +the values of newref. + +To reproduce: +echo 1 > /sys/kernel/debug/tracing/events/btrfs/btrfs_prelim_ref_insert/enable + +Perform some writeback operations. + +Backtrace: +BUG: kernel NULL pointer dereference, address: 0000000000000018 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 115949067 P4D 115949067 PUD 11594a067 PMD 0 + Oops: Oops: 0000 [#1] SMP NOPTI + CPU: 1 UID: 0 PID: 1188 Comm: fsstress Not tainted 6.15.0-rc2-tester+ #47 PREEMPT(voluntary) 7ca2cef72d5e9c600f0c7718adb6462de8149622 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-2-gc13ff2cd-prebuilt.qemu.org 04/01/2014 + RIP: 0010:trace_event_raw_event_btrfs__prelim_ref+0x72/0x130 + Code: e8 43 81 9f ff 48 85 c0 74 78 4d 85 e4 0f 84 8f 00 00 00 49 8b 94 24 c0 06 00 00 48 8b 0a 48 89 48 08 48 8b 52 08 48 89 50 10 <49> 8b 55 18 48 89 50 18 49 8b 55 20 48 89 50 20 41 0f b6 55 28 88 + RSP: 0018:ffffce44820077a0 EFLAGS: 00010286 + RAX: ffff8c6b403f9014 RBX: ffff8c6b55825730 RCX: 304994edf9cf506b + RDX: d8b11eb7f0fdb699 RSI: ffff8c6b403f9010 RDI: ffff8c6b403f9010 + RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000010 + R10: 00000000ffffffff R11: 0000000000000000 R12: ffff8c6b4e8fb000 + R13: 0000000000000000 R14: ffffce44820077a8 R15: ffff8c6b4abd1540 + FS: 00007f4dc6813740(0000) GS:ffff8c6c1d378000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000018 CR3: 000000010eb42000 CR4: 0000000000750ef0 + PKRU: 55555554 + Call Trace: + + prelim_ref_insert+0x1c1/0x270 + find_parent_nodes+0x12a6/0x1ee0 + ? __entry_text_end+0x101f06/0x101f09 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + ? srso_alias_return_thunk+0x5/0xfbef5 + btrfs_is_data_extent_shared+0x167/0x640 + ? fiemap_process_hole+0xd0/0x2c0 + extent_fiemap+0xa5c/0xbc0 + ? __entry_text_end+0x101f05/0x101f09 + btrfs_fiemap+0x7e/0xd0 + do_vfs_ioctl+0x425/0x9d0 + __x64_sys_ioctl+0x75/0xc0 + +Signed-off-by: Goldwyn Rodrigues +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + include/trace/events/btrfs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h +index 3c4d5ef6d4463..8ea1674069fe8 100644 +--- a/include/trace/events/btrfs.h ++++ b/include/trace/events/btrfs.h +@@ -1956,7 +1956,7 @@ DECLARE_EVENT_CLASS(btrfs__prelim_ref, + TP_PROTO(const struct btrfs_fs_info *fs_info, + const struct prelim_ref *oldref, + const struct prelim_ref *newref, u64 tree_size), +- TP_ARGS(fs_info, newref, oldref, tree_size), ++ TP_ARGS(fs_info, oldref, newref, tree_size), + + TP_STRUCT__entry_btrfs( + __field( u64, root_id ) +-- +2.39.5 + diff --git a/queue-6.6/btrfs-fix-non-empty-delayed-iputs-list-on-unmount-du.patch b/queue-6.6/btrfs-fix-non-empty-delayed-iputs-list-on-unmount-du.patch new file mode 100644 index 0000000000..6418966ea7 --- /dev/null +++ b/queue-6.6/btrfs-fix-non-empty-delayed-iputs-list-on-unmount-du.patch @@ -0,0 +1,85 @@ +From cd029f6074fce8a4c34a490cb756069e7d183dae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 14:25:38 +0000 +Subject: btrfs: fix non-empty delayed iputs list on unmount due to async + workers + +From: Filipe Manana + +[ Upstream commit cda76788f8b0f7de3171100e3164ec1ce702292e ] + +At close_ctree() after we have ran delayed iputs either explicitly through +calling btrfs_run_delayed_iputs() or later during the call to +btrfs_commit_super() or btrfs_error_commit_super(), we assert that the +delayed iputs list is empty. + +We have (another) race where this assertion might fail because we have +queued an async write into the fs_info->workers workqueue. Here's how it +happens: + +1) We are submitting a data bio for an inode that is not the data + relocation inode, so we call btrfs_wq_submit_bio(); + +2) btrfs_wq_submit_bio() submits a work for the fs_info->workers queue + that will run run_one_async_done(); + +3) We enter close_ctree(), flush several work queues except + fs_info->workers, explicitly run delayed iputs with a call to + btrfs_run_delayed_iputs() and then again shortly after by calling + btrfs_commit_super() or btrfs_error_commit_super(), which also run + delayed iputs; + +4) run_one_async_done() is executed in the work queue, and because there + was an IO error (bio->bi_status is not 0) it calls btrfs_bio_end_io(), + which drops the final reference on the associated ordered extent by + calling btrfs_put_ordered_extent() - and that adds a delayed iput for + the inode; + +5) At close_ctree() we find that after stopping the cleaner and + transaction kthreads the delayed iputs list is not empty, failing the + following assertion: + + ASSERT(list_empty(&fs_info->delayed_iputs)); + +Fix this by flushing the fs_info->workers workqueue before running delayed +iputs at close_ctree(). + +David reported this when running generic/648, which exercises IO error +paths by using the DM error table. + +Reported-by: David Sterba +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 1e1650012606e..34a30d61b470c 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4341,6 +4341,19 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) + */ + btrfs_flush_workqueue(fs_info->delalloc_workers); + ++ /* ++ * We can have ordered extents getting their last reference dropped from ++ * the fs_info->workers queue because for async writes for data bios we ++ * queue a work for that queue, at btrfs_wq_submit_bio(), that runs ++ * run_one_async_done() which calls btrfs_bio_end_io() in case the bio ++ * has an error, and that later function can do the final ++ * btrfs_put_ordered_extent() on the ordered extent attached to the bio, ++ * which adds a delayed iput for the inode. So we must flush the queue ++ * so that we don't have delayed iputs after committing the current ++ * transaction below and stopping the cleaner and transaction kthreads. ++ */ ++ btrfs_flush_workqueue(fs_info->workers); ++ + /* + * When finishing a compressed write bio we schedule a work queue item + * to finish an ordered extent - btrfs_finish_compressed_write_work() +-- +2.39.5 + diff --git a/queue-6.6/btrfs-get-zone-unusable-bytes-while-holding-lock-at-.patch b/queue-6.6/btrfs-get-zone-unusable-bytes-while-holding-lock-at-.patch new file mode 100644 index 0000000000..243a91ce3c --- /dev/null +++ b/queue-6.6/btrfs-get-zone-unusable-bytes-while-holding-lock-at-.patch @@ -0,0 +1,68 @@ +From bb9af0b468113fd035012a5119031bdec4116d00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Feb 2025 16:12:15 +0000 +Subject: btrfs: get zone unusable bytes while holding lock at + btrfs_reclaim_bgs_work() + +From: Filipe Manana + +[ Upstream commit 1283b8c125a83bf7a7dbe90c33d3472b6d7bf612 ] + +At btrfs_reclaim_bgs_work(), we are grabbing a block group's zone unusable +bytes while not under the protection of the block group's spinlock, so +this can trigger race reports from KCSAN (or similar tools) since that +field is typically updated while holding the lock, such as at +__btrfs_add_free_space_zoned() for example. + +Fix this by grabbing the zone unusable bytes while we are still in the +critical section holding the block group's spinlock, which is right above +where we are currently grabbing it. + +Reviewed-by: Johannes Thumshirn +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 434cf3d5f4cf1..226e6434a58a9 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -1885,6 +1885,17 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + up_write(&space_info->groups_sem); + goto next; + } ++ ++ /* ++ * Cache the zone_unusable value before turning the block group ++ * to read only. As soon as the block group is read only it's ++ * zone_unusable value gets moved to the block group's read-only ++ * bytes and isn't available for calculations anymore. We also ++ * cache it before unlocking the block group, to prevent races ++ * (reports from KCSAN and such tools) with tasks updating it. ++ */ ++ zone_unusable = bg->zone_unusable; ++ + spin_unlock(&bg->lock); + + /* +@@ -1900,13 +1911,6 @@ void btrfs_reclaim_bgs_work(struct work_struct *work) + goto next; + } + +- /* +- * Cache the zone_unusable value before turning the block group +- * to read only. As soon as the blog group is read only it's +- * zone_unusable value gets moved to the block group's read-only +- * bytes and isn't available for calculations anymore. +- */ +- zone_unusable = bg->zone_unusable; + ret = inc_block_group_ro(bg, 0); + up_write(&space_info->groups_sem); + if (ret < 0) +-- +2.39.5 + diff --git a/queue-6.6/btrfs-make-btrfs_discard_workfn-block_group-ref-expl.patch b/queue-6.6/btrfs-make-btrfs_discard_workfn-block_group-ref-expl.patch new file mode 100644 index 0000000000..3f8a53e549 --- /dev/null +++ b/queue-6.6/btrfs-make-btrfs_discard_workfn-block_group-ref-expl.patch @@ -0,0 +1,106 @@ +From 398a36903d9787291f04b24f377018310fdbfe4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 15:01:05 -0800 +Subject: btrfs: make btrfs_discard_workfn() block_group ref explicit + +From: Boris Burkov + +[ Upstream commit 895c6721d310c036dcfebb5ab845822229fa35eb ] + +Currently, the async discard machinery owns a ref to the block_group +when the block_group is queued on a discard list. However, to handle +races with discard cancellation and the discard workfn, we have a +specific logic to detect that the block_group is *currently* running in +the workfn, to protect the workfn's usage amidst cancellation. + +As far as I can tell, this doesn't have any overt bugs (though +finish_discard_pass() and remove_from_discard_list() racing can have a +surprising outcome for the caller of remove_from_discard_list() in that +it is again added at the end). + +But it is needlessly complicated to rely on locking and the nullity of +discard_ctl->block_group. Simplify this significantly by just taking a +refcount while we are in the workfn and unconditionally drop it in both +the remove and workfn paths, regardless of if they race. + +Reviewed-by: Filipe Manana +Signed-off-by: Boris Burkov +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/discard.c | 34 ++++++++++++++++------------------ + 1 file changed, 16 insertions(+), 18 deletions(-) + +diff --git a/fs/btrfs/discard.c b/fs/btrfs/discard.c +index 944a7340f6a44..3981c941f5b55 100644 +--- a/fs/btrfs/discard.c ++++ b/fs/btrfs/discard.c +@@ -167,13 +167,7 @@ static bool remove_from_discard_list(struct btrfs_discard_ctl *discard_ctl, + block_group->discard_eligible_time = 0; + queued = !list_empty(&block_group->discard_list); + list_del_init(&block_group->discard_list); +- /* +- * If the block group is currently running in the discard workfn, we +- * don't want to deref it, since it's still being used by the workfn. +- * The workfn will notice this case and deref the block group when it is +- * finished. +- */ +- if (queued && !running) ++ if (queued) + btrfs_put_block_group(block_group); + + spin_unlock(&discard_ctl->lock); +@@ -260,9 +254,10 @@ static struct btrfs_block_group *peek_discard_list( + block_group->discard_cursor = block_group->start; + block_group->discard_state = BTRFS_DISCARD_EXTENTS; + } +- discard_ctl->block_group = block_group; + } + if (block_group) { ++ btrfs_get_block_group(block_group); ++ discard_ctl->block_group = block_group; + *discard_state = block_group->discard_state; + *discard_index = block_group->discard_index; + } +@@ -493,9 +488,20 @@ static void btrfs_discard_workfn(struct work_struct *work) + + block_group = peek_discard_list(discard_ctl, &discard_state, + &discard_index, now); +- if (!block_group || !btrfs_run_discard_work(discard_ctl)) ++ if (!block_group) + return; ++ if (!btrfs_run_discard_work(discard_ctl)) { ++ spin_lock(&discard_ctl->lock); ++ btrfs_put_block_group(block_group); ++ discard_ctl->block_group = NULL; ++ spin_unlock(&discard_ctl->lock); ++ return; ++ } + if (now < block_group->discard_eligible_time) { ++ spin_lock(&discard_ctl->lock); ++ btrfs_put_block_group(block_group); ++ discard_ctl->block_group = NULL; ++ spin_unlock(&discard_ctl->lock); + btrfs_discard_schedule_work(discard_ctl, false); + return; + } +@@ -547,15 +553,7 @@ static void btrfs_discard_workfn(struct work_struct *work) + spin_lock(&discard_ctl->lock); + discard_ctl->prev_discard = trimmed; + discard_ctl->prev_discard_time = now; +- /* +- * If the block group was removed from the discard list while it was +- * running in this workfn, then we didn't deref it, since this function +- * still owned that reference. But we set the discard_ctl->block_group +- * back to NULL, so we can use that condition to know that now we need +- * to deref the block_group. +- */ +- if (discard_ctl->block_group == NULL) +- btrfs_put_block_group(block_group); ++ btrfs_put_block_group(block_group); + discard_ctl->block_group = NULL; + __btrfs_discard_schedule_work(discard_ctl, now, false); + spin_unlock(&discard_ctl->lock); +-- +2.39.5 + diff --git a/queue-6.6/btrfs-run-btrfs_error_commit_super-early.patch b/queue-6.6/btrfs-run-btrfs_error_commit_super-early.patch new file mode 100644 index 0000000000..5cfc744298 --- /dev/null +++ b/queue-6.6/btrfs-run-btrfs_error_commit_super-early.patch @@ -0,0 +1,98 @@ +From 105ae5f3d18688e6797dc38addfe255f76989e95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Mar 2025 14:36:10 +1030 +Subject: btrfs: run btrfs_error_commit_super() early + +From: Qu Wenruo + +[ Upstream commit df94a342efb451deb0e32b495d1d6cd4bb3a1648 ] + +[BUG] +Even after all the error fixes related the +"ASSERT(list_empty(&fs_info->delayed_iputs));" in close_ctree(), I can +still hit it reliably with my experimental 2K block size. + +[CAUSE] +In my case, all the error is triggered after the fs is already in error +status. + +I find the following call trace to be the cause of race: + + Main thread | endio_write_workers +---------------------------------------------+--------------------------- +close_ctree() | +|- btrfs_error_commit_super() | +| |- btrfs_cleanup_transaction() | +| | |- btrfs_destroy_all_ordered_extents() | +| | |- btrfs_wait_ordered_roots() | +| |- btrfs_run_delayed_iputs() | +| | btrfs_finish_ordered_io() +| | |- btrfs_put_ordered_extent() +| | |- btrfs_add_delayed_iput() +|- ASSERT(list_empty(delayed_iputs)) | + !!! Triggered !!! + +The root cause is that, btrfs_wait_ordered_roots() only wait for +ordered extents to finish their IOs, not to wait for them to finish and +removed. + +[FIX] +Since btrfs_error_commit_super() will flush and wait for all ordered +extents, it should be executed early, before we start flushing the +workqueues. + +And since btrfs_error_commit_super() now runs early, there is no need to +run btrfs_run_delayed_iputs() inside it, so just remove the +btrfs_run_delayed_iputs() call from btrfs_error_commit_super(). + +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 2387210231f23..1e1650012606e 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4313,6 +4313,14 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) + /* clear out the rbtree of defraggable inodes */ + btrfs_cleanup_defrag_inodes(fs_info); + ++ /* ++ * Handle the error fs first, as it will flush and wait for all ordered ++ * extents. This will generate delayed iputs, thus we want to handle ++ * it first. ++ */ ++ if (unlikely(BTRFS_FS_ERROR(fs_info))) ++ btrfs_error_commit_super(fs_info); ++ + /* + * Wait for any fixup workers to complete. + * If we don't wait for them here and they are still running by the time +@@ -4402,9 +4410,6 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) + btrfs_err(fs_info, "commit super ret %d", ret); + } + +- if (BTRFS_FS_ERROR(fs_info)) +- btrfs_error_commit_super(fs_info); +- + kthread_stop(fs_info->transaction_kthread); + kthread_stop(fs_info->cleaner_kthread); + +@@ -4541,10 +4546,6 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) + /* cleanup FS via transaction */ + btrfs_cleanup_transaction(fs_info); + +- mutex_lock(&fs_info->cleaner_mutex); +- btrfs_run_delayed_iputs(fs_info); +- mutex_unlock(&fs_info->cleaner_mutex); +- + down_write(&fs_info->cleanup_work_sem); + up_write(&fs_info->cleanup_work_sem); + } +-- +2.39.5 + diff --git a/queue-6.6/btrfs-send-return-enametoolong-when-attempting-a-pat.patch b/queue-6.6/btrfs-send-return-enametoolong-when-attempting-a-pat.patch new file mode 100644 index 0000000000..e950ad0eec --- /dev/null +++ b/queue-6.6/btrfs-send-return-enametoolong-when-attempting-a-pat.patch @@ -0,0 +1,46 @@ +From ab5f197025be086e30c09df451b76a3b1e1dfec7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 13:09:25 +0000 +Subject: btrfs: send: return -ENAMETOOLONG when attempting a path that is too + long + +From: Filipe Manana + +[ Upstream commit a77749b3e21813566cea050bbb3414ae74562eba ] + +When attempting to build a too long path we are currently returning +-ENOMEM, which is very odd and misleading. So update fs_path_ensure_buf() +to return -ENAMETOOLONG instead. Also, while at it, move the WARN_ON() +into the if statement's expression, as it makes it clear what is being +tested and also has the effect of adding 'unlikely' to the statement, +which allows the compiler to generate better code as this condition is +never expected to happen. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/send.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index aa1e6d88a72c7..e2ead36e5be42 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -487,10 +487,8 @@ static int fs_path_ensure_buf(struct fs_path *p, int len) + if (p->buf_len >= len) + return 0; + +- if (len > PATH_MAX) { +- WARN_ON(1); +- return -ENOMEM; +- } ++ if (WARN_ON(len > PATH_MAX)) ++ return -ENAMETOOLONG; + + path_len = p->end - p->start; + old_buf_len = p->buf_len; +-- +2.39.5 + diff --git a/queue-6.6/btrfs-zoned-exit-btrfs_can_activate_zone-if-btrfs_fs.patch b/queue-6.6/btrfs-zoned-exit-btrfs_can_activate_zone-if-btrfs_fs.patch new file mode 100644 index 0000000000..02392a270a --- /dev/null +++ b/queue-6.6/btrfs-zoned-exit-btrfs_can_activate_zone-if-btrfs_fs.patch @@ -0,0 +1,40 @@ +From 598ac7633343dd8d3e82fcafbed63b0febbc16d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 15:05:00 +0100 +Subject: btrfs: zoned: exit btrfs_can_activate_zone if + BTRFS_FS_NEED_ZONE_FINISH is set + +From: Johannes Thumshirn + +[ Upstream commit 26b38e28162ef4ceb1e0482299820fbbd7dbcd92 ] + +If BTRFS_FS_NEED_ZONE_FINISH is already set for the whole filesystem, exit +early in btrfs_can_activate_zone(). There's no need to check if +BTRFS_FS_NEED_ZONE_FINISH needs to be set if it is already set. + +Reviewed-by: Naohiro Aota +Signed-off-by: Johannes Thumshirn +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/zoned.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c +index 197dfafbf4013..6ef0b47facbf3 100644 +--- a/fs/btrfs/zoned.c ++++ b/fs/btrfs/zoned.c +@@ -2220,6 +2220,9 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags) + if (!btrfs_is_zoned(fs_info)) + return true; + ++ if (test_bit(BTRFS_FS_NEED_ZONE_FINISH, &fs_info->flags)) ++ return false; ++ + /* Check if there is a device with active zones left */ + mutex_lock(&fs_info->chunk_mutex); + spin_lock(&fs_info->zone_active_bgs_lock); +-- +2.39.5 + diff --git a/queue-6.6/can-c_can-use-of_property_present-to-test-existence-.patch b/queue-6.6/can-c_can-use-of_property_present-to-test-existence-.patch new file mode 100644 index 0000000000..72b2865135 --- /dev/null +++ b/queue-6.6/can-c_can-use-of_property_present-to-test-existence-.patch @@ -0,0 +1,38 @@ +From 70baca1838c795f88b1a5587eda57f25912c4f1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 21:23:14 +0100 +Subject: can: c_can: Use of_property_present() to test existence of DT + property + +From: Krzysztof Kozlowski + +[ Upstream commit ab1bc2290fd8311d49b87c29f1eb123fcb581bee ] + +of_property_read_bool() should be used only on boolean properties. + +Cc: Rob Herring +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/20250212-syscon-phandle-args-can-v2-3-ac9a1253396b@linaro.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/c_can/c_can_platform.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c +index 7f405bcf11c23..603680792f1ff 100644 +--- a/drivers/net/can/c_can/c_can_platform.c ++++ b/drivers/net/can/c_can/c_can_platform.c +@@ -333,7 +333,7 @@ static int c_can_plat_probe(struct platform_device *pdev) + /* Check if we need custom RAMINIT via syscon. Mostly for TI + * platforms. Only supported with DT boot. + */ +- if (np && of_property_read_bool(np, "syscon-raminit")) { ++ if (np && of_property_present(np, "syscon-raminit")) { + u32 id; + struct c_can_raminit *raminit = &priv->raminit_sys; + +-- +2.39.5 + diff --git a/queue-6.6/cgroup-fix-compilation-issue-due-to-cgroup_mutex-not.patch b/queue-6.6/cgroup-fix-compilation-issue-due-to-cgroup_mutex-not.patch new file mode 100644 index 0000000000..7a1960ccd6 --- /dev/null +++ b/queue-6.6/cgroup-fix-compilation-issue-due-to-cgroup_mutex-not.patch @@ -0,0 +1,48 @@ +From f625f123d92e71e72cce95b9d54b1aba817d68b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 07:30:00 +0000 +Subject: cgroup: Fix compilation issue due to cgroup_mutex not being exported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: gaoxu + +[ Upstream commit 87c259a7a359e73e6c52c68fcbec79988999b4e6 ] + +When adding folio_memcg function call in the zram module for +Android16-6.12, the following error occurs during compilation: +ERROR: modpost: "cgroup_mutex" [../soc-repo/zram.ko] undefined! + +This error is caused by the indirect call to lockdep_is_held(&cgroup_mutex) +within folio_memcg. The export setting for cgroup_mutex is controlled by +the CONFIG_PROVE_RCU macro. If CONFIG_LOCKDEP is enabled while +CONFIG_PROVE_RCU is not, this compilation error will occur. + +To resolve this issue, add a parallel macro CONFIG_LOCKDEP control to +ensure cgroup_mutex is properly exported when needed. + +Signed-off-by: gao xu +Acked-by: Michal Koutný +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cgroup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 3ccf80dfa587a..e8ef062f6ca05 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -90,7 +90,7 @@ + DEFINE_MUTEX(cgroup_mutex); + DEFINE_SPINLOCK(css_set_lock); + +-#ifdef CONFIG_PROVE_RCU ++#if (defined CONFIG_PROVE_RCU || defined CONFIG_LOCKDEP) + EXPORT_SYMBOL_GPL(cgroup_mutex); + EXPORT_SYMBOL_GPL(css_set_lock); + #endif +-- +2.39.5 + diff --git a/queue-6.6/cifs-add-fallback-for-smb2-create-without-file_read_.patch b/queue-6.6/cifs-add-fallback-for-smb2-create-without-file_read_.patch new file mode 100644 index 0000000000..bb71da2fb9 --- /dev/null +++ b/queue-6.6/cifs-add-fallback-for-smb2-create-without-file_read_.patch @@ -0,0 +1,65 @@ +From 0c68cccf5861b9c4118ced0bb0835a0838bff1a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2024 20:44:23 +0100 +Subject: cifs: Add fallback for SMB2 CREATE without FILE_READ_ATTRIBUTES +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit e255612b5ed9f179abe8196df7c2ba09dd227900 ] + +Some operations, like WRITE, does not require FILE_READ_ATTRIBUTES access. + +So when FILE_READ_ATTRIBUTES is not explicitly requested for +smb2_open_file() then first try to do SMB2 CREATE with FILE_READ_ATTRIBUTES +access (like it was before) and then fallback to SMB2 CREATE without +FILE_READ_ATTRIBUTES access (less common case). + +This change allows to complete WRITE operation to a file when it does not +grant FILE_READ_ATTRIBUTES permission and its parent directory does not +grant READ_DATA permission (parent directory READ_DATA is implicit grant of +child FILE_READ_ATTRIBUTES permission). + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb2file.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c +index db9c807115c60..d7f2835e0b1cc 100644 +--- a/fs/smb/client/smb2file.c ++++ b/fs/smb/client/smb2file.c +@@ -107,16 +107,25 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 + int err_buftype = CIFS_NO_BUFFER; + struct cifs_fid *fid = oparms->fid; + struct network_resiliency_req nr_ioctl_req; ++ bool retry_without_read_attributes = false; + + smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb); + if (smb2_path == NULL) + return -ENOMEM; + +- oparms->desired_access |= FILE_READ_ATTRIBUTES; ++ if (!(oparms->desired_access & FILE_READ_ATTRIBUTES)) { ++ oparms->desired_access |= FILE_READ_ATTRIBUTES; ++ retry_without_read_attributes = true; ++ } + smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH; + + rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, + &err_buftype); ++ if (rc == -EACCES && retry_without_read_attributes) { ++ oparms->desired_access &= ~FILE_READ_ATTRIBUTES; ++ rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, ++ &err_buftype); ++ } + if (rc && data) { + struct smb2_hdr *hdr = err_iov.iov_base; + +-- +2.39.5 + diff --git a/queue-6.6/cifs-add-validation-check-for-the-fields-in-smb_aces.patch b/queue-6.6/cifs-add-validation-check-for-the-fields-in-smb_aces.patch new file mode 100644 index 0000000000..e2f09f377b --- /dev/null +++ b/queue-6.6/cifs-add-validation-check-for-the-fields-in-smb_aces.patch @@ -0,0 +1,58 @@ +From 914c0c5fb88ef2eb0a7682533cd3c6dafe4935a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 17:52:19 +0900 +Subject: cifs: add validation check for the fields in smb_aces + +From: Namjae Jeon + +[ Upstream commit eeb827f2922eb07ffbf7d53569cc95b38272646f ] + +cifs.ko is missing validation check when accessing smb_aces. +This patch add validation check for the fields in smb_aces. + +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index db9076da2182a..bf32bc22ebd69 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -811,7 +811,23 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + return; + + for (i = 0; i < num_aces; ++i) { ++ if (end_of_acl - acl_base < acl_size) ++ break; ++ + ppace[i] = (struct smb_ace *) (acl_base + acl_size); ++ acl_base = (char *)ppace[i]; ++ acl_size = offsetof(struct smb_ace, sid) + ++ offsetof(struct smb_sid, sub_auth); ++ ++ if (end_of_acl - acl_base < acl_size || ++ ppace[i]->sid.num_subauth == 0 || ++ ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES || ++ (end_of_acl - acl_base < ++ acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) || ++ (le16_to_cpu(ppace[i]->size) < ++ acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth)) ++ break; ++ + #ifdef CONFIG_CIFS_DEBUG2 + dump_ace(ppace[i], end_of_acl); + #endif +@@ -855,7 +871,6 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + (void *)ppace[i], + sizeof(struct smb_ace)); */ + +- acl_base = (char *)ppace[i]; + acl_size = le16_to_cpu(ppace[i]->size); + } + +-- +2.39.5 + diff --git a/queue-6.6/cifs-fix-and-improve-cifs_query_path_info-and-cifs_q.patch b/queue-6.6/cifs-fix-and-improve-cifs_query_path_info-and-cifs_q.patch new file mode 100644 index 0000000000..8db0380a10 --- /dev/null +++ b/queue-6.6/cifs-fix-and-improve-cifs_query_path_info-and-cifs_q.patch @@ -0,0 +1,183 @@ +From 0ed532f044b9eded63790e045c92fcc892765585 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 20:34:18 +0100 +Subject: cifs: Fix and improve cifs_query_path_info() and + cifs_query_file_info() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 1041c117a2c33cdffc4f695ac4b469e9124d24d5 ] + +When CAP_NT_SMBS was not negotiated then do not issue CIFSSMBQPathInfo() +and CIFSSMBQFileInfo() commands. CIFSSMBQPathInfo() is not supported by +non-NT Win9x SMB server and CIFSSMBQFileInfo() returns from Win9x SMB +server bogus data in Attributes field (for example lot of files are marked +as reparse points, even Win9x does not support them and read-only bit is +not marked for read-only files). Correct information is returned by +CIFSFindFirst() or SMBQueryInformation() command. + +So as a fallback in cifs_query_path_info() function use CIFSFindFirst() +with SMB_FIND_FILE_FULL_DIRECTORY_INFO level which is supported by both NT +and non-NT servers and as a last option use SMBQueryInformation() as it was +before. + +And in function cifs_query_file_info() immediately returns -EOPNOTSUPP when +not communicating with NT server. Client then revalidate inode entry by the +cifs_query_path_info() call, which is working fine. So fstat() syscall on +already opened file will receive correct information. + +Note that both fallback functions in non-UNICODE mode expands wildcards. +Therefore those fallback functions cannot be used on paths which contain +SMB wildcard characters (* ? " > <). + +CIFSFindFirst() returns all 4 time attributes as opposite of +SMBQueryInformation() which returns only one. + +With this change it is possible to query all 4 times attributes from Win9x +server and at the same time, client minimize sending of unsupported +commands to server. + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb1ops.c | 103 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 95 insertions(+), 8 deletions(-) + +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index 0ba0f680205c1..58dcd6bdce981 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -541,24 +541,104 @@ static int cifs_query_path_info(const unsigned int xid, + const char *full_path, + struct cifs_open_info_data *data) + { +- int rc; ++ int rc = -EOPNOTSUPP; + FILE_ALL_INFO fi = {}; ++ struct cifs_search_info search_info = {}; ++ bool non_unicode_wildcard = false; + + data->symlink = false; + data->adjust_tz = false; + +- /* could do find first instead but this returns more info */ +- rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, cifs_sb->local_nls, +- cifs_remap(cifs_sb)); + /* +- * BB optimize code so we do not make the above call when server claims +- * no NT SMB support and the above call failed at least once - set flag +- * in tcon or mount. ++ * First try CIFSSMBQPathInfo() function which returns more info ++ * (NumberOfLinks) than CIFSFindFirst() fallback function. ++ * Some servers like Win9x do not support SMB_QUERY_FILE_ALL_INFO over ++ * TRANS2_QUERY_PATH_INFORMATION, but supports it with filehandle over ++ * TRANS2_QUERY_FILE_INFORMATION (function CIFSSMBQFileInfo(). But SMB ++ * Open command on non-NT servers works only for files, does not work ++ * for directories. And moreover Win9x SMB server returns bogus data in ++ * SMB_QUERY_FILE_ALL_INFO Attributes field. So for non-NT servers, ++ * do not even use CIFSSMBQPathInfo() or CIFSSMBQFileInfo() function. ++ */ ++ if (tcon->ses->capabilities & CAP_NT_SMBS) ++ rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, ++ cifs_sb->local_nls, cifs_remap(cifs_sb)); ++ ++ /* ++ * Non-UNICODE variant of fallback functions below expands wildcards, ++ * so they cannot be used for querying paths with wildcard characters. + */ +- if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { ++ if (rc && !(tcon->ses->capabilities & CAP_UNICODE) && strpbrk(full_path, "*?\"><")) ++ non_unicode_wildcard = true; ++ ++ /* ++ * Then fallback to CIFSFindFirst() which works also with non-NT servers ++ * but does not does not provide NumberOfLinks. ++ */ ++ if ((rc == -EOPNOTSUPP || rc == -EINVAL) && ++ !non_unicode_wildcard) { ++ if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) ++ search_info.info_level = SMB_FIND_FILE_INFO_STANDARD; ++ else ++ search_info.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO; ++ rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb, NULL, ++ CIFS_SEARCH_CLOSE_ALWAYS | CIFS_SEARCH_CLOSE_AT_END, ++ &search_info, false); ++ if (rc == 0) { ++ if (!(tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find)) { ++ FIND_FILE_STANDARD_INFO *di; ++ int offset = tcon->ses->server->timeAdj; ++ ++ di = (FIND_FILE_STANDARD_INFO *)search_info.srch_entries_start; ++ fi.CreationTime = cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm( ++ di->CreationDate, di->CreationTime, offset))); ++ fi.LastAccessTime = cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm( ++ di->LastAccessDate, di->LastAccessTime, offset))); ++ fi.LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm( ++ di->LastWriteDate, di->LastWriteTime, offset))); ++ fi.ChangeTime = fi.LastWriteTime; ++ fi.Attributes = cpu_to_le32(le16_to_cpu(di->Attributes)); ++ fi.AllocationSize = cpu_to_le64(le32_to_cpu(di->AllocationSize)); ++ fi.EndOfFile = cpu_to_le64(le32_to_cpu(di->DataSize)); ++ } else { ++ FILE_FULL_DIRECTORY_INFO *di; ++ ++ di = (FILE_FULL_DIRECTORY_INFO *)search_info.srch_entries_start; ++ fi.CreationTime = di->CreationTime; ++ fi.LastAccessTime = di->LastAccessTime; ++ fi.LastWriteTime = di->LastWriteTime; ++ fi.ChangeTime = di->ChangeTime; ++ fi.Attributes = di->ExtFileAttributes; ++ fi.AllocationSize = di->AllocationSize; ++ fi.EndOfFile = di->EndOfFile; ++ fi.EASize = di->EaSize; ++ } ++ fi.NumberOfLinks = cpu_to_le32(1); ++ fi.DeletePending = 0; ++ fi.Directory = !!(le32_to_cpu(fi.Attributes) & ATTR_DIRECTORY); ++ cifs_buf_release(search_info.ntwrk_buf_start); ++ } else if (!full_path[0]) { ++ /* ++ * CIFSFindFirst() does not work on root path if the ++ * root path was exported on the server from the top ++ * level path (drive letter). ++ */ ++ rc = -EOPNOTSUPP; ++ } ++ } ++ ++ /* ++ * If everything failed then fallback to the legacy SMB command ++ * SMB_COM_QUERY_INFORMATION which works with all servers, but ++ * provide just few information. ++ */ ++ if ((rc == -EOPNOTSUPP || rc == -EINVAL) && !non_unicode_wildcard) { + rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls, + cifs_remap(cifs_sb)); + data->adjust_tz = true; ++ } else if ((rc == -EOPNOTSUPP || rc == -EINVAL) && non_unicode_wildcard) { ++ /* Path with non-UNICODE wildcard character cannot exist. */ ++ rc = -ENOENT; + } + + if (!rc) { +@@ -655,6 +735,13 @@ static int cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon, + int rc; + FILE_ALL_INFO fi = {}; + ++ /* ++ * CIFSSMBQFileInfo() for non-NT servers returns bogus data in ++ * Attributes fields. So do not use this command for non-NT servers. ++ */ ++ if (!(tcon->ses->capabilities & CAP_NT_SMBS)) ++ return -EOPNOTSUPP; ++ + if (cfile->symlink_target) { + data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); + if (!data->symlink_target) +-- +2.39.5 + diff --git a/queue-6.6/cifs-fix-changing-times-and-read-only-attr-over-smb1.patch b/queue-6.6/cifs-fix-changing-times-and-read-only-attr-over-smb1.patch new file mode 100644 index 0000000000..600e869cb1 --- /dev/null +++ b/queue-6.6/cifs-fix-changing-times-and-read-only-attr-over-smb1.patch @@ -0,0 +1,334 @@ +From dbe494e0cfd2719705ea19f9ce22482dd52c05e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Dec 2024 21:32:39 +0100 +Subject: cifs: Fix changing times and read-only attr over SMB1 + smb_set_file_info() function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit f122121796f91168d0894c2710b8dd71330a34f8 ] + +Function CIFSSMBSetPathInfo() is not supported by non-NT servers and +returns error. Fallback code via open filehandle and CIFSSMBSetFileInfo() +does not work neither because CIFS_open() works also only on NT server. + +Therefore currently the whole smb_set_file_info() function as a SMB1 +callback for the ->set_file_info() does not work with older non-NT SMB +servers, like Win9x and others. + +This change implements fallback code in smb_set_file_info() which will +works with any server and allows to change time values and also to set or +clear read-only attributes. + +To make existing fallback code via CIFSSMBSetFileInfo() working with also +non-NT servers, it is needed to change open function from CIFS_open() +(which is NT specific) to cifs_open_file() which works with any server +(this is just a open wrapper function which choose the correct open +function supported by the server). + +CIFSSMBSetFileInfo() is working also on non-NT servers, but zero time +values are not treated specially. So first it is needed to fill all time +values if some of them are missing, via cifs_query_path_info() call. + +There is another issue, opening file in write-mode (needed for changing +attributes) is not possible when the file has read-only attribute set. +The only option how to clear read-only attribute is via SMB_COM_SETATTR +command. And opening directory is not possible neither and here the +SMB_COM_SETATTR command is the only option how to change attributes. +And CIFSSMBSetFileInfo() does not honor setting read-only attribute, so +for setting is also needed to use SMB_COM_SETATTR command. + +Existing code in cifs_query_path_info() is already using SMB_COM_GETATTR as +a fallback code path (function SMBQueryInformation()), so introduce a new +function SMBSetInformation which will implement SMB_COM_SETATTR command. + +My testing showed that Windows XP SMB1 client is also using SMB_COM_SETATTR +command for setting or clearing read-only attribute against non-NT server. +So this can prove that this is the correct way how to do it. + +With this change it is possible set all 4 time values and all attributes, +including clearing and setting read-only bit on non-NT SMB servers. +Tested against Win98 SMB1 server. + +This change fixes "touch" command which was failing when called on existing +file. And fixes also "chmod +w" and "chmod -w" commands which were also +failing (as they are changing read-only attribute). + +Note that this change depends on following change +"cifs: Improve cifs_query_path_info() and cifs_query_file_info()" +as it require to query all 4 time attribute values. + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifspdu.h | 5 +- + fs/smb/client/cifsproto.h | 4 ++ + fs/smb/client/cifssmb.c | 57 +++++++++++++++++++ + fs/smb/client/smb1ops.c | 112 +++++++++++++++++++++++++++++++++++--- + 4 files changed, 166 insertions(+), 12 deletions(-) + +diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h +index c46d418c1c0c3..ca33f6cd6a800 100644 +--- a/fs/smb/client/cifspdu.h ++++ b/fs/smb/client/cifspdu.h +@@ -1226,10 +1226,9 @@ typedef struct smb_com_query_information_rsp { + typedef struct smb_com_setattr_req { + struct smb_hdr hdr; /* wct = 8 */ + __le16 attr; +- __le16 time_low; +- __le16 time_high; ++ __le32 last_write_time; + __le16 reserved[5]; /* must be zero */ +- __u16 ByteCount; ++ __le16 ByteCount; + __u8 BufferFormat; /* 4 = ASCII */ + unsigned char fileName[]; + } __attribute__((packed)) SETATTR_REQ; +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 8584922204374..c6d325666b5cd 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -398,6 +398,10 @@ extern int CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon); + extern int CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, + struct kstatfs *FSData); + ++extern int SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon, ++ const char *fileName, __le32 attributes, __le64 write_time, ++ const struct nls_table *nls_codepage, ++ struct cifs_sb_info *cifs_sb); + extern int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, + const char *fileName, const FILE_BASIC_INFO *data, + const struct nls_table *nls_codepage, +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index 769950adb7763..b91184ebce02c 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -5157,6 +5157,63 @@ CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, + return rc; + } + ++int ++SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon, ++ const char *fileName, __le32 attributes, __le64 write_time, ++ const struct nls_table *nls_codepage, ++ struct cifs_sb_info *cifs_sb) ++{ ++ SETATTR_REQ *pSMB; ++ SETATTR_RSP *pSMBr; ++ struct timespec64 ts; ++ int bytes_returned; ++ int name_len; ++ int rc; ++ ++ cifs_dbg(FYI, "In %s path %s\n", __func__, fileName); ++ ++retry: ++ rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB, ++ (void **) &pSMBr); ++ if (rc) ++ return rc; ++ ++ if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { ++ name_len = ++ cifsConvertToUTF16((__le16 *) pSMB->fileName, ++ fileName, PATH_MAX, nls_codepage, ++ cifs_remap(cifs_sb)); ++ name_len++; /* trailing null */ ++ name_len *= 2; ++ } else { ++ name_len = copy_path_name(pSMB->fileName, fileName); ++ } ++ /* Only few attributes can be set by this command, others are not accepted by Win9x. */ ++ pSMB->attr = cpu_to_le16(le32_to_cpu(attributes) & ++ (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE)); ++ /* Zero write time value (in both NT and SETATTR formats) means to not change it. */ ++ if (le64_to_cpu(write_time) != 0) { ++ ts = cifs_NTtimeToUnix(write_time); ++ pSMB->last_write_time = cpu_to_le32(ts.tv_sec); ++ } ++ pSMB->BufferFormat = 0x04; ++ name_len++; /* account for buffer type byte */ ++ inc_rfc1001_len(pSMB, (__u16)name_len); ++ pSMB->ByteCount = cpu_to_le16(name_len); ++ ++ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, ++ (struct smb_hdr *) pSMBr, &bytes_returned, 0); ++ if (rc) ++ cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc); ++ ++ cifs_buf_release(pSMB); ++ ++ if (rc == -EAGAIN) ++ goto retry; ++ ++ return rc; ++} ++ + /* Some legacy servers such as NT4 require that the file times be set on + an open handle, rather than by pathname - this is awkward due to + potential access conflicts on the open, but it is unavoidable for these +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index 58dcd6bdce981..e62d9cc592e0c 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -912,6 +912,9 @@ smb_set_file_info(struct inode *inode, const char *full_path, + struct cifs_fid fid; + struct cifs_open_parms oparms; + struct cifsFileInfo *open_file; ++ FILE_BASIC_INFO new_buf; ++ struct cifs_open_info_data query_data; ++ __le64 write_time = buf->LastWriteTime; + struct cifsInodeInfo *cinode = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct tcon_link *tlink = NULL; +@@ -919,20 +922,58 @@ smb_set_file_info(struct inode *inode, const char *full_path, + + /* if the file is already open for write, just use that fileid */ + open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY); ++ + if (open_file) { + fid.netfid = open_file->fid.netfid; + netpid = open_file->pid; + tcon = tlink_tcon(open_file->tlink); +- goto set_via_filehandle; ++ } else { ++ tlink = cifs_sb_tlink(cifs_sb); ++ if (IS_ERR(tlink)) { ++ rc = PTR_ERR(tlink); ++ tlink = NULL; ++ goto out; ++ } ++ tcon = tlink_tcon(tlink); + } + +- tlink = cifs_sb_tlink(cifs_sb); +- if (IS_ERR(tlink)) { +- rc = PTR_ERR(tlink); +- tlink = NULL; +- goto out; ++ /* ++ * Non-NT servers interprets zero time value in SMB_SET_FILE_BASIC_INFO ++ * over TRANS2_SET_FILE_INFORMATION as a valid time value. NT servers ++ * interprets zero time value as do not change existing value on server. ++ * API of ->set_file_info() callback expects that zero time value has ++ * the NT meaning - do not change. Therefore if server is non-NT and ++ * some time values in "buf" are zero, then fetch missing time values. ++ */ ++ if (!(tcon->ses->capabilities & CAP_NT_SMBS) && ++ (!buf->CreationTime || !buf->LastAccessTime || ++ !buf->LastWriteTime || !buf->ChangeTime)) { ++ rc = cifs_query_path_info(xid, tcon, cifs_sb, full_path, &query_data); ++ if (rc) { ++ if (open_file) { ++ cifsFileInfo_put(open_file); ++ open_file = NULL; ++ } ++ goto out; ++ } ++ /* ++ * Original write_time from buf->LastWriteTime is preserved ++ * as SMBSetInformation() interprets zero as do not change. ++ */ ++ new_buf = *buf; ++ buf = &new_buf; ++ if (!buf->CreationTime) ++ buf->CreationTime = query_data.fi.CreationTime; ++ if (!buf->LastAccessTime) ++ buf->LastAccessTime = query_data.fi.LastAccessTime; ++ if (!buf->LastWriteTime) ++ buf->LastWriteTime = query_data.fi.LastWriteTime; ++ if (!buf->ChangeTime) ++ buf->ChangeTime = query_data.fi.ChangeTime; + } +- tcon = tlink_tcon(tlink); ++ ++ if (open_file) ++ goto set_via_filehandle; + + rc = CIFSSMBSetPathInfo(xid, tcon, full_path, buf, cifs_sb->local_nls, + cifs_sb); +@@ -953,8 +994,45 @@ smb_set_file_info(struct inode *inode, const char *full_path, + .fid = &fid, + }; + +- cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for times not supported by this server\n"); +- rc = CIFS_open(xid, &oparms, &oplock, NULL); ++ if (S_ISDIR(inode->i_mode) && !(tcon->ses->capabilities & CAP_NT_SMBS)) { ++ /* Opening directory path is not possible on non-NT servers. */ ++ rc = -EOPNOTSUPP; ++ } else { ++ /* ++ * Use cifs_open_file() instead of CIFS_open() as the ++ * cifs_open_file() selects the correct function which ++ * works also on non-NT servers. ++ */ ++ rc = cifs_open_file(xid, &oparms, &oplock, NULL); ++ /* ++ * Opening path for writing on non-NT servers is not ++ * possible when the read-only attribute is already set. ++ * Non-NT server in this case returns -EACCES. For those ++ * servers the only possible way how to clear the read-only ++ * bit is via SMB_COM_SETATTR command. ++ */ ++ if (rc == -EACCES && ++ (cinode->cifsAttrs & ATTR_READONLY) && ++ le32_to_cpu(buf->Attributes) != 0 && /* 0 = do not change attrs */ ++ !(le32_to_cpu(buf->Attributes) & ATTR_READONLY) && ++ !(tcon->ses->capabilities & CAP_NT_SMBS)) ++ rc = -EOPNOTSUPP; ++ } ++ ++ /* Fallback to SMB_COM_SETATTR command when absolutelty needed. */ ++ if (rc == -EOPNOTSUPP) { ++ cifs_dbg(FYI, "calling SetInformation since SetPathInfo for attrs/times not supported by this server\n"); ++ rc = SMBSetInformation(xid, tcon, full_path, ++ buf->Attributes != 0 ? buf->Attributes : cpu_to_le32(cinode->cifsAttrs), ++ write_time, ++ cifs_sb->local_nls, cifs_sb); ++ if (rc == 0) ++ cinode->cifsAttrs = le32_to_cpu(buf->Attributes); ++ else ++ rc = -EACCES; ++ goto out; ++ } ++ + if (rc != 0) { + if (rc == -EIO) + rc = -EINVAL; +@@ -962,6 +1040,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, + } + + netpid = current->tgid; ++ cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for attrs/times not supported by this server\n"); + + set_via_filehandle: + rc = CIFSSMBSetFileInfo(xid, tcon, buf, fid.netfid, netpid); +@@ -972,6 +1051,21 @@ smb_set_file_info(struct inode *inode, const char *full_path, + CIFSSMBClose(xid, tcon, fid.netfid); + else + cifsFileInfo_put(open_file); ++ ++ /* ++ * Setting the read-only bit is not honered on non-NT servers when done ++ * via open-semantics. So for setting it, use SMB_COM_SETATTR command. ++ * This command works only after the file is closed, so use it only when ++ * operation was called without the filehandle. ++ */ ++ if (open_file == NULL && ++ !(tcon->ses->capabilities & CAP_NT_SMBS) && ++ le32_to_cpu(buf->Attributes) & ATTR_READONLY) { ++ SMBSetInformation(xid, tcon, full_path, ++ buf->Attributes, ++ 0 /* do not change write time */, ++ cifs_sb->local_nls, cifs_sb); ++ } + out: + if (tlink != NULL) + cifs_put_tlink(tlink); +-- +2.39.5 + diff --git a/queue-6.6/cifs-fix-establishing-netbios-session-for-smb2-conne.patch b/queue-6.6/cifs-fix-establishing-netbios-session-for-smb2-conne.patch new file mode 100644 index 0000000000..8793305d43 --- /dev/null +++ b/queue-6.6/cifs-fix-establishing-netbios-session-for-smb2-conne.patch @@ -0,0 +1,120 @@ +From 0b1f96affd93ad430fce612d802bbfceb1205f32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Oct 2024 22:46:20 +0100 +Subject: cifs: Fix establishing NetBIOS session for SMB2+ connection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 781802aa5a5950f99899f13ff9d760f5db81d36d ] + +Function ip_rfc1001_connect() which establish NetBIOS session for SMB +connections, currently uses smb_send() function for sending NetBIOS Session +Request packet. This function expects that the passed buffer is SMB packet +and for SMB2+ connections it mangles packet header, which breaks prepared +NetBIOS Session Request packet. Result is that this function send garbage +packet for SMB2+ connection, which SMB2+ server cannot parse. That function +is not mangling packets for SMB1 connections, so it somehow works for SMB1. + +Fix this problem and instead of smb_send(), use smb_send_kvec() function +which does not mangle prepared packet, this function send them as is. Just +API of this function takes struct msghdr (kvec) instead of packet buffer. + +[MS-SMB2] specification allows SMB2 protocol to use NetBIOS as a transport +protocol. NetBIOS can be used over TCP via port 139. So this is a valid +configuration, just not so common. And even recent Windows versions (e.g. +Windows Server 2022) still supports this configuration: SMB over TCP port +139, including for modern SMB2 and SMB3 dialects. + +This change fixes SMB2 and SMB3 connections over TCP port 139 which +requires establishing of NetBIOS session. Tested that this change fixes +establishing of SMB2 and SMB3 connections with Windows Server 2022. + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsproto.h | 3 +++ + fs/smb/client/connect.c | 20 +++++++++++++++----- + fs/smb/client/transport.c | 2 +- + 3 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 7f97e54686524..8584922204374 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -31,6 +31,9 @@ extern void cifs_small_buf_release(void *); + extern void free_rsp_buf(int, void *); + extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *, + unsigned int /* length */); ++extern int smb_send_kvec(struct TCP_Server_Info *server, ++ struct msghdr *msg, ++ size_t *sent); + extern unsigned int _get_xid(void); + extern void _free_xid(unsigned int); + #define get_xid() \ +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 267fba234c12d..3faaee33ad455 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -3051,8 +3051,10 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) + * sessinit is sent but no second negprot + */ + struct rfc1002_session_packet req = {}; +- struct smb_hdr *smb_buf = (struct smb_hdr *)&req; ++ struct msghdr msg = {}; ++ struct kvec iov = {}; + unsigned int len; ++ size_t sent; + + req.trailer.session_req.called_len = sizeof(req.trailer.session_req.called_name); + +@@ -3081,10 +3083,18 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) + * As per rfc1002, @len must be the number of bytes that follows the + * length field of a rfc1002 session request payload. + */ +- len = sizeof(req) - offsetof(struct rfc1002_session_packet, trailer.session_req); ++ len = sizeof(req.trailer.session_req); ++ req.type = RFC1002_SESSION_REQUEST; ++ req.flags = 0; ++ req.length = cpu_to_be16(len); ++ len += offsetof(typeof(req), trailer.session_req); ++ iov.iov_base = &req; ++ iov.iov_len = len; ++ iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iov, 1, len); ++ rc = smb_send_kvec(server, &msg, &sent); ++ if (rc < 0 || len != sent) ++ return (rc == -EINTR || rc == -EAGAIN) ? rc : -ECONNABORTED; + +- smb_buf->smb_buf_length = cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | len); +- rc = smb_send(server, smb_buf, len); + /* + * RFC1001 layer in at least one server requires very short break before + * negprot presumably because not expecting negprot to follow so fast. +@@ -3093,7 +3103,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server) + */ + usleep_range(1000, 2000); + +- return rc; ++ return 0; + } + + static int +diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c +index ddf1a3aafee5c..2269963e50081 100644 +--- a/fs/smb/client/transport.c ++++ b/fs/smb/client/transport.c +@@ -178,7 +178,7 @@ delete_mid(struct mid_q_entry *mid) + * Our basic "send data to server" function. Should be called with srv_mutex + * held. The caller is responsible for handling the results. + */ +-static int ++int + smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, + size_t *sent) + { +-- +2.39.5 + diff --git a/queue-6.6/cifs-fix-negotiate-retry-functionality.patch b/queue-6.6/cifs-fix-negotiate-retry-functionality.patch new file mode 100644 index 0000000000..957f80832c --- /dev/null +++ b/queue-6.6/cifs-fix-negotiate-retry-functionality.patch @@ -0,0 +1,107 @@ +From b28592871c69191a4d10ed5ac216bc713e7d33b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 Nov 2024 20:06:50 +0100 +Subject: cifs: Fix negotiate retry functionality +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit e94e882a6d69525c07589222cf3a6ff57ad12b5b ] + +SMB negotiate retry functionality in cifs_negotiate() is currently broken +and does not work when doing socket reconnect. Caller of this function, +which is cifs_negotiate_protocol() requires that tcpStatus after successful +execution of negotiate callback stay in CifsInNegotiate. But if the +CIFSSMBNegotiate() called from cifs_negotiate() fails due to connection +issues then tcpStatus is changed as so repeated CIFSSMBNegotiate() call +does not help. + +Fix this problem by moving retrying code from negotiate callback (which is +either cifs_negotiate() or smb2_negotiate()) to cifs_negotiate_protocol() +which is caller of those callbacks. This allows to properly handle and +implement correct transistions between tcpStatus states as function +cifs_negotiate_protocol() already handles it. + +With this change, cifs_negotiate_protocol() now handles also -EAGAIN error +set by the RFC1002_NEGATIVE_SESSION_RESPONSE processing after reconnecting +with NetBIOS session. + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/connect.c | 10 ++++++++++ + fs/smb/client/smb1ops.c | 7 ------- + fs/smb/client/smb2ops.c | 3 --- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 54aba8d642ee7..267fba234c12d 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -3946,11 +3946,13 @@ int + cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, + struct TCP_Server_Info *server) + { ++ bool in_retry = false; + int rc = 0; + + if (!server->ops->need_neg || !server->ops->negotiate) + return -ENOSYS; + ++retry: + /* only send once per connect */ + spin_lock(&server->srv_lock); + if (server->tcpStatus != CifsGood && +@@ -3970,6 +3972,14 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, + spin_unlock(&server->srv_lock); + + rc = server->ops->negotiate(xid, ses, server); ++ if (rc == -EAGAIN) { ++ /* Allow one retry attempt */ ++ if (!in_retry) { ++ in_retry = true; ++ goto retry; ++ } ++ rc = -EHOSTDOWN; ++ } + if (rc == 0) { + spin_lock(&server->srv_lock); + if (server->tcpStatus == CifsInNegotiate) +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index caa1d852ece49..280885dd6bf08 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -426,13 +426,6 @@ cifs_negotiate(const unsigned int xid, + { + int rc; + rc = CIFSSMBNegotiate(xid, ses, server); +- if (rc == -EAGAIN) { +- /* retry only once on 1st time connection */ +- set_credits(server, 1); +- rc = CIFSSMBNegotiate(xid, ses, server); +- if (rc == -EAGAIN) +- rc = -EHOSTDOWN; +- } + return rc; + } + +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index b809a616728f2..cead96454bb3d 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -428,9 +428,6 @@ smb2_negotiate(const unsigned int xid, + server->CurrentMid = 0; + spin_unlock(&server->mid_lock); + rc = SMB2_negotiate(xid, ses, server); +- /* BB we probably don't need to retry with modern servers */ +- if (rc == -EAGAIN) +- rc = -EHOSTDOWN; + return rc; + } + +-- +2.39.5 + diff --git a/queue-6.6/cifs-fix-querying-and-creating-mf-symlinks-over-smb1.patch b/queue-6.6/cifs-fix-querying-and-creating-mf-symlinks-over-smb1.patch new file mode 100644 index 0000000000..5e136496ac --- /dev/null +++ b/queue-6.6/cifs-fix-querying-and-creating-mf-symlinks-over-smb1.patch @@ -0,0 +1,69 @@ +From f65913e60bd6604db4751bc797ef9a0b03576519 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 28 Dec 2024 21:09:54 +0100 +Subject: cifs: Fix querying and creating MF symlinks over SMB1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 4236ac9fe5b8b42756070d4abfb76fed718e87c2 ] + +Old SMB1 servers without CAP_NT_SMBS do not support CIFS_open() function +and instead SMBLegacyOpen() needs to be used. This logic is already handled +in cifs_open_file() function, which is server->ops->open callback function. + +So for querying and creating MF symlinks use open callback function instead +of CIFS_open() function directly. + +This change fixes querying and creating new MF symlinks on Windows 98. +Currently cifs_query_mf_symlink() is not able to detect MF symlink and +cifs_create_mf_symlink() is failing with EIO error. + +Signed-off-by: Pali Rohár +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/link.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c +index d86da949a9190..007da0a699cb0 100644 +--- a/fs/smb/client/link.c ++++ b/fs/smb/client/link.c +@@ -257,7 +257,7 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + struct cifs_open_parms oparms; + struct cifs_io_parms io_parms = {0}; + int buf_type = CIFS_NO_BUFFER; +- FILE_ALL_INFO file_info; ++ struct cifs_open_info_data query_data; + + oparms = (struct cifs_open_parms) { + .tcon = tcon, +@@ -269,11 +269,11 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + .fid = &fid, + }; + +- rc = CIFS_open(xid, &oparms, &oplock, &file_info); ++ rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &query_data); + if (rc) + return rc; + +- if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { ++ if (query_data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { + rc = -ENOENT; + /* it's not a symlink */ + goto out; +@@ -312,7 +312,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, + .fid = &fid, + }; + +- rc = CIFS_open(xid, &oparms, &oplock, NULL); ++ rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); + if (rc) + return rc; + +-- +2.39.5 + diff --git a/queue-6.6/clk-imx8mp-inform-ccf-of-maximum-frequency-of-clocks.patch b/queue-6.6/clk-imx8mp-inform-ccf-of-maximum-frequency-of-clocks.patch new file mode 100644 index 0000000000..8aeae59210 --- /dev/null +++ b/queue-6.6/clk-imx8mp-inform-ccf-of-maximum-frequency-of-clocks.patch @@ -0,0 +1,214 @@ +From 26992dee4300a29b285d0098c02c3a0342fdb535 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 19:26:46 +0100 +Subject: clk: imx8mp: inform CCF of maximum frequency of clocks + +From: Ahmad Fatoum + +[ Upstream commit 06a61b5cb6a8638fa8823cd09b17233b29696fa2 ] + +The IMX8MPCEC datasheet lists maximum frequencies allowed for different +modules. Some of these limits are universal, but some depend on +whether the SoC is operating in nominal or in overdrive mode. + +The imx8mp.dtsi currently assumes overdrive mode and configures some +clocks in accordance with this. Boards wishing to make use of nominal +mode will need to override some of the clock rates manually. + +As operating the clocks outside of their allowed range can lead to +difficult to debug issues, it makes sense to register the maximum rates +allowed in the driver, so the CCF can take them into account. + +Reviewed-by: Peng Fan +Signed-off-by: Ahmad Fatoum +Link: https://lore.kernel.org/r/20250218-imx8m-clk-v4-6-b7697dc2dcd0@pengutronix.de +Signed-off-by: Abel Vesa +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx8mp.c | 151 +++++++++++++++++++++++++++++++++++ + 1 file changed, 151 insertions(+) + +diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c +index 747f5397692e5..2a0804dd4b846 100644 +--- a/drivers/clk/imx/clk-imx8mp.c ++++ b/drivers/clk/imx/clk-imx8mp.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -406,11 +407,151 @@ static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_ + static struct clk_hw **hws; + static struct clk_hw_onecell_data *clk_hw_data; + ++struct imx8mp_clock_constraints { ++ unsigned int clkid; ++ u32 maxrate; ++}; ++ ++/* ++ * Below tables are taken from IMX8MPCEC Rev. 2.1, 07/2023 ++ * Table 13. Maximum frequency of modules. ++ * Probable typos fixed are marked with a comment. ++ */ ++static const struct imx8mp_clock_constraints imx8mp_clock_common_constraints[] = { ++ { IMX8MP_CLK_A53_DIV, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ENET_AXI, 266666667 }, /* Datasheet claims 266MHz */ ++ { IMX8MP_CLK_NAND_USDHC_BUS, 266666667 }, /* Datasheet claims 266MHz */ ++ { IMX8MP_CLK_MEDIA_APB, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HDMI_APB, 133333333 }, /* Datasheet claims 133MHz */ ++ { IMX8MP_CLK_ML_AXI, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_AHB, 133333333 }, ++ { IMX8MP_CLK_IPG_ROOT, 66666667 }, ++ { IMX8MP_CLK_AUDIO_AHB, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_DISP2_PIX, 170 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_DRAM_ALT, 666666667 }, ++ { IMX8MP_CLK_DRAM_APB, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_CAN1, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_CAN2, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_PCIE_AUX, 10 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_I2C5, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_I2C6, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_SAI1, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_SAI2, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_SAI3, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_SAI5, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_SAI6, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_ENET_QOS, 125 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ENET_QOS_TIMER, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ENET_REF, 125 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ENET_TIMER, 125 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ENET_PHY_REF, 125 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_NAND, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_QSPI, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_USDHC1, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_USDHC2, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_I2C1, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_I2C2, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_I2C3, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_I2C4, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_UART1, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_UART2, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_UART3, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_UART4, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ECSPI1, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ECSPI2, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_PWM1, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_PWM2, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_PWM3, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_PWM4, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_GPT1, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPT2, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPT3, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPT4, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPT5, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPT6, 100 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_WDOG, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_IPP_DO_CLKO1, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_IPP_DO_CLKO2, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HDMI_REF_266M, 266 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_USDHC3, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_MIPI_PHY1_REF, 300 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_DISP1_PIX, 250 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_CAM2_PIX, 277 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_LDB, 595 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ECSPI3, 80 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_PDM, 200 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_SAI7, 66666667 }, /* Datasheet claims 66MHz */ ++ { IMX8MP_CLK_MAIN_AXI, 400 * HZ_PER_MHZ }, ++ { /* Sentinel */ } ++}; ++ ++static const struct imx8mp_clock_constraints imx8mp_clock_nominal_constraints[] = { ++ { IMX8MP_CLK_M7_CORE, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ML_CORE, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU3D_CORE, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU3D_SHADER_CORE, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU2D_CORE, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_AUDIO_AXI_SRC, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HSIO_AXI, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_ISP, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_BUS, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_AXI, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HDMI_AXI, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU_AXI, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU_AHB, 300 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_NOC, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_NOC_IO, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ML_AHB, 300 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_G1, 600 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_G2, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_CAM1_PIX, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_VC8000E, 400 * HZ_PER_MHZ }, /* Datasheet claims 500MHz */ ++ { IMX8MP_CLK_DRAM_CORE, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GIC, 400 * HZ_PER_MHZ }, ++ { /* Sentinel */ } ++}; ++ ++static const struct imx8mp_clock_constraints imx8mp_clock_overdrive_constraints[] = { ++ { IMX8MP_CLK_M7_CORE, 800 * HZ_PER_MHZ}, ++ { IMX8MP_CLK_ML_CORE, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU3D_CORE, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU3D_SHADER_CORE, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU2D_CORE, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_AUDIO_AXI_SRC, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HSIO_AXI, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_ISP, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_BUS, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_AXI, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_HDMI_AXI, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU_AXI, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GPU_AHB, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_NOC, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_NOC_IO, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_ML_AHB, 400 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_G1, 800 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_G2, 700 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_MEDIA_CAM1_PIX, 500 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_VPU_VC8000E, 500 * HZ_PER_MHZ }, /* Datasheet claims 400MHz */ ++ { IMX8MP_CLK_DRAM_CORE, 1000 * HZ_PER_MHZ }, ++ { IMX8MP_CLK_GIC, 500 * HZ_PER_MHZ }, ++ { /* Sentinel */ } ++}; ++ ++static void imx8mp_clocks_apply_constraints(const struct imx8mp_clock_constraints constraints[]) ++{ ++ const struct imx8mp_clock_constraints *constr; ++ ++ for (constr = constraints; constr->clkid; constr++) ++ clk_hw_set_rate_range(hws[constr->clkid], 0, constr->maxrate); ++} ++ + static int imx8mp_clocks_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + struct device_node *np; + void __iomem *anatop_base, *ccm_base; ++ const char *opmode; + int err; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); +@@ -715,6 +856,16 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) + + imx_check_clk_hws(hws, IMX8MP_CLK_END); + ++ imx8mp_clocks_apply_constraints(imx8mp_clock_common_constraints); ++ ++ err = of_property_read_string(np, "fsl,operating-mode", &opmode); ++ if (!err) { ++ if (!strcmp(opmode, "nominal")) ++ imx8mp_clocks_apply_constraints(imx8mp_clock_nominal_constraints); ++ else if (!strcmp(opmode, "overdrive")) ++ imx8mp_clocks_apply_constraints(imx8mp_clock_overdrive_constraints); ++ } ++ + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (err < 0) { + dev_err(dev, "failed to register hws for i.MX8MP\n"); +-- +2.39.5 + diff --git a/queue-6.6/clk-qcom-camcc-sm8250-use-clk_rcg2_shared_ops-for-so.patch b/queue-6.6/clk-qcom-camcc-sm8250-use-clk_rcg2_shared_ops-for-so.patch new file mode 100644 index 0000000000..240312bf86 --- /dev/null +++ b/queue-6.6/clk-qcom-camcc-sm8250-use-clk_rcg2_shared_ops-for-so.patch @@ -0,0 +1,285 @@ +From a8aac06938d3922be2866894ad65f1555095f1ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 22:26:12 +0000 +Subject: clk: qcom: camcc-sm8250: Use clk_rcg2_shared_ops for some RCGs + +From: Jordan Crouse + +[ Upstream commit 52b10b591f83dc6d9a1d6c2dc89433470a787ecd ] + +Update some RCGs on the sm8250 camera clock controller to use +clk_rcg2_shared_ops. The shared_ops ensure the RCGs get parked +to the XO during clock disable to prevent the clocks from locking up +when the GDSC is enabled. These mirror similar fixes for other controllers +such as commit e5c359f70e4b ("clk: qcom: camcc: Update the clock ops for +the SC7180"). + +Signed-off-by: Jordan Crouse +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Bryan O'Donoghue +Link: https://lore.kernel.org/r/20250122222612.32351-1-jorcrous@amazon.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm8250.c | 56 ++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 28 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c +index 9b32c56a5bc5a..e29706d782870 100644 +--- a/drivers/clk/qcom/camcc-sm8250.c ++++ b/drivers/clk/qcom/camcc-sm8250.c +@@ -411,7 +411,7 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -433,7 +433,7 @@ static struct clk_rcg2 cam_cc_camnoc_axi_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -454,7 +454,7 @@ static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -469,7 +469,7 @@ static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -490,7 +490,7 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -511,7 +511,7 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -526,7 +526,7 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -556,7 +556,7 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -571,7 +571,7 @@ static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -586,7 +586,7 @@ static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -611,7 +611,7 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -634,7 +634,7 @@ static struct clk_rcg2 cam_cc_fd_core_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -649,7 +649,7 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -673,7 +673,7 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -710,7 +710,7 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -734,7 +734,7 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -749,7 +749,7 @@ static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -771,7 +771,7 @@ static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -786,7 +786,7 @@ static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -810,7 +810,7 @@ static struct clk_rcg2 cam_cc_ipe_0_clk_src = { + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -825,7 +825,7 @@ static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -847,7 +847,7 @@ static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -862,7 +862,7 @@ static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -877,7 +877,7 @@ static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -892,7 +892,7 @@ static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -907,7 +907,7 @@ static struct clk_rcg2 cam_cc_mclk4_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -922,7 +922,7 @@ static struct clk_rcg2 cam_cc_mclk5_clk_src = { + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +@@ -993,7 +993,7 @@ static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_ops, ++ .ops = &clk_rcg2_shared_ops, + }, + }; + +-- +2.39.5 + diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-do-not-use-random-stack-value.patch b/queue-6.6/clk-qcom-clk-alpha-pll-do-not-use-random-stack-value.patch new file mode 100644 index 0000000000..8fa09161db --- /dev/null +++ b/queue-6.6/clk-qcom-clk-alpha-pll-do-not-use-random-stack-value.patch @@ -0,0 +1,143 @@ +From 4a27bc862c6b84e8b37987e0280c7308211fd149 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 21:01:35 +0100 +Subject: clk: qcom: clk-alpha-pll: Do not use random stack value for recalc + rate + +From: Krzysztof Kozlowski + +[ Upstream commit 7a243e1b814a02ab40793026ef64223155d86395 ] + +If regmap_read() fails, random stack value was used in calculating new +frequency in recalc_rate() callbacks. Such failure is really not +expected as these are all MMIO reads, however code should be here +correct and bail out. This also avoids possible warning on +uninitialized value. + +Signed-off-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20250212-b4-clk-qcom-clean-v3-1-499f37444f5d@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-alpha-pll.c | 52 ++++++++++++++++++++++---------- + 1 file changed, 36 insertions(+), 16 deletions(-) + +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 80aadafffacdb..732ca46703ba3 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -645,14 +645,19 @@ clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 alpha_width = pll_alpha_width(pll); + +- regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); ++ if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) ++ return 0; ++ ++ if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) ++ return 0; + +- regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); + if (ctl & PLL_ALPHA_EN) { +- regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low); ++ if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &low)) ++ return 0; + if (alpha_width > 32) { +- regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), +- &high); ++ if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), ++ &high)) ++ return 0; + a = (u64)high << 32 | low; + } else { + a = low & GENMASK(alpha_width - 1, 0); +@@ -844,8 +849,11 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, alpha = 0, ctl, alpha_m, alpha_n; + +- regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); +- regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); ++ if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) ++ return 0; ++ ++ if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) ++ return 0; + + if (ctl & PLL_ALPHA_EN) { + regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha); +@@ -1039,8 +1047,11 @@ clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, frac, alpha_width = pll_alpha_width(pll); + +- regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); +- regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac); ++ if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) ++ return 0; ++ ++ if (regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &frac)) ++ return 0; + + return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); + } +@@ -1098,7 +1109,8 @@ clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + u32 ctl; + +- regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl); ++ if (regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &ctl)) ++ return 0; + + ctl >>= PLL_POST_DIV_SHIFT; + ctl &= PLL_POST_DIV_MASK(pll); +@@ -1314,8 +1326,11 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, frac, alpha_width = pll_alpha_width(pll); + +- regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); +- regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac); ++ if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) ++ return 0; ++ ++ if (regmap_read(pll->clkr.regmap, PLL_FRAC(pll), &frac)) ++ return 0; + + return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); + } +@@ -1465,7 +1480,8 @@ clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) + struct regmap *regmap = pll->clkr.regmap; + u32 i, div = 1, val; + +- regmap_read(regmap, PLL_USER_CTL(pll), &val); ++ if (regmap_read(regmap, PLL_USER_CTL(pll), &val)) ++ return 0; + + val >>= pll->post_div_shift; + val &= PLL_POST_DIV_MASK(pll); +@@ -2339,9 +2355,12 @@ static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw, + struct regmap *regmap = pll->clkr.regmap; + u32 l, frac; + +- regmap_read(regmap, PLL_L_VAL(pll), &l); ++ if (regmap_read(regmap, PLL_L_VAL(pll), &l)) ++ return 0; + l &= LUCID_EVO_PLL_L_VAL_MASK; +- regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); ++ ++ if (regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac)) ++ return 0; + + return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll)); + } +@@ -2416,7 +2435,8 @@ static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw, + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l; + +- regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); ++ if (regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l)) ++ return 0; + + return parent_rate * l; + } +-- +2.39.5 + diff --git a/queue-6.6/clk-qcom-ipq5018-allow-it-to-be-bulid-on-arm32.patch b/queue-6.6/clk-qcom-ipq5018-allow-it-to-be-bulid-on-arm32.patch new file mode 100644 index 0000000000..f3f18597a8 --- /dev/null +++ b/queue-6.6/clk-qcom-ipq5018-allow-it-to-be-bulid-on-arm32.patch @@ -0,0 +1,40 @@ +From 3aaf42fffe9782dd94d3dec70872057152417f1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 00:34:12 +0800 +Subject: clk: qcom: ipq5018: allow it to be bulid on arm32 + +From: Karl Chan + +[ Upstream commit 5d02941c83997b58e8fc15390290c7c6975acaff ] + +There are some ipq5018 based device's firmware only can able to boot +arm32 but the clock driver dont allow it to be compiled on arm32. +Therefore allow GCC for IPQ5018 to be selected when building ARM32 +kernel + +Signed-off-by: Karl Chan +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20241007163414.32458-4-exxxxkc@getgoogleoff.me +[bjorn: Updated commit message, per Dmitry's suggestion] +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig +index 1de1661037b1b..95cbea8d380c3 100644 +--- a/drivers/clk/qcom/Kconfig ++++ b/drivers/clk/qcom/Kconfig +@@ -148,7 +148,7 @@ config IPQ_GCC_4019 + + config IPQ_GCC_5018 + tristate "IPQ5018 Global Clock Controller" +- depends on ARM64 || COMPILE_TEST ++ depends on ARM || ARM64 || COMPILE_TEST + help + Support for global clock controller on ipq5018 devices. + Say Y if you want to use peripheral devices such as UART, SPI, +-- +2.39.5 + diff --git a/queue-6.6/clocksource-mips-gic-timer-enable-counter-when-cpus-.patch b/queue-6.6/clocksource-mips-gic-timer-enable-counter-when-cpus-.patch new file mode 100644 index 0000000000..b0aa967cc7 --- /dev/null +++ b/queue-6.6/clocksource-mips-gic-timer-enable-counter-when-cpus-.patch @@ -0,0 +1,68 @@ +From fa9355401a51c6e14be1dfe4db256d349dcc8c27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jan 2025 13:32:47 +0100 +Subject: clocksource: mips-gic-timer: Enable counter when CPUs start +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Burton + +[ Upstream commit 3128b0a2e0cf6e07aa78e5f8cf7dd9cd59dc8174 ] + +In multi-cluster MIPS I6500 systems there is a GIC in each cluster, +each with its own counter. When a cluster powers up the counter will +be stopped, with the COUNTSTOP bit set in the GIC_CONFIG register. + +In single cluster systems, it has been fine to clear COUNTSTOP once +in gic_clocksource_of_init() to start the counter. In multi-cluster +systems, this will only have started the counter in the boot cluster, +and any CPUs in other clusters will find their counter stopped which +will break the GIC clock_event_device. + +Resolve this by having CPUs clear the COUNTSTOP bit when they come +online, using the existing gic_starting_cpu() CPU hotplug callback. This +will allow CPUs in secondary clusters to ensure that the cluster's GIC +counter is running as expected. + +Signed-off-by: Paul Burton +Signed-off-by: Chao-ying Fu +Signed-off-by: Dragan Mladjenovic +Signed-off-by: Aleksandar Rikalo +Reviewed-by: Philippe Mathieu-Daudé +Tested-by: Serge Semin +Tested-by: Gregory CLEMENT +Acked-by: Daniel Lezcano +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + drivers/clocksource/mips-gic-timer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c +index b3ae38f367205..39c70b5ac44c9 100644 +--- a/drivers/clocksource/mips-gic-timer.c ++++ b/drivers/clocksource/mips-gic-timer.c +@@ -114,6 +114,9 @@ static void gic_update_frequency(void *data) + + static int gic_starting_cpu(unsigned int cpu) + { ++ /* Ensure the GIC counter is running */ ++ clear_gic_config(GIC_CONFIG_COUNTSTOP); ++ + gic_clockevent_cpu_init(cpu, this_cpu_ptr(&gic_clockevent_device)); + return 0; + } +@@ -248,9 +251,6 @@ static int __init gic_clocksource_of_init(struct device_node *node) + pr_warn("Unable to register clock notifier\n"); + } + +- /* And finally start the counter */ +- clear_gic_config(GIC_CONFIG_COUNTSTOP); +- + /* + * It's safe to use the MIPS GIC timer as a sched clock source only if + * its ticks are stable, which is true on either the platforms with +-- +2.39.5 + diff --git a/queue-6.6/cpufreq-add-sm8650-to-cpufreq-dt-platdev-blocklist.patch b/queue-6.6/cpufreq-add-sm8650-to-cpufreq-dt-platdev-blocklist.patch new file mode 100644 index 0000000000..c0cfe4f202 --- /dev/null +++ b/queue-6.6/cpufreq-add-sm8650-to-cpufreq-dt-platdev-blocklist.patch @@ -0,0 +1,39 @@ +From 4c8817844ff4e6954dd10480b142172c5ebeb42f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 5 Apr 2025 00:42:19 +0800 +Subject: cpufreq: Add SM8650 to cpufreq-dt-platdev blocklist + +From: Pengyu Luo + +[ Upstream commit fc5414a4774e14e51a93499a6adfdc45f2de82e0 ] + +SM8650 have already been supported by qcom-cpufreq-hw driver, but +never been added to cpufreq-dt-platdev. This makes noise + +[ 0.388525] cpufreq-dt cpufreq-dt: failed register driver: -17 +[ 0.388537] cpufreq-dt cpufreq-dt: probe with driver cpufreq-dt failed with error -17 + +So adding it to the cpufreq-dt-platdev driver's blocklist to fix it. + +Signed-off-by: Pengyu Luo +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 09becf14653b5..c58c1defd7458 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -165,6 +165,7 @@ static const struct of_device_id blocklist[] __initconst = { + { .compatible = "qcom,sm8350", }, + { .compatible = "qcom,sm8450", }, + { .compatible = "qcom,sm8550", }, ++ { .compatible = "qcom,sm8650", }, + + { .compatible = "st,stih407", }, + { .compatible = "st,stih410", }, +-- +2.39.5 + diff --git a/queue-6.6/cpufreq-tegra186-share-policy-per-cluster.patch b/queue-6.6/cpufreq-tegra186-share-policy-per-cluster.patch new file mode 100644 index 0000000000..4cbec5e66d --- /dev/null +++ b/queue-6.6/cpufreq-tegra186-share-policy-per-cluster.patch @@ -0,0 +1,47 @@ +From 938b4efe7fc0b93f7fc79580abab548fbddc553a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 00:28:48 -0500 +Subject: cpufreq: tegra186: Share policy per cluster + +From: Aaron Kling + +[ Upstream commit be4ae8c19492cd6d5de61ccb34ffb3f5ede5eec8 ] + +This functionally brings tegra186 in line with tegra210 and tegra194, +sharing a cpufreq policy between all cores in a cluster. + +Reviewed-by: Sumit Gupta +Acked-by: Thierry Reding +Signed-off-by: Aaron Kling +Signed-off-by: Viresh Kumar +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/tegra186-cpufreq.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c +index 7b8fcfa55038b..4e5b6f9a56d1b 100644 +--- a/drivers/cpufreq/tegra186-cpufreq.c ++++ b/drivers/cpufreq/tegra186-cpufreq.c +@@ -73,11 +73,18 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy) + { + struct tegra186_cpufreq_data *data = cpufreq_get_driver_data(); + unsigned int cluster = data->cpus[policy->cpu].bpmp_cluster_id; ++ u32 cpu; + + policy->freq_table = data->clusters[cluster].table; + policy->cpuinfo.transition_latency = 300 * 1000; + policy->driver_data = NULL; + ++ /* set same policy for all cpus in a cluster */ ++ for (cpu = 0; cpu < ARRAY_SIZE(tegra186_cpus); cpu++) { ++ if (data->cpus[cpu].bpmp_cluster_id == cluster) ++ cpumask_set_cpu(cpu, policy->cpus); ++ } ++ + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.6/cpuidle-menu-avoid-discarding-useful-information.patch b/queue-6.6/cpuidle-menu-avoid-discarding-useful-information.patch new file mode 100644 index 0000000000..31ae8aa0af --- /dev/null +++ b/queue-6.6/cpuidle-menu-avoid-discarding-useful-information.patch @@ -0,0 +1,65 @@ +From 1db38926609ad9c748775f23296ee9c23540938f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 15:29:05 +0100 +Subject: cpuidle: menu: Avoid discarding useful information + +From: Rafael J. Wysocki + +[ Upstream commit 85975daeaa4d6ec560bfcd354fc9c08ad7f38888 ] + +When giving up on making a high-confidence prediction, +get_typical_interval() always returns UINT_MAX which means that the +next idle interval prediction will be based entirely on the time till +the next timer. However, the information represented by the most +recent intervals may not be completely useless in those cases. + +Namely, the largest recent idle interval is an upper bound on the +recently observed idle duration, so it is reasonable to assume that +the next idle duration is unlikely to exceed it. Moreover, this is +still true after eliminating the suspected outliers if the sample +set still under consideration is at least as large as 50% of the +maximum sample set size. + +Accordingly, make get_typical_interval() return the current maximum +recent interval value in that case instead of UINT_MAX. + +Signed-off-by: Rafael J. Wysocki +Reported-by: Artem Bityutskiy +Tested-by: Artem Bityutskiy +Reviewed-by: Christian Loehle +Tested-by: Christian Loehle +Tested-by: Aboorva Devarajan +Link: https://patch.msgid.link/7770672.EvYhyI6sBW@rjwysocki.net +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/governors/menu.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c +index b96e3da0fedd0..edd9a8fb9878d 100644 +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -246,8 +246,19 @@ static unsigned int get_typical_interval(struct menu_device *data) + * This can deal with workloads that have long pauses interspersed + * with sporadic activity with a bunch of short pauses. + */ +- if ((divisor * 4) <= INTERVALS * 3) ++ if (divisor * 4 <= INTERVALS * 3) { ++ /* ++ * If there are sufficiently many data points still under ++ * consideration after the outliers have been eliminated, ++ * returning without a prediction would be a mistake because it ++ * is likely that the next interval will not exceed the current ++ * maximum, so return the latter in that case. ++ */ ++ if (divisor >= INTERVALS / 2) ++ return max; ++ + return UINT_MAX; ++ } + + thresh = max - 1; + goto again; +-- +2.39.5 + diff --git a/queue-6.6/crypto-ahash-set-default-reqsize-from-ahash_alg.patch b/queue-6.6/crypto-ahash-set-default-reqsize-from-ahash_alg.patch new file mode 100644 index 0000000000..53ba49654f --- /dev/null +++ b/queue-6.6/crypto-ahash-set-default-reqsize-from-ahash_alg.patch @@ -0,0 +1,66 @@ +From 049527b4756b519e42d99fe41f25fb714b3ff30c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Feb 2025 11:07:24 +0800 +Subject: crypto: ahash - Set default reqsize from ahash_alg + +From: Herbert Xu + +[ Upstream commit 9e01aaa1033d6e40f8d7cf4f20931a61ce9e3f04 ] + +Add a reqsize field to struct ahash_alg and use it to set the +default reqsize so that algorithms with a static reqsize are +not forced to create an init_tfm function. + +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ahash.c | 4 ++++ + include/crypto/hash.h | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index 709ef09407991..6168f3532f552 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -427,6 +427,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) + hash->setkey = ahash_nosetkey; + + crypto_ahash_set_statesize(hash, alg->halg.statesize); ++ crypto_ahash_set_reqsize(hash, alg->reqsize); + + if (tfm->__crt_alg->cra_type != &crypto_ahash_type) + return crypto_init_shash_ops_async(tfm); +@@ -599,6 +600,9 @@ static int ahash_prepare_alg(struct ahash_alg *alg) + if (alg->halg.statesize == 0) + return -EINVAL; + ++ if (alg->reqsize && alg->reqsize < alg->halg.statesize) ++ return -EINVAL; ++ + err = hash_prepare_alg(&alg->halg); + if (err) + return err; +diff --git a/include/crypto/hash.h b/include/crypto/hash.h +index f7c2a22cd776d..c0d472fdc82e6 100644 +--- a/include/crypto/hash.h ++++ b/include/crypto/hash.h +@@ -153,6 +153,7 @@ struct ahash_request { + * This is a counterpart to @init_tfm, used to remove + * various changes set in @init_tfm. + * @clone_tfm: Copy transform into new object, may allocate memory. ++ * @reqsize: Size of the request context. + * @halg: see struct hash_alg_common + */ + struct ahash_alg { +@@ -169,6 +170,8 @@ struct ahash_alg { + void (*exit_tfm)(struct crypto_ahash *tfm); + int (*clone_tfm)(struct crypto_ahash *dst, struct crypto_ahash *src); + ++ unsigned int reqsize; ++ + struct hash_alg_common halg; + }; + +-- +2.39.5 + diff --git a/queue-6.6/crypto-lzo-fix-compression-buffer-overrun.patch b/queue-6.6/crypto-lzo-fix-compression-buffer-overrun.patch new file mode 100644 index 0000000000..9c697af850 --- /dev/null +++ b/queue-6.6/crypto-lzo-fix-compression-buffer-overrun.patch @@ -0,0 +1,374 @@ +From e6f91c7f895b5b698944cf42c43683e07570337b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 17:04:46 +0800 +Subject: crypto: lzo - Fix compression buffer overrun + +From: Herbert Xu + +[ Upstream commit cc47f07234f72cbd8e2c973cdbf2a6730660a463 ] + +Unlike the decompression code, the compression code in LZO never +checked for output overruns. It instead assumes that the caller +always provides enough buffer space, disregarding the buffer length +provided by the caller. + +Add a safe compression interface that checks for the end of buffer +before each write. Use the safe interface in crypto/lzo. + +Signed-off-by: Herbert Xu +Reviewed-by: David Sterba +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/lzo-rle.c | 2 +- + crypto/lzo.c | 2 +- + include/linux/lzo.h | 8 +++ + lib/lzo/Makefile | 2 +- + lib/lzo/lzo1x_compress.c | 102 +++++++++++++++++++++++++--------- + lib/lzo/lzo1x_compress_safe.c | 18 ++++++ + 6 files changed, 106 insertions(+), 28 deletions(-) + create mode 100644 lib/lzo/lzo1x_compress_safe.c + +diff --git a/crypto/lzo-rle.c b/crypto/lzo-rle.c +index 0631d975bfac1..0abc2d87f0420 100644 +--- a/crypto/lzo-rle.c ++++ b/crypto/lzo-rle.c +@@ -55,7 +55,7 @@ static int __lzorle_compress(const u8 *src, unsigned int slen, + size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ + int err; + +- err = lzorle1x_1_compress(src, slen, dst, &tmp_len, ctx); ++ err = lzorle1x_1_compress_safe(src, slen, dst, &tmp_len, ctx); + + if (err != LZO_E_OK) + return -EINVAL; +diff --git a/crypto/lzo.c b/crypto/lzo.c +index ebda132dd22bf..8338851c7406a 100644 +--- a/crypto/lzo.c ++++ b/crypto/lzo.c +@@ -55,7 +55,7 @@ static int __lzo_compress(const u8 *src, unsigned int slen, + size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ + int err; + +- err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx); ++ err = lzo1x_1_compress_safe(src, slen, dst, &tmp_len, ctx); + + if (err != LZO_E_OK) + return -EINVAL; +diff --git a/include/linux/lzo.h b/include/linux/lzo.h +index e95c7d1092b28..4d30e3624acd2 100644 +--- a/include/linux/lzo.h ++++ b/include/linux/lzo.h +@@ -24,10 +24,18 @@ + int lzo1x_1_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + ++/* Same as above but does not write more than dst_len to dst. */ ++int lzo1x_1_compress_safe(const unsigned char *src, size_t src_len, ++ unsigned char *dst, size_t *dst_len, void *wrkmem); ++ + /* This requires 'wrkmem' of size LZO1X_1_MEM_COMPRESS */ + int lzorle1x_1_compress(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len, void *wrkmem); + ++/* Same as above but does not write more than dst_len to dst. */ ++int lzorle1x_1_compress_safe(const unsigned char *src, size_t src_len, ++ unsigned char *dst, size_t *dst_len, void *wrkmem); ++ + /* safe decompression with overrun testing */ + int lzo1x_decompress_safe(const unsigned char *src, size_t src_len, + unsigned char *dst, size_t *dst_len); +diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile +index 2f58fafbbdddc..fc7b2b7ef4b20 100644 +--- a/lib/lzo/Makefile ++++ b/lib/lzo/Makefile +@@ -1,5 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-only +-lzo_compress-objs := lzo1x_compress.o ++lzo_compress-objs := lzo1x_compress.o lzo1x_compress_safe.o + lzo_decompress-objs := lzo1x_decompress_safe.o + + obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o +diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c +index 9d31e7126606a..f00dff9b9d4e1 100644 +--- a/lib/lzo/lzo1x_compress.c ++++ b/lib/lzo/lzo1x_compress.c +@@ -18,11 +18,22 @@ + #include + #include "lzodefs.h" + +-static noinline size_t +-lzo1x_1_do_compress(const unsigned char *in, size_t in_len, +- unsigned char *out, size_t *out_len, +- size_t ti, void *wrkmem, signed char *state_offset, +- const unsigned char bitstream_version) ++#undef LZO_UNSAFE ++ ++#ifndef LZO_SAFE ++#define LZO_UNSAFE 1 ++#define LZO_SAFE(name) name ++#define HAVE_OP(x) 1 ++#endif ++ ++#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun ++ ++static noinline int ++LZO_SAFE(lzo1x_1_do_compress)(const unsigned char *in, size_t in_len, ++ unsigned char **out, unsigned char *op_end, ++ size_t *tp, void *wrkmem, ++ signed char *state_offset, ++ const unsigned char bitstream_version) + { + const unsigned char *ip; + unsigned char *op; +@@ -30,8 +41,9 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + const unsigned char * const ip_end = in + in_len - 20; + const unsigned char *ii; + lzo_dict_t * const dict = (lzo_dict_t *) wrkmem; ++ size_t ti = *tp; + +- op = out; ++ op = *out; + ip = in; + ii = ip; + ip += ti < 4 ? 4 - ti : 0; +@@ -116,25 +128,32 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + if (t != 0) { + if (t <= 3) { + op[*state_offset] |= t; ++ NEED_OP(4); + COPY4(op, ii); + op += t; + } else if (t <= 16) { ++ NEED_OP(17); + *op++ = (t - 3); + COPY8(op, ii); + COPY8(op + 8, ii + 8); + op += t; + } else { + if (t <= 18) { ++ NEED_OP(1); + *op++ = (t - 3); + } else { + size_t tt = t - 18; ++ NEED_OP(1); + *op++ = 0; + while (unlikely(tt > 255)) { + tt -= 255; ++ NEED_OP(1); + *op++ = 0; + } ++ NEED_OP(1); + *op++ = tt; + } ++ NEED_OP(t); + do { + COPY8(op, ii); + COPY8(op + 8, ii + 8); +@@ -151,6 +170,7 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + if (unlikely(run_length)) { + ip += run_length; + run_length -= MIN_ZERO_RUN_LENGTH; ++ NEED_OP(4); + put_unaligned_le32((run_length << 21) | 0xfffc18 + | (run_length & 0x7), op); + op += 4; +@@ -243,10 +263,12 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + ip += m_len; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) { + m_off -= 1; ++ NEED_OP(2); + *op++ = (((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = (m_off >> 3); + } else if (m_off <= M3_MAX_OFFSET) { + m_off -= 1; ++ NEED_OP(1); + if (m_len <= M3_MAX_LEN) + *op++ = (M3_MARKER | (m_len - 2)); + else { +@@ -254,14 +276,18 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + *op++ = M3_MARKER | 0; + while (unlikely(m_len > 255)) { + m_len -= 255; ++ NEED_OP(1); + *op++ = 0; + } ++ NEED_OP(1); + *op++ = (m_len); + } ++ NEED_OP(2); + *op++ = (m_off << 2); + *op++ = (m_off >> 6); + } else { + m_off -= 0x4000; ++ NEED_OP(1); + if (m_len <= M4_MAX_LEN) + *op++ = (M4_MARKER | ((m_off >> 11) & 8) + | (m_len - 2)); +@@ -282,11 +308,14 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + m_len -= M4_MAX_LEN; + *op++ = (M4_MARKER | ((m_off >> 11) & 8)); + while (unlikely(m_len > 255)) { ++ NEED_OP(1); + m_len -= 255; + *op++ = 0; + } ++ NEED_OP(1); + *op++ = (m_len); + } ++ NEED_OP(2); + *op++ = (m_off << 2); + *op++ = (m_off >> 6); + } +@@ -295,14 +324,20 @@ lzo1x_1_do_compress(const unsigned char *in, size_t in_len, + ii = ip; + goto next; + } +- *out_len = op - out; +- return in_end - (ii - ti); ++ *out = op; ++ *tp = in_end - (ii - ti); ++ return LZO_E_OK; ++ ++output_overrun: ++ return LZO_E_OUTPUT_OVERRUN; + } + +-static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len, +- unsigned char *out, size_t *out_len, +- void *wrkmem, const unsigned char bitstream_version) ++static int LZO_SAFE(lzogeneric1x_1_compress)( ++ const unsigned char *in, size_t in_len, ++ unsigned char *out, size_t *out_len, ++ void *wrkmem, const unsigned char bitstream_version) + { ++ unsigned char * const op_end = out + *out_len; + const unsigned char *ip = in; + unsigned char *op = out; + unsigned char *data_start; +@@ -326,14 +361,18 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len, + while (l > 20) { + size_t ll = min_t(size_t, l, m4_max_offset + 1); + uintptr_t ll_end = (uintptr_t) ip + ll; ++ int err; ++ + if ((ll_end + ((t + ll) >> 5)) <= ll_end) + break; + BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS); + memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t)); +- t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem, +- &state_offset, bitstream_version); ++ err = LZO_SAFE(lzo1x_1_do_compress)( ++ ip, ll, &op, op_end, &t, wrkmem, ++ &state_offset, bitstream_version); ++ if (err != LZO_E_OK) ++ return err; + ip += ll; +- op += *out_len; + l -= ll; + } + t += l; +@@ -342,20 +381,26 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len, + const unsigned char *ii = in + in_len - t; + + if (op == data_start && t <= 238) { ++ NEED_OP(1); + *op++ = (17 + t); + } else if (t <= 3) { + op[state_offset] |= t; + } else if (t <= 18) { ++ NEED_OP(1); + *op++ = (t - 3); + } else { + size_t tt = t - 18; ++ NEED_OP(1); + *op++ = 0; + while (tt > 255) { + tt -= 255; ++ NEED_OP(1); + *op++ = 0; + } ++ NEED_OP(1); + *op++ = tt; + } ++ NEED_OP(t); + if (t >= 16) do { + COPY8(op, ii); + COPY8(op + 8, ii + 8); +@@ -368,31 +413,38 @@ static int lzogeneric1x_1_compress(const unsigned char *in, size_t in_len, + } while (--t > 0); + } + ++ NEED_OP(3); + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = op - out; + return LZO_E_OK; ++ ++output_overrun: ++ return LZO_E_OUTPUT_OVERRUN; + } + +-int lzo1x_1_compress(const unsigned char *in, size_t in_len, +- unsigned char *out, size_t *out_len, +- void *wrkmem) ++int LZO_SAFE(lzo1x_1_compress)(const unsigned char *in, size_t in_len, ++ unsigned char *out, size_t *out_len, ++ void *wrkmem) + { +- return lzogeneric1x_1_compress(in, in_len, out, out_len, wrkmem, 0); ++ return LZO_SAFE(lzogeneric1x_1_compress)( ++ in, in_len, out, out_len, wrkmem, 0); + } + +-int lzorle1x_1_compress(const unsigned char *in, size_t in_len, +- unsigned char *out, size_t *out_len, +- void *wrkmem) ++int LZO_SAFE(lzorle1x_1_compress)(const unsigned char *in, size_t in_len, ++ unsigned char *out, size_t *out_len, ++ void *wrkmem) + { +- return lzogeneric1x_1_compress(in, in_len, out, out_len, +- wrkmem, LZO_VERSION); ++ return LZO_SAFE(lzogeneric1x_1_compress)( ++ in, in_len, out, out_len, wrkmem, LZO_VERSION); + } + +-EXPORT_SYMBOL_GPL(lzo1x_1_compress); +-EXPORT_SYMBOL_GPL(lzorle1x_1_compress); ++EXPORT_SYMBOL_GPL(LZO_SAFE(lzo1x_1_compress)); ++EXPORT_SYMBOL_GPL(LZO_SAFE(lzorle1x_1_compress)); + ++#ifndef LZO_UNSAFE + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("LZO1X-1 Compressor"); ++#endif +diff --git a/lib/lzo/lzo1x_compress_safe.c b/lib/lzo/lzo1x_compress_safe.c +new file mode 100644 +index 0000000000000..371c9f8494928 +--- /dev/null ++++ b/lib/lzo/lzo1x_compress_safe.c +@@ -0,0 +1,18 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * LZO1X Compressor from LZO ++ * ++ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer ++ * ++ * The full LZO package can be found at: ++ * http://www.oberhumer.com/opensource/lzo/ ++ * ++ * Changed for Linux kernel use by: ++ * Nitin Gupta ++ * Richard Purdie ++ */ ++ ++#define LZO_SAFE(name) name##_safe ++#define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x)) ++ ++#include "lzo1x_compress.c" +-- +2.39.5 + diff --git a/queue-6.6/crypto-octeontx2-suppress-auth-failure-screaming-due.patch b/queue-6.6/crypto-octeontx2-suppress-auth-failure-screaming-due.patch new file mode 100644 index 0000000000..56f6b67eee --- /dev/null +++ b/queue-6.6/crypto-octeontx2-suppress-auth-failure-screaming-due.patch @@ -0,0 +1,43 @@ +From e8d9d4c7f2dd1c172fcc2760a2a4b5b8716bfeee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 13:27:05 +0530 +Subject: crypto: octeontx2 - suppress auth failure screaming due to negative + tests + +From: Shashank Gupta + +[ Upstream commit 64b7871522a4cba99d092e1c849d6f9092868aaa ] + +This patch addresses an issue where authentication failures were being +erroneously reported due to negative test failures in the "ccm(aes)" +selftest. +pr_debug suppress unnecessary screaming of these tests. + +Signed-off-by: Shashank Gupta +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/marvell/octeontx2/otx2_cptvf_reqmgr.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_reqmgr.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_reqmgr.c +index 811ded72ce5fb..798bb40fed68d 100644 +--- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_reqmgr.c ++++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_reqmgr.c +@@ -410,9 +410,10 @@ static int cpt_process_ccode(struct otx2_cptlfs_info *lfs, + break; + } + +- dev_err(&pdev->dev, +- "Request failed with software error code 0x%x\n", +- cpt_status->s.uc_compcode); ++ pr_debug("Request failed with software error code 0x%x: algo = %s driver = %s\n", ++ cpt_status->s.uc_compcode, ++ info->req->areq->tfm->__crt_alg->cra_name, ++ info->req->areq->tfm->__crt_alg->cra_driver_name); + otx2_cpt_dump_sg_list(pdev, info->req); + break; + } +-- +2.39.5 + diff --git a/queue-6.6/crypto-skcipher-zap-type-in-crypto_alloc_sync_skciph.patch b/queue-6.6/crypto-skcipher-zap-type-in-crypto_alloc_sync_skciph.patch new file mode 100644 index 0000000000..010c1ffe9f --- /dev/null +++ b/queue-6.6/crypto-skcipher-zap-type-in-crypto_alloc_sync_skciph.patch @@ -0,0 +1,33 @@ +From 59db22222b6c793181559f3cadb9d3b63e9b8829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Feb 2025 08:57:51 +0800 +Subject: crypto: skcipher - Zap type in crypto_alloc_sync_skcipher + +From: Herbert Xu + +[ Upstream commit ee509efc74ddbc59bb5d6fd6e050f9ef25f74bff ] + +The type needs to be zeroed as otherwise the user could use it to +allocate an asynchronous sync skcipher. + +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/skcipher.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/skcipher.c b/crypto/skcipher.c +index 7b275716cf4e3..acc879ed6031a 100644 +--- a/crypto/skcipher.c ++++ b/crypto/skcipher.c +@@ -811,6 +811,7 @@ struct crypto_sync_skcipher *crypto_alloc_sync_skcipher( + + /* Only sync algorithms allowed. */ + mask |= CRYPTO_ALG_ASYNC | CRYPTO_ALG_SKCIPHER_REQSIZE_LARGE; ++ type &= ~(CRYPTO_ALG_ASYNC | CRYPTO_ALG_SKCIPHER_REQSIZE_LARGE); + + tfm = crypto_alloc_tfm(alg_name, &crypto_skcipher_type, type, mask); + +-- +2.39.5 + diff --git a/queue-6.6/dlm-make-tcp-still-work-in-multi-link-env.patch b/queue-6.6/dlm-make-tcp-still-work-in-multi-link-env.patch new file mode 100644 index 0000000000..7b493dcf92 --- /dev/null +++ b/queue-6.6/dlm-make-tcp-still-work-in-multi-link-env.patch @@ -0,0 +1,37 @@ +From e66b589ae507c0bd05237e52ffb6b0f93495d875 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 15:36:21 +0800 +Subject: dlm: make tcp still work in multi-link env + +From: Heming Zhao + +[ Upstream commit 03d2b62208a336a3bb984b9465ef6d89a046ea22 ] + +This patch bypasses multi-link errors in TCP mode, allowing dlm +to operate on the first tcp link. + +Signed-off-by: Heming Zhao +Signed-off-by: David Teigland +Signed-off-by: Sasha Levin +--- + fs/dlm/lowcomms.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c +index 0618af36f5506..3c9ab6461579c 100644 +--- a/fs/dlm/lowcomms.c ++++ b/fs/dlm/lowcomms.c +@@ -1826,8 +1826,8 @@ static int dlm_tcp_listen_validate(void) + { + /* We don't support multi-homed hosts */ + if (dlm_local_count > 1) { +- log_print("TCP protocol can't handle multi-homed hosts, try SCTP"); +- return -EINVAL; ++ log_print("Detect multi-homed hosts but use only the first IP address."); ++ log_print("Try SCTP, if you want to enable multi-link."); + } + + return 0; +-- +2.39.5 + diff --git a/queue-6.6/dm-cache-prevent-bug_on-by-blocking-retries-on-faile.patch b/queue-6.6/dm-cache-prevent-bug_on-by-blocking-retries-on-faile.patch new file mode 100644 index 0000000000..cd16008be5 --- /dev/null +++ b/queue-6.6/dm-cache-prevent-bug_on-by-blocking-retries-on-faile.patch @@ -0,0 +1,121 @@ +From 2b5a959bdaf5e2f728fa7e7cbc84d6e34a4b7da6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 16:41:50 +0800 +Subject: dm cache: prevent BUG_ON by blocking retries on failed device resumes + +From: Ming-Hung Tsai + +[ Upstream commit 5da692e2262b8f81993baa9592f57d12c2703dea ] + +A cache device failing to resume due to mapping errors should not be +retried, as the failure leaves a partially initialized policy object. +Repeating the resume operation risks triggering BUG_ON when reloading +cache mappings into the incomplete policy object. + +Reproduce steps: + +1. create a cache metadata consisting of 512 or more cache blocks, + with some mappings stored in the first array block of the mapping + array. Here we use cache_restore v1.0 to build the metadata. + +cat <> cmeta.xml + + + + + +EOF +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +cache_restore -i cmeta.xml -o /dev/mapper/cmeta --metadata-version=2 +dmsetup remove cmeta + +2. wipe the second array block of the mapping array to simulate + data degradations. + +mapping_root=$(dd if=/dev/sdc bs=1c count=8 skip=192 \ +2>/dev/null | hexdump -e '1/8 "%u\n"') +ablock=$(dd if=/dev/sdc bs=1c count=8 skip=$((4096*mapping_root+2056)) \ +2>/dev/null | hexdump -e '1/8 "%u\n"') +dd if=/dev/zero of=/dev/sdc bs=4k count=1 seek=$ablock + +3. try bringing up the cache device. The resume is expected to fail + due to the broken array block. + +dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" +dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" +dmsetup create corig --table "0 524288 linear /dev/sdc 262144" +dmsetup create cache --notable +dmsetup load cache --table "0 524288 cache /dev/mapper/cmeta \ +/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0" +dmsetup resume cache + +4. try resuming the cache again. An unexpected BUG_ON is triggered + while loading cache mappings. + +dmsetup resume cache + +Kernel logs: + +(snip) +------------[ cut here ]------------ +kernel BUG at drivers/md/dm-cache-policy-smq.c:752! +Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI +CPU: 0 UID: 0 PID: 332 Comm: dmsetup Not tainted 6.13.4 #3 +RIP: 0010:smq_load_mapping+0x3e5/0x570 + +Fix by disallowing resume operations for devices that failed the +initial attempt. + +Signed-off-by: Ming-Hung Tsai +Signed-off-by: Mikulas Patocka +Signed-off-by: Sasha Levin +--- + drivers/md/dm-cache-target.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c +index c5851c9f7ec04..0d002d50329da 100644 +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2903,6 +2903,27 @@ static dm_cblock_t get_cache_dev_size(struct cache *cache) + return to_cblock(size); + } + ++static bool can_resume(struct cache *cache) ++{ ++ /* ++ * Disallow retrying the resume operation for devices that failed the ++ * first resume attempt, as the failure leaves the policy object partially ++ * initialized. Retrying could trigger BUG_ON when loading cache mappings ++ * into the incomplete policy object. ++ */ ++ if (cache->sized && !cache->loaded_mappings) { ++ if (get_cache_mode(cache) != CM_WRITE) ++ DMERR("%s: unable to resume a failed-loaded cache, please check metadata.", ++ cache_device_name(cache)); ++ else ++ DMERR("%s: unable to resume cache due to missing proper cache table reload", ++ cache_device_name(cache)); ++ return false; ++ } ++ ++ return true; ++} ++ + static bool can_resize(struct cache *cache, dm_cblock_t new_size) + { + if (from_cblock(new_size) > from_cblock(cache->cache_size)) { +@@ -2951,6 +2972,9 @@ static int cache_preresume(struct dm_target *ti) + struct cache *cache = ti->private; + dm_cblock_t csize = get_cache_dev_size(cache); + ++ if (!can_resume(cache)) ++ return -EINVAL; ++ + /* + * Check to see if the cache has resized. + */ +-- +2.39.5 + diff --git a/queue-6.6/dm-fix-unconditional-io-throttle-caused-by-req_prefl.patch b/queue-6.6/dm-fix-unconditional-io-throttle-caused-by-req_prefl.patch new file mode 100644 index 0000000000..f98d334cf8 --- /dev/null +++ b/queue-6.6/dm-fix-unconditional-io-throttle-caused-by-req_prefl.patch @@ -0,0 +1,82 @@ +From 678f33ac1835912036bbc9e4e8eb5969bf3556f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2025 19:20:14 +0800 +Subject: dm: fix unconditional IO throttle caused by REQ_PREFLUSH + +From: Jinliang Zheng + +[ Upstream commit 88f7f56d16f568f19e1a695af34a7f4a6ce537a6 ] + +When a bio with REQ_PREFLUSH is submitted to dm, __send_empty_flush() +generates a flush_bio with REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC, +which causes the flush_bio to be throttled by wbt_wait(). + +An example from v5.4, similar problem also exists in upstream: + + crash> bt 2091206 + PID: 2091206 TASK: ffff2050df92a300 CPU: 109 COMMAND: "kworker/u260:0" + #0 [ffff800084a2f7f0] __switch_to at ffff80004008aeb8 + #1 [ffff800084a2f820] __schedule at ffff800040bfa0c4 + #2 [ffff800084a2f880] schedule at ffff800040bfa4b4 + #3 [ffff800084a2f8a0] io_schedule at ffff800040bfa9c4 + #4 [ffff800084a2f8c0] rq_qos_wait at ffff8000405925bc + #5 [ffff800084a2f940] wbt_wait at ffff8000405bb3a0 + #6 [ffff800084a2f9a0] __rq_qos_throttle at ffff800040592254 + #7 [ffff800084a2f9c0] blk_mq_make_request at ffff80004057cf38 + #8 [ffff800084a2fa60] generic_make_request at ffff800040570138 + #9 [ffff800084a2fae0] submit_bio at ffff8000405703b4 + #10 [ffff800084a2fb50] xlog_write_iclog at ffff800001280834 [xfs] + #11 [ffff800084a2fbb0] xlog_sync at ffff800001280c3c [xfs] + #12 [ffff800084a2fbf0] xlog_state_release_iclog at ffff800001280df4 [xfs] + #13 [ffff800084a2fc10] xlog_write at ffff80000128203c [xfs] + #14 [ffff800084a2fcd0] xlog_cil_push at ffff8000012846dc [xfs] + #15 [ffff800084a2fda0] xlog_cil_push_work at ffff800001284a2c [xfs] + #16 [ffff800084a2fdb0] process_one_work at ffff800040111d08 + #17 [ffff800084a2fe00] worker_thread at ffff8000401121cc + #18 [ffff800084a2fe70] kthread at ffff800040118de4 + +After commit 2def2845cc33 ("xfs: don't allow log IO to be throttled"), +the metadata submitted by xlog_write_iclog() should not be throttled. +But due to the existence of the dm layer, throttling flush_bio indirectly +causes the metadata bio to be throttled. + +Fix this by conditionally adding REQ_IDLE to flush_bio.bi_opf, which makes +wbt_should_throttle() return false to avoid wbt_wait(). + +Signed-off-by: Jinliang Zheng +Reviewed-by: Tianxiang Peng +Reviewed-by: Hao Peng +Signed-off-by: Mikulas Patocka +Signed-off-by: Sasha Levin +--- + drivers/md/dm.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 5dd0a42463a2b..9ea868bd0d129 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1536,14 +1536,18 @@ static void __send_empty_flush(struct clone_info *ci) + { + struct dm_table *t = ci->map; + struct bio flush_bio; ++ blk_opf_t opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC; ++ ++ if ((ci->io->orig_bio->bi_opf & (REQ_IDLE | REQ_SYNC)) == ++ (REQ_IDLE | REQ_SYNC)) ++ opf |= REQ_IDLE; + + /* + * Use an on-stack bio for this, it's safe since we don't + * need to reference it after submit. It's just used as + * the basis for the clone(s). + */ +- bio_init(&flush_bio, ci->io->md->disk->part0, NULL, 0, +- REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC); ++ bio_init(&flush_bio, ci->io->md->disk->part0, NULL, 0, opf); + + ci->bio = &flush_bio; + ci->sector_count = 0; +-- +2.39.5 + diff --git a/queue-6.6/dm-restrict-dm-device-size-to-2-63-512-bytes.patch b/queue-6.6/dm-restrict-dm-device-size-to-2-63-512-bytes.patch new file mode 100644 index 0000000000..1124ca3de3 --- /dev/null +++ b/queue-6.6/dm-restrict-dm-device-size-to-2-63-512-bytes.patch @@ -0,0 +1,39 @@ +From 6149515512ea31d1e7c2ec67cc62936f87c492c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Mar 2025 13:51:32 +0100 +Subject: dm: restrict dm device size to 2^63-512 bytes + +From: Mikulas Patocka + +[ Upstream commit 45fc728515c14f53f6205789de5bfd72a95af3b8 ] + +The devices with size >= 2^63 bytes can't be used reliably by userspace +because the type off_t is a signed 64-bit integer. + +Therefore, we limit the maximum size of a device mapper device to +2^63-512 bytes. + +Signed-off-by: Mikulas Patocka +Signed-off-by: Sasha Levin +--- + drivers/md/dm-table.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c +index 7a33da2dd64b1..bf2ade89c8c2d 100644 +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -669,6 +669,10 @@ int dm_table_add_target(struct dm_table *t, const char *type, + DMERR("%s: zero-length target", dm_device_name(t->md)); + return -EINVAL; + } ++ if (start + len < start || start + len > LLONG_MAX >> SECTOR_SHIFT) { ++ DMERR("%s: too large device", dm_device_name(t->md)); ++ return -EINVAL; ++ } + + ti->type = dm_get_target_type(type); + if (!ti->type) { +-- +2.39.5 + diff --git a/queue-6.6/dma-mapping-avoid-potential-unused-data-compilation-.patch b/queue-6.6/dma-mapping-avoid-potential-unused-data-compilation-.patch new file mode 100644 index 0000000000..931ae12885 --- /dev/null +++ b/queue-6.6/dma-mapping-avoid-potential-unused-data-compilation-.patch @@ -0,0 +1,50 @@ +From 19a570d742c9c665239c15607d230cba861e0341 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Apr 2025 09:56:59 +0200 +Subject: dma-mapping: avoid potential unused data compilation warning + +From: Marek Szyprowski + +[ Upstream commit c9b19ea63036fc537a69265acea1b18dabd1cbd3 ] + +When CONFIG_NEED_DMA_MAP_STATE is not defined, dma-mapping clients might +report unused data compilation warnings for dma_unmap_*() calls +arguments. Redefine macros for those calls to let compiler to notice that +it is okay when the provided arguments are not used. + +Reported-by: Andy Shevchenko +Suggested-by: Jakub Kicinski +Signed-off-by: Marek Szyprowski +Tested-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20250415075659.428549-1-m.szyprowski@samsung.com +Signed-off-by: Sasha Levin +--- + include/linux/dma-mapping.h | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h +index f0ccca16a0aca..608e8296ba206 100644 +--- a/include/linux/dma-mapping.h ++++ b/include/linux/dma-mapping.h +@@ -600,10 +600,14 @@ static inline int dma_mmap_wc(struct device *dev, + #else + #define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) + #define DEFINE_DMA_UNMAP_LEN(LEN_NAME) +-#define dma_unmap_addr(PTR, ADDR_NAME) (0) +-#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) +-#define dma_unmap_len(PTR, LEN_NAME) (0) +-#define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) ++#define dma_unmap_addr(PTR, ADDR_NAME) \ ++ ({ typeof(PTR) __p __maybe_unused = PTR; 0; }) ++#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) \ ++ do { typeof(PTR) __p __maybe_unused = PTR; } while (0) ++#define dma_unmap_len(PTR, LEN_NAME) \ ++ ({ typeof(PTR) __p __maybe_unused = PTR; 0; }) ++#define dma_unmap_len_set(PTR, LEN_NAME, VAL) \ ++ do { typeof(PTR) __p __maybe_unused = PTR; } while (0) + #endif + + #endif /* _LINUX_DMA_MAPPING_H */ +-- +2.39.5 + diff --git a/queue-6.6/dql-fix-dql-limit-value-when-reset.patch b/queue-6.6/dql-fix-dql-limit-value-when-reset.patch new file mode 100644 index 0000000000..05d6f0bddd --- /dev/null +++ b/queue-6.6/dql-fix-dql-limit-value-when-reset.patch @@ -0,0 +1,46 @@ +From 53be032e354f057c89439db5e61745f80523b808 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Mar 2025 16:57:51 +0800 +Subject: dql: Fix dql->limit value when reset. + +From: Jing Su + +[ Upstream commit 3a17f23f7c36bac3a3584aaf97d3e3e0b2790396 ] + +Executing dql_reset after setting a non-zero value for limit_min can +lead to an unreasonable situation where dql->limit is less than +dql->limit_min. + +For instance, after setting +/sys/class/net/eth*/queues/tx-0/byte_queue_limits/limit_min, +an ifconfig down/up operation might cause the ethernet driver to call +netdev_tx_reset_queue, which in turn invokes dql_reset. + +In this case, dql->limit is reset to 0 while dql->limit_min remains +non-zero value, which is unexpected. The limit should always be +greater than or equal to limit_min. + +Signed-off-by: Jing Su +Link: https://patch.msgid.link/Z9qHD1s/NEuQBdgH@pilot-ThinkCentre-M930t-N000 +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + lib/dynamic_queue_limits.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c +index fde0aa2441480..a75a9ca46b594 100644 +--- a/lib/dynamic_queue_limits.c ++++ b/lib/dynamic_queue_limits.c +@@ -116,7 +116,7 @@ EXPORT_SYMBOL(dql_completed); + void dql_reset(struct dql *dql) + { + /* Reset all dynamic values */ +- dql->limit = 0; ++ dql->limit = dql->min_limit; + dql->num_queued = 0; + dql->num_completed = 0; + dql->last_obj_cnt = 0; +-- +2.39.5 + diff --git a/queue-6.6/drm-add-valid-clones-check.patch b/queue-6.6/drm-add-valid-clones-check.patch new file mode 100644 index 0000000000..d43eb54f49 --- /dev/null +++ b/queue-6.6/drm-add-valid-clones-check.patch @@ -0,0 +1,70 @@ +From 61470535eef14f67a5c78f2142761dec23d7c26a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 16:43:14 -0800 +Subject: drm: Add valid clones check + +From: Jessica Zhang + +[ Upstream commit 41b4b11da02157c7474caf41d56baae0e941d01a ] + +Check that all encoders attached to a given CRTC are valid +possible_clones of each other. + +Signed-off-by: Jessica Zhang +Reviewed-by: Maxime Ripard +Link: https://patchwork.freedesktop.org/patch/msgid/20241216-concurrent-wb-v4-3-fe220297a7f0@quicinc.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_atomic_helper.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c +index f3681970887cc..1aa59586c8f81 100644 +--- a/drivers/gpu/drm/drm_atomic_helper.c ++++ b/drivers/gpu/drm/drm_atomic_helper.c +@@ -573,6 +573,30 @@ mode_valid(struct drm_atomic_state *state) + return 0; + } + ++static int drm_atomic_check_valid_clones(struct drm_atomic_state *state, ++ struct drm_crtc *crtc) ++{ ++ struct drm_encoder *drm_enc; ++ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, ++ crtc); ++ ++ drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask) { ++ if (!drm_enc->possible_clones) { ++ DRM_DEBUG("enc%d possible_clones is 0\n", drm_enc->base.id); ++ continue; ++ } ++ ++ if ((crtc_state->encoder_mask & drm_enc->possible_clones) != ++ crtc_state->encoder_mask) { ++ DRM_DEBUG("crtc%d failed valid clone check for mask 0x%x\n", ++ crtc->base.id, crtc_state->encoder_mask); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ + /** + * drm_atomic_helper_check_modeset - validate state object for modeset changes + * @dev: DRM device +@@ -744,6 +768,10 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, + ret = drm_atomic_add_affected_planes(state, crtc); + if (ret != 0) + return ret; ++ ++ ret = drm_atomic_check_valid_clones(state, crtc); ++ if (ret != 0) ++ return ret; + } + + /* +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-add-support-for-disconnected-edp-str.patch b/queue-6.6/drm-amd-display-add-support-for-disconnected-edp-str.patch new file mode 100644 index 0000000000..52598b4044 --- /dev/null +++ b/queue-6.6/drm-amd-display-add-support-for-disconnected-edp-str.patch @@ -0,0 +1,44 @@ +From d32da94ab309243745e573d5c416844013a123d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:46:53 -0500 +Subject: drm/amd/display: Add support for disconnected eDP streams + +From: Harry VanZyllDeJong + +[ Upstream commit 6571bef25fe48c642f7a69ccf7c3198b317c136a ] + +[Why] +eDP may not be connected to the GPU on driver start causing +fail enumeration. + +[How] +Move the virtual signal type check before the eDP connector +signal check. + +Reviewed-by: Wenjing Liu +Signed-off-by: Harry VanZyllDeJong +Signed-off-by: Roman Li +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +index 1e621eae9b7da..adf0ef8b70e4b 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +@@ -920,6 +920,9 @@ bool link_decide_link_settings(struct dc_stream_state *stream, + * TODO: add MST specific link training routine + */ + decide_mst_link_settings(link, link_setting); ++ } else if (stream->signal == SIGNAL_TYPE_VIRTUAL) { ++ link_setting->lane_count = LANE_COUNT_FOUR; ++ link_setting->link_rate = LINK_RATE_HIGH3; + } else if (link->connector_signal == SIGNAL_TYPE_EDP) { + /* enable edp link optimization for DSC eDP case */ + if (stream->timing.flags.DSC) { +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-calculate-the-remain-segments-for-al.patch b/queue-6.6/drm-amd-display-calculate-the-remain-segments-for-al.patch new file mode 100644 index 0000000000..b6b535d41b --- /dev/null +++ b/queue-6.6/drm-amd-display-calculate-the-remain-segments-for-al.patch @@ -0,0 +1,95 @@ +From d895468507392417db7b557461a102af687a3680 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 20:09:14 +0800 +Subject: drm/amd/display: calculate the remain segments for all pipes + +From: Zhikai Zhai + +[ Upstream commit d3069feecdb5542604d29b59acfd1fd213bad95b ] + +[WHY] +In some cases the remain de-tile buffer segments will be greater +than zero if we don't add the non-top pipe to calculate, at +this time the override de-tile buffer size will be valid and used. +But it makes the de-tile buffer segments used finally for all of pipes +exceed the maximum. + +[HOW] +Add the non-top pipe to calculate the remain de-tile buffer segments. +Don't set override size to use the average according to pipe count +if the value exceed the maximum. + +Reviewed-by: Charlene Liu +Signed-off-by: Zhikai Zhai +Signed-off-by: Tom Chung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../amd/display/dc/dcn315/dcn315_resource.c | 42 +++++++++---------- + 1 file changed, 20 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +index 597fa0364a3a9..d1601d61f05ad 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c +@@ -1692,7 +1692,7 @@ static int dcn315_populate_dml_pipes_from_context( + pipes[pipe_cnt].dout.dsc_input_bpc = 0; + DC_FP_START(); + dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt); +- if (pixel_rate_crb && !pipe->top_pipe && !pipe->prev_odm_pipe) { ++ if (pixel_rate_crb) { + int bpp = source_format_to_bpp(pipes[pipe_cnt].pipe.src.source_format); + /* Ceil to crb segment size */ + int approx_det_segs_required_for_pstate = dcn_get_approx_det_segs_required_for_pstate( +@@ -1749,28 +1749,26 @@ static int dcn315_populate_dml_pipes_from_context( + continue; + } + +- if (!pipe->top_pipe && !pipe->prev_odm_pipe) { +- bool split_required = pipe->stream->timing.pix_clk_100hz >= dcn_get_max_non_odm_pix_rate_100hz(&dc->dml.soc) +- || (pipe->plane_state && pipe->plane_state->src_rect.width > 5120); +- +- if (remaining_det_segs > MIN_RESERVED_DET_SEGS && crb_pipes != 0) +- pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs - MIN_RESERVED_DET_SEGS) / crb_pipes + +- (crb_idx < (remaining_det_segs - MIN_RESERVED_DET_SEGS) % crb_pipes ? 1 : 0); +- if (pipes[pipe_cnt].pipe.src.det_size_override > 2 * DCN3_15_MAX_DET_SEGS) { +- /* Clamp to 2 pipe split max det segments */ +- remaining_det_segs += pipes[pipe_cnt].pipe.src.det_size_override - 2 * (DCN3_15_MAX_DET_SEGS); +- pipes[pipe_cnt].pipe.src.det_size_override = 2 * DCN3_15_MAX_DET_SEGS; +- } +- if (pipes[pipe_cnt].pipe.src.det_size_override > DCN3_15_MAX_DET_SEGS || split_required) { +- /* If we are splitting we must have an even number of segments */ +- remaining_det_segs += pipes[pipe_cnt].pipe.src.det_size_override % 2; +- pipes[pipe_cnt].pipe.src.det_size_override -= pipes[pipe_cnt].pipe.src.det_size_override % 2; +- } +- /* Convert segments into size for DML use */ +- pipes[pipe_cnt].pipe.src.det_size_override *= DCN3_15_CRB_SEGMENT_SIZE_KB; +- +- crb_idx++; ++ bool split_required = pipe->stream->timing.pix_clk_100hz >= dcn_get_max_non_odm_pix_rate_100hz(&dc->dml.soc) ++ || (pipe->plane_state && pipe->plane_state->src_rect.width > 5120); ++ ++ if (remaining_det_segs > MIN_RESERVED_DET_SEGS && crb_pipes != 0) ++ pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs - MIN_RESERVED_DET_SEGS) / crb_pipes + ++ (crb_idx < (remaining_det_segs - MIN_RESERVED_DET_SEGS) % crb_pipes ? 1 : 0); ++ if (pipes[pipe_cnt].pipe.src.det_size_override > 2 * DCN3_15_MAX_DET_SEGS) { ++ /* Clamp to 2 pipe split max det segments */ ++ remaining_det_segs += pipes[pipe_cnt].pipe.src.det_size_override - 2 * (DCN3_15_MAX_DET_SEGS); ++ pipes[pipe_cnt].pipe.src.det_size_override = 2 * DCN3_15_MAX_DET_SEGS; ++ } ++ if (pipes[pipe_cnt].pipe.src.det_size_override > DCN3_15_MAX_DET_SEGS || split_required) { ++ /* If we are splitting we must have an even number of segments */ ++ remaining_det_segs += pipes[pipe_cnt].pipe.src.det_size_override % 2; ++ pipes[pipe_cnt].pipe.src.det_size_override -= pipes[pipe_cnt].pipe.src.det_size_override % 2; + } ++ /* Convert segments into size for DML use */ ++ pipes[pipe_cnt].pipe.src.det_size_override *= DCN3_15_CRB_SEGMENT_SIZE_KB; ++ ++ crb_idx++; + pipe_cnt++; + } + } +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-dm-drop-hw_support-check-in-amdgpu_d.patch b/queue-6.6/drm-amd-display-dm-drop-hw_support-check-in-amdgpu_d.patch new file mode 100644 index 0000000000..08610fa412 --- /dev/null +++ b/queue-6.6/drm-amd-display-dm-drop-hw_support-check-in-amdgpu_d.patch @@ -0,0 +1,34 @@ +From a1f6b1fda88f5e39766d7d8bacd0d2d33baaa89d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 09:25:18 -0500 +Subject: drm/amd/display/dm: drop hw_support check in amdgpu_dm_i2c_xfer() + +From: Alex Deucher + +[ Upstream commit 33da70bd1e115d7d73f45fb1c09f5ecc448f3f13 ] + +DC supports SW i2c as well. Drop the check. + +Reviewed-by: Harry Wentland +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index bcf0dc05c7676..be17aebf9b342 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -7474,7 +7474,7 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, + int i; + int result = -EIO; + +- if (!ddc_service->ddc_pin || !ddc_service->ddc_pin->hw_info.hw_supported) ++ if (!ddc_service->ddc_pin) + return result; + + cmd.payloads = kcalloc(num, sizeof(struct i2c_payload), GFP_KERNEL); +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-don-t-try-aux-transactions-on-discon.patch b/queue-6.6/drm-amd-display-don-t-try-aux-transactions-on-discon.patch new file mode 100644 index 0000000000..d4ca0e27a2 --- /dev/null +++ b/queue-6.6/drm-amd-display-don-t-try-aux-transactions-on-discon.patch @@ -0,0 +1,57 @@ +From da545d498a77b4fbf8a01e073bf69e56f4a5f21e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 13:14:54 -0500 +Subject: drm/amd/display: Don't try AUX transactions on disconnected link + +From: Ilya Bakoulin + +[ Upstream commit e8bffa52e0253cfd689813a620e64521256bc712 ] + +[Why] +Setting link DPMS off in response to HPD disconnect creates AUX +transactions on a link that is supposed to be disconnected. This can +cause issues in some cases when the sink re-asserts HPD and expects +source to re-enable the link. + +[How] +Avoid AUX transactions on disconnected link. + +Reviewed-by: Wenjing Liu +Signed-off-by: Ilya Bakoulin +Signed-off-by: Aurabindo Pillai +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +index 9bde0c8bf914a..f01a3df584552 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +@@ -74,7 +74,8 @@ void dp_disable_link_phy(struct dc_link *link, + struct dc *dc = link->ctx->dc; + + if (!link->wa_flags.dp_keep_receiver_powered && +- !link->skip_implict_edp_power_control) ++ !link->skip_implict_edp_power_control && ++ link->type != dc_connection_none) + dpcd_write_rx_power_ctrl(link, false); + + dc->hwss.disable_link_output(link, link_res, signal); +@@ -159,8 +160,9 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource + } else { + if (link->fec_state == dc_link_fec_ready) { + fec_config = 0; +- core_link_write_dpcd(link, DP_FEC_CONFIGURATION, +- &fec_config, sizeof(fec_config)); ++ if (link->type != dc_connection_none) ++ core_link_write_dpcd(link, DP_FEC_CONFIGURATION, ++ &fec_config, sizeof(fec_config)); + + link_enc->funcs->fec_set_ready(link_enc, false); + link->fec_state = dc_link_fec_not_ready; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-fix-incorrect-dpcd-configs-while-rep.patch b/queue-6.6/drm-amd-display-fix-incorrect-dpcd-configs-while-rep.patch new file mode 100644 index 0000000000..87c5a911e4 --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-incorrect-dpcd-configs-while-rep.patch @@ -0,0 +1,80 @@ +From a5c1768f879400a84505b92a6e6b3fedb3da179e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Feb 2025 15:45:43 +0800 +Subject: drm/amd/display: Fix incorrect DPCD configs while Replay/PSR switch + +From: Leon Huang + +[ Upstream commit 0d9cabc8f591ea1cd97c071b853b75b155c13259 ] + +[Why] +When switching between PSR/Replay, +the DPCD config of previous mode is not cleared, +resulting in unexpected behavior in TCON. + +[How] +Initialize the DPCD in setup function + +Reviewed-by: Robin Chen +Signed-off-by: Leon Huang +Signed-off-by: Tom Chung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../link/protocols/link_edp_panel_control.c | 25 ++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +index 13104d000b9e0..d4d92da153ece 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +@@ -662,6 +662,18 @@ bool edp_setup_psr(struct dc_link *link, + if (!link) + return false; + ++ //Clear PSR cfg ++ memset(&psr_configuration, 0, sizeof(psr_configuration)); ++ dm_helpers_dp_write_dpcd( ++ link->ctx, ++ link, ++ DP_PSR_EN_CFG, ++ &psr_configuration.raw, ++ sizeof(psr_configuration.raw)); ++ ++ if (link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED) ++ return false; ++ + dc = link->ctx->dc; + dmcu = dc->res_pool->dmcu; + psr = dc->res_pool->psr; +@@ -672,9 +684,6 @@ bool edp_setup_psr(struct dc_link *link, + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + +- +- memset(&psr_configuration, 0, sizeof(psr_configuration)); +- + psr_configuration.bits.ENABLE = 1; + psr_configuration.bits.CRC_VERIFICATION = 1; + psr_configuration.bits.FRAME_CAPTURE_INDICATION = +@@ -938,6 +947,16 @@ bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream + if (!link) + return false; + ++ //Clear Replay config ++ dm_helpers_dp_write_dpcd(link->ctx, link, ++ DP_SINK_PR_ENABLE_AND_CONFIGURATION, ++ (uint8_t *)&(replay_config.raw), sizeof(uint8_t)); ++ ++ if (!(link->replay_settings.config.replay_supported)) ++ return false; ++ ++ link->replay_settings.config.replay_error_status.raw = 0; ++ + dc = link->ctx->dc; + + replay = dc->res_pool->replay; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-guard-against-setting-dispclk-low-fo.patch b/queue-6.6/drm-amd-display-guard-against-setting-dispclk-low-fo.patch new file mode 100644 index 0000000000..4533423c26 --- /dev/null +++ b/queue-6.6/drm-amd-display-guard-against-setting-dispclk-low-fo.patch @@ -0,0 +1,113 @@ +From db44332141213f6ff471847d0cdbb20a502c8ef0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 23:15:56 +0800 +Subject: drm/amd/display: Guard against setting dispclk low for dcn31x + +From: Jing Zhou + +[ Upstream commit 9c2f4ae64bb6f6d83a54d88b9ee0f369cdbb9fa8 ] + +[WHY] +We should never apply a minimum dispclk value while in +prepare_bandwidth or while displays are active. This is +always an optimizaiton for when all displays are disabled. + +[HOW] +Defer dispclk optimization until safe_to_lower = true +and display_count reaches 0. + +Since 0 has a special value in this logic (ie. no dispclk +required) we also need adjust the logic that clamps it for +the actual request to PMFW. + +Reviewed-by: Charlene Liu +Reviewed-by: Chris Park +Reviewed-by: Eric Yang +Signed-off-by: Jing Zhou +Signed-off-by: Nicholas Kazlauskas +Signed-off-by: Alex Hung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 20 +++++++++++-------- + .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 13 +++++++++--- + 2 files changed, 22 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +index d4d3f58a613f7..ebeb969ee180b 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +@@ -130,7 +130,7 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; + struct dc *dc = clk_mgr_base->ctx->dc; +- int display_count; ++ int display_count = 0; + bool update_dppclk = false; + bool update_dispclk = false; + bool dpp_clock_lowered = false; +@@ -204,15 +204,19 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, + update_dppclk = true; + } + +- if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { +- /* No need to apply the w/a if we haven't taken over from bios yet */ +- if (clk_mgr_base->clks.dispclk_khz) +- dcn315_disable_otg_wa(clk_mgr_base, context, true); ++ if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) && ++ (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) { ++ int requested_dispclk_khz = new_clocks->dispclk_khz; + ++ dcn315_disable_otg_wa(clk_mgr_base, context, true); ++ ++ /* Clamp the requested clock to PMFW based on their limit. */ ++ if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz) ++ requested_dispclk_khz = dc->debug.min_disp_clk_khz; ++ ++ dcn315_smu_set_dispclk(clk_mgr, requested_dispclk_khz); + clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; +- dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); +- if (clk_mgr_base->clks.dispclk_khz) +- dcn315_disable_otg_wa(clk_mgr_base, context, false); ++ dcn315_disable_otg_wa(clk_mgr_base, context, false); + + update_dispclk = true; + } +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +index a13ead3d21e31..6f1785715dfb7 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +@@ -140,7 +140,7 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; + struct dc *dc = clk_mgr_base->ctx->dc; +- int display_count; ++ int display_count = 0; + bool update_dppclk = false; + bool update_dispclk = false; + bool dpp_clock_lowered = false; +@@ -211,11 +211,18 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, + update_dppclk = true; + } + +- if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { ++ if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) && ++ (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) { ++ int requested_dispclk_khz = new_clocks->dispclk_khz; ++ + dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true); + ++ /* Clamp the requested clock to PMFW based on their limit. */ ++ if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz) ++ requested_dispclk_khz = dc->debug.min_disp_clk_khz; ++ ++ dcn316_smu_set_dispclk(clk_mgr, requested_dispclk_khz); + clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; +- dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); + dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false); + + update_dispclk = true; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-handle-max_downscale_src_width-fail-.patch b/queue-6.6/drm-amd-display-handle-max_downscale_src_width-fail-.patch new file mode 100644 index 0000000000..d2723cb9ef --- /dev/null +++ b/queue-6.6/drm-amd-display-handle-max_downscale_src_width-fail-.patch @@ -0,0 +1,59 @@ +From 726c97fe8b67f1565fd5469fffa73b62aa9b1aab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 15:17:56 -0500 +Subject: drm/amd/display: handle max_downscale_src_width fail check + +From: Yihan Zhu + +[ Upstream commit 02a940da2ccc0cc0299811379580852b405a0ea2 ] + +[WHY] +If max_downscale_src_width check fails, we exit early from TAP calculation and left a NULL +value to the scaling data structure to cause the zero divide in the DML validation. + +[HOW] +Call set default TAP calculation before early exit in get_optimal_number_of_taps due to +max downscale limit exceed. + +Reviewed-by: Samson Tam +Signed-off-by: Yihan Zhu +Signed-off-by: Zaeem Mohamed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c +index 50dc834046446..4ce45f1bdac0f 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c +@@ -392,11 +392,6 @@ bool dpp3_get_optimal_number_of_taps( + int min_taps_y, min_taps_c; + enum lb_memory_config lb_config; + +- if (scl_data->viewport.width > scl_data->h_active && +- dpp->ctx->dc->debug.max_downscale_src_width != 0 && +- scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) +- return false; +- + /* + * Set default taps if none are provided + * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling +@@ -434,6 +429,12 @@ bool dpp3_get_optimal_number_of_taps( + else + scl_data->taps.h_taps_c = in_taps->h_taps_c; + ++ // Avoid null data in the scl data with this early return, proceed non-adaptive calcualtion first ++ if (scl_data->viewport.width > scl_data->h_active && ++ dpp->ctx->dc->debug.max_downscale_src_width != 0 && ++ scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) ++ return false; ++ + /*Ensure we can support the requested number of vtaps*/ + min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert); + min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c); +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-increase-block_sequence-array-size.patch b/queue-6.6/drm-amd-display-increase-block_sequence-array-size.patch new file mode 100644 index 0000000000..e81681df8c --- /dev/null +++ b/queue-6.6/drm-amd-display-increase-block_sequence-array-size.patch @@ -0,0 +1,46 @@ +From a20e1780271ec5909790fa22306c425ebed9bc34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 12:03:23 -0500 +Subject: drm/amd/display: Increase block_sequence array size + +From: Joshua Aberback + +[ Upstream commit 3a7810c212bcf2f722671dadf4b23ff70a7d23ee ] + +[Why] +It's possible to generate more than 50 steps in hwss_build_fast_sequence, +for example with a 6-pipe asic where all pipes are in one MPC chain. This +overflows the block_sequence buffer and corrupts block_sequence_steps, +causing a crash. + +[How] +Expand block_sequence to 100 items. A naive upper bound on the possible +number of steps for a 6-pipe asic, ignoring the potential for steps to be +mutually exclusive, is 91 with current code, therefore 100 is sufficient. + +Reviewed-by: Alvin Lee +Signed-off-by: Joshua Aberback +Signed-off-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +index eaad1260bfd18..4b284ce669ae5 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +@@ -532,7 +532,7 @@ struct dc_state { + */ + struct bw_context bw_ctx; + +- struct block_sequence block_sequence[50]; ++ struct block_sequence block_sequence[100]; + unsigned int block_sequence_steps; + struct dc_dmub_cmd dc_dmub_cmd[10]; + unsigned int dmub_cmd_count; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-initial-psr_version-with-correct-set.patch b/queue-6.6/drm-amd-display-initial-psr_version-with-correct-set.patch new file mode 100644 index 0000000000..ee386b8c70 --- /dev/null +++ b/queue-6.6/drm-amd-display-initial-psr_version-with-correct-set.patch @@ -0,0 +1,40 @@ +From 179d78b652f354b5de87070a84e08699362f8e95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 14:22:31 +0800 +Subject: drm/amd/display: Initial psr_version with correct setting + +From: Tom Chung + +[ Upstream commit d8c782cac5007e68e7484d420168f12d3490def6 ] + +[Why & How] +The initial setting for psr_version is not correct while +create a virtual link. + +The default psr_version should be DC_PSR_VERSION_UNSUPPORTED. + +Reviewed-by: Roman Li +Signed-off-by: Tom Chung +Signed-off-by: Zaeem Mohamed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index c2efe18ceacd0..640d010b52bec 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -266,6 +266,7 @@ static bool create_links( + link->link_id.type = OBJECT_TYPE_CONNECTOR; + link->link_id.id = CONNECTOR_ID_VIRTUAL; + link->link_id.enum_id = ENUM_ID_1; ++ link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); + + if (!link->link_enc) { +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-remove-minimum-dispclk-and-apply-oem.patch b/queue-6.6/drm-amd-display-remove-minimum-dispclk-and-apply-oem.patch new file mode 100644 index 0000000000..ab6eacec06 --- /dev/null +++ b/queue-6.6/drm-amd-display-remove-minimum-dispclk-and-apply-oem.patch @@ -0,0 +1,71 @@ +From da5196f82b352341b794182bc67e1ebbb68dfa75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 13:53:16 -0500 +Subject: drm/amd/display: remove minimum Dispclk and apply oem panel timing. + +From: Charlene Liu + +[ Upstream commit 756e58e83e89d372b94269c0cde61fe55da76947 ] + +[why & how] +1. apply oem panel timing (not only on OLED) +2. remove MIN_DPP_DISP_CLK request in driver. + +This fix will apply for dcn31x but not +sync with DML's output. + +Reviewed-by: Ovidiu Bunea +Signed-off-by: Charlene Liu +Signed-off-by: Tom Chung +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 -- + drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 2 -- + drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 ++- + 3 files changed, 2 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +index ebeb969ee180b..327776eeb9f3e 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +@@ -194,8 +194,6 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, + // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. + if (new_clocks->dppclk_khz < MIN_DPP_DISP_CLK) + new_clocks->dppclk_khz = MIN_DPP_DISP_CLK; +- if (new_clocks->dispclk_khz < MIN_DPP_DISP_CLK) +- new_clocks->dispclk_khz = MIN_DPP_DISP_CLK; + + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +index 6f1785715dfb7..f95e5e767eb1a 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +@@ -201,8 +201,6 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, + // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. + if (new_clocks->dppclk_khz < 100000) + new_clocks->dppclk_khz = 100000; +- if (new_clocks->dispclk_khz < 100000) +- new_clocks->dispclk_khz = 100000; + + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index 7b5c1498941dd..d389eeb264a79 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -1066,7 +1066,8 @@ void dce110_edp_backlight_control( + DC_LOG_DC("edp_receiver_ready_T9 skipped\n"); + } + +- if (!enable && link->dpcd_sink_ext_caps.bits.oled) { ++ if (!enable) { ++ /*follow oem panel config's requirement*/ + pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms; + msleep(pre_T11_delay); + } +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-skip-checking-frl_mode-bit-for-pcon-.patch b/queue-6.6/drm-amd-display-skip-checking-frl_mode-bit-for-pcon-.patch new file mode 100644 index 0000000000..fb0a8e5e66 --- /dev/null +++ b/queue-6.6/drm-amd-display-skip-checking-frl_mode-bit-for-pcon-.patch @@ -0,0 +1,70 @@ +From 1658d57b5f63429ef92ab8caa4f5aef1151f122f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 22:00:13 -0500 +Subject: drm/amd/display: Skip checking FRL_MODE bit for PCON BW determination + +From: George Shen + +[ Upstream commit 0584bbcf0c53c133081100e4f4c9fe41e598d045 ] + +[Why/How] +Certain PCON will clear the FRL_MODE bit despite supporting the link BW +indicated in the other bits. + +Thus, skip checking the FRL_MODE bit when interpreting the +hdmi_encoded_link_bw struct. + +Reviewed-by: Wenjing Liu +Signed-off-by: George Shen +Signed-off-by: Wayne Lin +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../dc/link/protocols/link_dp_capability.c | 30 +++++++++---------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +index 3d589072fe307..1e621eae9b7da 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +@@ -239,21 +239,21 @@ static uint32_t intersect_frl_link_bw_support( + { + uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps; + +- // HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode) +- if (hdmi_encoded_link_bw.bits.FRL_MODE) { +- if (hdmi_encoded_link_bw.bits.BW_48Gbps) +- supported_bw_in_kbps = 48000000; +- else if (hdmi_encoded_link_bw.bits.BW_40Gbps) +- supported_bw_in_kbps = 40000000; +- else if (hdmi_encoded_link_bw.bits.BW_32Gbps) +- supported_bw_in_kbps = 32000000; +- else if (hdmi_encoded_link_bw.bits.BW_24Gbps) +- supported_bw_in_kbps = 24000000; +- else if (hdmi_encoded_link_bw.bits.BW_18Gbps) +- supported_bw_in_kbps = 18000000; +- else if (hdmi_encoded_link_bw.bits.BW_9Gbps) +- supported_bw_in_kbps = 9000000; +- } ++ /* Skip checking FRL_MODE bit, as certain PCON will clear ++ * it despite supporting the link BW indicated in the other bits. ++ */ ++ if (hdmi_encoded_link_bw.bits.BW_48Gbps) ++ supported_bw_in_kbps = 48000000; ++ else if (hdmi_encoded_link_bw.bits.BW_40Gbps) ++ supported_bw_in_kbps = 40000000; ++ else if (hdmi_encoded_link_bw.bits.BW_32Gbps) ++ supported_bw_in_kbps = 32000000; ++ else if (hdmi_encoded_link_bw.bits.BW_24Gbps) ++ supported_bw_in_kbps = 24000000; ++ else if (hdmi_encoded_link_bw.bits.BW_18Gbps) ++ supported_bw_in_kbps = 18000000; ++ else if (hdmi_encoded_link_bw.bits.BW_9Gbps) ++ supported_bw_in_kbps = 9000000; + + return supported_bw_in_kbps; + } +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-update-cr-aux-rd-interval-interpreta.patch b/queue-6.6/drm-amd-display-update-cr-aux-rd-interval-interpreta.patch new file mode 100644 index 0000000000..4637230c69 --- /dev/null +++ b/queue-6.6/drm-amd-display-update-cr-aux-rd-interval-interpreta.patch @@ -0,0 +1,71 @@ +From 32a4df3804f7e154eaa1d093063d55af292bd5e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 11:35:46 -0500 +Subject: drm/amd/display: Update CR AUX RD interval interpretation + +From: George Shen + +[ Upstream commit 6a7fde433231c18164c117592d3e18ced648ad58 ] + +[Why] +DP spec updated to have the CR AUX RD interval match the EQ AUX RD +interval interpretation of DPCD 0000Eh/0220Eh for 8b/10b non-LTTPR mode +and LTTPR transparent mode cases. + +[How] +Update interpretation of DPCD 0000Eh/0220Eh for CR AUX RD interval +during 8b/10b link training. + +Reviewed-by: Michael Strauss +Reviewed-by: Wenjing Liu +Signed-off-by: George Shen +Signed-off-by: Zaeem Mohamed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../display/dc/link/protocols/link_dp_training_8b_10b.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +index 2b4c15b0b4070..52261e7c11c0b 100644 +--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c ++++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +@@ -36,7 +36,8 @@ + link->ctx->logger + + static int32_t get_cr_training_aux_rd_interval(struct dc_link *link, +- const struct dc_link_settings *link_settings) ++ const struct dc_link_settings *link_settings, ++ enum lttpr_mode lttpr_mode) + { + union training_aux_rd_interval training_rd_interval; + uint32_t wait_in_micro_secs = 100; +@@ -49,6 +50,8 @@ static int32_t get_cr_training_aux_rd_interval(struct dc_link *link, + DP_TRAINING_AUX_RD_INTERVAL, + (uint8_t *)&training_rd_interval, + sizeof(training_rd_interval)); ++ if (lttpr_mode != LTTPR_MODE_NON_TRANSPARENT) ++ wait_in_micro_secs = 400; + if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) + wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000; + } +@@ -110,7 +113,6 @@ void decide_8b_10b_training_settings( + */ + lt_settings->link_settings.link_spread = link->dp_ss_off ? + LINK_SPREAD_DISABLED : LINK_SPREAD_05_DOWNSPREAD_30KHZ; +- lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting); + lt_settings->eq_pattern_time = get_eq_training_aux_rd_interval(link, link_setting); + lt_settings->pattern_for_cr = decide_cr_training_pattern(link_setting); + lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting); +@@ -119,6 +121,7 @@ void decide_8b_10b_training_settings( + lt_settings->disallow_per_lane_settings = true; + lt_settings->always_match_dpcd_with_hw_lane_settings = true; + lt_settings->lttpr_mode = dp_decide_8b_10b_lttpr_mode(link); ++ lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting, lt_settings->lttpr_mode); + dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + } + +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-allow-p2p-access-through-xgmi.patch b/queue-6.6/drm-amdgpu-allow-p2p-access-through-xgmi.patch new file mode 100644 index 0000000000..247911d73c --- /dev/null +++ b/queue-6.6/drm-amdgpu-allow-p2p-access-through-xgmi.patch @@ -0,0 +1,88 @@ +From 19da78cfcb3627246ad201453bb25302c7784a59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 00:19:13 -0400 +Subject: drm/amdgpu: Allow P2P access through XGMI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Kuehling + +[ Upstream commit a92741e72f91b904c1d8c3d409ed8dbe9c1f2b26 ] + +If peer memory is accessible through XGMI, allow leaving it in VRAM +rather than forcing its migration to GTT on DMABuf attachment. + +Signed-off-by: Felix Kuehling +Tested-by: Hao (Claire) Zhou +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +(cherry picked from commit 372c8d72c3680fdea3fbb2d6b089f76b4a6d596a) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 30 ++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +index be4cc4868a748..493e18bcea069 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +@@ -43,6 +43,29 @@ + #include + #include + ++static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops; ++ ++/** ++ * dma_buf_attach_adev - Helper to get adev of an attachment ++ * ++ * @attach: attachment ++ * ++ * Returns: ++ * A struct amdgpu_device * if the attaching device is an amdgpu device or ++ * partition, NULL otherwise. ++ */ ++static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *attach) ++{ ++ if (attach->importer_ops == &amdgpu_dma_buf_attach_ops) { ++ struct drm_gem_object *obj = attach->importer_priv; ++ struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); ++ ++ return amdgpu_ttm_adev(bo->tbo.bdev); ++ } ++ ++ return NULL; ++} ++ + /** + * amdgpu_dma_buf_attach - &dma_buf_ops.attach implementation + * +@@ -54,12 +77,14 @@ + static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attach) + { ++ struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach); + struct drm_gem_object *obj = dmabuf->priv; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + int r; + +- if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) ++ if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) && ++ pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0) + attach->peer2peer = false; + + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); +@@ -482,6 +507,9 @@ bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev, + struct drm_gem_object *obj = &bo->tbo.base; + struct drm_gem_object *gobj; + ++ if (!adev) ++ return false; ++ + if (obj->import_attach) { + struct dma_buf *dma_buf = obj->import_attach->dmabuf; + +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-do-not-program-agp-bar-regs-under-sriov-i.patch b/queue-6.6/drm-amdgpu-do-not-program-agp-bar-regs-under-sriov-i.patch new file mode 100644 index 0000000000..9deefbcea3 --- /dev/null +++ b/queue-6.6/drm-amdgpu-do-not-program-agp-bar-regs-under-sriov-i.patch @@ -0,0 +1,45 @@ +From be899f7143a7b64322a82edcf049adf813e21e17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 18:38:28 -0500 +Subject: drm/amdgpu: Do not program AGP BAR regs under SRIOV in gfxhub_v1_0.c + +From: Victor Lu + +[ Upstream commit 057fef20b8401110a7bc1c2fe9d804a8a0bf0d24 ] + +SRIOV VF does not have write access to AGP BAR regs. +Skip the writes to avoid a dmesg warning. + +Signed-off-by: Victor Lu +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +index 66c6bab75f8a5..0d3d00681edac 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +@@ -92,12 +92,12 @@ static void gfxhub_v1_0_init_system_aperture_regs(struct amdgpu_device *adev) + { + uint64_t value; + +- /* Program the AGP BAR */ +- WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_BASE, 0); +- WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); +- WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); +- + if (!amdgpu_sriov_vf(adev) || adev->asic_type <= CHIP_VEGA10) { ++ /* Program the AGP BAR */ ++ WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_BASE, 0); ++ WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_BOT, adev->gmc.agp_start >> 24); ++ WREG32_SOC15_RLC(GC, 0, mmMC_VM_AGP_TOP, adev->gmc.agp_end >> 24); ++ + /* Program the system aperture low logical page number. */ + WREG32_SOC15_RLC(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, + min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-enlarge-the-vbios-binary-size-limit.patch b/queue-6.6/drm-amdgpu-enlarge-the-vbios-binary-size-limit.patch new file mode 100644 index 0000000000..c912b217d2 --- /dev/null +++ b/queue-6.6/drm-amdgpu-enlarge-the-vbios-binary-size-limit.patch @@ -0,0 +1,36 @@ +From 1f849f7e4531f6a9f73b93a3793dfa9fe2b43774 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2024 15:58:39 +0800 +Subject: drm/amdgpu: enlarge the VBIOS binary size limit + +From: Shiwu Zhang + +[ Upstream commit 667b96134c9e206aebe40985650bf478935cbe04 ] + +Some chips have a larger VBIOS file so raise the size limit to support +the flashing tool. + +Signed-off-by: Shiwu Zhang +Reviewed-by: Hawking Zhang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index a4ab02c85f65b..ffa5e72a84ebc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -43,7 +43,7 @@ + #include "amdgpu_securedisplay.h" + #include "amdgpu_atomfirmware.h" + +-#define AMD_VBIOS_FILE_MAX_SIZE_B (1024*1024*3) ++#define AMD_VBIOS_FILE_MAX_SIZE_B (1024*1024*16) + + static int psp_load_smu_fw(struct psp_context *psp); + static int psp_rap_terminate(struct psp_context *psp); +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-reset-psp-cmd-to-null-after-releasing-the.patch b/queue-6.6/drm-amdgpu-reset-psp-cmd-to-null-after-releasing-the.patch new file mode 100644 index 0000000000..278d1fc594 --- /dev/null +++ b/queue-6.6/drm-amdgpu-reset-psp-cmd-to-null-after-releasing-the.patch @@ -0,0 +1,45 @@ +From 3516fd6344fd744a5f8eca62359ef533c218863d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 14:28:49 +0800 +Subject: drm/amdgpu: reset psp->cmd to NULL after releasing the buffer + +From: Jiang Liu + +[ Upstream commit e92f3f94cad24154fd3baae30c6dfb918492278d ] + +Reset psp->cmd to NULL after releasing the buffer in function psp_sw_fini(). + +Reviewed-by: Lijo Lazar +Signed-off-by: Jiang Liu +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +index 6a24e8ceb9449..a4ab02c85f65b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +@@ -506,7 +506,6 @@ static int psp_sw_fini(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct psp_context *psp = &adev->psp; +- struct psp_gfx_cmd_resp *cmd = psp->cmd; + + psp_memory_training_fini(psp); + +@@ -516,8 +515,8 @@ static int psp_sw_fini(void *handle) + amdgpu_ucode_release(&psp->cap_fw); + amdgpu_ucode_release(&psp->toc_fw); + +- kfree(cmd); +- cmd = NULL; ++ kfree(psp->cmd); ++ psp->cmd = NULL; + + psp_free_shared_bufs(psp); + +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-set-snoop-bit-for-sdma-for-mi-series.patch b/queue-6.6/drm-amdgpu-set-snoop-bit-for-sdma-for-mi-series.patch new file mode 100644 index 0000000000..fa57ffc64d --- /dev/null +++ b/queue-6.6/drm-amdgpu-set-snoop-bit-for-sdma-for-mi-series.patch @@ -0,0 +1,368 @@ +From 8a0b9a5d75290b1460a5f55fc71317962d05930c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 17:57:47 -0500 +Subject: drm/amdgpu: Set snoop bit for SDMA for MI series + +From: Harish Kasiviswanathan + +[ Upstream commit 3394b1f76d3f8adf695ceed350a5dae49003eb37 ] + +SDMA writes has to probe invalidate RW lines. Set snoop bit in mmhub for +this to happen. + +v2: Missed a few mmhub_v9_4. Added now. +v3: Calculate hub offset once since it doesn't change inside the loop + Modified function names based on review comments. + +Signed-off-by: Harish Kasiviswanathan +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c | 25 ++++++++++ + drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c | 27 +++++++++++ + drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c | 31 ++++++++++++ + .../asic_reg/mmhub/mmhub_9_4_1_offset.h | 32 +++++++++++++ + .../asic_reg/mmhub/mmhub_9_4_1_sh_mask.h | 48 +++++++++++++++++++ + 5 files changed, 163 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c +index 9086f2fdfaf42..553f4f24f5ade 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c +@@ -172,6 +172,30 @@ static void mmhub_v1_7_init_tlb_regs(struct amdgpu_device *adev) + WREG32_SOC15(MMHUB, 0, regMC_VM_MX_L1_TLB_CNTL, tmp); + } + ++/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */ ++static void mmhub_v1_7_init_snoop_override_regs(struct amdgpu_device *adev) ++{ ++ uint32_t tmp; ++ int i; ++ uint32_t distance = regDAGB1_WRCLI_GPU_SNOOP_OVERRIDE - ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE; ++ ++ for (i = 0; i < 5; i++) { /* DAGB instances */ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, 0, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, i * distance); ++ tmp |= (1 << 15); /* SDMA client is BIT15 */ ++ WREG32_SOC15_OFFSET(MMHUB, 0, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, i * distance, tmp); ++ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, 0, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, i * distance); ++ tmp |= (1 << 15); ++ WREG32_SOC15_OFFSET(MMHUB, 0, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, i * distance, tmp); ++ } ++ ++} ++ + static void mmhub_v1_7_init_cache_regs(struct amdgpu_device *adev) + { + uint32_t tmp; +@@ -337,6 +361,7 @@ static int mmhub_v1_7_gart_enable(struct amdgpu_device *adev) + mmhub_v1_7_init_system_aperture_regs(adev); + mmhub_v1_7_init_tlb_regs(adev); + mmhub_v1_7_init_cache_regs(adev); ++ mmhub_v1_7_init_snoop_override_regs(adev); + + mmhub_v1_7_enable_system_domain(adev); + mmhub_v1_7_disable_identity_aperture(adev); +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +index 3d8e579d5c4e8..c7bdccff785b7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +@@ -213,6 +213,32 @@ static void mmhub_v1_8_init_tlb_regs(struct amdgpu_device *adev) + } + } + ++/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */ ++static void mmhub_v1_8_init_snoop_override_regs(struct amdgpu_device *adev) ++{ ++ uint32_t tmp, inst_mask; ++ int i, j; ++ uint32_t distance = regDAGB1_WRCLI_GPU_SNOOP_OVERRIDE - ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE; ++ ++ inst_mask = adev->aid_mask; ++ for_each_inst(i, inst_mask) { ++ for (j = 0; j < 5; j++) { /* DAGB instances */ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, i, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, j * distance); ++ tmp |= (1 << 15); /* SDMA client is BIT15 */ ++ WREG32_SOC15_OFFSET(MMHUB, i, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, j * distance, tmp); ++ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, i, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, j * distance); ++ tmp |= (1 << 15); ++ WREG32_SOC15_OFFSET(MMHUB, i, ++ regDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, j * distance, tmp); ++ } ++ } ++} ++ + static void mmhub_v1_8_init_cache_regs(struct amdgpu_device *adev) + { + uint32_t tmp, inst_mask; +@@ -418,6 +444,7 @@ static int mmhub_v1_8_gart_enable(struct amdgpu_device *adev) + mmhub_v1_8_init_system_aperture_regs(adev); + mmhub_v1_8_init_tlb_regs(adev); + mmhub_v1_8_init_cache_regs(adev); ++ mmhub_v1_8_init_snoop_override_regs(adev); + + mmhub_v1_8_enable_system_domain(adev); + mmhub_v1_8_disable_identity_aperture(adev); +diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c +index 5718e4d40e666..9713cb59d1c14 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c ++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c +@@ -198,6 +198,36 @@ static void mmhub_v9_4_init_tlb_regs(struct amdgpu_device *adev, int hubid) + hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp); + } + ++/* Set snoop bit for SDMA so that SDMA writes probe-invalidates RW lines */ ++static void mmhub_v9_4_init_snoop_override_regs(struct amdgpu_device *adev, int hubid) ++{ ++ uint32_t tmp; ++ int i; ++ uint32_t distance = mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE - ++ mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE; ++ uint32_t huboffset = hubid * MMHUB_INSTANCE_REGISTER_OFFSET; ++ ++ for (i = 0; i < 5 - (2 * hubid); i++) { ++ /* DAGB instances 0 to 4 are in hub0 and 5 to 7 are in hub1 */ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, 0, ++ mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, ++ huboffset + i * distance); ++ tmp |= (1 << 15); /* SDMA client is BIT15 */ ++ WREG32_SOC15_OFFSET(MMHUB, 0, ++ mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE, ++ huboffset + i * distance, tmp); ++ ++ tmp = RREG32_SOC15_OFFSET(MMHUB, 0, ++ mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, ++ huboffset + i * distance); ++ tmp |= (1 << 15); ++ WREG32_SOC15_OFFSET(MMHUB, 0, ++ mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE, ++ huboffset + i * distance, tmp); ++ } ++ ++} ++ + static void mmhub_v9_4_init_cache_regs(struct amdgpu_device *adev, int hubid) + { + uint32_t tmp; +@@ -392,6 +422,7 @@ static int mmhub_v9_4_gart_enable(struct amdgpu_device *adev) + if (!amdgpu_sriov_vf(adev)) + mmhub_v9_4_init_cache_regs(adev, i); + ++ mmhub_v9_4_init_snoop_override_regs(adev, i); + mmhub_v9_4_enable_system_domain(adev, i); + if (!amdgpu_sriov_vf(adev)) + mmhub_v9_4_disable_identity_aperture(adev, i); +diff --git a/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_offset.h b/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_offset.h +index c488d4a50cf46..b2252deabc17a 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_offset.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_offset.h +@@ -203,6 +203,10 @@ + #define mmDAGB0_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB0_WR_MISC_CREDIT 0x0058 + #define mmDAGB0_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE 0x005b ++#define mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x005c ++#define mmDAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB0_WRCLI_ASK_PENDING 0x005d + #define mmDAGB0_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB0_WRCLI_GO_PENDING 0x005e +@@ -455,6 +459,10 @@ + #define mmDAGB1_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB1_WR_MISC_CREDIT 0x00d8 + #define mmDAGB1_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE 0x00db ++#define mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x00dc ++#define mmDAGB1_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB1_WRCLI_ASK_PENDING 0x00dd + #define mmDAGB1_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB1_WRCLI_GO_PENDING 0x00de +@@ -707,6 +715,10 @@ + #define mmDAGB2_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB2_WR_MISC_CREDIT 0x0158 + #define mmDAGB2_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB2_WRCLI_GPU_SNOOP_OVERRIDE 0x015b ++#define mmDAGB2_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB2_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x015c ++#define mmDAGB2_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB2_WRCLI_ASK_PENDING 0x015d + #define mmDAGB2_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB2_WRCLI_GO_PENDING 0x015e +@@ -959,6 +971,10 @@ + #define mmDAGB3_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB3_WR_MISC_CREDIT 0x01d8 + #define mmDAGB3_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB3_WRCLI_GPU_SNOOP_OVERRIDE 0x01db ++#define mmDAGB3_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB3_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x01dc ++#define mmDAGB3_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB3_WRCLI_ASK_PENDING 0x01dd + #define mmDAGB3_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB3_WRCLI_GO_PENDING 0x01de +@@ -1211,6 +1227,10 @@ + #define mmDAGB4_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB4_WR_MISC_CREDIT 0x0258 + #define mmDAGB4_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB4_WRCLI_GPU_SNOOP_OVERRIDE 0x025b ++#define mmDAGB4_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB4_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x025c ++#define mmDAGB4_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB4_WRCLI_ASK_PENDING 0x025d + #define mmDAGB4_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB4_WRCLI_GO_PENDING 0x025e +@@ -4793,6 +4813,10 @@ + #define mmDAGB5_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB5_WR_MISC_CREDIT 0x3058 + #define mmDAGB5_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB5_WRCLI_GPU_SNOOP_OVERRIDE 0x305b ++#define mmDAGB5_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB5_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x305c ++#define mmDAGB5_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB5_WRCLI_ASK_PENDING 0x305d + #define mmDAGB5_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB5_WRCLI_GO_PENDING 0x305e +@@ -5045,6 +5069,10 @@ + #define mmDAGB6_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB6_WR_MISC_CREDIT 0x30d8 + #define mmDAGB6_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB6_WRCLI_GPU_SNOOP_OVERRIDE 0x30db ++#define mmDAGB6_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB6_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x30dc ++#define mmDAGB6_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB6_WRCLI_ASK_PENDING 0x30dd + #define mmDAGB6_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB6_WRCLI_GO_PENDING 0x30de +@@ -5297,6 +5325,10 @@ + #define mmDAGB7_WR_DATA_CREDIT_BASE_IDX 1 + #define mmDAGB7_WR_MISC_CREDIT 0x3158 + #define mmDAGB7_WR_MISC_CREDIT_BASE_IDX 1 ++#define mmDAGB7_WRCLI_GPU_SNOOP_OVERRIDE 0x315b ++#define mmDAGB7_WRCLI_GPU_SNOOP_OVERRIDE_BASE_IDX 1 ++#define mmDAGB7_WRCLI_GPU_SNOOP_OVERRIDE_VALUE 0x315c ++#define mmDAGB7_WRCLI_GPU_SNOOP_OVERRIDE_VALUE_BASE_IDX 1 + #define mmDAGB7_WRCLI_ASK_PENDING 0x315d + #define mmDAGB7_WRCLI_ASK_PENDING_BASE_IDX 1 + #define mmDAGB7_WRCLI_GO_PENDING 0x315e +diff --git a/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_sh_mask.h +index 2969fbf282b7d..5069d2fd467f2 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_sh_mask.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_sh_mask.h +@@ -1532,6 +1532,12 @@ + //DAGB0_WRCLI_DBUS_GO_PENDING + #define DAGB0_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB0_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB0_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB0_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB0_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB0_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB0_DAGB_DLY + #define DAGB0_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB0_DAGB_DLY__CLI__SHIFT 0x8 +@@ -3207,6 +3213,12 @@ + //DAGB1_WRCLI_DBUS_GO_PENDING + #define DAGB1_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB1_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB1_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB1_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB1_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB1_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB1_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB1_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB1_DAGB_DLY + #define DAGB1_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB1_DAGB_DLY__CLI__SHIFT 0x8 +@@ -4882,6 +4894,12 @@ + //DAGB2_WRCLI_DBUS_GO_PENDING + #define DAGB2_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB2_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB2_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB2_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB2_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB2_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB2_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB2_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB2_DAGB_DLY + #define DAGB2_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB2_DAGB_DLY__CLI__SHIFT 0x8 +@@ -6557,6 +6575,12 @@ + //DAGB3_WRCLI_DBUS_GO_PENDING + #define DAGB3_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB3_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB3_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB3_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB3_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB3_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB3_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB3_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB3_DAGB_DLY + #define DAGB3_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB3_DAGB_DLY__CLI__SHIFT 0x8 +@@ -8232,6 +8256,12 @@ + //DAGB4_WRCLI_DBUS_GO_PENDING + #define DAGB4_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB4_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB4_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB4_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB4_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB4_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB4_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB4_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB4_DAGB_DLY + #define DAGB4_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB4_DAGB_DLY__CLI__SHIFT 0x8 +@@ -28737,6 +28767,12 @@ + //DAGB5_WRCLI_DBUS_GO_PENDING + #define DAGB5_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB5_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB5_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB5_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB5_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB5_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB5_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB5_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB5_DAGB_DLY + #define DAGB5_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB5_DAGB_DLY__CLI__SHIFT 0x8 +@@ -30412,6 +30448,12 @@ + //DAGB6_WRCLI_DBUS_GO_PENDING + #define DAGB6_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB6_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB6_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB6_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB6_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB6_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB6_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB6_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB6_DAGB_DLY + #define DAGB6_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB6_DAGB_DLY__CLI__SHIFT 0x8 +@@ -32087,6 +32129,12 @@ + //DAGB7_WRCLI_DBUS_GO_PENDING + #define DAGB7_WRCLI_DBUS_GO_PENDING__BUSY__SHIFT 0x0 + #define DAGB7_WRCLI_DBUS_GO_PENDING__BUSY_MASK 0xFFFFFFFFL ++//DAGB7_WRCLI_GPU_SNOOP_OVERRIDE ++#define DAGB7_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE__SHIFT 0x0 ++#define DAGB7_WRCLI_GPU_SNOOP_OVERRIDE__ENABLE_MASK 0xFFFFFFFFL ++//DAGB7_WRCLI_GPU_SNOOP_OVERRIDE_VALUE ++#define DAGB7_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE__SHIFT 0x0 ++#define DAGB7_WRCLI_GPU_SNOOP_OVERRIDE_VALUE__ENABLE_MASK 0xFFFFFFFFL + //DAGB7_DAGB_DLY + #define DAGB7_DAGB_DLY__DLY__SHIFT 0x0 + #define DAGB7_DAGB_DLY__CLI__SHIFT 0x8 +-- +2.39.5 + diff --git a/queue-6.6/drm-amdgpu-update-sriov-video-codec-caps.patch b/queue-6.6/drm-amdgpu-update-sriov-video-codec-caps.patch new file mode 100644 index 0000000000..fa0bc31aa5 --- /dev/null +++ b/queue-6.6/drm-amdgpu-update-sriov-video-codec-caps.patch @@ -0,0 +1,91 @@ +From f4b0c8ffb6f57b8b86bcb3de744c0530133b8b75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Feb 2025 13:44:32 +0100 +Subject: drm/amdgpu: Update SRIOV video codec caps + +From: David Rosca + +[ Upstream commit 19478f2011f8b53dee401c91423c4e0b73753e4f ] + +There have been multiple fixes to the video caps that are missing for +SRIOV. Update the SRIOV caps with correct values. + +Signed-off-by: David Rosca +Acked-by: Alex Deucher +Reviewed-by: Ruijing Dong +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/nv.c | 16 ++++++++-------- + drivers/gpu/drm/amd/amdgpu/soc21.c | 10 ++-------- + 2 files changed, 10 insertions(+), 16 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c +index 7910c463ae385..82709e692f4cc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/nv.c ++++ b/drivers/gpu/drm/amd/amdgpu/nv.c +@@ -142,23 +142,23 @@ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = { + }; + + static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, + }; + + static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn1[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 1920, 1088, 3)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 1920, 1088, 5)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 1920, 1088, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + }; + +diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c +index 4712ffc0a482c..7819f5d584f59 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc21.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c +@@ -117,23 +117,17 @@ static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn1 = { + }; + + static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn0[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, + }; + + static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_decode_array_vcn1[] = { +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, +- {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, ++ {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 16384, 16384, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, + }; + +-- +2.39.5 + diff --git a/queue-6.6/drm-amdkfd-kfd-release_work-possible-circular-lockin.patch b/queue-6.6/drm-amdkfd-kfd-release_work-possible-circular-lockin.patch new file mode 100644 index 0000000000..a61aeb13be --- /dev/null +++ b/queue-6.6/drm-amdkfd-kfd-release_work-possible-circular-lockin.patch @@ -0,0 +1,80 @@ +From 195125ca306022c039959298ccd0e9f6bfc1655c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 20:08:29 -0500 +Subject: drm/amdkfd: KFD release_work possible circular locking + +From: Philip Yang + +[ Upstream commit 1b9366c601039d60546794c63fbb83ce8e53b978 ] + +If waiting for gpu reset done in KFD release_work, thers is WARNING: +possible circular locking dependency detected + + #2 kfd_create_process + kfd_process_mutex + flush kfd release work + + #1 kfd release work + wait for amdgpu reset work + + #0 amdgpu_device_gpu_reset + kgd2kfd_pre_reset + kfd_process_mutex + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock((work_completion)(&p->release_work)); + lock((wq_completion)kfd_process_wq); + lock((work_completion)(&p->release_work)); + lock((wq_completion)amdgpu-reset-dev); + +To fix this, KFD create process move flush release work outside +kfd_process_mutex. + +Signed-off-by: Philip Yang +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_process.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +index a6d08dee74f6e..93740b8fc3f44 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c +@@ -812,6 +812,14 @@ struct kfd_process *kfd_create_process(struct task_struct *thread) + return ERR_PTR(-EINVAL); + } + ++ /* If the process just called exec(3), it is possible that the ++ * cleanup of the kfd_process (following the release of the mm ++ * of the old process image) is still in the cleanup work queue. ++ * Make sure to drain any job before trying to recreate any ++ * resource for this process. ++ */ ++ flush_workqueue(kfd_process_wq); ++ + /* + * take kfd processes mutex before starting of process creation + * so there won't be a case where two threads of the same process +@@ -830,14 +838,6 @@ struct kfd_process *kfd_create_process(struct task_struct *thread) + if (process) { + pr_debug("Process already found\n"); + } else { +- /* If the process just called exec(3), it is possible that the +- * cleanup of the kfd_process (following the release of the mm +- * of the old process image) is still in the cleanup work queue. +- * Make sure to drain any job before trying to recreate any +- * resource for this process. +- */ +- flush_workqueue(kfd_process_wq); +- + process = create_process(thread); + if (IS_ERR(process)) + goto out; +-- +2.39.5 + diff --git a/queue-6.6/drm-amdkfd-set-per-process-flags-only-once-cik-vi.patch b/queue-6.6/drm-amdkfd-set-per-process-flags-only-once-cik-vi.patch new file mode 100644 index 0000000000..7f573a2864 --- /dev/null +++ b/queue-6.6/drm-amdkfd-set-per-process-flags-only-once-cik-vi.patch @@ -0,0 +1,301 @@ +From 3edbcf5df4c473ea8d8406fb518dcb1f09d9a790 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jan 2025 14:07:24 -0500 +Subject: drm/amdkfd: Set per-process flags only once cik/vi + +From: Harish Kasiviswanathan + +[ Upstream commit 289e68503a4533b014f8447e2af28ad44c92c221 ] + +Set per-process static sh_mem config only once during process +initialization. Move all static changes from update_qpd() which is +called each time a queue is created to set_cache_memory_policy() which +is called once during process initialization. + +set_cache_memory_policy() is currently defined only for cik and vi +family. So this commit only focuses on these two. A separate commit will +address other asics. + +Signed-off-by: Harish Kasiviswanathan +Reviewed-by: Amber Lin +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + .../drm/amd/amdkfd/kfd_device_queue_manager.c | 39 +--------- + .../amd/amdkfd/kfd_device_queue_manager_cik.c | 69 ++++++++++++------ + .../amd/amdkfd/kfd_device_queue_manager_vi.c | 71 ++++++++++++------- + 3 files changed, 94 insertions(+), 85 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +index 4d9a406925e18..fd4a75073364c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -2147,14 +2147,6 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, + return retval; + } + +-/* +- * Low bits must be 0000/FFFF as required by HW, high bits must be 0 to +- * stay in user mode. +- */ +-#define APE1_FIXED_BITS_MASK 0xFFFF80000000FFFFULL +-/* APE1 limit is inclusive and 64K aligned. */ +-#define APE1_LIMIT_ALIGNMENT 0xFFFF +- + static bool set_cache_memory_policy(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + enum cache_policy default_policy, +@@ -2169,34 +2161,6 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, + + dqm_lock(dqm); + +- if (alternate_aperture_size == 0) { +- /* base > limit disables APE1 */ +- qpd->sh_mem_ape1_base = 1; +- qpd->sh_mem_ape1_limit = 0; +- } else { +- /* +- * In FSA64, APE1_Base[63:0] = { 16{SH_MEM_APE1_BASE[31]}, +- * SH_MEM_APE1_BASE[31:0], 0x0000 } +- * APE1_Limit[63:0] = { 16{SH_MEM_APE1_LIMIT[31]}, +- * SH_MEM_APE1_LIMIT[31:0], 0xFFFF } +- * Verify that the base and size parameters can be +- * represented in this format and convert them. +- * Additionally restrict APE1 to user-mode addresses. +- */ +- +- uint64_t base = (uintptr_t)alternate_aperture_base; +- uint64_t limit = base + alternate_aperture_size - 1; +- +- if (limit <= base || (base & APE1_FIXED_BITS_MASK) != 0 || +- (limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) { +- retval = false; +- goto out; +- } +- +- qpd->sh_mem_ape1_base = base >> 16; +- qpd->sh_mem_ape1_limit = limit >> 16; +- } +- + retval = dqm->asic_ops.set_cache_memory_policy( + dqm, + qpd, +@@ -2205,6 +2169,9 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, + alternate_aperture_base, + alternate_aperture_size); + ++ if (retval) ++ goto out; ++ + if ((dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0)) + program_sh_mem_settings(dqm, qpd); + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c +index d4d95c7f2e5d4..32bedef912b3b 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c +@@ -27,6 +27,14 @@ + #include "oss/oss_2_4_sh_mask.h" + #include "gca/gfx_7_2_sh_mask.h" + ++/* ++ * Low bits must be 0000/FFFF as required by HW, high bits must be 0 to ++ * stay in user mode. ++ */ ++#define APE1_FIXED_BITS_MASK 0xFFFF80000000FFFFULL ++/* APE1 limit is inclusive and 64K aligned. */ ++#define APE1_LIMIT_ALIGNMENT 0xFFFF ++ + static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + enum cache_policy default_policy, +@@ -84,6 +92,36 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, + { + uint32_t default_mtype; + uint32_t ape1_mtype; ++ unsigned int temp; ++ bool retval = true; ++ ++ if (alternate_aperture_size == 0) { ++ /* base > limit disables APE1 */ ++ qpd->sh_mem_ape1_base = 1; ++ qpd->sh_mem_ape1_limit = 0; ++ } else { ++ /* ++ * In FSA64, APE1_Base[63:0] = { 16{SH_MEM_APE1_BASE[31]}, ++ * SH_MEM_APE1_BASE[31:0], 0x0000 } ++ * APE1_Limit[63:0] = { 16{SH_MEM_APE1_LIMIT[31]}, ++ * SH_MEM_APE1_LIMIT[31:0], 0xFFFF } ++ * Verify that the base and size parameters can be ++ * represented in this format and convert them. ++ * Additionally restrict APE1 to user-mode addresses. ++ */ ++ ++ uint64_t base = (uintptr_t)alternate_aperture_base; ++ uint64_t limit = base + alternate_aperture_size - 1; ++ ++ if (limit <= base || (base & APE1_FIXED_BITS_MASK) != 0 || ++ (limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) { ++ retval = false; ++ goto out; ++ } ++ ++ qpd->sh_mem_ape1_base = base >> 16; ++ qpd->sh_mem_ape1_limit = limit >> 16; ++ } + + default_mtype = (default_policy == cache_policy_coherent) ? + MTYPE_NONCACHED : +@@ -97,37 +135,22 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, + | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) + | DEFAULT_MTYPE(default_mtype) + | APE1_MTYPE(ape1_mtype); +- +- return true; +-} +- +-static int update_qpd_cik(struct device_queue_manager *dqm, +- struct qcm_process_device *qpd) +-{ +- struct kfd_process_device *pdd; +- unsigned int temp; +- +- pdd = qpd_to_pdd(qpd); +- +- /* check if sh_mem_config register already configured */ +- if (qpd->sh_mem_config == 0) { +- qpd->sh_mem_config = +- ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | +- DEFAULT_MTYPE(MTYPE_NONCACHED) | +- APE1_MTYPE(MTYPE_NONCACHED); +- qpd->sh_mem_ape1_limit = 0; +- qpd->sh_mem_ape1_base = 0; +- } +- + /* On dGPU we're always in GPUVM64 addressing mode with 64-bit + * aperture addresses. + */ +- temp = get_sh_mem_bases_nybble_64(pdd); ++ temp = get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd)); + qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); + + pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n", + qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases); + ++out: ++ return retval; ++} ++ ++static int update_qpd_cik(struct device_queue_manager *dqm, ++ struct qcm_process_device *qpd) ++{ + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c +index b291ee0fab943..320518f418903 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c +@@ -27,6 +27,14 @@ + #include "gca/gfx_8_0_sh_mask.h" + #include "oss/oss_3_0_sh_mask.h" + ++/* ++ * Low bits must be 0000/FFFF as required by HW, high bits must be 0 to ++ * stay in user mode. ++ */ ++#define APE1_FIXED_BITS_MASK 0xFFFF80000000FFFFULL ++/* APE1 limit is inclusive and 64K aligned. */ ++#define APE1_LIMIT_ALIGNMENT 0xFFFF ++ + static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + enum cache_policy default_policy, +@@ -85,6 +93,36 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, + { + uint32_t default_mtype; + uint32_t ape1_mtype; ++ unsigned int temp; ++ bool retval = true; ++ ++ if (alternate_aperture_size == 0) { ++ /* base > limit disables APE1 */ ++ qpd->sh_mem_ape1_base = 1; ++ qpd->sh_mem_ape1_limit = 0; ++ } else { ++ /* ++ * In FSA64, APE1_Base[63:0] = { 16{SH_MEM_APE1_BASE[31]}, ++ * SH_MEM_APE1_BASE[31:0], 0x0000 } ++ * APE1_Limit[63:0] = { 16{SH_MEM_APE1_LIMIT[31]}, ++ * SH_MEM_APE1_LIMIT[31:0], 0xFFFF } ++ * Verify that the base and size parameters can be ++ * represented in this format and convert them. ++ * Additionally restrict APE1 to user-mode addresses. ++ */ ++ ++ uint64_t base = (uintptr_t)alternate_aperture_base; ++ uint64_t limit = base + alternate_aperture_size - 1; ++ ++ if (limit <= base || (base & APE1_FIXED_BITS_MASK) != 0 || ++ (limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT) { ++ retval = false; ++ goto out; ++ } ++ ++ qpd->sh_mem_ape1_base = base >> 16; ++ qpd->sh_mem_ape1_limit = limit >> 16; ++ } + + default_mtype = (default_policy == cache_policy_coherent) ? + MTYPE_UC : +@@ -100,40 +138,21 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, + default_mtype << SH_MEM_CONFIG__DEFAULT_MTYPE__SHIFT | + ape1_mtype << SH_MEM_CONFIG__APE1_MTYPE__SHIFT; + +- return true; +-} +- +-static int update_qpd_vi(struct device_queue_manager *dqm, +- struct qcm_process_device *qpd) +-{ +- struct kfd_process_device *pdd; +- unsigned int temp; +- +- pdd = qpd_to_pdd(qpd); +- +- /* check if sh_mem_config register already configured */ +- if (qpd->sh_mem_config == 0) { +- qpd->sh_mem_config = +- SH_MEM_ALIGNMENT_MODE_UNALIGNED << +- SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT | +- MTYPE_UC << +- SH_MEM_CONFIG__DEFAULT_MTYPE__SHIFT | +- MTYPE_UC << +- SH_MEM_CONFIG__APE1_MTYPE__SHIFT; +- +- qpd->sh_mem_ape1_limit = 0; +- qpd->sh_mem_ape1_base = 0; +- } +- + /* On dGPU we're always in GPUVM64 addressing mode with 64-bit + * aperture addresses. + */ +- temp = get_sh_mem_bases_nybble_64(pdd); ++ temp = get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd)); + qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); + + pr_debug("sh_mem_bases nybble: 0x%X and register 0x%X\n", + temp, qpd->sh_mem_bases); ++out: ++ return retval; ++} + ++static int update_qpd_vi(struct device_queue_manager *dqm, ++ struct qcm_process_device *qpd) ++{ + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.6/drm-ast-find-vbios-mode-from-regular-display-size.patch b/queue-6.6/drm-ast-find-vbios-mode-from-regular-display-size.patch new file mode 100644 index 0000000000..6b5d706efe --- /dev/null +++ b/queue-6.6/drm-ast-find-vbios-mode-from-regular-display-size.patch @@ -0,0 +1,89 @@ +From 030c3d80a163aa5d2b2483ef89333e1e431a9efd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Jan 2025 10:21:08 +0100 +Subject: drm/ast: Find VBIOS mode from regular display size + +From: Thomas Zimmermann + +[ Upstream commit c81202906b5cd56db403e95db3d29c9dfc8c74c1 ] + +The ast driver looks up supplied display modes from an internal list of +display modes supported by the VBIOS. + +Do not use the crtc_-prefixed display values from struct drm_display_mode +for looking up the VBIOS mode. The fields contain raw values that the +driver programs to hardware. They are affected by display settings like +double-scan or interlace. + +Instead use the regular vdisplay and hdisplay fields for lookup. As the +programmed values can now differ from the values used for lookup, set +struct drm_display_mode.crtc_vdisplay and .crtc_hdisplay from the VBIOS +mode. + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Jocelyn Falempe +Link: https://patchwork.freedesktop.org/patch/msgid/20250131092257.115596-9-tzimmermann@suse.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/ast/ast_mode.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c +index 3de0f457fff6a..5f58da6ebaadb 100644 +--- a/drivers/gpu/drm/ast/ast_mode.c ++++ b/drivers/gpu/drm/ast/ast_mode.c +@@ -132,7 +132,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + return false; + } + +- switch (mode->crtc_hdisplay) { ++ switch (mode->hdisplay) { + case 640: + vbios_mode->enh_table = &res_640x480[refresh_rate_index]; + break; +@@ -146,7 +146,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + vbios_mode->enh_table = &res_1152x864[refresh_rate_index]; + break; + case 1280: +- if (mode->crtc_vdisplay == 800) ++ if (mode->vdisplay == 800) + vbios_mode->enh_table = &res_1280x800[refresh_rate_index]; + else + vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; +@@ -158,7 +158,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; + break; + case 1600: +- if (mode->crtc_vdisplay == 900) ++ if (mode->vdisplay == 900) + vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; + else + vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; +@@ -167,7 +167,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; + break; + case 1920: +- if (mode->crtc_vdisplay == 1080) ++ if (mode->vdisplay == 1080) + vbios_mode->enh_table = &res_1920x1080[refresh_rate_index]; + else + vbios_mode->enh_table = &res_1920x1200[refresh_rate_index]; +@@ -211,6 +211,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; + vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; + ++ adjusted_mode->crtc_hdisplay = vbios_mode->enh_table->hde; + adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht; + adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder; + adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder; +@@ -220,6 +221,7 @@ static bool ast_get_vbios_mode_info(const struct drm_format_info *format, + vbios_mode->enh_table->hfp + + vbios_mode->enh_table->hsync); + ++ adjusted_mode->crtc_vdisplay = vbios_mode->enh_table->vde; + adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt; + adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder; + adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder; +-- +2.39.5 + diff --git a/queue-6.6/drm-atomic-clarify-the-rules-around-drm_atomic_state.patch b/queue-6.6/drm-atomic-clarify-the-rules-around-drm_atomic_state.patch new file mode 100644 index 0000000000..5093514c39 --- /dev/null +++ b/queue-6.6/drm-atomic-clarify-the-rules-around-drm_atomic_state.patch @@ -0,0 +1,90 @@ +From 3caa226d25094a9f907011954fe712c02629de62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 18:24:16 +0100 +Subject: drm/atomic: clarify the rules around drm_atomic_state->allow_modeset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Simona Vetter + +[ Upstream commit c5e3306a424b52e38ad2c28c7f3399fcd03e383d ] + +msm is automagically upgrading normal commits to full modesets, and +that's a big no-no: + +- for one this results in full on->off->on transitions on all these + crtc, at least if you're using the usual helpers. Which seems to be + the case, and is breaking uapi + +- further even if the ctm change itself would not result in flicker, + this can hide modesets for other reasons. Which again breaks the + uapi + +v2: I forgot the case of adding unrelated crtc state. Add that case +and link to the existing kerneldoc explainers. This has come up in an +irc discussion with Manasi and Ville about intel's bigjoiner mode. +Also cc everyone involved in the msm irc discussion, more people +joined after I sent out v1. + +v3: Wording polish from Pekka and Thomas + +Acked-by: Pekka Paalanen +Acked-by: Dmitry Baryshkov +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Thomas Zimmermann +Cc: David Airlie +Cc: Daniel Vetter +Cc: Pekka Paalanen +Cc: Rob Clark +Cc: Simon Ser +Cc: Manasi Navare +Cc: Ville Syrjälä +Cc: Abhinav Kumar +Cc: Dmitry Baryshkov +Signed-off-by: Simona Vetter +Signed-off-by: Simona Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20250108172417.160831-1-simona.vetter@ffwll.ch +Signed-off-by: Sasha Levin +--- + include/drm/drm_atomic.h | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h +index 9a022caacf936..f3e7e3e5078db 100644 +--- a/include/drm/drm_atomic.h ++++ b/include/drm/drm_atomic.h +@@ -372,8 +372,27 @@ struct drm_atomic_state { + * + * Allow full modeset. This is used by the ATOMIC IOCTL handler to + * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should +- * never consult this flag, instead looking at the output of +- * drm_atomic_crtc_needs_modeset(). ++ * generally not consult this flag, but instead look at the output of ++ * drm_atomic_crtc_needs_modeset(). The detailed rules are: ++ * ++ * - Drivers must not consult @allow_modeset in the atomic commit path. ++ * Use drm_atomic_crtc_needs_modeset() instead. ++ * ++ * - Drivers must consult @allow_modeset before adding unrelated struct ++ * drm_crtc_state to this commit by calling ++ * drm_atomic_get_crtc_state(). See also the warning in the ++ * documentation for that function. ++ * ++ * - Drivers must never change this flag, it is under the exclusive ++ * control of userspace. ++ * ++ * - Drivers may consult @allow_modeset in the atomic check path, if ++ * they have the choice between an optimal hardware configuration ++ * which requires a modeset, and a less optimal configuration which ++ * can be committed without a modeset. An example would be suboptimal ++ * scanout FIFO allocation resulting in increased idle power ++ * consumption. This allows userspace to avoid flickering and delays ++ * for the normal composition loop at reasonable cost. + */ + bool allow_modeset : 1; + /** +-- +2.39.5 + diff --git a/queue-6.6/drm-bridge-adv7511-fill-stream-capabilities.patch b/queue-6.6/drm-bridge-adv7511-fill-stream-capabilities.patch new file mode 100644 index 0000000000..f32c89cda8 --- /dev/null +++ b/queue-6.6/drm-bridge-adv7511-fill-stream-capabilities.patch @@ -0,0 +1,39 @@ +From 9aea55c931fb5dbd810d549a200b63b34c840739 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 18:03:54 +0100 +Subject: drm: bridge: adv7511: fill stream capabilities + +From: Olivier Moysan + +[ Upstream commit c852646f12d4cd5b4f19eeec2976c5d98c0382f8 ] + +Set no_i2s_capture and no_spdif_capture flags in hdmi_codec_pdata structure +to report that the ADV7511 HDMI bridge does not support i2s or spdif audio +capture. + +Signed-off-by: Olivier Moysan +Reviewed-by: Dmitry Baryshkov +Link: https://patchwork.freedesktop.org/patch/msgid/20250108170356.413063-2-olivier.moysan@foss.st.com +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/adv7511/adv7511_audio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +index 8f786592143b6..24e1e11acf697 100644 +--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c ++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +@@ -244,7 +244,9 @@ static const struct hdmi_codec_pdata codec_data = { + .ops = &adv7511_codec_ops, + .max_i2s_channels = 2, + .i2s = 1, ++ .no_i2s_capture = 1, + .spdif = 1, ++ .no_spdif_capture = 1, + }; + + int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511) +-- +2.39.5 + diff --git a/queue-6.6/drm-gem-test-for-imported-gem-buffers-with-helper.patch b/queue-6.6/drm-gem-test-for-imported-gem-buffers-with-helper.patch new file mode 100644 index 0000000000..99ca277c93 --- /dev/null +++ b/queue-6.6/drm-gem-test-for-imported-gem-buffers-with-helper.patch @@ -0,0 +1,88 @@ +From e9a7ab00abcf3afbd52cd2d618eadc910a04a556 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 18:03:04 +0100 +Subject: drm/gem: Test for imported GEM buffers with helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Zimmermann + +[ Upstream commit b57aa47d39e94dc47403a745e2024664e544078c ] + +Add drm_gem_is_imported() that tests if a GEM object's buffer has +been imported. Update the GEM code accordingly. + +GEM code usually tests for imports if import_attach has been set +in struct drm_gem_object. But attaching a dma-buf on import requires +a DMA-capable importer device, which is not the case for many serial +busses like USB or I2C. The new helper tests if a GEM object's dma-buf +has been created from the GEM object. + +Signed-off-by: Thomas Zimmermann +Reviewed-by: Anusha Srivatsa +Reviewed-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20250226172457.217725-2-tzimmermann@suse.de +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_gem.c | 4 ++-- + include/drm/drm_gem.h | 14 ++++++++++++++ + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 44a948b80ee14..deb93f78ce344 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -322,7 +322,7 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, + return -ENOENT; + + /* Don't allow imported objects to be mapped */ +- if (obj->import_attach) { ++ if (drm_gem_is_imported(obj)) { + ret = -EINVAL; + goto out; + } +@@ -1155,7 +1155,7 @@ void drm_gem_print_info(struct drm_printer *p, unsigned int indent, + drm_vma_node_start(&obj->vma_node)); + drm_printf_indent(p, indent, "size=%zu\n", obj->size); + drm_printf_indent(p, indent, "imported=%s\n", +- str_yes_no(obj->import_attach)); ++ str_yes_no(drm_gem_is_imported(obj))); + + if (obj->funcs->print_info) + obj->funcs->print_info(p, indent, obj); +diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h +index 7c2ec139c464a..fbfccb96dd17b 100644 +--- a/include/drm/drm_gem.h ++++ b/include/drm/drm_gem.h +@@ -35,6 +35,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -557,6 +558,19 @@ static inline bool drm_gem_object_is_shared_for_memory_stats(struct drm_gem_obje + return (obj->handle_count > 1) || obj->dma_buf; + } + ++/** ++ * drm_gem_is_imported() - Tests if GEM object's buffer has been imported ++ * @obj: the GEM object ++ * ++ * Returns: ++ * True if the GEM object's buffer has been imported, false otherwise ++ */ ++static inline bool drm_gem_is_imported(const struct drm_gem_object *obj) ++{ ++ /* The dma-buf's priv field points to the original GEM object. */ ++ return obj->dma_buf && (obj->dma_buf->priv != obj); ++} ++ + #ifdef CONFIG_LOCKDEP + /** + * drm_gem_gpuva_set_lock() - Set the lock protecting accesses to the gpuva list. +-- +2.39.5 + diff --git a/queue-6.6/drm-mediatek-mtk_dpi-add-checks-for-reg_h_fre_con-ex.patch b/queue-6.6/drm-mediatek-mtk_dpi-add-checks-for-reg_h_fre_con-ex.patch new file mode 100644 index 0000000000..f6f8e937f3 --- /dev/null +++ b/queue-6.6/drm-mediatek-mtk_dpi-add-checks-for-reg_h_fre_con-ex.patch @@ -0,0 +1,51 @@ +From b0b7bf89f24f47ecb017532fc4908152f6a34714 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 16:47:58 +0100 +Subject: drm/mediatek: mtk_dpi: Add checks for reg_h_fre_con existence + +From: AngeloGioacchino Del Regno + +[ Upstream commit 8c9da7cd0bbcc90ab444454fecf535320456a312 ] + +In preparation for adding support for newer DPI instances which +do support direct-pin but do not have any H_FRE_CON register, +like the one found in MT8195 and MT8188, add a branch to check +if the reg_h_fre_con variable was declared in the mtk_dpi_conf +structure for the probed SoC DPI version. + +As a note, this is useful specifically only for cases in which +the support_direct_pin variable is true, so mt8195-dpintf is +not affected by any issue. + +Reviewed-by: CK Hu +Signed-off-by: AngeloGioacchino Del Regno +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250217154836.108895-6-angelogioacchino.delregno@collabora.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_dpi.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c +index 54fc3f819577e..6391afdf202e2 100644 +--- a/drivers/gpu/drm/mediatek/mtk_dpi.c ++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c +@@ -410,12 +410,13 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable) + + static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) + { +- mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); ++ if (dpi->conf->reg_h_fre_con) ++ mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); + } + + static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) + { +- if (dpi->conf->edge_sel_en) ++ if (dpi->conf->edge_sel_en && dpi->conf->reg_h_fre_con) + mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); + } + +-- +2.39.5 + diff --git a/queue-6.6/drm-panel-edp-add-starry-116khd024006.patch b/queue-6.6/drm-panel-edp-add-starry-116khd024006.patch new file mode 100644 index 0000000000..96fd1c71e6 --- /dev/null +++ b/queue-6.6/drm-panel-edp-add-starry-116khd024006.patch @@ -0,0 +1,57 @@ +From e4352e0dae0cd8e7f11bdfb079ef572e7087e639 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Jan 2025 14:28:53 -0800 +Subject: drm/panel-edp: Add Starry 116KHD024006 + +From: Douglas Anderson + +[ Upstream commit 749b5b279e5636cdcef51e15d67b77162cca6caa ] + +We have a few reports of sc7180-trogdor-pompom devices that have a +panel in them that IDs as STA 0x0004 and has the following raw EDID: + + 00 ff ff ff ff ff ff 00 4e 81 04 00 00 00 00 00 + 10 20 01 04 a5 1a 0e 78 0a dc dd 96 5b 5b 91 28 + 1f 52 54 00 00 00 01 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 8e 1c 56 a0 50 00 1e 30 28 20 + 55 00 00 90 10 00 00 18 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe + 00 31 31 36 4b 48 44 30 32 34 30 30 36 0a 00 e6 + +We've been unable to locate a datasheet for this panel and our partner +has not been responsive, but all Starry eDP datasheets that we can +find agree on the same timing (delay_100_500_e200) so it should be +safe to use that here instead of the super conservative timings. We'll +still go a little extra conservative and allow `hpd_absent` of 200 +instead of 100 because that won't add any real-world delay in most +cases. + +We'll associate the string from the EDID ("116KHD024006") with this +panel. Given that the ID is the suspicious value of 0x0004 it seems +likely that Starry doesn't always update their IDs but the string will +still work to differentiate if we ever need to in the future. + +Reviewed-by: Neil Armstrong +Signed-off-by: Douglas Anderson +Link: https://patchwork.freedesktop.org/patch/msgid/20250109142853.1.Ibcc3009933fd19507cc9c713ad0c99c7a9e4fe17@changeid +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-edp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c +index 94fe2f3836a9a..53b3b24d7d7c0 100644 +--- a/drivers/gpu/drm/panel/panel-edp.c ++++ b/drivers/gpu/drm/panel/panel-edp.c +@@ -1923,6 +1923,7 @@ static const struct edp_panel_entry edp_panels[] = { + EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &sharp_lq140m1jw46.delay, "LQ140M1JW46"), + EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"), + ++ EDP_PANEL_ENTRY('S', 'T', 'A', 0x0004, &delay_200_500_e200, "116KHD024006"), + EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"), + + { /* sentinal */ } +-- +2.39.5 + diff --git a/queue-6.6/drm-rockchip-vop2-add-uv-swap-for-cluster-window.patch b/queue-6.6/drm-rockchip-vop2-add-uv-swap-for-cluster-window.patch new file mode 100644 index 0000000000..30d6620e4e --- /dev/null +++ b/queue-6.6/drm-rockchip-vop2-add-uv-swap-for-cluster-window.patch @@ -0,0 +1,46 @@ +From 3cbc2c43013927ee925d23d30166a8f0fea5f3a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 11:44:17 +0800 +Subject: drm/rockchip: vop2: Add uv swap for cluster window + +From: Andy Yan + +[ Upstream commit e7aae9f6d762139f8d2b86db03793ae0ab3dd802 ] + +The Cluster windows of upcoming VOP on rk3576 also support +linear YUV support, we need to set uv swap bit for it. + +As the VOP2_WIN_UV_SWA register defined on rk3568/rk3588 is +0xffffffff, so this register will not be touched on these +two platforms. + +Signed-off-by: Andy Yan +Tested-by: Michael Riesch # on RK3568 +Tested-by: Detlev Casanova +Signed-off-by: Heiko Stuebner +Link: https://patchwork.freedesktop.org/patch/msgid/20250303034436.192400-4-andyshrk@163.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +index d8f8c37c326c4..0193d10867dd2 100644 +--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c ++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +@@ -1290,10 +1290,8 @@ static void vop2_plane_atomic_update(struct drm_plane *plane, + + rb_swap = vop2_win_rb_swap(fb->format->format); + vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap); +- if (!vop2_cluster_window(win)) { +- uv_swap = vop2_win_uv_swap(fb->format->format); +- vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap); +- } ++ uv_swap = vop2_win_uv_swap(fb->format->format); ++ vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap); + + if (fb->format->is_yuv) { + vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4)); +-- +2.39.5 + diff --git a/queue-6.6/drm-v3d-add-clock-handling.patch b/queue-6.6/drm-v3d-add-clock-handling.patch new file mode 100644 index 0000000000..9885941e0c --- /dev/null +++ b/queue-6.6/drm-v3d-add-clock-handling.patch @@ -0,0 +1,108 @@ +From 0d5fdc1f64e8ea18da075a1a5e4a24f461420fe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Feb 2025 13:50:46 +0100 +Subject: drm/v3d: Add clock handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Stefan Wahren + +[ Upstream commit 4dd40b5f9c3d89b67af0dbe059cf4a51aac6bf06 ] + +Since the initial commit 57692c94dcbe ("drm/v3d: Introduce a new DRM driver +for Broadcom V3D V3.x+") the struct v3d_dev reserved a pointer for +an optional V3D clock. But there wasn't any code, which fetched it. +So add the missing clock handling before accessing any V3D registers. + +Signed-off-by: Stefan Wahren +Reviewed-by: Maíra Canal +Signed-off-by: Maíra Canal +Link: https://patchwork.freedesktop.org/patch/msgid/20250201125046.33030-1-wahrenst@gmx.net +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/v3d/v3d_drv.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c +index ffbbe9d527d32..0e8ea99011884 100644 +--- a/drivers/gpu/drm/v3d/v3d_drv.c ++++ b/drivers/gpu/drm/v3d/v3d_drv.c +@@ -226,11 +226,21 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ v3d->clk = devm_clk_get_optional(dev, NULL); ++ if (IS_ERR(v3d->clk)) ++ return dev_err_probe(dev, PTR_ERR(v3d->clk), "Failed to get V3D clock\n"); ++ ++ ret = clk_prepare_enable(v3d->clk); ++ if (ret) { ++ dev_err(&pdev->dev, "Couldn't enable the V3D clock\n"); ++ return ret; ++ } ++ + mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO); + mask = DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH)); + ret = dma_set_mask_and_coherent(dev, mask); + if (ret) +- return ret; ++ goto clk_disable; + + v3d->va_width = 30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_VA_WIDTH); + +@@ -245,28 +255,29 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) + ret = PTR_ERR(v3d->reset); + + if (ret == -EPROBE_DEFER) +- return ret; ++ goto clk_disable; + + v3d->reset = NULL; + ret = map_regs(v3d, &v3d->bridge_regs, "bridge"); + if (ret) { + dev_err(dev, + "Failed to get reset control or bridge regs\n"); +- return ret; ++ goto clk_disable; + } + } + + if (v3d->ver < 41) { + ret = map_regs(v3d, &v3d->gca_regs, "gca"); + if (ret) +- return ret; ++ goto clk_disable; + } + + v3d->mmu_scratch = dma_alloc_wc(dev, 4096, &v3d->mmu_scratch_paddr, + GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); + if (!v3d->mmu_scratch) { + dev_err(dev, "Failed to allocate MMU scratch page\n"); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto clk_disable; + } + + ret = v3d_gem_init(drm); +@@ -289,6 +300,8 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) + v3d_gem_destroy(drm); + dma_free: + dma_free_wc(dev, 4096, v3d->mmu_scratch, v3d->mmu_scratch_paddr); ++clk_disable: ++ clk_disable_unprepare(v3d->clk); + return ret; + } + +@@ -303,6 +316,8 @@ static void v3d_platform_drm_remove(struct platform_device *pdev) + + dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch, + v3d->mmu_scratch_paddr); ++ ++ clk_disable_unprepare(v3d->clk); + } + + static struct platform_driver v3d_platform_driver = { +-- +2.39.5 + diff --git a/queue-6.6/edac-ie31200-work-around-false-positive-build-warnin.patch b/queue-6.6/edac-ie31200-work-around-false-positive-build-warnin.patch new file mode 100644 index 0000000000..723ac8d901 --- /dev/null +++ b/queue-6.6/edac-ie31200-work-around-false-positive-build-warnin.patch @@ -0,0 +1,105 @@ +From 3753c9ebab9d27dcc7709582df376989cf686711 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 07:50:26 +0100 +Subject: EDAC/ie31200: work around false positive build warning + +From: Arnd Bergmann + +[ Upstream commit c29dfd661fe2f8d1b48c7f00590929c04b25bf40 ] + +gcc-14 produces a bogus warning in some configurations: + +drivers/edac/ie31200_edac.c: In function 'ie31200_probe1.isra': +drivers/edac/ie31200_edac.c:412:26: error: 'dimm_info' is used uninitialized [-Werror=uninitialized] + 412 | struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL]; + | ^~~~~~~~~ +drivers/edac/ie31200_edac.c:412:26: note: 'dimm_info' declared here + 412 | struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL]; + | ^~~~~~~~~ + +I don't see any way the unintialized access could really happen here, +but I can see why the compiler gets confused by the two loops. + +Instead, rework the two nested loops to only read the addr_decode +registers and then keep only one instance of the dimm info structure. + +[Tony: Qiuxu pointed out that the "populate DIMM info" comment was left +behind in the refactor and suggested moving it. I deleted the comment +as unnecessry in front os a call to populate_dimm_info(). That seems +pretty self-describing.] + +Signed-off-by: Arnd Bergmann +Acked-by: Jason Baron +Signed-off-by: Tony Luck +Link: https://lore.kernel.org/all/20250122065031.1321015-1-arnd@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/edac/ie31200_edac.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c +index 56be8ef40f376..e3635fba63b49 100644 +--- a/drivers/edac/ie31200_edac.c ++++ b/drivers/edac/ie31200_edac.c +@@ -405,10 +405,9 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) + int i, j, ret; + struct mem_ctl_info *mci = NULL; + struct edac_mc_layer layers[2]; +- struct dimm_data dimm_info[IE31200_CHANNELS][IE31200_DIMMS_PER_CHANNEL]; + void __iomem *window; + struct ie31200_priv *priv; +- u32 addr_decode, mad_offset; ++ u32 addr_decode[IE31200_CHANNELS], mad_offset; + + /* + * Kaby Lake, Coffee Lake seem to work like Skylake. Please re-visit +@@ -466,19 +465,10 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) + mad_offset = IE31200_MAD_DIMM_0_OFFSET; + } + +- /* populate DIMM info */ + for (i = 0; i < IE31200_CHANNELS; i++) { +- addr_decode = readl(window + mad_offset + ++ addr_decode[i] = readl(window + mad_offset + + (i * 4)); +- edac_dbg(0, "addr_decode: 0x%x\n", addr_decode); +- for (j = 0; j < IE31200_DIMMS_PER_CHANNEL; j++) { +- populate_dimm_info(&dimm_info[i][j], addr_decode, j, +- skl); +- edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n", +- dimm_info[i][j].size, +- dimm_info[i][j].dual_rank, +- dimm_info[i][j].x16_width); +- } ++ edac_dbg(0, "addr_decode: 0x%x\n", addr_decode[i]); + } + + /* +@@ -489,14 +479,22 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) + */ + for (i = 0; i < IE31200_DIMMS_PER_CHANNEL; i++) { + for (j = 0; j < IE31200_CHANNELS; j++) { ++ struct dimm_data dimm_info; + struct dimm_info *dimm; + unsigned long nr_pages; + +- nr_pages = IE31200_PAGES(dimm_info[j][i].size, skl); ++ populate_dimm_info(&dimm_info, addr_decode[j], i, ++ skl); ++ edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n", ++ dimm_info.size, ++ dimm_info.dual_rank, ++ dimm_info.x16_width); ++ ++ nr_pages = IE31200_PAGES(dimm_info.size, skl); + if (nr_pages == 0) + continue; + +- if (dimm_info[j][i].dual_rank) { ++ if (dimm_info.dual_rank) { + nr_pages = nr_pages / 2; + dimm = edac_get_dimm(mci, (i * 2) + 1, j, 0); + dimm->nr_pages = nr_pages; +-- +2.39.5 + diff --git a/queue-6.6/eth-mlx4-don-t-try-to-complete-xdp-frames-in-netpoll.patch b/queue-6.6/eth-mlx4-don-t-try-to-complete-xdp-frames-in-netpoll.patch new file mode 100644 index 0000000000..ace1ca0cff --- /dev/null +++ b/queue-6.6/eth-mlx4-don-t-try-to-complete-xdp-frames-in-netpoll.patch @@ -0,0 +1,39 @@ +From 23a4d37e5a00f45b4684f19190dfcb13b781ffa2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 17:06:33 -0800 +Subject: eth: mlx4: don't try to complete XDP frames in netpoll + +From: Jakub Kicinski + +[ Upstream commit 8fdeafd66edaf420ea0063a1f13442fe3470fe70 ] + +mlx4 doesn't support ndo_xdp_xmit / XDP_REDIRECT and wasn't +using page pool until now, so it could run XDP completions +in netpoll (NAPI budget == 0) just fine. Page pool has calling +context requirements, make sure we don't try to call it from +what is potentially HW IRQ context. + +Reviewed-by: Tariq Toukan +Link: https://patch.msgid.link/20250213010635.1354034-3-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx4/en_tx.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +index 65cb63f6c4658..61a0fd8424a2c 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +@@ -450,6 +450,8 @@ int mlx4_en_process_tx_cq(struct net_device *dev, + + if (unlikely(!priv->port_up)) + return 0; ++ if (unlikely(!napi_budget) && cq->type == TX_XDP) ++ return 0; + + netdev_txq_bql_complete_prefetchw(ring->tx_queue); + +-- +2.39.5 + diff --git a/queue-6.6/exit-fix-the-usage-of-delay_group_leader-exit_code-i.patch b/queue-6.6/exit-fix-the-usage-of-delay_group_leader-exit_code-i.patch new file mode 100644 index 0000000000..8981014a2d --- /dev/null +++ b/queue-6.6/exit-fix-the-usage-of-delay_group_leader-exit_code-i.patch @@ -0,0 +1,52 @@ +From a519a9b68e0f8ab06feb6ee7e4514e2b36a1c0d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 18:19:41 +0100 +Subject: exit: fix the usage of delay_group_leader->exit_code in + do_notify_parent() and pidfs_exit() + +From: Oleg Nesterov + +[ Upstream commit 9133607de37a4887c6f89ed937176a0a0c1ebb17 ] + +Consider a process with a group leader L and a sub-thread T. +L does sys_exit(1), then T does sys_exit_group(2). + +In this case wait_task_zombie(L) will notice SIGNAL_GROUP_EXIT and use +L->signal->group_exit_code, this is correct. + +But, before that, do_notify_parent(L) called by release_task(T) will use +L->exit_code != L->signal->group_exit_code, and this is not consistent. +We don't really care, I think that nobody relies on the info which comes +with SIGCHLD, if nothing else SIGCHLD < SIGRTMIN can be queued only once. + +But pidfs_exit() is more problematic, I think pidfs_exit_info->exit_code +should report ->group_exit_code in this case, just like wait_task_zombie(). + +TODO: with this change we can hopefully cleanup (or may be even kill) the +similar SIGNAL_GROUP_EXIT checks, at least in wait_task_zombie(). + +Signed-off-by: Oleg Nesterov +Link: https://lore.kernel.org/r/20250324171941.GA13114@redhat.com +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + kernel/exit.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/exit.c b/kernel/exit.c +index 3540b2c9b1b6a..1b7257c12cb10 100644 +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -264,6 +264,9 @@ void release_task(struct task_struct *p) + leader = p->group_leader; + if (leader != p && thread_group_empty(leader) + && leader->exit_state == EXIT_ZOMBIE) { ++ /* for pidfs_exit() and do_notify_parent() */ ++ if (leader->signal->flags & SIGNAL_GROUP_EXIT) ++ leader->exit_code = leader->signal->group_exit_code; + /* + * If we were the last child thread and the leader has + * exited already, and the leader's parent ignores SIGCHLD, +-- +2.39.5 + diff --git a/queue-6.6/ext4-do-not-convert-the-unwritten-extents-if-data-wr.patch b/queue-6.6/ext4-do-not-convert-the-unwritten-extents-if-data-wr.patch new file mode 100644 index 0000000000..f410ff36d1 --- /dev/null +++ b/queue-6.6/ext4-do-not-convert-the-unwritten-extents-if-data-wr.patch @@ -0,0 +1,90 @@ +From ce22aa6064edcc7703c6d3032971bdecbfcbc0a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 19:05:26 +0800 +Subject: ext4: do not convert the unwritten extents if data writeback fails + +From: Baokun Li + +[ Upstream commit e856f93e0fb249955f7d5efb18fe20500a9ccc6d ] + +When dioread_nolock is turned on (the default), it will convert unwritten +extents to written at ext4_end_io_end(), even if the data writeback fails. + +It leads to the possibility that stale data may be exposed when the +physical block corresponding to the file data is read-only (i.e., writes +return -EIO, but reads are normal). + +Therefore a new ext4_io_end->flags EXT4_IO_END_FAILED is added, which +indicates that some bio write-back failed in the current ext4_io_end. +When this flag is set, the unwritten to written conversion is no longer +performed. Users can read the data normally until the caches are dropped, +after that, the failed extents can only be read to all 0. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Reviewed-by: Zhang Yi +Link: https://patch.msgid.link/20250122110533.4116662-3-libaokun@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/ext4.h | 3 ++- + fs/ext4/page-io.c | 16 ++++++++++++++-- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 60455c84a9374..bf62c3dab4fa2 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -273,7 +273,8 @@ struct ext4_system_blocks { + /* + * Flags for ext4_io_end->flags + */ +-#define EXT4_IO_END_UNWRITTEN 0x0001 ++#define EXT4_IO_END_UNWRITTEN 0x0001 ++#define EXT4_IO_END_FAILED 0x0002 + + struct ext4_io_end_vec { + struct list_head list; /* list of io_end_vec */ +diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c +index 7ab4f5a9bf5b8..7287dbfe13f12 100644 +--- a/fs/ext4/page-io.c ++++ b/fs/ext4/page-io.c +@@ -181,14 +181,25 @@ static int ext4_end_io_end(ext4_io_end_t *io_end) + "list->prev 0x%p\n", + io_end, inode->i_ino, io_end->list.next, io_end->list.prev); + +- io_end->handle = NULL; /* Following call will use up the handle */ +- ret = ext4_convert_unwritten_io_end_vec(handle, io_end); ++ /* ++ * Do not convert the unwritten extents if data writeback fails, ++ * or stale data may be exposed. ++ */ ++ io_end->handle = NULL; /* Following call will use up the handle */ ++ if (unlikely(io_end->flag & EXT4_IO_END_FAILED)) { ++ ret = -EIO; ++ if (handle) ++ jbd2_journal_free_reserved(handle); ++ } else { ++ ret = ext4_convert_unwritten_io_end_vec(handle, io_end); ++ } + if (ret < 0 && !ext4_forced_shutdown(inode->i_sb)) { + ext4_msg(inode->i_sb, KERN_EMERG, + "failed to convert unwritten extents to written " + "extents -- potential data loss! " + "(inode %lu, error %d)", inode->i_ino, ret); + } ++ + ext4_clear_io_unwritten_flag(io_end); + ext4_release_io_end(io_end); + return ret; +@@ -344,6 +355,7 @@ static void ext4_end_bio(struct bio *bio) + bio->bi_status, inode->i_ino, + (unsigned long long) + bi_sector >> (inode->i_blkbits - 9)); ++ io_end->flag |= EXT4_IO_END_FAILED; + mapping_set_error(inode->i_mapping, + blk_status_to_errno(bio->bi_status)); + } +-- +2.39.5 + diff --git a/queue-6.6/ext4-don-t-write-back-data-before-punch-hole-in-nojo.patch b/queue-6.6/ext4-don-t-write-back-data-before-punch-hole-in-nojo.patch new file mode 100644 index 0000000000..2a36c10f96 --- /dev/null +++ b/queue-6.6/ext4-don-t-write-back-data-before-punch-hole-in-nojo.patch @@ -0,0 +1,71 @@ +From 917d76b6f6ff0f8c2e0f1bd7dc716b49cc6339d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 09:16:30 +0800 +Subject: ext4: don't write back data before punch hole in nojournal mode + +From: Zhang Yi + +[ Upstream commit 43d0105e2c7523cc6b14cad65e2044e829c0a07a ] + +There is no need to write back all data before punching a hole in +non-journaled mode since it will be dropped soon after removing space. +Therefore, the call to filemap_write_and_wait_range() can be eliminated. +Besides, similar to ext4_zero_range(), we must address the case of +partially punched folios when block size < page size. It is essential to +remove writable userspace mappings to ensure that the folio can be +faulted again during subsequent mmap write access. + +In journaled mode, we need to write dirty pages out before discarding +page cache in case of crash before committing the freeing data +transaction, which could expose old, stale data, even if synchronization +has been performed. + +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Reviewed-by: Ojaswin Mujoo +Link: https://patch.msgid.link/20241220011637.1157197-4-yi.zhang@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/inode.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index d3d28e6587202..456f686136fc5 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -3946,17 +3946,6 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length) + + trace_ext4_punch_hole(inode, offset, length, 0); + +- /* +- * Write out all dirty pages to avoid race conditions +- * Then release them. +- */ +- if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { +- ret = filemap_write_and_wait_range(mapping, offset, +- offset + length - 1); +- if (ret) +- return ret; +- } +- + inode_lock(inode); + + /* No need to punch hole beyond i_size */ +@@ -4018,8 +4007,11 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length) + ret = ext4_update_disksize_before_punch(inode, offset, length); + if (ret) + goto out_dio; +- truncate_pagecache_range(inode, first_block_offset, +- last_block_offset); ++ ++ ret = ext4_truncate_page_cache_block_range(inode, ++ first_block_offset, last_block_offset + 1); ++ if (ret) ++ goto out_dio; + } + + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) +-- +2.39.5 + diff --git a/queue-6.6/ext4-on-a-remount-only-log-the-ro-or-r-w-state-when-.patch b/queue-6.6/ext4-on-a-remount-only-log-the-ro-or-r-w-state-when-.patch new file mode 100644 index 0000000000..7a2487838e --- /dev/null +++ b/queue-6.6/ext4-on-a-remount-only-log-the-ro-or-r-w-state-when-.patch @@ -0,0 +1,56 @@ +From 47d7575ed065da6ed238944148ba2908bdc56e51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Mar 2025 11:10:11 -0600 +Subject: ext4: on a remount, only log the ro or r/w state when it has changed + +From: Nicolas Bretz + +[ Upstream commit d7b0befd09320e3356a75cb96541c030515e7f5f ] + +A user complained that a message such as: + +EXT4-fs (nvme0n1p3): re-mounted UUID ro. Quota mode: none. + +implied that the file system was previously mounted read/write and was +now remounted read-only, when it could have been some other mount +state that had changed by the "mount -o remount" operation. Fix this +by only logging "ro"or "r/w" when it has changed. + +https://bugzilla.kernel.org/show_bug.cgi?id=219132 + +Signed-off-by: Nicolas Bretz +Link: https://patch.msgid.link/20250319171011.8372-1-bretznic@gmail.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/super.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 751c879271e05..3dcaf06ada364 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -6771,6 +6771,7 @@ static int ext4_reconfigure(struct fs_context *fc) + { + struct super_block *sb = fc->root->d_sb; + int ret; ++ bool old_ro = sb_rdonly(sb); + + fc->s_fs_info = EXT4_SB(sb); + +@@ -6782,9 +6783,9 @@ static int ext4_reconfigure(struct fs_context *fc) + if (ret < 0) + return ret; + +- ext4_msg(sb, KERN_INFO, "re-mounted %pU %s. Quota mode: %s.", +- &sb->s_uuid, sb_rdonly(sb) ? "ro" : "r/w", +- ext4_quota_mode(sb)); ++ ext4_msg(sb, KERN_INFO, "re-mounted %pU%s.", ++ &sb->s_uuid, ++ (old_ro != sb_rdonly(sb)) ? (sb_rdonly(sb) ? " ro" : " r/w") : ""); + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/ext4-reject-the-data_err-abort-option-in-nojournal-m.patch b/queue-6.6/ext4-reject-the-data_err-abort-option-in-nojournal-m.patch new file mode 100644 index 0000000000..27391dff56 --- /dev/null +++ b/queue-6.6/ext4-reject-the-data_err-abort-option-in-nojournal-m.patch @@ -0,0 +1,56 @@ +From ec0d39270ac14d0aae0dc8549a2a823ac6ff1f3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 19:05:27 +0800 +Subject: ext4: reject the 'data_err=abort' option in nojournal mode + +From: Baokun Li + +[ Upstream commit 26343ca0df715097065b02a6cddb4a029d5b9327 ] + +data_err=abort aborts the journal on I/O errors. However, this option is +meaningless if journal is disabled, so it is rejected in nojournal mode +to reduce unnecessary checks. Also, this option is ignored upon remount. + +Signed-off-by: Baokun Li +Reviewed-by: Zhang Yi +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20250122110533.4116662-4-libaokun@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/super.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 3dcaf06ada364..d2b58f940aab5 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2821,6 +2821,13 @@ static int ext4_check_opt_consistency(struct fs_context *fc, + } + + if (is_remount) { ++ if (!sbi->s_journal && ++ ctx_test_mount_opt(ctx, EXT4_MOUNT_DATA_ERR_ABORT)) { ++ ext4_msg(NULL, KERN_WARNING, ++ "Remounting fs w/o journal so ignoring data_err option"); ++ ctx_clear_mount_opt(ctx, EXT4_MOUNT_DATA_ERR_ABORT); ++ } ++ + if (ctx_test_mount_opt(ctx, EXT4_MOUNT_DAX_ALWAYS) && + (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) { + ext4_msg(NULL, KERN_ERR, "can't mount with " +@@ -5421,6 +5428,11 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) + "data=, fs mounted w/o journal"); + goto failed_mount3a; + } ++ if (test_opt(sb, DATA_ERR_ABORT)) { ++ ext4_msg(sb, KERN_ERR, ++ "can't mount with data_err=abort, fs mounted w/o journal"); ++ goto failed_mount3a; ++ } + sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM; + clear_opt(sb, JOURNAL_CHECKSUM); + clear_opt(sb, DATA_FLAGS); +-- +2.39.5 + diff --git a/queue-6.6/ext4-remove-writable-userspace-mappings-before-trunc.patch b/queue-6.6/ext4-remove-writable-userspace-mappings-before-trunc.patch new file mode 100644 index 0000000000..6b73b4e952 --- /dev/null +++ b/queue-6.6/ext4-remove-writable-userspace-mappings-before-trunc.patch @@ -0,0 +1,185 @@ +From 63ba92105331da8563f96f1ef3f4441181ddc742 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Dec 2024 09:16:28 +0800 +Subject: ext4: remove writable userspace mappings before truncating page cache + +From: Zhang Yi + +[ Upstream commit 17207d0bb209e8b40f27d7f3f96e82a78af0bf2c ] + +When zeroing a range of folios on the filesystem which block size is +less than the page size, the file's mapped blocks within one page will +be marked as unwritten, we should remove writable userspace mappings to +ensure that ext4_page_mkwrite() can be called during subsequent write +access to these partial folios. Otherwise, data written by subsequent +mmap writes may not be saved to disk. + + $mkfs.ext4 -b 1024 /dev/vdb + $mount /dev/vdb /mnt + $xfs_io -t -f -c "pwrite -S 0x58 0 4096" -c "mmap -rw 0 4096" \ + -c "mwrite -S 0x5a 2048 2048" -c "fzero 2048 2048" \ + -c "mwrite -S 0x59 2048 2048" -c "close" /mnt/foo + + $od -Ax -t x1z /mnt/foo + 000000 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 + * + 000800 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 59 + * + 001000 + + $umount /mnt && mount /dev/vdb /mnt + $od -Ax -t x1z /mnt/foo + 000000 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 + * + 000800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + 001000 + +Fix this by introducing ext4_truncate_page_cache_block_range() to remove +writable userspace mappings when truncating a partial folio range. +Additionally, move the journal data mode-specific handlers and +truncate_pagecache_range() into this function, allowing it to serve as a +common helper that correctly manages the page cache in preparation for +block range manipulations. + +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Reviewed-by: Ojaswin Mujoo +Link: https://patch.msgid.link/20241220011637.1157197-2-yi.zhang@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/ext4.h | 2 ++ + fs/ext4/extents.c | 19 ++++---------- + fs/ext4/inode.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 70 insertions(+), 14 deletions(-) + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index bf62c3dab4fa2..81fe87fcbfa06 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2995,6 +2995,8 @@ extern int ext4_inode_attach_jinode(struct inode *inode); + extern int ext4_can_truncate(struct inode *inode); + extern int ext4_truncate(struct inode *); + extern int ext4_break_layouts(struct inode *); ++extern int ext4_truncate_page_cache_block_range(struct inode *inode, ++ loff_t start, loff_t end); + extern int ext4_punch_hole(struct file *file, loff_t offset, loff_t length); + extern void ext4_set_inode_flags(struct inode *, bool init); + extern int ext4_alloc_da_blocks(struct inode *inode); +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 32218ac7f50fe..39e3661a80c43 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4660,22 +4660,13 @@ static long ext4_zero_range(struct file *file, loff_t offset, + goto out_mutex; + } + +- /* +- * For journalled data we need to write (and checkpoint) pages +- * before discarding page cache to avoid inconsitent data on +- * disk in case of crash before zeroing trans is committed. +- */ +- if (ext4_should_journal_data(inode)) { +- ret = filemap_write_and_wait_range(mapping, start, +- end - 1); +- if (ret) { +- filemap_invalidate_unlock(mapping); +- goto out_mutex; +- } ++ /* Now release the pages and zero block aligned part of pages */ ++ ret = ext4_truncate_page_cache_block_range(inode, start, end); ++ if (ret) { ++ filemap_invalidate_unlock(mapping); ++ goto out_mutex; + } + +- /* Now release the pages and zero block aligned part of pages */ +- truncate_pagecache_range(inode, start, end - 1); + inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 456f686136fc5..86245e27be18d 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -3892,6 +3893,68 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset, + return ret; + } + ++static inline void ext4_truncate_folio(struct inode *inode, ++ loff_t start, loff_t end) ++{ ++ unsigned long blocksize = i_blocksize(inode); ++ struct folio *folio; ++ ++ /* Nothing to be done if no complete block needs to be truncated. */ ++ if (round_up(start, blocksize) >= round_down(end, blocksize)) ++ return; ++ ++ folio = filemap_lock_folio(inode->i_mapping, start >> PAGE_SHIFT); ++ if (IS_ERR(folio)) ++ return; ++ ++ if (folio_mkclean(folio)) ++ folio_mark_dirty(folio); ++ folio_unlock(folio); ++ folio_put(folio); ++} ++ ++int ext4_truncate_page_cache_block_range(struct inode *inode, ++ loff_t start, loff_t end) ++{ ++ unsigned long blocksize = i_blocksize(inode); ++ int ret; ++ ++ /* ++ * For journalled data we need to write (and checkpoint) pages ++ * before discarding page cache to avoid inconsitent data on disk ++ * in case of crash before freeing or unwritten converting trans ++ * is committed. ++ */ ++ if (ext4_should_journal_data(inode)) { ++ ret = filemap_write_and_wait_range(inode->i_mapping, start, ++ end - 1); ++ if (ret) ++ return ret; ++ goto truncate_pagecache; ++ } ++ ++ /* ++ * If the block size is less than the page size, the file's mapped ++ * blocks within one page could be freed or converted to unwritten. ++ * So it's necessary to remove writable userspace mappings, and then ++ * ext4_page_mkwrite() can be called during subsequent write access ++ * to these partial folios. ++ */ ++ if (!IS_ALIGNED(start | end, PAGE_SIZE) && ++ blocksize < PAGE_SIZE && start < inode->i_size) { ++ loff_t page_boundary = round_up(start, PAGE_SIZE); ++ ++ ext4_truncate_folio(inode, start, min(page_boundary, end)); ++ if (end > page_boundary) ++ ext4_truncate_folio(inode, ++ round_down(end, PAGE_SIZE), end); ++ } ++ ++truncate_pagecache: ++ truncate_pagecache_range(inode, start, end - 1); ++ return 0; ++} ++ + static void ext4_wait_dax_page(struct inode *inode) + { + filemap_invalidate_unlock(inode->i_mapping); +-- +2.39.5 + diff --git a/queue-6.6/ext4-reorder-capability-check-last.patch b/queue-6.6/ext4-reorder-capability-check-last.patch new file mode 100644 index 0000000000..22aa0468af --- /dev/null +++ b/queue-6.6/ext4-reorder-capability-check-last.patch @@ -0,0 +1,55 @@ +From 0c84eaaa40c4cff932bbbea757f9e606d4d31b68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Mar 2025 17:06:39 +0100 +Subject: ext4: reorder capability check last +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian Göttsche + +[ Upstream commit 1b419c889c0767a5b66d0a6c566cae491f1cb0f7 ] + +capable() calls refer to enabled LSMs whether to permit or deny the +request. This is relevant in connection with SELinux, where a +capability check results in a policy decision and by default a denial +message on insufficient permission is issued. +It can lead to three undesired cases: + 1. A denial message is generated, even in case the operation was an + unprivileged one and thus the syscall succeeded, creating noise. + 2. To avoid the noise from 1. the policy writer adds a rule to ignore + those denial messages, hiding future syscalls, where the task + performs an actual privileged operation, leading to hidden limited + functionality of that task. + 3. To avoid the noise from 1. the policy writer adds a rule to permit + the task the requested capability, while it does not need it, + violating the principle of least privilege. + +Signed-off-by: Christian Göttsche +Reviewed-by: Serge Hallyn +Reviewed-by: Jan Kara +Link: https://patch.msgid.link/20250302160657.127253-2-cgoettsche@seltendoof.de +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/balloc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index 396474e9e2bff..3a2dfc59fb40f 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -641,8 +641,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi, + /* Hm, nope. Are (enough) root reserved clusters available? */ + if (uid_eq(sbi->s_resuid, current_fsuid()) || + (!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) && in_group_p(sbi->s_resgid)) || +- capable(CAP_SYS_RESOURCE) || +- (flags & EXT4_MB_USE_ROOT_BLOCKS)) { ++ (flags & EXT4_MB_USE_ROOT_BLOCKS) || ++ capable(CAP_SYS_RESOURCE)) { + + if (free_clusters >= (nclusters + dirty_clusters + + resv_clusters)) +-- +2.39.5 + diff --git a/queue-6.6/f2fs-defer-readonly-check-vs-norecovery.patch b/queue-6.6/f2fs-defer-readonly-check-vs-norecovery.patch new file mode 100644 index 0000000000..c0b8cd64f4 --- /dev/null +++ b/queue-6.6/f2fs-defer-readonly-check-vs-norecovery.patch @@ -0,0 +1,56 @@ +From e2bb2972e0846d3d0093cc3cf91c12ae24aadc7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 11:12:17 -0600 +Subject: f2fs: defer readonly check vs norecovery + +From: Eric Sandeen + +[ Upstream commit 9cca49875997a1a7e92800a828a62bacb0f577b9 ] + +Defer the readonly-vs-norecovery check until after option parsing is done +so that option parsing does not require an active superblock for the test. +Add a helpful message, while we're at it. + +(I think could be moved back into parsing after we switch to the new mount +API if desired, as the fs context will have RO state available.) + +Signed-off-by: Eric Sandeen +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/super.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index 4cc87921aac3e..10e50bede8080 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -707,10 +707,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) + set_opt(sbi, DISABLE_ROLL_FORWARD); + break; + case Opt_norecovery: +- /* this option mounts f2fs with ro */ ++ /* requires ro mount, checked in f2fs_default_check */ + set_opt(sbi, NORECOVERY); +- if (!f2fs_readonly(sb)) +- return -EINVAL; + break; + case Opt_discard: + if (!f2fs_hw_support_discard(sbi)) { +@@ -1390,6 +1388,12 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) + f2fs_err(sbi, "Allow to mount readonly mode only"); + return -EROFS; + } ++ ++ if (test_opt(sbi, NORECOVERY) && !f2fs_readonly(sbi->sb)) { ++ f2fs_err(sbi, "norecovery requires readonly mount"); ++ return -EINVAL; ++ } ++ + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.6/f2fs-introduce-f2fs_base_attr-for-global-sysfs-entri.patch b/queue-6.6/f2fs-introduce-f2fs_base_attr-for-global-sysfs-entri.patch new file mode 100644 index 0000000000..3c153f575e --- /dev/null +++ b/queue-6.6/f2fs-introduce-f2fs_base_attr-for-global-sysfs-entri.patch @@ -0,0 +1,155 @@ +From 11176f0457966c07340e557cd9f77327d4ec9516 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2025 05:06:07 +0000 +Subject: f2fs: introduce f2fs_base_attr for global sysfs entries + +From: Jaegeuk Kim + +[ Upstream commit 21925ede449e038ed6f9efdfe0e79f15bddc34bc ] + +In /sys/fs/f2fs/features, there's no f2fs_sb_info, so let's avoid to get +the pointer. + +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/sysfs.c | 74 ++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 52 insertions(+), 22 deletions(-) + +diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c +index 180feefc4a9ce..c4b0661888a15 100644 +--- a/fs/f2fs/sysfs.c ++++ b/fs/f2fs/sysfs.c +@@ -61,6 +61,12 @@ struct f2fs_attr { + int id; + }; + ++struct f2fs_base_attr { ++ struct attribute attr; ++ ssize_t (*show)(struct f2fs_base_attr *a, char *buf); ++ ssize_t (*store)(struct f2fs_base_attr *a, const char *buf, size_t len); ++}; ++ + static ssize_t f2fs_sbi_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf); + +@@ -791,6 +797,25 @@ static void f2fs_sb_release(struct kobject *kobj) + complete(&sbi->s_kobj_unregister); + } + ++static ssize_t f2fs_base_attr_show(struct kobject *kobj, ++ struct attribute *attr, char *buf) ++{ ++ struct f2fs_base_attr *a = container_of(attr, ++ struct f2fs_base_attr, attr); ++ ++ return a->show ? a->show(a, buf) : 0; ++} ++ ++static ssize_t f2fs_base_attr_store(struct kobject *kobj, ++ struct attribute *attr, ++ const char *buf, size_t len) ++{ ++ struct f2fs_base_attr *a = container_of(attr, ++ struct f2fs_base_attr, attr); ++ ++ return a->store ? a->store(a, buf, len) : 0; ++} ++ + /* + * Note that there are three feature list entries: + * 1) /sys/fs/f2fs/features +@@ -809,14 +834,13 @@ static void f2fs_sb_release(struct kobject *kobj) + * please add new on-disk feature in this list only. + * - ref. F2FS_SB_FEATURE_RO_ATTR() + */ +-static ssize_t f2fs_feature_show(struct f2fs_attr *a, +- struct f2fs_sb_info *sbi, char *buf) ++static ssize_t f2fs_feature_show(struct f2fs_base_attr *a, char *buf) + { + return sysfs_emit(buf, "supported\n"); + } + + #define F2FS_FEATURE_RO_ATTR(_name) \ +-static struct f2fs_attr f2fs_attr_##_name = { \ ++static struct f2fs_base_attr f2fs_base_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_feature_show, \ + } +@@ -1166,37 +1190,38 @@ static struct attribute *f2fs_attrs[] = { + }; + ATTRIBUTE_GROUPS(f2fs); + ++#define BASE_ATTR_LIST(name) (&f2fs_base_attr_##name.attr) + static struct attribute *f2fs_feat_attrs[] = { + #ifdef CONFIG_FS_ENCRYPTION +- ATTR_LIST(encryption), +- ATTR_LIST(test_dummy_encryption_v2), ++ BASE_ATTR_LIST(encryption), ++ BASE_ATTR_LIST(test_dummy_encryption_v2), + #if IS_ENABLED(CONFIG_UNICODE) +- ATTR_LIST(encrypted_casefold), ++ BASE_ATTR_LIST(encrypted_casefold), + #endif + #endif /* CONFIG_FS_ENCRYPTION */ + #ifdef CONFIG_BLK_DEV_ZONED +- ATTR_LIST(block_zoned), ++ BASE_ATTR_LIST(block_zoned), + #endif +- ATTR_LIST(atomic_write), +- ATTR_LIST(extra_attr), +- ATTR_LIST(project_quota), +- ATTR_LIST(inode_checksum), +- ATTR_LIST(flexible_inline_xattr), +- ATTR_LIST(quota_ino), +- ATTR_LIST(inode_crtime), +- ATTR_LIST(lost_found), ++ BASE_ATTR_LIST(atomic_write), ++ BASE_ATTR_LIST(extra_attr), ++ BASE_ATTR_LIST(project_quota), ++ BASE_ATTR_LIST(inode_checksum), ++ BASE_ATTR_LIST(flexible_inline_xattr), ++ BASE_ATTR_LIST(quota_ino), ++ BASE_ATTR_LIST(inode_crtime), ++ BASE_ATTR_LIST(lost_found), + #ifdef CONFIG_FS_VERITY +- ATTR_LIST(verity), ++ BASE_ATTR_LIST(verity), + #endif +- ATTR_LIST(sb_checksum), ++ BASE_ATTR_LIST(sb_checksum), + #if IS_ENABLED(CONFIG_UNICODE) +- ATTR_LIST(casefold), ++ BASE_ATTR_LIST(casefold), + #endif +- ATTR_LIST(readonly), ++ BASE_ATTR_LIST(readonly), + #ifdef CONFIG_F2FS_FS_COMPRESSION +- ATTR_LIST(compression), ++ BASE_ATTR_LIST(compression), + #endif +- ATTR_LIST(pin_file), ++ BASE_ATTR_LIST(pin_file), + NULL, + }; + ATTRIBUTE_GROUPS(f2fs_feat); +@@ -1263,9 +1288,14 @@ static struct kset f2fs_kset = { + .kobj = {.ktype = &f2fs_ktype}, + }; + ++static const struct sysfs_ops f2fs_feat_attr_ops = { ++ .show = f2fs_base_attr_show, ++ .store = f2fs_base_attr_store, ++}; ++ + static const struct kobj_type f2fs_feat_ktype = { + .default_groups = f2fs_feat_groups, +- .sysfs_ops = &f2fs_attr_ops, ++ .sysfs_ops = &f2fs_feat_attr_ops, + }; + + static struct kobject f2fs_feat = { +-- +2.39.5 + diff --git a/queue-6.6/fbcon-use-correct-erase-colour-for-clearing-in-fbcon.patch b/queue-6.6/fbcon-use-correct-erase-colour-for-clearing-in-fbcon.patch new file mode 100644 index 0000000000..e406869aa3 --- /dev/null +++ b/queue-6.6/fbcon-use-correct-erase-colour-for-clearing-in-fbcon.patch @@ -0,0 +1,242 @@ +From 327e75b0284b00836e4e321bccce159022074ea1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Feb 2025 21:33:46 +0100 +Subject: fbcon: Use correct erase colour for clearing in fbcon + +From: Zsolt Kajtar + +[ Upstream commit 892c788d73fe4a94337ed092cb998c49fa8ecaf4 ] + +The erase colour calculation for fbcon clearing should use get_color instead +of attr_col_ec, like everything else. The latter is similar but is not correct. +For example it's missing the depth dependent remapping and doesn't care about +blanking. + +The problem can be reproduced by setting up the background colour to grey +(vt.color=0x70) and having an fbcon console set to 2bpp (4 shades of gray). +Now the background attribute should be 1 (dark gray) on the console. + +If the screen is scrolled when pressing enter in a shell prompt at the bottom +line then the new line is cleared using colour 7 instead of 1. That's not +something fillrect likes (at 2bbp it expect 0-3) so the result is interesting. + +This patch switches to get_color with vc_video_erase_char to determine the +erase colour from attr_col_ec. That makes the latter function redundant as +no other users were left. + +Use correct erase colour for clearing in fbcon + +Signed-off-by: Zsolt Kajtar +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/core/bitblit.c | 5 ++-- + drivers/video/fbdev/core/fbcon.c | 10 +++++--- + drivers/video/fbdev/core/fbcon.h | 38 +--------------------------- + drivers/video/fbdev/core/fbcon_ccw.c | 5 ++-- + drivers/video/fbdev/core/fbcon_cw.c | 5 ++-- + drivers/video/fbdev/core/fbcon_ud.c | 5 ++-- + drivers/video/fbdev/core/tileblit.c | 8 +++--- + 7 files changed, 18 insertions(+), 58 deletions(-) + +diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c +index 8587c9da06700..42e681a78136a 100644 +--- a/drivers/video/fbdev/core/bitblit.c ++++ b/drivers/video/fbdev/core/bitblit.c +@@ -59,12 +59,11 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, + } + + static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width) ++ int sx, int height, int width, int fg, int bg) + { +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + struct fb_fillrect region; + +- region.color = attr_bgcol_ec(bgshift, vc, info); ++ region.color = bg; + region.dx = sx * vc->vc_font.width; + region.dy = sy * vc->vc_font.height; + region.width = width * vc->vc_font.width; +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 405d587450ef8..7a6f9a3cb3ba3 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -1240,7 +1240,7 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + { + struct fb_info *info = fbcon_info_from_console(vc->vc_num); + struct fbcon_ops *ops = info->fbcon_par; +- ++ int fg, bg; + struct fbcon_display *p = &fb_display[vc->vc_num]; + u_int y_break; + +@@ -1261,16 +1261,18 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + fbcon_clear_margins(vc, 0); + } + ++ fg = get_color(vc, info, vc->vc_video_erase_char, 1); ++ bg = get_color(vc, info, vc->vc_video_erase_char, 0); + /* Split blits that cross physical y_wrap boundary */ + + y_break = p->vrows - p->yscroll; + if (sy < y_break && sy + height - 1 >= y_break) { + u_int b = y_break - sy; +- ops->clear(vc, info, real_y(p, sy), sx, b, width); ++ ops->clear(vc, info, real_y(p, sy), sx, b, width, fg, bg); + ops->clear(vc, info, real_y(p, sy + b), sx, height - b, +- width); ++ width, fg, bg); + } else +- ops->clear(vc, info, real_y(p, sy), sx, height, width); ++ ops->clear(vc, info, real_y(p, sy), sx, height, width, fg, bg); + } + + static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, +diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h +index 0eaf54a211516..25691d4b027bf 100644 +--- a/drivers/video/fbdev/core/fbcon.h ++++ b/drivers/video/fbdev/core/fbcon.h +@@ -55,7 +55,7 @@ struct fbcon_ops { + void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, + int sx, int dy, int dx, int height, int width); + void (*clear)(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width); ++ int sx, int height, int width, int fb, int bg); + void (*putcs)(struct vc_data *vc, struct fb_info *info, + const unsigned short *s, int count, int yy, int xx, + int fg, int bg); +@@ -116,42 +116,6 @@ static inline int mono_col(const struct fb_info *info) + return (~(0xfff << max_len)) & 0xff; + } + +-static inline int attr_col_ec(int shift, struct vc_data *vc, +- struct fb_info *info, int is_fg) +-{ +- int is_mono01; +- int col; +- int fg; +- int bg; +- +- if (!vc) +- return 0; +- +- if (vc->vc_can_do_color) +- return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char) +- : attr_bgcol(shift,vc->vc_video_erase_char); +- +- if (!info) +- return 0; +- +- col = mono_col(info); +- is_mono01 = info->fix.visual == FB_VISUAL_MONO01; +- +- if (attr_reverse(vc->vc_video_erase_char)) { +- fg = is_mono01 ? col : 0; +- bg = is_mono01 ? 0 : col; +- } +- else { +- fg = is_mono01 ? 0 : col; +- bg = is_mono01 ? col : 0; +- } +- +- return is_fg ? fg : bg; +-} +- +-#define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0) +-#define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1) +- + /* + * Scroll Method + */ +diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c +index 2789ace796342..9f4d65478554a 100644 +--- a/drivers/video/fbdev/core/fbcon_ccw.c ++++ b/drivers/video/fbdev/core/fbcon_ccw.c +@@ -78,14 +78,13 @@ static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + } + + static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width) ++ int sx, int height, int width, int fg, int bg) + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vyres = GETVYRES(ops->p, info); + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = bg; + region.dx = sy * vc->vc_font.height; + region.dy = vyres - ((sx + width) * vc->vc_font.width); + region.height = width * vc->vc_font.width; +diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c +index 86a254c1b2b7b..b18e31886da10 100644 +--- a/drivers/video/fbdev/core/fbcon_cw.c ++++ b/drivers/video/fbdev/core/fbcon_cw.c +@@ -63,14 +63,13 @@ static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy, + } + + static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width) ++ int sx, int height, int width, int fg, int bg) + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vxres = GETVXRES(ops->p, info); + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = bg; + region.dx = vxres - ((sy + height) * vc->vc_font.height); + region.dy = sx * vc->vc_font.width; + region.height = width * vc->vc_font.width; +diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c +index 23bc045769d08..b6b074cfd9dc0 100644 +--- a/drivers/video/fbdev/core/fbcon_ud.c ++++ b/drivers/video/fbdev/core/fbcon_ud.c +@@ -64,15 +64,14 @@ static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy, + } + + static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width) ++ int sx, int height, int width, int fg, int bg) + { + struct fbcon_ops *ops = info->fbcon_par; + struct fb_fillrect region; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; + u32 vyres = GETVYRES(ops->p, info); + u32 vxres = GETVXRES(ops->p, info); + +- region.color = attr_bgcol_ec(bgshift,vc,info); ++ region.color = bg; + region.dy = vyres - ((sy + height) * vc->vc_font.height); + region.dx = vxres - ((sx + width) * vc->vc_font.width); + region.width = width * vc->vc_font.width; +diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c +index 2768eff247ba4..674ca6a410ec8 100644 +--- a/drivers/video/fbdev/core/tileblit.c ++++ b/drivers/video/fbdev/core/tileblit.c +@@ -32,16 +32,14 @@ static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy, + } + + static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy, +- int sx, int height, int width) ++ int sx, int height, int width, int fg, int bg) + { + struct fb_tilerect rect; +- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; +- int fgshift = (vc->vc_hi_font_mask) ? 9 : 8; + + rect.index = vc->vc_video_erase_char & + ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); +- rect.fg = attr_fgcol_ec(fgshift, vc, info); +- rect.bg = attr_bgcol_ec(bgshift, vc, info); ++ rect.fg = fg; ++ rect.bg = bg; + rect.sx = sx; + rect.sy = sy; + rect.width = width; +-- +2.39.5 + diff --git a/queue-6.6/fbdev-core-tileblit-implement-missing-margin-clearin.patch b/queue-6.6/fbdev-core-tileblit-implement-missing-margin-clearin.patch new file mode 100644 index 0000000000..3dd6517565 --- /dev/null +++ b/queue-6.6/fbdev-core-tileblit-implement-missing-margin-clearin.patch @@ -0,0 +1,95 @@ +From 93f83cb68ee1b0b46a00aacf435826f34ff4f829 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Feb 2025 09:18:09 +0100 +Subject: fbdev: core: tileblit: Implement missing margin clearing for tileblit + +From: Zsolt Kajtar + +[ Upstream commit 76d3ca89981354e1f85a3e0ad9ac4217d351cc72 ] + +I was wondering why there's garbage at the bottom of the screen when +tile blitting is used with an odd mode like 1080, 600 or 200. Sure there's +only space for half a tile but the same area is clean when the buffer +is bitmap. + +Then later I found that it's supposed to be cleaned but that's not +implemented. So I took what's in bitblit and adapted it for tileblit. + +This implementation was tested for both the horizontal and vertical case, +and now does the same as what's done for bitmap buffers. + +If anyone is interested to reproduce the problem then I could bet that'd +be on a S3 or Ark. Just set up a mode with an odd line count and make +sure that the virtual size covers the complete tile at the bottom. E.g. +for 600 lines that's 608 virtual lines for a 16 tall tile. Then the +bottom area should be cleaned. + +For the right side it's more difficult as there the drivers won't let an +odd size happen, unless the code is modified. But once it reports back a +few pixel columns short then fbcon won't use the last column. With the +patch that column is now clean. + +Btw. the virtual size should be rounded up by the driver for both axes +(not only the horizontal) so that it's dividable by the tile size. +That's a driver bug but correcting it is not in scope for this patch. + +Implement missing margin clearing for tileblit + +Signed-off-by: Zsolt Kajtar +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/core/tileblit.c | 37 ++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c +index 674ca6a410ec8..b3aa0c6620c7d 100644 +--- a/drivers/video/fbdev/core/tileblit.c ++++ b/drivers/video/fbdev/core/tileblit.c +@@ -74,7 +74,42 @@ static void tile_putcs(struct vc_data *vc, struct fb_info *info, + static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, + int color, int bottom_only) + { +- return; ++ unsigned int cw = vc->vc_font.width; ++ unsigned int ch = vc->vc_font.height; ++ unsigned int rw = info->var.xres - (vc->vc_cols*cw); ++ unsigned int bh = info->var.yres - (vc->vc_rows*ch); ++ unsigned int rs = info->var.xres - rw; ++ unsigned int bs = info->var.yres - bh; ++ unsigned int vwt = info->var.xres_virtual / cw; ++ unsigned int vht = info->var.yres_virtual / ch; ++ struct fb_tilerect rect; ++ ++ rect.index = vc->vc_video_erase_char & ++ ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); ++ rect.fg = color; ++ rect.bg = color; ++ ++ if ((int) rw > 0 && !bottom_only) { ++ rect.sx = (info->var.xoffset + rs + cw - 1) / cw; ++ rect.sy = 0; ++ rect.width = (rw + cw - 1) / cw; ++ rect.height = vht; ++ if (rect.width + rect.sx > vwt) ++ rect.width = vwt - rect.sx; ++ if (rect.sx < vwt) ++ info->tileops->fb_tilefill(info, &rect); ++ } ++ ++ if ((int) bh > 0) { ++ rect.sx = info->var.xoffset / cw; ++ rect.sy = (info->var.yoffset + bs) / ch; ++ rect.width = rs / cw; ++ rect.height = (bh + ch - 1) / ch; ++ if (rect.height + rect.sy > vht) ++ rect.height = vht - rect.sy; ++ if (rect.sy < vht) ++ info->tileops->fb_tilefill(info, &rect); ++ } + } + + static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode, +-- +2.39.5 + diff --git a/queue-6.6/fbdev-fsl-diu-fb-add-missing-device_remove_file.patch b/queue-6.6/fbdev-fsl-diu-fb-add-missing-device_remove_file.patch new file mode 100644 index 0000000000..3a45f81154 --- /dev/null +++ b/queue-6.6/fbdev-fsl-diu-fb-add-missing-device_remove_file.patch @@ -0,0 +1,33 @@ +From d0ddc939169b029552d8394548539d58fc51e0fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Mar 2025 09:54:31 +0800 +Subject: fbdev: fsl-diu-fb: add missing device_remove_file() + +From: Shixiong Ou + +[ Upstream commit 86d16cd12efa547ed43d16ba7a782c1251c80ea8 ] + +Call device_remove_file() when driver remove. + +Signed-off-by: Shixiong Ou +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/fsl-diu-fb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/video/fbdev/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c +index 0bced82fa4940..8cf1268a4e554 100644 +--- a/drivers/video/fbdev/fsl-diu-fb.c ++++ b/drivers/video/fbdev/fsl-diu-fb.c +@@ -1827,6 +1827,7 @@ static void fsl_diu_remove(struct platform_device *pdev) + int i; + + data = dev_get_drvdata(&pdev->dev); ++ device_remove_file(&pdev->dev, &data->dev_attr); + disable_lcdc(&data->fsl_diu_info[0]); + + free_irq(data->irq, data->diu_reg); +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_ffa-reject-higher-major-version-as-inco.patch b/queue-6.6/firmware-arm_ffa-reject-higher-major-version-as-inco.patch new file mode 100644 index 0000000000..2db7f89815 --- /dev/null +++ b/queue-6.6/firmware-arm_ffa-reject-higher-major-version-as-inco.patch @@ -0,0 +1,50 @@ +From b93e0111ed83a149275a5fd422d9555f6efd2f86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 15:38:53 +0000 +Subject: firmware: arm_ffa: Reject higher major version as incompatible + +From: Sudeep Holla + +[ Upstream commit efff6a7f16b34fd902f342b58bd8bafc2d6f2fd1 ] + +When the firmware compatibility was handled previously in the commit +8e3f9da608f1 ("firmware: arm_ffa: Handle compatibility with different firmware versions"), +we only addressed firmware versions that have higher minor versions +compared to the driver version which is should be considered compatible +unless the firmware returns NOT_SUPPORTED. + +However, if the firmware reports higher major version than the driver +supported, we need to reject it. If the firmware can work in a compatible +mode with the driver requested version, it must return the same major +version as requested. + +Tested-by: Viresh Kumar +Message-Id: <20250217-ffa_updates-v3-12-bd1d9de615e7@arm.com> +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_ffa/driver.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c +index 7c2db3f017651..488f8345dd1b6 100644 +--- a/drivers/firmware/arm_ffa/driver.c ++++ b/drivers/firmware/arm_ffa/driver.c +@@ -121,6 +121,14 @@ static int ffa_version_check(u32 *version) + return -EOPNOTSUPP; + } + ++ if (FFA_MAJOR_VERSION(ver.a0) > FFA_MAJOR_VERSION(FFA_DRIVER_VERSION)) { ++ pr_err("Incompatible v%d.%d! Latest supported v%d.%d\n", ++ FFA_MAJOR_VERSION(ver.a0), FFA_MINOR_VERSION(ver.a0), ++ FFA_MAJOR_VERSION(FFA_DRIVER_VERSION), ++ FFA_MINOR_VERSION(FFA_DRIVER_VERSION)); ++ return -EINVAL; ++ } ++ + if (ver.a0 < FFA_MIN_VERSION) { + pr_err("Incompatible v%d.%d! Earliest supported v%d.%d\n", + FFA_MAJOR_VERSION(ver.a0), FFA_MINOR_VERSION(ver.a0), +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_ffa-set-dma_mask-for-ffa-devices.patch b/queue-6.6/firmware-arm_ffa-set-dma_mask-for-ffa-devices.patch new file mode 100644 index 0000000000..d1abc4372f --- /dev/null +++ b/queue-6.6/firmware-arm_ffa-set-dma_mask-for-ffa-devices.patch @@ -0,0 +1,37 @@ +From 8e574b52aa1f1e681f043f7148be51607a0eb3f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2025 15:35:52 +0530 +Subject: firmware: arm_ffa: Set dma_mask for ffa devices + +From: Viresh Kumar + +[ Upstream commit cc0aac7ca17e0ea3ca84b552fc79f3e86fd07f53 ] + +Set dma_mask for FFA devices, otherwise DMA allocation using the device pointer +lead to following warning: + +WARNING: CPU: 1 PID: 1 at kernel/dma/mapping.c:597 dma_alloc_attrs+0xe0/0x124 + +Signed-off-by: Viresh Kumar +Message-Id: +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_ffa/bus.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c +index 7865438b36960..d885e1381072a 100644 +--- a/drivers/firmware/arm_ffa/bus.c ++++ b/drivers/firmware/arm_ffa/bus.c +@@ -191,6 +191,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, + dev = &ffa_dev->dev; + dev->bus = &ffa_bus_type; + dev->release = ffa_release_device; ++ dev->dma_mask = &dev->coherent_dma_mask; + dev_set_name(&ffa_dev->dev, "arm-ffa-%d", id); + + ffa_dev->id = id; +-- +2.39.5 + diff --git a/queue-6.6/firmware-arm_scmi-relax-duplicate-name-constraint-ac.patch b/queue-6.6/firmware-arm_scmi-relax-duplicate-name-constraint-ac.patch new file mode 100644 index 0000000000..d75599ba0f --- /dev/null +++ b/queue-6.6/firmware-arm_scmi-relax-duplicate-name-constraint-ac.patch @@ -0,0 +1,76 @@ +From 76719a0f18a0f147923e7640183654df1827e4fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Jan 2025 14:18:20 +0000 +Subject: firmware: arm_scmi: Relax duplicate name constraint across protocol + ids + +From: Sudeep Holla + +[ Upstream commit 21ee965267bcbdd733be0f35344fa0f0226d7861 ] + +Currently in scmi_protocol_device_request(), no duplicate scmi device +name is allowed across any protocol. However scmi_dev_match_id() first +matches the protocol id and then the name. So, there is no strict +requirement to keep this scmi device name unique across all the protocols. + +Relax the constraint on the duplicate name across the protocols and +inhibit only within the same protocol id. + +Message-Id: <20250131141822.514342-1-sudeep.holla@arm.com> +Reviewed-by: Dhruva Gole +Reviewed-by: Peng Fan +Signed-off-by: Sudeep Holla +Signed-off-by: Sasha Levin +--- + drivers/firmware/arm_scmi/bus.c | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c +index 51eeaf14367da..e1b949aedf9e0 100644 +--- a/drivers/firmware/arm_scmi/bus.c ++++ b/drivers/firmware/arm_scmi/bus.c +@@ -42,7 +42,7 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0); + * This helper let an SCMI driver request specific devices identified by the + * @id_table to be created for each active SCMI instance. + * +- * The requested device name MUST NOT be already existent for any protocol; ++ * The requested device name MUST NOT be already existent for this protocol; + * at first the freshly requested @id_table is annotated in the IDR table + * @scmi_requested_devices and then the requested device is advertised to any + * registered party via the @scmi_requested_devices_nh notification chain. +@@ -52,7 +52,6 @@ static atomic_t scmi_syspower_registered = ATOMIC_INIT(0); + static int scmi_protocol_device_request(const struct scmi_device_id *id_table) + { + int ret = 0; +- unsigned int id = 0; + struct list_head *head, *phead = NULL; + struct scmi_requested_dev *rdev; + +@@ -67,19 +66,13 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) + } + + /* +- * Search for the matching protocol rdev list and then search +- * of any existent equally named device...fails if any duplicate found. ++ * Find the matching protocol rdev list and then search of any ++ * existent equally named device...fails if any duplicate found. + */ + mutex_lock(&scmi_requested_devices_mtx); +- idr_for_each_entry(&scmi_requested_devices, head, id) { +- if (!phead) { +- /* A list found registered in the IDR is never empty */ +- rdev = list_first_entry(head, struct scmi_requested_dev, +- node); +- if (rdev->id_table->protocol_id == +- id_table->protocol_id) +- phead = head; +- } ++ phead = idr_find(&scmi_requested_devices, id_table->protocol_id); ++ if (phead) { ++ head = phead; + list_for_each_entry(rdev, head, node) { + if (!strcmp(rdev->id_table->name, id_table->name)) { + pr_err("Ignoring duplicate request [%d] %s\n", +-- +2.39.5 + diff --git a/queue-6.6/fpga-altera-cvp-increase-credit-timeout.patch b/queue-6.6/fpga-altera-cvp-increase-credit-timeout.patch new file mode 100644 index 0000000000..dbc4d9fb57 --- /dev/null +++ b/queue-6.6/fpga-altera-cvp-increase-credit-timeout.patch @@ -0,0 +1,43 @@ +From 3639e9407a49384de997b9072023d12f41a92a0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 06:12:49 +0800 +Subject: fpga: altera-cvp: Increase credit timeout + +From: Kuhanh Murugasen Krishnan + +[ Upstream commit 0f05886a40fdc55016ba4d9ae0a9c41f8312f15b ] + +Increase the timeout for SDM (Secure device manager) data credits from +20ms to 40ms. Internal stress tests running at 500 loops failed with the +current timeout of 20ms. At the start of a FPGA configuration, the CVP +host driver reads the transmit credits from SDM. It then sends bitstream +FPGA data to SDM based on the total credits. Each credit allows the +CVP host driver to send 4kBytes of data. There are situations whereby, +the SDM did not respond in time during testing. + +Signed-off-by: Ang Tien Sung +Signed-off-by: Kuhanh Murugasen Krishnan +Acked-by: Xu Yilun +Link: https://lore.kernel.org/r/20250212221249.2715929-1-tien.sung.ang@intel.com +Signed-off-by: Xu Yilun +Signed-off-by: Sasha Levin +--- + drivers/fpga/altera-cvp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c +index 4ffb9da537d82..5295ff90482bc 100644 +--- a/drivers/fpga/altera-cvp.c ++++ b/drivers/fpga/altera-cvp.c +@@ -52,7 +52,7 @@ + /* V2 Defines */ + #define VSE_CVP_TX_CREDITS 0x49 /* 8bit */ + +-#define V2_CREDIT_TIMEOUT_US 20000 ++#define V2_CREDIT_TIMEOUT_US 40000 + #define V2_CHECK_CREDIT_US 10 + #define V2_POLL_TIMEOUT_US 1000000 + #define V2_USER_TIMEOUT_US 500000 +-- +2.39.5 + diff --git a/queue-6.6/fs-mpage-avoid-negative-shift-for-large-blocksize.patch b/queue-6.6/fs-mpage-avoid-negative-shift-for-large-blocksize.patch new file mode 100644 index 0000000000..aa2e660816 --- /dev/null +++ b/queue-6.6/fs-mpage-avoid-negative-shift-for-large-blocksize.patch @@ -0,0 +1,49 @@ +From 966dd16171be03ee31a7d390a6802bec42c2e823 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Feb 2025 14:38:18 -0800 +Subject: fs/mpage: avoid negative shift for large blocksize + +From: Hannes Reinecke + +[ Upstream commit 86c60efd7c0ede43bd677f2eee1d84200528df1e ] + +For large blocksizes the number of block bits is larger than PAGE_SHIFT, +so calculate the sector number from the byte offset instead. This is +required to enable large folios with buffer-heads. + +Reviewed-by: "Matthew Wilcox (Oracle)" +Signed-off-by: Luis Chamberlain +Signed-off-by: Hannes Reinecke +Link: https://lore.kernel.org/r/20250221223823.1680616-4-mcgrof@kernel.org +Reviewed-by: Hannes Reinecke +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/mpage.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/mpage.c b/fs/mpage.c +index 242e213ee0644..20d95847666b6 100644 +--- a/fs/mpage.c ++++ b/fs/mpage.c +@@ -189,7 +189,7 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) + if (folio_buffers(folio)) + goto confused; + +- block_in_file = (sector_t)folio->index << (PAGE_SHIFT - blkbits); ++ block_in_file = folio_pos(folio) >> blkbits; + last_block = block_in_file + args->nr_pages * blocks_per_page; + last_block_in_file = (i_size_read(inode) + blocksize - 1) >> blkbits; + if (last_block > last_block_in_file) +@@ -543,7 +543,7 @@ static int __mpage_writepage(struct folio *folio, struct writeback_control *wbc, + * The page has no buffers: map it to disk + */ + BUG_ON(!folio_test_uptodate(folio)); +- block_in_file = (sector_t)folio->index << (PAGE_SHIFT - blkbits); ++ block_in_file = folio_pos(folio) >> blkbits; + /* + * Whole page beyond EOF? Skip allocating blocks to avoid leaking + * space. +-- +2.39.5 + diff --git a/queue-6.6/fuse-return-eperm-rather-than-enosys-from-link.patch b/queue-6.6/fuse-return-eperm-rather-than-enosys-from-link.patch new file mode 100644 index 0000000000..b09b6884e5 --- /dev/null +++ b/queue-6.6/fuse-return-eperm-rather-than-enosys-from-link.patch @@ -0,0 +1,36 @@ +From 919e39eac439d9f3269f359f2af2c9418df2726a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 09:17:53 +0800 +Subject: fuse: Return EPERM rather than ENOSYS from link() + +From: Matt Johnston + +[ Upstream commit 8344213571b2ac8caf013cfd3b37bc3467c3a893 ] + +link() is documented to return EPERM when a filesystem doesn't support +the operation, return that instead. + +Link: https://github.com/libfuse/libfuse/issues/925 +Signed-off-by: Matt Johnston +Signed-off-by: Miklos Szeredi +Signed-off-by: Sasha Levin +--- + fs/fuse/dir.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index e4d6cc0d2332a..82951a535d2d4 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1121,6 +1121,8 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, + else if (err == -EINTR) + fuse_invalidate_attr(inode); + ++ if (err == -ENOSYS) ++ err = -EPERM; + return err; + } + +-- +2.39.5 + diff --git a/queue-6.6/genirq-msi-store-the-iommu-iova-directly-in-msi_desc.patch b/queue-6.6/genirq-msi-store-the-iommu-iova-directly-in-msi_desc.patch new file mode 100644 index 0000000000..daba22d52b --- /dev/null +++ b/queue-6.6/genirq-msi-store-the-iommu-iova-directly-in-msi_desc.patch @@ -0,0 +1,175 @@ +From 9f14ccee8919116884167ba64b01c68867516c17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Feb 2025 17:31:36 -0800 +Subject: genirq/msi: Store the IOMMU IOVA directly in msi_desc instead of + iommu_cookie + +From: Jason Gunthorpe + +[ Upstream commit 1f7df3a691740a7736bbc99dc4ed536120eb4746 ] + +The IOMMU translation for MSI message addresses has been a 2-step process, +separated in time: + + 1) iommu_dma_prepare_msi(): A cookie pointer containing the IOVA address + is stored in the MSI descriptor when an MSI interrupt is allocated. + + 2) iommu_dma_compose_msi_msg(): this cookie pointer is used to compute a + translated message address. + +This has an inherent lifetime problem for the pointer stored in the cookie +that must remain valid between the two steps. However, there is no locking +at the irq layer that helps protect the lifetime. Today, this works under +the assumption that the iommu domain is not changed while MSI interrupts +being programmed. This is true for normal DMA API users within the kernel, +as the iommu domain is attached before the driver is probed and cannot be +changed while a driver is attached. + +Classic VFIO type1 also prevented changing the iommu domain while VFIO was +running as it does not support changing the "container" after starting up. + +However, iommufd has improved this so that the iommu domain can be changed +during VFIO operation. This potentially allows userspace to directly race +VFIO_DEVICE_ATTACH_IOMMUFD_PT (which calls iommu_attach_group()) and +VFIO_DEVICE_SET_IRQS (which calls into iommu_dma_compose_msi_msg()). + +This potentially causes both the cookie pointer and the unlocked call to +iommu_get_domain_for_dev() on the MSI translation path to become UAFs. + +Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA +address is already known during iommu_dma_prepare_msi() and cannot change. +Thus, it can simply be stored as an integer in the MSI descriptor. + +The other UAF related to iommu_get_domain_for_dev() will be addressed in +patch "iommu: Make iommu_dma_prepare_msi() into a generic operation" by +using the IOMMU group mutex. + +Link: https://patch.msgid.link/r/a4f2cd76b9dc1833ee6c1cf325cba57def22231c.1740014950.git.nicolinc@nvidia.com +Signed-off-by: Nicolin Chen +Reviewed-by: Thomas Gleixner +Signed-off-by: Jason Gunthorpe +Signed-off-by: Sasha Levin +--- + drivers/iommu/dma-iommu.c | 28 +++++++++++++--------------- + include/linux/msi.h | 33 ++++++++++++--------------------- + 2 files changed, 25 insertions(+), 36 deletions(-) + +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index 2da969fc89900..3f7fcf1801a97 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -1716,7 +1716,7 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) + static DEFINE_MUTEX(msi_prepare_lock); /* see below */ + + if (!domain || !domain->iova_cookie) { +- desc->iommu_cookie = NULL; ++ msi_desc_set_iommu_msi_iova(desc, 0, 0); + return 0; + } + +@@ -1728,11 +1728,12 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) + mutex_lock(&msi_prepare_lock); + msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain); + mutex_unlock(&msi_prepare_lock); +- +- msi_desc_set_iommu_cookie(desc, msi_page); +- + if (!msi_page) + return -ENOMEM; ++ ++ msi_desc_set_iommu_msi_iova( ++ desc, msi_page->iova, ++ ilog2(cookie_msi_granule(domain->iova_cookie))); + return 0; + } + +@@ -1743,18 +1744,15 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) + */ + void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg) + { +- struct device *dev = msi_desc_to_dev(desc); +- const struct iommu_domain *domain = iommu_get_domain_for_dev(dev); +- const struct iommu_dma_msi_page *msi_page; ++#ifdef CONFIG_IRQ_MSI_IOMMU ++ if (desc->iommu_msi_shift) { ++ u64 msi_iova = desc->iommu_msi_iova << desc->iommu_msi_shift; + +- msi_page = msi_desc_get_iommu_cookie(desc); +- +- if (!domain || !domain->iova_cookie || WARN_ON(!msi_page)) +- return; +- +- msg->address_hi = upper_32_bits(msi_page->iova); +- msg->address_lo &= cookie_msi_granule(domain->iova_cookie) - 1; +- msg->address_lo += lower_32_bits(msi_page->iova); ++ msg->address_hi = upper_32_bits(msi_iova); ++ msg->address_lo = lower_32_bits(msi_iova) | ++ (msg->address_lo & ((1 << desc->iommu_msi_shift) - 1)); ++ } ++#endif + } + + static int iommu_dma_init(void) +diff --git a/include/linux/msi.h b/include/linux/msi.h +index ddace8c34dcf9..2cf15cf5d060a 100644 +--- a/include/linux/msi.h ++++ b/include/linux/msi.h +@@ -171,6 +171,10 @@ struct msi_desc_data { + * @dev: Pointer to the device which uses this descriptor + * @msg: The last set MSI message cached for reuse + * @affinity: Optional pointer to a cpu affinity mask for this descriptor ++ * @iommu_msi_iova: Optional shifted IOVA from the IOMMU to override the msi_addr. ++ * Only used if iommu_msi_shift != 0 ++ * @iommu_msi_shift: Indicates how many bits of the original address should be ++ * preserved when using iommu_msi_iova. + * @sysfs_attr: Pointer to sysfs device attribute + * + * @write_msi_msg: Callback that may be called when the MSI message +@@ -189,7 +193,8 @@ struct msi_desc { + struct msi_msg msg; + struct irq_affinity_desc *affinity; + #ifdef CONFIG_IRQ_MSI_IOMMU +- const void *iommu_cookie; ++ u64 iommu_msi_iova : 58; ++ u64 iommu_msi_shift : 6; + #endif + #ifdef CONFIG_SYSFS + struct device_attribute *sysfs_attrs; +@@ -306,28 +311,14 @@ struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid, + + #define msi_desc_to_dev(desc) ((desc)->dev) + +-#ifdef CONFIG_IRQ_MSI_IOMMU +-static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) +-{ +- return desc->iommu_cookie; +-} +- +-static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc, +- const void *iommu_cookie) +-{ +- desc->iommu_cookie = iommu_cookie; +-} +-#else +-static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) ++static inline void msi_desc_set_iommu_msi_iova(struct msi_desc *desc, u64 msi_iova, ++ unsigned int msi_shift) + { +- return NULL; +-} +- +-static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc, +- const void *iommu_cookie) +-{ +-} ++#ifdef CONFIG_IRQ_MSI_IOMMU ++ desc->iommu_msi_iova = msi_iova >> msi_shift; ++ desc->iommu_msi_shift = msi_shift; + #endif ++} + + int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid, + struct msi_desc *init_desc); +-- +2.39.5 + diff --git a/queue-6.6/gfs2-check-for-empty-queue-in-run_queue.patch b/queue-6.6/gfs2-check-for-empty-queue-in-run_queue.patch new file mode 100644 index 0000000000..cf3357f14a --- /dev/null +++ b/queue-6.6/gfs2-check-for-empty-queue-in-run_queue.patch @@ -0,0 +1,64 @@ +From 7c83d222bcdfbb37b1de207593d333411166aced Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 14:58:39 +0100 +Subject: gfs2: Check for empty queue in run_queue + +From: Andreas Gruenbacher + +[ Upstream commit d838605fea6eabae3746a276fd448f6719eb3926 ] + +In run_queue(), check if the queue of pending requests is empty instead +of blindly assuming that it won't be. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glock.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index 2c0908a302102..687670075d225 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -853,11 +853,12 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock) + __releases(&gl->gl_lockref.lock) + __acquires(&gl->gl_lockref.lock) + { +- struct gfs2_holder *gh = NULL; ++ struct gfs2_holder *gh; + + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + return; + ++ /* While a demote is in progress, the GLF_LOCK flag must be set. */ + GLOCK_BUG_ON(gl, test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags)); + + if (test_bit(GLF_DEMOTE, &gl->gl_flags) && +@@ -869,18 +870,22 @@ __acquires(&gl->gl_lockref.lock) + set_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags); + GLOCK_BUG_ON(gl, gl->gl_demote_state == LM_ST_EXCLUSIVE); + gl->gl_target = gl->gl_demote_state; ++ do_xmote(gl, NULL, gl->gl_target); ++ return; + } else { + if (test_bit(GLF_DEMOTE, &gl->gl_flags)) + gfs2_demote_wake(gl); + if (do_promote(gl)) + goto out_unlock; + gh = find_first_waiter(gl); ++ if (!gh) ++ goto out_unlock; + gl->gl_target = gh->gh_state; + if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) + do_error(gl, 0); /* Fail queued try locks */ ++ do_xmote(gl, gh, gl->gl_target); ++ return; + } +- do_xmote(gl, gh, gl->gl_target); +- return; + + out_sched: + clear_bit(GLF_LOCK, &gl->gl_flags); +-- +2.39.5 + diff --git a/queue-6.6/gpio-pca953x-fix-irq-storm-on-system-wake-up.patch b/queue-6.6/gpio-pca953x-fix-irq-storm-on-system-wake-up.patch new file mode 100644 index 0000000000..2c754edd62 --- /dev/null +++ b/queue-6.6/gpio-pca953x-fix-irq-storm-on-system-wake-up.patch @@ -0,0 +1,67 @@ +From 0fc9b700b2c94278694a6a40051ac9e2d3ff517d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 May 2025 11:54:41 +0200 +Subject: gpio: pca953x: fix IRQ storm on system wake up + +From: Emanuele Ghidoli + +[ Upstream commit 3e38f946062b4845961ab86b726651b4457b2af8 ] + +If an input changes state during wake-up and is used as an interrupt +source, the IRQ handler reads the volatile input register to clear the +interrupt mask and deassert the IRQ line. However, the IRQ handler is +triggered before access to the register is granted, causing the read +operation to fail. + +As a result, the IRQ handler enters a loop, repeatedly printing the +"failed reading register" message, until `pca953x_resume()` is eventually +called, which restores the driver context and enables access to +registers. + +Fix by disabling the IRQ line before entering suspend mode, and +re-enabling it after the driver context is restored in `pca953x_resume()`. + +An IRQ can be disabled with disable_irq() and still wake the system as +long as the IRQ has wake enabled, so the wake-up functionality is +preserved. + +Fixes: b76574300504 ("gpio: pca953x: Restore registers after suspend/resume cycle") +Cc: stable@vger.kernel.org +Signed-off-by: Emanuele Ghidoli +Signed-off-by: Francesco Dolcini +Reviewed-by: Andy Shevchenko +Tested-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20250512095441.31645-1-francesco@dolcini.it +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-pca953x.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index a39c8ebd410e4..faadbe66b23e7 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -1209,6 +1209,8 @@ static int pca953x_restore_context(struct pca953x_chip *chip) + + guard(mutex)(&chip->i2c_lock); + ++ if (chip->client->irq > 0) ++ enable_irq(chip->client->irq); + regcache_cache_only(chip->regmap, false); + regcache_mark_dirty(chip->regmap); + ret = pca953x_regcache_sync(chip); +@@ -1221,6 +1223,10 @@ static int pca953x_restore_context(struct pca953x_chip *chip) + static void pca953x_save_context(struct pca953x_chip *chip) + { + guard(mutex)(&chip->i2c_lock); ++ ++ /* Disable IRQ to prevent early triggering while regmap "cache only" is on */ ++ if (chip->client->irq > 0) ++ disable_irq(chip->client->irq); + regcache_cache_only(chip->regmap, true); + } + +-- +2.39.5 + diff --git a/queue-6.6/gpio-pca953x-simplify-code-with-cleanup-helpers.patch b/queue-6.6/gpio-pca953x-simplify-code-with-cleanup-helpers.patch new file mode 100644 index 0000000000..c8a4f90fee --- /dev/null +++ b/queue-6.6/gpio-pca953x-simplify-code-with-cleanup-helpers.patch @@ -0,0 +1,223 @@ +From b534373752e16edcfc5b959a2c7326a28a26b368 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 16:40:36 +0300 +Subject: gpio: pca953x: Simplify code with cleanup helpers + +From: Andy Shevchenko + +[ Upstream commit 8e471b784a720f6f34f9fb449ba0744359dcaccb ] + +Use macros defined in linux/cleanup.h to automate resource lifetime +control in gpio-pca953x. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 3e38f946062b ("gpio: pca953x: fix IRQ storm on system wake up") +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-pca953x.c | 77 ++++++++++++++----------------------- + 1 file changed, 29 insertions(+), 48 deletions(-) + +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index fddf0cf031007..a39c8ebd410e4 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -519,12 +520,10 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) + struct pca953x_chip *chip = gpiochip_get_data(gc); + u8 dirreg = chip->recalc_addr(chip, chip->regs->direction, off); + u8 bit = BIT(off % BANK_SZ); +- int ret; + +- mutex_lock(&chip->i2c_lock); +- ret = regmap_write_bits(chip->regmap, dirreg, bit, bit); +- mutex_unlock(&chip->i2c_lock); +- return ret; ++ guard(mutex)(&chip->i2c_lock); ++ ++ return regmap_write_bits(chip->regmap, dirreg, bit, bit); + } + + static int pca953x_gpio_direction_output(struct gpio_chip *gc, +@@ -536,17 +535,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, + u8 bit = BIT(off % BANK_SZ); + int ret; + +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); ++ + /* set output level */ + ret = regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0); + if (ret) +- goto exit; ++ return ret; + + /* then direction */ +- ret = regmap_write_bits(chip->regmap, dirreg, bit, 0); +-exit: +- mutex_unlock(&chip->i2c_lock); +- return ret; ++ return regmap_write_bits(chip->regmap, dirreg, bit, 0); + } + + static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) +@@ -557,9 +554,8 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) + u32 reg_val; + int ret; + +- mutex_lock(&chip->i2c_lock); +- ret = regmap_read(chip->regmap, inreg, ®_val); +- mutex_unlock(&chip->i2c_lock); ++ scoped_guard(mutex, &chip->i2c_lock) ++ ret = regmap_read(chip->regmap, inreg, ®_val); + if (ret < 0) + return ret; + +@@ -572,9 +568,9 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) + u8 outreg = chip->recalc_addr(chip, chip->regs->output, off); + u8 bit = BIT(off % BANK_SZ); + +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); ++ + regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0); +- mutex_unlock(&chip->i2c_lock); + } + + static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) +@@ -585,9 +581,8 @@ static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off) + u32 reg_val; + int ret; + +- mutex_lock(&chip->i2c_lock); +- ret = regmap_read(chip->regmap, dirreg, ®_val); +- mutex_unlock(&chip->i2c_lock); ++ scoped_guard(mutex, &chip->i2c_lock) ++ ret = regmap_read(chip->regmap, dirreg, ®_val); + if (ret < 0) + return ret; + +@@ -604,9 +599,8 @@ static int pca953x_gpio_get_multiple(struct gpio_chip *gc, + DECLARE_BITMAP(reg_val, MAX_LINE); + int ret; + +- mutex_lock(&chip->i2c_lock); +- ret = pca953x_read_regs(chip, chip->regs->input, reg_val); +- mutex_unlock(&chip->i2c_lock); ++ scoped_guard(mutex, &chip->i2c_lock) ++ ret = pca953x_read_regs(chip, chip->regs->input, reg_val); + if (ret) + return ret; + +@@ -621,16 +615,15 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, + DECLARE_BITMAP(reg_val, MAX_LINE); + int ret; + +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); ++ + ret = pca953x_read_regs(chip, chip->regs->output, reg_val); + if (ret) +- goto exit; ++ return; + + bitmap_replace(reg_val, reg_val, bits, mask, gc->ngpio); + + pca953x_write_regs(chip, chip->regs->output, reg_val); +-exit: +- mutex_unlock(&chip->i2c_lock); + } + + static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, +@@ -638,7 +631,6 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, + unsigned long config) + { + enum pin_config_param param = pinconf_to_config_param(config); +- + u8 pull_en_reg = chip->recalc_addr(chip, PCAL953X_PULL_EN, offset); + u8 pull_sel_reg = chip->recalc_addr(chip, PCAL953X_PULL_SEL, offset); + u8 bit = BIT(offset % BANK_SZ); +@@ -651,7 +643,7 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, + if (!(chip->driver_data & PCA_PCAL)) + return -ENOTSUPP; + +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); + + /* Configure pull-up/pull-down */ + if (param == PIN_CONFIG_BIAS_PULL_UP) +@@ -661,17 +653,13 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip, + else + ret = 0; + if (ret) +- goto exit; ++ return ret; + + /* Disable/Enable pull-up/pull-down */ + if (param == PIN_CONFIG_BIAS_DISABLE) +- ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); ++ return regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); + else +- ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); +- +-exit: +- mutex_unlock(&chip->i2c_lock); +- return ret; ++ return regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); + } + + static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset, +@@ -883,10 +871,8 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) + + bitmap_zero(pending, MAX_LINE); + +- mutex_lock(&chip->i2c_lock); +- ret = pca953x_irq_pending(chip, pending); +- mutex_unlock(&chip->i2c_lock); +- ++ scoped_guard(mutex, &chip->i2c_lock) ++ ret = pca953x_irq_pending(chip, pending); + if (ret) { + ret = 0; + +@@ -1221,26 +1207,21 @@ static int pca953x_restore_context(struct pca953x_chip *chip) + { + int ret; + +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); + + regcache_cache_only(chip->regmap, false); + regcache_mark_dirty(chip->regmap); + ret = pca953x_regcache_sync(chip); +- if (ret) { +- mutex_unlock(&chip->i2c_lock); ++ if (ret) + return ret; +- } + +- ret = regcache_sync(chip->regmap); +- mutex_unlock(&chip->i2c_lock); +- return ret; ++ return regcache_sync(chip->regmap); + } + + static void pca953x_save_context(struct pca953x_chip *chip) + { +- mutex_lock(&chip->i2c_lock); ++ guard(mutex)(&chip->i2c_lock); + regcache_cache_only(chip->regmap, true); +- mutex_unlock(&chip->i2c_lock); + } + + static int pca953x_suspend(struct device *dev) +-- +2.39.5 + diff --git a/queue-6.6/gpio-pca953x-split-pca953x_restore_context-and-pca95.patch b/queue-6.6/gpio-pca953x-split-pca953x_restore_context-and-pca95.patch new file mode 100644 index 0000000000..350c6dcd77 --- /dev/null +++ b/queue-6.6/gpio-pca953x-split-pca953x_restore_context-and-pca95.patch @@ -0,0 +1,99 @@ +From 91373f2a1a6ea06f8f2aeaef9cede7aa1226c6f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 16:40:35 +0300 +Subject: gpio: pca953x: Split pca953x_restore_context() and + pca953x_save_context() + +From: Andy Shevchenko + +[ Upstream commit ec5bde62019b0a5300c67bd81b9864a8ea12274e ] + +Split regcache handling to the respective helpers. It will allow to +have further refactoring with ease. + +Signed-off-by: Andy Shevchenko +Signed-off-by: Bartosz Golaszewski +Stable-dep-of: 3e38f946062b ("gpio: pca953x: fix IRQ storm on system wake up") +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-pca953x.c | 44 ++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c +index b882b26ab5007..fddf0cf031007 100644 +--- a/drivers/gpio/gpio-pca953x.c ++++ b/drivers/gpio/gpio-pca953x.c +@@ -1168,9 +1168,9 @@ static int pca953x_probe(struct i2c_client *client) + } + + #ifdef CONFIG_PM_SLEEP +-static int pca953x_regcache_sync(struct device *dev) ++static int pca953x_regcache_sync(struct pca953x_chip *chip) + { +- struct pca953x_chip *chip = dev_get_drvdata(dev); ++ struct device *dev = &chip->client->dev; + int ret; + u8 regaddr; + +@@ -1217,13 +1217,37 @@ static int pca953x_regcache_sync(struct device *dev) + return 0; + } + +-static int pca953x_suspend(struct device *dev) ++static int pca953x_restore_context(struct pca953x_chip *chip) + { +- struct pca953x_chip *chip = dev_get_drvdata(dev); ++ int ret; ++ ++ mutex_lock(&chip->i2c_lock); ++ ++ regcache_cache_only(chip->regmap, false); ++ regcache_mark_dirty(chip->regmap); ++ ret = pca953x_regcache_sync(chip); ++ if (ret) { ++ mutex_unlock(&chip->i2c_lock); ++ return ret; ++ } ++ ++ ret = regcache_sync(chip->regmap); ++ mutex_unlock(&chip->i2c_lock); ++ return ret; ++} + ++static void pca953x_save_context(struct pca953x_chip *chip) ++{ + mutex_lock(&chip->i2c_lock); + regcache_cache_only(chip->regmap, true); + mutex_unlock(&chip->i2c_lock); ++} ++ ++static int pca953x_suspend(struct device *dev) ++{ ++ struct pca953x_chip *chip = dev_get_drvdata(dev); ++ ++ pca953x_save_context(chip); + + if (atomic_read(&chip->wakeup_path)) + device_set_wakeup_path(dev); +@@ -1246,17 +1270,7 @@ static int pca953x_resume(struct device *dev) + } + } + +- mutex_lock(&chip->i2c_lock); +- regcache_cache_only(chip->regmap, false); +- regcache_mark_dirty(chip->regmap); +- ret = pca953x_regcache_sync(dev); +- if (ret) { +- mutex_unlock(&chip->i2c_lock); +- return ret; +- } +- +- ret = regcache_sync(chip->regmap); +- mutex_unlock(&chip->i2c_lock); ++ ret = pca953x_restore_context(chip); + if (ret) { + dev_err(dev, "Failed to restore register map: %d\n", ret); + return ret; +-- +2.39.5 + diff --git a/queue-6.6/hid-usbkbd-fix-the-bit-shift-number-for-led_kana.patch b/queue-6.6/hid-usbkbd-fix-the-bit-shift-number-for-led_kana.patch new file mode 100644 index 0000000000..83aebb1be6 --- /dev/null +++ b/queue-6.6/hid-usbkbd-fix-the-bit-shift-number-for-led_kana.patch @@ -0,0 +1,34 @@ +From 825bfb069ef19e045da212c7d280cdb3ec888328 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Nov 2024 10:35:18 +0800 +Subject: HID: usbkbd: Fix the bit shift number for LED_KANA + +From: junan + +[ Upstream commit d73a4bfa2881a6859b384b75a414c33d4898b055 ] + +Since "LED_KANA" was defined as "0x04", the shift number should be "4". + +Signed-off-by: junan +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/usbhid/usbkbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c +index c439ed2f16dbc..af6bc76dbf649 100644 +--- a/drivers/hid/usbhid/usbkbd.c ++++ b/drivers/hid/usbhid/usbkbd.c +@@ -160,7 +160,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type, + return -1; + + spin_lock_irqsave(&kbd->leds_lock, flags); +- kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) | ++ kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 4) | (!!test_bit(LED_COMPOSE, dev->led) << 3) | + (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) | + (!!test_bit(LED_NUML, dev->led)); + +-- +2.39.5 + diff --git a/queue-6.6/hwmon-dell-smm-increment-the-number-of-fans.patch b/queue-6.6/hwmon-dell-smm-increment-the-number-of-fans.patch new file mode 100644 index 0000000000..9e5da71b6c --- /dev/null +++ b/queue-6.6/hwmon-dell-smm-increment-the-number-of-fans.patch @@ -0,0 +1,86 @@ +From dde58fb104382b4a2359d78cf9ca1b6462ff2dd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 00:52:50 -0500 +Subject: hwmon: (dell-smm) Increment the number of fans + +From: Kurt Borja + +[ Upstream commit dbcfcb239b3b452ef8782842c36fb17dd1b9092f ] + +Some Alienware laptops that support the SMM interface, may have up to 4 +fans. + +Tested on an Alienware x15 r1. + +Signed-off-by: Kurt Borja +Link: https://lore.kernel.org/r/20250304055249.51940-2-kuurtb@gmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + Documentation/hwmon/dell-smm-hwmon.rst | 14 +++++++------- + drivers/hwmon/dell-smm-hwmon.c | 5 ++++- + 2 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/Documentation/hwmon/dell-smm-hwmon.rst b/Documentation/hwmon/dell-smm-hwmon.rst +index d8f1d6859b964..1c12fbba440bc 100644 +--- a/Documentation/hwmon/dell-smm-hwmon.rst ++++ b/Documentation/hwmon/dell-smm-hwmon.rst +@@ -32,12 +32,12 @@ Temperature sensors and fans can be queried and set via the standard + =============================== ======= ======================================= + Name Perm Description + =============================== ======= ======================================= +-fan[1-3]_input RO Fan speed in RPM. +-fan[1-3]_label RO Fan label. +-fan[1-3]_min RO Minimal Fan speed in RPM +-fan[1-3]_max RO Maximal Fan speed in RPM +-fan[1-3]_target RO Expected Fan speed in RPM +-pwm[1-3] RW Control the fan PWM duty-cycle. ++fan[1-4]_input RO Fan speed in RPM. ++fan[1-4]_label RO Fan label. ++fan[1-4]_min RO Minimal Fan speed in RPM ++fan[1-4]_max RO Maximal Fan speed in RPM ++fan[1-4]_target RO Expected Fan speed in RPM ++pwm[1-4] RW Control the fan PWM duty-cycle. + pwm1_enable WO Enable or disable automatic BIOS fan + control (not supported on all laptops, + see below for details). +@@ -93,7 +93,7 @@ Again, when you find new codes, we'd be happy to have your patches! + --------------------------- + + The driver also exports the fans as thermal cooling devices with +-``type`` set to ``dell-smm-fan[1-3]``. This allows for easy fan control ++``type`` set to ``dell-smm-fan[1-4]``. This allows for easy fan control + using one of the thermal governors. + + Module parameters +diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c +index 44aaf9b9191d4..8d94ecc3cc468 100644 +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -67,7 +67,7 @@ + #define I8K_POWER_BATTERY 0x01 + + #define DELL_SMM_NO_TEMP 10 +-#define DELL_SMM_NO_FANS 3 ++#define DELL_SMM_NO_FANS 4 + + struct dell_smm_data { + struct mutex i8k_mutex; /* lock for sensors writes */ +@@ -940,11 +940,14 @@ static const struct hwmon_channel_info * const dell_smm_info[] = { + HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | + HWMON_F_TARGET, + HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | ++ HWMON_F_TARGET, ++ HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | + HWMON_F_TARGET + ), + HWMON_CHANNEL_INFO(pwm, + HWMON_PWM_INPUT | HWMON_PWM_ENABLE, + HWMON_PWM_INPUT, ++ HWMON_PWM_INPUT, + HWMON_PWM_INPUT + ), + NULL +-- +2.39.5 + diff --git a/queue-6.6/hwmon-gpio-fan-add-missing-mutex-locks.patch b/queue-6.6/hwmon-gpio-fan-add-missing-mutex-locks.patch new file mode 100644 index 0000000000..4510835428 --- /dev/null +++ b/queue-6.6/hwmon-gpio-fan-add-missing-mutex-locks.patch @@ -0,0 +1,75 @@ +From 933f1cde0a87cbb2f50de361faa475ce88b74866 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Feb 2025 15:59:30 +0100 +Subject: hwmon: (gpio-fan) Add missing mutex locks + +From: Alexander Stein + +[ Upstream commit 9fee7d19bab635f89223cc40dfd2c8797fdc4988 ] + +set_fan_speed() is expected to be called with fan_data->lock being locked. +Add locking for proper synchronization. + +Signed-off-by: Alexander Stein +Link: https://lore.kernel.org/r/20250210145934.761280-3-alexander.stein@ew.tq-group.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/gpio-fan.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c +index d92c536be9af7..b779240328d59 100644 +--- a/drivers/hwmon/gpio-fan.c ++++ b/drivers/hwmon/gpio-fan.c +@@ -393,7 +393,12 @@ static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev, + if (state >= fan_data->num_speed) + return -EINVAL; + ++ mutex_lock(&fan_data->lock); ++ + set_fan_speed(fan_data, state); ++ ++ mutex_unlock(&fan_data->lock); ++ + return 0; + } + +@@ -489,7 +494,11 @@ MODULE_DEVICE_TABLE(of, of_gpio_fan_match); + + static void gpio_fan_stop(void *data) + { ++ struct gpio_fan_data *fan_data = data; ++ ++ mutex_lock(&fan_data->lock); + set_fan_speed(data, 0); ++ mutex_unlock(&fan_data->lock); + } + + static int gpio_fan_probe(struct platform_device *pdev) +@@ -562,7 +571,9 @@ static int gpio_fan_suspend(struct device *dev) + + if (fan_data->gpios) { + fan_data->resume_speed = fan_data->speed_index; ++ mutex_lock(&fan_data->lock); + set_fan_speed(fan_data, 0); ++ mutex_unlock(&fan_data->lock); + } + + return 0; +@@ -572,8 +583,11 @@ static int gpio_fan_resume(struct device *dev) + { + struct gpio_fan_data *fan_data = dev_get_drvdata(dev); + +- if (fan_data->gpios) ++ if (fan_data->gpios) { ++ mutex_lock(&fan_data->lock); + set_fan_speed(fan_data, fan_data->resume_speed); ++ mutex_unlock(&fan_data->lock); ++ } + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/hwmon-xgene-hwmon-use-appropriate-type-for-the-laten.patch b/queue-6.6/hwmon-xgene-hwmon-use-appropriate-type-for-the-laten.patch new file mode 100644 index 0000000000..1b38c1a8e9 --- /dev/null +++ b/queue-6.6/hwmon-xgene-hwmon-use-appropriate-type-for-the-laten.patch @@ -0,0 +1,45 @@ +From 307b391a83cbd5f8709b61ca6566c1d44bd7d8a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 09:54:08 +0000 +Subject: hwmon: (xgene-hwmon) use appropriate type for the latency value + +From: Andrey Vatoropin + +[ Upstream commit 8df0f002827e18632dcd986f7546c1abf1953a6f ] + +The expression PCC_NUM_RETRIES * pcc_chan->latency is currently being +evaluated using 32-bit arithmetic. + +Since a value of type 'u64' is used to store the eventual result, +and this result is later sent to the function usecs_to_jiffies with +input parameter unsigned int, the current data type is too wide to +store the value of ctx->usecs_lat. + +Change the data type of "usecs_lat" to a more suitable (narrower) type. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Andrey Vatoropin +Link: https://lore.kernel.org/r/20250204095400.95013-1-a.vatoropin@crpt.ru +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/xgene-hwmon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/xgene-hwmon.c b/drivers/hwmon/xgene-hwmon.c +index 207084d55044a..6768dbf390390 100644 +--- a/drivers/hwmon/xgene-hwmon.c ++++ b/drivers/hwmon/xgene-hwmon.c +@@ -111,7 +111,7 @@ struct xgene_hwmon_dev { + + phys_addr_t comm_base_addr; + void *pcc_comm_addr; +- u64 usecs_lat; ++ unsigned int usecs_lat; + }; + + /* +-- +2.39.5 + diff --git a/queue-6.6/hypfs_create_cpu_files-add-missing-check-for-hypfs_m.patch b/queue-6.6/hypfs_create_cpu_files-add-missing-check-for-hypfs_m.patch new file mode 100644 index 0000000000..dd57f3e6a6 --- /dev/null +++ b/queue-6.6/hypfs_create_cpu_files-add-missing-check-for-hypfs_m.patch @@ -0,0 +1,31 @@ +From 1cc99e5346dfd8b74406514a240e4aa05482c4f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Mar 2025 22:06:04 -0400 +Subject: hypfs_create_cpu_files(): add missing check for hypfs_mkdir() failure + +From: Al Viro + +[ Upstream commit 00cdfdcfa0806202aea56b02cedbf87ef1e75df8 ] + +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + arch/s390/hypfs/hypfs_diag_fs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/s390/hypfs/hypfs_diag_fs.c b/arch/s390/hypfs/hypfs_diag_fs.c +index 00a6d370a2803..280266a74f378 100644 +--- a/arch/s390/hypfs/hypfs_diag_fs.c ++++ b/arch/s390/hypfs/hypfs_diag_fs.c +@@ -208,6 +208,8 @@ static int hypfs_create_cpu_files(struct dentry *cpus_dir, void *cpu_info) + snprintf(buffer, TMP_SIZE, "%d", cpu_info__cpu_addr(diag204_get_info_type(), + cpu_info)); + cpu_dir = hypfs_mkdir(cpus_dir, buffer); ++ if (IS_ERR(cpu_dir)) ++ return PTR_ERR(cpu_dir); + rc = hypfs_create_u64(cpu_dir, "mgmtime", + cpu_info__acc_time(diag204_get_info_type(), cpu_info) - + cpu_info__lp_time(diag204_get_info_type(), cpu_info)); +-- +2.39.5 + diff --git a/queue-6.6/i2c-designware-fix-an-error-handling-path-in-i2c_dw_.patch b/queue-6.6/i2c-designware-fix-an-error-handling-path-in-i2c_dw_.patch new file mode 100644 index 0000000000..513e2f6ef5 --- /dev/null +++ b/queue-6.6/i2c-designware-fix-an-error-handling-path-in-i2c_dw_.patch @@ -0,0 +1,44 @@ +From 36e6dd3eef2d3d79589215139655931148e36e40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 May 2025 19:56:41 +0200 +Subject: i2c: designware: Fix an error handling path in i2c_dw_pci_probe() + +From: Christophe JAILLET + +[ Upstream commit 1cfe51ef07ca3286581d612debfb0430eeccbb65 ] + +If navi_amd_register_client() fails, the previous i2c_dw_probe() call +should be undone by a corresponding i2c_del_adapter() call, as already done +in the remove function. + +Fixes: 17631e8ca2d3 ("i2c: designware: Add driver support for AMD NAVI GPU") +Signed-off-by: Christophe JAILLET +Cc: # v5.13+ +Acked-by: Jarkko Nikula +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/fcd9651835a32979df8802b2db9504c523a8ebbb.1747158983.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-pcidrv.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 36c13612b55d4..b85f1e4ed13bc 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -335,9 +335,11 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, + + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { + dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, &dgpu_node); +- if (IS_ERR(dev->slave)) ++ if (IS_ERR(dev->slave)) { ++ i2c_del_adapter(&dev->adapter); + return dev_err_probe(device, PTR_ERR(dev->slave), + "register UCSI failed\n"); ++ } + } + + pm_runtime_set_autosuspend_delay(device, 1000); +-- +2.39.5 + diff --git a/queue-6.6/i2c-designware-remove-disable-callback.patch b/queue-6.6/i2c-designware-remove-disable-callback.patch new file mode 100644 index 0000000000..a769600ff9 --- /dev/null +++ b/queue-6.6/i2c-designware-remove-disable-callback.patch @@ -0,0 +1,159 @@ +From 3da2491d6ed90873caa64218176d25639c267a7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 20:58:41 +0300 +Subject: i2c: designware: Remove ->disable() callback + +From: Andy Shevchenko + +[ Upstream commit bc07fb417007b323d34651be20b9135480a947dc ] + +Commit 90312351fd1e ("i2c: designware: MASTER mode as separated driver") +introduced ->disable() callback but there is no real use for it. Both +i2c-designware-master.c and i2c-designware-slave.c set it to the same +i2c_dw_disable() and scope is inside the same kernel module. + +That said, replace the callback by explicitly calling the i2c_dw_disable(). + +Reviewed-by: Andi Shyti +Signed-off-by: Andy Shevchenko +Signed-off-by: Andi Shyti +Stable-dep-of: 1cfe51ef07ca ("i2c: designware: Fix an error handling path in i2c_dw_pci_probe()") +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-common.c | 1 + + drivers/i2c/busses/i2c-designware-core.h | 4 +--- + drivers/i2c/busses/i2c-designware-master.c | 1 - + drivers/i2c/busses/i2c-designware-pcidrv.c | 5 +++-- + drivers/i2c/busses/i2c-designware-platdrv.c | 4 ++-- + drivers/i2c/busses/i2c-designware-slave.c | 3 +-- + 6 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c +index ced2fb4aeda8d..79e083aab08e0 100644 +--- a/drivers/i2c/busses/i2c-designware-common.c ++++ b/drivers/i2c/busses/i2c-designware-common.c +@@ -669,6 +669,7 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) + + i2c_dw_release_lock(dev); + } ++EXPORT_SYMBOL_GPL(i2c_dw_disable); + + MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); + MODULE_LICENSE("GPL"); +diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h +index a26fff9716ddc..e93870a0f9a45 100644 +--- a/drivers/i2c/busses/i2c-designware-core.h ++++ b/drivers/i2c/busses/i2c-designware-core.h +@@ -238,7 +238,6 @@ struct reset_control; + * @semaphore_idx: Index of table with semaphore type attached to the bus. It's + * -1 if there is no semaphore. + * @shared_with_punit: true if this bus is shared with the SoCs PUNIT +- * @disable: function to disable the controller + * @init: function to initialize the I2C hardware + * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing + * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE +@@ -295,7 +294,6 @@ struct dw_i2c_dev { + void (*release_lock)(void); + int semaphore_idx; + bool shared_with_punit; +- void (*disable)(struct dw_i2c_dev *dev); + int (*init)(struct dw_i2c_dev *dev); + int (*set_sda_hold_time)(struct dw_i2c_dev *dev); + int mode; +@@ -340,7 +338,6 @@ int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); + int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); + int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); + u32 i2c_dw_func(struct i2c_adapter *adap); +-void i2c_dw_disable(struct dw_i2c_dev *dev); + + static inline void __i2c_dw_enable(struct dw_i2c_dev *dev) + { +@@ -355,6 +352,7 @@ static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev) + } + + void __i2c_dw_disable(struct dw_i2c_dev *dev); ++void i2c_dw_disable(struct dw_i2c_dev *dev); + + extern void i2c_dw_configure_master(struct dw_i2c_dev *dev); + extern int i2c_dw_probe_master(struct dw_i2c_dev *dev); +diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c +index c1e516df5cd4c..51f5491648c07 100644 +--- a/drivers/i2c/busses/i2c-designware-master.c ++++ b/drivers/i2c/busses/i2c-designware-master.c +@@ -1001,7 +1001,6 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) + init_completion(&dev->cmd_complete); + + dev->init = i2c_dw_init_master; +- dev->disable = i2c_dw_disable; + + ret = i2c_dw_init_regmap(dev); + if (ret) +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 9be9a2658e1f6..6db6f9d5d4d4e 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -198,7 +198,7 @@ static int __maybe_unused i2c_dw_pci_runtime_suspend(struct device *dev) + { + struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); + +- i_dev->disable(i_dev); ++ i2c_dw_disable(i_dev); + return 0; + } + +@@ -354,7 +354,8 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) + { + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); + +- dev->disable(dev); ++ i2c_dw_disable(dev); ++ + pm_runtime_forbid(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); + +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index 4ab41ba39d55f..61c506092abdb 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -407,7 +407,7 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) + + i2c_del_adapter(&dev->adapter); + +- dev->disable(dev); ++ i2c_dw_disable(dev); + + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_sync(&pdev->dev); +@@ -436,7 +436,7 @@ static int dw_i2c_plat_runtime_suspend(struct device *dev) + if (i_dev->shared_with_punit) + return 0; + +- i_dev->disable(i_dev); ++ i2c_dw_disable(i_dev); + i2c_dw_prepare_clk(i_dev, false); + + return 0; +diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c +index 78e2c47e3d7da..345b532a2b455 100644 +--- a/drivers/i2c/busses/i2c-designware-slave.c ++++ b/drivers/i2c/busses/i2c-designware-slave.c +@@ -88,7 +88,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) + struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); + + regmap_write(dev->map, DW_IC_INTR_MASK, 0); +- dev->disable(dev); ++ i2c_dw_disable(dev); + synchronize_irq(dev->irq); + dev->slave = NULL; + pm_runtime_put(dev->dev); +@@ -235,7 +235,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev) + int ret; + + dev->init = i2c_dw_init_slave; +- dev->disable = i2c_dw_disable; + + ret = i2c_dw_init_regmap(dev); + if (ret) +-- +2.39.5 + diff --git a/queue-6.6/i2c-designware-uniform-initialization-flow-for-polli.patch b/queue-6.6/i2c-designware-uniform-initialization-flow-for-polli.patch new file mode 100644 index 0000000000..3344bbf778 --- /dev/null +++ b/queue-6.6/i2c-designware-uniform-initialization-flow-for-polli.patch @@ -0,0 +1,136 @@ +From 04be69b8f574c6fb08c3790fd77909b69f2a9a25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Feb 2024 14:48:42 +0200 +Subject: i2c: designware: Uniform initialization flow for polling mode + +From: Jarkko Nikula + +[ Upstream commit 535677e44d57a31e1363529b5ecddb92653d7136 ] + +Currently initialization flow in i2c_dw_probe_master() skips a few steps +and has code duplication for polling mode implementation. + +Simplify this by adding a new ACCESS_POLLING flag that is set for those +two platforms that currently use polling mode and use it to skip +interrupt handler setup. + +Signed-off-by: Jarkko Nikula +Tested-by: Jiawen Wu +Signed-off-by: Andi Shyti +Stable-dep-of: 1cfe51ef07ca ("i2c: designware: Fix an error handling path in i2c_dw_pci_probe()") +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-core.h | 1 + + drivers/i2c/busses/i2c-designware-master.c | 42 ++++----------------- + drivers/i2c/busses/i2c-designware-pcidrv.c | 2 +- + drivers/i2c/busses/i2c-designware-platdrv.c | 2 +- + 4 files changed, 11 insertions(+), 36 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h +index 5eb130c1d6719..a26fff9716ddc 100644 +--- a/drivers/i2c/busses/i2c-designware-core.h ++++ b/drivers/i2c/busses/i2c-designware-core.h +@@ -305,6 +305,7 @@ struct dw_i2c_dev { + #define ACCESS_INTR_MASK BIT(0) + #define ACCESS_NO_IRQ_SUSPEND BIT(1) + #define ARBITRATION_SEMAPHORE BIT(2) ++#define ACCESS_POLLING BIT(3) + + #define MODEL_MSCC_OCELOT BIT(8) + #define MODEL_BAIKAL_BT1 BIT(9) +diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c +index 579c668cb78a6..c1e516df5cd4c 100644 +--- a/drivers/i2c/busses/i2c-designware-master.c ++++ b/drivers/i2c/busses/i2c-designware-master.c +@@ -991,31 +991,6 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) + return 0; + } + +-static int i2c_dw_poll_adap_quirk(struct dw_i2c_dev *dev) +-{ +- struct i2c_adapter *adap = &dev->adapter; +- int ret; +- +- pm_runtime_get_noresume(dev->dev); +- ret = i2c_add_numbered_adapter(adap); +- if (ret) +- dev_err(dev->dev, "Failed to add adapter: %d\n", ret); +- pm_runtime_put_noidle(dev->dev); +- +- return ret; +-} +- +-static bool i2c_dw_is_model_poll(struct dw_i2c_dev *dev) +-{ +- switch (dev->flags & MODEL_MASK) { +- case MODEL_AMD_NAVI_GPU: +- case MODEL_WANGXUN_SP: +- return true; +- default: +- return false; +- } +-} +- + int i2c_dw_probe_master(struct dw_i2c_dev *dev) + { + struct i2c_adapter *adap = &dev->adapter; +@@ -1071,9 +1046,6 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) + adap->dev.parent = dev->dev; + i2c_set_adapdata(adap, dev); + +- if (i2c_dw_is_model_poll(dev)) +- return i2c_dw_poll_adap_quirk(dev); +- + if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { + irq_flags = IRQF_NO_SUSPEND; + } else { +@@ -1087,12 +1059,14 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) + regmap_write(dev->map, DW_IC_INTR_MASK, 0); + i2c_dw_release_lock(dev); + +- ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, irq_flags, +- dev_name(dev->dev), dev); +- if (ret) { +- dev_err(dev->dev, "failure requesting irq %i: %d\n", +- dev->irq, ret); +- return ret; ++ if (!(dev->flags & ACCESS_POLLING)) { ++ ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, ++ irq_flags, dev_name(dev->dev), dev); ++ if (ret) { ++ dev_err(dev->dev, "failure requesting irq %i: %d\n", ++ dev->irq, ret); ++ return ret; ++ } + } + + ret = i2c_dw_init_recovery_info(dev); +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 61d7a27aa0701..9be9a2658e1f6 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -154,7 +154,7 @@ static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c) + { + struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev); + +- dev->flags |= MODEL_AMD_NAVI_GPU; ++ dev->flags |= MODEL_AMD_NAVI_GPU | ACCESS_POLLING; + dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ; + return 0; + } +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index 855b698e99c08..4ab41ba39d55f 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -290,7 +290,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + + dev->flags = (uintptr_t)device_get_match_data(&pdev->dev); + if (device_property_present(&pdev->dev, "wx,i2c-snps-model")) +- dev->flags = MODEL_WANGXUN_SP; ++ dev->flags = MODEL_WANGXUN_SP | ACCESS_POLLING; + + dev->dev = &pdev->dev; + dev->irq = irq; +-- +2.39.5 + diff --git a/queue-6.6/i2c-designware-use-temporary-variable-for-struct-dev.patch b/queue-6.6/i2c-designware-use-temporary-variable-for-struct-dev.patch new file mode 100644 index 0000000000..fd2c5f6108 --- /dev/null +++ b/queue-6.6/i2c-designware-use-temporary-variable-for-struct-dev.patch @@ -0,0 +1,229 @@ +From 1ee1c73079b40960eb876015c9ca67b88a542441 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 15:44:19 +0300 +Subject: i2c: designware: Use temporary variable for struct device + +From: Andy Shevchenko + +[ Upstream commit d2f94dccab8319063dd1fbc1738b4a280c2e4009 ] + +Use temporary variable for struct device to make code neater. + +Reviewed-by: Mario Limonciello +Reviewed-by: Andi Shyti +Signed-off-by: Andy Shevchenko +Acked-by: Jarkko Nikula +Signed-off-by: Andi Shyti +Stable-dep-of: 1cfe51ef07ca ("i2c: designware: Fix an error handling path in i2c_dw_pci_probe()") +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-designware-pcidrv.c | 29 ++++++------- + drivers/i2c/busses/i2c-designware-platdrv.c | 48 ++++++++++----------- + 2 files changed, 37 insertions(+), 40 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 6db6f9d5d4d4e..36c13612b55d4 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -248,6 +248,7 @@ static const struct software_node dgpu_node = { + static int i2c_dw_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) + { ++ struct device *device = &pdev->dev; + struct dw_i2c_dev *dev; + struct i2c_adapter *adap; + int r; +@@ -256,25 +257,22 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, + struct i2c_timings *t; + + if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) +- return dev_err_probe(&pdev->dev, -EINVAL, +- "Invalid driver data %ld\n", ++ return dev_err_probe(device, -EINVAL, "Invalid driver data %ld\n", + id->driver_data); + + controller = &dw_pci_controllers[id->driver_data]; + + r = pcim_enable_device(pdev); + if (r) +- return dev_err_probe(&pdev->dev, r, +- "Failed to enable I2C PCI device\n"); ++ return dev_err_probe(device, r, "Failed to enable I2C PCI device\n"); + + pci_set_master(pdev); + + r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); + if (r) +- return dev_err_probe(&pdev->dev, r, +- "I/O memory remapping failed\n"); ++ return dev_err_probe(device, r, "I/O memory remapping failed\n"); + +- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); ++ dev = devm_kzalloc(device, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + +@@ -284,7 +282,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, + + dev->get_clk_rate_khz = controller->get_clk_rate_khz; + dev->base = pcim_iomap_table(pdev)[0]; +- dev->dev = &pdev->dev; ++ dev->dev = device; + dev->irq = pci_irq_vector(pdev, 0); + dev->flags |= controller->flags; + +@@ -338,14 +336,14 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) { + dev->slave = i2c_new_ccgx_ucsi(&dev->adapter, dev->irq, &dgpu_node); + if (IS_ERR(dev->slave)) +- return dev_err_probe(dev->dev, PTR_ERR(dev->slave), ++ return dev_err_probe(device, PTR_ERR(dev->slave), + "register UCSI failed\n"); + } + +- pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); +- pm_runtime_use_autosuspend(&pdev->dev); +- pm_runtime_put_autosuspend(&pdev->dev); +- pm_runtime_allow(&pdev->dev); ++ pm_runtime_set_autosuspend_delay(device, 1000); ++ pm_runtime_use_autosuspend(device); ++ pm_runtime_put_autosuspend(device); ++ pm_runtime_allow(device); + + return 0; + } +@@ -353,11 +351,12 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev, + static void i2c_dw_pci_remove(struct pci_dev *pdev) + { + struct dw_i2c_dev *dev = pci_get_drvdata(pdev); ++ struct device *device = &pdev->dev; + + i2c_dw_disable(dev); + +- pm_runtime_forbid(&pdev->dev); +- pm_runtime_get_noresume(&pdev->dev); ++ pm_runtime_forbid(device); ++ pm_runtime_get_noresume(device); + + i2c_del_adapter(&dev->adapter); + devm_free_irq(&pdev->dev, dev->irq, dev); +diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c +index 61c506092abdb..f3245a6856309 100644 +--- a/drivers/i2c/busses/i2c-designware-platdrv.c ++++ b/drivers/i2c/busses/i2c-designware-platdrv.c +@@ -275,6 +275,7 @@ static void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev) + + static int dw_i2c_plat_probe(struct platform_device *pdev) + { ++ struct device *device = &pdev->dev; + struct i2c_adapter *adap; + struct dw_i2c_dev *dev; + struct i2c_timings *t; +@@ -284,15 +285,15 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); ++ dev = devm_kzalloc(device, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + +- dev->flags = (uintptr_t)device_get_match_data(&pdev->dev); +- if (device_property_present(&pdev->dev, "wx,i2c-snps-model")) ++ dev->flags = (uintptr_t)device_get_match_data(device); ++ if (device_property_present(device, "wx,i2c-snps-model")) + dev->flags = MODEL_WANGXUN_SP | ACCESS_POLLING; + +- dev->dev = &pdev->dev; ++ dev->dev = device; + dev->irq = irq; + platform_set_drvdata(pdev, dev); + +@@ -300,7 +301,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + if (ret) + return ret; + +- dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); ++ dev->rst = devm_reset_control_get_optional_exclusive(device, NULL); + if (IS_ERR(dev->rst)) + return PTR_ERR(dev->rst); + +@@ -328,13 +329,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + i2c_dw_configure(dev); + + /* Optional interface clock */ +- dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk"); ++ dev->pclk = devm_clk_get_optional(device, "pclk"); + if (IS_ERR(dev->pclk)) { + ret = PTR_ERR(dev->pclk); + goto exit_reset; + } + +- dev->clk = devm_clk_get_optional(&pdev->dev, NULL); ++ dev->clk = devm_clk_get_optional(device, NULL); + if (IS_ERR(dev->clk)) { + ret = PTR_ERR(dev->clk); + goto exit_reset; +@@ -363,28 +364,24 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + adap->dev.of_node = pdev->dev.of_node; + adap->nr = -1; + +- if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { +- dev_pm_set_driver_flags(&pdev->dev, +- DPM_FLAG_SMART_PREPARE); +- } else { +- dev_pm_set_driver_flags(&pdev->dev, +- DPM_FLAG_SMART_PREPARE | +- DPM_FLAG_SMART_SUSPEND); +- } ++ if (dev->flags & ACCESS_NO_IRQ_SUSPEND) ++ dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE); ++ else ++ dev_pm_set_driver_flags(device, DPM_FLAG_SMART_PREPARE | DPM_FLAG_SMART_SUSPEND); + +- device_enable_async_suspend(&pdev->dev); ++ device_enable_async_suspend(device); + + /* The code below assumes runtime PM to be disabled. */ +- WARN_ON(pm_runtime_enabled(&pdev->dev)); ++ WARN_ON(pm_runtime_enabled(device)); + +- pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); +- pm_runtime_use_autosuspend(&pdev->dev); +- pm_runtime_set_active(&pdev->dev); ++ pm_runtime_set_autosuspend_delay(device, 1000); ++ pm_runtime_use_autosuspend(device); ++ pm_runtime_set_active(device); + + if (dev->shared_with_punit) +- pm_runtime_get_noresume(&pdev->dev); ++ pm_runtime_get_noresume(device); + +- pm_runtime_enable(&pdev->dev); ++ pm_runtime_enable(device); + + ret = i2c_dw_probe(dev); + if (ret) +@@ -402,15 +399,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) + static void dw_i2c_plat_remove(struct platform_device *pdev) + { + struct dw_i2c_dev *dev = platform_get_drvdata(pdev); ++ struct device *device = &pdev->dev; + +- pm_runtime_get_sync(&pdev->dev); ++ pm_runtime_get_sync(device); + + i2c_del_adapter(&dev->adapter); + + i2c_dw_disable(dev); + +- pm_runtime_dont_use_autosuspend(&pdev->dev); +- pm_runtime_put_sync(&pdev->dev); ++ pm_runtime_dont_use_autosuspend(device); ++ pm_runtime_put_sync(device); + dw_i2c_plat_pm_cleanup(dev); + + i2c_dw_remove_lock_support(dev); +-- +2.39.5 + diff --git a/queue-6.6/i2c-pxa-fix-call-balance-of-i2c-clk-handling-routine.patch b/queue-6.6/i2c-pxa-fix-call-balance-of-i2c-clk-handling-routine.patch new file mode 100644 index 0000000000..95f7b68741 --- /dev/null +++ b/queue-6.6/i2c-pxa-fix-call-balance-of-i2c-clk-handling-routine.patch @@ -0,0 +1,41 @@ +From 5f70aa1ab49afefca0585c8631806c4d3894609d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 20:28:03 +0300 +Subject: i2c: pxa: fix call balance of i2c->clk handling routines + +From: Vitalii Mordan + +[ Upstream commit be7113d2e2a6f20cbee99c98d261a1fd6fd7b549 ] + +If the clock i2c->clk was not enabled in i2c_pxa_probe(), it should not be +disabled in any path. + +Found by Linux Verification Center (linuxtesting.org) with Klever. + +Signed-off-by: Vitalii Mordan +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20250212172803.1422136-1-mordan@ispras.ru +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-pxa.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c +index 3bd406470940f..affdd94f06aaf 100644 +--- a/drivers/i2c/busses/i2c-pxa.c ++++ b/drivers/i2c/busses/i2c-pxa.c +@@ -1504,7 +1504,10 @@ static int i2c_pxa_probe(struct platform_device *dev) + i2c->adap.name); + } + +- clk_prepare_enable(i2c->clk); ++ ret = clk_prepare_enable(i2c->clk); ++ if (ret) ++ return dev_err_probe(&dev->dev, ret, ++ "failed to enable clock\n"); + + if (i2c->use_pio) { + i2c->adap.algo = &i2c_pxa_pio_algorithm; +-- +2.39.5 + diff --git a/queue-6.6/i2c-qup-vote-for-interconnect-bandwidth-to-dram.patch b/queue-6.6/i2c-qup-vote-for-interconnect-bandwidth-to-dram.patch new file mode 100644 index 0000000000..11a0ae48cb --- /dev/null +++ b/queue-6.6/i2c-qup-vote-for-interconnect-bandwidth-to-dram.patch @@ -0,0 +1,139 @@ +From cb61f0a022af4c1b994a054146dd90d7e2b1db10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Nov 2023 10:48:37 +0100 +Subject: i2c: qup: Vote for interconnect bandwidth to DRAM + +From: Stephan Gerhold + +[ Upstream commit d4f35233a6345f62637463ef6e0708f44ffaa583 ] + +When the I2C QUP controller is used together with a DMA engine it needs +to vote for the interconnect path to the DRAM. Otherwise it may be +unable to access the memory quickly enough. + +The requested peak bandwidth is dependent on the I2C core clock. + +To avoid sending votes too often the bandwidth is always requested when +a DMA transfer starts, but dropped only on runtime suspend. Runtime +suspend should only happen if no transfer is active. After resumption we +can defer the next vote until the first DMA transfer actually happens. + +The implementation is largely identical to the one introduced for +spi-qup in commit ecdaa9473019 ("spi: qup: Vote for interconnect +bandwidth to DRAM") since both drivers represent the same hardware +block. + +Signed-off-by: Stephan Gerhold +Signed-off-by: Andi Shyti +Link: https://lore.kernel.org/r/20231128-i2c-qup-dvfs-v1-3-59a0e3039111@kernkonzept.com +Signed-off-by: Sasha Levin +--- + drivers/i2c/busses/i2c-qup.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c +index 598102d16677a..ee92a315f074f 100644 +--- a/drivers/i2c/busses/i2c-qup.c ++++ b/drivers/i2c/busses/i2c-qup.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -150,6 +151,8 @@ + /* TAG length for DATA READ in RX FIFO */ + #define READ_RX_TAGS_LEN 2 + ++#define QUP_BUS_WIDTH 8 ++ + static unsigned int scl_freq; + module_param_named(scl_freq, scl_freq, uint, 0444); + MODULE_PARM_DESC(scl_freq, "SCL frequency override"); +@@ -227,6 +230,7 @@ struct qup_i2c_dev { + int irq; + struct clk *clk; + struct clk *pclk; ++ struct icc_path *icc_path; + struct i2c_adapter adap; + + int clk_ctl; +@@ -255,6 +259,10 @@ struct qup_i2c_dev { + /* To configure when bus is in run state */ + u32 config_run; + ++ /* bandwidth votes */ ++ u32 src_clk_freq; ++ u32 cur_bw_clk_freq; ++ + /* dma parameters */ + bool is_dma; + /* To check if the current transfer is using DMA */ +@@ -453,6 +461,23 @@ static int qup_i2c_bus_active(struct qup_i2c_dev *qup, int len) + return ret; + } + ++static int qup_i2c_vote_bw(struct qup_i2c_dev *qup, u32 clk_freq) ++{ ++ u32 needed_peak_bw; ++ int ret; ++ ++ if (qup->cur_bw_clk_freq == clk_freq) ++ return 0; ++ ++ needed_peak_bw = Bps_to_icc(clk_freq * QUP_BUS_WIDTH); ++ ret = icc_set_bw(qup->icc_path, 0, needed_peak_bw); ++ if (ret) ++ return ret; ++ ++ qup->cur_bw_clk_freq = clk_freq; ++ return 0; ++} ++ + static void qup_i2c_write_tx_fifo_v1(struct qup_i2c_dev *qup) + { + struct qup_i2c_block *blk = &qup->blk; +@@ -840,6 +865,10 @@ static int qup_i2c_bam_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, + int ret = 0; + int idx = 0; + ++ ret = qup_i2c_vote_bw(qup, qup->src_clk_freq); ++ if (ret) ++ return ret; ++ + enable_irq(qup->irq); + ret = qup_i2c_req_dma(qup); + +@@ -1645,6 +1674,7 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup) + config = readl(qup->base + QUP_CONFIG); + config |= QUP_CLOCK_AUTO_GATE; + writel(config, qup->base + QUP_CONFIG); ++ qup_i2c_vote_bw(qup, 0); + clk_disable_unprepare(qup->pclk); + } + +@@ -1745,6 +1775,11 @@ static int qup_i2c_probe(struct platform_device *pdev) + goto fail_dma; + } + qup->is_dma = true; ++ ++ qup->icc_path = devm_of_icc_get(&pdev->dev, NULL); ++ if (IS_ERR(qup->icc_path)) ++ return dev_err_probe(&pdev->dev, PTR_ERR(qup->icc_path), ++ "failed to get interconnect path\n"); + } + + nodma: +@@ -1793,6 +1828,7 @@ static int qup_i2c_probe(struct platform_device *pdev) + qup_i2c_enable_clocks(qup); + src_clk_freq = clk_get_rate(qup->clk); + } ++ qup->src_clk_freq = src_clk_freq; + + /* + * Bootloaders might leave a pending interrupt on certain QUP's, +-- +2.39.5 + diff --git a/queue-6.6/i3c-master-svc-fix-missing-stop-for-master-request.patch b/queue-6.6/i3c-master-svc-fix-missing-stop-for-master-request.patch new file mode 100644 index 0000000000..a1a7b1ec55 --- /dev/null +++ b/queue-6.6/i3c-master-svc-fix-missing-stop-for-master-request.patch @@ -0,0 +1,37 @@ +From 29d4ba310b67d0bf8b5183e55fb247ad71a90254 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Mar 2025 13:36:06 +0800 +Subject: i3c: master: svc: Fix missing STOP for master request + +From: Stanley Chu + +[ Upstream commit 0430bf9bc1ac068c8b8c540eb93e5751872efc51 ] + +The controller driver nacked the master request but didn't emit a +STOP to end the transaction. The driver shall refuse the unsupported +requests and return the controller state to IDLE by emitting a STOP. + +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Link: https://lore.kernel.org/r/20250318053606.3087121-4-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index fa1f12a89158c..3cef3794f10d3 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -503,6 +503,7 @@ static void svc_i3c_master_ibi_work(struct work_struct *work) + queue_work(master->base.wq, &master->hj_work); + break; + case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST: ++ svc_i3c_master_emit_stop(master); + default: + break; + } +-- +2.39.5 + diff --git a/queue-6.6/i3c-master-svc-flush-fifo-before-sending-dynamic-add.patch b/queue-6.6/i3c-master-svc-flush-fifo-before-sending-dynamic-add.patch new file mode 100644 index 0000000000..cac301ecf4 --- /dev/null +++ b/queue-6.6/i3c-master-svc-flush-fifo-before-sending-dynamic-add.patch @@ -0,0 +1,40 @@ +From 7d665eb6e60c0023594ff659903be2ff362bbaf2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jan 2025 11:22:50 -0500 +Subject: i3c: master: svc: Flush FIFO before sending Dynamic Address + Assignment(DAA) + +From: Frank Li + +[ Upstream commit a892ee4cf22a50e1d6988d0464a9a421f3e5db2f ] + +Ensure the FIFO is empty before issuing the DAA command to prevent +incorrect command data from being sent. Align with other data transfers, +such as svc_i3c_master_start_xfer_locked(), which flushes the FIFO before +sending a command. + +Signed-off-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://lore.kernel.org/r/20250129162250.3629189-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index 3cef3794f10d3..3d1734849e0d9 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -841,6 +841,8 @@ static int svc_i3c_master_do_daa_locked(struct svc_i3c_master *master, + u32 reg; + int ret, i; + ++ svc_i3c_master_flush_fifo(master); ++ + while (true) { + /* Enter/proceed with DAA */ + writel(SVC_I3C_MCTRL_REQUEST_PROC_DAA | +-- +2.39.5 + diff --git a/queue-6.6/ice-count-combined-queues-using-rx-tx-count.patch b/queue-6.6/ice-count-combined-queues-using-rx-tx-count.patch new file mode 100644 index 0000000000..1f9300be5d --- /dev/null +++ b/queue-6.6/ice-count-combined-queues-using-rx-tx-count.patch @@ -0,0 +1,40 @@ +From 95ed43c8ad41d276c08ea1a34307ac6cdbff062a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 07:58:09 +0100 +Subject: ice: count combined queues using Rx/Tx count + +From: Michal Swiatkowski + +[ Upstream commit c3a392bdd31adc474f1009ee85c13fdd01fe800d ] + +Previous implementation assumes that there is 1:1 matching between +vectors and queues. It isn't always true. + +Get minimum value from Rx/Tx queues to determine combined queues number. + +Reviewed-by: Jacob Keller +Tested-by: Pucha Himasekhar Reddy +Signed-off-by: Michal Swiatkowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ethtool.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index 39b5f24be7e4f..dd58b2372dc0c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -3329,8 +3329,7 @@ static u32 ice_get_combined_cnt(struct ice_vsi *vsi) + ice_for_each_q_vector(vsi, q_idx) { + struct ice_q_vector *q_vector = vsi->q_vectors[q_idx]; + +- if (q_vector->rx.rx_ring && q_vector->tx.tx_ring) +- combined++; ++ combined += min(q_vector->num_ring_tx, q_vector->num_ring_rx); + } + + return combined; +-- +2.39.5 + diff --git a/queue-6.6/ice-treat-dyn_allowed-only-as-suggestion.patch b/queue-6.6/ice-treat-dyn_allowed-only-as-suggestion.patch new file mode 100644 index 0000000000..308717acdc --- /dev/null +++ b/queue-6.6/ice-treat-dyn_allowed-only-as-suggestion.patch @@ -0,0 +1,133 @@ +From ec2e17b450b5596bbfe2520209d056ea9e6407cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 07:58:14 +0100 +Subject: ice: treat dyn_allowed only as suggestion + +From: Michal Swiatkowski + +[ Upstream commit a8c2d3932c1106af2764cc6869b29bcf3cb5bc47 ] + +It can be needed to have some MSI-X allocated as static and rest as +dynamic. For example on PF VSI. We want to always have minimum one MSI-X +on it, because of that it is allocated as a static one, rest can be +dynamic if it is supported. + +Change the ice_get_irq_res() to allow using static entries if they are +free even if caller wants dynamic one. + +Adjust limit values to the new approach. Min and max in limit means the +values that are valid, so decrease max and num_static by one. + +Set vsi::irq_dyn_alloc if dynamic allocation is supported. + +Reviewed-by: Jacob Keller +Reviewed-by: Wojciech Drewek +Tested-by: Pucha Himasekhar Reddy +Signed-off-by: Michal Swiatkowski +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_irq.c | 25 ++++++++++++------------ + drivers/net/ethernet/intel/ice/ice_lib.c | 2 ++ + 2 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_irq.c b/drivers/net/ethernet/intel/ice/ice_irq.c +index ad82ff7d19957..09f9c7ba52795 100644 +--- a/drivers/net/ethernet/intel/ice/ice_irq.c ++++ b/drivers/net/ethernet/intel/ice/ice_irq.c +@@ -45,7 +45,7 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index) + /** + * ice_get_irq_res - get an interrupt resource + * @pf: board private structure +- * @dyn_only: force entry to be dynamically allocated ++ * @dyn_allowed: allow entry to be dynamically allocated + * + * Allocate new irq entry in the free slot of the tracker. Since xarray + * is used, always allocate new entry at the lowest possible index. Set +@@ -53,11 +53,12 @@ static void ice_free_irq_res(struct ice_pf *pf, u16 index) + * + * Returns allocated irq entry or NULL on failure. + */ +-static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) ++static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, ++ bool dyn_allowed) + { +- struct xa_limit limit = { .max = pf->irq_tracker.num_entries, ++ struct xa_limit limit = { .max = pf->irq_tracker.num_entries - 1, + .min = 0 }; +- unsigned int num_static = pf->irq_tracker.num_static; ++ unsigned int num_static = pf->irq_tracker.num_static - 1; + struct ice_irq_entry *entry; + unsigned int index; + int ret; +@@ -66,9 +67,9 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) + if (!entry) + return NULL; + +- /* skip preallocated entries if the caller says so */ +- if (dyn_only) +- limit.min = num_static; ++ /* only already allocated if the caller says so */ ++ if (!dyn_allowed) ++ limit.max = num_static; + + ret = xa_alloc(&pf->irq_tracker.entries, &index, entry, limit, + GFP_KERNEL); +@@ -78,7 +79,7 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, bool dyn_only) + entry = NULL; + } else { + entry->index = index; +- entry->dynamic = index >= num_static; ++ entry->dynamic = index > num_static; + } + + return entry; +@@ -272,7 +273,7 @@ int ice_init_interrupt_scheme(struct ice_pf *pf) + /** + * ice_alloc_irq - Allocate new interrupt vector + * @pf: board private structure +- * @dyn_only: force dynamic allocation of the interrupt ++ * @dyn_allowed: allow dynamic allocation of the interrupt + * + * Allocate new interrupt vector for a given owner id. + * return struct msi_map with interrupt details and track +@@ -285,20 +286,20 @@ int ice_init_interrupt_scheme(struct ice_pf *pf) + * interrupt will be allocated with pci_msix_alloc_irq_at. + * + * Some callers may only support dynamically allocated interrupts. +- * This is indicated with dyn_only flag. ++ * This is indicated with dyn_allowed flag. + * + * On failure, return map with negative .index. The caller + * is expected to check returned map index. + * + */ +-struct msi_map ice_alloc_irq(struct ice_pf *pf, bool dyn_only) ++struct msi_map ice_alloc_irq(struct ice_pf *pf, bool dyn_allowed) + { + int sriov_base_vector = pf->sriov_base_vector; + struct msi_map map = { .index = -ENOENT }; + struct device *dev = ice_pf_to_dev(pf); + struct ice_irq_entry *entry; + +- entry = ice_get_irq_res(pf, dyn_only); ++ entry = ice_get_irq_res(pf, dyn_allowed); + if (!entry) + return map; + +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 1fc4805353eb5..a6a290514e548 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -587,6 +587,8 @@ ice_vsi_alloc_def(struct ice_vsi *vsi, struct ice_channel *ch) + return -ENOMEM; + } + ++ vsi->irq_dyn_alloc = pci_msix_can_alloc_dyn(vsi->back->pdev); ++ + switch (vsi->type) { + case ICE_VSI_SWITCHDEV_CTRL: + /* Setup eswitch MSIX irq handler for VSI */ +-- +2.39.5 + diff --git a/queue-6.6/ieee802154-ca8210-use-proper-setters-and-getters-for.patch b/queue-6.6/ieee802154-ca8210-use-proper-setters-and-getters-for.patch new file mode 100644 index 0000000000..a4c27f2390 --- /dev/null +++ b/queue-6.6/ieee802154-ca8210-use-proper-setters-and-getters-for.patch @@ -0,0 +1,77 @@ +From 38e34f3866228483b023eb6734d6ce8adfeb0005 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 12:55:34 +0200 +Subject: ieee802154: ca8210: Use proper setters and getters for bitwise types + +From: Andy Shevchenko + +[ Upstream commit 169b2262205836a5d1213ff44dca2962276bece1 ] + +Sparse complains that the driver doesn't respect the bitwise types: + +drivers/net/ieee802154/ca8210.c:1796:27: warning: incorrect type in assignment (different base types) +drivers/net/ieee802154/ca8210.c:1796:27: expected restricted __le16 [addressable] [assigned] [usertype] pan_id +drivers/net/ieee802154/ca8210.c:1796:27: got unsigned short [usertype] +drivers/net/ieee802154/ca8210.c:1801:25: warning: incorrect type in assignment (different base types) +drivers/net/ieee802154/ca8210.c:1801:25: expected restricted __le16 [addressable] [assigned] [usertype] pan_id +drivers/net/ieee802154/ca8210.c:1801:25: got unsigned short [usertype] +drivers/net/ieee802154/ca8210.c:1928:28: warning: incorrect type in argument 3 (different base types) +drivers/net/ieee802154/ca8210.c:1928:28: expected unsigned short [usertype] dst_pan_id +drivers/net/ieee802154/ca8210.c:1928:28: got restricted __le16 [addressable] [usertype] pan_id + +Use proper setters and getters for bitwise types. + +Note, in accordance with [1] the protocol is little endian. + +Link: https://www.cascoda.com/wp-content/uploads/2018/11/CA-8210_datasheet_0418.pdf [1] +Reviewed-by: Miquel Raynal +Reviewed-by: Linus Walleij +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/20250305105656.2133487-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Stefan Schmidt +Signed-off-by: Sasha Levin +--- + drivers/net/ieee802154/ca8210.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c +index 0a0ad3d77557f..587643a371de3 100644 +--- a/drivers/net/ieee802154/ca8210.c ++++ b/drivers/net/ieee802154/ca8210.c +@@ -1446,8 +1446,7 @@ static u8 mcps_data_request( + command.pdata.data_req.src_addr_mode = src_addr_mode; + command.pdata.data_req.dst.mode = dst_address_mode; + if (dst_address_mode != MAC_MODE_NO_ADDR) { +- command.pdata.data_req.dst.pan_id[0] = LS_BYTE(dst_pan_id); +- command.pdata.data_req.dst.pan_id[1] = MS_BYTE(dst_pan_id); ++ put_unaligned_le16(dst_pan_id, command.pdata.data_req.dst.pan_id); + if (dst_address_mode == MAC_MODE_SHORT_ADDR) { + command.pdata.data_req.dst.address[0] = LS_BYTE( + dst_addr->short_address +@@ -1795,12 +1794,12 @@ static int ca8210_skb_rx( + } + hdr.source.mode = data_ind[0]; + dev_dbg(&priv->spi->dev, "srcAddrMode: %#03x\n", hdr.source.mode); +- hdr.source.pan_id = *(u16 *)&data_ind[1]; ++ hdr.source.pan_id = cpu_to_le16(get_unaligned_le16(&data_ind[1])); + dev_dbg(&priv->spi->dev, "srcPanId: %#06x\n", hdr.source.pan_id); + memcpy(&hdr.source.extended_addr, &data_ind[3], 8); + hdr.dest.mode = data_ind[11]; + dev_dbg(&priv->spi->dev, "dstAddrMode: %#03x\n", hdr.dest.mode); +- hdr.dest.pan_id = *(u16 *)&data_ind[12]; ++ hdr.dest.pan_id = cpu_to_le16(get_unaligned_le16(&data_ind[12])); + dev_dbg(&priv->spi->dev, "dstPanId: %#06x\n", hdr.dest.pan_id); + memcpy(&hdr.dest.extended_addr, &data_ind[14], 8); + +@@ -1927,7 +1926,7 @@ static int ca8210_skb_tx( + status = mcps_data_request( + header.source.mode, + header.dest.mode, +- header.dest.pan_id, ++ le16_to_cpu(header.dest.pan_id), + (union macaddr *)&header.dest.extended_addr, + skb->len - mac_len, + &skb->data[mac_len], +-- +2.39.5 + diff --git a/queue-6.6/ima-process_measurement-needlessly-takes-inode_lock-.patch b/queue-6.6/ima-process_measurement-needlessly-takes-inode_lock-.patch new file mode 100644 index 0000000000..00a0de09d1 --- /dev/null +++ b/queue-6.6/ima-process_measurement-needlessly-takes-inode_lock-.patch @@ -0,0 +1,43 @@ +From a69acccbeec2a34f95c5d1106bbad648afd6b603 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 11:09:11 -0500 +Subject: ima: process_measurement() needlessly takes inode_lock() on MAY_READ + +From: Frederick Lawler + +[ Upstream commit 30d68cb0c37ebe2dc63aa1d46a28b9163e61caa2 ] + +On IMA policy update, if a measure rule exists in the policy, +IMA_MEASURE is set for ima_policy_flags which makes the violation_check +variable always true. Coupled with a no-action on MAY_READ for a +FILE_CHECK call, we're always taking the inode_lock(). + +This becomes a performance problem for extremely heavy read-only workloads. +Therefore, prevent this only in the case there's no action to be taken. + +Signed-off-by: Frederick Lawler +Acked-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index 98308a2bdef6e..068edb0d79f73 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -235,7 +235,9 @@ static int process_measurement(struct file *file, const struct cred *cred, + &allowed_algos); + violation_check = ((func == FILE_CHECK || func == MMAP_CHECK || + func == MMAP_CHECK_REQPROT) && +- (ima_policy_flag & IMA_MEASURE)); ++ (ima_policy_flag & IMA_MEASURE) && ++ ((action & IMA_MEASURE) || ++ (file->f_mode & FMODE_WRITE))); + if (!action && !violation_check) + return 0; + +-- +2.39.5 + diff --git a/queue-6.6/intel_th-avoid-using-deprecated-page-mapping-index-f.patch b/queue-6.6/intel_th-avoid-using-deprecated-page-mapping-index-f.patch new file mode 100644 index 0000000000..41ea48dbd6 --- /dev/null +++ b/queue-6.6/intel_th-avoid-using-deprecated-page-mapping-index-f.patch @@ -0,0 +1,145 @@ +From 2bc33a893142eb30a926cb0f5ccd210e4828b7f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Mar 2025 13:56:08 +0100 +Subject: intel_th: avoid using deprecated page->mapping, index fields + +From: Lorenzo Stoakes + +[ Upstream commit 8e553520596bbd5ce832e26e9d721e6a0c797b8b ] + +The struct page->mapping, index fields are deprecated and soon to be only +available as part of a folio. + +It is likely the intel_th code which sets page->mapping, index is was +implemented out of concern that some aspect of the page fault logic may +encounter unexpected problems should they not. + +However, the appropriate interface for inserting kernel-allocated memory is +vm_insert_page() in a VM_MIXEDMAP. By using the helper function +vmf_insert_mixed() we can do this with minimal churn in the existing fault +handler. + +By doing so, we bypass the remainder of the faulting logic. The pages are +still pinned so there is no possibility of anything unexpected being done +with the pages once established. + +It would also be reasonable to pre-map everything on fault, however to +minimise churn we retain the fault handler. + +We also eliminate all code which clears page->mapping on teardown as this +has now become unnecessary. + +The MSU code relies on faulting to function correctly, so is by definition +dependent on CONFIG_MMU. We avoid spurious reports about compilation +failure for unsupported platforms by making this requirement explicit in +Kconfig as part of this change too. + +Signed-off-by: Lorenzo Stoakes +Acked-by: Alexander Shishkin +Link: https://lore.kernel.org/r/20250331125608.60300-1-lorenzo.stoakes@oracle.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/intel_th/Kconfig | 1 + + drivers/hwtracing/intel_th/msu.c | 31 +++++++----------------------- + 2 files changed, 8 insertions(+), 24 deletions(-) + +diff --git a/drivers/hwtracing/intel_th/Kconfig b/drivers/hwtracing/intel_th/Kconfig +index 4b6359326ede9..4f7d2b6d79e29 100644 +--- a/drivers/hwtracing/intel_th/Kconfig ++++ b/drivers/hwtracing/intel_th/Kconfig +@@ -60,6 +60,7 @@ config INTEL_TH_STH + + config INTEL_TH_MSU + tristate "Intel(R) Trace Hub Memory Storage Unit" ++ depends on MMU + help + Memory Storage Unit (MSU) trace output device enables + storing STP traces to system memory. It supports single +diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c +index 9621efe0e95c4..54629458fb710 100644 +--- a/drivers/hwtracing/intel_th/msu.c ++++ b/drivers/hwtracing/intel_th/msu.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_X86 + #include +@@ -965,7 +966,6 @@ static void msc_buffer_contig_free(struct msc *msc) + for (off = 0; off < msc->nr_pages << PAGE_SHIFT; off += PAGE_SIZE) { + struct page *page = virt_to_page(msc->base + off); + +- page->mapping = NULL; + __free_page(page); + } + +@@ -1147,9 +1147,6 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win) + int i; + + for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) { +- struct page *page = msc_sg_page(sg); +- +- page->mapping = NULL; + dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE, + sg_virt(sg), sg_dma_address(sg)); + } +@@ -1584,22 +1581,10 @@ static void msc_mmap_close(struct vm_area_struct *vma) + { + struct msc_iter *iter = vma->vm_file->private_data; + struct msc *msc = iter->msc; +- unsigned long pg; + + if (!atomic_dec_and_mutex_lock(&msc->mmap_count, &msc->buf_mutex)) + return; + +- /* drop page _refcounts */ +- for (pg = 0; pg < msc->nr_pages; pg++) { +- struct page *page = msc_buffer_get_page(msc, pg); +- +- if (WARN_ON_ONCE(!page)) +- continue; +- +- if (page->mapping) +- page->mapping = NULL; +- } +- + /* last mapping -- drop user_count */ + atomic_dec(&msc->user_count); + mutex_unlock(&msc->buf_mutex); +@@ -1609,16 +1594,14 @@ static vm_fault_t msc_mmap_fault(struct vm_fault *vmf) + { + struct msc_iter *iter = vmf->vma->vm_file->private_data; + struct msc *msc = iter->msc; ++ struct page *page; + +- vmf->page = msc_buffer_get_page(msc, vmf->pgoff); +- if (!vmf->page) ++ page = msc_buffer_get_page(msc, vmf->pgoff); ++ if (!page) + return VM_FAULT_SIGBUS; + +- get_page(vmf->page); +- vmf->page->mapping = vmf->vma->vm_file->f_mapping; +- vmf->page->index = vmf->pgoff; +- +- return 0; ++ get_page(page); ++ return vmf_insert_mixed(vmf->vma, vmf->address, page_to_pfn_t(page)); + } + + static const struct vm_operations_struct msc_mmap_ops = { +@@ -1659,7 +1642,7 @@ static int intel_th_msc_mmap(struct file *file, struct vm_area_struct *vma) + atomic_dec(&msc->user_count); + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +- vm_flags_set(vma, VM_DONTEXPAND | VM_DONTCOPY); ++ vm_flags_set(vma, VM_DONTEXPAND | VM_DONTCOPY | VM_MIXEDMAP); + vma->vm_ops = &msc_mmap_ops; + return ret; + } +-- +2.39.5 + diff --git a/queue-6.6/io_uring-fdinfo-annotate-racy-sq-cq-head-tail-reads.patch b/queue-6.6/io_uring-fdinfo-annotate-racy-sq-cq-head-tail-reads.patch new file mode 100644 index 0000000000..5f40f9282b --- /dev/null +++ b/queue-6.6/io_uring-fdinfo-annotate-racy-sq-cq-head-tail-reads.patch @@ -0,0 +1,47 @@ +From 02ff60f84c0d560941d8c605246a673c91a83800 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Apr 2025 07:17:17 -0600 +Subject: io_uring/fdinfo: annotate racy sq/cq head/tail reads + +From: Jens Axboe + +[ Upstream commit f024d3a8ded0d8d2129ae123d7a5305c29ca44ce ] + +syzbot complains about the cached sq head read, and it's totally right. +But we don't need to care, it's just reading fdinfo, and reading the +CQ or SQ tail/head entries are known racy in that they are just a view +into that very instant and may of course be outdated by the time they +are reported. + +Annotate both the SQ head and CQ tail read with data_race() to avoid +this syzbot complaint. + +Link: https://lore.kernel.org/io-uring/6811f6dc.050a0220.39e3a1.0d0e.GAE@google.com/ +Reported-by: syzbot+3e77fd302e99f5af9394@syzkaller.appspotmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/fdinfo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c +index 976e9500f6518..a26cf840e623d 100644 +--- a/io_uring/fdinfo.c ++++ b/io_uring/fdinfo.c +@@ -81,11 +81,11 @@ __cold void io_uring_show_fdinfo(struct seq_file *m, struct file *f) + seq_printf(m, "SqMask:\t0x%x\n", sq_mask); + seq_printf(m, "SqHead:\t%u\n", sq_head); + seq_printf(m, "SqTail:\t%u\n", sq_tail); +- seq_printf(m, "CachedSqHead:\t%u\n", ctx->cached_sq_head); ++ seq_printf(m, "CachedSqHead:\t%u\n", data_race(ctx->cached_sq_head)); + seq_printf(m, "CqMask:\t0x%x\n", cq_mask); + seq_printf(m, "CqHead:\t%u\n", cq_head); + seq_printf(m, "CqTail:\t%u\n", cq_tail); +- seq_printf(m, "CachedCqTail:\t%u\n", ctx->cached_cq_tail); ++ seq_printf(m, "CachedCqTail:\t%u\n", data_race(ctx->cached_cq_tail)); + seq_printf(m, "SQEs:\t%u\n", sq_tail - sq_head); + sq_entries = min(sq_tail - sq_head, ctx->sq_entries); + for (i = 0; i < sq_entries; i++) { +-- +2.39.5 + diff --git a/queue-6.6/iommu-amd-pgtbl_v2-improve-error-handling.patch b/queue-6.6/iommu-amd-pgtbl_v2-improve-error-handling.patch new file mode 100644 index 0000000000..77a3f1fee6 --- /dev/null +++ b/queue-6.6/iommu-amd-pgtbl_v2-improve-error-handling.patch @@ -0,0 +1,36 @@ +From 881db972f0a37c3d4f3bf8fcece50a916f85318d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 16:23:16 +0000 +Subject: iommu/amd/pgtbl_v2: Improve error handling + +From: Vasant Hegde + +[ Upstream commit 36a1cfd497435ba5e37572fe9463bb62a7b1b984 ] + +Return -ENOMEM if v2_alloc_pte() fails to allocate memory. + +Signed-off-by: Vasant Hegde +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20250227162320.5805-4-vasant.hegde@amd.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd/io_pgtable_v2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd/io_pgtable_v2.c b/drivers/iommu/amd/io_pgtable_v2.c +index cbf0c46015125..6c0777a3c57b7 100644 +--- a/drivers/iommu/amd/io_pgtable_v2.c ++++ b/drivers/iommu/amd/io_pgtable_v2.c +@@ -259,7 +259,7 @@ static int iommu_v2_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + pte = v2_alloc_pte(pdom->nid, pdom->iop.pgd, + iova, map_size, gfp, &updated); + if (!pte) { +- ret = -EINVAL; ++ ret = -ENOMEM; + goto out; + } + +-- +2.39.5 + diff --git a/queue-6.6/ip-fib_rules-fetch-net-from-fib_rule-in-fib-46-_rule.patch b/queue-6.6/ip-fib_rules-fetch-net-from-fib_rule-in-fib-46-_rule.patch new file mode 100644 index 0000000000..1ee1a192d8 --- /dev/null +++ b/queue-6.6/ip-fib_rules-fetch-net-from-fib_rule-in-fib-46-_rule.patch @@ -0,0 +1,61 @@ +From da3e6514f4acb1e7858f7cd3ac38ab014c5f93de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 16:24:58 +0900 +Subject: ip: fib_rules: Fetch net from fib_rule in fib[46]_rule_configure(). + +From: Kuniyuki Iwashima + +[ Upstream commit 5a1ccffd30a08f5a2428cd5fbb3ab03e8eb6c66d ] + +The following patch will not set skb->sk from VRF path. + +Let's fetch net from fib_rule->fr_net instead of sock_net(skb->sk) +in fib[46]_rule_configure(). + +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Reviewed-by: Ido Schimmel +Tested-by: Ido Schimmel +Link: https://patch.msgid.link/20250207072502.87775-5-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/fib_rules.c | 4 ++-- + net/ipv6/fib6_rules.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c +index 513f475c6a534..298a9944a3d1e 100644 +--- a/net/ipv4/fib_rules.c ++++ b/net/ipv4/fib_rules.c +@@ -222,9 +222,9 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, + struct nlattr **tb, + struct netlink_ext_ack *extack) + { +- struct net *net = sock_net(skb->sk); ++ struct fib4_rule *rule4 = (struct fib4_rule *)rule; ++ struct net *net = rule->fr_net; + int err = -EINVAL; +- struct fib4_rule *rule4 = (struct fib4_rule *) rule; + + if (!inet_validate_dscp(frh->tos)) { + NL_SET_ERR_MSG(extack, +diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c +index 6eeab21512ba9..e0f0c5f8cccda 100644 +--- a/net/ipv6/fib6_rules.c ++++ b/net/ipv6/fib6_rules.c +@@ -350,9 +350,9 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, + struct nlattr **tb, + struct netlink_ext_ack *extack) + { ++ struct fib6_rule *rule6 = (struct fib6_rule *)rule; ++ struct net *net = rule->fr_net; + int err = -EINVAL; +- struct net *net = sock_net(skb->sk); +- struct fib6_rule *rule6 = (struct fib6_rule *) rule; + + if (!inet_validate_dscp(frh->tos)) { + NL_SET_ERR_MSG(extack, +-- +2.39.5 + diff --git a/queue-6.6/ipv4-fib-move-fib_valid_key_len-to-rtm_to_fib_config.patch b/queue-6.6/ipv4-fib-move-fib_valid_key_len-to-rtm_to_fib_config.patch new file mode 100644 index 0000000000..df30e9dc9d --- /dev/null +++ b/queue-6.6/ipv4-fib-move-fib_valid_key_len-to-rtm_to_fib_config.patch @@ -0,0 +1,128 @@ +From 0810e18c529d7f398fc906d6a747b6b57a060271 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 20:23:27 -0800 +Subject: ipv4: fib: Move fib_valid_key_len() to rtm_to_fib_config(). + +From: Kuniyuki Iwashima + +[ Upstream commit 254ba7e6032d3fc738050d500b0c1d8197af90ca ] + +fib_valid_key_len() is called in the beginning of fib_table_insert() +or fib_table_delete() to check if the prefix length is valid. + +fib_table_insert() and fib_table_delete() are called from 3 paths + + - ip_rt_ioctl() + - inet_rtm_newroute() / inet_rtm_delroute() + - fib_magic() + +In the first ioctl() path, rtentry_to_fib_config() checks the prefix +length with bad_mask(). Also, fib_magic() always passes the correct +prefix: 32 or ifa->ifa_prefixlen, which is already validated. + +Let's move fib_valid_key_len() to the rtnetlink path, rtm_to_fib_config(). + +While at it, 2 direct returns in rtm_to_fib_config() are changed to +goto to match other places in the same function + +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20250228042328.96624-12-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/fib_frontend.c | 18 ++++++++++++++++-- + net/ipv4/fib_trie.c | 22 ---------------------- + 2 files changed, 16 insertions(+), 24 deletions(-) + +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 90ce87ffed461..7993ff46de23c 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -829,19 +829,33 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, + } + } + ++ if (cfg->fc_dst_len > 32) { ++ NL_SET_ERR_MSG(extack, "Invalid prefix length"); ++ err = -EINVAL; ++ goto errout; ++ } ++ ++ if (cfg->fc_dst_len < 32 && (ntohl(cfg->fc_dst) << cfg->fc_dst_len)) { ++ NL_SET_ERR_MSG(extack, "Invalid prefix for given prefix length"); ++ err = -EINVAL; ++ goto errout; ++ } ++ + if (cfg->fc_nh_id) { + if (cfg->fc_oif || cfg->fc_gw_family || + cfg->fc_encap || cfg->fc_mp) { + NL_SET_ERR_MSG(extack, + "Nexthop specification and nexthop id are mutually exclusive"); +- return -EINVAL; ++ err = -EINVAL; ++ goto errout; + } + } + + if (has_gw && has_via) { + NL_SET_ERR_MSG(extack, + "Nexthop configuration can not contain both GATEWAY and VIA"); +- return -EINVAL; ++ err = -EINVAL; ++ goto errout; + } + + if (!cfg->fc_table) +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 77b97c48da5ea..fa54b36b241ac 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -1192,22 +1192,6 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp, + return 0; + } + +-static bool fib_valid_key_len(u32 key, u8 plen, struct netlink_ext_ack *extack) +-{ +- if (plen > KEYLENGTH) { +- NL_SET_ERR_MSG(extack, "Invalid prefix length"); +- return false; +- } +- +- if ((plen < KEYLENGTH) && (key << plen)) { +- NL_SET_ERR_MSG(extack, +- "Invalid prefix for given prefix length"); +- return false; +- } +- +- return true; +-} +- + static void fib_remove_alias(struct trie *t, struct key_vector *tp, + struct key_vector *l, struct fib_alias *old); + +@@ -1228,9 +1212,6 @@ int fib_table_insert(struct net *net, struct fib_table *tb, + + key = ntohl(cfg->fc_dst); + +- if (!fib_valid_key_len(key, plen, extack)) +- return -EINVAL; +- + pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen); + + fi = fib_create_info(cfg, extack); +@@ -1723,9 +1704,6 @@ int fib_table_delete(struct net *net, struct fib_table *tb, + + key = ntohl(cfg->fc_dst); + +- if (!fib_valid_key_len(key, plen, extack)) +- return -EINVAL; +- + l = fib_find_node(t, &tp, key); + if (!l) + return -ESRCH; +-- +2.39.5 + diff --git a/queue-6.6/ipv4-ip_gre-fix-set-but-not-used-warning-in-ipgre_er.patch b/queue-6.6/ipv4-ip_gre-fix-set-but-not-used-warning-in-ipgre_er.patch new file mode 100644 index 0000000000..1e0903ab26 --- /dev/null +++ b/queue-6.6/ipv4-ip_gre-fix-set-but-not-used-warning-in-ipgre_er.patch @@ -0,0 +1,78 @@ +From d43feec0438900bdf3e797c0cc53448026454937 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 22:36:54 +0100 +Subject: ipv4: ip_gre: Fix set but not used warning in ipgre_err() if + IPv4-only +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit 50f37fc2a39c4a8cc4813629b4cf239b71c6097d ] + +if CONFIG_NET_IPGRE is enabled, but CONFIG_IPV6 is disabled: + + net/ipv4/ip_gre.c: In function ‘ipgre_err’: + net/ipv4/ip_gre.c:144:22: error: variable ‘data_len’ set but not used [-Werror=unused-but-set-variable] + 144 | unsigned int data_len = 0; + | ^~~~~~~~ + +Fix this by moving all data_len processing inside the IPV6-only section +that uses its result. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202501121007.2GofXmh5-lkp@intel.com/ +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/d09113cfe2bfaca02f3dddf832fb5f48dd20958b.1738704881.git.geert@linux-m68k.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/ip_gre.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index 890c15510b421..f261e29adc7c2 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -140,7 +140,6 @@ static int ipgre_err(struct sk_buff *skb, u32 info, + const struct iphdr *iph; + const int type = icmp_hdr(skb)->type; + const int code = icmp_hdr(skb)->code; +- unsigned int data_len = 0; + struct ip_tunnel *t; + + if (tpi->proto == htons(ETH_P_TEB)) +@@ -181,7 +180,6 @@ static int ipgre_err(struct sk_buff *skb, u32 info, + case ICMP_TIME_EXCEEDED: + if (code != ICMP_EXC_TTL) + return 0; +- data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */ + break; + + case ICMP_REDIRECT: +@@ -189,10 +187,16 @@ static int ipgre_err(struct sk_buff *skb, u32 info, + } + + #if IS_ENABLED(CONFIG_IPV6) +- if (tpi->proto == htons(ETH_P_IPV6) && +- !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, +- type, data_len)) +- return 0; ++ if (tpi->proto == htons(ETH_P_IPV6)) { ++ unsigned int data_len = 0; ++ ++ if (type == ICMP_TIME_EXCEEDED) ++ data_len = icmp_hdr(skb)->un.reserved[1] * 4; /* RFC 4884 4.1 */ ++ ++ if (!ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4 + tpi->hdr_len, ++ type, data_len)) ++ return 0; ++ } + #endif + + if (t->parms.iph.daddr == 0 || +-- +2.39.5 + diff --git a/queue-6.6/ipv6-save-dontfrag-in-cork.patch b/queue-6.6/ipv6-save-dontfrag-in-cork.patch new file mode 100644 index 0000000000..707f338abe --- /dev/null +++ b/queue-6.6/ipv6-save-dontfrag-in-cork.patch @@ -0,0 +1,103 @@ +From 4422b8aef38cc85db0921e7e1895173bd38fbd31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 22:34:09 -0500 +Subject: ipv6: save dontfrag in cork + +From: Willem de Bruijn + +[ Upstream commit a18dfa9925b9ef6107ea3aa5814ca3c704d34a8a ] + +When spanning datagram construction over multiple send calls using +MSG_MORE, per datagram settings are configured on the first send. + +That is when ip(6)_setup_cork stores these settings for subsequent use +in __ip(6)_append_data and others. + +The only flag that escaped this was dontfrag. As a result, a datagram +could be constructed with df=0 on the first sendmsg, but df=1 on a +next. Which is what cmsg_ip.sh does in an upcoming MSG_MORE test in +the "diff" scenario. + +Changing datagram conditions in the middle of constructing an skb +makes this already complex code path even more convoluted. It is here +unintentional. Bring this flag in line with expected sockopt/cmsg +behavior. + +And stop passing ipc6 to __ip6_append_data, to avoid such issues +in the future. This is already the case for __ip_append_data. + +inet6_cork had a 6 byte hole, so the 1B flag has no impact. + +Signed-off-by: Willem de Bruijn +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250307033620.411611-3-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/linux/ipv6.h | 1 + + net/ipv6/ip6_output.c | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h +index af8a771a053c5..d79851c5fabd8 100644 +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -199,6 +199,7 @@ struct inet6_cork { + struct ipv6_txoptions *opt; + u8 hop_limit; + u8 tclass; ++ u8 dontfrag:1; + }; + + /* struct ipv6_pinfo - ipv6 private area */ +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index c86d5dca29df0..28777b1422404 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1452,6 +1452,7 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, + } + v6_cork->hop_limit = ipc6->hlimit; + v6_cork->tclass = ipc6->tclass; ++ v6_cork->dontfrag = ipc6->dontfrag; + if (rt->dst.flags & DST_XFRM_TUNNEL) + mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? + READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); +@@ -1485,7 +1486,7 @@ static int __ip6_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, + int len, int odd, struct sk_buff *skb), + void *from, size_t length, int transhdrlen, +- unsigned int flags, struct ipcm6_cookie *ipc6) ++ unsigned int flags) + { + struct sk_buff *skb, *skb_prev = NULL; + struct inet_cork *cork = &cork_full->base; +@@ -1541,7 +1542,7 @@ static int __ip6_append_data(struct sock *sk, + if (headersize + transhdrlen > mtu) + goto emsgsize; + +- if (cork->length + length > mtu - headersize && ipc6->dontfrag && ++ if (cork->length + length > mtu - headersize && v6_cork->dontfrag && + (sk->sk_protocol == IPPROTO_UDP || + sk->sk_protocol == IPPROTO_ICMPV6 || + sk->sk_protocol == IPPROTO_RAW)) { +@@ -1913,7 +1914,7 @@ int ip6_append_data(struct sock *sk, + + return __ip6_append_data(sk, &sk->sk_write_queue, &inet->cork, + &np->cork, sk_page_frag(sk), getfrag, +- from, length, transhdrlen, flags, ipc6); ++ from, length, transhdrlen, flags); + } + EXPORT_SYMBOL_GPL(ip6_append_data); + +@@ -2118,7 +2119,7 @@ struct sk_buff *ip6_make_skb(struct sock *sk, + err = __ip6_append_data(sk, &queue, cork, &v6_cork, + ¤t->task_frag, getfrag, from, + length + exthdrlen, transhdrlen + exthdrlen, +- flags, ipc6); ++ flags); + if (err) { + __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork); + return ERR_PTR(err); +-- +2.39.5 + diff --git a/queue-6.6/jbd2-do-not-try-to-recover-wiped-journal.patch b/queue-6.6/jbd2-do-not-try-to-recover-wiped-journal.patch new file mode 100644 index 0000000000..a6652d8233 --- /dev/null +++ b/queue-6.6/jbd2-do-not-try-to-recover-wiped-journal.patch @@ -0,0 +1,60 @@ +From 73b1a426201c592821ebc1332cede3708fb0ae05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 10:46:59 +0100 +Subject: jbd2: do not try to recover wiped journal + +From: Jan Kara + +[ Upstream commit a662f3c03b754e1f97a2781fa242e95bdb139798 ] + +If a journal is wiped, we will set journal->j_tail to 0. However if +'write' argument is not set (as it happens for read-only device or for +ocfs2), the on-disk superblock is not updated accordingly and thus +jbd2_journal_recover() cat try to recover the wiped journal. Fix the +check in jbd2_journal_recover() to use journal->j_tail for checking +empty journal instead. + +Signed-off-by: Jan Kara +Reviewed-by: Zhang Yi +Link: https://patch.msgid.link/20250206094657.20865-4-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/jbd2/recovery.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c +index 421c0d360836e..19ec325374833 100644 +--- a/fs/jbd2/recovery.c ++++ b/fs/jbd2/recovery.c +@@ -286,21 +286,22 @@ static int fc_do_one_pass(journal_t *journal, + int jbd2_journal_recover(journal_t *journal) + { + int err, err2; +- journal_superblock_t * sb; +- + struct recovery_info info; + errseq_t wb_err; + struct address_space *mapping; + + memset(&info, 0, sizeof(info)); +- sb = journal->j_superblock; + + /* + * The journal superblock's s_start field (the current log head) + * is always zero if, and only if, the journal was cleanly +- * unmounted. ++ * unmounted. We use its in-memory version j_tail here because ++ * jbd2_journal_wipe() could have updated it without updating journal ++ * superblock. + */ +- if (!sb->s_start) { ++ if (!journal->j_tail) { ++ journal_superblock_t *sb = journal->j_superblock; ++ + jbd2_debug(1, "No recovery required, last transaction %d, head block %u\n", + be32_to_cpu(sb->s_sequence), be32_to_cpu(sb->s_head)); + journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1; +-- +2.39.5 + diff --git a/queue-6.6/kbuild-fix-argument-parsing-in-scripts-config.patch b/queue-6.6/kbuild-fix-argument-parsing-in-scripts-config.patch new file mode 100644 index 0000000000..f4e84cbef4 --- /dev/null +++ b/queue-6.6/kbuild-fix-argument-parsing-in-scripts-config.patch @@ -0,0 +1,82 @@ +From 16a6c46288daa2ff243c35ad016cd36a08a68e7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Mar 2025 17:21:37 -0500 +Subject: kbuild: fix argument parsing in scripts/config + +From: Seyediman Seyedarab + +[ Upstream commit f757f6011c92b5a01db742c39149bed9e526478f ] + +The script previously assumed --file was always the first argument, +which caused issues when it appeared later. This patch updates the +parsing logic to scan all arguments to find --file, sets the config +file correctly, and resets the argument list with the remaining +commands. + +It also fixes --refresh to respect --file by passing KCONFIG_CONFIG=$FN +to make oldconfig. + +Signed-off-by: Seyediman Seyedarab +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + scripts/config | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/scripts/config b/scripts/config +index ff88e2faefd35..ea475c07de283 100755 +--- a/scripts/config ++++ b/scripts/config +@@ -32,6 +32,7 @@ commands: + Disable option directly after other option + --module-after|-M beforeopt option + Turn option into module directly after other option ++ --refresh Refresh the config using old settings + + commands can be repeated multiple times + +@@ -124,16 +125,22 @@ undef_var() { + txt_delete "^# $name is not set" "$FN" + } + +-if [ "$1" = "--file" ]; then +- FN="$2" +- if [ "$FN" = "" ] ; then +- usage ++FN=.config ++CMDS=() ++while [[ $# -gt 0 ]]; do ++ if [ "$1" = "--file" ]; then ++ if [ "$2" = "" ]; then ++ usage ++ fi ++ FN="$2" ++ shift 2 ++ else ++ CMDS+=("$1") ++ shift + fi +- shift 2 +-else +- FN=.config +-fi ++done + ++set -- "${CMDS[@]}" + if [ "$1" = "" ] ; then + usage + fi +@@ -217,9 +224,8 @@ while [ "$1" != "" ] ; do + set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A" + ;; + +- # undocumented because it ignores --file (fixme) + --refresh) +- yes "" | make oldconfig ++ yes "" | make oldconfig KCONFIG_CONFIG=$FN + ;; + + *) +-- +2.39.5 + diff --git a/queue-6.6/kconfig-merge_config-use-an-empty-file-as-initfile.patch b/queue-6.6/kconfig-merge_config-use-an-empty-file-as-initfile.patch new file mode 100644 index 0000000000..cb7bf47108 --- /dev/null +++ b/queue-6.6/kconfig-merge_config-use-an-empty-file-as-initfile.patch @@ -0,0 +1,48 @@ +From 8493c66cbeee27b1225d65c2659d89648250ac3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Mar 2025 14:28:37 +0000 +Subject: kconfig: merge_config: use an empty file as initfile + +From: Daniel Gomez + +[ Upstream commit a26fe287eed112b4e21e854f173c8918a6a8596d ] + +The scripts/kconfig/merge_config.sh script requires an existing +$INITFILE (or the $1 argument) as a base file for merging Kconfig +fragments. However, an empty $INITFILE can serve as an initial starting +point, later referenced by the KCONFIG_ALLCONFIG Makefile variable +if -m is not used. This variable can point to any configuration file +containing preset config symbols (the merged output) as stated in +Documentation/kbuild/kconfig.rst. When -m is used $INITFILE will +contain just the merge output requiring the user to run make (i.e. +KCONFIG_ALLCONFIG=<$INITFILE> make or make +olddefconfig). + +Instead of failing when `$INITFILE` is missing, create an empty file and +use it as the starting point for merges. + +Signed-off-by: Daniel Gomez +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + scripts/kconfig/merge_config.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh +index 0b7952471c18f..79c09b378be81 100755 +--- a/scripts/kconfig/merge_config.sh ++++ b/scripts/kconfig/merge_config.sh +@@ -112,8 +112,8 @@ INITFILE=$1 + shift; + + if [ ! -r "$INITFILE" ]; then +- echo "The base file '$INITFILE' does not exist. Exit." >&2 +- exit 1 ++ echo "The base file '$INITFILE' does not exist. Creating one..." >&2 ++ touch "$INITFILE" + fi + + MERGE_LIST=$* +-- +2.39.5 + diff --git a/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_get_parent_den.patch b/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_get_parent_den.patch new file mode 100644 index 0000000000..62427b905f --- /dev/null +++ b/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_get_parent_den.patch @@ -0,0 +1,41 @@ +From 9362b3f10e85a21ca5746eb6728a4b04cd9f7bcc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 15:50:19 +0100 +Subject: kernfs: Acquire kernfs_rwsem in kernfs_get_parent_dentry(). + +From: Sebastian Andrzej Siewior + +[ Upstream commit 122ab92dee80582c39740609a627198dd5b6b595 ] + +kernfs_get_parent_dentry() passes kernfs_node::parent to +kernfs_get_inode(). + +Acquire kernfs_root::kernfs_rwsem to ensure kernfs_node::parent isn't +replaced during the operation. + +Acked-by: Tejun Heo +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20250213145023.2820193-3-bigeasy@linutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/mount.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c +index c4bf26142eec9..5fda25dbbd256 100644 +--- a/fs/kernfs/mount.c ++++ b/fs/kernfs/mount.c +@@ -147,7 +147,9 @@ static struct dentry *kernfs_fh_to_parent(struct super_block *sb, + static struct dentry *kernfs_get_parent_dentry(struct dentry *child) + { + struct kernfs_node *kn = kernfs_dentry_node(child); ++ struct kernfs_root *root = kernfs_root(kn); + ++ guard(rwsem_read)(&root->kernfs_rwsem); + return d_obtain_alias(kernfs_get_inode(child->d_sb, kn->parent)); + } + +-- +2.39.5 + diff --git a/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_notify_workfn.patch b/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_notify_workfn.patch new file mode 100644 index 0000000000..5c0d8e3ead --- /dev/null +++ b/queue-6.6/kernfs-acquire-kernfs_rwsem-in-kernfs_notify_workfn.patch @@ -0,0 +1,47 @@ +From bfa4512bf9c7000a225e25d0267d41d27ca321bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 15:50:18 +0100 +Subject: kernfs: Acquire kernfs_rwsem in kernfs_notify_workfn(). + +From: Sebastian Andrzej Siewior + +[ Upstream commit 400188ae361a9d9a72a47a6cedaf2d2efcc84aa8 ] + +kernfs_notify_workfn() dereferences kernfs_node::name and passes it +later to fsnotify(). If the node is renamed then the previously observed +name pointer becomes invalid. + +Acquire kernfs_root::kernfs_rwsem to block renames of the node. + +Acked-by: Tejun Heo +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20250213145023.2820193-2-bigeasy@linutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c +index 332d08d2fe0d5..501502cd5194e 100644 +--- a/fs/kernfs/file.c ++++ b/fs/kernfs/file.c +@@ -926,6 +926,7 @@ static void kernfs_notify_workfn(struct work_struct *work) + /* kick fsnotify */ + + down_read(&root->kernfs_supers_rwsem); ++ down_read(&root->kernfs_rwsem); + list_for_each_entry(info, &kernfs_root(kn)->supers, node) { + struct kernfs_node *parent; + struct inode *p_inode = NULL; +@@ -962,6 +963,7 @@ static void kernfs_notify_workfn(struct work_struct *work) + iput(inode); + } + ++ up_read(&root->kernfs_rwsem); + up_read(&root->kernfs_supers_rwsem); + kernfs_put(kn); + goto repeat; +-- +2.39.5 + diff --git a/queue-6.6/kernfs-don-t-re-lock-kernfs_root-kernfs_rwsem-in-ker.patch b/queue-6.6/kernfs-don-t-re-lock-kernfs_root-kernfs_rwsem-in-ker.patch new file mode 100644 index 0000000000..fa02cfafba --- /dev/null +++ b/queue-6.6/kernfs-don-t-re-lock-kernfs_root-kernfs_rwsem-in-ker.patch @@ -0,0 +1,56 @@ +From e4b9fe871c485a3fd77452bc61d1adf5ce7f5167 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 15:50:21 +0100 +Subject: kernfs: Don't re-lock kernfs_root::kernfs_rwsem in + kernfs_fop_readdir(). + +From: Sebastian Andrzej Siewior + +[ Upstream commit 9aab10a0249eab4ec77c6a5e4f66442610c12a09 ] + +The readdir operation iterates over all entries and invokes dir_emit() +for every entry passing kernfs_node::name as argument. +Since the name argument can change, and become invalid, the +kernfs_root::kernfs_rwsem lock should not be dropped to prevent renames +during the operation. + +The lock drop around dir_emit() has been initially introduced in commit + 1e5289c97bba2 ("sysfs: Cache the last sysfs_dirent to improve readdir scalability v2") + +to avoid holding a global lock during a page fault. The lock drop is +wrong since the support of renames and not a big burden since the lock +is no longer global. + +Don't re-acquire kernfs_root::kernfs_rwsem while copying the name to the +userpace buffer. + +Acked-by: Tejun Heo +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20250213145023.2820193-5-bigeasy@linutronix.de +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/dir.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index b068ed32d7b32..60ea525dd205f 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -1868,10 +1868,10 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) + file->private_data = pos; + kernfs_get(pos); + +- up_read(&root->kernfs_rwsem); +- if (!dir_emit(ctx, name, len, ino, type)) ++ if (!dir_emit(ctx, name, len, ino, type)) { ++ up_read(&root->kernfs_rwsem); + return 0; +- down_read(&root->kernfs_rwsem); ++ } + } + up_read(&root->kernfs_rwsem); + file->private_data = NULL; +-- +2.39.5 + diff --git a/queue-6.6/kunit-tool-use-qboot-on-qemu-x86_64.patch b/queue-6.6/kunit-tool-use-qboot-on-qemu-x86_64.patch new file mode 100644 index 0000000000..9635eb2945 --- /dev/null +++ b/queue-6.6/kunit-tool-use-qboot-on-qemu-x86_64.patch @@ -0,0 +1,46 @@ +From bf0c06315985a849b1b2312fe8294cf1a5257249 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 11:01:42 +0000 +Subject: kunit: tool: Use qboot on QEMU x86_64 + +From: Brendan Jackman + +[ Upstream commit 08fafac4c9f289a9d9a22d838921e4b3eb22c664 ] + +As noted in [0], SeaBIOS (QEMU default) makes a mess of the terminal, +qboot does not. + +It turns out this is actually useful with kunit.py, since the user is +exposed to this issue if they set --raw_output=all. + +qboot is also faster than SeaBIOS, but it's is marginal for this +usecase. + +[0] https://lore.kernel.org/all/CA+i-1C0wYb-gZ8Mwh3WSVpbk-LF-Uo+njVbASJPe1WXDURoV7A@mail.gmail.com/ + +Both SeaBIOS and qboot are x86-specific. + +Link: https://lore.kernel.org/r/20250124-kunit-qboot-v1-1-815e4d4c6f7c@google.com +Signed-off-by: Brendan Jackman +Reviewed-by: David Gow +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/kunit/qemu_configs/x86_64.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/kunit/qemu_configs/x86_64.py b/tools/testing/kunit/qemu_configs/x86_64.py +index dc79490768630..4a6bf4e048f5b 100644 +--- a/tools/testing/kunit/qemu_configs/x86_64.py ++++ b/tools/testing/kunit/qemu_configs/x86_64.py +@@ -7,4 +7,6 @@ CONFIG_SERIAL_8250_CONSOLE=y''', + qemu_arch='x86_64', + kernel_path='arch/x86/boot/bzImage', + kernel_command_line='console=ttyS0', +- extra_qemu_params=[]) ++ # qboot is faster than SeaBIOS and doesn't mess up ++ # the terminal. ++ extra_qemu_params=['-bios', 'qboot.rom']) +-- +2.39.5 + diff --git a/queue-6.6/leds-pwm-multicolor-add-check-for-fwnode_property_re.patch b/queue-6.6/leds-pwm-multicolor-add-check-for-fwnode_property_re.patch new file mode 100644 index 0000000000..1c336a647d --- /dev/null +++ b/queue-6.6/leds-pwm-multicolor-add-check-for-fwnode_property_re.patch @@ -0,0 +1,40 @@ +From 0917f6ec6eae8c48147ad700f2586e493aaa8288 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 23 Feb 2025 20:14:59 +0800 +Subject: leds: pwm-multicolor: Add check for fwnode_property_read_u32 + +From: Yuanjun Gong + +[ Upstream commit 6d91124e7edc109f114b1afe6d00d85d0d0ac174 ] + +Add a check to the return value of fwnode_property_read_u32() +in case it fails. + +Signed-off-by: Yuanjun Gong +Link: https://lore.kernel.org/r/20250223121459.2889484-1-ruc_gongyuanjun@163.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/rgb/leds-pwm-multicolor.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/leds/rgb/leds-pwm-multicolor.c b/drivers/leds/rgb/leds-pwm-multicolor.c +index e1a81e0109e8a..c0aa34b1d0e2d 100644 +--- a/drivers/leds/rgb/leds-pwm-multicolor.c ++++ b/drivers/leds/rgb/leds-pwm-multicolor.c +@@ -135,8 +135,11 @@ static int led_pwm_mc_probe(struct platform_device *pdev) + + /* init the multicolor's LED class device */ + cdev = &priv->mc_cdev.led_cdev; +- fwnode_property_read_u32(mcnode, "max-brightness", ++ ret = fwnode_property_read_u32(mcnode, "max-brightness", + &cdev->max_brightness); ++ if (ret) ++ goto release_mcnode; ++ + cdev->flags = LED_CORE_SUSPENDRESUME; + cdev->brightness_set_blocking = led_pwm_mc_set; + +-- +2.39.5 + diff --git a/queue-6.6/leds-trigger-netdev-configure-led-blink-interval-for.patch b/queue-6.6/leds-trigger-netdev-configure-led-blink-interval-for.patch new file mode 100644 index 0000000000..151f7a77c1 --- /dev/null +++ b/queue-6.6/leds-trigger-netdev-configure-led-blink-interval-for.patch @@ -0,0 +1,84 @@ +From fe04ea820522af4d48940761d43147cba78b3094 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Jan 2025 12:36:53 +0100 +Subject: leds: trigger: netdev: Configure LED blink interval for HW offload + +From: Marek Vasut + +[ Upstream commit c629c972b310af41e9e072febb6dae9a299edde6 ] + +In case a PHY LED implements .blink_set callback to set LED blink +interval, call it even if .hw_control is already set, as that LED +blink interval likely controls the blink rate of that HW offloaded +LED. For PHY LEDs, that can be their activity blinking interval. + +The software blinking is not affected by this change. + +With this change, the LED interval setting looks something like this: +$ echo netdev > /sys/class/leds/led:green:lan/trigger +$ echo 1 > /sys/class/leds/led:green:lan/brightness +$ echo 250 > /sys/class/leds/led:green:lan/interval + +Signed-off-by: Marek Vasut +Link: https://lore.kernel.org/r/20250120113740.91807-1-marex@denx.de +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/trigger/ledtrig-netdev.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c +index 79719fc8a08fb..f8912fa60c498 100644 +--- a/drivers/leds/trigger/ledtrig-netdev.c ++++ b/drivers/leds/trigger/ledtrig-netdev.c +@@ -54,6 +54,7 @@ struct led_netdev_data { + unsigned int last_activity; + + unsigned long mode; ++ unsigned long blink_delay; + int link_speed; + u8 duplex; + +@@ -69,6 +70,10 @@ static void set_baseline_state(struct led_netdev_data *trigger_data) + /* Already validated, hw control is possible with the requested mode */ + if (trigger_data->hw_control) { + led_cdev->hw_control_set(led_cdev, trigger_data->mode); ++ if (led_cdev->blink_set) { ++ led_cdev->blink_set(led_cdev, &trigger_data->blink_delay, ++ &trigger_data->blink_delay); ++ } + + return; + } +@@ -386,10 +391,11 @@ static ssize_t interval_store(struct device *dev, + size_t size) + { + struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); ++ struct led_classdev *led_cdev = trigger_data->led_cdev; + unsigned long value; + int ret; + +- if (trigger_data->hw_control) ++ if (trigger_data->hw_control && !led_cdev->blink_set) + return -EINVAL; + + ret = kstrtoul(buf, 0, &value); +@@ -398,9 +404,13 @@ static ssize_t interval_store(struct device *dev, + + /* impose some basic bounds on the timer interval */ + if (value >= 5 && value <= 10000) { +- cancel_delayed_work_sync(&trigger_data->work); ++ if (trigger_data->hw_control) { ++ trigger_data->blink_delay = value; ++ } else { ++ cancel_delayed_work_sync(&trigger_data->work); + +- atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); ++ atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); ++ } + set_baseline_state(trigger_data); /* resets timer */ + } + +-- +2.39.5 + diff --git a/queue-6.6/libbpf-fix-ldx-stx-st-co-re-relocation-size-adjustme.patch b/queue-6.6/libbpf-fix-ldx-stx-st-co-re-relocation-size-adjustme.patch new file mode 100644 index 0000000000..2f857031aa --- /dev/null +++ b/queue-6.6/libbpf-fix-ldx-stx-st-co-re-relocation-size-adjustme.patch @@ -0,0 +1,92 @@ +From dfee39a7da12f80d599393f6cd36f1d96fddd66a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 17:48:08 -0800 +Subject: libbpf: fix LDX/STX/ST CO-RE relocation size adjustment logic + +From: Andrii Nakryiko + +[ Upstream commit 06096d19ee3897a7e70922580159607fe315da7a ] + +Libbpf has a somewhat obscure feature of automatically adjusting the +"size" of LDX/STX/ST instruction (memory store and load instructions), +based on originally recorded access size (u8, u16, u32, or u64) and the +actual size of the field on target kernel. This is meant to facilitate +using BPF CO-RE on 32-bit architectures (pointers are always 64-bit in +BPF, but host kernel's BTF will have it as 32-bit type), as well as +generally supporting safe type changes (unsigned integer type changes +can be transparently "relocated"). + +One issue that surfaced only now, 5 years after this logic was +implemented, is how this all works when dealing with fields that are +arrays. This isn't all that easy and straightforward to hit (see +selftests that reproduce this condition), but one of sched_ext BPF +programs did hit it with innocent looking loop. + +Long story short, libbpf used to calculate entire array size, instead of +making sure to only calculate array's element size. But it's the element +that is loaded by LDX/STX/ST instructions (1, 2, 4, or 8 bytes), so +that's what libbpf should check. This patch adjusts the logic for +arrays and fixed the issue. + +Reported-by: Emil Tsalapatis +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20250207014809.1573841-1-andrii@kernel.org +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/relo_core.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c +index 63a4d5ad12d1a..26cde1b27174b 100644 +--- a/tools/lib/bpf/relo_core.c ++++ b/tools/lib/bpf/relo_core.c +@@ -683,7 +683,7 @@ static int bpf_core_calc_field_relo(const char *prog_name, + { + const struct bpf_core_accessor *acc; + const struct btf_type *t; +- __u32 byte_off, byte_sz, bit_off, bit_sz, field_type_id; ++ __u32 byte_off, byte_sz, bit_off, bit_sz, field_type_id, elem_id; + const struct btf_member *m; + const struct btf_type *mt; + bool bitfield; +@@ -706,8 +706,14 @@ static int bpf_core_calc_field_relo(const char *prog_name, + if (!acc->name) { + if (relo->kind == BPF_CORE_FIELD_BYTE_OFFSET) { + *val = spec->bit_offset / 8; +- /* remember field size for load/store mem size */ +- sz = btf__resolve_size(spec->btf, acc->type_id); ++ /* remember field size for load/store mem size; ++ * note, for arrays we care about individual element ++ * sizes, not the overall array size ++ */ ++ t = skip_mods_and_typedefs(spec->btf, acc->type_id, &elem_id); ++ while (btf_is_array(t)) ++ t = skip_mods_and_typedefs(spec->btf, btf_array(t)->type, &elem_id); ++ sz = btf__resolve_size(spec->btf, elem_id); + if (sz < 0) + return -EINVAL; + *field_sz = sz; +@@ -767,7 +773,17 @@ static int bpf_core_calc_field_relo(const char *prog_name, + case BPF_CORE_FIELD_BYTE_OFFSET: + *val = byte_off; + if (!bitfield) { +- *field_sz = byte_sz; ++ /* remember field size for load/store mem size; ++ * note, for arrays we care about individual element ++ * sizes, not the overall array size ++ */ ++ t = skip_mods_and_typedefs(spec->btf, field_type_id, &elem_id); ++ while (btf_is_array(t)) ++ t = skip_mods_and_typedefs(spec->btf, btf_array(t)->type, &elem_id); ++ sz = btf__resolve_size(spec->btf, elem_id); ++ if (sz < 0) ++ return -EINVAL; ++ *field_sz = sz; + *type_id = field_type_id; + } + break; +-- +2.39.5 + diff --git a/queue-6.6/libbpf-fix-out-of-bound-read.patch b/queue-6.6/libbpf-fix-out-of-bound-read.patch new file mode 100644 index 0000000000..bcf5dc018e --- /dev/null +++ b/queue-6.6/libbpf-fix-out-of-bound-read.patch @@ -0,0 +1,43 @@ +From 957df4c609ecb84d47da9376de4f79257a4492be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Feb 2025 02:31:11 +0530 +Subject: libbpf: Fix out-of-bound read + +From: Nandakumar Edamana + +[ Upstream commit 236d3910117e9f97ebf75e511d8bcc950f1a4e5f ] + +In `set_kcfg_value_str`, an untrusted string is accessed with the assumption +that it will be at least two characters long due to the presence of checks for +opening and closing quotes. But the check for the closing quote +(value[len - 1] != '"') misses the fact that it could be checking the opening +quote itself in case of an invalid input that consists of just the opening +quote. + +This commit adds an explicit check to make sure the string is at least two +characters long. + +Signed-off-by: Nandakumar Edamana +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20250221210110.3182084-1-nandakumar@nandakumar.co.in +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/libbpf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c +index 2fad178949efe..fa2abe56e845d 100644 +--- a/tools/lib/bpf/libbpf.c ++++ b/tools/lib/bpf/libbpf.c +@@ -1802,7 +1802,7 @@ static int set_kcfg_value_str(struct extern_desc *ext, char *ext_val, + } + + len = strlen(value); +- if (value[len - 1] != '"') { ++ if (len < 2 || value[len - 1] != '"') { + pr_warn("extern (kcfg) '%s': invalid string config '%s'\n", + ext->name, value); + return -EINVAL; +-- +2.39.5 + diff --git a/queue-6.6/libnvdimm-labels-fix-divide-error-in-nd_label_data_i.patch b/queue-6.6/libnvdimm-labels-fix-divide-error-in-nd_label_data_i.patch new file mode 100644 index 0000000000..f04e3dcec2 --- /dev/null +++ b/queue-6.6/libnvdimm-labels-fix-divide-error-in-nd_label_data_i.patch @@ -0,0 +1,64 @@ +From a94ca19da6c3b5cf36d2862272e26d51b54406b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:22:22 +0100 +Subject: libnvdimm/labels: Fix divide error in nd_label_data_init() + +From: Robert Richter + +[ Upstream commit ef1d3455bbc1922f94a91ed58d3d7db440652959 ] + +If a faulty CXL memory device returns a broken zero LSA size in its +memory device information (Identify Memory Device (Opcode 4000h), CXL +spec. 3.1, 8.2.9.9.1.1), a divide error occurs in the libnvdimm +driver: + + Oops: divide error: 0000 [#1] PREEMPT SMP NOPTI + RIP: 0010:nd_label_data_init+0x10e/0x800 [libnvdimm] + +Code and flow: + +1) CXL Command 4000h returns LSA size = 0 +2) config_size is assigned to zero LSA size (CXL pmem driver): + +drivers/cxl/pmem.c: .config_size = mds->lsa_size, + +3) max_xfer is set to zero (nvdimm driver): + +drivers/nvdimm/label.c: max_xfer = min_t(size_t, ndd->nsarea.max_xfer, config_size); + +4) A subsequent DIV_ROUND_UP() causes a division by zero: + +drivers/nvdimm/label.c: /* Make our initial read size a multiple of max_xfer size */ +drivers/nvdimm/label.c: read_size = min(DIV_ROUND_UP(read_size, max_xfer) * max_xfer, +drivers/nvdimm/label.c- config_size); + +Fix this by checking the config size parameter by extending an +existing check. + +Signed-off-by: Robert Richter +Reviewed-by: Pankaj Gupta +Reviewed-by: Ira Weiny +Link: https://patch.msgid.link/20250320112223.608320-1-rrichter@amd.com +Signed-off-by: Ira Weiny +Signed-off-by: Sasha Levin +--- + drivers/nvdimm/label.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c +index 082253a3a9560..04f4a049599a1 100644 +--- a/drivers/nvdimm/label.c ++++ b/drivers/nvdimm/label.c +@@ -442,7 +442,8 @@ int nd_label_data_init(struct nvdimm_drvdata *ndd) + if (ndd->data) + return 0; + +- if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0) { ++ if (ndd->nsarea.status || ndd->nsarea.max_xfer == 0 || ++ ndd->nsarea.config_size == 0) { + dev_dbg(ndd->dev, "failed to init config data area: (%u:%u)\n", + ndd->nsarea.max_xfer, ndd->nsarea.config_size); + return -ENXIO; +-- +2.39.5 + diff --git a/queue-6.6/lockdep-fix-wait-context-check-on-softirq-for-preemp.patch b/queue-6.6/lockdep-fix-wait-context-check-on-softirq-for-preemp.patch new file mode 100644 index 0000000000..d076f13f17 --- /dev/null +++ b/queue-6.6/lockdep-fix-wait-context-check-on-softirq-for-preemp.patch @@ -0,0 +1,99 @@ +From 328689d911b240a57d627be94f8880f2bd6181d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Mar 2025 07:33:22 -0700 +Subject: lockdep: Fix wait context check on softirq for PREEMPT_RT + +From: Ryo Takakura + +[ Upstream commit 61c39d8c83e2077f33e0a2c8980a76a7f323f0ce ] + +Since: + + 0c1d7a2c2d32 ("lockdep: Remove softirq accounting on PREEMPT_RT.") + +the wait context test for mutex usage within "in softirq context" fails +as it references @softirq_context: + + | wait context tests | + -------------------------------------------------------------------------- + | rcu | raw | spin |mutex | + -------------------------------------------------------------------------- + in hardirq context: ok | ok | ok | ok | + in hardirq context (not threaded): ok | ok | ok | ok | + in softirq context: ok | ok | ok |FAILED| + +As a fix, add lockdep map for BH disabled section. This fixes the +issue by letting us catch cases when local_bh_disable() gets called +with preemption disabled where local_lock doesn't get acquired. +In the case of "in softirq context" selftest, local_bh_disable() was +being called with preemption disable as it's early in the boot. + +[ boqun: Move the lockdep annotations into __local_bh_*() to avoid false + positives because of unpaired local_bh_disable() reported by + Borislav Petkov and Peter Zijlstra, and make bh_lock_map + only exist for PREEMPT_RT. ] + +[ mingo: Restored authorship and improved the bh_lock_map definition. ] + +Signed-off-by: Ryo Takakura +Signed-off-by: Boqun Feng +Signed-off-by: Ingo Molnar +Link: https://lore.kernel.org/r/20250321143322.79651-1-boqun.feng@gmail.com +Signed-off-by: Sasha Levin +--- + kernel/softirq.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/kernel/softirq.c b/kernel/softirq.c +index f24d80cf20bd3..d9e37f3fa1303 100644 +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -125,6 +125,18 @@ static DEFINE_PER_CPU(struct softirq_ctrl, softirq_ctrl) = { + .lock = INIT_LOCAL_LOCK(softirq_ctrl.lock), + }; + ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++static struct lock_class_key bh_lock_key; ++struct lockdep_map bh_lock_map = { ++ .name = "local_bh", ++ .key = &bh_lock_key, ++ .wait_type_outer = LD_WAIT_FREE, ++ .wait_type_inner = LD_WAIT_CONFIG, /* PREEMPT_RT makes BH preemptible. */ ++ .lock_type = LD_LOCK_PERCPU, ++}; ++EXPORT_SYMBOL_GPL(bh_lock_map); ++#endif ++ + /** + * local_bh_blocked() - Check for idle whether BH processing is blocked + * +@@ -147,6 +159,8 @@ void __local_bh_disable_ip(unsigned long ip, unsigned int cnt) + + WARN_ON_ONCE(in_hardirq()); + ++ lock_map_acquire_read(&bh_lock_map); ++ + /* First entry of a task into a BH disabled section? */ + if (!current->softirq_disable_cnt) { + if (preemptible()) { +@@ -210,6 +224,8 @@ void __local_bh_enable_ip(unsigned long ip, unsigned int cnt) + WARN_ON_ONCE(in_hardirq()); + lockdep_assert_irqs_enabled(); + ++ lock_map_release(&bh_lock_map); ++ + local_irq_save(flags); + curcnt = __this_cpu_read(softirq_ctrl.cnt); + +@@ -260,6 +276,8 @@ static inline void ksoftirqd_run_begin(void) + /* Counterpart to ksoftirqd_run_begin() */ + static inline void ksoftirqd_run_end(void) + { ++ /* pairs with the lock_map_acquire_read() in ksoftirqd_run_begin() */ ++ lock_map_release(&bh_lock_map); + __local_bh_enable(SOFTIRQ_OFFSET, true); + WARN_ON_ONCE(in_interrupt()); + local_irq_enable(); +-- +2.39.5 + diff --git a/queue-6.6/mailbox-pcc-use-acpi_os_ioremap-instead-of-ioremap.patch b/queue-6.6/mailbox-pcc-use-acpi_os_ioremap-instead-of-ioremap.patch new file mode 100644 index 0000000000..7000cf59ae --- /dev/null +++ b/queue-6.6/mailbox-pcc-use-acpi_os_ioremap-instead-of-ioremap.patch @@ -0,0 +1,49 @@ +From b2d10ebde3b5983e43f160003b08f1ba6cfca252 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Mar 2025 15:28:51 +0000 +Subject: mailbox: pcc: Use acpi_os_ioremap() instead of ioremap() + +From: Sudeep Holla + +[ Upstream commit d181acea5b864e91f38f5771b8961215ce5017ae ] + +The Platform Communication Channel (PCC) mailbox driver currently uses +ioremap() to map channel shared memory regions. However it is preferred +to use acpi_os_ioremap(), which is mapping function specific to EFI/ACPI +defined memory regions. It ensures that the correct memory attributes +are applied when mapping ACPI-provided regions. + +While at it, also add checks for handling any errors with the mapping. + +Acked-by: Huisong Li +Tested-by: Huisong Li +Tested-by: Adam Young +Signed-off-by: Sudeep Holla +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + drivers/mailbox/pcc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index f8215a8f656a4..49254d99a8ad6 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -419,8 +419,12 @@ int pcc_mbox_ioremap(struct mbox_chan *chan) + return -1; + pchan_info = chan->con_priv; + pcc_mbox_chan = &pchan_info->chan; +- pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr, +- pcc_mbox_chan->shmem_size); ++ ++ pcc_mbox_chan->shmem = acpi_os_ioremap(pcc_mbox_chan->shmem_base_addr, ++ pcc_mbox_chan->shmem_size); ++ if (!pcc_mbox_chan->shmem) ++ return -ENXIO; ++ + return 0; + } + EXPORT_SYMBOL_GPL(pcc_mbox_ioremap); +-- +2.39.5 + diff --git a/queue-6.6/mailbox-use-error-ret-code-of-of_parse_phandle_with_.patch b/queue-6.6/mailbox-use-error-ret-code-of-of_parse_phandle_with_.patch new file mode 100644 index 0000000000..e6addf4650 --- /dev/null +++ b/queue-6.6/mailbox-use-error-ret-code-of-of_parse_phandle_with_.patch @@ -0,0 +1,45 @@ +From 6b58d890c89293bb0e388cf459b2e94f2610903a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 08:27:13 +0000 +Subject: mailbox: use error ret code of of_parse_phandle_with_args() + +From: Tudor Ambarus + +[ Upstream commit 24fdd5074b205cfb0ef4cd0751a2d03031455929 ] + +In case of error, of_parse_phandle_with_args() returns -EINVAL when the +passed index is negative, or -ENOENT when the index is for an empty +phandle. The mailbox core overwrote the error return code with a less +precise -ENODEV. Use the error returned code from +of_parse_phandle_with_args(). + +Signed-off-by: Tudor Ambarus +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + drivers/mailbox/mailbox.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index ebff3baf30451..f13d705f7861a 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -415,11 +415,12 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) + + mutex_lock(&con_mutex); + +- if (of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", index, &spec)) { ++ ret = of_parse_phandle_with_args(dev->of_node, "mboxes", "#mbox-cells", ++ index, &spec); ++ if (ret) { + dev_dbg(dev, "%s: can't parse \"mboxes\" property\n", __func__); + mutex_unlock(&con_mutex); +- return ERR_PTR(-ENODEV); ++ return ERR_PTR(ret); + } + + chan = ERR_PTR(-EPROBE_DEFER); +-- +2.39.5 + diff --git a/queue-6.6/media-adv7180-disable-test-pattern-control-on-adv718.patch b/queue-6.6/media-adv7180-disable-test-pattern-control-on-adv718.patch new file mode 100644 index 0000000000..4a980ca67c --- /dev/null +++ b/queue-6.6/media-adv7180-disable-test-pattern-control-on-adv718.patch @@ -0,0 +1,131 @@ +From 93ff09f9c3a3b78319bec80296ce735468804537 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Feb 2025 00:09:07 +0100 +Subject: media: adv7180: Disable test-pattern control on adv7180 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Söderlund + +[ Upstream commit a980bc5f56b0292336e408f657f79e574e8067c0 ] + +The register that enables selecting a test-pattern to be outputted in +free-run mode (FREE_RUN_PAT_SEL[2:0]) is only available on adv7280 based +devices, not the adv7180 based ones. + +Add a flag to mark devices that are capable of generating test-patterns, +and those that are not. And only register the control on supported +devices. + +Signed-off-by: Niklas Söderlund +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/adv7180.c | 34 ++++++++++++++++++++++------------ + 1 file changed, 22 insertions(+), 12 deletions(-) + +diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c +index 99ba925e8ec8e..114ac0c263fb2 100644 +--- a/drivers/media/i2c/adv7180.c ++++ b/drivers/media/i2c/adv7180.c +@@ -194,6 +194,7 @@ struct adv7180_state; + #define ADV7180_FLAG_V2 BIT(1) + #define ADV7180_FLAG_MIPI_CSI2 BIT(2) + #define ADV7180_FLAG_I2P BIT(3) ++#define ADV7180_FLAG_TEST_PATTERN BIT(4) + + struct adv7180_chip_info { + unsigned int flags; +@@ -673,11 +674,15 @@ static int adv7180_init_controls(struct adv7180_state *state) + ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF); + v4l2_ctrl_new_custom(&state->ctrl_hdl, &adv7180_ctrl_fast_switch, NULL); + +- v4l2_ctrl_new_std_menu_items(&state->ctrl_hdl, &adv7180_ctrl_ops, +- V4L2_CID_TEST_PATTERN, +- ARRAY_SIZE(test_pattern_menu) - 1, +- 0, ARRAY_SIZE(test_pattern_menu) - 1, +- test_pattern_menu); ++ if (state->chip_info->flags & ADV7180_FLAG_TEST_PATTERN) { ++ v4l2_ctrl_new_std_menu_items(&state->ctrl_hdl, ++ &adv7180_ctrl_ops, ++ V4L2_CID_TEST_PATTERN, ++ ARRAY_SIZE(test_pattern_menu) - 1, ++ 0, ++ ARRAY_SIZE(test_pattern_menu) - 1, ++ test_pattern_menu); ++ } + + state->sd.ctrl_handler = &state->ctrl_hdl; + if (state->ctrl_hdl.error) { +@@ -1209,7 +1214,7 @@ static const struct adv7180_chip_info adv7182_info = { + }; + + static const struct adv7180_chip_info adv7280_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P | ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN3) | +@@ -1223,7 +1228,8 @@ static const struct adv7180_chip_info adv7280_info = { + }; + + static const struct adv7180_chip_info adv7280_m_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P | ++ ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN3) | +@@ -1244,7 +1250,8 @@ static const struct adv7180_chip_info adv7280_m_info = { + }; + + static const struct adv7180_chip_info adv7281_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ++ ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN7) | +@@ -1259,7 +1266,8 @@ static const struct adv7180_chip_info adv7281_info = { + }; + + static const struct adv7180_chip_info adv7281_m_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ++ ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN3) | +@@ -1279,7 +1287,8 @@ static const struct adv7180_chip_info adv7281_m_info = { + }; + + static const struct adv7180_chip_info adv7281_ma_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ++ ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN3) | +@@ -1304,7 +1313,7 @@ static const struct adv7180_chip_info adv7281_ma_info = { + }; + + static const struct adv7180_chip_info adv7282_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P | ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN7) | +@@ -1319,7 +1328,8 @@ static const struct adv7180_chip_info adv7282_info = { + }; + + static const struct adv7180_chip_info adv7282_m_info = { +- .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P, ++ .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P | ++ ADV7180_FLAG_TEST_PATTERN, + .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) | + BIT(ADV7182_INPUT_CVBS_AIN2) | + BIT(ADV7182_INPUT_CVBS_AIN3) | +-- +2.39.5 + diff --git a/queue-6.6/media-c8sectpfe-call-of_node_put-i2c_bus-only-once-i.patch b/queue-6.6/media-c8sectpfe-call-of_node_put-i2c_bus-only-once-i.patch new file mode 100644 index 0000000000..15006f043b --- /dev/null +++ b/queue-6.6/media-c8sectpfe-call-of_node_put-i2c_bus-only-once-i.patch @@ -0,0 +1,45 @@ +From f54bbd22d5a6cbc723de6bec287dff2e7508de18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 4 Oct 2024 15:50:15 +0200 +Subject: media: c8sectpfe: Call of_node_put(i2c_bus) only once in + c8sectpfe_probe() + +From: Markus Elfring + +[ Upstream commit b773530a34df0687020520015057075f8b7b4ac4 ] + +An of_node_put(i2c_bus) call was immediately used after a pointer check +for an of_find_i2c_adapter_by_node() call in this function implementation. +Thus call such a function only once instead directly before the check. + +This issue was transformed by using the Coccinelle software. + +Signed-off-by: Markus Elfring +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +index 5dc1f908b49bd..9aa484126a0dd 100644 +--- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c ++++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c +@@ -806,13 +806,12 @@ static int c8sectpfe_probe(struct platform_device *pdev) + } + tsin->i2c_adapter = + of_find_i2c_adapter_by_node(i2c_bus); ++ of_node_put(i2c_bus); + if (!tsin->i2c_adapter) { + dev_err(&pdev->dev, "No i2c adapter found\n"); +- of_node_put(i2c_bus); + ret = -ENODEV; + goto err_node_put; + } +- of_node_put(i2c_bus); + + /* Acquire reset GPIO and activate it */ + tsin->rst_gpio = devm_fwnode_gpiod_get(dev, +-- +2.39.5 + diff --git a/queue-6.6/media-cx231xx-set-device_caps-for-417.patch b/queue-6.6/media-cx231xx-set-device_caps-for-417.patch new file mode 100644 index 0000000000..c57e28cb3b --- /dev/null +++ b/queue-6.6/media-cx231xx-set-device_caps-for-417.patch @@ -0,0 +1,40 @@ +From deaaf8d46d822b3c1b7c7d771066cdf095cfd588 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 14:13:24 +0100 +Subject: media: cx231xx: set device_caps for 417 + +From: Hans Verkuil + +[ Upstream commit a79efc44b51432490538a55b9753a721f7d3ea42 ] + +The video_device for the MPEG encoder did not set device_caps. + +Add this, otherwise the video device can't be registered (you get a +WARN_ON instead). + +Not seen before since currently 417 support is disabled, but I found +this while experimenting with it. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/usb/cx231xx/cx231xx-417.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c +index c5e21785fafe2..02343e88cc618 100644 +--- a/drivers/media/usb/cx231xx/cx231xx-417.c ++++ b/drivers/media/usb/cx231xx/cx231xx-417.c +@@ -1722,6 +1722,8 @@ static void cx231xx_video_dev_init( + vfd->lock = &dev->lock; + vfd->release = video_device_release_empty; + vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl; ++ vfd->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | ++ V4L2_CAP_VIDEO_CAPTURE; + video_set_drvdata(vfd, dev); + if (dev->tuner_type == TUNER_ABSENT) { + v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); +-- +2.39.5 + diff --git a/queue-6.6/media-i2c-imx219-correct-the-minimum-vblanking-value.patch b/queue-6.6/media-i2c-imx219-correct-the-minimum-vblanking-value.patch new file mode 100644 index 0000000000..b8386015a5 --- /dev/null +++ b/queue-6.6/media-i2c-imx219-correct-the-minimum-vblanking-value.patch @@ -0,0 +1,40 @@ +From d242003ed16e0c313c153c998814b740edf58680 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 12:34:36 +0530 +Subject: media: i2c: imx219: Correct the minimum vblanking value + +From: David Plowman + +[ Upstream commit e3b82d49bf676f3c873e642038765eac32ab6d39 ] + +The datasheet for this sensor documents the minimum vblanking as being +32 lines. It does fix some problems with occasional black lines at the +bottom of images (tested on Raspberry Pi). + +Signed-off-by: David Plowman +Reviewed-by: Jacopo Mondi +Reviewed-by: Dave Stevenson +Signed-off-by: Jai Luthra +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/imx219.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c +index a14e571dc62bc..a3d5a8a7c660b 100644 +--- a/drivers/media/i2c/imx219.c ++++ b/drivers/media/i2c/imx219.c +@@ -77,7 +77,7 @@ + #define IMX219_VTS_30FPS_640x480 0x06e3 + #define IMX219_VTS_MAX 0xffff + +-#define IMX219_VBLANK_MIN 4 ++#define IMX219_VBLANK_MIN 32 + + /*Frame Length Line*/ + #define IMX219_FLL_MIN 0x08a6 +-- +2.39.5 + diff --git a/queue-6.6/media-qcom-camss-csid-only-add-tpg-v4l2-ctrl-if-tpg-.patch b/queue-6.6/media-qcom-camss-csid-only-add-tpg-v4l2-ctrl-if-tpg-.patch new file mode 100644 index 0000000000..67ab87dae6 --- /dev/null +++ b/queue-6.6/media-qcom-camss-csid-only-add-tpg-v4l2-ctrl-if-tpg-.patch @@ -0,0 +1,139 @@ +From 026c29845a39a8f03bca64cbf1b148e397da3b04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 10:01:28 +0530 +Subject: media: qcom: camss: csid: Only add TPG v4l2 ctrl if TPG hardware is + available + +From: Depeng Shao + +[ Upstream commit 2f1361f862a68063f37362f1beb400e78e289581 ] + +There is no CSID TPG on some SoCs, so the v4l2 ctrl in CSID driver +shouldn't be registered. Checking the supported TPG modes to indicate +if the TPG hardware exists or not and only registering v4l2 ctrl for +CSID only when the TPG hardware is present. + +Signed-off-by: Depeng Shao +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + .../media/platform/qcom/camss/camss-csid.c | 60 +++++++++++-------- + 1 file changed, 35 insertions(+), 25 deletions(-) + +diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c +index 6360314f04a63..b90e2e690f3aa 100644 +--- a/drivers/media/platform/qcom/camss/camss-csid.c ++++ b/drivers/media/platform/qcom/camss/camss-csid.c +@@ -239,11 +239,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable) + int ret; + + if (enable) { +- ret = v4l2_ctrl_handler_setup(&csid->ctrls); +- if (ret < 0) { +- dev_err(csid->camss->dev, +- "could not sync v4l2 controls: %d\n", ret); +- return ret; ++ if (csid->testgen.nmodes != CSID_PAYLOAD_MODE_DISABLED) { ++ ret = v4l2_ctrl_handler_setup(&csid->ctrls); ++ if (ret < 0) { ++ dev_err(csid->camss->dev, ++ "could not sync v4l2 controls: %d\n", ret); ++ return ret; ++ } + } + + if (!csid->testgen.enabled && +@@ -318,7 +320,8 @@ static void csid_try_format(struct csid_device *csid, + break; + + case MSM_CSID_PAD_SRC: +- if (csid->testgen_mode->cur.val == 0) { ++ if (csid->testgen.nmodes == CSID_PAYLOAD_MODE_DISABLED || ++ csid->testgen_mode->cur.val == 0) { + /* Test generator is disabled, */ + /* keep pad formats in sync */ + u32 code = fmt->code; +@@ -368,7 +371,8 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd, + + code->code = csid->formats[code->index].code; + } else { +- if (csid->testgen_mode->cur.val == 0) { ++ if (csid->testgen.nmodes == CSID_PAYLOAD_MODE_DISABLED || ++ csid->testgen_mode->cur.val == 0) { + struct v4l2_mbus_framefmt *sink_fmt; + + sink_fmt = __csid_get_format(csid, sd_state, +@@ -750,7 +754,8 @@ static int csid_link_setup(struct media_entity *entity, + + /* If test generator is enabled */ + /* do not allow a link from CSIPHY to CSID */ +- if (csid->testgen_mode->cur.val != 0) ++ if (csid->testgen.nmodes != CSID_PAYLOAD_MODE_DISABLED && ++ csid->testgen_mode->cur.val != 0) + return -EBUSY; + + sd = media_entity_to_v4l2_subdev(remote->entity); +@@ -843,24 +848,27 @@ int msm_csid_register_entity(struct csid_device *csid, + MSM_CSID_NAME, csid->id); + v4l2_set_subdevdata(sd, csid); + +- ret = v4l2_ctrl_handler_init(&csid->ctrls, 1); +- if (ret < 0) { +- dev_err(dev, "Failed to init ctrl handler: %d\n", ret); +- return ret; +- } ++ if (csid->testgen.nmodes != CSID_PAYLOAD_MODE_DISABLED) { ++ ret = v4l2_ctrl_handler_init(&csid->ctrls, 1); ++ if (ret < 0) { ++ dev_err(dev, "Failed to init ctrl handler: %d\n", ret); ++ return ret; ++ } + +- csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls, +- &csid_ctrl_ops, V4L2_CID_TEST_PATTERN, +- csid->testgen.nmodes, 0, 0, +- csid->testgen.modes); ++ csid->testgen_mode = ++ v4l2_ctrl_new_std_menu_items(&csid->ctrls, ++ &csid_ctrl_ops, V4L2_CID_TEST_PATTERN, ++ csid->testgen.nmodes, 0, 0, ++ csid->testgen.modes); + +- if (csid->ctrls.error) { +- dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error); +- ret = csid->ctrls.error; +- goto free_ctrl; +- } ++ if (csid->ctrls.error) { ++ dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error); ++ ret = csid->ctrls.error; ++ goto free_ctrl; ++ } + +- csid->subdev.ctrl_handler = &csid->ctrls; ++ csid->subdev.ctrl_handler = &csid->ctrls; ++ } + + ret = csid_init_formats(sd, NULL); + if (ret < 0) { +@@ -891,7 +899,8 @@ int msm_csid_register_entity(struct csid_device *csid, + media_cleanup: + media_entity_cleanup(&sd->entity); + free_ctrl: +- v4l2_ctrl_handler_free(&csid->ctrls); ++ if (csid->testgen.nmodes != CSID_PAYLOAD_MODE_DISABLED) ++ v4l2_ctrl_handler_free(&csid->ctrls); + + return ret; + } +@@ -904,5 +913,6 @@ void msm_csid_unregister_entity(struct csid_device *csid) + { + v4l2_device_unregister_subdev(&csid->subdev); + media_entity_cleanup(&csid->subdev.entity); +- v4l2_ctrl_handler_free(&csid->ctrls); ++ if (csid->testgen.nmodes != CSID_PAYLOAD_MODE_DISABLED) ++ v4l2_ctrl_handler_free(&csid->ctrls); + } +-- +2.39.5 + diff --git a/queue-6.6/media-tc358746-improve-calculation-of-the-d-phy-timi.patch b/queue-6.6/media-tc358746-improve-calculation-of-the-d-phy-timi.patch new file mode 100644 index 0000000000..b684d18f95 --- /dev/null +++ b/queue-6.6/media-tc358746-improve-calculation-of-the-d-phy-timi.patch @@ -0,0 +1,80 @@ +From f156b79886bb7b1947cf9da49009aa6eeca6c763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jan 2025 17:07:01 +0100 +Subject: media: tc358746: improve calculation of the D-PHY timing registers + +From: Matthias Fend + +[ Upstream commit 78d7265e2e1ce349e7f3c6a085f2b66d7b73f4ca ] + +When calculating D-PHY registers, using data rates that are not multiples +of 16 can lead to precision loss in division operations. This can result in +register values that produce timing violations against the MIPI standard. + +An example: +cfg->hs_clk_rate = 294MHz +hf_clk = 18 + +If the desired value in cfg->init is 100us, which is the minimum allowed +value, then the LINEINITCNT register is calculated as 1799. But since the +actual clock is 18.375MHz instead of 18MHz, this setting results in a time +that is shorter than 100us and thus violates the standard. The correct +value for LINEINITCNT would be 1837. + +Improve the precision of calculations by using Hz instead of MHz as unit. + +Signed-off-by: Matthias Fend +Reviewed-by: Marco Felsch +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/tc358746.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c +index 566f5eaddd572..b12a6bd42102e 100644 +--- a/drivers/media/i2c/tc358746.c ++++ b/drivers/media/i2c/tc358746.c +@@ -460,24 +460,20 @@ static int tc358746_apply_misc_config(struct tc358746 *tc358746) + return err; + } + +-/* Use MHz as base so the div needs no u64 */ +-static u32 tc358746_cfg_to_cnt(unsigned int cfg_val, +- unsigned int clk_mhz, +- unsigned int time_base) ++static u32 tc358746_cfg_to_cnt(unsigned long cfg_val, unsigned long clk_hz, ++ unsigned long long time_base) + { +- return DIV_ROUND_UP(cfg_val * clk_mhz, time_base); ++ return div64_u64((u64)cfg_val * clk_hz + time_base - 1, time_base); + } + +-static u32 tc358746_ps_to_cnt(unsigned int cfg_val, +- unsigned int clk_mhz) ++static u32 tc358746_ps_to_cnt(unsigned long cfg_val, unsigned long clk_hz) + { +- return tc358746_cfg_to_cnt(cfg_val, clk_mhz, USEC_PER_SEC); ++ return tc358746_cfg_to_cnt(cfg_val, clk_hz, PSEC_PER_SEC); + } + +-static u32 tc358746_us_to_cnt(unsigned int cfg_val, +- unsigned int clk_mhz) ++static u32 tc358746_us_to_cnt(unsigned long cfg_val, unsigned long clk_hz) + { +- return tc358746_cfg_to_cnt(cfg_val, clk_mhz, 1); ++ return tc358746_cfg_to_cnt(cfg_val, clk_hz, USEC_PER_SEC); + } + + static int tc358746_apply_dphy_config(struct tc358746 *tc358746) +@@ -492,7 +488,6 @@ static int tc358746_apply_dphy_config(struct tc358746 *tc358746) + + /* The hs_byte_clk is also called SYSCLK in the excel sheet */ + hs_byte_clk = cfg->hs_clk_rate / 8; +- hs_byte_clk /= HZ_PER_MHZ; + hf_clk = hs_byte_clk / 2; + + val = tc358746_us_to_cnt(cfg->init, hf_clk) - 1; +-- +2.39.5 + diff --git a/queue-6.6/media-test-drivers-vivid-don-t-call-schedule-in-loop.patch b/queue-6.6/media-test-drivers-vivid-don-t-call-schedule-in-loop.patch new file mode 100644 index 0000000000..f67ecd81d7 --- /dev/null +++ b/queue-6.6/media-test-drivers-vivid-don-t-call-schedule-in-loop.patch @@ -0,0 +1,128 @@ +From 426507ab70089e2868c830b4aa43341e8e3b48d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2024 16:00:16 +0100 +Subject: media: test-drivers: vivid: don't call schedule in loop + +From: Hans Verkuil + +[ Upstream commit e4740118b752005cbed339aec9a1d1c43620e0b9 ] + +Artem reported that the CPU load was 100% when capturing from +vivid at low resolution with ffmpeg. + +This was caused by: + +while (time_is_after_jiffies(cur_jiffies + wait_jiffies) && + !kthread_should_stop()) + schedule(); + +If there are no other processes running that can be scheduled, +then this is basically a busy-loop. + +Change it to wait_event_interruptible_timeout() which doesn't +have that problem. + +Signed-off-by: Hans Verkuil +Reported-by: Artem S. Tashkinov +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219570 +Reviewed-by: Nicolas Dufresne +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Sasha Levin +--- + drivers/media/test-drivers/vivid/vivid-kthread-cap.c | 11 ++++++++--- + drivers/media/test-drivers/vivid/vivid-kthread-out.c | 11 ++++++++--- + .../media/test-drivers/vivid/vivid-kthread-touch.c | 11 ++++++++--- + drivers/media/test-drivers/vivid/vivid-sdr-cap.c | 11 ++++++++--- + 4 files changed, 32 insertions(+), 12 deletions(-) + +diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +index 42048727d7ff3..b8cdffc9a1e9e 100644 +--- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c ++++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +@@ -765,9 +765,14 @@ static int vivid_thread_vid_cap(void *data) + next_jiffies_since_start = jiffies_since_start; + + wait_jiffies = next_jiffies_since_start - jiffies_since_start; +- while (time_is_after_jiffies(cur_jiffies + wait_jiffies) && +- !kthread_should_stop()) +- schedule(); ++ if (!time_is_after_jiffies(cur_jiffies + wait_jiffies)) ++ continue; ++ ++ wait_queue_head_t wait; ++ ++ init_waitqueue_head(&wait); ++ wait_event_interruptible_timeout(wait, kthread_should_stop(), ++ cur_jiffies + wait_jiffies - jiffies); + } + dprintk(dev, 1, "Video Capture Thread End\n"); + return 0; +diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-out.c b/drivers/media/test-drivers/vivid/vivid-kthread-out.c +index fac6208b51da8..015a7b166a1e6 100644 +--- a/drivers/media/test-drivers/vivid/vivid-kthread-out.c ++++ b/drivers/media/test-drivers/vivid/vivid-kthread-out.c +@@ -235,9 +235,14 @@ static int vivid_thread_vid_out(void *data) + next_jiffies_since_start = jiffies_since_start; + + wait_jiffies = next_jiffies_since_start - jiffies_since_start; +- while (time_is_after_jiffies(cur_jiffies + wait_jiffies) && +- !kthread_should_stop()) +- schedule(); ++ if (!time_is_after_jiffies(cur_jiffies + wait_jiffies)) ++ continue; ++ ++ wait_queue_head_t wait; ++ ++ init_waitqueue_head(&wait); ++ wait_event_interruptible_timeout(wait, kthread_should_stop(), ++ cur_jiffies + wait_jiffies - jiffies); + } + dprintk(dev, 1, "Video Output Thread End\n"); + return 0; +diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c +index fa711ee36a3fb..c862689786b69 100644 +--- a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c ++++ b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c +@@ -135,9 +135,14 @@ static int vivid_thread_touch_cap(void *data) + next_jiffies_since_start = jiffies_since_start; + + wait_jiffies = next_jiffies_since_start - jiffies_since_start; +- while (time_is_after_jiffies(cur_jiffies + wait_jiffies) && +- !kthread_should_stop()) +- schedule(); ++ if (!time_is_after_jiffies(cur_jiffies + wait_jiffies)) ++ continue; ++ ++ wait_queue_head_t wait; ++ ++ init_waitqueue_head(&wait); ++ wait_event_interruptible_timeout(wait, kthread_should_stop(), ++ cur_jiffies + wait_jiffies - jiffies); + } + dprintk(dev, 1, "Touch Capture Thread End\n"); + return 0; +diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c +index a81f26b769883..1dd59c710dae7 100644 +--- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c ++++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c +@@ -206,9 +206,14 @@ static int vivid_thread_sdr_cap(void *data) + next_jiffies_since_start = jiffies_since_start; + + wait_jiffies = next_jiffies_since_start - jiffies_since_start; +- while (time_is_after_jiffies(cur_jiffies + wait_jiffies) && +- !kthread_should_stop()) +- schedule(); ++ if (!time_is_after_jiffies(cur_jiffies + wait_jiffies)) ++ continue; ++ ++ wait_queue_head_t wait; ++ ++ init_waitqueue_head(&wait); ++ wait_event_interruptible_timeout(wait, kthread_should_stop(), ++ cur_jiffies + wait_jiffies - jiffies); + } + dprintk(dev, 1, "SDR Capture Thread End\n"); + return 0; +-- +2.39.5 + diff --git a/queue-6.6/media-uvcvideo-add-sanity-check-to-uvc_ioctl_xu_ctrl.patch b/queue-6.6/media-uvcvideo-add-sanity-check-to-uvc_ioctl_xu_ctrl.patch new file mode 100644 index 0000000000..738d0fd7e8 --- /dev/null +++ b/queue-6.6/media-uvcvideo-add-sanity-check-to-uvc_ioctl_xu_ctrl.patch @@ -0,0 +1,42 @@ +From 4a5da0b4266552d4679a0b49ec36888dd9a47c99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Feb 2025 11:55:51 +0000 +Subject: media: uvcvideo: Add sanity check to uvc_ioctl_xu_ctrl_map + +From: Ricardo Ribalda + +[ Upstream commit 990262fdfce24d6055df9711424343d94d829e6a ] + +Do not process unknown data types. + +Tested-by: Yunke Cao +Reviewed-by: Hans de Goede +Signed-off-by: Ricardo Ribalda +Link: https://lore.kernel.org/r/20250203-uvc-roi-v17-15-5900a9fed613@chromium.org +Signed-off-by: Hans de Goede +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_v4l2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c +index 7bcd706281daf..cb7d9fb589fca 100644 +--- a/drivers/media/usb/uvc/uvc_v4l2.c ++++ b/drivers/media/usb/uvc/uvc_v4l2.c +@@ -106,6 +106,12 @@ static int uvc_ioctl_xu_ctrl_map(struct uvc_video_chain *chain, + struct uvc_control_mapping *map; + int ret; + ++ if (xmap->data_type > UVC_CTRL_DATA_TYPE_BITMASK) { ++ uvc_dbg(chain->dev, CONTROL, ++ "Unsupported UVC data type %u\n", xmap->data_type); ++ return -EINVAL; ++ } ++ + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (map == NULL) + return -ENOMEM; +-- +2.39.5 + diff --git a/queue-6.6/media-uvcvideo-handle-uvc-menu-translation-inside-uv.patch b/queue-6.6/media-uvcvideo-handle-uvc-menu-translation-inside-uv.patch new file mode 100644 index 0000000000..b7fd1b2d42 --- /dev/null +++ b/queue-6.6/media-uvcvideo-handle-uvc-menu-translation-inside-uv.patch @@ -0,0 +1,161 @@ +From 3de5f0c9b6671850daed4aee36254bed80239238 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Feb 2025 11:55:40 +0000 +Subject: media: uvcvideo: Handle uvc menu translation inside uvc_get_le_value + +From: Ricardo Ribalda + +[ Upstream commit 9109a0b4cb10fd681e9c6e9a4497a6fec5b91c39 ] + +map->get() gets a value from an uvc_control in "UVC format" and converts +it to a value that can be consumed by v4l2. + +Instead of using a special get function for V4L2_CTRL_TYPE_MENU, we +were converting from uvc_get_le_value in two different places. + +Move the conversion to uvc_get_le_value(). + +Reviewed-by: Hans de Goede +Tested-by: Yunke Cao +Signed-off-by: Ricardo Ribalda +Link: https://lore.kernel.org/r/20250203-uvc-roi-v17-4-5900a9fed613@chromium.org +Signed-off-by: Hans de Goede +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_ctrl.c | 77 +++++++++++++------------------- + 1 file changed, 32 insertions(+), 45 deletions(-) + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index 028c4a5049af9..5926a9dfb0b1f 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -815,6 +815,25 @@ static inline void uvc_clear_bit(u8 *data, int bit) + data[bit >> 3] &= ~(1 << (bit & 7)); + } + ++static s32 uvc_menu_to_v4l2_menu(struct uvc_control_mapping *mapping, s32 val) ++{ ++ unsigned int i; ++ ++ for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { ++ u32 menu_value; ++ ++ if (!test_bit(i, &mapping->menu_mask)) ++ continue; ++ ++ menu_value = uvc_mapping_get_menu_value(mapping, i); ++ ++ if (menu_value == val) ++ return i; ++ } ++ ++ return val; ++} ++ + /* + * Extract the bit string specified by mapping->offset and mapping->size + * from the little-endian data stored at 'data' and return the result as +@@ -849,6 +868,16 @@ static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, + if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) + value |= -(value & (1 << (mapping->size - 1))); + ++ /* If it is a menu, convert from uvc to v4l2. */ ++ if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) ++ return value; ++ ++ switch (query) { ++ case UVC_GET_CUR: ++ case UVC_GET_DEF: ++ return uvc_menu_to_v4l2_menu(mapping, value); ++ } ++ + return value; + } + +@@ -1013,32 +1042,6 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, + return 0; + } + +-static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, +- const u8 *data) +-{ +- s32 value = mapping->get(mapping, UVC_GET_CUR, data); +- +- if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { +- unsigned int i; +- +- for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { +- u32 menu_value; +- +- if (!test_bit(i, &mapping->menu_mask)) +- continue; +- +- menu_value = uvc_mapping_get_menu_value(mapping, i); +- +- if (menu_value == value) { +- value = i; +- break; +- } +- } +- } +- +- return value; +-} +- + static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain, + struct uvc_control *ctrl) + { +@@ -1089,8 +1092,8 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain, + if (ret < 0) + return ret; + +- *value = __uvc_ctrl_get_value(mapping, +- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); ++ *value = mapping->get(mapping, UVC_GET_CUR, ++ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); + + return 0; + } +@@ -1240,7 +1243,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, + { + struct uvc_control_mapping *master_map = NULL; + struct uvc_control *master_ctrl = NULL; +- unsigned int i; + + memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); + v4l2_ctrl->id = mapping->id; +@@ -1283,21 +1285,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, + v4l2_ctrl->minimum = ffs(mapping->menu_mask) - 1; + v4l2_ctrl->maximum = fls(mapping->menu_mask) - 1; + v4l2_ctrl->step = 1; +- +- for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { +- u32 menu_value; +- +- if (!test_bit(i, &mapping->menu_mask)) +- continue; +- +- menu_value = uvc_mapping_get_menu_value(mapping, i); +- +- if (menu_value == v4l2_ctrl->default_value) { +- v4l2_ctrl->default_value = i; +- break; +- } +- } +- + return 0; + + case V4L2_CTRL_TYPE_BOOLEAN: +@@ -1580,7 +1567,7 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain, + uvc_ctrl_set_handle(handle, ctrl, NULL); + + list_for_each_entry(mapping, &ctrl->info.mappings, list) { +- s32 value = __uvc_ctrl_get_value(mapping, data); ++ s32 value = mapping->get(mapping, UVC_GET_CUR, data); + + /* + * handle may be NULL here if the device sends auto-update +-- +2.39.5 + diff --git a/queue-6.6/media-v4l-memset-argument-to-0-before-calling-get_mb.patch b/queue-6.6/media-v4l-memset-argument-to-0-before-calling-get_mb.patch new file mode 100644 index 0000000000..3c87b47e10 --- /dev/null +++ b/queue-6.6/media-v4l-memset-argument-to-0-before-calling-get_mb.patch @@ -0,0 +1,55 @@ +From f62cd63c668479476a311bbe3bfb719f7b9568fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 10:48:49 +0200 +Subject: media: v4l: Memset argument to 0 before calling get_mbus_config pad + op + +From: Sakari Ailus + +[ Upstream commit 91d6a99acfa5ce9f95ede775074b80f7193bd717 ] + +Memset the config argument to get_mbus_config V4L2 sub-device pad +operation to zero before calling the operation. This ensures the callers +don't need to bother with it nor the implementations need to set all +fields that may not be relevant to them. + +Signed-off-by: Sakari Ailus +Reviewed-by: Tomi Valkeinen +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/v4l2-core/v4l2-subdev.c | 2 ++ + include/media/v4l2-subdev.h | 4 +++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c +index 5f115438d0722..cb3ad72a3e54a 100644 +--- a/drivers/media/v4l2-core/v4l2-subdev.c ++++ b/drivers/media/v4l2-core/v4l2-subdev.c +@@ -351,6 +351,8 @@ static int call_enum_dv_timings(struct v4l2_subdev *sd, + static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_config *config) + { ++ memset(config, 0, sizeof(*config)); ++ + return check_pad(sd, pad) ? : + sd->ops->pad->get_mbus_config(sd, pad, config); + } +diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h +index b4fcd0164048e..0740dfc6c0488 100644 +--- a/include/media/v4l2-subdev.h ++++ b/include/media/v4l2-subdev.h +@@ -822,7 +822,9 @@ struct v4l2_subdev_state { + * possible configuration from the remote end, likely calling + * this operation as close as possible to stream on time. The + * operation shall fail if the pad index it has been called on +- * is not valid or in case of unrecoverable failures. ++ * is not valid or in case of unrecoverable failures. The ++ * config argument has been memset to 0 just before calling ++ * the op. + * + * @set_routing: enable or disable data connection routes described in the + * subdevice routing table. +-- +2.39.5 + diff --git a/queue-6.6/mfd-tps65219-remove-tps65219_reg_ti_dev_id-check.patch b/queue-6.6/mfd-tps65219-remove-tps65219_reg_ti_dev_id-check.patch new file mode 100644 index 0000000000..b77cb0329d --- /dev/null +++ b/queue-6.6/mfd-tps65219-remove-tps65219_reg_ti_dev_id-check.patch @@ -0,0 +1,58 @@ +From 817d6ceab4f037a2efb56c7b8ef975164fda4499 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 11:37:23 -0600 +Subject: mfd: tps65219: Remove TPS65219_REG_TI_DEV_ID check + +From: Shree Ramamoorthy + +[ Upstream commit 76b58d5111fdcffce615beb71520bc7a6f1742c9 ] + +The chipid macro/variable and regmap_read function call is not needed +because the TPS65219_REG_TI_DEV_ID register value is not a consistent value +across TPS65219 PMIC config versions. Reading from the DEV_ID register +without a consistent value to compare it to isn't useful. There isn't a +way to verify the match data ID is the same ID read from the DEV_ID device +register. 0xF0 isn't a DEV_ID value consistent across TPS65219 NVM +configurations. + +For TPS65215, there is a consistent value in bits 5-0 of the DEV_ID +register. However, there are other error checks in place within probe() +that apply to both PMICs rather than keeping this isolated check for one +PMIC. + +Signed-off-by: Shree Ramamoorthy +Link: https://lore.kernel.org/r/20250206173725.386720-4-s-ramamoorthy@ti.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/tps65219.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c +index 0e0c42e4fdfc7..72a5f51fe32a5 100644 +--- a/drivers/mfd/tps65219.c ++++ b/drivers/mfd/tps65219.c +@@ -228,7 +228,6 @@ static struct regmap_irq_chip tps65219_irq_chip = { + static int tps65219_probe(struct i2c_client *client) + { + struct tps65219 *tps; +- unsigned int chipid; + bool pwr_button; + int ret; + +@@ -253,12 +252,6 @@ static int tps65219_probe(struct i2c_client *client) + if (ret) + return ret; + +- ret = regmap_read(tps->regmap, TPS65219_REG_TI_DEV_ID, &chipid); +- if (ret) { +- dev_err(tps->dev, "Failed to read device ID: %d\n", ret); +- return ret; +- } +- + ret = devm_mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, + tps65219_cells, ARRAY_SIZE(tps65219_cells), + NULL, 0, regmap_irq_get_domain(tps->irq_data)); +-- +2.39.5 + diff --git a/queue-6.6/mips-pm-cps-use-per-cpu-variables-as-per-cpu-not-per.patch b/queue-6.6/mips-pm-cps-use-per-cpu-variables-as-per-cpu-not-per.patch new file mode 100644 index 0000000000..47668e97a3 --- /dev/null +++ b/queue-6.6/mips-pm-cps-use-per-cpu-variables-as-per-cpu-not-per.patch @@ -0,0 +1,128 @@ +From d5b7d7fd94470d357d12e107ebd5ae10ac6efc0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jan 2025 13:32:48 +0100 +Subject: MIPS: pm-cps: Use per-CPU variables as per-CPU, not per-core + +From: Paul Burton + +[ Upstream commit 00a134fc2bb4a5f8fada58cf7ff4259149691d64 ] + +The pm-cps code has up until now used per-CPU variables indexed by core, +rather than CPU number, in order to share data amongst sibling CPUs (ie. +VPs/threads in a core). This works fine for single cluster systems, but +with multi-cluster systems a core number is no longer unique in the +system, leading to sharing between CPUs that are not actually siblings. + +Avoid this issue by using per-CPU variables as they are more generally +used - ie. access them using CPU numbers rather than core numbers. +Sharing between siblings is then accomplished by: + - Assigning the same pointer to entries for each sibling CPU for the + nc_asm_enter & ready_count variables, which allow this by virtue of + being per-CPU pointers. + + - Indexing by the first CPU set in a CPUs cpu_sibling_map in the case + of pm_barrier, for which we can't use the previous approach because + the per-CPU variable is not a pointer. + +Signed-off-by: Paul Burton +Signed-off-by: Dragan Mladjenovic +Signed-off-by: Aleksandar Rikalo +Tested-by: Serge Semin +Tested-by: Gregory CLEMENT +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/pm-cps.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c +index 9bf60d7d44d36..a7bcf2b814c86 100644 +--- a/arch/mips/kernel/pm-cps.c ++++ b/arch/mips/kernel/pm-cps.c +@@ -56,10 +56,7 @@ static DEFINE_PER_CPU_ALIGNED(u32*, ready_count); + /* Indicates online CPUs coupled with the current CPU */ + static DEFINE_PER_CPU_ALIGNED(cpumask_t, online_coupled); + +-/* +- * Used to synchronize entry to deep idle states. Actually per-core rather +- * than per-CPU. +- */ ++/* Used to synchronize entry to deep idle states */ + static DEFINE_PER_CPU_ALIGNED(atomic_t, pm_barrier); + + /* Saved CPU state across the CPS_PM_POWER_GATED state */ +@@ -118,9 +115,10 @@ int cps_pm_enter_state(enum cps_pm_state state) + cps_nc_entry_fn entry; + struct core_boot_config *core_cfg; + struct vpe_boot_config *vpe_cfg; ++ atomic_t *barrier; + + /* Check that there is an entry function for this state */ +- entry = per_cpu(nc_asm_enter, core)[state]; ++ entry = per_cpu(nc_asm_enter, cpu)[state]; + if (!entry) + return -EINVAL; + +@@ -156,7 +154,7 @@ int cps_pm_enter_state(enum cps_pm_state state) + smp_mb__after_atomic(); + + /* Create a non-coherent mapping of the core ready_count */ +- core_ready_count = per_cpu(ready_count, core); ++ core_ready_count = per_cpu(ready_count, cpu); + nc_addr = kmap_noncoherent(virt_to_page(core_ready_count), + (unsigned long)core_ready_count); + nc_addr += ((unsigned long)core_ready_count & ~PAGE_MASK); +@@ -164,7 +162,8 @@ int cps_pm_enter_state(enum cps_pm_state state) + + /* Ensure ready_count is zero-initialised before the assembly runs */ + WRITE_ONCE(*nc_core_ready_count, 0); +- coupled_barrier(&per_cpu(pm_barrier, core), online); ++ barrier = &per_cpu(pm_barrier, cpumask_first(&cpu_sibling_map[cpu])); ++ coupled_barrier(barrier, online); + + /* Run the generated entry code */ + left = entry(online, nc_core_ready_count); +@@ -635,12 +634,14 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) + + static int cps_pm_online_cpu(unsigned int cpu) + { +- enum cps_pm_state state; +- unsigned core = cpu_core(&cpu_data[cpu]); ++ unsigned int sibling, core; + void *entry_fn, *core_rc; ++ enum cps_pm_state state; ++ ++ core = cpu_core(&cpu_data[cpu]); + + for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { +- if (per_cpu(nc_asm_enter, core)[state]) ++ if (per_cpu(nc_asm_enter, cpu)[state]) + continue; + if (!test_bit(state, state_support)) + continue; +@@ -652,16 +653,19 @@ static int cps_pm_online_cpu(unsigned int cpu) + clear_bit(state, state_support); + } + +- per_cpu(nc_asm_enter, core)[state] = entry_fn; ++ for_each_cpu(sibling, &cpu_sibling_map[cpu]) ++ per_cpu(nc_asm_enter, sibling)[state] = entry_fn; + } + +- if (!per_cpu(ready_count, core)) { ++ if (!per_cpu(ready_count, cpu)) { + core_rc = kmalloc(sizeof(u32), GFP_KERNEL); + if (!core_rc) { + pr_err("Failed allocate core %u ready_count\n", core); + return -ENOMEM; + } +- per_cpu(ready_count, core) = core_rc; ++ ++ for_each_cpu(sibling, &cpu_sibling_map[cpu]) ++ per_cpu(ready_count, sibling) = core_rc; + } + + return 0; +-- +2.39.5 + diff --git a/queue-6.6/mips-use-arch-specific-syscall-name-match-function.patch b/queue-6.6/mips-use-arch-specific-syscall-name-match-function.patch new file mode 100644 index 0000000000..bdc9a4fc5c --- /dev/null +++ b/queue-6.6/mips-use-arch-specific-syscall-name-match-function.patch @@ -0,0 +1,55 @@ +From 1098d9efd122f275f55411194ff92ecf4580d90c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Jun 2020 10:54:35 +0800 +Subject: MIPS: Use arch specific syscall name match function + +From: Bibo Mao + +[ Upstream commit 756276ce78d5624dc814f9d99f7d16c8fd51076e ] + +On MIPS system, most of the syscall function name begin with prefix +sys_. Some syscalls are special such as clone/fork, function name of +these begin with __sys_. Since scratch registers need be saved in +stack when these system calls happens. + +With ftrace system call method, system call functions are declared with +SYSCALL_DEFINEx, metadata of the system call symbol name begins with +sys_. Here mips specific function arch_syscall_match_sym_name is used to +compare function name between sys_call_table[] and metadata of syscall +symbol. + +Signed-off-by: Bibo Mao +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/include/asm/ftrace.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h +index db497a8167da2..e3212f44446fa 100644 +--- a/arch/mips/include/asm/ftrace.h ++++ b/arch/mips/include/asm/ftrace.h +@@ -87,4 +87,20 @@ struct dyn_arch_ftrace { + #endif /* CONFIG_DYNAMIC_FTRACE */ + #endif /* __ASSEMBLY__ */ + #endif /* CONFIG_FUNCTION_TRACER */ ++ ++#ifdef CONFIG_FTRACE_SYSCALLS ++#ifndef __ASSEMBLY__ ++/* ++ * Some syscall entry functions on mips start with "__sys_" (fork and clone, ++ * for instance). We should also match the sys_ variant with those. ++ */ ++#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME ++static inline bool arch_syscall_match_sym_name(const char *sym, ++ const char *name) ++{ ++ return !strcmp(sym, name) || ++ (!strncmp(sym, "__sys_", 6) && !strcmp(sym + 6, name + 4)); ++} ++#endif /* __ASSEMBLY__ */ ++#endif /* CONFIG_FTRACE_SYSCALLS */ + #endif /* _ASM_MIPS_FTRACE_H */ +-- +2.39.5 + diff --git a/queue-6.6/mmc-dw_mmc-add-exynos7870-dw-mmc-support.patch b/queue-6.6/mmc-dw_mmc-add-exynos7870-dw-mmc-support.patch new file mode 100644 index 0000000000..f4b597d811 --- /dev/null +++ b/queue-6.6/mmc-dw_mmc-add-exynos7870-dw-mmc-support.patch @@ -0,0 +1,174 @@ +From 65c0fbf589f7bfa3e0839842f892e76ee91ba2e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Feb 2025 00:17:49 +0530 +Subject: mmc: dw_mmc: add exynos7870 DW MMC support + +From: Kaustabh Chakraborty + +[ Upstream commit 7cbe799ac10fd8be85af5e0615c4337f81e575f3 ] + +Add support for Exynos7870 DW MMC controllers, for both SMU and non-SMU +variants. These controllers require a quirk to access 64-bit FIFO in 32-bit +accesses (DW_MMC_QUIRK_FIFO64_32). + +Signed-off-by: Kaustabh Chakraborty +Link: https://lore.kernel.org/r/20250219-exynos7870-mmc-v2-3-b4255a3e39ed@disroot.org +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/dw_mmc-exynos.c | 41 +++++++++++++++++++++++++++++++- + 1 file changed, 40 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c +index 698408e8bad03..381a61adf06ee 100644 +--- a/drivers/mmc/host/dw_mmc-exynos.c ++++ b/drivers/mmc/host/dw_mmc-exynos.c +@@ -28,6 +28,8 @@ enum dw_mci_exynos_type { + DW_MCI_TYPE_EXYNOS5420_SMU, + DW_MCI_TYPE_EXYNOS7, + DW_MCI_TYPE_EXYNOS7_SMU, ++ DW_MCI_TYPE_EXYNOS7870, ++ DW_MCI_TYPE_EXYNOS7870_SMU, + DW_MCI_TYPE_ARTPEC8, + }; + +@@ -70,6 +72,12 @@ static struct dw_mci_exynos_compatible { + }, { + .compatible = "samsung,exynos7-dw-mshc-smu", + .ctrl_type = DW_MCI_TYPE_EXYNOS7_SMU, ++ }, { ++ .compatible = "samsung,exynos7870-dw-mshc", ++ .ctrl_type = DW_MCI_TYPE_EXYNOS7870, ++ }, { ++ .compatible = "samsung,exynos7870-dw-mshc-smu", ++ .ctrl_type = DW_MCI_TYPE_EXYNOS7870_SMU, + }, { + .compatible = "axis,artpec8-dw-mshc", + .ctrl_type = DW_MCI_TYPE_ARTPEC8, +@@ -86,6 +94,8 @@ static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) + return EXYNOS4210_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; + else +@@ -101,7 +111,8 @@ static void dw_mci_exynos_config_smu(struct dw_mci *host) + * set for non-ecryption mode at this time. + */ + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || +- priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) { + mci_writel(host, MPSBEGIN0, 0); + mci_writel(host, MPSEND0, SDMMC_ENDING_SEC_NR_MAX); + mci_writel(host, MPSCTRL0, SDMMC_MPSCTRL_SECURE_WRITE_BIT | +@@ -127,6 +138,12 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); + } + ++ if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) { ++ /* Quirk needed for certain Exynos SoCs */ ++ host->quirks |= DW_MMC_QUIRK_FIFO64_32; ++ } ++ + if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) { + /* Quirk needed for the ARTPEC-8 SoC */ + host->quirks |= DW_MMC_QUIRK_EXTENDED_TMOUT; +@@ -144,6 +161,8 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + clksel = mci_readl(host, CLKSEL64); + else +@@ -153,6 +172,8 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + mci_writel(host, CLKSEL64, clksel); + else +@@ -223,6 +244,8 @@ static int dw_mci_exynos_resume_noirq(struct device *dev) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + clksel = mci_readl(host, CLKSEL64); + else +@@ -231,6 +254,8 @@ static int dw_mci_exynos_resume_noirq(struct device *dev) + if (clksel & SDMMC_CLKSEL_WAKEUP_INT) { + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + mci_writel(host, CLKSEL64, clksel); + else +@@ -410,6 +435,8 @@ static inline u8 dw_mci_exynos_get_clksmpl(struct dw_mci *host) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL64)); + else +@@ -423,6 +450,8 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + clksel = mci_readl(host, CLKSEL64); + else +@@ -430,6 +459,8 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + mci_writel(host, CLKSEL64, clksel); + else +@@ -444,6 +475,8 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + clksel = mci_readl(host, CLKSEL64); + else +@@ -454,6 +487,8 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || ++ priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || + priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) + mci_writel(host, CLKSEL64, clksel); + else +@@ -633,6 +668,10 @@ static const struct of_device_id dw_mci_exynos_match[] = { + .data = &exynos_drv_data, }, + { .compatible = "samsung,exynos7-dw-mshc-smu", + .data = &exynos_drv_data, }, ++ { .compatible = "samsung,exynos7870-dw-mshc", ++ .data = &exynos_drv_data, }, ++ { .compatible = "samsung,exynos7870-dw-mshc-smu", ++ .data = &exynos_drv_data, }, + { .compatible = "axis,artpec8-dw-mshc", + .data = &artpec_drv_data, }, + {}, +-- +2.39.5 + diff --git a/queue-6.6/mmc-host-wait-for-vdd-to-settle-on-card-power-off.patch b/queue-6.6/mmc-host-wait-for-vdd-to-settle-on-card-power-off.patch new file mode 100644 index 0000000000..8127bcd8b0 --- /dev/null +++ b/queue-6.6/mmc-host-wait-for-vdd-to-settle-on-card-power-off.patch @@ -0,0 +1,46 @@ +From 93fb77d73622ff24bf8bad19016bddfefa66f3b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Mar 2025 14:50:21 -0500 +Subject: mmc: host: Wait for Vdd to settle on card power off + +From: Erick Shepherd + +[ Upstream commit 31e75ed964582257f59156ce6a42860e1ae4cc39 ] + +The SD spec version 6.0 section 6.4.1.5 requires that Vdd must be +lowered to less than 0.5V for a minimum of 1 ms when powering off a +card. Increase wait to 15 ms so that voltage has time to drain down +to 0.5V and cards can power off correctly. Issues with voltage drain +time were only observed on Apollo Lake and Bay Trail host controllers +so this fix is limited to those devices. + +Signed-off-by: Erick Shepherd +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20250314195021.1588090-1-erick.shepherd@ni.com +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci-pci-core.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c +index 6b351810a301c..dbfe0a5324eaf 100644 +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -608,8 +608,12 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, + + sdhci_set_power(host, mode, vdd); + +- if (mode == MMC_POWER_OFF) ++ if (mode == MMC_POWER_OFF) { ++ if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD || ++ slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SD) ++ usleep_range(15000, 17500); + return; ++ } + + /* + * Bus power might not enable after D3 -> D0 transition due to the +-- +2.39.5 + diff --git a/queue-6.6/mmc-sdhci-disable-sd-card-clock-before-changing-para.patch b/queue-6.6/mmc-sdhci-disable-sd-card-clock-before-changing-para.patch new file mode 100644 index 0000000000..26b4602690 --- /dev/null +++ b/queue-6.6/mmc-sdhci-disable-sd-card-clock-before-changing-para.patch @@ -0,0 +1,54 @@ +From 0cd91e0f4dcef1e51b8c1bac676ae8f537dd27a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Feb 2025 15:46:45 -0600 +Subject: mmc: sdhci: Disable SD card clock before changing parameters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Erick Shepherd + +[ Upstream commit fb3bbc46c94f261b6156ee863c1b06c84cf157dc ] + +Per the SD Host Controller Simplified Specification v4.20 §3.2.3, change +the SD card clock parameters only after first disabling the external card +clock. Doing this fixes a spurious clock pulse on Baytrail and Apollo Lake +SD controllers which otherwise breaks voltage switching with a specific +Swissbit SD card. + +Signed-off-by: Kyle Roeschley +Signed-off-by: Brad Mouring +Signed-off-by: Erick Shepherd +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20250211214645.469279-1-erick.shepherd@ni.com +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index 9796a3cb3ca62..f32429ff905ff 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2035,10 +2035,15 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) + + host->mmc->actual_clock = 0; + +- sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ if (clk & SDHCI_CLOCK_CARD_EN) ++ sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, ++ SDHCI_CLOCK_CONTROL); + +- if (clock == 0) ++ if (clock == 0) { ++ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + return; ++ } + + clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); + sdhci_enable_clk(host, clk); +-- +2.39.5 + diff --git a/queue-6.6/net-enetc-refactor-bulk-flipping-of-rx-buffers-to-se.patch b/queue-6.6/net-enetc-refactor-bulk-flipping-of-rx-buffers-to-se.patch new file mode 100644 index 0000000000..9cb345e8d2 --- /dev/null +++ b/queue-6.6/net-enetc-refactor-bulk-flipping-of-rx-buffers-to-se.patch @@ -0,0 +1,66 @@ +From 958c34f80c2862a1a6869ee275482939905b2e8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Apr 2025 15:00:04 +0300 +Subject: net: enetc: refactor bulk flipping of RX buffers to separate function + +From: Vladimir Oltean + +[ Upstream commit 1d587faa5be7e9785b682cc5f58ba8f4100c13ea ] + +This small snippet of code ensures that we do something with the array +of RX software buffer descriptor elements after passing the skb to the +stack. In this case, we see if the other half of the page is reusable, +and if so, we "turn around" the buffers, making them directly usable by +enetc_refill_rx_ring() without going to enetc_new_page(). + +We will need to perform this kind of buffer flipping from a new code +path, i.e. from XDP_PASS. Currently, enetc_build_skb() does it there +buffer by buffer, but in a subsequent change we will stop using +enetc_build_skb() for XDP_PASS. + +Signed-off-by: Vladimir Oltean +Reviewed-by: Wei Fang +Link: https://patch.msgid.link/20250417120005.3288549-3-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/enetc/enetc.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c +index 8feb7d4226bb5..0c09d82dbf00d 100644 +--- a/drivers/net/ethernet/freescale/enetc/enetc.c ++++ b/drivers/net/ethernet/freescale/enetc/enetc.c +@@ -1572,6 +1572,16 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first, + } + } + ++static void enetc_bulk_flip_buff(struct enetc_bdr *rx_ring, int rx_ring_first, ++ int rx_ring_last) ++{ ++ while (rx_ring_first != rx_ring_last) { ++ enetc_flip_rx_buff(rx_ring, ++ &rx_ring->rx_swbd[rx_ring_first]); ++ enetc_bdr_idx_inc(rx_ring, &rx_ring_first); ++ } ++} ++ + static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, + struct napi_struct *napi, int work_limit, + struct bpf_prog *prog) +@@ -1687,11 +1697,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, + enetc_xdp_drop(rx_ring, orig_i, i); + rx_ring->stats.xdp_redirect_failures++; + } else { +- while (orig_i != i) { +- enetc_flip_rx_buff(rx_ring, +- &rx_ring->rx_swbd[orig_i]); +- enetc_bdr_idx_inc(rx_ring, &orig_i); +- } ++ enetc_bulk_flip_buff(rx_ring, orig_i, i); + xdp_redirect_frm_cnt++; + rx_ring->stats.xdp_redirect++; + } +-- +2.39.5 + diff --git a/queue-6.6/net-ethernet-mtk_ppe_offload-allow-qinq-double-eth_p.patch b/queue-6.6/net-ethernet-mtk_ppe_offload-allow-qinq-double-eth_p.patch new file mode 100644 index 0000000000..c11fb18287 --- /dev/null +++ b/queue-6.6/net-ethernet-mtk_ppe_offload-allow-qinq-double-eth_p.patch @@ -0,0 +1,88 @@ +From 86bdd207cee727569caba662ecc09f17bb0b1eea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 21:15:09 +0100 +Subject: net: ethernet: mtk_ppe_offload: Allow QinQ, double ETH_P_8021Q only + +From: Eric Woudstra + +[ Upstream commit 7fe0353606d77a32c4c7f2814833dd1c043ebdd2 ] + +mtk_foe_entry_set_vlan() in mtk_ppe.c already supports double vlan +tagging, but mtk_flow_offload_replace() in mtk_ppe_offload.c only allows +for 1 vlan tag, optionally in combination with pppoe and dsa tags. + +However, mtk_foe_entry_set_vlan() only allows for setting the vlan id. +The protocol cannot be set, it is always ETH_P_8021Q, for inner and outer +tag. This patch adds QinQ support to mtk_flow_offload_replace(), only in +the case that both inner and outer tags are ETH_P_8021Q. + +Only PPPoE-in-Q (as before) and Q-in-Q are allowed. A combination +of PPPoE and Q-in-Q is not allowed. + +Signed-off-by: Eric Woudstra +Link: https://patch.msgid.link/20250225201509.20843-1-ericwouds@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mediatek/mtk_ppe_offload.c | 22 +++++++++---------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +index a4efbeb162084..889fd26843e60 100644 +--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +@@ -34,8 +34,10 @@ struct mtk_flow_data { + u16 vlan_in; + + struct { +- u16 id; +- __be16 proto; ++ struct { ++ u16 id; ++ __be16 proto; ++ } vlans[2]; + u8 num; + } vlan; + struct { +@@ -330,18 +332,19 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, + case FLOW_ACTION_CSUM: + break; + case FLOW_ACTION_VLAN_PUSH: +- if (data.vlan.num == 1 || ++ if (data.vlan.num + data.pppoe.num == 2 || + act->vlan.proto != htons(ETH_P_8021Q)) + return -EOPNOTSUPP; + +- data.vlan.id = act->vlan.vid; +- data.vlan.proto = act->vlan.proto; ++ data.vlan.vlans[data.vlan.num].id = act->vlan.vid; ++ data.vlan.vlans[data.vlan.num].proto = act->vlan.proto; + data.vlan.num++; + break; + case FLOW_ACTION_VLAN_POP: + break; + case FLOW_ACTION_PPPOE_PUSH: +- if (data.pppoe.num == 1) ++ if (data.pppoe.num == 1 || ++ data.vlan.num == 2) + return -EOPNOTSUPP; + + data.pppoe.sid = act->pppoe.sid; +@@ -431,12 +434,9 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, + if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE) + foe.bridge.vlan = data.vlan_in; + +- if (data.vlan.num == 1) { +- if (data.vlan.proto != htons(ETH_P_8021Q)) +- return -EOPNOTSUPP; ++ for (i = 0; i < data.vlan.num; i++) ++ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.vlans[i].id); + +- mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id); +- } + if (data.pppoe.num == 1) + mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid); + +-- +2.39.5 + diff --git a/queue-6.6/net-ethernet-ti-cpsw_new-populate-netdev-of_node.patch b/queue-6.6/net-ethernet-ti-cpsw_new-populate-netdev-of_node.patch new file mode 100644 index 0000000000..0934d9c7a8 --- /dev/null +++ b/queue-6.6/net-ethernet-ti-cpsw_new-populate-netdev-of_node.patch @@ -0,0 +1,37 @@ +From b16c89e1db5a295221f32efbaffd03dffd44c776 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 08:46:57 +0100 +Subject: net: ethernet: ti: cpsw_new: populate netdev of_node + +From: Alexander Sverdlin + +[ Upstream commit 7ff1c88fc89688c27f773ba956f65f0c11367269 ] + +So that of_find_net_device_by_node() can find CPSW ports and other DSA +switches can be stacked downstream. Tested in conjunction with KSZ8873. + +Reviewed-by: Siddharth Vadapalli +Reviewed-by: Andrew Lunn +Signed-off-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250303074703.1758297-1-alexander.sverdlin@siemens.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/cpsw_new.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c +index 9061dca97fcbf..1c1d4806c119b 100644 +--- a/drivers/net/ethernet/ti/cpsw_new.c ++++ b/drivers/net/ethernet/ti/cpsw_new.c +@@ -1416,6 +1416,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw) + ndev->netdev_ops = &cpsw_netdev_ops; + ndev->ethtool_ops = &cpsw_ethtool_ops; + SET_NETDEV_DEV(ndev, dev); ++ ndev->dev.of_node = slave_data->slave_node; + + if (!napi_ndev) { + /* CPSW Host port CPDMA interface is shared between +-- +2.39.5 + diff --git a/queue-6.6/net-fec-refactor-mac-reset-to-function.patch b/queue-6.6/net-fec-refactor-mac-reset-to-function.patch new file mode 100644 index 0000000000..949a589a90 --- /dev/null +++ b/queue-6.6/net-fec-refactor-mac-reset-to-function.patch @@ -0,0 +1,118 @@ +From f1c01a0b61d142baf83f1a26c72bd0f95f5b37a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:12:55 +0100 +Subject: net: fec: Refactor MAC reset to function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Csókás, Bence + +[ Upstream commit 67800d296191d0a9bde0a7776f99ca1ddfa0fc26 ] + +The core is reset both in `fec_restart()` (called on link-up) and +`fec_stop()` (going to sleep, driver remove etc.). These two functions +had their separate implementations, which was at first only a register +write and a `udelay()` (and the accompanying block comment). However, +since then we got soft-reset (MAC disable) and Wake-on-LAN support, which +meant that these implementations diverged, often causing bugs. + +For instance, as of now, `fec_stop()` does not check for +`FEC_QUIRK_NO_HARD_RESET`, meaning the MII/RMII mode is cleared on eg. +a PM power-down event; and `fec_restart()` missed the refactor renaming +the "magic" constant `1` to `FEC_ECR_RESET`. + +To harmonize current implementations, and eliminate this source of +potential future bugs, refactor implementation to a common function. + +Reviewed-by: Michal Swiatkowski +Reviewed-by: Jacob Keller +Reviewed-by: Simon Horman +Signed-off-by: Csókás, Bence +Link: https://patch.msgid.link/20250207121255.161146-2-csokas.bence@prolan.hu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_main.c | 52 +++++++++++------------ + 1 file changed, 25 insertions(+), 27 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 7261838a09db6..291c88a76a27f 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -1079,6 +1079,29 @@ static void fec_enet_enable_ring(struct net_device *ndev) + } + } + ++/* Whack a reset. We should wait for this. ++ * For i.MX6SX SOC, enet use AXI bus, we use disable MAC ++ * instead of reset MAC itself. ++ */ ++static void fec_ctrl_reset(struct fec_enet_private *fep, bool allow_wol) ++{ ++ u32 val; ++ ++ if (!allow_wol || !(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) { ++ if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES || ++ ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) { ++ writel(0, fep->hwp + FEC_ECNTRL); ++ } else { ++ writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL); ++ udelay(10); ++ } ++ } else { ++ val = readl(fep->hwp + FEC_ECNTRL); ++ val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP); ++ writel(val, fep->hwp + FEC_ECNTRL); ++ } ++} ++ + /* + * This function is called to start or restart the FEC during a link + * change, transmit timeout, or to reconfigure the FEC. The network +@@ -1095,17 +1118,7 @@ fec_restart(struct net_device *ndev) + if (fep->bufdesc_ex) + fec_ptp_save_state(fep); + +- /* Whack a reset. We should wait for this. +- * For i.MX6SX SOC, enet use AXI bus, we use disable MAC +- * instead of reset MAC itself. +- */ +- if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES || +- ((fep->quirks & FEC_QUIRK_NO_HARD_RESET) && fep->link)) { +- writel(0, fep->hwp + FEC_ECNTRL); +- } else { +- writel(1, fep->hwp + FEC_ECNTRL); +- udelay(10); +- } ++ fec_ctrl_reset(fep, false); + + /* + * enet-mac reset will reset mac address registers too, +@@ -1359,22 +1372,7 @@ fec_stop(struct net_device *ndev) + if (fep->bufdesc_ex) + fec_ptp_save_state(fep); + +- /* Whack a reset. We should wait for this. +- * For i.MX6SX SOC, enet use AXI bus, we use disable MAC +- * instead of reset MAC itself. +- */ +- if (!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) { +- if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) { +- writel(0, fep->hwp + FEC_ECNTRL); +- } else { +- writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL); +- udelay(10); +- } +- } else { +- val = readl(fep->hwp + FEC_ECNTRL); +- val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP); +- writel(val, fep->hwp + FEC_ECNTRL); +- } ++ fec_ctrl_reset(fep, true); + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); + writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + +-- +2.39.5 + diff --git a/queue-6.6/net-mana-fix-warning-in-the-writer-of-client-oob.patch b/queue-6.6/net-mana-fix-warning-in-the-writer-of-client-oob.patch new file mode 100644 index 0000000000..6ef66fef64 --- /dev/null +++ b/queue-6.6/net-mana-fix-warning-in-the-writer-of-client-oob.patch @@ -0,0 +1,37 @@ +From 57f6da6aaf73717ef4bbcd619981f57fd369821d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Jan 2025 09:27:14 -0800 +Subject: net/mana: fix warning in the writer of client oob + +From: Konstantin Taranov + +[ Upstream commit 5ec7e1c86c441c46a374577bccd9488abea30037 ] + +Do not warn on missing pad_data when oob is in sgl. + +Signed-off-by: Konstantin Taranov +Link: https://patch.msgid.link/1737394039-28772-9-git-send-email-kotaranov@linux.microsoft.com +Reviewed-by: Shiraz Saleem +Reviewed-by: Long Li +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index ae014e21eb605..9ed965d61e355 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -1036,7 +1036,7 @@ static u32 mana_gd_write_client_oob(const struct gdma_wqe_request *wqe_req, + header->inline_oob_size_div4 = client_oob_size / sizeof(u32); + + if (oob_in_sgl) { +- WARN_ON_ONCE(!pad_data || wqe_req->num_sge < 2); ++ WARN_ON_ONCE(wqe_req->num_sge < 2); + + header->client_oob_in_sgl = 1; + +-- +2.39.5 + diff --git a/queue-6.6/net-mlx4_core-avoid-impossible-mlx4_db_alloc-order-v.patch b/queue-6.6/net-mlx4_core-avoid-impossible-mlx4_db_alloc-order-v.patch new file mode 100644 index 0000000000..ba4df04a08 --- /dev/null +++ b/queue-6.6/net-mlx4_core-avoid-impossible-mlx4_db_alloc-order-v.patch @@ -0,0 +1,78 @@ +From 3df6b08b978f66b74b2317b19afe05c39b45c8d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Feb 2025 09:45:05 -0800 +Subject: net/mlx4_core: Avoid impossible mlx4_db_alloc() order value + +From: Kees Cook + +[ Upstream commit 4a6f18f28627e121bd1f74b5fcc9f945d6dbeb1e ] + +GCC can see that the value range for "order" is capped, but this leads +it to consider that it might be negative, leading to a false positive +warning (with GCC 15 with -Warray-bounds -fdiagnostics-details): + +../drivers/net/ethernet/mellanox/mlx4/alloc.c:691:47: error: array subscript -1 is below array bounds of 'long unsigned int *[2]' [-Werror=array-bounds=] + 691 | i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE >> o); + | ~~~~~~~~~~~^~~ + 'mlx4_alloc_db_from_pgdir': events 1-2 + 691 | i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE >> o); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | | | (2) out of array bounds here + | (1) when the condition is evaluated to true In file included from ../drivers/net/ethernet/mellanox/mlx4/mlx4.h:53, + from ../drivers/net/ethernet/mellanox/mlx4/alloc.c:42: +../include/linux/mlx4/device.h:664:33: note: while referencing 'bits' + 664 | unsigned long *bits[2]; + | ^~~~ + +Switch the argument to unsigned int, which removes the compiler needing +to consider negative values. + +Signed-off-by: Kees Cook +Link: https://patch.msgid.link/20250210174504.work.075-kees@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx4/alloc.c | 6 +++--- + include/linux/mlx4/device.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c +index b330020dc0d67..f2bded847e61d 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/alloc.c ++++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c +@@ -682,9 +682,9 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device) + } + + static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir, +- struct mlx4_db *db, int order) ++ struct mlx4_db *db, unsigned int order) + { +- int o; ++ unsigned int o; + int i; + + for (o = order; o <= 1; ++o) { +@@ -712,7 +712,7 @@ static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir, + return 0; + } + +-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order) ++int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, unsigned int order) + { + struct mlx4_priv *priv = mlx4_priv(dev); + struct mlx4_db_pgdir *pgdir; +diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h +index 27f42f713c891..86f0f2a25a3d6 100644 +--- a/include/linux/mlx4/device.h ++++ b/include/linux/mlx4/device.h +@@ -1135,7 +1135,7 @@ int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, + int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, + struct mlx4_buf *buf); + +-int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order); ++int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, unsigned int order); + void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db); + + int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres, +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-apply-rate-limiting-to-high-temperature-war.patch b/queue-6.6/net-mlx5-apply-rate-limiting-to-high-temperature-war.patch new file mode 100644 index 0000000000..9b64533bac --- /dev/null +++ b/queue-6.6/net-mlx5-apply-rate-limiting-to-high-temperature-war.patch @@ -0,0 +1,45 @@ +From 50aa18e8869c8e4cf687c3a6072cbb071cb52a3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 11:46:38 +0200 +Subject: net/mlx5: Apply rate-limiting to high temperature warning + +From: Shahar Shitrit + +[ Upstream commit 9dd3d5d258aceb37bdf09c8b91fa448f58ea81f0 ] + +Wrap the high temperature warning in a temperature event with +a call to net_ratelimit() to prevent flooding the kernel log +with repeated warning messages when temperature exceeds the +threshold multiple times within a short duration. + +Signed-off-by: Shahar Shitrit +Signed-off-by: Tariq Toukan +Reviewed-by: Mateusz Polchlopek +Link: https://patch.msgid.link/20250213094641.226501-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/events.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/events.c b/drivers/net/ethernet/mellanox/mlx5/core/events.c +index 0f4763dab5d25..e7143d32b2211 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/events.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/events.c +@@ -169,9 +169,10 @@ static int temp_warn(struct notifier_block *nb, unsigned long type, void *data) + value_lsb &= 0x1; + value_msb = be64_to_cpu(eqe->data.temp_warning.sensor_warning_msb); + +- mlx5_core_warn(events->dev, +- "High temperature on sensors with bit set %llx %llx", +- value_msb, value_lsb); ++ if (net_ratelimit()) ++ mlx5_core_warn(events->dev, ++ "High temperature on sensors with bit set %llx %llx", ++ value_msb, value_lsb); + + return NOTIFY_OK; + } +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-avoid-report-two-health-errors-on-same-synd.patch b/queue-6.6/net-mlx5-avoid-report-two-health-errors-on-same-synd.patch new file mode 100644 index 0000000000..86a323c6f1 --- /dev/null +++ b/queue-6.6/net-mlx5-avoid-report-two-health-errors-on-same-synd.patch @@ -0,0 +1,42 @@ +From c7bc02f446028b92d62343b0a4c065099037ab0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 14:25:40 +0200 +Subject: net/mlx5: Avoid report two health errors on same syndrome + +From: Moshe Shemesh + +[ Upstream commit b5d7b2f04ebcff740f44ef4d295b3401aeb029f4 ] + +In case health counter has not increased for few polling intervals, miss +counter will reach max misses threshold and health report will be +triggered for FW health reporter. In case syndrome found on same health +poll another health report will be triggered. + +Avoid two health reports on same syndrome by marking this syndrome as +already known. + +Signed-off-by: Moshe Shemesh +Reviewed-by: Shahar Shitrit +Signed-off-by: Tariq Toukan +Reviewed-by: Kalesh AP +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/health.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c +index d798834c4e755..3ac8043f76dac 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c +@@ -833,6 +833,7 @@ static void poll_health(struct timer_list *t) + health->prev = count; + if (health->miss_counter == MAX_MISSES) { + mlx5_core_err(dev, "device's health compromised - reached miss count\n"); ++ health->synd = ioread8(&h->synd); + print_health_info(dev); + queue_work(health->wq, &health->report_work); + } +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-change-pool_next_size-define-value-and-make.patch b/queue-6.6/net-mlx5-change-pool_next_size-define-value-and-make.patch new file mode 100644 index 0000000000..e50db6a10e --- /dev/null +++ b/queue-6.6/net-mlx5-change-pool_next_size-define-value-and-make.patch @@ -0,0 +1,108 @@ +From c9725d99fe0a208b3be7443630a018013b6292a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Feb 2025 10:58:08 +0200 +Subject: net/mlx5: Change POOL_NEXT_SIZE define value and make it global + +From: Patrisious Haddad + +[ Upstream commit 80df31f384b4146a62a01b3d4beb376cc7b9a89e ] + +Change POOL_NEXT_SIZE define value from 0 to BIT(30), since this define +is used to request the available maximum sized flow table, and zero doesn't +make sense for it, whereas some places in the driver use zero explicitly +expecting the smallest table size possible but instead due to this +define they end up allocating the biggest table size unawarely. + +In addition move the definition to "include/linux/mlx5/fs.h" to expose the +define to IB driver as well, while appropriately renaming it. + +Signed-off-by: Patrisious Haddad +Reviewed-by: Maor Gottlieb +Reviewed-by: Mark Bloch +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20250219085808.349923-3-tariqt@nvidia.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c | 2 +- + drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c | 6 ++++-- + drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.h | 2 -- + drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c | 3 ++- + include/linux/mlx5/fs.h | 2 ++ + 5 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c +index 8587cd572da53..bdb825aa87268 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c +@@ -96,7 +96,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw) + if (!flow_group_in) + return -ENOMEM; + +- ft_attr.max_fte = POOL_NEXT_SIZE; ++ ft_attr.max_fte = MLX5_FS_MAX_POOL_SIZE; + ft_attr.prio = LEGACY_FDB_PRIO; + fdb = mlx5_create_flow_table(root_ns, &ft_attr); + if (IS_ERR(fdb)) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c +index c14590acc7726..f6abfd00d7e68 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c +@@ -50,10 +50,12 @@ mlx5_ft_pool_get_avail_sz(struct mlx5_core_dev *dev, enum fs_flow_table_type tab + int i, found_i = -1; + + for (i = ARRAY_SIZE(FT_POOLS) - 1; i >= 0; i--) { +- if (dev->priv.ft_pool->ft_left[i] && FT_POOLS[i] >= desired_size && ++ if (dev->priv.ft_pool->ft_left[i] && ++ (FT_POOLS[i] >= desired_size || ++ desired_size == MLX5_FS_MAX_POOL_SIZE) && + FT_POOLS[i] <= max_ft_size) { + found_i = i; +- if (desired_size != POOL_NEXT_SIZE) ++ if (desired_size != MLX5_FS_MAX_POOL_SIZE) + break; + } + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.h +index 25f4274b372b5..173e312db7204 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.h +@@ -7,8 +7,6 @@ + #include + #include "fs_core.h" + +-#define POOL_NEXT_SIZE 0 +- + int mlx5_ft_pool_init(struct mlx5_core_dev *dev); + void mlx5_ft_pool_destroy(struct mlx5_core_dev *dev); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +index 711d14dea2485..d313cb7f0ed88 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +@@ -161,7 +161,8 @@ mlx5_chains_create_table(struct mlx5_fs_chains *chains, + ft_attr.flags |= (MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT | + MLX5_FLOW_TABLE_TUNNEL_EN_DECAP); + +- sz = (chain == mlx5_chains_get_nf_ft_chain(chains)) ? FT_TBL_SZ : POOL_NEXT_SIZE; ++ sz = (chain == mlx5_chains_get_nf_ft_chain(chains)) ? ++ FT_TBL_SZ : MLX5_FS_MAX_POOL_SIZE; + ft_attr.max_fte = sz; + + /* We use chains_default_ft(chains) as the table's next_ft till +diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h +index 3fb428ce7d1c7..b6b9a4dfa4fb9 100644 +--- a/include/linux/mlx5/fs.h ++++ b/include/linux/mlx5/fs.h +@@ -40,6 +40,8 @@ + + #define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v) + ++#define MLX5_FS_MAX_POOL_SIZE BIT(30) ++ + enum mlx5_flow_destination_type { + MLX5_FLOW_DESTINATION_TYPE_NONE, + MLX5_FLOW_DESTINATION_TYPE_VPORT, +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-extend-ethtool-loopback-selftest-to-support.patch b/queue-6.6/net-mlx5-extend-ethtool-loopback-selftest-to-support.patch new file mode 100644 index 0000000000..caaf141bff --- /dev/null +++ b/queue-6.6/net-mlx5-extend-ethtool-loopback-selftest-to-support.patch @@ -0,0 +1,41 @@ +From eff47068e084abe3bd86f9006b78f9a276a1224e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 12:17:15 +0200 +Subject: net/mlx5: Extend Ethtool loopback selftest to support non-linear SKB + +From: Alexei Lazar + +[ Upstream commit 95b9606b15bb3ce1198d28d2393dd0e1f0a5f3e9 ] + +Current loopback test validation ignores non-linear SKB case in +the SKB access, which can lead to failures in scenarios such as +when HW GRO is enabled. +Linearize the SKB so both cases will be handled. + +Signed-off-by: Alexei Lazar +Reviewed-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20250209101716.112774-15-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +index 08a75654f5f18..c170503b3aace 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +@@ -165,6 +165,9 @@ mlx5e_test_loopback_validate(struct sk_buff *skb, + struct udphdr *udph; + struct iphdr *iph; + ++ if (skb_linearize(skb)) ++ goto out; ++ + /* We are only going to peek, no need to clone the SKB */ + if (MLX5E_TEST_PKT_SIZE - ETH_HLEN > skb_headlen(skb)) + goto out; +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-modify-lsb-bitmask-in-temperature-event-to-.patch b/queue-6.6/net-mlx5-modify-lsb-bitmask-in-temperature-event-to-.patch new file mode 100644 index 0000000000..befa1d1685 --- /dev/null +++ b/queue-6.6/net-mlx5-modify-lsb-bitmask-in-temperature-event-to-.patch @@ -0,0 +1,46 @@ +From 0eabecbc4b39475d71abe72e7111e718a985c1dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Feb 2025 11:46:40 +0200 +Subject: net/mlx5: Modify LSB bitmask in temperature event to include only the + first bit + +From: Shahar Shitrit + +[ Upstream commit 633f16d7e07c129a36b882c05379e01ce5bdb542 ] + +In the sensor_count field of the MTEWE register, bits 1-62 are +supported only for unmanaged switches, not for NICs, and bit 63 +is reserved for internal use. + +To prevent confusing output that may include set bits that are +not relevant to NIC sensors, we update the bitmask to retain only +the first bit, which corresponds to the sensor ASIC. + +Signed-off-by: Shahar Shitrit +Signed-off-by: Tariq Toukan +Reviewed-by: Mateusz Polchlopek +Link: https://patch.msgid.link/20250213094641.226501-4-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/events.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/events.c b/drivers/net/ethernet/mellanox/mlx5/core/events.c +index 3ec892d51f57d..0f4763dab5d25 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/events.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/events.c +@@ -163,6 +163,10 @@ static int temp_warn(struct notifier_block *nb, unsigned long type, void *data) + u64 value_msb; + + value_lsb = be64_to_cpu(eqe->data.temp_warning.sensor_warning_lsb); ++ /* bit 1-63 are not supported for NICs, ++ * hence read only bit 0 (asic) from lsb. ++ */ ++ value_lsb &= 0x1; + value_msb = be64_to_cpu(eqe->data.temp_warning.sensor_warning_msb); + + mlx5_core_warn(events->dev, +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5e-avoid-warn_on-when-configuring-mqprio-with.patch b/queue-6.6/net-mlx5e-avoid-warn_on-when-configuring-mqprio-with.patch new file mode 100644 index 0000000000..f1bd29bfc0 --- /dev/null +++ b/queue-6.6/net-mlx5e-avoid-warn_on-when-configuring-mqprio-with.patch @@ -0,0 +1,49 @@ +From d85da5f2954200b3e0272629439e56d07baeb66e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Feb 2025 23:35:16 +0200 +Subject: net/mlx5e: Avoid WARN_ON when configuring MQPRIO with HTB offload + enabled + +From: Carolina Jubran + +[ Upstream commit 689805dcc474c2accb5cffbbcea1c06ee4a54570 ] + +When attempting to enable MQPRIO while HTB offload is already +configured, the driver currently returns `-EINVAL` and triggers a +`WARN_ON`, leading to an unnecessary call trace. + +Update the code to handle this case more gracefully by returning +`-EOPNOTSUPP` instead, while also providing a helpful user message. + +Signed-off-by: Carolina Jubran +Reviewed-by: Yael Chemla +Reviewed-by: Cosmin Ratiu +Signed-off-by: Tariq Toukan +Reviewed-by: Kalesh AP +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index d9dc7280302eb..5c6f01abdcb91 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -3627,8 +3627,11 @@ static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, + /* MQPRIO is another toplevel qdisc that can't be attached + * simultaneously with the offloaded HTB. + */ +- if (WARN_ON(mlx5e_selq_is_htb_enabled(&priv->selq))) +- return -EINVAL; ++ if (mlx5e_selq_is_htb_enabled(&priv->selq)) { ++ NL_SET_ERR_MSG_MOD(mqprio->extack, ++ "MQPRIO cannot be configured when HTB offload is enabled."); ++ return -EOPNOTSUPP; ++ } + + switch (mqprio->mode) { + case TC_MQPRIO_MODE_DCB: +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5e-reduce-rep-rxq-depth-to-256-for-ecpf.patch b/queue-6.6/net-mlx5e-reduce-rep-rxq-depth-to-256-for-ecpf.patch new file mode 100644 index 0000000000..b1c562edeb --- /dev/null +++ b/queue-6.6/net-mlx5e-reduce-rep-rxq-depth-to-256-for-ecpf.patch @@ -0,0 +1,75 @@ +From c77f3a396942e2df6c7a6c8b5bb3c0e607d9bf19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 12:17:08 +0200 +Subject: net/mlx5e: reduce rep rxq depth to 256 for ECPF + +From: William Tu + +[ Upstream commit b9cc8f9d700867aaa77aedddfea85e53d5e5d584 ] + +By experiments, a single queue representor netdev consumes kernel +memory around 2.8MB, and 1.8MB out of the 2.8MB is due to page +pool for the RXQ. Scaling to a thousand representors consumes 2.8GB, +which becomes a memory pressure issue for embedded devices such as +BlueField-2 16GB / BlueField-3 32GB memory. + +Since representor netdevs mostly handles miss traffic, and ideally, +most of the traffic will be offloaded, reduce the default non-uplink +rep netdev's RXQ default depth from 1024 to 256 if mdev is ecpf eswitch +manager. This saves around 1MB of memory per regular RQ, +(1024 - 256) * 2KB, allocated from page pool. + +With rxq depth of 256, the netlink page pool tool reports +$./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml \ + --dump page-pool-get + {'id': 277, + 'ifindex': 9, + 'inflight': 128, + 'inflight-mem': 786432, + 'napi-id': 775}] + +This is due to mtu 1500 + headroom consumes half pages, so 256 rxq +entries consumes around 128 pages (thus create a page pool with +size 128), shown above at inflight. + +Note that each netdev has multiple types of RQs, including +Regular RQ, XSK, PTP, Drop, Trap RQ. Since non-uplink representor +only supports regular rq, this patch only changes the regular RQ's +default depth. + +Signed-off-by: William Tu +Reviewed-by: Bodong Wang +Reviewed-by: Saeed Mahameed +Signed-off-by: Tariq Toukan +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250209101716.112774-8-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 39d8e63e8856d..851c499faa795 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -63,6 +63,7 @@ + #define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \ + max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE) + #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1 ++#define MLX5E_REP_PARAMS_DEF_LOG_RQ_SIZE 0x8 + + static const char mlx5e_rep_driver_name[] = "mlx5e_rep"; + +@@ -798,6 +799,8 @@ static void mlx5e_build_rep_params(struct net_device *netdev) + + /* RQ */ + mlx5e_build_rq_params(mdev, params); ++ if (!mlx5e_is_uplink_rep(priv) && mlx5_core_is_ecpf(mdev)) ++ params->log_rq_mtu_frames = MLX5E_REP_PARAMS_DEF_LOG_RQ_SIZE; + + /* If netdev is already registered (e.g. move from nic profile to uplink, + * RTNL lock must be held before triggering netdev notifiers. +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5e-reduce-the-max-log-mpwrq-sz-for-ecpf-and-r.patch b/queue-6.6/net-mlx5e-reduce-the-max-log-mpwrq-sz-for-ecpf-and-r.patch new file mode 100644 index 0000000000..b2e08be455 --- /dev/null +++ b/queue-6.6/net-mlx5e-reduce-the-max-log-mpwrq-sz-for-ecpf-and-r.patch @@ -0,0 +1,92 @@ +From ca3aff3746ba7ab557d7cdd695615b83ca134605 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 12:17:07 +0200 +Subject: net/mlx5e: reduce the max log mpwrq sz for ECPF and reps + +From: William Tu + +[ Upstream commit e1d68ea58c7e9ebacd9ad7a99b25a3578fa62182 ] + +For the ECPF and representors, reduce the max MPWRQ size from 256KB (18) +to 128KB (17). This prepares the later patch for saving representor +memory. + +With Striding RQ, there is a minimum of 4 MPWQEs. So with 128KB of max +MPWRQ size, the minimal memory is 4 * 128KB = 512KB. When creating page +pool, consider 1500 mtu, the minimal page pool size will be 512KB/4KB = +128 pages = 256 rx ring entries (2 entries per page). + +Before this patch, setting RX ringsize (ethtool -G rx) to 256 causes +driver to allocate page pool size more than it needs due to max MPWRQ +is 256KB (18). Ex: 4 * 256KB = 1MB, 1MB/4KB = 256 pages, but actually +128 pages is good enough. Reducing the max MPWRQ to 128KB fixes the +limitation. + +Signed-off-by: William Tu +Signed-off-by: Tariq Toukan +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250209101716.112774-7-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 -- + .../net/ethernet/mellanox/mlx5/core/en/params.c | 15 +++++++++++---- + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index 20a6bc1a234f4..9cf33ae48c216 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -93,8 +93,6 @@ struct page_pool; + #define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) \ + MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, order_base_2(MLX5E_RX_MAX_HEAD)) + +-#define MLX5_MPWRQ_MAX_LOG_WQE_SZ 18 +- + /* Keep in sync with mlx5e_mpwrq_log_wqe_sz. + * These are theoretical maximums, which can be further restricted by + * capabilities. These values are used for static resource allocations and +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +index 775010e94cb7c..dcd5db907f102 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +@@ -9,6 +9,9 @@ + #include + #include + ++#define MLX5_MPWRQ_MAX_LOG_WQE_SZ 18 ++#define MLX5_REP_MPWRQ_MAX_LOG_WQE_SZ 17 ++ + static u8 mlx5e_mpwrq_min_page_shift(struct mlx5_core_dev *mdev) + { + u8 min_page_shift = MLX5_CAP_GEN_2(mdev, log_min_mkey_entity_size); +@@ -102,18 +105,22 @@ u8 mlx5e_mpwrq_log_wqe_sz(struct mlx5_core_dev *mdev, u8 page_shift, + enum mlx5e_mpwrq_umr_mode umr_mode) + { + u8 umr_entry_size = mlx5e_mpwrq_umr_entry_size(umr_mode); +- u8 max_pages_per_wqe, max_log_mpwqe_size; ++ u8 max_pages_per_wqe, max_log_wqe_size_calc; ++ u8 max_log_wqe_size_cap; + u16 max_wqe_size; + + /* Keep in sync with MLX5_MPWRQ_MAX_PAGES_PER_WQE. */ + max_wqe_size = mlx5e_get_max_sq_aligned_wqebbs(mdev) * MLX5_SEND_WQE_BB; + max_pages_per_wqe = ALIGN_DOWN(max_wqe_size - sizeof(struct mlx5e_umr_wqe), + MLX5_UMR_FLEX_ALIGNMENT) / umr_entry_size; +- max_log_mpwqe_size = ilog2(max_pages_per_wqe) + page_shift; ++ max_log_wqe_size_calc = ilog2(max_pages_per_wqe) + page_shift; ++ ++ WARN_ON_ONCE(max_log_wqe_size_calc < MLX5E_ORDER2_MAX_PACKET_MTU); + +- WARN_ON_ONCE(max_log_mpwqe_size < MLX5E_ORDER2_MAX_PACKET_MTU); ++ max_log_wqe_size_cap = mlx5_core_is_ecpf(mdev) ? ++ MLX5_REP_MPWRQ_MAX_LOG_WQE_SZ : MLX5_MPWRQ_MAX_LOG_WQE_SZ; + +- return min_t(u8, max_log_mpwqe_size, MLX5_MPWRQ_MAX_LOG_WQE_SZ); ++ return min_t(u8, max_log_wqe_size_calc, max_log_wqe_size_cap); + } + + u8 mlx5e_mpwrq_pages_per_wqe(struct mlx5_core_dev *mdev, u8 page_shift, +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5e-set-the-tx_queue_len-for-pfifo_fast.patch b/queue-6.6/net-mlx5e-set-the-tx_queue_len-for-pfifo_fast.patch new file mode 100644 index 0000000000..073707a46b --- /dev/null +++ b/queue-6.6/net-mlx5e-set-the-tx_queue_len-for-pfifo_fast.patch @@ -0,0 +1,44 @@ +From ff95722a86befd51e0273700eb6d569d2d5de097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 12:17:09 +0200 +Subject: net/mlx5e: set the tx_queue_len for pfifo_fast + +From: William Tu + +[ Upstream commit a38cc5706fb9f7dc4ee3a443f61de13ce1e410ed ] + +By default, the mq netdev creates a pfifo_fast qdisc. On a +system with 16 core, the pfifo_fast with 3 bands consumes +16 * 3 * 8 (size of pointer) * 1024 (default tx queue len) += 393KB. The patch sets the tx qlen to representor default +value, 128 (1< +Reviewed-by: Daniel Jurgens +Signed-off-by: Tariq Toukan +Reviewed-by: Michal Swiatkowski +Link: https://patch.msgid.link/20250209101716.112774-9-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +index 751d3ffcd2f6c..39d8e63e8856d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +@@ -829,6 +829,8 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev, + netdev->ethtool_ops = &mlx5e_rep_ethtool_ops; + + netdev->watchdog_timeo = 15 * HZ; ++ if (mlx5_core_is_ecpf(mdev)) ++ netdev->tx_queue_len = 1 << MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE; + + #if IS_ENABLED(CONFIG_MLX5_CLS_ACT) + netdev->hw_features |= NETIF_F_HW_TC; +-- +2.39.5 + diff --git a/queue-6.6/net-phylink-use-pl-link_interface-in-phylink_expects.patch b/queue-6.6/net-phylink-use-pl-link_interface-in-phylink_expects.patch new file mode 100644 index 0000000000..27ed438cee --- /dev/null +++ b/queue-6.6/net-phylink-use-pl-link_interface-in-phylink_expects.patch @@ -0,0 +1,59 @@ +From 029b96cdd2062b1e2092f9be3a998419f9386935 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 20:15:17 +0800 +Subject: net: phylink: use pl->link_interface in phylink_expects_phy() + +From: Choong Yong Liang + +[ Upstream commit b63263555eaafbf9ab1a82f2020bbee872d83759 ] + +The phylink_expects_phy() function allows MAC drivers to check if they are +expecting a PHY to attach. The checking condition in phylink_expects_phy() +aims to achieve the same result as the checking condition in +phylink_attach_phy(). + +However, the checking condition in phylink_expects_phy() uses +pl->link_config.interface, while phylink_attach_phy() uses +pl->link_interface. + +Initially, both pl->link_interface and pl->link_config.interface are set +to SGMII, and pl->cfg_link_an_mode is set to MLO_AN_INBAND. + +When the interface switches from SGMII to 2500BASE-X, +pl->link_config.interface is updated by phylink_major_config(). +At this point, pl->cfg_link_an_mode remains MLO_AN_INBAND, and +pl->link_config.interface is set to 2500BASE-X. +Subsequently, when the STMMAC interface is taken down +administratively and brought back up, it is blocked by +phylink_expects_phy(). + +Since phylink_expects_phy() and phylink_attach_phy() aim to achieve the +same result, phylink_expects_phy() should check pl->link_interface, +which never changes, instead of pl->link_config.interface, which is +updated by phylink_major_config(). + +Reviewed-by: Russell King (Oracle) +Signed-off-by: Choong Yong Liang +Link: https://patch.msgid.link/20250227121522.1802832-2-yong.liang.choong@linux.intel.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/phylink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c +index b5f012619e42d..800e8b9eb4532 100644 +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -1718,7 +1718,7 @@ bool phylink_expects_phy(struct phylink *pl) + { + if (pl->cfg_link_an_mode == MLO_AN_FIXED || + (pl->cfg_link_an_mode == MLO_AN_INBAND && +- phy_interface_mode_is_8023z(pl->link_config.interface))) ++ phy_interface_mode_is_8023z(pl->link_interface))) + return false; + return true; + } +-- +2.39.5 + diff --git a/queue-6.6/net-pktgen-fix-access-outside-of-user-given-buffer-i.patch b/queue-6.6/net-pktgen-fix-access-outside-of-user-given-buffer-i.patch new file mode 100644 index 0000000000..a9c265908c --- /dev/null +++ b/queue-6.6/net-pktgen-fix-access-outside-of-user-given-buffer-i.patch @@ -0,0 +1,50 @@ +From 8a58edc6b62ed29b400fe0d5f9c1685aecff0d24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Feb 2025 09:45:27 +0100 +Subject: net: pktgen: fix access outside of user given buffer in + pktgen_thread_write() + +From: Peter Seiderer + +[ Upstream commit 425e64440ad0a2f03bdaf04be0ae53dededbaa77 ] + +Honour the user given buffer size for the strn_len() calls (otherwise +strn_len() will access memory outside of the user given buffer). + +Signed-off-by: Peter Seiderer +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250219084527.20488-8-ps.report@gmx.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/pktgen.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 1decd6300f34c..6afea369ca213 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -1877,8 +1877,8 @@ static ssize_t pktgen_thread_write(struct file *file, + i = len; + + /* Read variable name */ +- +- len = strn_len(&user_buffer[i], sizeof(name) - 1); ++ max = min(sizeof(name) - 1, count - i); ++ len = strn_len(&user_buffer[i], max); + if (len < 0) + return len; + +@@ -1908,7 +1908,8 @@ static ssize_t pktgen_thread_write(struct file *file, + if (!strcmp(name, "add_device")) { + char f[32]; + memset(f, 0, 32); +- len = strn_len(&user_buffer[i], sizeof(f) - 1); ++ max = min(sizeof(f) - 1, count - i); ++ len = strn_len(&user_buffer[i], max); + if (len < 0) { + ret = len; + goto out; +-- +2.39.5 + diff --git a/queue-6.6/net-pktgen-fix-mpls-maximum-labels-list-parsing.patch b/queue-6.6/net-pktgen-fix-mpls-maximum-labels-list-parsing.patch new file mode 100644 index 0000000000..39f1368a62 --- /dev/null +++ b/queue-6.6/net-pktgen-fix-mpls-maximum-labels-list-parsing.patch @@ -0,0 +1,52 @@ +From f964176d7cec25a57c4ff5414eb1af445ec36955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 14:56:00 +0100 +Subject: net: pktgen: fix mpls maximum labels list parsing + +From: Peter Seiderer + +[ Upstream commit 2b15a0693f70d1e8119743ee89edbfb1271b3ea8 ] + +Fix mpls maximum labels list parsing up to MAX_MPLS_LABELS entries (instead +of up to MAX_MPLS_LABELS - 1). + +Addresses the following: + + $ echo "mpls 00000f00,00000f01,00000f02,00000f03,00000f04,00000f05,00000f06,00000f07,00000f08,00000f09,00000f0a,00000f0b,00000f0c,00000f0d,00000f0e,00000f0f" > /proc/net/pktgen/lo\@0 + -bash: echo: write error: Argument list too long + +Signed-off-by: Peter Seiderer +Reviewed-by: Simon Horman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/core/pktgen.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 359e24c3f22ca..1decd6300f34c 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -897,6 +897,10 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev) + pkt_dev->nr_labels = 0; + do { + __u32 tmp; ++ ++ if (n >= MAX_MPLS_LABELS) ++ return -E2BIG; ++ + len = hex32_arg(&buffer[i], 8, &tmp); + if (len <= 0) + return len; +@@ -908,8 +912,6 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev) + return -EFAULT; + i++; + n++; +- if (n >= MAX_MPLS_LABELS) +- return -E2BIG; + } while (c == ','); + + pkt_dev->nr_labels = n; +-- +2.39.5 + diff --git a/queue-6.6/net-smc-use-the-correct-ndev-to-find-pnetid-by-pneti.patch b/queue-6.6/net-smc-use-the-correct-ndev-to-find-pnetid-by-pneti.patch new file mode 100644 index 0000000000..314b1a7f48 --- /dev/null +++ b/queue-6.6/net-smc-use-the-correct-ndev-to-find-pnetid-by-pneti.patch @@ -0,0 +1,120 @@ +From 267d0e66f7328dc4e7aa3997cb6557a020b55f45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 20:43:04 +0800 +Subject: net/smc: use the correct ndev to find pnetid by pnetid table + +From: Guangguan Wang + +[ Upstream commit bfc6c67ec2d64d0ca4e5cc3e1ac84298a10b8d62 ] + +When using smc_pnet in SMC, it will only search the pnetid in the +base_ndev of the netdev hierarchy(both HW PNETID and User-defined +sw pnetid). This may not work for some scenarios when using SMC in +container on cloud environment. +In container, there have choices of different container network, +such as directly using host network, virtual network IPVLAN, veth, +etc. Different choices of container network have different netdev +hierarchy. Examples of netdev hierarchy show below. (eth0 and eth1 +in host below is the netdev directly related to the physical device). + _______________________________ + | _________________ | + | |POD | | + | | | | + | | eth0_________ | | + | |____| |__| | + | | | | + | | | | + | eth1|base_ndev| eth0_______ | + | | | | RDMA || + | host |_________| |_______|| + --------------------------------- + netdev hierarchy if directly using host network + ________________________________ + | _________________ | + | |POD __________ | | + | | |upper_ndev| | | + | |eth0|__________| | | + | |_______|_________| | + | |lower netdev | + | __|______ | + | eth1| | eth0_______ | + | |base_ndev| | RDMA || + | host |_________| |_______|| + --------------------------------- + netdev hierarchy if using IPVLAN + _______________________________ + | _____________________ | + | |POD _________ | | + | | |base_ndev|| | + | |eth0(veth)|_________|| | + | |____________|________| | + | |pairs | + | _______|_ | + | | | eth0_______ | + | veth|base_ndev| | RDMA || + | |_________| |_______|| + | _________ | + | eth1|base_ndev| | + | host |_________| | + --------------------------------- + netdev hierarchy if using veth +Due to some reasons, the eth1 in host is not RDMA attached netdevice, +pnetid is needed to map the eth1(in host) with RDMA device so that POD +can do SMC-R. Because the eth1(in host) is managed by CNI plugin(such +as Terway, network management plugin in container environment), and in +cloud environment the eth(in host) can dynamically be inserted by CNI +when POD create and dynamically be removed by CNI when POD destroy and +no POD related to the eth(in host) anymore. It is hard to config the +pnetid to the eth1(in host). But it is easy to config the pnetid to the +netdevice which can be seen in POD. When do SMC-R, both the container +directly using host network and the container using veth network can +successfully match the RDMA device, because the configured pnetid netdev +is a base_ndev. But the container using IPVLAN can not successfully +match the RDMA device and 0x03030000 fallback happens, because the +configured pnetid netdev is not a base_ndev. Additionally, if config +pnetid to the eth1(in host) also can not work for matching RDMA device +when using veth network and doing SMC-R in POD. + +To resolve the problems list above, this patch extends to search user +-defined sw pnetid in the clc handshake ndev when no pnetid can be found +in the base_ndev, and the base_ndev take precedence over ndev for backward +compatibility. This patch also can unify the pnetid setup of different +network choices list above in container(Config user-defined sw pnetid in +the netdevice can be seen in POD). + +Signed-off-by: Guangguan Wang +Reviewed-by: Wenjia Zhang +Reviewed-by: Halil Pasic +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/smc/smc_pnet.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c +index dbcc72b43d0c0..d44d7f427fc94 100644 +--- a/net/smc/smc_pnet.c ++++ b/net/smc/smc_pnet.c +@@ -1084,14 +1084,16 @@ static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev, + struct smc_init_info *ini) + { + u8 ndev_pnetid[SMC_MAX_PNETID_LEN]; ++ struct net_device *base_ndev; + struct net *net; + +- ndev = pnet_find_base_ndev(ndev); ++ base_ndev = pnet_find_base_ndev(ndev); + net = dev_net(ndev); +- if (smc_pnetid_by_dev_port(ndev->dev.parent, ndev->dev_port, ++ if (smc_pnetid_by_dev_port(base_ndev->dev.parent, base_ndev->dev_port, + ndev_pnetid) && ++ smc_pnet_find_ndev_pnetid_by_table(base_ndev, ndev_pnetid) && + smc_pnet_find_ndev_pnetid_by_table(ndev, ndev_pnetid)) { +- smc_pnet_find_rdma_dev(ndev, ini); ++ smc_pnet_find_rdma_dev(base_ndev, ini); + return; /* pnetid could not be determined */ + } + _smc_pnet_find_roce_by_pnetid(ndev_pnetid, ini, NULL, net); +-- +2.39.5 + diff --git a/queue-6.6/net-xgene-v2-remove-incorrect-acpi_ptr-annotation.patch b/queue-6.6/net-xgene-v2-remove-incorrect-acpi_ptr-annotation.patch new file mode 100644 index 0000000000..3521c3fdcd --- /dev/null +++ b/queue-6.6/net-xgene-v2-remove-incorrect-acpi_ptr-annotation.patch @@ -0,0 +1,47 @@ +From 26763c7b34c5a456bcb7c24dcfb1b476def4dbe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 17:33:33 +0100 +Subject: net: xgene-v2: remove incorrect ACPI_PTR annotation + +From: Arnd Bergmann + +[ Upstream commit 01358e8fe922f716c05d7864ac2213b2440026e7 ] + +Building with W=1 shows a warning about xge_acpi_match being unused when +CONFIG_ACPI is disabled: + +drivers/net/ethernet/apm/xgene-v2/main.c:723:36: error: unused variable 'xge_acpi_match' [-Werror,-Wunused-const-variable] + +Signed-off-by: Arnd Bergmann +Link: https://patch.msgid.link/20250225163341.4168238-2-arnd@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/apm/xgene-v2/main.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c +index 379d19d18dbed..5808e3c73a8f4 100644 +--- a/drivers/net/ethernet/apm/xgene-v2/main.c ++++ b/drivers/net/ethernet/apm/xgene-v2/main.c +@@ -9,8 +9,6 @@ + + #include "main.h" + +-static const struct acpi_device_id xge_acpi_match[]; +- + static int xge_get_resources(struct xge_pdata *pdata) + { + struct platform_device *pdev; +@@ -733,7 +731,7 @@ MODULE_DEVICE_TABLE(acpi, xge_acpi_match); + static struct platform_driver xge_driver = { + .driver = { + .name = "xgene-enet-v2", +- .acpi_match_table = ACPI_PTR(xge_acpi_match), ++ .acpi_match_table = xge_acpi_match, + }, + .probe = xge_probe, + .remove = xge_remove, +-- +2.39.5 + diff --git a/queue-6.6/netfilter-conntrack-bound-nf_conntrack-sysctl-writes.patch b/queue-6.6/netfilter-conntrack-bound-nf_conntrack-sysctl-writes.patch new file mode 100644 index 0000000000..950504a703 --- /dev/null +++ b/queue-6.6/netfilter-conntrack-bound-nf_conntrack-sysctl-writes.patch @@ -0,0 +1,85 @@ +From f460dae8073f29c0ac0602f6721d5ffbd1188953 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Jan 2025 18:06:30 +0100 +Subject: netfilter: conntrack: Bound nf_conntrack sysctl writes + +From: Nicolas Bouchinet + +[ Upstream commit 8b6861390ffee6b8ed78b9395e3776c16fec6579 ] + +nf_conntrack_max and nf_conntrack_expect_max sysctls were authorized to +be written any negative value, which would then be stored in the +unsigned int variables nf_conntrack_max and nf_ct_expect_max variables. + +While the do_proc_dointvec_conv function is supposed to limit writing +handled by proc_dointvec proc_handler to INT_MAX. Such a negative value +being written in an unsigned int leads to a very high value, exceeding +this limit. + +Moreover, the nf_conntrack_expect_max sysctl documentation specifies the +minimum value is 1. + +The proc_handlers have thus been updated to proc_dointvec_minmax in +order to specify the following write bounds : + +* Bound nf_conntrack_max sysctl writings between SYSCTL_ZERO + and SYSCTL_INT_MAX. + +* Bound nf_conntrack_expect_max sysctl writings between SYSCTL_ONE + and SYSCTL_INT_MAX as defined in the sysctl documentation. + +With this patch applied, sysctl writes outside the defined in the bound +will thus lead to a write error : + +``` +sysctl -w net.netfilter.nf_conntrack_expect_max=-1 +sysctl: setting key "net.netfilter.nf_conntrack_expect_max": Invalid argument +``` + +Signed-off-by: Nicolas Bouchinet +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_standalone.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index 559665467b04d..1d5de1d9f008d 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -621,7 +621,9 @@ static struct ctl_table nf_ct_sysctl_table[] = { + .data = &nf_conntrack_max, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_INT_MAX, + }, + [NF_SYSCTL_CT_COUNT] = { + .procname = "nf_conntrack_count", +@@ -657,7 +659,9 @@ static struct ctl_table nf_ct_sysctl_table[] = { + .data = &nf_ct_expect_max, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ONE, ++ .extra2 = SYSCTL_INT_MAX, + }, + [NF_SYSCTL_CT_ACCT] = { + .procname = "nf_conntrack_acct", +@@ -951,7 +955,9 @@ static struct ctl_table nf_ct_netfilter_table[] = { + .data = &nf_conntrack_max, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = SYSCTL_ZERO, ++ .extra2 = SYSCTL_INT_MAX, + }, + { } + }; +-- +2.39.5 + diff --git a/queue-6.6/nfs-don-t-allow-waiting-for-exiting-tasks.patch b/queue-6.6/nfs-don-t-allow-waiting-for-exiting-tasks.patch new file mode 100644 index 0000000000..5dfa2ceca9 --- /dev/null +++ b/queue-6.6/nfs-don-t-allow-waiting-for-exiting-tasks.patch @@ -0,0 +1,108 @@ +From d80e561e42874f8636ec2c687258afdebc3bd5c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Mar 2025 13:19:18 -0400 +Subject: NFS: Don't allow waiting for exiting tasks + +From: Trond Myklebust + +[ Upstream commit 8d3ca331026a7f9700d3747eed59a67b8f828cdc ] + +Once a task calls exit_signals() it can no longer be signalled. So do +not allow it to do killable waits. + +Reviewed-by: Jeff Layton +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/inode.c | 2 ++ + fs/nfs/internal.h | 5 +++++ + fs/nfs/nfs3proc.c | 2 +- + fs/nfs/nfs4proc.c | 9 +++++++-- + 4 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 56bbf59bda3cf..06230baaa554e 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -74,6 +74,8 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr) + + int nfs_wait_bit_killable(struct wait_bit_key *key, int mode) + { ++ if (unlikely(nfs_current_task_exiting())) ++ return -EINTR; + schedule(); + if (signal_pending_state(mode, current)) + return -ERESTARTSYS; +diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h +index ca49d999159eb..c29ad2e1d4163 100644 +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -865,6 +865,11 @@ static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid) + NFS4_STATEID_OTHER_SIZE); + } + ++static inline bool nfs_current_task_exiting(void) ++{ ++ return (current->flags & PF_EXITING) != 0; ++} ++ + static inline bool nfs_error_is_fatal(int err) + { + switch (err) { +diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c +index 4bf208a0a8e99..715753f41fb07 100644 +--- a/fs/nfs/nfs3proc.c ++++ b/fs/nfs/nfs3proc.c +@@ -39,7 +39,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) + __set_current_state(TASK_KILLABLE|TASK_FREEZABLE_UNSAFE); + schedule_timeout(NFS_JUKEBOX_RETRY_TIME); + res = -ERESTARTSYS; +- } while (!fatal_signal_pending(current)); ++ } while (!fatal_signal_pending(current) && !nfs_current_task_exiting()); + return res; + } + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index c140427e322ce..1b94a55215e7d 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -422,6 +422,8 @@ static int nfs4_delay_killable(long *timeout) + { + might_sleep(); + ++ if (unlikely(nfs_current_task_exiting())) ++ return -EINTR; + __set_current_state(TASK_KILLABLE|TASK_FREEZABLE_UNSAFE); + schedule_timeout(nfs4_update_delay(timeout)); + if (!__fatal_signal_pending(current)) +@@ -433,6 +435,8 @@ static int nfs4_delay_interruptible(long *timeout) + { + might_sleep(); + ++ if (unlikely(nfs_current_task_exiting())) ++ return -EINTR; + __set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE_UNSAFE); + schedule_timeout(nfs4_update_delay(timeout)); + if (!signal_pending(current)) +@@ -1712,7 +1716,8 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, + rcu_read_unlock(); + trace_nfs4_open_stateid_update_wait(state->inode, stateid, 0); + +- if (!fatal_signal_pending(current)) { ++ if (!fatal_signal_pending(current) && ++ !nfs_current_task_exiting()) { + if (schedule_timeout(5*HZ) == 0) + status = -EAGAIN; + else +@@ -3494,7 +3499,7 @@ static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst, + write_sequnlock(&state->seqlock); + trace_nfs4_close_stateid_update_wait(state->inode, dst, 0); + +- if (fatal_signal_pending(current)) ++ if (fatal_signal_pending(current) || nfs_current_task_exiting()) + status = -EINTR; + else + if (schedule_timeout(5*HZ) != 0) +-- +2.39.5 + diff --git a/queue-6.6/nfsv4-check-for-delegation-validity-in-nfs_start_del.patch b/queue-6.6/nfsv4-check-for-delegation-validity-in-nfs_start_del.patch new file mode 100644 index 0000000000..2b23b21580 --- /dev/null +++ b/queue-6.6/nfsv4-check-for-delegation-validity-in-nfs_start_del.patch @@ -0,0 +1,36 @@ +From f4c2ca8712673514c2ccfddbacea2582372724e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 19:20:53 -0400 +Subject: NFSv4: Check for delegation validity in + nfs_start_delegation_return_locked() + +From: Trond Myklebust + +[ Upstream commit 9e8f324bd44c1fe026b582b75213de4eccfa1163 ] + +Check that the delegation is still attached after taking the spin lock +in nfs_start_delegation_return_locked(). + +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/delegation.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c +index 55cfa1c4e0a65..bbd582d8a7dc9 100644 +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -297,7 +297,8 @@ nfs_start_delegation_return_locked(struct nfs_inode *nfsi) + if (delegation == NULL) + goto out; + spin_lock(&delegation->lock); +- if (!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { ++ if (delegation->inode && ++ !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { + clear_bit(NFS_DELEGATION_RETURN_DELAYED, &delegation->flags); + /* Refcount matched in nfs_end_delegation_return() */ + ret = nfs_get_delegation(delegation); +-- +2.39.5 + diff --git a/queue-6.6/nfsv4-treat-enetunreach-errors-as-fatal-for-state-re.patch b/queue-6.6/nfsv4-treat-enetunreach-errors-as-fatal-for-state-re.patch new file mode 100644 index 0000000000..faef3edef1 --- /dev/null +++ b/queue-6.6/nfsv4-treat-enetunreach-errors-as-fatal-for-state-re.patch @@ -0,0 +1,46 @@ +From 3a72dc932a4b746fe993c43657779ae2e485e615 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 20:35:33 -0400 +Subject: NFSv4: Treat ENETUNREACH errors as fatal for state recovery + +From: Trond Myklebust + +[ Upstream commit 0af5fb5ed3d2fd9e110c6112271f022b744a849a ] + +If a containerised process is killed and causes an ENETUNREACH or +ENETDOWN error to be propagated to the state manager, then mark the +nfs_client as being dead so that we don't loop in functions that are +expecting recovery to succeed. + +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + fs/nfs/nfs4state.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 794bb4aa588d3..9fc71dc090c25 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -2741,7 +2741,15 @@ static void nfs4_state_manager(struct nfs_client *clp) + pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s" + " with error %d\n", section_sep, section, + clp->cl_hostname, -status); +- ssleep(1); ++ switch (status) { ++ case -ENETDOWN: ++ case -ENETUNREACH: ++ nfs_mark_client_ready(clp, -EIO); ++ break; ++ default: ++ ssleep(1); ++ break; ++ } + out_drain: + memalloc_nofs_restore(memflags); + nfs4_end_drain_session(clp); +-- +2.39.5 + diff --git a/queue-6.6/nvme-map-uring_cmd-data-even-if-address-is-0.patch b/queue-6.6/nvme-map-uring_cmd-data-even-if-address-is-0.patch new file mode 100644 index 0000000000..871e0d1857 --- /dev/null +++ b/queue-6.6/nvme-map-uring_cmd-data-even-if-address-is-0.patch @@ -0,0 +1,48 @@ +From 3a7a1c26111bbdc05abbf63eb0b23015f6328e57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 14:39:13 -0800 +Subject: nvme: map uring_cmd data even if address is 0 + +From: Xinyu Zhang + +[ Upstream commit 99fde895ff56ac2241e7b7b4566731d72f2fdaa7 ] + +When using kernel registered bvec fixed buffers, the "address" is +actually the offset into the bvec rather than userspace address. +Therefore it can be 0. + +We can skip checking whether the address is NULL before mapping +uring_cmd data. Bad userspace address will be handled properly later when +the user buffer is imported. + +With this patch, we will be able to use the kernel registered bvec fixed +buffers in io_uring NVMe passthru with ublk zero-copy support. + +Reviewed-by: Caleb Sander Mateos +Reviewed-by: Jens Axboe +Reviewed-by: Ming Lei +Signed-off-by: Xinyu Zhang +Signed-off-by: Keith Busch +Link: https://lore.kernel.org/r/20250227223916.143006-4-kbusch@meta.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/ioctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c +index 4ce31f9f06947..83908f2dd07fe 100644 +--- a/drivers/nvme/host/ioctl.c ++++ b/drivers/nvme/host/ioctl.c +@@ -618,7 +618,7 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + return PTR_ERR(req); + req->timeout = d.timeout_ms ? msecs_to_jiffies(d.timeout_ms) : 0; + +- if (d.addr && d.data_len) { ++ if (d.data_len) { + ret = nvme_map_user_request(req, d.addr, + d.data_len, nvme_to_user_ptr(d.metadata), + d.metadata_len, 0, &meta, ioucmd, vec); +-- +2.39.5 + diff --git a/queue-6.6/nvme-pci-add-quirks-for-device-126f-1001.patch b/queue-6.6/nvme-pci-add-quirks-for-device-126f-1001.patch new file mode 100644 index 0000000000..6aa81f0f7b --- /dev/null +++ b/queue-6.6/nvme-pci-add-quirks-for-device-126f-1001.patch @@ -0,0 +1,49 @@ +From 6b2ea9d8097e3fd8864f95b1ac91a2db6ca29d75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Apr 2025 20:17:25 +0800 +Subject: nvme-pci: add quirks for device 126f:1001 + +From: Wentao Guan + +[ Upstream commit 5b960f92ac3e5b4d7f60a506a6b6735eead1da01 ] + +This commit adds NVME_QUIRK_NO_DEEPEST_PS and NVME_QUIRK_BOGUS_NID for +device [126f:1001]. + +It is similar to commit e89086c43f05 ("drivers/nvme: Add quirks for +device 126f:2262") + +Diff is according the dmesg, use NVME_QUIRK_IGNORE_DEV_SUBNQN. + +dmesg | grep -i nvme0: + nvme nvme0: pci function 0000:01:00.0 + nvme nvme0: missing or invalid SUBNQN field. + nvme nvme0: 12/0/0 default/read/poll queues + +Link:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e89086c43f0500bc7c4ce225495b73b8ce234c1f +Signed-off-by: Wentao Guan +Signed-off-by: WangYuli +Reviewed-by: Sagi Grimberg +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 1e5c8220e365c..91c2dacb90430 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3429,6 +3429,9 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */ + .driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, }, ++ { PCI_DEVICE(0x126f, 0x1001), /* Silicon Motion generic */ ++ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | ++ NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x126f, 0x2262), /* Silicon Motion generic */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_BOGUS_NID, }, +-- +2.39.5 + diff --git a/queue-6.6/nvme-pci-add-quirks-for-wdc-blue-sn550-15b7-5009.patch b/queue-6.6/nvme-pci-add-quirks-for-wdc-blue-sn550-15b7-5009.patch new file mode 100644 index 0000000000..c0bb7ed36d --- /dev/null +++ b/queue-6.6/nvme-pci-add-quirks-for-wdc-blue-sn550-15b7-5009.patch @@ -0,0 +1,87 @@ +From e20922b8a55a4764b4434986467ed571e3fcc5a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Apr 2025 10:40:10 +0800 +Subject: nvme-pci: add quirks for WDC Blue SN550 15b7:5009 + +From: Wentao Guan + +[ Upstream commit ab35ad950d439ec3409509835d229b3d93d3c7f9 ] + +Add two quirks for the WDC Blue SN550 (PCI ID 15b7:5009) based on user +reports and hardware analysis: + + - NVME_QUIRK_NO_DEEPEST_PS: + liaozw talked to me the problem and solved with + nvme_core.default_ps_max_latency_us=0, so add the quirk. + I also found some reports in the following link. + + - NVME_QUIRK_BROKEN_MSI: + after get the lspci from Jack Rio. + I think that the disk also have NVME_QUIRK_BROKEN_MSI. + described in commit d5887dc6b6c0 ("nvme-pci: Add quirk for broken MSIs") + as sean said in link which match the MSI 1/32 and MSI-X 17. + +Log: +lspci -nn | grep -i memory +03:00.0 Non-Volatile memory controller [0108]: Sandisk Corp SanDisk Ultra 3D / WD PC SN530, IX SN530, Blue SN550 NVMe SSD (DRAM-less) [15b7:5009] (rev 01) +lspci -v -d 15b7:5009 +03:00.0 Non-Volatile memory controller: Sandisk Corp SanDisk Ultra 3D / WD PC SN530, IX SN530, Blue SN550 NVMe SSD (DRAM-less) (rev 01) (prog-if 02 [NVM Express]) + Subsystem: Sandisk Corp WD Blue SN550 NVMe SSD + Flags: bus master, fast devsel, latency 0, IRQ 35, IOMMU group 10 + Memory at fe800000 (64-bit, non-prefetchable) [size=16K] + Memory at fe804000 (64-bit, non-prefetchable) [size=256] + Capabilities: [80] Power Management version 3 + Capabilities: [90] MSI: Enable- Count=1/32 Maskable- 64bit+ + Capabilities: [b0] MSI-X: Enable+ Count=17 Masked- + Capabilities: [c0] Express Endpoint, MSI 00 + Capabilities: [100] Advanced Error Reporting + Capabilities: [150] Device Serial Number 00-00-00-00-00-00-00-00 + Capabilities: [1b8] Latency Tolerance Reporting + Capabilities: [300] Secondary PCI Express + Capabilities: [900] L1 PM Substates + Kernel driver in use: nvme +dmesg | grep nvme +[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.12.20-amd64-desktop-rolling root=UUID= ro splash quiet nvme_core.default_ps_max_latency_us=0 DEEPIN_GFXMODE= +[ 0.059301] Kernel command line: BOOT_IMAGE=/vmlinuz-6.12.20-amd64-desktop-rolling root=UUID= ro splash quiet nvme_core.default_ps_max_latency_us=0 DEEPIN_GFXMODE= +[ 0.542430] nvme nvme0: pci function 0000:03:00.0 +[ 0.560426] nvme nvme0: allocated 32 MiB host memory buffer. +[ 0.562491] nvme nvme0: 16/0/0 default/read/poll queues +[ 0.567764] nvme0n1: p1 p2 p3 p4 p5 p6 p7 p8 p9 +[ 6.388726] EXT4-fs (nvme0n1p7): mounted filesystem ro with ordered data mode. Quota mode: none. +[ 6.893421] EXT4-fs (nvme0n1p7): re-mounted r/w. Quota mode: none. +[ 7.125419] Adding 16777212k swap on /dev/nvme0n1p8. Priority:-2 extents:1 across:16777212k SS +[ 7.157588] EXT4-fs (nvme0n1p6): mounted filesystem r/w with ordered data mode. Quota mode: none. +[ 7.165021] EXT4-fs (nvme0n1p9): mounted filesystem r/w with ordered data mode. Quota mode: none. +[ 8.036932] nvme nvme0: using unchecked data buffer +[ 8.096023] block nvme0n1: No UUID available providing old NGUID + +Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5887dc6b6c054d0da3cd053afc15b7be1f45ff6 +Link: https://lore.kernel.org/all/20240422162822.3539156-1-sean.anderson@linux.dev/ +Reported-by: liaozw +Closes: https://bbs.deepin.org.cn/post/286300 +Reported-by: rugk +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=208123 +Signed-off-by: Wentao Guan +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 91c2dacb90430..1a33be577397f 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3455,6 +3455,9 @@ static const struct pci_device_id nvme_id_table[] = { + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x15b7, 0x5008), /* Sandisk SN530 */ + .driver_data = NVME_QUIRK_BROKEN_MSI }, ++ { PCI_DEVICE(0x15b7, 0x5009), /* Sandisk SN550 */ ++ .driver_data = NVME_QUIRK_BROKEN_MSI | ++ NVME_QUIRK_NO_DEEPEST_PS }, + { PCI_DEVICE(0x1987, 0x5012), /* Phison E12 */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, + { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ +-- +2.39.5 + diff --git a/queue-6.6/nvmem-core-update-raw_len-if-the-bit-reading-is-requ.patch b/queue-6.6/nvmem-core-update-raw_len-if-the-bit-reading-is-requ.patch new file mode 100644 index 0000000000..b1a5a1a09c --- /dev/null +++ b/queue-6.6/nvmem-core-update-raw_len-if-the-bit-reading-is-requ.patch @@ -0,0 +1,42 @@ +From 115e767c05798e260ae2d486f8a757f34c8b1683 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 12:22:48 +0100 +Subject: nvmem: core: update raw_len if the bit reading is required + +From: Dmitry Baryshkov + +[ Upstream commit 6786484223d5705bf7f919c1e5055d478ebeec32 ] + +If NVMEM cell uses bit offset or specifies bit truncation, update +raw_len manually (following the cell->bytes update), ensuring that the +NVMEM access is still word-aligned. + +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20250411112251.68002-11-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/nvmem/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index 3d69c76f19236..dd00cc09ae5ec 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -456,9 +456,11 @@ static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, + cell->nbits = info->nbits; + cell->np = info->np; + +- if (cell->nbits) ++ if (cell->nbits) { + cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset, + BITS_PER_BYTE); ++ cell->raw_len = ALIGN(cell->bytes, nvmem->word_size); ++ } + + if (!IS_ALIGNED(cell->offset, nvmem->stride)) { + dev_err(&nvmem->dev, +-- +2.39.5 + diff --git a/queue-6.6/nvmem-core-verify-cell-s-raw_len.patch b/queue-6.6/nvmem-core-verify-cell-s-raw_len.patch new file mode 100644 index 0000000000..572b467f86 --- /dev/null +++ b/queue-6.6/nvmem-core-verify-cell-s-raw_len.patch @@ -0,0 +1,48 @@ +From 75d478fd85eefe7a7de969f37b13db90432fb0cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 12:22:47 +0100 +Subject: nvmem: core: verify cell's raw_len + +From: Dmitry Baryshkov + +[ Upstream commit 13bcd440f2ff38cd7e42a179c223d4b833158b33 ] + +Check that the NVMEM cell's raw_len is a aligned to word_size. Otherwise +Otherwise drivers might face incomplete read while accessing the last +part of the NVMEM cell. + +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20250411112251.68002-10-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/nvmem/core.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c +index 3ea94bc26e800..3d69c76f19236 100644 +--- a/drivers/nvmem/core.c ++++ b/drivers/nvmem/core.c +@@ -467,6 +467,18 @@ static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, + return -EINVAL; + } + ++ if (!IS_ALIGNED(cell->raw_len, nvmem->word_size)) { ++ dev_err(&nvmem->dev, ++ "cell %s raw len %zd unaligned to nvmem word size %d\n", ++ cell->name ?: "", cell->raw_len, ++ nvmem->word_size); ++ ++ if (info->raw_len) ++ return -EINVAL; ++ ++ cell->raw_len = ALIGN(cell->raw_len, nvmem->word_size); ++ } ++ + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.6/nvmem-qfprom-switch-to-4-byte-aligned-reads.patch b/queue-6.6/nvmem-qfprom-switch-to-4-byte-aligned-reads.patch new file mode 100644 index 0000000000..588137f86f --- /dev/null +++ b/queue-6.6/nvmem-qfprom-switch-to-4-byte-aligned-reads.patch @@ -0,0 +1,84 @@ +From eff82a5b8a69b8829101c986f3d838168bec29bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 12:22:49 +0100 +Subject: nvmem: qfprom: switch to 4-byte aligned reads + +From: Dmitry Baryshkov + +[ Upstream commit 3566a737db87a9bf360c2fd36433c5149f805f2e ] + +All platforms since Snapdragon 8 Gen1 (SM8450) require using 4-byte +reads to access QFPROM data. While older platforms were more than happy +with 1-byte reads, change the qfprom driver to use 4-byte reads for all +the platforms. Specify stride and word size of 4 bytes. To retain +compatibility with the existing DT and to simplify porting data from +vendor kernels, use fixup_dt_cell_info in order to bump alignment +requirements. + +Signed-off-by: Dmitry Baryshkov +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20250411112251.68002-12-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/nvmem/qfprom.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c +index 6c554040c6e67..7b0621fdbc82e 100644 +--- a/drivers/nvmem/qfprom.c ++++ b/drivers/nvmem/qfprom.c +@@ -321,19 +321,32 @@ static int qfprom_reg_read(void *context, + unsigned int reg, void *_val, size_t bytes) + { + struct qfprom_priv *priv = context; +- u8 *val = _val; +- int i = 0, words = bytes; ++ u32 *val = _val; + void __iomem *base = priv->qfpcorrected; ++ int words = DIV_ROUND_UP(bytes, sizeof(u32)); ++ int i; + + if (read_raw_data && priv->qfpraw) + base = priv->qfpraw; + +- while (words--) +- *val++ = readb(base + reg + i++); ++ for (i = 0; i < words; i++) ++ *val++ = readl(base + reg + i * sizeof(u32)); + + return 0; + } + ++/* Align reads to word boundary */ ++static void qfprom_fixup_dt_cell_info(struct nvmem_device *nvmem, ++ struct nvmem_cell_info *cell) ++{ ++ unsigned int byte_offset = cell->offset % sizeof(u32); ++ ++ cell->bit_offset += byte_offset * BITS_PER_BYTE; ++ cell->offset -= byte_offset; ++ if (byte_offset && !cell->nbits) ++ cell->nbits = cell->bytes * BITS_PER_BYTE; ++} ++ + static void qfprom_runtime_disable(void *data) + { + pm_runtime_disable(data); +@@ -358,10 +371,11 @@ static int qfprom_probe(struct platform_device *pdev) + struct nvmem_config econfig = { + .name = "qfprom", + .add_legacy_fixed_of_cells = true, +- .stride = 1, +- .word_size = 1, ++ .stride = 4, ++ .word_size = 4, + .id = NVMEM_DEVID_AUTO, + .reg_read = qfprom_reg_read, ++ .fixup_dt_cell_info = qfprom_fixup_dt_cell_info, + }; + struct device *dev = &pdev->dev; + struct resource *res; +-- +2.39.5 + diff --git a/queue-6.6/nvmem-rockchip-otp-add-rk3576-variant-data.patch b/queue-6.6/nvmem-rockchip-otp-add-rk3576-variant-data.patch new file mode 100644 index 0000000000..2f26adc425 --- /dev/null +++ b/queue-6.6/nvmem-rockchip-otp-add-rk3576-variant-data.patch @@ -0,0 +1,55 @@ +From 0f7c97eee4c8f2cd25230886541bdba629ccfaef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 12:22:42 +0100 +Subject: nvmem: rockchip-otp: add rk3576 variant data + +From: Heiko Stuebner + +[ Upstream commit 50d75a13a9ce880a5ef07a4ccc63ba561cc2e69a ] + +The variant works very similar to the rk3588, just with a different +read-offset and size. + +Signed-off-by: Heiko Stuebner +Tested-by: Nicolas Frattaroli +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20250411112251.68002-5-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/nvmem/rockchip-otp.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index a0252ac867bf7..c6684ab14e742 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -273,6 +273,14 @@ static const struct rockchip_data px30_data = { + .reg_read = px30_otp_read, + }; + ++static const struct rockchip_data rk3576_data = { ++ .size = 0x100, ++ .read_offset = 0x700, ++ .clks = px30_otp_clocks, ++ .num_clks = ARRAY_SIZE(px30_otp_clocks), ++ .reg_read = rk3588_otp_read, ++}; ++ + static const char * const rk3588_otp_clocks[] = { + "otp", "apb_pclk", "phy", "arb", + }; +@@ -294,6 +302,10 @@ static const struct of_device_id rockchip_otp_match[] = { + .compatible = "rockchip,rk3308-otp", + .data = &px30_data, + }, ++ { ++ .compatible = "rockchip,rk3576-otp", ++ .data = &rk3576_data, ++ }, + { + .compatible = "rockchip,rk3588-otp", + .data = &rk3588_data, +-- +2.39.5 + diff --git a/queue-6.6/nvmem-rockchip-otp-move-read-offset-into-variant-dat.patch b/queue-6.6/nvmem-rockchip-otp-move-read-offset-into-variant-dat.patch new file mode 100644 index 0000000000..76745461fa --- /dev/null +++ b/queue-6.6/nvmem-rockchip-otp-move-read-offset-into-variant-dat.patch @@ -0,0 +1,67 @@ +From 13c56862c3851f2153560765c97be80b9133f86c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 12:22:39 +0100 +Subject: nvmem: rockchip-otp: Move read-offset into variant-data + +From: Heiko Stuebner + +[ Upstream commit 6907e8093b3070d877ee607e5ceede60cfd08bde ] + +The RK3588 has an offset into the OTP area where the readable area begins +and automatically adds this to the start address. +Other variants are very much similar to rk3588, just with a different +offset, so move that value into variant-data. + +To match the size in bytes, store this value also in bytes and not in +number of blocks. + +Signed-off-by: Heiko Stuebner +Tested-by: Nicolas Frattaroli +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20250411112251.68002-2-srinivas.kandagatla@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/nvmem/rockchip-otp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c +index 7107d68a2f8c7..a0252ac867bf7 100644 +--- a/drivers/nvmem/rockchip-otp.c ++++ b/drivers/nvmem/rockchip-otp.c +@@ -59,7 +59,6 @@ + #define RK3588_OTPC_AUTO_EN 0x08 + #define RK3588_OTPC_INT_ST 0x84 + #define RK3588_OTPC_DOUT0 0x20 +-#define RK3588_NO_SECURE_OFFSET 0x300 + #define RK3588_NBYTES 4 + #define RK3588_BURST_NUM 1 + #define RK3588_BURST_SHIFT 8 +@@ -69,6 +68,7 @@ + + struct rockchip_data { + int size; ++ int read_offset; + const char * const *clks; + int num_clks; + nvmem_reg_read_t reg_read; +@@ -196,7 +196,7 @@ static int rk3588_otp_read(void *context, unsigned int offset, + addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; + addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; + addr_len = addr_end - addr_start; +- addr_start += RK3588_NO_SECURE_OFFSET; ++ addr_start += otp->data->read_offset / RK3588_NBYTES; + + buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); + if (!buf) +@@ -279,6 +279,7 @@ static const char * const rk3588_otp_clocks[] = { + + static const struct rockchip_data rk3588_data = { + .size = 0x400, ++ .read_offset = 0xc00, + .clks = rk3588_otp_clocks, + .num_clks = ARRAY_SIZE(rk3588_otp_clocks), + .reg_read = rk3588_otp_read, +-- +2.39.5 + diff --git a/queue-6.6/nvmet-tcp-don-t-restore-null-sk_state_change.patch b/queue-6.6/nvmet-tcp-don-t-restore-null-sk_state_change.patch new file mode 100644 index 0000000000..16f61d2329 --- /dev/null +++ b/queue-6.6/nvmet-tcp-don-t-restore-null-sk_state_change.patch @@ -0,0 +1,227 @@ +From 6b09c7311ef167a07d0180e7b6aa77f36307a333 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Apr 2025 16:06:21 +1000 +Subject: nvmet-tcp: don't restore null sk_state_change + +From: Alistair Francis + +[ Upstream commit 46d22b47df2741996af277a2838b95f130436c13 ] + +queue->state_change is set as part of nvmet_tcp_set_queue_sock(), but if +the TCP connection isn't established when nvmet_tcp_set_queue_sock() is +called then queue->state_change isn't set and sock->sk->sk_state_change +isn't replaced. + +As such we don't need to restore sock->sk->sk_state_change if +queue->state_change is NULL. + +This avoids NULL pointer dereferences such as this: + +[ 286.462026][ C0] BUG: kernel NULL pointer dereference, address: 0000000000000000 +[ 286.462814][ C0] #PF: supervisor instruction fetch in kernel mode +[ 286.463796][ C0] #PF: error_code(0x0010) - not-present page +[ 286.464392][ C0] PGD 8000000140620067 P4D 8000000140620067 PUD 114201067 PMD 0 +[ 286.465086][ C0] Oops: Oops: 0010 [#1] SMP KASAN PTI +[ 286.465559][ C0] CPU: 0 UID: 0 PID: 1628 Comm: nvme Not tainted 6.15.0-rc2+ #11 PREEMPT(voluntary) +[ 286.466393][ C0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 +[ 286.467147][ C0] RIP: 0010:0x0 +[ 286.467420][ C0] Code: Unable to access opcode bytes at 0xffffffffffffffd6. +[ 286.467977][ C0] RSP: 0018:ffff8883ae008580 EFLAGS: 00010246 +[ 286.468425][ C0] RAX: 0000000000000000 RBX: ffff88813fd34100 RCX: ffffffffa386cc43 +[ 286.469019][ C0] RDX: 1ffff11027fa68b6 RSI: 0000000000000008 RDI: ffff88813fd34100 +[ 286.469545][ C0] RBP: ffff88813fd34160 R08: 0000000000000000 R09: ffffed1027fa682c +[ 286.470072][ C0] R10: ffff88813fd34167 R11: 0000000000000000 R12: ffff88813fd344c3 +[ 286.470585][ C0] R13: ffff88813fd34112 R14: ffff88813fd34aec R15: ffff888132cdd268 +[ 286.471070][ C0] FS: 00007fe3c04c7d80(0000) GS:ffff88840743f000(0000) knlGS:0000000000000000 +[ 286.471644][ C0] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 286.472543][ C0] CR2: ffffffffffffffd6 CR3: 000000012daca000 CR4: 00000000000006f0 +[ 286.473500][ C0] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 286.474467][ C0] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 +[ 286.475453][ C0] Call Trace: +[ 286.476102][ C0] +[ 286.476719][ C0] tcp_fin+0x2bb/0x440 +[ 286.477429][ C0] tcp_data_queue+0x190f/0x4e60 +[ 286.478174][ C0] ? __build_skb_around+0x234/0x330 +[ 286.478940][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.479659][ C0] ? __pfx_tcp_data_queue+0x10/0x10 +[ 286.480431][ C0] ? tcp_try_undo_loss+0x640/0x6c0 +[ 286.481196][ C0] ? seqcount_lockdep_reader_access.constprop.0+0x82/0x90 +[ 286.482046][ C0] ? kvm_clock_get_cycles+0x14/0x30 +[ 286.482769][ C0] ? ktime_get+0x66/0x150 +[ 286.483433][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.484146][ C0] tcp_rcv_established+0x6e4/0x2050 +[ 286.484857][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.485523][ C0] ? ipv4_dst_check+0x160/0x2b0 +[ 286.486203][ C0] ? __pfx_tcp_rcv_established+0x10/0x10 +[ 286.486917][ C0] ? lock_release+0x217/0x2c0 +[ 286.487595][ C0] tcp_v4_do_rcv+0x4d6/0x9b0 +[ 286.488279][ C0] tcp_v4_rcv+0x2af8/0x3e30 +[ 286.488904][ C0] ? raw_local_deliver+0x51b/0xad0 +[ 286.489551][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.490198][ C0] ? __pfx_tcp_v4_rcv+0x10/0x10 +[ 286.490813][ C0] ? __pfx_raw_local_deliver+0x10/0x10 +[ 286.491487][ C0] ? __pfx_nf_confirm+0x10/0x10 [nf_conntrack] +[ 286.492275][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.492900][ C0] ip_protocol_deliver_rcu+0x8f/0x370 +[ 286.493579][ C0] ip_local_deliver_finish+0x297/0x420 +[ 286.494268][ C0] ip_local_deliver+0x168/0x430 +[ 286.494867][ C0] ? __pfx_ip_local_deliver+0x10/0x10 +[ 286.495498][ C0] ? __pfx_ip_local_deliver_finish+0x10/0x10 +[ 286.496204][ C0] ? ip_rcv_finish_core+0x19a/0x1f20 +[ 286.496806][ C0] ? lock_release+0x217/0x2c0 +[ 286.497414][ C0] ip_rcv+0x455/0x6e0 +[ 286.497945][ C0] ? __pfx_ip_rcv+0x10/0x10 +[ 286.498550][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.499137][ C0] ? __pfx_ip_rcv_finish+0x10/0x10 +[ 286.499763][ C0] ? lock_release+0x217/0x2c0 +[ 286.500327][ C0] ? dl_scaled_delta_exec+0xd1/0x2c0 +[ 286.500922][ C0] ? __pfx_ip_rcv+0x10/0x10 +[ 286.501480][ C0] __netif_receive_skb_one_core+0x166/0x1b0 +[ 286.502173][ C0] ? __pfx___netif_receive_skb_one_core+0x10/0x10 +[ 286.502903][ C0] ? lock_acquire+0x2b2/0x310 +[ 286.503487][ C0] ? process_backlog+0x372/0x1350 +[ 286.504087][ C0] ? lock_release+0x217/0x2c0 +[ 286.504642][ C0] process_backlog+0x3b9/0x1350 +[ 286.505214][ C0] ? process_backlog+0x372/0x1350 +[ 286.505779][ C0] __napi_poll.constprop.0+0xa6/0x490 +[ 286.506363][ C0] net_rx_action+0x92e/0xe10 +[ 286.506889][ C0] ? __pfx_net_rx_action+0x10/0x10 +[ 286.507437][ C0] ? timerqueue_add+0x1f0/0x320 +[ 286.507977][ C0] ? sched_clock_cpu+0x68/0x540 +[ 286.508492][ C0] ? lock_acquire+0x2b2/0x310 +[ 286.509043][ C0] ? kvm_sched_clock_read+0xd/0x20 +[ 286.509607][ C0] ? handle_softirqs+0x1aa/0x7d0 +[ 286.510187][ C0] handle_softirqs+0x1f2/0x7d0 +[ 286.510754][ C0] ? __pfx_handle_softirqs+0x10/0x10 +[ 286.511348][ C0] ? irqtime_account_irq+0x181/0x290 +[ 286.511937][ C0] ? __dev_queue_xmit+0x85d/0x3450 +[ 286.512510][ C0] do_softirq.part.0+0x89/0xc0 +[ 286.513100][ C0] +[ 286.513548][ C0] +[ 286.513953][ C0] __local_bh_enable_ip+0x112/0x140 +[ 286.514522][ C0] ? __dev_queue_xmit+0x85d/0x3450 +[ 286.515072][ C0] __dev_queue_xmit+0x872/0x3450 +[ 286.515619][ C0] ? nft_do_chain+0xe16/0x15b0 [nf_tables] +[ 286.516252][ C0] ? __pfx___dev_queue_xmit+0x10/0x10 +[ 286.516817][ C0] ? selinux_ip_postroute+0x43c/0xc50 +[ 286.517433][ C0] ? __pfx_selinux_ip_postroute+0x10/0x10 +[ 286.518061][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.518606][ C0] ? ip_output+0x164/0x4a0 +[ 286.519149][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.519671][ C0] ? ip_finish_output2+0x17d5/0x1fb0 +[ 286.520258][ C0] ip_finish_output2+0xb4b/0x1fb0 +[ 286.520787][ C0] ? __pfx_ip_finish_output2+0x10/0x10 +[ 286.521355][ C0] ? __ip_finish_output+0x15d/0x750 +[ 286.521890][ C0] ip_output+0x164/0x4a0 +[ 286.522372][ C0] ? __pfx_ip_output+0x10/0x10 +[ 286.522872][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.523402][ C0] ? _raw_spin_unlock_irqrestore+0x4c/0x60 +[ 286.524031][ C0] ? __pfx_ip_finish_output+0x10/0x10 +[ 286.524605][ C0] ? __ip_queue_xmit+0x999/0x2260 +[ 286.525200][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.525744][ C0] ? ipv4_dst_check+0x16a/0x2b0 +[ 286.526279][ C0] ? lock_release+0x217/0x2c0 +[ 286.526793][ C0] __ip_queue_xmit+0x1883/0x2260 +[ 286.527324][ C0] ? __skb_clone+0x54c/0x730 +[ 286.527827][ C0] __tcp_transmit_skb+0x209b/0x37a0 +[ 286.528374][ C0] ? __pfx___tcp_transmit_skb+0x10/0x10 +[ 286.528952][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.529472][ C0] ? seqcount_lockdep_reader_access.constprop.0+0x82/0x90 +[ 286.530152][ C0] ? trace_hardirqs_on+0x12/0x120 +[ 286.530691][ C0] tcp_write_xmit+0xb81/0x88b0 +[ 286.531224][ C0] ? mod_memcg_state+0x4d/0x60 +[ 286.531736][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.532253][ C0] __tcp_push_pending_frames+0x90/0x320 +[ 286.532826][ C0] tcp_send_fin+0x141/0xb50 +[ 286.533352][ C0] ? __pfx_tcp_send_fin+0x10/0x10 +[ 286.533908][ C0] ? __local_bh_enable_ip+0xab/0x140 +[ 286.534495][ C0] inet_shutdown+0x243/0x320 +[ 286.535077][ C0] nvme_tcp_alloc_queue+0xb3b/0x2590 [nvme_tcp] +[ 286.535709][ C0] ? do_raw_spin_lock+0x129/0x260 +[ 286.536314][ C0] ? __pfx_nvme_tcp_alloc_queue+0x10/0x10 [nvme_tcp] +[ 286.536996][ C0] ? do_raw_spin_unlock+0x54/0x1e0 +[ 286.537550][ C0] ? _raw_spin_unlock+0x29/0x50 +[ 286.538127][ C0] ? do_raw_spin_lock+0x129/0x260 +[ 286.538664][ C0] ? __pfx_do_raw_spin_lock+0x10/0x10 +[ 286.539249][ C0] ? nvme_tcp_alloc_admin_queue+0xd5/0x340 [nvme_tcp] +[ 286.539892][ C0] ? __wake_up+0x40/0x60 +[ 286.540392][ C0] nvme_tcp_alloc_admin_queue+0xd5/0x340 [nvme_tcp] +[ 286.541047][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.541589][ C0] nvme_tcp_setup_ctrl+0x8b/0x7a0 [nvme_tcp] +[ 286.542254][ C0] ? _raw_spin_unlock_irqrestore+0x4c/0x60 +[ 286.542887][ C0] ? __pfx_nvme_tcp_setup_ctrl+0x10/0x10 [nvme_tcp] +[ 286.543568][ C0] ? trace_hardirqs_on+0x12/0x120 +[ 286.544166][ C0] ? _raw_spin_unlock_irqrestore+0x35/0x60 +[ 286.544792][ C0] ? nvme_change_ctrl_state+0x196/0x2e0 [nvme_core] +[ 286.545477][ C0] nvme_tcp_create_ctrl+0x839/0xb90 [nvme_tcp] +[ 286.546126][ C0] nvmf_dev_write+0x3db/0x7e0 [nvme_fabrics] +[ 286.546775][ C0] ? rw_verify_area+0x69/0x520 +[ 286.547334][ C0] vfs_write+0x218/0xe90 +[ 286.547854][ C0] ? do_syscall_64+0x9f/0x190 +[ 286.548408][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 +[ 286.549037][ C0] ? syscall_exit_to_user_mode+0x93/0x280 +[ 286.549659][ C0] ? __pfx_vfs_write+0x10/0x10 +[ 286.550259][ C0] ? do_syscall_64+0x9f/0x190 +[ 286.550840][ C0] ? syscall_exit_to_user_mode+0x8e/0x280 +[ 286.551516][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 +[ 286.552180][ C0] ? syscall_exit_to_user_mode+0x93/0x280 +[ 286.552834][ C0] ? ksys_read+0xf5/0x1c0 +[ 286.553386][ C0] ? __pfx_ksys_read+0x10/0x10 +[ 286.553964][ C0] ksys_write+0xf5/0x1c0 +[ 286.554499][ C0] ? __pfx_ksys_write+0x10/0x10 +[ 286.555072][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 +[ 286.555698][ C0] ? syscall_exit_to_user_mode+0x93/0x280 +[ 286.556319][ C0] ? do_syscall_64+0x54/0x190 +[ 286.556866][ C0] do_syscall_64+0x93/0x190 +[ 286.557420][ C0] ? rcu_read_unlock+0x17/0x60 +[ 286.557986][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.558526][ C0] ? lock_release+0x217/0x2c0 +[ 286.559087][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.559659][ C0] ? count_memcg_events.constprop.0+0x4a/0x60 +[ 286.560476][ C0] ? exc_page_fault+0x7a/0x110 +[ 286.561064][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.561647][ C0] ? lock_release+0x217/0x2c0 +[ 286.562257][ C0] ? do_user_addr_fault+0x171/0xa00 +[ 286.562839][ C0] ? do_user_addr_fault+0x4a2/0xa00 +[ 286.563453][ C0] ? irqentry_exit_to_user_mode+0x84/0x270 +[ 286.564112][ C0] ? rcu_is_watching+0x11/0xb0 +[ 286.564677][ C0] ? irqentry_exit_to_user_mode+0x84/0x270 +[ 286.565317][ C0] ? trace_hardirqs_on_prepare+0xdb/0x120 +[ 286.565922][ C0] entry_SYSCALL_64_after_hwframe+0x76/0x7e +[ 286.566542][ C0] RIP: 0033:0x7fe3c05e6504 +[ 286.567102][ C0] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d c5 8b 10 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 55 48 89 e5 48 83 ec 20 48 89 +[ 286.568931][ C0] RSP: 002b:00007fff76444f58 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 +[ 286.569807][ C0] RAX: ffffffffffffffda RBX: 000000003b40d930 RCX: 00007fe3c05e6504 +[ 286.570621][ C0] RDX: 00000000000000cf RSI: 000000003b40d930 RDI: 0000000000000003 +[ 286.571443][ C0] RBP: 0000000000000003 R08: 00000000000000cf R09: 000000003b40d930 +[ 286.572246][ C0] R10: 0000000000000000 R11: 0000000000000202 R12: 000000003b40cd60 +[ 286.573069][ C0] R13: 00000000000000cf R14: 00007fe3c07417f8 R15: 00007fe3c073502e +[ 286.573886][ C0] + +Closes: https://lore.kernel.org/linux-nvme/5hdonndzoqa265oq3bj6iarwtfk5dewxxjtbjvn5uqnwclpwt6@a2n6w3taxxex/ +Signed-off-by: Alistair Francis +Reviewed-by: Sagi Grimberg +Tested-by: Shin'ichiro Kawasaki +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/tcp.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index a0af659a4c4a2..6a539c3b8b530 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -1456,6 +1456,9 @@ static void nvmet_tcp_restore_socket_callbacks(struct nvmet_tcp_queue *queue) + { + struct socket *sock = queue->sock; + ++ if (!queue->state_change) ++ return; ++ + write_lock_bh(&sock->sk->sk_callback_lock); + sock->sk->sk_data_ready = queue->data_ready; + sock->sk->sk_state_change = queue->state_change; +-- +2.39.5 + diff --git a/queue-6.6/objtool-fix-error-handling-inconsistencies-in-check.patch b/queue-6.6/objtool-fix-error-handling-inconsistencies-in-check.patch new file mode 100644 index 0000000000..5a54b912b7 --- /dev/null +++ b/queue-6.6/objtool-fix-error-handling-inconsistencies-in-check.patch @@ -0,0 +1,67 @@ +From 3fa5cddf82b491ae4d4bb9d848d81e510e0f2d07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Mar 2025 12:29:00 -0700 +Subject: objtool: Fix error handling inconsistencies in check() + +From: Josh Poimboeuf + +[ Upstream commit b745962cb97569aad026806bb0740663cf813147 ] + +Make sure all fatal errors are funneled through the 'out' label with a +negative ret. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Brendan Jackman +Link: https://lore.kernel.org/r/0f49d6a27a080b4012e84e6df1e23097f44cc082.1741975349.git.jpoimboe@kernel.org +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index f5af48502c9c8..f8e676a6e6f8e 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -4692,8 +4692,10 @@ int check(struct objtool_file *file) + init_cfi_state(&force_undefined_cfi); + force_undefined_cfi.force_undefined = true; + +- if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) ++ if (!cfi_hash_alloc(1UL << (file->elf->symbol_bits - 3))) { ++ ret = -1; + goto out; ++ } + + cfi_hash_add(&init_cfi); + cfi_hash_add(&func_cfi); +@@ -4710,7 +4712,7 @@ int check(struct objtool_file *file) + if (opts.retpoline) { + ret = validate_retpoline(file); + if (ret < 0) +- return ret; ++ goto out; + warnings += ret; + } + +@@ -4746,7 +4748,7 @@ int check(struct objtool_file *file) + */ + ret = validate_unrets(file); + if (ret < 0) +- return ret; ++ goto out; + warnings += ret; + } + +@@ -4809,7 +4811,7 @@ int check(struct objtool_file *file) + if (opts.prefix) { + ret = add_prefix_symbols(file); + if (ret < 0) +- return ret; ++ goto out; + warnings += ret; + } + +-- +2.39.5 + diff --git a/queue-6.6/objtool-properly-disable-uaccess-validation.patch b/queue-6.6/objtool-properly-disable-uaccess-validation.patch new file mode 100644 index 0000000000..9534a59a5e --- /dev/null +++ b/queue-6.6/objtool-properly-disable-uaccess-validation.patch @@ -0,0 +1,68 @@ +From f29673cc6ba9fcd8bd3fadebede3f8241fd37d1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 14:55:58 -0700 +Subject: objtool: Properly disable uaccess validation + +From: Josh Poimboeuf + +[ Upstream commit e1a9dda74dbffbc3fa2069ff418a1876dc99fb14 ] + +If opts.uaccess isn't set, the uaccess validation is disabled, but only +partially: it doesn't read the uaccess_safe_builtin list but still tries +to do the validation. Disable it completely to prevent false warnings. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Ingo Molnar +Cc: Linus Torvalds +Link: https://lore.kernel.org/r/0e95581c1d2107fb5f59418edf2b26bba38b0cbb.1742852846.git.jpoimboe@kernel.org +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index a1b14378bab04..f5af48502c9c8 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -3287,7 +3287,7 @@ static int handle_insn_ops(struct instruction *insn, + if (update_cfi_state(insn, next_insn, &state->cfi, op)) + return 1; + +- if (!insn->alt_group) ++ if (!opts.uaccess || !insn->alt_group) + continue; + + if (op->dest.type == OP_DEST_PUSHF) { +@@ -3754,6 +3754,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, + return 0; + + case INSN_STAC: ++ if (!opts.uaccess) ++ break; ++ + if (state.uaccess) { + WARN_INSN(insn, "recursive UACCESS enable"); + return 1; +@@ -3763,6 +3766,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, + break; + + case INSN_CLAC: ++ if (!opts.uaccess) ++ break; ++ + if (!state.uaccess && func) { + WARN_INSN(insn, "redundant UACCESS disable"); + return 1; +@@ -4238,7 +4244,8 @@ static int validate_symbol(struct objtool_file *file, struct section *sec, + if (!insn || insn->ignore || insn->visited) + return 0; + +- state->uaccess = sym->uaccess_safe; ++ if (opts.uaccess) ++ state->uaccess = sym->uaccess_safe; + + ret = validate_branch(file, insn_func(insn), insn, *state); + if (ret) +-- +2.39.5 + diff --git a/queue-6.6/octeontx2-af-rpm-register-driver-with-pci-subsys-ids.patch b/queue-6.6/octeontx2-af-rpm-register-driver-with-pci-subsys-ids.patch new file mode 100644 index 0000000000..6921699900 --- /dev/null +++ b/queue-6.6/octeontx2-af-rpm-register-driver-with-pci-subsys-ids.patch @@ -0,0 +1,67 @@ +From 0f098c025a8c6a3bb000423ca8dc4249fc1e0954 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 09:26:03 +0530 +Subject: Octeontx2-af: RPM: Register driver with PCI subsys IDs + +From: Hariprasad Kelam + +[ Upstream commit fc9167192f29485be5621e2e9c8208b717b65753 ] + +Although the PCI device ID and Vendor ID for the RPM (MAC) block +have remained the same across Octeon CN10K and the next-generation +CN20K silicon, Hardware architecture has changed (NIX mapped RPMs +and RFOE Mapped RPMs). + +Add PCI Subsystem IDs to the device table to ensure that this driver +can be probed from NIX mapped RPM devices only. + +Signed-off-by: Hariprasad Kelam +Link: https://patch.msgid.link/20250224035603.1220913-1-hkelam@marvell.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 14 ++++++++++++-- + drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 2 ++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 339be6950c039..6302990e9a5ff 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -66,8 +66,18 @@ static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool en); + /* Supported devices */ + static const struct pci_device_id cgx_id_table[] = { + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_CGX) }, +- { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RPM) }, +- { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10KB_RPM) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CN10K_A) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CNF10K_A) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CNF10K_B) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10KB_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CN10K_B) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10KB_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CN20KA) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10KB_RPM, ++ PCI_ANY_ID, PCI_SUBSYS_DEVID_CNF20KA) }, + { 0, } /* end of table */ + }; + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +index a607c7294b0c5..9fbc071ef29b0 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +@@ -30,6 +30,8 @@ + #define PCI_SUBSYS_DEVID_CNF10K_A 0xBA00 + #define PCI_SUBSYS_DEVID_CNF10K_B 0xBC00 + #define PCI_SUBSYS_DEVID_CN10K_B 0xBD00 ++#define PCI_SUBSYS_DEVID_CN20KA 0xC220 ++#define PCI_SUBSYS_DEVID_CNF20KA 0xC320 + + /* PCI BAR nos */ + #define PCI_AF_REG_BAR_NUM 0 +-- +2.39.5 + diff --git a/queue-6.6/orangefs-do-not-truncate-file-size.patch b/queue-6.6/orangefs-do-not-truncate-file-size.patch new file mode 100644 index 0000000000..ed8d3f5e6d --- /dev/null +++ b/queue-6.6/orangefs-do-not-truncate-file-size.patch @@ -0,0 +1,50 @@ +From fcb689d1159b49cfefea77d9feb2570065ede46f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 20:47:25 +0000 +Subject: orangefs: Do not truncate file size + +From: Matthew Wilcox (Oracle) + +[ Upstream commit 062e8093592fb866b8e016641a8b27feb6ac509d ] + +'len' is used to store the result of i_size_read(), so making 'len' +a size_t results in truncation to 4GiB on 32-bit systems. + +Signed-off-by: "Matthew Wilcox (Oracle)" +Link: https://lore.kernel.org/r/20250305204734.1475264-2-willy@infradead.org +Tested-by: Mike Marshall +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/orangefs/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c +index 0859122684425..dd4dc70e4aaab 100644 +--- a/fs/orangefs/inode.c ++++ b/fs/orangefs/inode.c +@@ -23,9 +23,9 @@ static int orangefs_writepage_locked(struct page *page, + struct orangefs_write_range *wr = NULL; + struct iov_iter iter; + struct bio_vec bv; +- size_t len, wlen; ++ size_t wlen; + ssize_t ret; +- loff_t off; ++ loff_t len, off; + + set_page_writeback(page); + +@@ -92,8 +92,7 @@ static int orangefs_writepages_work(struct orangefs_writepages *ow, + struct orangefs_write_range *wrp, wr; + struct iov_iter iter; + ssize_t ret; +- size_t len; +- loff_t off; ++ loff_t len, off; + int i; + + len = i_size_read(inode); +-- +2.39.5 + diff --git a/queue-6.6/pci-brcmstb-add-a-softdep-to-mip-msi-x-driver.patch b/queue-6.6/pci-brcmstb-add-a-softdep-to-mip-msi-x-driver.patch new file mode 100644 index 0000000000..cacc5f3b53 --- /dev/null +++ b/queue-6.6/pci-brcmstb-add-a-softdep-to-mip-msi-x-driver.patch @@ -0,0 +1,41 @@ +From 0333d8fbf2ded7c8d0ca725efcb00f1eca045187 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 10:35:56 +0200 +Subject: PCI: brcmstb: Add a softdep to MIP MSI-X driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Stanimir Varbanov + +[ Upstream commit 2294059118c550464dd8906286324d90c33b152b ] + +Then the brcmstb PCIe driver and MIP MSI-X interrupt controller +drivers are built as modules there could be a race in probing. + +To avoid this, add a softdep to MIP driver to guarantee that +MIP driver will be load first. + +Signed-off-by: Stanimir Varbanov +Reviewed-by: Florian Fainelli +Tested-by: Ivan T. Ivanov +Link: https://lore.kernel.org/r/20250224083559.47645-5-svarbanov@suse.de +[kwilczynski: commit log] +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-brcmstb.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c +index 8b88e30db7447..9bcf4c68058eb 100644 +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -1632,3 +1632,4 @@ module_platform_driver(brcm_pcie_driver); + MODULE_LICENSE("GPL"); + MODULE_DESCRIPTION("Broadcom STB PCIe RC driver"); + MODULE_AUTHOR("Broadcom"); ++MODULE_SOFTDEP("pre: irq_bcm2712_mip"); +-- +2.39.5 + diff --git a/queue-6.6/pci-brcmstb-expand-inbound-window-size-up-to-64gb.patch b/queue-6.6/pci-brcmstb-expand-inbound-window-size-up-to-64gb.patch new file mode 100644 index 0000000000..5a818302a3 --- /dev/null +++ b/queue-6.6/pci-brcmstb-expand-inbound-window-size-up-to-64gb.patch @@ -0,0 +1,48 @@ +From c6dbb6e5a9e4681f8a6fc7d4ea66ebdb56d858ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 10:35:58 +0200 +Subject: PCI: brcmstb: Expand inbound window size up to 64GB +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Stanimir Varbanov + +[ Upstream commit 25a98c727015638baffcfa236e3f37b70cedcf87 ] + +The BCM2712 memory map can support up to 64GB of system memory, thus +expand the inbound window size in calculation helper function. + +The change is safe for the currently supported SoCs that have smaller +inbound window sizes. + +Signed-off-by: Stanimir Varbanov +Reviewed-by: Florian Fainelli +Reviewed-by: Jim Quinlan +Tested-by: Ivan T. Ivanov +Link: https://lore.kernel.org/r/20250224083559.47645-7-svarbanov@suse.de +[kwilczynski: commit log] +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/pcie-brcmstb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c +index 940af934ce1bb..8b88e30db7447 100644 +--- a/drivers/pci/controller/pcie-brcmstb.c ++++ b/drivers/pci/controller/pcie-brcmstb.c +@@ -284,8 +284,8 @@ static int brcm_pcie_encode_ibar_size(u64 size) + if (log2_in >= 12 && log2_in <= 15) + /* Covers 4KB to 32KB (inclusive) */ + return (log2_in - 12) + 0x1c; +- else if (log2_in >= 16 && log2_in <= 35) +- /* Covers 64KB to 32GB, (inclusive) */ ++ else if (log2_in >= 16 && log2_in <= 36) ++ /* Covers 64KB to 64GB, (inclusive) */ + return log2_in - 15; + /* Something is awry so disable */ + return 0; +-- +2.39.5 + diff --git a/queue-6.6/pci-dwc-ep-ensure-proper-iteration-over-outbound-map.patch b/queue-6.6/pci-dwc-ep-ensure-proper-iteration-over-outbound-map.patch new file mode 100644 index 0000000000..7f2b3c1358 --- /dev/null +++ b/queue-6.6/pci-dwc-ep-ensure-proper-iteration-over-outbound-map.patch @@ -0,0 +1,45 @@ +From c9f97a5157524187d51b454b5ae61bff4275b158 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Mar 2025 15:15:46 -0500 +Subject: PCI: dwc: ep: Ensure proper iteration over outbound map windows + +From: Frank Li + +[ Upstream commit f3e1dccba0a0833fc9a05fb838ebeb6ea4ca0e1a ] + +Most systems' PCIe outbound map windows have non-zero physical addresses, +but the possibility of encountering zero increased after following commit +("PCI: dwc: Use parent_bus_offset"). + +'ep->outbound_addr[n]', representing 'parent_bus_address', might be 0 on +some hardware, which trims high address bits through bus fabric before +sending to the PCIe controller. + +Replace the iteration logic with 'for_each_set_bit()' to ensure only +allocated map windows are iterated when determining the ATU index from a +given address. + +Link: https://lore.kernel.org/r/20250315201548.858189-12-helgaas@kernel.org +Signed-off-by: Frank Li +Signed-off-by: Bjorn Helgaas +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c +index f2e5feba55267..26ad643fb4248 100644 +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -281,7 +281,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, + u32 index; + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + +- for (index = 0; index < pci->num_ob_windows; index++) { ++ for_each_set_bit(index, ep->ob_window_map, pci->num_ob_windows) { + if (ep->outbound_addr[index] != addr) + continue; + *atu_index = index; +-- +2.39.5 + diff --git a/queue-6.6/pci-fix-old_size-lower-bound-in-calculate_iosize-too.patch b/queue-6.6/pci-fix-old_size-lower-bound-in-calculate_iosize-too.patch new file mode 100644 index 0000000000..53bfd625e0 --- /dev/null +++ b/queue-6.6/pci-fix-old_size-lower-bound-in-calculate_iosize-too.patch @@ -0,0 +1,48 @@ +From 093c96f1af6c81413ae6f71d7d56b9ab578efe22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 19:56:12 +0200 +Subject: PCI: Fix old_size lower bound in calculate_iosize() too +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit ff61f380de5652e723168341480cc7adf1dd6213 ] + +Commit 903534fa7d30 ("PCI: Fix resource double counting on remove & +rescan") fixed double counting of mem resources because of old_size being +applied too early. + +Fix a similar counting bug on the io resource side. + +Link: https://lore.kernel.org/r/20241216175632.4175-6-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Tested-by: Xiaochun Lee +Signed-off-by: Sasha Levin +--- + drivers/pci/setup-bus.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index fba402f4f6330..3f40be417856e 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -802,11 +802,9 @@ static resource_size_t calculate_iosize(resource_size_t size, + size = (size & 0xff) + ((size & ~0xffUL) << 2); + #endif + size = size + size1; +- if (size < old_size) +- size = old_size; + +- size = ALIGN(max(size, add_size) + children_add_size, align); +- return size; ++ size = max(size, add_size) + children_add_size; ++ return ALIGN(max(size, old_size), align); + } + + static resource_size_t calculate_memsize(resource_size_t size, +-- +2.39.5 + diff --git a/queue-6.6/pci-vmd-disable-msi-remapping-bypass-under-xen.patch b/queue-6.6/pci-vmd-disable-msi-remapping-bypass-under-xen.patch new file mode 100644 index 0000000000..0de5ceb58c --- /dev/null +++ b/queue-6.6/pci-vmd-disable-msi-remapping-bypass-under-xen.patch @@ -0,0 +1,78 @@ +From d5b194a75c35b1cc87e19e3bfe2d0744b98be801 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Feb 2025 10:20:56 +0100 +Subject: PCI: vmd: Disable MSI remapping bypass under Xen +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Roger Pau Monne + +[ Upstream commit 6c4d5aadf5df31ea0ac025980670eee9beaf466b ] + +MSI remapping bypass (directly configuring MSI entries for devices on the +VMD bus) won't work under Xen, as Xen is not aware of devices in such bus, +and hence cannot configure the entries using the pIRQ interface in the PV +case, and in the PVH case traps won't be setup for MSI entries for such +devices. + +Until Xen is aware of devices in the VMD bus prevent the +VMD_FEAT_CAN_BYPASS_MSI_REMAP capability from being used when running as +any kind of Xen guest. + +The MSI remapping bypass is an optional feature of VMD bridges, and hence +when running under Xen it will be masked and devices will be forced to +redirect its interrupts from the VMD bridge. That mode of operation must +always be supported by VMD bridges and works when Xen is not aware of +devices behind the VMD bridge. + +Signed-off-by: Roger Pau Monné +Acked-by: Bjorn Helgaas +Message-ID: <20250219092059.90850-3-roger.pau@citrix.com> +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/vmd.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c +index dfa222e02c4da..ad82feff0405e 100644 +--- a/drivers/pci/controller/vmd.c ++++ b/drivers/pci/controller/vmd.c +@@ -17,6 +17,8 @@ + #include + #include + ++#include ++ + #include + + #define VMD_CFGBAR 0 +@@ -981,6 +983,24 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id) + struct vmd_dev *vmd; + int err; + ++ if (xen_domain()) { ++ /* ++ * Xen doesn't have knowledge about devices in the VMD bus ++ * because the config space of devices behind the VMD bridge is ++ * not known to Xen, and hence Xen cannot discover or configure ++ * them in any way. ++ * ++ * Bypass of MSI remapping won't work in that case as direct ++ * write by Linux to the MSI entries won't result in functional ++ * interrupts, as Xen is the entity that manages the host ++ * interrupt controller and must configure interrupts. However ++ * multiplexing of interrupts by the VMD bridge will work under ++ * Xen, so force the usage of that mode which must always be ++ * supported by VMD bridges. ++ */ ++ features &= ~VMD_FEAT_CAN_BYPASS_MSI_REMAP; ++ } ++ + if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20)) + return -ENOMEM; + +-- +2.39.5 + diff --git a/queue-6.6/perf-amd-ibs-fix-config-to-sample-period-calculation.patch b/queue-6.6/perf-amd-ibs-fix-config-to-sample-period-calculation.patch new file mode 100644 index 0000000000..877738fc43 --- /dev/null +++ b/queue-6.6/perf-amd-ibs-fix-config-to-sample-period-calculation.patch @@ -0,0 +1,74 @@ +From f4be1e3af2c0e0fdfa15431ffc95aa99633fbe34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 05:44:32 +0000 +Subject: perf/amd/ibs: Fix ->config to sample period calculation for OP PMU + +From: Ravi Bangoria + +[ Upstream commit 598bdf4fefff5af4ce6d26d16f7b2a20808fc4cb ] + +Instead of using standard perf_event_attr->freq=0 and ->sample_period +fields, IBS event in 'sample period mode' can also be opened by setting +period value directly in perf_event_attr->config in a MaxCnt bit-field +format. + +IBS OP MaxCnt bits are defined as: + + (high bits) IbsOpCtl[26:20] = IbsOpMaxCnt[26:20] + (low bits) IbsOpCtl[15:0] = IbsOpMaxCnt[19:4] + +Perf event sample period can be derived from MaxCnt bits as: + + sample_period = (high bits) | ((low_bits) << 4); + +However, current code just masks MaxCnt bits and shifts all of them, +including high bits, which is incorrect. Fix it. + +Signed-off-by: Ravi Bangoria +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Namhyung Kim +Link: https://lkml.kernel.org/r/20250115054438.1021-4-ravi.bangoria@amd.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/ibs.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c +index 85731f121feb5..fac3d97111b09 100644 +--- a/arch/x86/events/amd/ibs.c ++++ b/arch/x86/events/amd/ibs.c +@@ -272,7 +272,7 @@ static int perf_ibs_init(struct perf_event *event) + { + struct hw_perf_event *hwc = &event->hw; + struct perf_ibs *perf_ibs; +- u64 max_cnt, config; ++ u64 config; + int ret; + + perf_ibs = get_ibs_pmu(event->attr.type); +@@ -306,10 +306,19 @@ static int perf_ibs_init(struct perf_event *event) + if (!hwc->sample_period) + hwc->sample_period = 0x10; + } else { +- max_cnt = config & perf_ibs->cnt_mask; ++ u64 period = 0; ++ ++ if (perf_ibs == &perf_ibs_op) { ++ period = (config & IBS_OP_MAX_CNT) << 4; ++ if (ibs_caps & IBS_CAPS_OPCNTEXT) ++ period |= config & IBS_OP_MAX_CNT_EXT_MASK; ++ } else { ++ period = (config & IBS_FETCH_MAX_CNT) << 4; ++ } ++ + config &= ~perf_ibs->cnt_mask; +- event->attr.sample_period = max_cnt << 4; +- hwc->sample_period = event->attr.sample_period; ++ event->attr.sample_period = period; ++ hwc->sample_period = period; + } + + if (!hwc->sample_period) +-- +2.39.5 + diff --git a/queue-6.6/perf-amd-ibs-fix-perf_ibs_op.cnt_mask-for-curcnt.patch b/queue-6.6/perf-amd-ibs-fix-perf_ibs_op.cnt_mask-for-curcnt.patch new file mode 100644 index 0000000000..bfb5d5c178 --- /dev/null +++ b/queue-6.6/perf-amd-ibs-fix-perf_ibs_op.cnt_mask-for-curcnt.patch @@ -0,0 +1,63 @@ +From 072cbbb7ff184e2980de498f39557f72d05880db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 05:44:33 +0000 +Subject: perf/amd/ibs: Fix perf_ibs_op.cnt_mask for CurCnt + +From: Ravi Bangoria + +[ Upstream commit 46dcf85566170d4528b842bf83ffc350d71771fa ] + +IBS Op uses two counters: MaxCnt and CurCnt. MaxCnt is programmed with +the desired sample period. IBS hw generates sample when CurCnt reaches +to MaxCnt. The size of these counter used to be 20 bits but later they +were extended to 27 bits. The 7 bit extension is indicated by CPUID +Fn8000_001B_EAX[6 / OpCntExt]. + +perf_ibs->cnt_mask variable contains bit masks for MaxCnt and CurCnt. +But IBS driver does not set upper 7 bits of CurCnt in cnt_mask even +when OpCntExt CPUID bit is set. Fix this. + +IBS driver uses cnt_mask[CurCnt] bits only while disabling an event. +Fortunately, CurCnt bits are not read from MSR while re-enabling the +event, instead MaxCnt is programmed with desired period and CurCnt is +set to 0. Hence, we did not see any issues so far. + +Signed-off-by: Ravi Bangoria +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Namhyung Kim +Link: https://lkml.kernel.org/r/20250115054438.1021-5-ravi.bangoria@amd.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/amd/ibs.c | 3 ++- + arch/x86/include/asm/perf_event.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c +index f483874fa20f1..85731f121feb5 100644 +--- a/arch/x86/events/amd/ibs.c ++++ b/arch/x86/events/amd/ibs.c +@@ -1219,7 +1219,8 @@ static __init int perf_ibs_op_init(void) + if (ibs_caps & IBS_CAPS_OPCNTEXT) { + perf_ibs_op.max_period |= IBS_OP_MAX_CNT_EXT_MASK; + perf_ibs_op.config_mask |= IBS_OP_MAX_CNT_EXT_MASK; +- perf_ibs_op.cnt_mask |= IBS_OP_MAX_CNT_EXT_MASK; ++ perf_ibs_op.cnt_mask |= (IBS_OP_MAX_CNT_EXT_MASK | ++ IBS_OP_CUR_CNT_EXT_MASK); + } + + if (ibs_caps & IBS_CAPS_ZEN4) +diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h +index 384e8a7db4827..ba2a3935dc624 100644 +--- a/arch/x86/include/asm/perf_event.h ++++ b/arch/x86/include/asm/perf_event.h +@@ -501,6 +501,7 @@ struct pebs_xmm { + */ + #define IBS_OP_CUR_CNT (0xFFF80ULL<<32) + #define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32) ++#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52) + #define IBS_OP_CNT_CTL (1ULL<<19) + #define IBS_OP_VAL (1ULL<<18) + #define IBS_OP_ENABLE (1ULL<<17) +-- +2.39.5 + diff --git a/queue-6.6/perf-arm_pmuv3-call-kvm_vcpu_pmu_resync_el0-before-e.patch b/queue-6.6/perf-arm_pmuv3-call-kvm_vcpu_pmu_resync_el0-before-e.patch new file mode 100644 index 0000000000..cd9ad74848 --- /dev/null +++ b/queue-6.6/perf-arm_pmuv3-call-kvm_vcpu_pmu_resync_el0-before-e.patch @@ -0,0 +1,44 @@ +From c69365d272ed0ba00453804e32c655e61115e73b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 14:39:56 -0600 +Subject: perf: arm_pmuv3: Call kvm_vcpu_pmu_resync_el0() before enabling + counters + +From: Rob Herring (Arm) + +[ Upstream commit 04bd15c4cbc3f7bd2399d1baab958c5e738dbfc9 ] + +Counting events related to setup of the PMU is not desired, but +kvm_vcpu_pmu_resync_el0() is called just after the PMU counters have +been enabled. Move the call to before enabling the counters. + +Signed-off-by: Rob Herring (Arm) +Reviewed-by: Anshuman Khandual +Tested-by: James Clark +Link: https://lore.kernel.org/r/20250218-arm-brbe-v19-v20-1-4e9922fc2e8e@kernel.org +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/perf/arm_pmuv3.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/perf/arm_pmuv3.c b/drivers/perf/arm_pmuv3.c +index 0e8f54168cb64..0858e6096453e 100644 +--- a/drivers/perf/arm_pmuv3.c ++++ b/drivers/perf/arm_pmuv3.c +@@ -751,10 +751,10 @@ static void armv8pmu_start(struct arm_pmu *cpu_pmu) + else + armv8pmu_disable_user_access(); + ++ kvm_vcpu_pmu_resync_el0(); ++ + /* Enable all counters */ + armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); +- +- kvm_vcpu_pmu_resync_el0(); + } + + static void armv8pmu_stop(struct arm_pmu *cpu_pmu) +-- +2.39.5 + diff --git a/queue-6.6/perf-avoid-the-read-if-the-count-is-already-updated.patch b/queue-6.6/perf-avoid-the-read-if-the-count-is-already-updated.patch new file mode 100644 index 0000000000..0e180a7f55 --- /dev/null +++ b/queue-6.6/perf-avoid-the-read-if-the-count-is-already-updated.patch @@ -0,0 +1,144 @@ +From b1ddb91306bf2653d1fe1aaf1908f591916b428a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Jan 2025 07:23:02 -0800 +Subject: perf: Avoid the read if the count is already updated + +From: Peter Zijlstra (Intel) + +[ Upstream commit 8ce939a0fa194939cc1f92dbd8bc1a7806e7d40a ] + +The event may have been updated in the PMU-specific implementation, +e.g., Intel PEBS counters snapshotting. The common code should not +read and overwrite the value. + +The PERF_SAMPLE_READ in the data->sample_type can be used to detect +whether the PMU-specific value is available. If yes, avoid the +pmu->read() in the common code. Add a new flag, skip_read, to track the +case. + +Factor out a perf_pmu_read() to clean up the code. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Kan Liang +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20250121152303.3128733-3-kan.liang@linux.intel.com +Signed-off-by: Sasha Levin +--- + include/linux/perf_event.h | 8 +++++++- + kernel/events/core.c | 33 ++++++++++++++++----------------- + kernel/events/ring_buffer.c | 1 + + 3 files changed, 24 insertions(+), 18 deletions(-) + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index fcb834dd75c24..90c782749b055 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1016,7 +1016,13 @@ struct perf_output_handle { + struct perf_buffer *rb; + unsigned long wakeup; + unsigned long size; +- u64 aux_flags; ++ union { ++ u64 flags; /* perf_output*() */ ++ u64 aux_flags; /* perf_aux_output*() */ ++ struct { ++ u64 skip_read : 1; ++ }; ++ }; + union { + void *addr; + unsigned long head; +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 987807b1040ae..5dd6424e62fa8 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -1163,6 +1163,12 @@ static void perf_assert_pmu_disabled(struct pmu *pmu) + WARN_ON_ONCE(*this_cpu_ptr(pmu->pmu_disable_count) == 0); + } + ++static inline void perf_pmu_read(struct perf_event *event) ++{ ++ if (event->state == PERF_EVENT_STATE_ACTIVE) ++ event->pmu->read(event); ++} ++ + static void get_ctx(struct perf_event_context *ctx) + { + refcount_inc(&ctx->refcount); +@@ -3397,8 +3403,7 @@ static void __perf_event_sync_stat(struct perf_event *event, + * we know the event must be on the current CPU, therefore we + * don't need to use it. + */ +- if (event->state == PERF_EVENT_STATE_ACTIVE) +- event->pmu->read(event); ++ perf_pmu_read(event); + + perf_event_update_time(event); + +@@ -4524,15 +4529,8 @@ static void __perf_event_read(void *info) + + pmu->read(event); + +- for_each_sibling_event(sub, event) { +- if (sub->state == PERF_EVENT_STATE_ACTIVE) { +- /* +- * Use sibling's PMU rather than @event's since +- * sibling could be on different (eg: software) PMU. +- */ +- sub->pmu->read(sub); +- } +- } ++ for_each_sibling_event(sub, event) ++ perf_pmu_read(sub); + + data->ret = pmu->commit_txn(pmu); + +@@ -7297,9 +7295,8 @@ static void perf_output_read_group(struct perf_output_handle *handle, + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + values[n++] = running; + +- if ((leader != event) && +- (leader->state == PERF_EVENT_STATE_ACTIVE)) +- leader->pmu->read(leader); ++ if ((leader != event) && !handle->skip_read) ++ perf_pmu_read(leader); + + values[n++] = perf_event_count(leader); + if (read_format & PERF_FORMAT_ID) +@@ -7312,9 +7309,8 @@ static void perf_output_read_group(struct perf_output_handle *handle, + for_each_sibling_event(sub, leader) { + n = 0; + +- if ((sub != event) && +- (sub->state == PERF_EVENT_STATE_ACTIVE)) +- sub->pmu->read(sub); ++ if ((sub != event) && !handle->skip_read) ++ perf_pmu_read(sub); + + values[n++] = perf_event_count(sub); + if (read_format & PERF_FORMAT_ID) +@@ -7369,6 +7365,9 @@ void perf_output_sample(struct perf_output_handle *handle, + { + u64 sample_type = data->type; + ++ if (data->sample_flags & PERF_SAMPLE_READ) ++ handle->skip_read = 1; ++ + perf_output_put(handle, *header); + + if (sample_type & PERF_SAMPLE_IDENTIFIER) +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index 52de76ef8723b..dc1193b779c08 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -181,6 +181,7 @@ __perf_output_begin(struct perf_output_handle *handle, + + handle->rb = rb; + handle->event = event; ++ handle->flags = 0; + + have_lost = local_read(&rb->lost); + if (unlikely(have_lost)) { +-- +2.39.5 + diff --git a/queue-6.6/perf-hw_breakpoint-return-eopnotsupp-for-unsupported.patch b/queue-6.6/perf-hw_breakpoint-return-eopnotsupp-for-unsupported.patch new file mode 100644 index 0000000000..7be26aa18a --- /dev/null +++ b/queue-6.6/perf-hw_breakpoint-return-eopnotsupp-for-unsupported.patch @@ -0,0 +1,54 @@ +From ff2faea0b98c7be734054f260cc4eb2738fa604a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 14:54:51 +0530 +Subject: perf/hw_breakpoint: Return EOPNOTSUPP for unsupported breakpoint type + +From: Saket Kumar Bhaskar + +[ Upstream commit 061c991697062f3bf87b72ed553d1d33a0e370dd ] + +Currently, __reserve_bp_slot() returns -ENOSPC for unsupported +breakpoint types on the architecture. For example, powerpc +does not support hardware instruction breakpoints. This causes +the perf_skip BPF selftest to fail, as neither ENOENT nor +EOPNOTSUPP is returned by perf_event_open for unsupported +breakpoint types. As a result, the test that should be skipped +for this arch is not correctly identified. + +To resolve this, hw_breakpoint_event_init() should exit early by +checking for unsupported breakpoint types using +hw_breakpoint_slots_cached() and return the appropriate error +(-EOPNOTSUPP). + +Signed-off-by: Saket Kumar Bhaskar +Signed-off-by: Ingo Molnar +Cc: Marco Elver +Cc: Dmitry Vyukov +Cc: Ian Rogers +Cc: Frederic Weisbecker +Link: https://lore.kernel.org/r/20250303092451.1862862-1-skb99@linux.ibm.com +Signed-off-by: Sasha Levin +--- + kernel/events/hw_breakpoint.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c +index 6c2cb4e4f48da..8f3f624419aa9 100644 +--- a/kernel/events/hw_breakpoint.c ++++ b/kernel/events/hw_breakpoint.c +@@ -950,9 +950,10 @@ static int hw_breakpoint_event_init(struct perf_event *bp) + return -ENOENT; + + /* +- * no branch sampling for breakpoint events ++ * Check if breakpoint type is supported before proceeding. ++ * Also, no branch sampling for breakpoint events. + */ +- if (has_branch_stack(bp)) ++ if (!hw_breakpoint_slots_cached(find_slot_idx(bp->attr.bp_type)) || has_branch_stack(bp)) + return -EOPNOTSUPP; + + err = register_perf_hw_breakpoint(bp); +-- +2.39.5 + diff --git a/queue-6.6/phy-core-don-t-require-set_mode-callback-for-phy_get.patch b/queue-6.6/phy-core-don-t-require-set_mode-callback-for-phy_get.patch new file mode 100644 index 0000000000..1588ad0806 --- /dev/null +++ b/queue-6.6/phy-core-don-t-require-set_mode-callback-for-phy_get.patch @@ -0,0 +1,54 @@ +From 4d2c5c95bc465cd9ddf5158efd0455f1d6f6104d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2025 14:31:45 +0200 +Subject: phy: core: don't require set_mode() callback for phy_get_mode() to + work + +From: Dmitry Baryshkov + +[ Upstream commit d58c04e305afbaa9dda7969151f06c4efe2c98b0 ] + +As reported by Damon Ding, the phy_get_mode() call doesn't work as +expected unless the PHY driver has a .set_mode() call. This prompts PHY +drivers to have empty stubs for .set_mode() for the sake of being able +to get the mode. + +Make .set_mode() callback truly optional and update PHY's mode even if +it there is none. + +Cc: Damon Ding +Link: https://lore.kernel.org/r/96f8310f-93f1-4bcb-8637-137e1159ff83@rock-chips.com +Tested-by: Damon Ding +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250209-phy-fix-set-moe-v2-1-76e248503856@linaro.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/phy-core.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c +index a892e1d7e2d02..9417372a01554 100644 +--- a/drivers/phy/phy-core.c ++++ b/drivers/phy/phy-core.c +@@ -400,13 +400,14 @@ EXPORT_SYMBOL_GPL(phy_power_off); + + int phy_set_mode_ext(struct phy *phy, enum phy_mode mode, int submode) + { +- int ret; ++ int ret = 0; + +- if (!phy || !phy->ops->set_mode) ++ if (!phy) + return 0; + + mutex_lock(&phy->mutex); +- ret = phy->ops->set_mode(phy, mode, submode); ++ if (phy->ops->set_mode) ++ ret = phy->ops->set_mode(phy, mode, submode); + if (!ret) + phy->attrs.mode = mode; + mutex_unlock(&phy->mutex); +-- +2.39.5 + diff --git a/queue-6.6/phy-renesas-rcar-gen3-usb2-add-support-to-initialize.patch b/queue-6.6/phy-renesas-rcar-gen3-usb2-add-support-to-initialize.patch new file mode 100644 index 0000000000..b2d83c429b --- /dev/null +++ b/queue-6.6/phy-renesas-rcar-gen3-usb2-add-support-to-initialize.patch @@ -0,0 +1,156 @@ +From d9054b6d6a21b9a3a89916a1beba49fc59c72b99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 18:27:55 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Add support to initialize the bus + +From: Claudiu Beznea + +[ Upstream commit 4eae16375357a2a7e8501be5469532f7636064b3 ] + +The Renesas RZ/G3S need to initialize the USB BUS before transferring data +due to hardware limitation. As the register that need to be touched for +this is in the address space of the USB PHY, and the UBS PHY need to be +initialized before any other USB drivers handling data transfer, add +support to initialize the USB BUS. + +As the USB PHY is probed before any other USB drivers that enables +clocks and de-assert the reset signals and the BUS initialization is done +in the probe phase, we need to add code to de-assert reset signal and +runtime resume the device (which enables its clocks) before accessing +the registers. + +As the reset signals are not required by the USB PHY driver for the other +USB PHY hardware variants, the reset signals and runtime PM was handled +only in the function that initialize the USB BUS. + +The PHY initialization was done right after runtime PM enable to have +all in place when the PHYs are registered. + +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20240822152801.602318-11-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Stable-dep-of: 9ce71e85b29e ("phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off") +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 50 ++++++++++++++++++++++-- + 1 file changed, 47 insertions(+), 3 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index aa578be2bcb6d..d2bbf6c6ed5e0 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -19,12 +19,14 @@ + #include + #include + #include ++#include + #include + #include + #include + + /******* USB2.0 Host registers (original offset is +0x200) *******/ + #define USB2_INT_ENABLE 0x000 ++#define USB2_AHB_BUS_CTR 0x008 + #define USB2_USBCTR 0x00c + #define USB2_SPD_RSM_TIMSET 0x10c + #define USB2_OC_TIMSET 0x110 +@@ -40,6 +42,10 @@ + #define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) /* For EHCI */ + #define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) /* For OHCI */ + ++/* AHB_BUS_CTR */ ++#define USB2_AHB_BUS_CTR_MBL_MASK GENMASK(1, 0) ++#define USB2_AHB_BUS_CTR_MBL_INCR4 2 ++ + /* USBCTR */ + #define USB2_USBCTR_DIRPD BIT(2) + #define USB2_USBCTR_PLL_RST BIT(1) +@@ -110,6 +116,7 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; ++ struct reset_control *rstc; + struct work_struct work; + struct mutex lock; /* protects rphys[...].powered */ + enum usb_dr_mode dr_mode; +@@ -124,6 +131,7 @@ struct rcar_gen3_chan { + struct rcar_gen3_phy_drv_data { + const struct phy_ops *phy_usb2_ops; + bool no_adp_ctrl; ++ bool init_bus; + }; + + /* +@@ -645,6 +653,35 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) ++{ ++ struct device *dev = channel->dev; ++ int ret; ++ u32 val; ++ ++ channel->rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(channel->rstc)) ++ return PTR_ERR(channel->rstc); ++ ++ ret = pm_runtime_resume_and_get(dev); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_deassert(channel->rstc); ++ if (ret) ++ goto rpm_put; ++ ++ val = readl(channel->base + USB2_AHB_BUS_CTR); ++ val &= ~USB2_AHB_BUS_CTR_MBL_MASK; ++ val |= USB2_AHB_BUS_CTR_MBL_INCR4; ++ writel(val, channel->base + USB2_AHB_BUS_CTR); ++ ++rpm_put: ++ pm_runtime_put(dev); ++ ++ return ret; ++} ++ + static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + { + const struct rcar_gen3_phy_drv_data *phy_data; +@@ -698,6 +735,15 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + goto error; + } + ++ platform_set_drvdata(pdev, channel); ++ channel->dev = dev; ++ ++ if (phy_data->init_bus) { ++ ret = rcar_gen3_phy_usb2_init_bus(channel); ++ if (ret) ++ goto error; ++ } ++ + channel->soc_no_adp_ctrl = phy_data->no_adp_ctrl; + if (phy_data->no_adp_ctrl) + channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; +@@ -725,9 +771,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + channel->vbus = NULL; + } + +- platform_set_drvdata(pdev, channel); +- channel->dev = dev; +- + provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate); + if (IS_ERR(provider)) { + dev_err(dev, "Failed to register PHY provider\n"); +@@ -754,6 +797,7 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + ++ reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + }; + +-- +2.39.5 + diff --git a/queue-6.6/phy-renesas-rcar-gen3-usb2-assert-pll-reset-on-phy-p.patch b/queue-6.6/phy-renesas-rcar-gen3-usb2-assert-pll-reset-on-phy-p.patch new file mode 100644 index 0000000000..faa5af8d51 --- /dev/null +++ b/queue-6.6/phy-renesas-rcar-gen3-usb2-assert-pll-reset-on-phy-p.patch @@ -0,0 +1,50 @@ +From fd95073c0f7d10016a3f55f7cdd7b631813b2727 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 May 2025 15:50:31 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off + +From: Claudiu Beznea + +[ Upstream commit 9ce71e85b29eb63e48e294479742e670513f03a0 ] + +Assert PLL reset on PHY power off. This saves power. + +Fixes: f3b5a8d9b50d ("phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver") +Cc: stable@vger.kernel.org +Reviewed-by: Yoshihiro Shimoda +Tested-by: Yoshihiro Shimoda +Reviewed-by: Lad Prabhakar +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20250507125032.565017-5-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index 793f076171170..9a6391361a0be 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -537,9 +537,17 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) + struct rcar_gen3_chan *channel = rphy->ch; + int ret = 0; + +- scoped_guard(spinlock_irqsave, &channel->lock) ++ scoped_guard(spinlock_irqsave, &channel->lock) { + rphy->powered = false; + ++ if (rcar_gen3_are_all_rphys_power_off(channel)) { ++ u32 val = readl(channel->base + USB2_USBCTR); ++ ++ val |= USB2_USBCTR_PLL_RST; ++ writel(val, channel->base + USB2_USBCTR); ++ } ++ } ++ + if (channel->vbus) + ret = regulator_disable(channel->vbus); + +-- +2.39.5 + diff --git a/queue-6.6/phy-renesas-rcar-gen3-usb2-lock-around-hardware-regi.patch b/queue-6.6/phy-renesas-rcar-gen3-usb2-lock-around-hardware-regi.patch new file mode 100644 index 0000000000..5bd5191901 --- /dev/null +++ b/queue-6.6/phy-renesas-rcar-gen3-usb2-lock-around-hardware-regi.patch @@ -0,0 +1,199 @@ +From 8ad1d64d05b0b1850365613737a03ff9bce216e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 May 2025 15:50:30 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Lock around hardware registers and + driver data + +From: Claudiu Beznea + +[ Upstream commit 55a387ebb9219cbe4edfa8ba9996ccb0e7ad4932 ] + +The phy-rcar-gen3-usb2 driver exposes four individual PHYs that are +requested and configured by PHY users. The struct phy_ops APIs access the +same set of registers to configure all PHYs. Additionally, PHY settings can +be modified through sysfs or an IRQ handler. While some struct phy_ops APIs +are protected by a driver-wide mutex, others rely on individual +PHY-specific mutexes. + +This approach can lead to various issues, including: +1/ the IRQ handler may interrupt PHY settings in progress, racing with + hardware configuration protected by a mutex lock +2/ due to msleep(20) in rcar_gen3_init_otg(), while a configuration thread + suspends to wait for the delay, another thread may try to configure + another PHY (with phy_init() + phy_power_on()); re-running the + phy_init() goes to the exact same configuration code, re-running the + same hardware configuration on the same set of registers (and bits) + which might impact the result of the msleep for the 1st configuring + thread +3/ sysfs can configure the hardware (though role_store()) and it can + still race with the phy_init()/phy_power_on() APIs calling into the + drivers struct phy_ops + +To address these issues, add a spinlock to protect hardware register access +and driver private data structures (e.g., calls to +rcar_gen3_is_any_rphy_initialized()). Checking driver-specific data remains +necessary as all PHY instances share common settings. With this change, +the existing mutex protection is removed and the cleanup.h helpers are +used. + +While at it, to keep the code simpler, do not skip +regulator_enable()/regulator_disable() APIs in +rcar_gen3_phy_usb2_power_on()/rcar_gen3_phy_usb2_power_off() as the +regulators enable/disable operations are reference counted anyway. + +Fixes: f3b5a8d9b50d ("phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver") +Cc: stable@vger.kernel.org +Reviewed-by: Yoshihiro Shimoda +Tested-by: Yoshihiro Shimoda +Reviewed-by: Lad Prabhakar +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20250507125032.565017-4-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Stable-dep-of: 9ce71e85b29e ("phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off") +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 49 +++++++++++++----------- + 1 file changed, 26 insertions(+), 23 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index a033bc60997ce..793f076171170 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -9,6 +9,7 @@ + * Copyright (C) 2014 Cogent Embedded, Inc. + */ + ++#include + #include + #include + #include +@@ -118,7 +119,7 @@ struct rcar_gen3_chan { + struct regulator *vbus; + struct reset_control *rstc; + struct work_struct work; +- struct mutex lock; /* protects rphys[...].powered */ ++ spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; + u32 obint_enable_bits; + bool extcon_host; +@@ -345,6 +346,8 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, + bool is_b_device; + enum phy_mode cur_mode, new_mode; + ++ guard(spinlock_irqsave)(&ch->lock); ++ + if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch)) + return -EIO; + +@@ -412,7 +415,7 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch) + val = readl(usb2_base + USB2_ADPCTRL); + writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL); + } +- msleep(20); ++ mdelay(20); + + writel(0xffffffff, usb2_base + USB2_OBINTSTA); + writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN); +@@ -433,12 +436,14 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) + if (pm_runtime_suspended(dev)) + goto rpm_put; + +- status = readl(usb2_base + USB2_OBINTSTA); +- if (status & ch->obint_enable_bits) { +- dev_vdbg(dev, "%s: %08x\n", __func__, status); +- writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); +- rcar_gen3_device_recognition(ch); +- ret = IRQ_HANDLED; ++ scoped_guard(spinlock, &ch->lock) { ++ status = readl(usb2_base + USB2_OBINTSTA); ++ if (status & ch->obint_enable_bits) { ++ dev_vdbg(dev, "%s: %08x\n", __func__, status); ++ writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); ++ rcar_gen3_device_recognition(ch); ++ ret = IRQ_HANDLED; ++ } + } + + rpm_put: +@@ -453,6 +458,8 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) + void __iomem *usb2_base = channel->base; + u32 val; + ++ guard(spinlock_irqsave)(&channel->lock); ++ + /* Initialize USB2 part */ + val = readl(usb2_base + USB2_INT_ENABLE); + val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits; +@@ -479,6 +486,8 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p) + void __iomem *usb2_base = channel->base; + u32 val; + ++ guard(spinlock_irqsave)(&channel->lock); ++ + rphy->initialized = false; + + val = readl(usb2_base + USB2_INT_ENABLE); +@@ -498,16 +507,17 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) + u32 val; + int ret = 0; + +- mutex_lock(&channel->lock); +- if (!rcar_gen3_are_all_rphys_power_off(channel)) +- goto out; +- + if (channel->vbus) { + ret = regulator_enable(channel->vbus); + if (ret) +- goto out; ++ return ret; + } + ++ guard(spinlock_irqsave)(&channel->lock); ++ ++ if (!rcar_gen3_are_all_rphys_power_off(channel)) ++ goto out; ++ + val = readl(usb2_base + USB2_USBCTR); + val |= USB2_USBCTR_PLL_RST; + writel(val, usb2_base + USB2_USBCTR); +@@ -517,7 +527,6 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) + out: + /* The powered flag should be set for any other phys anyway */ + rphy->powered = true; +- mutex_unlock(&channel->lock); + + return 0; + } +@@ -528,18 +537,12 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) + struct rcar_gen3_chan *channel = rphy->ch; + int ret = 0; + +- mutex_lock(&channel->lock); +- rphy->powered = false; +- +- if (!rcar_gen3_are_all_rphys_power_off(channel)) +- goto out; ++ scoped_guard(spinlock_irqsave, &channel->lock) ++ rphy->powered = false; + + if (channel->vbus) + ret = regulator_disable(channel->vbus); + +-out: +- mutex_unlock(&channel->lock); +- + return ret; + } + +@@ -740,7 +743,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + if (phy_data->no_adp_ctrl) + channel->obint_enable_bits = USB2_OBINT_IDCHG_EN; + +- mutex_init(&channel->lock); ++ spin_lock_init(&channel->lock); + for (i = 0; i < NUM_OF_PHYS; i++) { + channel->rphys[i].phy = devm_phy_create(dev, NULL, + phy_data->phy_usb2_ops); +-- +2.39.5 + diff --git a/queue-6.6/phy-renesas-rcar-gen3-usb2-move-irq-request-in-probe.patch b/queue-6.6/phy-renesas-rcar-gen3-usb2-move-irq-request-in-probe.patch new file mode 100644 index 0000000000..66f50b035e --- /dev/null +++ b/queue-6.6/phy-renesas-rcar-gen3-usb2-move-irq-request-in-probe.patch @@ -0,0 +1,144 @@ +From 2b8f739c5a1041d47ce7cc5370b498c6eff6cc82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 May 2025 15:50:29 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Move IRQ request in probe + +From: Claudiu Beznea + +[ Upstream commit de76809f60cc938d3580bbbd5b04b7d12af6ce3a ] + +Commit 08b0ad375ca6 ("phy: renesas: rcar-gen3-usb2: move IRQ registration +to init") moved the IRQ request operation from probe to +struct phy_ops::phy_init API to avoid triggering interrupts (which lead to +register accesses) while the PHY clocks (enabled through runtime PM APIs) +are not active. If this happens, it results in a synchronous abort. + +One way to reproduce this issue is by enabling CONFIG_DEBUG_SHIRQ, which +calls free_irq() on driver removal. + +Move the IRQ request and free operations back to probe, and take the +runtime PM state into account in IRQ handler. This commit is preparatory +for the subsequent fixes in this series. + +Reviewed-by: Yoshihiro Shimoda +Tested-by: Yoshihiro Shimoda +Reviewed-by: Lad Prabhakar +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20250507125032.565017-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Stable-dep-of: 9ce71e85b29e ("phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off") +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 46 +++++++++++++----------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index d2bbf6c6ed5e0..a033bc60997ce 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -120,7 +120,6 @@ struct rcar_gen3_chan { + struct work_struct work; + struct mutex lock; /* protects rphys[...].powered */ + enum usb_dr_mode dr_mode; +- int irq; + u32 obint_enable_bits; + bool extcon_host; + bool is_otg_channel; +@@ -425,16 +424,25 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) + { + struct rcar_gen3_chan *ch = _ch; + void __iomem *usb2_base = ch->base; +- u32 status = readl(usb2_base + USB2_OBINTSTA); ++ struct device *dev = ch->dev; + irqreturn_t ret = IRQ_NONE; ++ u32 status; + ++ pm_runtime_get_noresume(dev); ++ ++ if (pm_runtime_suspended(dev)) ++ goto rpm_put; ++ ++ status = readl(usb2_base + USB2_OBINTSTA); + if (status & ch->obint_enable_bits) { +- dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); ++ dev_vdbg(dev, "%s: %08x\n", __func__, status); + writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA); + rcar_gen3_device_recognition(ch); + ret = IRQ_HANDLED; + } + ++rpm_put: ++ pm_runtime_put_noidle(dev); + return ret; + } + +@@ -444,17 +452,6 @@ static int rcar_gen3_phy_usb2_init(struct phy *p) + struct rcar_gen3_chan *channel = rphy->ch; + void __iomem *usb2_base = channel->base; + u32 val; +- int ret; +- +- if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) { +- INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); +- ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq, +- IRQF_SHARED, dev_name(channel->dev), channel); +- if (ret < 0) { +- dev_err(channel->dev, "No irq handler (%d)\n", channel->irq); +- return ret; +- } +- } + + /* Initialize USB2 part */ + val = readl(usb2_base + USB2_INT_ENABLE); +@@ -490,9 +487,6 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p) + val &= ~USB2_INT_ENABLE_UCOM_INTEN; + writel(val, usb2_base + USB2_INT_ENABLE); + +- if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel)) +- free_irq(channel->irq, channel); +- + return 0; + } + +@@ -688,7 +682,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct rcar_gen3_chan *channel; + struct phy_provider *provider; +- int ret = 0, i; ++ int ret = 0, i, irq; + + if (!dev->of_node) { + dev_err(dev, "This driver needs device tree\n"); +@@ -704,8 +698,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + return PTR_ERR(channel->base); + + channel->obint_enable_bits = USB2_OBINT_BITS; +- /* get irq number here and request_irq for OTG in phy_init */ +- channel->irq = platform_get_irq_optional(pdev, 0); + channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); + if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { + channel->is_otg_channel = true; +@@ -771,6 +763,20 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) + channel->vbus = NULL; + } + ++ irq = platform_get_irq_optional(pdev, 0); ++ if (irq < 0 && irq != -ENXIO) { ++ ret = irq; ++ goto error; ++ } else if (irq > 0) { ++ INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); ++ ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, ++ IRQF_SHARED, dev_name(dev), channel); ++ if (ret < 0) { ++ dev_err(dev, "Failed to request irq (%d)\n", irq); ++ goto error; ++ } ++ } ++ + provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate); + if (IS_ERR(provider)) { + dev_err(dev, "Failed to register PHY provider\n"); +-- +2.39.5 + diff --git a/queue-6.6/pinctrl-bcm281xx-use-unsigned-int-instead-of-bare-un.patch b/queue-6.6/pinctrl-bcm281xx-use-unsigned-int-instead-of-bare-un.patch new file mode 100644 index 0000000000..7bd368bdab --- /dev/null +++ b/queue-6.6/pinctrl-bcm281xx-use-unsigned-int-instead-of-bare-un.patch @@ -0,0 +1,177 @@ +From f3c9b07a0f65808130ea50d343563435d8d17a0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 21:54:47 +0100 +Subject: pinctrl: bcm281xx: Use "unsigned int" instead of bare "unsigned" + +From: Artur Weber + +[ Upstream commit 07b5a2a13f4704c5eae3be7277ec54ffdba45f72 ] + +Replace uses of bare "unsigned" with "unsigned int" to fix checkpatch +warnings. No functional change. + +Signed-off-by: Artur Weber +Link: https://lore.kernel.org/20250303-bcm21664-pinctrl-v3-2-5f8b80e4ab51@gmail.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 44 +++++++++++++------------- + 1 file changed, 22 insertions(+), 22 deletions(-) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +index cf6efa9c0364a..a039b490cdb8e 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +@@ -72,7 +72,7 @@ static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI; + struct bcm281xx_pin_function { + const char *name; + const char * const *groups; +- const unsigned ngroups; ++ const unsigned int ngroups; + }; + + /* +@@ -84,10 +84,10 @@ struct bcm281xx_pinctrl_data { + + /* List of all pins */ + const struct pinctrl_pin_desc *pins; +- const unsigned npins; ++ const unsigned int npins; + + const struct bcm281xx_pin_function *functions; +- const unsigned nfunctions; ++ const unsigned int nfunctions; + + struct regmap *regmap; + }; +@@ -941,7 +941,7 @@ static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = { + }; + + static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev, +- unsigned pin) ++ unsigned int pin) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + +@@ -985,7 +985,7 @@ static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) + } + + static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev, +- unsigned group) ++ unsigned int group) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + +@@ -993,9 +993,9 @@ static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + } + + static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, +- unsigned group, ++ unsigned int group, + const unsigned **pins, +- unsigned *num_pins) ++ unsigned int *num_pins) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + +@@ -1007,7 +1007,7 @@ static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + + static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, +- unsigned offset) ++ unsigned int offset) + { + seq_printf(s, " %s", dev_name(pctldev->dev)); + } +@@ -1029,7 +1029,7 @@ static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev) + } + + static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev, +- unsigned function) ++ unsigned int function) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + +@@ -1037,9 +1037,9 @@ static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev, + } + + static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev, +- unsigned function, ++ unsigned int function, + const char * const **groups, +- unsigned * const num_groups) ++ unsigned int * const num_groups) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + +@@ -1050,8 +1050,8 @@ static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev, + } + + static int bcm281xx_pinmux_set(struct pinctrl_dev *pctldev, +- unsigned function, +- unsigned group) ++ unsigned int function, ++ unsigned int group) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + const struct bcm281xx_pin_function *f = &pdata->functions[function]; +@@ -1082,7 +1082,7 @@ static const struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = { + }; + + static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev, +- unsigned pin, ++ unsigned int pin, + unsigned long *config) + { + return -ENOTSUPP; +@@ -1091,9 +1091,9 @@ static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev, + + /* Goes through the configs and update register val/mask */ + static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev, +- unsigned pin, ++ unsigned int pin, + unsigned long *configs, +- unsigned num_configs, ++ unsigned int num_configs, + u32 *val, + u32 *mask) + { +@@ -1207,9 +1207,9 @@ static const u16 bcm281xx_pullup_map[] = { + + /* Goes through the configs and update register val/mask */ + static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev, +- unsigned pin, ++ unsigned int pin, + unsigned long *configs, +- unsigned num_configs, ++ unsigned int num_configs, + u32 *val, + u32 *mask) + { +@@ -1277,9 +1277,9 @@ static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev, + + /* Goes through the configs and update register val/mask */ + static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev, +- unsigned pin, ++ unsigned int pin, + unsigned long *configs, +- unsigned num_configs, ++ unsigned int num_configs, + u32 *val, + u32 *mask) + { +@@ -1321,9 +1321,9 @@ static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev, + } + + static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev, +- unsigned pin, ++ unsigned int pin, + unsigned long *configs, +- unsigned num_configs) ++ unsigned int num_configs) + { + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + enum bcm281xx_pin_type pin_type; +-- +2.39.5 + diff --git a/queue-6.6/pinctrl-devicetree-do-not-goto-err-when-probing-hogs.patch b/queue-6.6/pinctrl-devicetree-do-not-goto-err-when-probing-hogs.patch new file mode 100644 index 0000000000..df4c82b2d8 --- /dev/null +++ b/queue-6.6/pinctrl-devicetree-do-not-goto-err-when-probing-hogs.patch @@ -0,0 +1,110 @@ +From db9daea4034ac30a8d9db1e75f79a98035609adc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jan 2025 18:00:09 +0100 +Subject: pinctrl: devicetree: do not goto err when probing hogs in + pinctrl_dt_to_map + +From: Valentin Caron + +[ Upstream commit c98868e816209e568c9d72023ba0bc1e4d96e611 ] + +Cross case in pinctrl framework make impossible to an hogged pin and +another, not hogged, used within the same device-tree node. For example +with this simplified device-tree : + + &pinctrl { + pinctrl_pin_1: pinctrl-pin-1 { + pins = "dummy-pinctrl-pin"; + }; + }; + + &rtc { + pinctrl-names = "default" + pinctrl-0 = <&pinctrl_pin_1 &rtc_pin_1> + + rtc_pin_1: rtc-pin-1 { + pins = "dummy-rtc-pin"; + }; + }; + +"pinctrl_pin_1" configuration is never set. This produces this path in +the code: + + really_probe() + pinctrl_bind_pins() + | devm_pinctrl_get() + | pinctrl_get() + | create_pinctrl() + | pinctrl_dt_to_map() + | // Hog pin create an abort for all pins of the node + | ret = dt_to_map_one_config() + | | /* Do not defer probing of hogs (circular loop) */ + | | if (np_pctldev == p->dev->of_node) + | | return -ENODEV; + | if (ret) + | goto err + | + call_driver_probe() + stm32_rtc_probe() + pinctrl_enable() + pinctrl_claim_hogs() + create_pinctrl() + for_each_maps(maps_node, i, map) + // Not hog pin is skipped + if (pctldev && strcmp(dev_name(pctldev->dev), + map->ctrl_dev_name)) + continue; + +At the first call of create_pinctrl() the hogged pin produces an abort to +avoid a defer of hogged pins. All other pin configurations are trashed. + +At the second call, create_pinctrl is now called with pctldev parameter to +get hogs, but in this context only hogs are set. And other pins are +skipped. + +To handle this, do not produce an abort in the first call of +create_pinctrl(). Classic pin configuration will be set in +pinctrl_bind_pins() context. And the hogged pin configuration will be set +in pinctrl_claim_hogs() context. + +Signed-off-by: Valentin Caron +Link: https://lore.kernel.org/20250116170009.2075544-1-valentin.caron@foss.st.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/devicetree.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c +index 5ee746cb81f59..6520b88db1105 100644 +--- a/drivers/pinctrl/devicetree.c ++++ b/drivers/pinctrl/devicetree.c +@@ -143,10 +143,14 @@ static int dt_to_map_one_config(struct pinctrl *p, + pctldev = get_pinctrl_dev_from_of_node(np_pctldev); + if (pctldev) + break; +- /* Do not defer probing of hogs (circular loop) */ ++ /* ++ * Do not defer probing of hogs (circular loop) ++ * ++ * Return 1 to let the caller catch the case. ++ */ + if (np_pctldev == p->dev->of_node) { + of_node_put(np_pctldev); +- return -ENODEV; ++ return 1; + } + } + of_node_put(np_pctldev); +@@ -265,6 +269,8 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) + ret = dt_to_map_one_config(p, pctldev, statename, + np_config); + of_node_put(np_config); ++ if (ret == 1) ++ continue; + if (ret < 0) + goto err; + } +-- +2.39.5 + diff --git a/queue-6.6/pinctrl-meson-define-the-pull-up-down-resistor-value.patch b/queue-6.6/pinctrl-meson-define-the-pull-up-down-resistor-value.patch new file mode 100644 index 0000000000..7c3896321d --- /dev/null +++ b/queue-6.6/pinctrl-meson-define-the-pull-up-down-resistor-value.patch @@ -0,0 +1,53 @@ +From 4caaacbc2f4d66893a6d9e36c9ebb504fdb0c94e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Mar 2025 20:01:32 +0100 +Subject: pinctrl: meson: define the pull up/down resistor value as 60 kOhm + +From: Martin Blumenstingl + +[ Upstream commit e56088a13708757da68ad035269d69b93ac8c389 ] + +The public datasheets of the following Amlogic SoCs describe a typical +resistor value for the built-in pull up/down resistor: +- Meson8/8b/8m2: not documented +- GXBB (S905): 60 kOhm +- GXL (S905X): 60 kOhm +- GXM (S912): 60 kOhm +- G12B (S922X): 60 kOhm +- SM1 (S905D3): 60 kOhm + +The public G12B and SM1 datasheets additionally state min and max +values: +- min value: 50 kOhm for both, pull-up and pull-down +- max value for the pull-up: 70 kOhm +- max value for the pull-down: 130 kOhm + +Use 60 kOhm in the pinctrl-meson driver as well so it's shown in the +debugfs output. It may not be accurate for Meson8/8b/8m2 but in reality +60 kOhm is closer to the actual value than 1 Ohm. + +Signed-off-by: Martin Blumenstingl +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/20250329190132.855196-1-martin.blumenstingl@googlemail.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/meson/pinctrl-meson.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c +index 524424ee6c4e7..5cc00fdc48d84 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson.c ++++ b/drivers/pinctrl/meson/pinctrl-meson.c +@@ -486,7 +486,7 @@ static int meson_pinconf_get(struct pinctrl_dev *pcdev, unsigned int pin, + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (meson_pinconf_get_pull(pc, pin) == param) +- arg = 1; ++ arg = 60000; + else + return -EINVAL; + break; +-- +2.39.5 + diff --git a/queue-6.6/pinctrl-tegra-restore-sfsel-bit-when-freeing-pins.patch b/queue-6.6/pinctrl-tegra-restore-sfsel-bit-when-freeing-pins.patch new file mode 100644 index 0000000000..52011b4cee --- /dev/null +++ b/queue-6.6/pinctrl-tegra-restore-sfsel-bit-when-freeing-pins.patch @@ -0,0 +1,183 @@ +From b7badafe1b8542f9b1f1db11ed7179091cfad514 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 16:19:39 +0530 +Subject: pinctrl-tegra: Restore SFSEL bit when freeing pins + +From: Prathamesh Shete + +[ Upstream commit c12bfa0fee65940b10ff5187349f76c6f6b1df9c ] + +Each pin can be configured as a Special Function IO (SFIO) or GPIO, +where the SFIO enables the pin to operate in alternative modes such as +I2C, SPI, etc. + +The current implementation sets all the pins back to SFIO mode +even if they were initially in GPIO mode. This can cause glitches +on the pins when pinctrl_gpio_free() is called. + +Avoid these undesired glitches by storing the pin's SFIO/GPIO +state on GPIO request and restoring it on GPIO free. + +Signed-off-by: Prathamesh Shete +Link: https://lore.kernel.org/20250305104939.15168-2-pshete@nvidia.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/tegra/pinctrl-tegra.c | 59 +++++++++++++++++++++++---- + drivers/pinctrl/tegra/pinctrl-tegra.h | 6 +++ + 2 files changed, 57 insertions(+), 8 deletions(-) + +diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c +index 7c12a3470642c..1350ab56fbc03 100644 +--- a/drivers/pinctrl/tegra/pinctrl-tegra.c ++++ b/drivers/pinctrl/tegra/pinctrl-tegra.c +@@ -280,8 +280,8 @@ static int tegra_pinctrl_set_mux(struct pinctrl_dev *pctldev, + return 0; + } + +-static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctldev, +- unsigned int offset) ++static int tegra_pinctrl_get_group_index(struct pinctrl_dev *pctldev, ++ unsigned int offset) + { + struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + unsigned int group, num_pins, j; +@@ -294,12 +294,35 @@ static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev * + continue; + for (j = 0; j < num_pins; j++) { + if (offset == pins[j]) +- return &pmx->soc->groups[group]; ++ return group; + } + } + +- dev_err(pctldev->dev, "Pingroup not found for pin %u\n", offset); +- return NULL; ++ return -EINVAL; ++} ++ ++static const struct tegra_pingroup *tegra_pinctrl_get_group(struct pinctrl_dev *pctldev, ++ unsigned int offset, ++ int group_index) ++{ ++ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); ++ ++ if (group_index < 0 || group_index > pmx->soc->ngroups) ++ return NULL; ++ ++ return &pmx->soc->groups[group_index]; ++} ++ ++static struct tegra_pingroup_config *tegra_pinctrl_get_group_config(struct pinctrl_dev *pctldev, ++ unsigned int offset, ++ int group_index) ++{ ++ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); ++ ++ if (group_index < 0) ++ return NULL; ++ ++ return &pmx->pingroup_configs[group_index]; + } + + static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, +@@ -308,12 +331,15 @@ static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, + { + struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + const struct tegra_pingroup *group; ++ struct tegra_pingroup_config *config; ++ int group_index; + u32 value; + + if (!pmx->soc->sfsel_in_mux) + return 0; + +- group = tegra_pinctrl_get_group(pctldev, offset); ++ group_index = tegra_pinctrl_get_group_index(pctldev, offset); ++ group = tegra_pinctrl_get_group(pctldev, offset, group_index); + + if (!group) + return -EINVAL; +@@ -321,7 +347,11 @@ static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, + if (group->mux_reg < 0 || group->sfsel_bit < 0) + return -EINVAL; + ++ config = tegra_pinctrl_get_group_config(pctldev, offset, group_index); ++ if (!config) ++ return -EINVAL; + value = pmx_readl(pmx, group->mux_bank, group->mux_reg); ++ config->is_sfsel = (value & BIT(group->sfsel_bit)) != 0; + value &= ~BIT(group->sfsel_bit); + pmx_writel(pmx, value, group->mux_bank, group->mux_reg); + +@@ -334,12 +364,15 @@ static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev, + { + struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + const struct tegra_pingroup *group; ++ struct tegra_pingroup_config *config; ++ int group_index; + u32 value; + + if (!pmx->soc->sfsel_in_mux) + return; + +- group = tegra_pinctrl_get_group(pctldev, offset); ++ group_index = tegra_pinctrl_get_group_index(pctldev, offset); ++ group = tegra_pinctrl_get_group(pctldev, offset, group_index); + + if (!group) + return; +@@ -347,8 +380,12 @@ static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev, + if (group->mux_reg < 0 || group->sfsel_bit < 0) + return; + ++ config = tegra_pinctrl_get_group_config(pctldev, offset, group_index); ++ if (!config) ++ return; + value = pmx_readl(pmx, group->mux_bank, group->mux_reg); +- value |= BIT(group->sfsel_bit); ++ if (config->is_sfsel) ++ value |= BIT(group->sfsel_bit); + pmx_writel(pmx, value, group->mux_bank, group->mux_reg); + } + +@@ -785,6 +822,12 @@ int tegra_pinctrl_probe(struct platform_device *pdev, + pmx->dev = &pdev->dev; + pmx->soc = soc_data; + ++ pmx->pingroup_configs = devm_kcalloc(&pdev->dev, ++ pmx->soc->ngroups, sizeof(*pmx->pingroup_configs), ++ GFP_KERNEL); ++ if (!pmx->pingroup_configs) ++ return -ENOMEM; ++ + /* + * Each mux group will appear in 4 functions' list of groups. + * This over-allocates slightly, since not all groups are mux groups. +diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h +index b3289bdf727d8..b97136685f7a8 100644 +--- a/drivers/pinctrl/tegra/pinctrl-tegra.h ++++ b/drivers/pinctrl/tegra/pinctrl-tegra.h +@@ -8,6 +8,10 @@ + #ifndef __PINMUX_TEGRA_H__ + #define __PINMUX_TEGRA_H__ + ++struct tegra_pingroup_config { ++ bool is_sfsel; ++}; ++ + struct tegra_pmx { + struct device *dev; + struct pinctrl_dev *pctl; +@@ -21,6 +25,8 @@ struct tegra_pmx { + int nbanks; + void __iomem **regs; + u32 *backup_regs; ++ /* Array of size soc->ngroups */ ++ struct tegra_pingroup_config *pingroup_configs; + }; + + enum tegra_pinconf_param { +-- +2.39.5 + diff --git a/queue-6.6/pmdomain-imx-gpcv2-use-proper-helper-for-property-de.patch b/queue-6.6/pmdomain-imx-gpcv2-use-proper-helper-for-property-de.patch new file mode 100644 index 0000000000..16f3ef6a18 --- /dev/null +++ b/queue-6.6/pmdomain-imx-gpcv2-use-proper-helper-for-property-de.patch @@ -0,0 +1,40 @@ +From 443e9e4e51a3ec5410dd8d587c4547e681f988b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 20:18:32 +0100 +Subject: pmdomain: imx: gpcv2: use proper helper for property detection + +From: Ahmad Fatoum + +[ Upstream commit 6568cb40e73163fa25e2779f7234b169b2e1a32e ] + +Starting with commit c141ecc3cecd7 ("of: Warn when of_property_read_bool() +is used on non-boolean properties"), probing the gpcv2 device on i.MX8M +SoCs leads to warnings when LOCKDEP is enabled. + +Fix this by checking property presence with of_property_present as +intended. + +Signed-off-by: Ahmad Fatoum +Link: https://lore.kernel.org/r/20250218-gpcv2-of-property-present-v1-1-3bb1a9789654@pengutronix.de +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/pmdomain/imx/gpcv2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c +index 13fce2b134f60..84d68c805cac8 100644 +--- a/drivers/pmdomain/imx/gpcv2.c ++++ b/drivers/pmdomain/imx/gpcv2.c +@@ -1350,7 +1350,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) + } + + if (IS_ENABLED(CONFIG_LOCKDEP) && +- of_property_read_bool(domain->dev->of_node, "power-domains")) ++ of_property_present(domain->dev->of_node, "power-domains")) + lockdep_set_subclass(&domain->genpd.mlock, 1); + + ret = of_genpd_add_provider_simple(domain->dev->of_node, +-- +2.39.5 + diff --git a/queue-6.6/pnfs-flexfiles-report-enetdown-as-a-connection-error.patch b/queue-6.6/pnfs-flexfiles-report-enetdown-as-a-connection-error.patch new file mode 100644 index 0000000000..a0e7c5c410 --- /dev/null +++ b/queue-6.6/pnfs-flexfiles-report-enetdown-as-a-connection-error.patch @@ -0,0 +1,37 @@ +From 673bca1e056481e8b94e37c3c33e127ebf160fe6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Mar 2025 12:45:01 -0400 +Subject: pNFS/flexfiles: Report ENETDOWN as a connection error + +From: Trond Myklebust + +[ Upstream commit aa42add73ce9b9e3714723d385c254b75814e335 ] + +If the client should see an ENETDOWN when trying to connect to the data +server, it might still be able to talk to the metadata server through +another NIC. If so, report the error. + +Signed-off-by: Trond Myklebust +Reviewed-by: Jeff Layton +Tested-by: Jeff Layton +Acked-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfs/flexfilelayout/flexfilelayout.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 2b3c5eea1f134..0bc537de1b295 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -1255,6 +1255,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, + case -ECONNRESET: + case -EHOSTDOWN: + case -EHOSTUNREACH: ++ case -ENETDOWN: + case -ENETUNREACH: + case -EADDRINUSE: + case -ENOBUFS: +-- +2.39.5 + diff --git a/queue-6.6/posix-timers-add-cond_resched-to-posix_timer_add-sea.patch b/queue-6.6/posix-timers-add-cond_resched-to-posix_timer_add-sea.patch new file mode 100644 index 0000000000..66b44b7048 --- /dev/null +++ b/queue-6.6/posix-timers-add-cond_resched-to-posix_timer_add-sea.patch @@ -0,0 +1,41 @@ +From 73fd6fb1a1c7a67d97f6924b642f4ecf6998c547 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Mar 2025 17:48:17 +0100 +Subject: posix-timers: Add cond_resched() to posix_timer_add() search loop + +From: Eric Dumazet + +[ Upstream commit 5f2909c6cd13564a07ae692a95457f52295c4f22 ] + +With a large number of POSIX timers the search for a valid ID might cause a +soft lockup on PREEMPT_NONE/VOLUNTARY kernels. + +Add cond_resched() to the loop to prevent that. + +[ tglx: Split out from Eric's series ] + +Signed-off-by: Eric Dumazet +Signed-off-by: Thomas Gleixner +Reviewed-by: Frederic Weisbecker +Link: https://lore.kernel.org/all/20250214135911.2037402-2-edumazet@google.com +Link: https://lore.kernel.org/all/20250308155623.635612865@linutronix.de +Signed-off-by: Sasha Levin +--- + kernel/time/posix-timers.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c +index b924f0f096fa4..7534069f60333 100644 +--- a/kernel/time/posix-timers.c ++++ b/kernel/time/posix-timers.c +@@ -118,6 +118,7 @@ static int posix_timer_add(struct k_itimer *timer) + return id; + } + spin_unlock(&hash_lock); ++ cond_resched(); + } + /* POSIX return code when no timer ID could be allocated */ + return -EAGAIN; +-- +2.39.5 + diff --git a/queue-6.6/powerpc-prom_init-fixup-missing-size-cells-on-powerb.patch b/queue-6.6/powerpc-prom_init-fixup-missing-size-cells-on-powerb.patch new file mode 100644 index 0000000000..dbcd5c9346 --- /dev/null +++ b/queue-6.6/powerpc-prom_init-fixup-missing-size-cells-on-powerb.patch @@ -0,0 +1,44 @@ +From 4d354b104997f72b4129fe4ff34c7c9b31b1bb5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 18:19:09 +0100 +Subject: powerpc/prom_init: Fixup missing #size-cells on PowerBook6,7 + +From: Andreas Schwab + +[ Upstream commit 7e67ef889c9ab7246547db73d524459f47403a77 ] + +Similar to the PowerMac3,1, the PowerBook6,7 is missing the #size-cells +property on the i2s node. + +Depends-on: commit 045b14ca5c36 ("of: WARN on deprecated #address-cells/#size-cells handling") +Signed-off-by: Andreas Schwab +Acked-by: Rob Herring (Arm) +[maddy: added "commit" work in depends-on to avoid checkpatch error] +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/875xmizl6a.fsf@igel.home +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/prom_init.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c +index a6090896f7497..ac669e58e2023 100644 +--- a/arch/powerpc/kernel/prom_init.c ++++ b/arch/powerpc/kernel/prom_init.c +@@ -2974,11 +2974,11 @@ static void __init fixup_device_tree_pmac(void) + char type[8]; + phandle node; + +- // Some pmacs are missing #size-cells on escc nodes ++ // Some pmacs are missing #size-cells on escc or i2s nodes + for (node = 0; prom_next_node(&node); ) { + type[0] = '\0'; + prom_getprop(node, "device_type", type, sizeof(type)); +- if (prom_strcmp(type, "escc")) ++ if (prom_strcmp(type, "escc") && prom_strcmp(type, "i2s")) + continue; + + if (prom_getproplen(node, "#size-cells") != PROM_ERROR) +-- +2.39.5 + diff --git a/queue-6.6/powerpc-pseries-iommu-memory-notifier-incorrectly-ad.patch b/queue-6.6/powerpc-pseries-iommu-memory-notifier-incorrectly-ad.patch new file mode 100644 index 0000000000..271f77abb5 --- /dev/null +++ b/queue-6.6/powerpc-pseries-iommu-memory-notifier-incorrectly-ad.patch @@ -0,0 +1,138 @@ +From e1dd7608bdb859c9a95c083038159d545454ec28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2025 12:38:54 -0600 +Subject: powerpc/pseries/iommu: memory notifier incorrectly adds TCEs for + pmemory + +From: Gaurav Batra + +[ Upstream commit 6aa989ab2bd0d37540c812b4270006ff794662e7 ] + +iommu_mem_notifier() is invoked when RAM is dynamically added/removed. This +notifier call is responsible to add/remove TCEs from the Dynamic DMA Window +(DDW) when TCEs are pre-mapped. TCEs are pre-mapped only for RAM and not +for persistent memory (pmemory). For DMA buffers in pmemory, TCEs are +dynamically mapped when the device driver instructs to do so. + +The issue is 'daxctl' command is capable of adding pmemory as "System RAM" +after LPAR boot. The command to do so is - + +daxctl reconfigure-device --mode=system-ram dax0.0 --force + +This will dynamically add pmemory range to LPAR RAM eventually invoking +iommu_mem_notifier(). The address range of pmemory is way beyond the Max +RAM that the LPAR can have. Which means, this range is beyond the DDW +created for the device, at device initialization time. + +As a result when TCEs are pre-mapped for the pmemory range, by +iommu_mem_notifier(), PHYP HCALL returns H_PARAMETER. This failed the +command, daxctl, to add pmemory as RAM. + +The solution is to not pre-map TCEs for pmemory. + +Signed-off-by: Gaurav Batra +Tested-by: Donet Tom +Reviewed-by: Donet Tom +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250130183854.92258-1-gbatra@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/mmzone.h | 1 + + arch/powerpc/mm/numa.c | 2 +- + arch/powerpc/platforms/pseries/iommu.c | 29 ++++++++++++++------------ + 3 files changed, 18 insertions(+), 14 deletions(-) + +diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h +index da827d2d08666..f2c4457c94c39 100644 +--- a/arch/powerpc/include/asm/mmzone.h ++++ b/arch/powerpc/include/asm/mmzone.h +@@ -35,6 +35,7 @@ extern cpumask_var_t node_to_cpumask_map[]; + #ifdef CONFIG_MEMORY_HOTPLUG + extern unsigned long max_pfn; + u64 memory_hotplug_max(void); ++u64 hot_add_drconf_memory_max(void); + #else + #define memory_hotplug_max() memblock_end_of_DRAM() + #endif +diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c +index f6c4ace3b2219..65a9df0b9e5a0 100644 +--- a/arch/powerpc/mm/numa.c ++++ b/arch/powerpc/mm/numa.c +@@ -1342,7 +1342,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr) + return nid; + } + +-static u64 hot_add_drconf_memory_max(void) ++u64 hot_add_drconf_memory_max(void) + { + struct device_node *memory = NULL; + struct device_node *dn = NULL; +diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c +index b1e6d275cda9e..bf02f94a973db 100644 +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -1183,17 +1183,13 @@ static LIST_HEAD(failed_ddw_pdn_list); + + static phys_addr_t ddw_memory_hotplug_max(void) + { +- resource_size_t max_addr = memory_hotplug_max(); +- struct device_node *memory; ++ resource_size_t max_addr; + +- for_each_node_by_type(memory, "memory") { +- struct resource res; +- +- if (of_address_to_resource(memory, 0, &res)) +- continue; +- +- max_addr = max_t(resource_size_t, max_addr, res.end + 1); +- } ++#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG) ++ max_addr = hot_add_drconf_memory_max(); ++#else ++ max_addr = memblock_end_of_DRAM(); ++#endif + + return max_addr; + } +@@ -1471,7 +1467,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) + window->direct = true; + + /* DDW maps the whole partition, so enable direct DMA mapping */ +- ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT, ++ ret = walk_system_ram_range(0, ddw_memory_hotplug_max() >> PAGE_SHIFT, + win64->value, tce_setrange_multi_pSeriesLP_walk); + if (ret) { + dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n", +@@ -1658,11 +1654,17 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, + struct memory_notify *arg = data; + int ret = 0; + ++ /* This notifier can get called when onlining persistent memory as well. ++ * TCEs are not pre-mapped for persistent memory. Persistent memory will ++ * always be above ddw_memory_hotplug_max() ++ */ ++ + switch (action) { + case MEM_GOING_ONLINE: + spin_lock(&dma_win_list_lock); + list_for_each_entry(window, &dma_win_list, list) { +- if (window->direct) { ++ if (window->direct && (arg->start_pfn << PAGE_SHIFT) < ++ ddw_memory_hotplug_max()) { + ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn, + arg->nr_pages, window->prop); + } +@@ -1674,7 +1676,8 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, + case MEM_OFFLINE: + spin_lock(&dma_win_list_lock); + list_for_each_entry(window, &dma_win_list, list) { +- if (window->direct) { ++ if (window->direct && (arg->start_pfn << PAGE_SHIFT) < ++ ddw_memory_hotplug_max()) { + ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn, + arg->nr_pages, window->prop); + } +-- +2.39.5 + diff --git a/queue-6.6/printk-check-con_suspend-when-unblanking-a-console.patch b/queue-6.6/printk-check-con_suspend-when-unblanking-a-console.patch new file mode 100644 index 0000000000..9a6ceb95a0 --- /dev/null +++ b/queue-6.6/printk-check-con_suspend-when-unblanking-a-console.patch @@ -0,0 +1,59 @@ +From 1ca98ffb6c9c0b9923931c33c25a16c1cbad5e43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 16:59:05 -0300 +Subject: printk: Check CON_SUSPEND when unblanking a console + +From: Marcos Paulo de Souza + +[ Upstream commit 72c96a2dacc0fb056d13a5f02b0845c4c910fe54 ] + +The commit 9e70a5e109a4 ("printk: Add per-console suspended state") +introduced the CON_SUSPENDED flag for consoles. The suspended consoles +will stop receiving messages, so don't unblank suspended consoles +because it won't be showing anything either way. + +Signed-off-by: Marcos Paulo de Souza +Reviewed-by: Petr Mladek +Reviewed-by: John Ogness +Link: https://lore.kernel.org/r/20250226-printk-renaming-v1-5-0b878577f2e6@suse.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + kernel/printk/printk.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c +index dcdf449615bda..51c43e0f9b29b 100644 +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -3119,7 +3119,12 @@ void console_unblank(void) + */ + cookie = console_srcu_read_lock(); + for_each_console_srcu(c) { +- if ((console_srcu_read_flags(c) & CON_ENABLED) && c->unblank) { ++ short flags = console_srcu_read_flags(c); ++ ++ if (flags & CON_SUSPENDED) ++ continue; ++ ++ if ((flags & CON_ENABLED) && c->unblank) { + found_unblank = true; + break; + } +@@ -3156,7 +3161,12 @@ void console_unblank(void) + + cookie = console_srcu_read_lock(); + for_each_console_srcu(c) { +- if ((console_srcu_read_flags(c) & CON_ENABLED) && c->unblank) ++ short flags = console_srcu_read_flags(c); ++ ++ if (flags & CON_SUSPENDED) ++ continue; ++ ++ if ((flags & CON_ENABLED) && c->unblank) + c->unblank(); + } + console_srcu_read_unlock(cookie); +-- +2.39.5 + diff --git a/queue-6.6/pstore-change-kmsg_bytes-storage-size-to-u32.patch b/queue-6.6/pstore-change-kmsg_bytes-storage-size-to-u32.patch new file mode 100644 index 0000000000..097bcd1fc6 --- /dev/null +++ b/queue-6.6/pstore-change-kmsg_bytes-storage-size-to-u32.patch @@ -0,0 +1,108 @@ +From 83268697b91a5c29e434ccd2afe0c16ee626de1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 11:16:59 -0800 +Subject: pstore: Change kmsg_bytes storage size to u32 + +From: Kees Cook + +[ Upstream commit 5674609535bafa834ab014d90d9bbe8e89223a0b ] + +The types around kmsg_bytes were inconsistent. The global was unsigned +long, the argument to pstore_set_kmsg_bytes() was int, and the filesystem +option was u32. Given other internal limits, there's not much sense +in making a single pstore record larger than INT_MAX and it can't be +negative, so use u32 everywhere. Additionally, use READ/WRITE_ONCE and a +local variable in pstore_dump() to avoid kmsg_bytes changing during a +dump. + +Link: https://lore.kernel.org/r/20250206191655.work.798-kees@kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Sasha Levin +--- + fs/pstore/inode.c | 2 +- + fs/pstore/internal.h | 4 ++-- + fs/pstore/platform.c | 11 ++++++----- + 3 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c +index 7dbbf3b6d98d3..a1c97cd2720a6 100644 +--- a/fs/pstore/inode.c ++++ b/fs/pstore/inode.c +@@ -264,7 +264,7 @@ static void parse_options(char *options) + static int pstore_show_options(struct seq_file *m, struct dentry *root) + { + if (kmsg_bytes != CONFIG_PSTORE_DEFAULT_KMSG_BYTES) +- seq_printf(m, ",kmsg_bytes=%lu", kmsg_bytes); ++ seq_printf(m, ",kmsg_bytes=%u", kmsg_bytes); + return 0; + } + +diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h +index 801d6c0b170c3..a0fc511969100 100644 +--- a/fs/pstore/internal.h ++++ b/fs/pstore/internal.h +@@ -6,7 +6,7 @@ + #include + #include + +-extern unsigned long kmsg_bytes; ++extern unsigned int kmsg_bytes; + + #ifdef CONFIG_PSTORE_FTRACE + extern void pstore_register_ftrace(void); +@@ -35,7 +35,7 @@ static inline void pstore_unregister_pmsg(void) {} + + extern struct pstore_info *psinfo; + +-extern void pstore_set_kmsg_bytes(int); ++extern void pstore_set_kmsg_bytes(unsigned int bytes); + extern void pstore_get_records(int); + extern void pstore_get_backend_records(struct pstore_info *psi, + struct dentry *root, int quiet); +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index 03425928d2fb3..ef62389212b60 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -92,8 +92,8 @@ module_param(compress, charp, 0444); + MODULE_PARM_DESC(compress, "compression to use"); + + /* How much of the kernel log to snapshot */ +-unsigned long kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES; +-module_param(kmsg_bytes, ulong, 0444); ++unsigned int kmsg_bytes = CONFIG_PSTORE_DEFAULT_KMSG_BYTES; ++module_param(kmsg_bytes, uint, 0444); + MODULE_PARM_DESC(kmsg_bytes, "amount of kernel log to snapshot (in bytes)"); + + static void *compress_workspace; +@@ -107,9 +107,9 @@ static void *compress_workspace; + static char *big_oops_buf; + static size_t max_compressed_size; + +-void pstore_set_kmsg_bytes(int bytes) ++void pstore_set_kmsg_bytes(unsigned int bytes) + { +- kmsg_bytes = bytes; ++ WRITE_ONCE(kmsg_bytes, bytes); + } + + /* Tag each group of saved records with a sequence number */ +@@ -278,6 +278,7 @@ static void pstore_dump(struct kmsg_dumper *dumper, + enum kmsg_dump_reason reason) + { + struct kmsg_dump_iter iter; ++ unsigned int remaining = READ_ONCE(kmsg_bytes); + unsigned long total = 0; + const char *why; + unsigned int part = 1; +@@ -300,7 +301,7 @@ static void pstore_dump(struct kmsg_dumper *dumper, + kmsg_dump_rewind(&iter); + + oopscount++; +- while (total < kmsg_bytes) { ++ while (total < remaining) { + char *dst; + size_t dst_size; + int header_size; +-- +2.39.5 + diff --git a/queue-6.6/r8152-add-vendor-device-id-pair-for-dell-alienware-a.patch b/queue-6.6/r8152-add-vendor-device-id-pair-for-dell-alienware-a.patch new file mode 100644 index 0000000000..284be800d4 --- /dev/null +++ b/queue-6.6/r8152-add-vendor-device-id-pair-for-dell-alienware-a.patch @@ -0,0 +1,50 @@ +From 3b537f3138ff815ad406ff6fc199cf4e27e9b3a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 23:40:33 +0100 +Subject: r8152: add vendor/device ID pair for Dell Alienware AW1022z + +From: Aleksander Jan Bajkowski + +[ Upstream commit 848b09d53d923b4caee5491f57a5c5b22d81febc ] + +The Dell AW1022z is an RTL8156B based 2.5G Ethernet controller. + +Add the vendor and product ID values to the driver. This makes Ethernet +work with the adapter. + +Signed-off-by: Aleksander Jan Bajkowski +Link: https://patch.msgid.link/20250206224033.980115-1-olek2@wp.pl +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/r8152.c | 1 + + include/linux/usb/r8152.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index bbcefcc7ef8f0..1e85cfe524e87 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -10032,6 +10032,7 @@ static const struct usb_device_id rtl8152_table[] = { + { USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff) }, + { USB_DEVICE(VENDOR_ID_TPLINK, 0x0601) }, + { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, ++ { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, + { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, + {} + }; +diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h +index 33a4c146dc19c..2ca60828f28bb 100644 +--- a/include/linux/usb/r8152.h ++++ b/include/linux/usb/r8152.h +@@ -30,6 +30,7 @@ + #define VENDOR_ID_NVIDIA 0x0955 + #define VENDOR_ID_TPLINK 0x2357 + #define VENDOR_ID_DLINK 0x2001 ++#define VENDOR_ID_DELL 0x413c + #define VENDOR_ID_ASUS 0x0b05 + + #if IS_REACHABLE(CONFIG_USB_RTL8152) +-- +2.39.5 + diff --git a/queue-6.6/r8169-don-t-scan-phy-addresses-0.patch b/queue-6.6/r8169-don-t-scan-phy-addresses-0.patch new file mode 100644 index 0000000000..c82d678e5d --- /dev/null +++ b/queue-6.6/r8169-don-t-scan-phy-addresses-0.patch @@ -0,0 +1,36 @@ +From d119a3cbce392ed06a913b215b3a445c0f196244 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 07:58:17 +0100 +Subject: r8169: don't scan PHY addresses > 0 + +From: Heiner Kallweit + +[ Upstream commit faac69a4ae5abb49e62c79c66b51bb905c9aa5ec ] + +The PHY address is a dummy, because r8169 PHY access registers +don't support a PHY address. Therefore scan address 0 only. + +Signed-off-by: Heiner Kallweit +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/830637dd-4016-4a68-92b3-618fcac6589d@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/realtek/r8169_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c +index 7e5258b2c4290..5af932a5e70c4 100644 +--- a/drivers/net/ethernet/realtek/r8169_main.c ++++ b/drivers/net/ethernet/realtek/r8169_main.c +@@ -5125,6 +5125,7 @@ static int r8169_mdio_register(struct rtl8169_private *tp) + new_bus->priv = tp; + new_bus->parent = &pdev->dev; + new_bus->irq[0] = PHY_MAC_INTERRUPT; ++ new_bus->phy_mask = GENMASK(31, 1); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x-%x", + pci_domain_nr(pdev->bus), pci_dev_id(pdev)); + +-- +2.39.5 + diff --git a/queue-6.6/rcu-fix-header-guard-for-rcu_all_qs.patch b/queue-6.6/rcu-fix-header-guard-for-rcu_all_qs.patch new file mode 100644 index 0000000000..b5d35e3e25 --- /dev/null +++ b/queue-6.6/rcu-fix-header-guard-for-rcu_all_qs.patch @@ -0,0 +1,44 @@ +From 8e2c421e3859d1ad17965d3a060f5f187c2a4305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Dec 2024 20:06:52 -0800 +Subject: rcu: fix header guard for rcu_all_qs() + +From: Ankur Arora + +[ Upstream commit ad6b5b73ff565e88aca7a7d1286788d80c97ba71 ] + +rcu_all_qs() is defined for !CONFIG_PREEMPT_RCU but the declaration +is conditioned on CONFIG_PREEMPTION. + +With CONFIG_PREEMPT_LAZY, CONFIG_PREEMPTION=y does not imply +CONFIG_PREEMPT_RCU=y. + +Decouple the two. + +Cc: Paul E. McKenney +Reviewed-by: Frederic Weisbecker +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: Ankur Arora +Signed-off-by: Paul E. McKenney +Signed-off-by: Boqun Feng +Signed-off-by: Sasha Levin +--- + include/linux/rcutree.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h +index 126f6b418f6af..559f758bf2eaa 100644 +--- a/include/linux/rcutree.h ++++ b/include/linux/rcutree.h +@@ -104,7 +104,7 @@ extern int rcu_scheduler_active; + void rcu_end_inkernel_boot(void); + bool rcu_inkernel_boot_has_ended(void); + bool rcu_is_watching(void); +-#ifndef CONFIG_PREEMPTION ++#ifndef CONFIG_PREEMPT_RCU + void rcu_all_qs(void); + #endif + +-- +2.39.5 + diff --git a/queue-6.6/rcu-handle-quiescent-states-for-preempt_rcu-n-preemp.patch b/queue-6.6/rcu-handle-quiescent-states-for-preempt_rcu-n-preemp.patch new file mode 100644 index 0000000000..3b7721d950 --- /dev/null +++ b/queue-6.6/rcu-handle-quiescent-states-for-preempt_rcu-n-preemp.patch @@ -0,0 +1,63 @@ +From 248faa6a5dab92ff0b4e5ec1b502ce73401c8f13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Dec 2024 20:06:56 -0800 +Subject: rcu: handle quiescent states for PREEMPT_RCU=n, PREEMPT_COUNT=y + +From: Ankur Arora + +[ Upstream commit 83b28cfe796464ebbde1cf7916c126da6d572685 ] + +With PREEMPT_RCU=n, cond_resched() provides urgently needed quiescent +states for read-side critical sections via rcu_all_qs(). +One reason why this was needed: lacking preempt-count, the tick +handler has no way of knowing whether it is executing in a +read-side critical section or not. + +With (PREEMPT_LAZY=y, PREEMPT_DYNAMIC=n), we get (PREEMPT_COUNT=y, +PREEMPT_RCU=n). In this configuration cond_resched() is a stub and +does not provide quiescent states via rcu_all_qs(). +(PREEMPT_RCU=y provides this information via rcu_read_unlock() and +its nesting counter.) + +So, use the availability of preempt_count() to report quiescent states +in rcu_flavor_sched_clock_irq(). + +Suggested-by: Paul E. McKenney +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: Ankur Arora +Reviewed-by: Frederic Weisbecker +Signed-off-by: Paul E. McKenney +Signed-off-by: Boqun Feng +Signed-off-by: Sasha Levin +--- + kernel/rcu/tree_plugin.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h +index 41021080ad258..dccfc46496393 100644 +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -963,13 +963,16 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp) + */ + static void rcu_flavor_sched_clock_irq(int user) + { +- if (user || rcu_is_cpu_rrupt_from_idle()) { ++ if (user || rcu_is_cpu_rrupt_from_idle() || ++ (IS_ENABLED(CONFIG_PREEMPT_COUNT) && ++ (preempt_count() == HARDIRQ_OFFSET))) { + + /* + * Get here if this CPU took its interrupt from user +- * mode or from the idle loop, and if this is not a +- * nested interrupt. In this case, the CPU is in +- * a quiescent state, so note it. ++ * mode, from the idle loop without this being a nested ++ * interrupt, or while not holding the task preempt count ++ * (with PREEMPT_COUNT=y). In this case, the CPU is in a ++ * quiescent state, so note it. + * + * No memory barrier is required here because rcu_qs() + * references only CPU-local variables that other CPUs +-- +2.39.5 + diff --git a/queue-6.6/rcu-handle-unstable-rdp-in-rcu_read_unlock_strict.patch b/queue-6.6/rcu-handle-unstable-rdp-in-rcu_read_unlock_strict.patch new file mode 100644 index 0000000000..74ab8fe074 --- /dev/null +++ b/queue-6.6/rcu-handle-unstable-rdp-in-rcu_read_unlock_strict.patch @@ -0,0 +1,68 @@ +From 8f760dc3ea56e29de86215a87d3e7bfc1fe65af5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Dec 2024 20:06:55 -0800 +Subject: rcu: handle unstable rdp in rcu_read_unlock_strict() + +From: Ankur Arora + +[ Upstream commit fcf0e25ad4c8d14d2faab4d9a17040f31efce205 ] + +rcu_read_unlock_strict() can be called with preemption enabled +which can make for an unstable rdp and a racy norm value. + +Fix this by dropping the preempt-count in __rcu_read_unlock() +after the call to rcu_read_unlock_strict(), adjusting the +preempt-count check appropriately. + +Suggested-by: Frederic Weisbecker +Signed-off-by: Ankur Arora +Reviewed-by: Frederic Weisbecker +Signed-off-by: Paul E. McKenney +Signed-off-by: Boqun Feng +Signed-off-by: Sasha Levin +--- + include/linux/rcupdate.h | 2 +- + kernel/rcu/tree_plugin.h | 11 ++++++++++- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h +index 72da69cc5764f..27531a0b3a6e7 100644 +--- a/include/linux/rcupdate.h ++++ b/include/linux/rcupdate.h +@@ -97,9 +97,9 @@ static inline void __rcu_read_lock(void) + + static inline void __rcu_read_unlock(void) + { +- preempt_enable(); + if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD)) + rcu_read_unlock_strict(); ++ preempt_enable(); + } + + static inline int rcu_preempt_depth(void) +diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h +index dccfc46496393..94b715139f52d 100644 +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -821,8 +821,17 @@ void rcu_read_unlock_strict(void) + { + struct rcu_data *rdp; + +- if (irqs_disabled() || preempt_count() || !rcu_state.gp_kthread) ++ if (irqs_disabled() || in_atomic_preempt_off() || !rcu_state.gp_kthread) + return; ++ ++ /* ++ * rcu_report_qs_rdp() can only be invoked with a stable rdp and ++ * from the local CPU. ++ * ++ * The in_atomic_preempt_off() check ensures that we come here holding ++ * the last preempt_count (which will get dropped once we return to ++ * __rcu_read_unlock(). ++ */ + rdp = this_cpu_ptr(&rcu_data); + rdp->cpu_no_qs.b.norm = false; + rcu_report_qs_rdp(rdp); +-- +2.39.5 + diff --git a/queue-6.6/rdma-core-fix-best-page-size-finding-when-it-can-cro.patch b/queue-6.6/rdma-core-fix-best-page-size-finding-when-it-can-cro.patch new file mode 100644 index 0000000000..53f2735447 --- /dev/null +++ b/queue-6.6/rdma-core-fix-best-page-size-finding-when-it-can-cro.patch @@ -0,0 +1,139 @@ +From ca187b57315d89032527a51b64ef0bc41f2ed36b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 14:16:23 +0000 +Subject: RDMA/core: Fix best page size finding when it can cross SG entries + +From: Michael Margolin + +[ Upstream commit 486055f5e09df959ad4e3aa4ee75b5c91ddeec2e ] + +A single scatter-gather entry is limited by a 32 bits "length" field +that is practically 4GB - PAGE_SIZE. This means that even when the +memory is physically contiguous, we might need more than one entry to +represent it. Additionally when using dmabuf, the sg_table might be +originated outside the subsystem and optimized for other needs. + +For instance an SGT of 16GB GPU continuous memory might look like this: +(a real life example) + +dma_address 34401400000, length fffff000 +dma_address 345013ff000, length fffff000 +dma_address 346013fe000, length fffff000 +dma_address 347013fd000, length fffff000 +dma_address 348013fc000, length 4000 + +Since ib_umem_find_best_pgsz works within SG entries, in the above case +we will result with the worst possible 4KB page size. + +Fix this by taking into consideration only the alignment of addresses of +real discontinuity points rather than treating SG entries as such, and +adjust the page iterator to correctly handle cross SG entry pages. + +There is currently an assumption that drivers do not ask for pages +bigger than maximal DMA size supported by their devices. + +Reviewed-by: Firas Jahjah +Reviewed-by: Yonatan Nachum +Signed-off-by: Michael Margolin +Link: https://patch.msgid.link/20250217141623.12428-1-mrgolin@amazon.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/umem.c | 36 ++++++++++++++++++++++++--------- + drivers/infiniband/core/verbs.c | 11 +++++----- + 2 files changed, 32 insertions(+), 15 deletions(-) + +diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c +index 07c571c7b6999..c5b6863947605 100644 +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -80,9 +80,12 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, + unsigned long pgsz_bitmap, + unsigned long virt) + { +- struct scatterlist *sg; ++ unsigned long curr_len = 0; ++ dma_addr_t curr_base = ~0; + unsigned long va, pgoff; ++ struct scatterlist *sg; + dma_addr_t mask; ++ dma_addr_t end; + int i; + + umem->iova = va = virt; +@@ -107,17 +110,30 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, + pgoff = umem->address & ~PAGE_MASK; + + for_each_sgtable_dma_sg(&umem->sgt_append.sgt, sg, i) { +- /* Walk SGL and reduce max page size if VA/PA bits differ +- * for any address. ++ /* If the current entry is physically contiguous with the previous ++ * one, no need to take its start addresses into consideration. + */ +- mask |= (sg_dma_address(sg) + pgoff) ^ va; ++ if (check_add_overflow(curr_base, curr_len, &end) || ++ end != sg_dma_address(sg)) { ++ ++ curr_base = sg_dma_address(sg); ++ curr_len = 0; ++ ++ /* Reduce max page size if VA/PA bits differ */ ++ mask |= (curr_base + pgoff) ^ va; ++ ++ /* The alignment of any VA matching a discontinuity point ++ * in the physical memory sets the maximum possible page ++ * size as this must be a starting point of a new page that ++ * needs to be aligned. ++ */ ++ if (i != 0) ++ mask |= va; ++ } ++ ++ curr_len += sg_dma_len(sg); + va += sg_dma_len(sg) - pgoff; +- /* Except for the last entry, the ending iova alignment sets +- * the maximum possible page size as the low bits of the iova +- * must be zero when starting the next chunk. +- */ +- if (i != (umem->sgt_append.sgt.nents - 1)) +- mask |= va; ++ + pgoff = 0; + } + +diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c +index ba05de0380e96..6567d43751280 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -3029,22 +3029,23 @@ EXPORT_SYMBOL(__rdma_block_iter_start); + bool __rdma_block_iter_next(struct ib_block_iter *biter) + { + unsigned int block_offset; +- unsigned int sg_delta; ++ unsigned int delta; + + if (!biter->__sg_nents || !biter->__sg) + return false; + + biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance; + block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1); +- sg_delta = BIT_ULL(biter->__pg_bit) - block_offset; ++ delta = BIT_ULL(biter->__pg_bit) - block_offset; + +- if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) { +- biter->__sg_advance += sg_delta; +- } else { ++ while (biter->__sg_nents && biter->__sg && ++ sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) { ++ delta -= sg_dma_len(biter->__sg) - biter->__sg_advance; + biter->__sg_advance = 0; + biter->__sg = sg_next(biter->__sg); + biter->__sg_nents--; + } ++ biter->__sg_advance += delta; + + return true; + } +-- +2.39.5 + diff --git a/queue-6.6/rdma-uverbs-propagate-errors-from-rdma_lookup_get_uo.patch b/queue-6.6/rdma-uverbs-propagate-errors-from-rdma_lookup_get_uo.patch new file mode 100644 index 0000000000..a47ac54896 --- /dev/null +++ b/queue-6.6/rdma-uverbs-propagate-errors-from-rdma_lookup_get_uo.patch @@ -0,0 +1,432 @@ +From e5ad7a449642fa12a30fea2a15790d7961515479 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 15:54:13 +0200 +Subject: RDMA/uverbs: Propagate errors from rdma_lookup_get_uobject() + +From: Maher Sanalla + +[ Upstream commit 81f8f7454ad9e0bf95efdec6542afdc9a6ab1e24 ] + +Currently, the IB uverbs API calls uobj_get_uobj_read(), which in turn +uses the rdma_lookup_get_uobject() helper to retrieve user objects. +In case of failure, uobj_get_uobj_read() returns NULL, overriding the +error code from rdma_lookup_get_uobject(). The IB uverbs API then +translates this NULL to -EINVAL, masking the actual error and +complicating debugging. For example, applications calling ibv_modify_qp +that fails with EBUSY when retrieving the QP uobject will see the +overridden error code EINVAL instead, masking the actual error. + +Furthermore, based on rdma-core commit: +"2a22f1ced5f3 ("Merge pull request #1568 from jakemoroni/master")" +Kernel's IB uverbs return values are either ignored and passed on as is +to application or overridden with other errnos in a few cases. + +Thus, to improve error reporting and debuggability, propagate the +original error from rdma_lookup_get_uobject() instead of replacing it +with EINVAL. + +Signed-off-by: Maher Sanalla +Link: https://patch.msgid.link/64f9d3711b183984e939962c2f83383904f97dfb.1740577869.git.leon@kernel.org +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/core/uverbs_cmd.c | 144 ++++++++++++++------------- + include/rdma/uverbs_std_types.h | 2 +- + 2 files changed, 77 insertions(+), 69 deletions(-) + +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index c6053e82ecf6f..33e2fe0facd52 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -718,8 +718,8 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs) + goto err_free; + + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs); +- if (!pd) { +- ret = -EINVAL; ++ if (IS_ERR(pd)) { ++ ret = PTR_ERR(pd); + goto err_free; + } + +@@ -809,8 +809,8 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) + if (cmd.flags & IB_MR_REREG_PD) { + new_pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, + attrs); +- if (!new_pd) { +- ret = -EINVAL; ++ if (IS_ERR(new_pd)) { ++ ret = PTR_ERR(new_pd); + goto put_uobjs; + } + } else { +@@ -919,8 +919,8 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs) + return PTR_ERR(uobj); + + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs); +- if (!pd) { +- ret = -EINVAL; ++ if (IS_ERR(pd)) { ++ ret = PTR_ERR(pd); + goto err_free; + } + +@@ -1127,8 +1127,8 @@ static int ib_uverbs_resize_cq(struct uverbs_attr_bundle *attrs) + return ret; + + cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs); +- if (!cq) +- return -EINVAL; ++ if (IS_ERR(cq)) ++ return PTR_ERR(cq); + + ret = cq->device->ops.resize_cq(cq, cmd.cqe, &attrs->driver_udata); + if (ret) +@@ -1189,8 +1189,8 @@ static int ib_uverbs_poll_cq(struct uverbs_attr_bundle *attrs) + return ret; + + cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs); +- if (!cq) +- return -EINVAL; ++ if (IS_ERR(cq)) ++ return PTR_ERR(cq); + + /* we copy a struct ib_uverbs_poll_cq_resp to user space */ + header_ptr = attrs->ucore.outbuf; +@@ -1238,8 +1238,8 @@ static int ib_uverbs_req_notify_cq(struct uverbs_attr_bundle *attrs) + return ret; + + cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs); +- if (!cq) +- return -EINVAL; ++ if (IS_ERR(cq)) ++ return PTR_ERR(cq); + + ib_req_notify_cq(cq, cmd.solicited_only ? + IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); +@@ -1321,8 +1321,8 @@ static int create_qp(struct uverbs_attr_bundle *attrs, + ind_tbl = uobj_get_obj_read(rwq_ind_table, + UVERBS_OBJECT_RWQ_IND_TBL, + cmd->rwq_ind_tbl_handle, attrs); +- if (!ind_tbl) { +- ret = -EINVAL; ++ if (IS_ERR(ind_tbl)) { ++ ret = PTR_ERR(ind_tbl); + goto err_put; + } + +@@ -1360,8 +1360,10 @@ static int create_qp(struct uverbs_attr_bundle *attrs, + if (cmd->is_srq) { + srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, + cmd->srq_handle, attrs); +- if (!srq || srq->srq_type == IB_SRQT_XRC) { +- ret = -EINVAL; ++ if (IS_ERR(srq) || ++ srq->srq_type == IB_SRQT_XRC) { ++ ret = IS_ERR(srq) ? PTR_ERR(srq) : ++ -EINVAL; + goto err_put; + } + } +@@ -1371,23 +1373,29 @@ static int create_qp(struct uverbs_attr_bundle *attrs, + rcq = uobj_get_obj_read( + cq, UVERBS_OBJECT_CQ, + cmd->recv_cq_handle, attrs); +- if (!rcq) { +- ret = -EINVAL; ++ if (IS_ERR(rcq)) { ++ ret = PTR_ERR(rcq); + goto err_put; + } + } + } + } + +- if (has_sq) ++ if (has_sq) { + scq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, + cmd->send_cq_handle, attrs); ++ if (IS_ERR(scq)) { ++ ret = PTR_ERR(scq); ++ goto err_put; ++ } ++ } ++ + if (!ind_tbl && cmd->qp_type != IB_QPT_XRC_INI) + rcq = rcq ?: scq; + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd->pd_handle, + attrs); +- if (!pd || (!scq && has_sq)) { +- ret = -EINVAL; ++ if (IS_ERR(pd)) { ++ ret = PTR_ERR(pd); + goto err_put; + } + +@@ -1482,18 +1490,18 @@ static int create_qp(struct uverbs_attr_bundle *attrs, + err_put: + if (!IS_ERR(xrcd_uobj)) + uobj_put_read(xrcd_uobj); +- if (pd) ++ if (!IS_ERR_OR_NULL(pd)) + uobj_put_obj_read(pd); +- if (scq) ++ if (!IS_ERR_OR_NULL(scq)) + rdma_lookup_put_uobject(&scq->uobject->uevent.uobject, + UVERBS_LOOKUP_READ); +- if (rcq && rcq != scq) ++ if (!IS_ERR_OR_NULL(rcq) && rcq != scq) + rdma_lookup_put_uobject(&rcq->uobject->uevent.uobject, + UVERBS_LOOKUP_READ); +- if (srq) ++ if (!IS_ERR_OR_NULL(srq)) + rdma_lookup_put_uobject(&srq->uobject->uevent.uobject, + UVERBS_LOOKUP_READ); +- if (ind_tbl) ++ if (!IS_ERR_OR_NULL(ind_tbl)) + uobj_put_obj_read(ind_tbl); + + uobj_alloc_abort(&obj->uevent.uobject, attrs); +@@ -1655,8 +1663,8 @@ static int ib_uverbs_query_qp(struct uverbs_attr_bundle *attrs) + } + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) { +- ret = -EINVAL; ++ if (IS_ERR(qp)) { ++ ret = PTR_ERR(qp); + goto out; + } + +@@ -1761,8 +1769,8 @@ static int modify_qp(struct uverbs_attr_bundle *attrs, + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd->base.qp_handle, + attrs); +- if (!qp) { +- ret = -EINVAL; ++ if (IS_ERR(qp)) { ++ ret = PTR_ERR(qp); + goto out; + } + +@@ -2027,8 +2035,8 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs) + return -ENOMEM; + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) { +- ret = -EINVAL; ++ if (IS_ERR(qp)) { ++ ret = PTR_ERR(qp); + goto out; + } + +@@ -2065,9 +2073,9 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs) + + ud->ah = uobj_get_obj_read(ah, UVERBS_OBJECT_AH, + user_wr->wr.ud.ah, attrs); +- if (!ud->ah) { ++ if (IS_ERR(ud->ah)) { ++ ret = PTR_ERR(ud->ah); + kfree(ud); +- ret = -EINVAL; + goto out_put; + } + ud->remote_qpn = user_wr->wr.ud.remote_qpn; +@@ -2304,8 +2312,8 @@ static int ib_uverbs_post_recv(struct uverbs_attr_bundle *attrs) + return PTR_ERR(wr); + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) { +- ret = -EINVAL; ++ if (IS_ERR(qp)) { ++ ret = PTR_ERR(qp); + goto out; + } + +@@ -2355,8 +2363,8 @@ static int ib_uverbs_post_srq_recv(struct uverbs_attr_bundle *attrs) + return PTR_ERR(wr); + + srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs); +- if (!srq) { +- ret = -EINVAL; ++ if (IS_ERR(srq)) { ++ ret = PTR_ERR(srq); + goto out; + } + +@@ -2412,8 +2420,8 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs) + } + + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs); +- if (!pd) { +- ret = -EINVAL; ++ if (IS_ERR(pd)) { ++ ret = PTR_ERR(pd); + goto err; + } + +@@ -2482,8 +2490,8 @@ static int ib_uverbs_attach_mcast(struct uverbs_attr_bundle *attrs) + return ret; + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) +- return -EINVAL; ++ if (IS_ERR(qp)) ++ return PTR_ERR(qp); + + obj = qp->uobject; + +@@ -2532,8 +2540,8 @@ static int ib_uverbs_detach_mcast(struct uverbs_attr_bundle *attrs) + return ret; + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) +- return -EINVAL; ++ if (IS_ERR(qp)) ++ return PTR_ERR(qp); + + obj = qp->uobject; + mutex_lock(&obj->mcast_lock); +@@ -2667,8 +2675,8 @@ static int kern_spec_to_ib_spec_action(struct uverbs_attr_bundle *attrs, + UVERBS_OBJECT_FLOW_ACTION, + kern_spec->action.handle, + attrs); +- if (!ib_spec->action.act) +- return -EINVAL; ++ if (IS_ERR(ib_spec->action.act)) ++ return PTR_ERR(ib_spec->action.act); + ib_spec->action.size = + sizeof(struct ib_flow_spec_action_handle); + flow_resources_add(uflow_res, +@@ -2685,8 +2693,8 @@ static int kern_spec_to_ib_spec_action(struct uverbs_attr_bundle *attrs, + UVERBS_OBJECT_COUNTERS, + kern_spec->flow_count.handle, + attrs); +- if (!ib_spec->flow_count.counters) +- return -EINVAL; ++ if (IS_ERR(ib_spec->flow_count.counters)) ++ return PTR_ERR(ib_spec->flow_count.counters); + ib_spec->flow_count.size = + sizeof(struct ib_flow_spec_action_count); + flow_resources_add(uflow_res, +@@ -2904,14 +2912,14 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs) + return PTR_ERR(obj); + + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs); +- if (!pd) { +- err = -EINVAL; ++ if (IS_ERR(pd)) { ++ err = PTR_ERR(pd); + goto err_uobj; + } + + cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs); +- if (!cq) { +- err = -EINVAL; ++ if (IS_ERR(cq)) { ++ err = PTR_ERR(cq); + goto err_put_pd; + } + +@@ -3012,8 +3020,8 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs) + return -EINVAL; + + wq = uobj_get_obj_read(wq, UVERBS_OBJECT_WQ, cmd.wq_handle, attrs); +- if (!wq) +- return -EINVAL; ++ if (IS_ERR(wq)) ++ return PTR_ERR(wq); + + if (cmd.attr_mask & IB_WQ_FLAGS) { + wq_attr.flags = cmd.flags; +@@ -3096,8 +3104,8 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs) + num_read_wqs++) { + wq = uobj_get_obj_read(wq, UVERBS_OBJECT_WQ, + wqs_handles[num_read_wqs], attrs); +- if (!wq) { +- err = -EINVAL; ++ if (IS_ERR(wq)) { ++ err = PTR_ERR(wq); + goto put_wqs; + } + +@@ -3252,8 +3260,8 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs) + } + + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); +- if (!qp) { +- err = -EINVAL; ++ if (IS_ERR(qp)) { ++ err = PTR_ERR(qp); + goto err_uobj; + } + +@@ -3399,15 +3407,15 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, + if (ib_srq_has_cq(cmd->srq_type)) { + attr.ext.cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, + cmd->cq_handle, attrs); +- if (!attr.ext.cq) { +- ret = -EINVAL; ++ if (IS_ERR(attr.ext.cq)) { ++ ret = PTR_ERR(attr.ext.cq); + goto err_put_xrcd; + } + } + + pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd->pd_handle, attrs); +- if (!pd) { +- ret = -EINVAL; ++ if (IS_ERR(pd)) { ++ ret = PTR_ERR(pd); + goto err_put_cq; + } + +@@ -3514,8 +3522,8 @@ static int ib_uverbs_modify_srq(struct uverbs_attr_bundle *attrs) + return ret; + + srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs); +- if (!srq) +- return -EINVAL; ++ if (IS_ERR(srq)) ++ return PTR_ERR(srq); + + attr.max_wr = cmd.max_wr; + attr.srq_limit = cmd.srq_limit; +@@ -3542,8 +3550,8 @@ static int ib_uverbs_query_srq(struct uverbs_attr_bundle *attrs) + return ret; + + srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs); +- if (!srq) +- return -EINVAL; ++ if (IS_ERR(srq)) ++ return PTR_ERR(srq); + + ret = ib_query_srq(srq, &attr); + +@@ -3668,8 +3676,8 @@ static int ib_uverbs_ex_modify_cq(struct uverbs_attr_bundle *attrs) + return -EOPNOTSUPP; + + cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs); +- if (!cq) +- return -EINVAL; ++ if (IS_ERR(cq)) ++ return PTR_ERR(cq); + + ret = rdma_set_cq_moderation(cq, cmd.attr.cq_count, cmd.attr.cq_period); + +diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h +index fe05121169589..555ea3d142a46 100644 +--- a/include/rdma/uverbs_std_types.h ++++ b/include/rdma/uverbs_std_types.h +@@ -34,7 +34,7 @@ + static inline void *_uobj_get_obj_read(struct ib_uobject *uobj) + { + if (IS_ERR(uobj)) +- return NULL; ++ return ERR_CAST(uobj); + return uobj->object; + } + #define uobj_get_obj_read(_object, _type, _id, _attrs) \ +-- +2.39.5 + diff --git a/queue-6.6/regulator-ad5398-add-device-tree-support.patch b/queue-6.6/regulator-ad5398-add-device-tree-support.patch new file mode 100644 index 0000000000..3f299ac116 --- /dev/null +++ b/queue-6.6/regulator-ad5398-add-device-tree-support.patch @@ -0,0 +1,63 @@ +From e51cf862a3e7727d051b929ba46a29f77eda514b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 17:31:43 +0000 +Subject: regulator: ad5398: Add device tree support + +From: Isaac Scott + +[ Upstream commit 5a6a461079decea452fdcae955bccecf92e07e97 ] + +Previously, the ad5398 driver used only platform_data, which is +deprecated in favour of device tree. This caused the AD5398 to fail to +probe as it could not load its init_data. If the AD5398 has a device +tree node, pull the init_data from there using +of_get_regulator_init_data. + +Signed-off-by: Isaac Scott +Acked-by: Michael Hennerich +Link: https://patch.msgid.link/20250128173143.959600-4-isaac.scott@ideasonboard.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/ad5398.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c +index 40f7dba42b5ad..404cbe32711e7 100644 +--- a/drivers/regulator/ad5398.c ++++ b/drivers/regulator/ad5398.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #define AD5398_CURRENT_EN_MASK 0x8000 + +@@ -221,15 +222,20 @@ static int ad5398_probe(struct i2c_client *client) + const struct ad5398_current_data_format *df = + (struct ad5398_current_data_format *)id->driver_data; + +- if (!init_data) +- return -EINVAL; +- + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + config.dev = &client->dev; ++ if (client->dev.of_node) ++ init_data = of_get_regulator_init_data(&client->dev, ++ client->dev.of_node, ++ &ad5398_reg); ++ if (!init_data) ++ return -EINVAL; ++ + config.init_data = init_data; ++ config.of_node = client->dev.of_node; + config.driver_data = chip; + + chip->client = client; +-- +2.39.5 + diff --git a/queue-6.6/remoteproc-qcom_wcnss-handle-platforms-with-only-sin.patch b/queue-6.6/remoteproc-qcom_wcnss-handle-platforms-with-only-sin.patch new file mode 100644 index 0000000000..5a4238486e --- /dev/null +++ b/queue-6.6/remoteproc-qcom_wcnss-handle-platforms-with-only-sin.patch @@ -0,0 +1,113 @@ +From 3322f112f31808eec9448329f639cc0371dd7898 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 20:56:48 +0100 +Subject: remoteproc: qcom_wcnss: Handle platforms with only single power + domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Matti Lehtimäki + +[ Upstream commit 65991ea8a6d1e68effdc01d95ebe39f1653f7b71 ] + +Both MSM8974 and MSM8226 have only CX as power domain with MX & PX being +handled as regulators. Handle this case by reodering pd_names to have CX +first, and handling that the driver core will already attach a single +power domain internally. + +Signed-off-by: Matti Lehtimäki +[luca: minor changes] +Signed-off-by: Luca Weiss +Link: https://lore.kernel.org/r/20250206-wcnss-singlepd-v2-2-9a53ee953dee@lucaweiss.eu +[bjorn: Added missing braces to else after multi-statement if] +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_wcnss.c | 33 ++++++++++++++++++++++++++------- + 1 file changed, 26 insertions(+), 7 deletions(-) + +diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c +index 90de22c81da97..153260b4e2eb4 100644 +--- a/drivers/remoteproc/qcom_wcnss.c ++++ b/drivers/remoteproc/qcom_wcnss.c +@@ -117,10 +117,10 @@ static const struct wcnss_data pronto_v1_data = { + .pmu_offset = 0x1004, + .spare_offset = 0x1088, + +- .pd_names = { "mx", "cx" }, ++ .pd_names = { "cx", "mx" }, + .vregs = (struct wcnss_vreg_info[]) { +- { "vddmx", 950000, 1150000, 0 }, + { "vddcx", .super_turbo = true}, ++ { "vddmx", 950000, 1150000, 0 }, + { "vddpx", 1800000, 1800000, 0 }, + }, + .num_pd_vregs = 2, +@@ -131,10 +131,10 @@ static const struct wcnss_data pronto_v2_data = { + .pmu_offset = 0x1004, + .spare_offset = 0x1088, + +- .pd_names = { "mx", "cx" }, ++ .pd_names = { "cx", "mx" }, + .vregs = (struct wcnss_vreg_info[]) { +- { "vddmx", 1287500, 1287500, 0 }, + { "vddcx", .super_turbo = true }, ++ { "vddmx", 1287500, 1287500, 0 }, + { "vddpx", 1800000, 1800000, 0 }, + }, + .num_pd_vregs = 2, +@@ -397,8 +397,17 @@ static irqreturn_t wcnss_stop_ack_interrupt(int irq, void *dev) + static int wcnss_init_pds(struct qcom_wcnss *wcnss, + const char * const pd_names[WCNSS_MAX_PDS]) + { ++ struct device *dev = wcnss->dev; + int i, ret; + ++ /* Handle single power domain */ ++ if (dev->pm_domain) { ++ wcnss->pds[0] = dev; ++ wcnss->num_pds = 1; ++ pm_runtime_enable(dev); ++ return 0; ++ } ++ + for (i = 0; i < WCNSS_MAX_PDS; i++) { + if (!pd_names[i]) + break; +@@ -418,8 +427,15 @@ static int wcnss_init_pds(struct qcom_wcnss *wcnss, + + static void wcnss_release_pds(struct qcom_wcnss *wcnss) + { ++ struct device *dev = wcnss->dev; + int i; + ++ /* Handle single power domain */ ++ if (wcnss->num_pds == 1 && dev->pm_domain) { ++ pm_runtime_disable(dev); ++ return; ++ } ++ + for (i = 0; i < wcnss->num_pds; i++) + dev_pm_domain_detach(wcnss->pds[i], false); + } +@@ -437,10 +453,13 @@ static int wcnss_init_regulators(struct qcom_wcnss *wcnss, + * the regulators for the power domains. For old device trees we need to + * reserve extra space to manage them through the regulator interface. + */ +- if (wcnss->num_pds) +- info += num_pd_vregs; +- else ++ if (wcnss->num_pds) { ++ info += wcnss->num_pds; ++ /* Handle single power domain case */ ++ num_vregs += num_pd_vregs - wcnss->num_pds; ++ } else { + num_vregs += num_pd_vregs; ++ } + + bulk = devm_kcalloc(wcnss->dev, + num_vregs, sizeof(struct regulator_bulk_data), +-- +2.39.5 + diff --git a/queue-6.6/riscv-allow-nommu-kernels-to-access-all-of-ram.patch b/queue-6.6/riscv-allow-nommu-kernels-to-access-all-of-ram.patch new file mode 100644 index 0000000000..6d2a9138a4 --- /dev/null +++ b/queue-6.6/riscv-allow-nommu-kernels-to-access-all-of-ram.patch @@ -0,0 +1,80 @@ +From 5e3e73dcb6cb1399dfd9fef6a19dce4e0c1c4c7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Oct 2024 10:13:54 -0700 +Subject: riscv: Allow NOMMU kernels to access all of RAM + +From: Samuel Holland + +[ Upstream commit 2c0391b29b27f315c1b4c29ffde66f50b29fab99 ] + +NOMMU kernels currently cannot access memory below the kernel link +address. Remove this restriction by setting PAGE_OFFSET to the actual +start of RAM, as determined from the devicetree. The kernel link address +must be a constant, so keep using CONFIG_PAGE_OFFSET for that purpose. + +Signed-off-by: Samuel Holland +Reviewed-by: Jesse Taube +Link: https://lore.kernel.org/r/20241026171441.3047904-3-samuel.holland@sifive.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/page.h | 12 ++++-------- + arch/riscv/include/asm/pgtable.h | 2 +- + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h +index 4d1f58848129e..dbb9d0d0f405e 100644 +--- a/arch/riscv/include/asm/page.h ++++ b/arch/riscv/include/asm/page.h +@@ -26,12 +26,9 @@ + * When not using MMU this corresponds to the first free page in + * physical memory (aligned on a page boundary). + */ +-#ifdef CONFIG_64BIT + #ifdef CONFIG_MMU ++#ifdef CONFIG_64BIT + #define PAGE_OFFSET kernel_map.page_offset +-#else +-#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) +-#endif + /* + * By default, CONFIG_PAGE_OFFSET value corresponds to SV57 address space so + * define the PAGE_OFFSET value for SV48 and SV39. +@@ -41,6 +38,9 @@ + #else + #define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) + #endif /* CONFIG_64BIT */ ++#else ++#define PAGE_OFFSET ((unsigned long)phys_ram_base) ++#endif /* CONFIG_MMU */ + + #ifndef __ASSEMBLY__ + +@@ -97,11 +97,7 @@ typedef struct page *pgtable_t; + #define MIN_MEMBLOCK_ADDR 0 + #endif + +-#ifdef CONFIG_MMU + #define ARCH_PFN_OFFSET (PFN_DOWN((unsigned long)phys_ram_base)) +-#else +-#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) +-#endif /* CONFIG_MMU */ + + struct kernel_mapping { + unsigned long page_offset; +diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h +index f540b2625714d..332a6bf72b1d5 100644 +--- a/arch/riscv/include/asm/pgtable.h ++++ b/arch/riscv/include/asm/pgtable.h +@@ -12,7 +12,7 @@ + #include + + #ifndef CONFIG_MMU +-#define KERNEL_LINK_ADDR PAGE_OFFSET ++#define KERNEL_LINK_ADDR _AC(CONFIG_PAGE_OFFSET, UL) + #define KERN_VIRT_SIZE (UL(-1)) + #else + +-- +2.39.5 + diff --git a/queue-6.6/rtc-ds1307-stop-disabling-alarms-on-probe.patch b/queue-6.6/rtc-ds1307-stop-disabling-alarms-on-probe.patch new file mode 100644 index 0000000000..12dd11f0b4 --- /dev/null +++ b/queue-6.6/rtc-ds1307-stop-disabling-alarms-on-probe.patch @@ -0,0 +1,38 @@ +From e45f6588e7e731be49298ea5a5e8fc5d150f507f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Mar 2025 23:37:44 +0100 +Subject: rtc: ds1307: stop disabling alarms on probe + +From: Alexandre Belloni + +[ Upstream commit dcec12617ee61beed928e889607bf37e145bf86b ] + +It is a bad practice to disable alarms on probe or remove as this will +prevent alarms across reboots. + +Link: https://lore.kernel.org/r/20250303223744.1135672-1-alexandre.belloni@bootlin.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/rtc-ds1307.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c +index 506b7d1c23970..0c78451960926 100644 +--- a/drivers/rtc/rtc-ds1307.c ++++ b/drivers/rtc/rtc-ds1307.c +@@ -1802,10 +1802,8 @@ static int ds1307_probe(struct i2c_client *client) + * For some variants, be sure alarms can trigger when we're + * running on Vbackup (BBSQI/BBSQW) + */ +- if (want_irq || ds1307_can_wakeup_device) { ++ if (want_irq || ds1307_can_wakeup_device) + regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit; +- regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); +- } + + regmap_write(ds1307->regmap, DS1337_REG_CONTROL, + regs[0]); +-- +2.39.5 + diff --git a/queue-6.6/rtc-rv3032-fix-eerd-location.patch b/queue-6.6/rtc-rv3032-fix-eerd-location.patch new file mode 100644 index 0000000000..f37cd2b0ae --- /dev/null +++ b/queue-6.6/rtc-rv3032-fix-eerd-location.patch @@ -0,0 +1,34 @@ +From c12743f95241a688e6add83a462d1d6a36d7b082 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Mar 2025 22:42:41 +0100 +Subject: rtc: rv3032: fix EERD location + +From: Alexandre Belloni + +[ Upstream commit b0f9cb4a0706b0356e84d67e48500b77b343debe ] + +EERD is bit 2 in CTRL1 + +Link: https://lore.kernel.org/r/20250306214243.1167692-1-alexandre.belloni@bootlin.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/rtc-rv3032.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c +index 35b2e36b426a0..cb01038a2e27f 100644 +--- a/drivers/rtc/rtc-rv3032.c ++++ b/drivers/rtc/rtc-rv3032.c +@@ -69,7 +69,7 @@ + #define RV3032_CLKOUT2_FD_MSK GENMASK(6, 5) + #define RV3032_CLKOUT2_OS BIT(7) + +-#define RV3032_CTRL1_EERD BIT(3) ++#define RV3032_CTRL1_EERD BIT(2) + #define RV3032_CTRL1_WADA BIT(5) + + #define RV3032_CTRL2_STOP BIT(0) +-- +2.39.5 + diff --git a/queue-6.6/s390-vfio-ap-fix-no-ap-queue-sharing-allowed-message.patch b/queue-6.6/s390-vfio-ap-fix-no-ap-queue-sharing-allowed-message.patch new file mode 100644 index 0000000000..eb2554ac44 --- /dev/null +++ b/queue-6.6/s390-vfio-ap-fix-no-ap-queue-sharing-allowed-message.patch @@ -0,0 +1,192 @@ +From f83a53964bac02e28c01fba04f324cee27b23ec4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 06:32:57 -0400 +Subject: s390/vfio-ap: Fix no AP queue sharing allowed message written to + kernel log + +From: Anthony Krowiak + +[ Upstream commit d33d729afcc8ad2148d99f9bc499b33fd0c0d73b ] + +An erroneous message is written to the kernel log when either of the +following actions are taken by a user: + +1. Assign an adapter or domain to a vfio_ap mediated device via its sysfs + assign_adapter or assign_domain attributes that would result in one or + more AP queues being assigned that are already assigned to a different + mediated device. Sharing of queues between mdevs is not allowed. + +2. Reserve an adapter or domain for the host device driver via the AP bus + driver's sysfs apmask or aqmask attribute that would result in providing + host access to an AP queue that is in use by a vfio_ap mediated device. + Reserving a queue for a host driver that is in use by an mdev is not + allowed. + +In both cases, the assignment will return an error; however, a message like +the following is written to the kernel log: + +vfio_ap_mdev e1839397-51a0-4e3c-91e0-c3b9c3d3047d: Userspace may not +re-assign queue 00.0028 already assigned to \ +e1839397-51a0-4e3c-91e0-c3b9c3d3047d + +Notice the mdev reporting the error is the same as the mdev identified +in the message as the one to which the queue is being assigned. +It is perfectly okay to assign a queue to an mdev to which it is +already assigned; the assignment is simply ignored by the vfio_ap device +driver. + +This patch logs more descriptive and accurate messages for both 1 and 2 +above to the kernel log: + +Example for 1: +vfio_ap_mdev 0fe903a0-a323-44db-9daf-134c68627d61: Userspace may not assign +queue 00.0033 to mdev: already assigned to \ +62177883-f1bb-47f0-914d-32a22e3a8804 + +Example for 2: +vfio_ap_mdev 62177883-f1bb-47f0-914d-32a22e3a8804: Can not reserve queue +00.0033 for host driver: in use by mdev + +Signed-off-by: Anthony Krowiak +Link: https://lore.kernel.org/r/20250311103304.1539188-1-akrowiak@linux.ibm.com +Signed-off-by: Heiko Carstens +Signed-off-by: Vasily Gorbik +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/vfio_ap_ops.c | 72 ++++++++++++++++++++----------- + 1 file changed, 46 insertions(+), 26 deletions(-) + +diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c +index d6ea2fd4c2a02..d4151f519e8b2 100644 +--- a/drivers/s390/crypto/vfio_ap_ops.c ++++ b/drivers/s390/crypto/vfio_ap_ops.c +@@ -834,48 +834,66 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev) + vfio_put_device(&matrix_mdev->vdev); + } + +-#define MDEV_SHARING_ERR "Userspace may not re-assign queue %02lx.%04lx " \ +- "already assigned to %s" ++#define MDEV_SHARING_ERR "Userspace may not assign queue %02lx.%04lx to mdev: already assigned to %s" + +-static void vfio_ap_mdev_log_sharing_err(struct ap_matrix_mdev *matrix_mdev, +- unsigned long *apm, +- unsigned long *aqm) ++#define MDEV_IN_USE_ERR "Can not reserve queue %02lx.%04lx for host driver: in use by mdev" ++ ++static void vfio_ap_mdev_log_sharing_err(struct ap_matrix_mdev *assignee, ++ struct ap_matrix_mdev *assigned_to, ++ unsigned long *apm, unsigned long *aqm) + { + unsigned long apid, apqi; +- const struct device *dev = mdev_dev(matrix_mdev->mdev); +- const char *mdev_name = dev_name(dev); + +- for_each_set_bit_inv(apid, apm, AP_DEVICES) ++ for_each_set_bit_inv(apid, apm, AP_DEVICES) { ++ for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) { ++ dev_warn(mdev_dev(assignee->mdev), MDEV_SHARING_ERR, ++ apid, apqi, dev_name(mdev_dev(assigned_to->mdev))); ++ } ++ } ++} ++ ++static void vfio_ap_mdev_log_in_use_err(struct ap_matrix_mdev *assignee, ++ unsigned long *apm, unsigned long *aqm) ++{ ++ unsigned long apid, apqi; ++ ++ for_each_set_bit_inv(apid, apm, AP_DEVICES) { + for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) +- dev_warn(dev, MDEV_SHARING_ERR, apid, apqi, mdev_name); ++ dev_warn(mdev_dev(assignee->mdev), MDEV_IN_USE_ERR, apid, apqi); ++ } + } + + /** + * vfio_ap_mdev_verify_no_sharing - verify APQNs are not shared by matrix mdevs + * ++ * @assignee: the matrix mdev to which @mdev_apm and @mdev_aqm are being ++ * assigned; or, NULL if this function was called by the AP bus ++ * driver in_use callback to verify none of the APQNs being reserved ++ * for the host device driver are in use by a vfio_ap mediated device + * @mdev_apm: mask indicating the APIDs of the APQNs to be verified + * @mdev_aqm: mask indicating the APQIs of the APQNs to be verified + * +- * Verifies that each APQN derived from the Cartesian product of a bitmap of +- * AP adapter IDs and AP queue indexes is not configured for any matrix +- * mediated device. AP queue sharing is not allowed. ++ * Verifies that each APQN derived from the Cartesian product of APIDs ++ * represented by the bits set in @mdev_apm and the APQIs of the bits set in ++ * @mdev_aqm is not assigned to a mediated device other than the mdev to which ++ * the APQN is being assigned (@assignee). AP queue sharing is not allowed. + * + * Return: 0 if the APQNs are not shared; otherwise return -EADDRINUSE. + */ +-static int vfio_ap_mdev_verify_no_sharing(unsigned long *mdev_apm, ++static int vfio_ap_mdev_verify_no_sharing(struct ap_matrix_mdev *assignee, ++ unsigned long *mdev_apm, + unsigned long *mdev_aqm) + { +- struct ap_matrix_mdev *matrix_mdev; ++ struct ap_matrix_mdev *assigned_to; + DECLARE_BITMAP(apm, AP_DEVICES); + DECLARE_BITMAP(aqm, AP_DOMAINS); + +- list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) { ++ list_for_each_entry(assigned_to, &matrix_dev->mdev_list, node) { + /* +- * If the input apm and aqm are fields of the matrix_mdev +- * object, then move on to the next matrix_mdev. ++ * If the mdev to which the mdev_apm and mdev_aqm is being ++ * assigned is the same as the mdev being verified + */ +- if (mdev_apm == matrix_mdev->matrix.apm && +- mdev_aqm == matrix_mdev->matrix.aqm) ++ if (assignee == assigned_to) + continue; + + memset(apm, 0, sizeof(apm)); +@@ -885,15 +903,16 @@ static int vfio_ap_mdev_verify_no_sharing(unsigned long *mdev_apm, + * We work on full longs, as we can only exclude the leftover + * bits in non-inverse order. The leftover is all zeros. + */ +- if (!bitmap_and(apm, mdev_apm, matrix_mdev->matrix.apm, +- AP_DEVICES)) ++ if (!bitmap_and(apm, mdev_apm, assigned_to->matrix.apm, AP_DEVICES)) + continue; + +- if (!bitmap_and(aqm, mdev_aqm, matrix_mdev->matrix.aqm, +- AP_DOMAINS)) ++ if (!bitmap_and(aqm, mdev_aqm, assigned_to->matrix.aqm, AP_DOMAINS)) + continue; + +- vfio_ap_mdev_log_sharing_err(matrix_mdev, apm, aqm); ++ if (assignee) ++ vfio_ap_mdev_log_sharing_err(assignee, assigned_to, apm, aqm); ++ else ++ vfio_ap_mdev_log_in_use_err(assigned_to, apm, aqm); + + return -EADDRINUSE; + } +@@ -922,7 +941,8 @@ static int vfio_ap_mdev_validate_masks(struct ap_matrix_mdev *matrix_mdev) + matrix_mdev->matrix.aqm)) + return -EADDRNOTAVAIL; + +- return vfio_ap_mdev_verify_no_sharing(matrix_mdev->matrix.apm, ++ return vfio_ap_mdev_verify_no_sharing(matrix_mdev, ++ matrix_mdev->matrix.apm, + matrix_mdev->matrix.aqm); + } + +@@ -2271,7 +2291,7 @@ int vfio_ap_mdev_resource_in_use(unsigned long *apm, unsigned long *aqm) + + mutex_lock(&matrix_dev->guests_lock); + mutex_lock(&matrix_dev->mdevs_lock); +- ret = vfio_ap_mdev_verify_no_sharing(apm, aqm); ++ ret = vfio_ap_mdev_verify_no_sharing(NULL, apm, aqm); + mutex_unlock(&matrix_dev->mdevs_lock); + mutex_unlock(&matrix_dev->guests_lock); + +-- +2.39.5 + diff --git a/queue-6.6/samples-bpf-fix-compilation-failure-for-samples-bpf-.patch b/queue-6.6/samples-bpf-fix-compilation-failure-for-samples-bpf-.patch new file mode 100644 index 0000000000..4214c96ff1 --- /dev/null +++ b/queue-6.6/samples-bpf-fix-compilation-failure-for-samples-bpf-.patch @@ -0,0 +1,59 @@ +From 2c6a6ba1933c7fdd028eb7ee8939a8979a452c1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Apr 2025 17:50:42 +0800 +Subject: samples/bpf: Fix compilation failure for samples/bpf on LoongArch + Fedora + +From: Haoran Jiang + +[ Upstream commit 548762f05d19c5542db7590bcdfb9be1fb928376 ] + +When building the latest samples/bpf on LoongArch Fedora + + make M=samples/bpf + +There are compilation errors as follows: + +In file included from ./linux/samples/bpf/sockex2_kern.c:2: +In file included from ./include/uapi/linux/in.h:25: +In file included from ./include/linux/socket.h:8: +In file included from ./include/linux/uio.h:9: +In file included from ./include/linux/thread_info.h:60: +In file included from ./arch/loongarch/include/asm/thread_info.h:15: +In file included from ./arch/loongarch/include/asm/processor.h:13: +In file included from ./arch/loongarch/include/asm/cpu-info.h:11: +./arch/loongarch/include/asm/loongarch.h:13:10: fatal error: 'larchintrin.h' file not found + ^~~~~~~~~~~~~~~ +1 error generated. + +larchintrin.h is included in /usr/lib64/clang/14.0.6/include, +and the header file location is specified at compile time. + +Test on LoongArch Fedora: +https://github.com/fedora-remix-loongarch/releases-info + +Signed-off-by: Haoran Jiang +Signed-off-by: zhangxi +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20250425095042.838824-1-jianghaoran@kylinos.cn +Signed-off-by: Sasha Levin +--- + samples/bpf/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile +index 3fa16412db15c..927d72659173e 100644 +--- a/samples/bpf/Makefile ++++ b/samples/bpf/Makefile +@@ -392,7 +392,7 @@ $(obj)/%.o: $(src)/%.c + @echo " CLANG-bpf " $@ + $(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(BPF_EXTRA_CFLAGS) \ + -I$(obj) -I$(srctree)/tools/testing/selftests/bpf/ \ +- -I$(LIBBPF_INCLUDE) \ ++ -I$(LIBBPF_INCLUDE) $(CLANG_SYS_INCLUDES) \ + -D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \ + -D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \ + -Wno-gnu-variable-sized-type-not-at-end \ +-- +2.39.5 + diff --git a/queue-6.6/sched-reduce-the-default-slice-to-avoid-tasks-gettin.patch b/queue-6.6/sched-reduce-the-default-slice-to-avoid-tasks-gettin.patch new file mode 100644 index 0000000000..9c2ed745cc --- /dev/null +++ b/queue-6.6/sched-reduce-the-default-slice-to-avoid-tasks-gettin.patch @@ -0,0 +1,80 @@ +From ef2360bffb3cfff6409281e746657b516b2b6153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Feb 2025 15:53:23 +0800 +Subject: sched: Reduce the default slice to avoid tasks getting an extra tick + +From: zihan zhou <15645113830zzh@gmail.com> + +[ Upstream commit 2ae891b826958b60919ea21c727f77bcd6ffcc2c ] + +The old default value for slice is 0.75 msec * (1 + ilog(ncpus)) which +means that we have a default slice of: + + 0.75 for 1 cpu + 1.50 up to 3 cpus + 2.25 up to 7 cpus + 3.00 for 8 cpus and above. + +For HZ=250 and HZ=100, because of the tick accuracy, the runtime of +tasks is far higher than their slice. + +For HZ=1000 with 8 cpus or more, the accuracy of tick is already +satisfactory, but there is still an issue that tasks will get an extra +tick because the tick often arrives a little faster than expected. In +this case, the task can only wait until the next tick to consider that it +has reached its deadline, and will run 1ms longer. + +vruntime + sysctl_sched_base_slice = deadline + |-----------|-----------|-----------|-----------| + 1ms 1ms 1ms 1ms + ^ ^ ^ ^ + tick1 tick2 tick3 tick4(nearly 4ms) + +There are two reasons for tick error: clockevent precision and the +CONFIG_IRQ_TIME_ACCOUNTING/CONFIG_PARAVIRT_TIME_ACCOUNTING. with +CONFIG_IRQ_TIME_ACCOUNTING every tick will be less than 1ms, but even +without it, because of clockevent precision, tick still often less than +1ms. + +In order to make scheduling more precise, we changed 0.75 to 0.70, +Using 0.70 instead of 0.75 should not change much for other configs +and would fix this issue: + + 0.70 for 1 cpu + 1.40 up to 3 cpus + 2.10 up to 7 cpus + 2.8 for 8 cpus and above. + +This does not guarantee that tasks can run the slice time accurately +every time, but occasionally running an extra tick has little impact. + +Signed-off-by: zihan zhou <15645113830zzh@gmail.com> +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Vincent Guittot +Link: https://lkml.kernel.org/r/20250208075322.13139-1-15645113830zzh@gmail.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 268e2a49b964e..6ce3028e6e852 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -73,10 +73,10 @@ unsigned int sysctl_sched_tunable_scaling = SCHED_TUNABLESCALING_LOG; + /* + * Minimal preemption granularity for CPU-bound tasks: + * +- * (default: 0.75 msec * (1 + ilog(ncpus)), units: nanoseconds) ++ * (default: 0.70 msec * (1 + ilog(ncpus)), units: nanoseconds) + */ +-unsigned int sysctl_sched_base_slice = 750000ULL; +-static unsigned int normalized_sysctl_sched_base_slice = 750000ULL; ++unsigned int sysctl_sched_base_slice = 700000ULL; ++static unsigned int normalized_sysctl_sched_base_slice = 700000ULL; + + /* + * After fork, child runs first. If set to 0 (default) then +-- +2.39.5 + diff --git a/queue-6.6/scsi-lpfc-free-phba-irq-in-lpfc_sli4_enable_msi-when.patch b/queue-6.6/scsi-lpfc-free-phba-irq-in-lpfc_sli4_enable_msi-when.patch new file mode 100644 index 0000000000..e71c2507d7 --- /dev/null +++ b/queue-6.6/scsi-lpfc-free-phba-irq-in-lpfc_sli4_enable_msi-when.patch @@ -0,0 +1,47 @@ +From 05b1c838454230ad8cea7fe3a695211f747ae67e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2025 16:05:20 -0800 +Subject: scsi: lpfc: Free phba irq in lpfc_sli4_enable_msi() when + pci_irq_vector() fails + +From: Justin Tee + +[ Upstream commit f0842902b383982d1f72c490996aa8fc29a7aa0d ] + +Fix smatch warning regarding missed calls to free_irq(). Free the phba IRQ +in the failed pci_irq_vector cases. + +lpfc_init.c: lpfc_sli4_enable_msi() warn: 'phba->pcidev->irq' from + request_irq() not released. + +Signed-off-by: Justin Tee +Link: https://lore.kernel.org/r/20250131000524.163662-3-justintee8345@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_init.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c +index 424b39a8155cb..7c8e0e1d36da9 100644 +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -13180,6 +13180,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) + eqhdl = lpfc_get_eq_hdl(0); + rc = pci_irq_vector(phba->pcidev, 0); + if (rc < 0) { ++ free_irq(phba->pcidev->irq, phba); + pci_free_irq_vectors(phba->pcidev); + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, + "0496 MSI pci_irq_vec failed (%d)\n", rc); +@@ -13260,6 +13261,7 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) + eqhdl = lpfc_get_eq_hdl(0); + retval = pci_irq_vector(phba->pcidev, 0); + if (retval < 0) { ++ free_irq(phba->pcidev->irq, phba); + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, + "0502 INTR pci_irq_vec failed (%d)\n", + retval); +-- +2.39.5 + diff --git a/queue-6.6/scsi-lpfc-handle-duplicate-d_ids-in-ndlp-search-by-d.patch b/queue-6.6/scsi-lpfc-handle-duplicate-d_ids-in-ndlp-search-by-d.patch new file mode 100644 index 0000000000..166b1ab63f --- /dev/null +++ b/queue-6.6/scsi-lpfc-handle-duplicate-d_ids-in-ndlp-search-by-d.patch @@ -0,0 +1,66 @@ +From 4555a4d6bb1b9981de820c30d6f27e43c59b2420 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jan 2025 16:05:22 -0800 +Subject: scsi: lpfc: Handle duplicate D_IDs in ndlp search-by D_ID routine + +From: Justin Tee + +[ Upstream commit 56c3d809b7b450379162d0b8a70bbe71ab8db706 ] + +After a port swap between separate fabrics, there may be multiple nodes in +the vport's fc_nodes list with the same fabric well known address. +Duplication is temporary and eventually resolves itself after dev_loss_tmo +expires, but nameserver queries may still occur before dev_loss_tmo. This +possibly results in returning stale fabric ndlp objects. Fix by adding an +nlp_state check to ensure the ndlp search routine returns the correct newer +allocated ndlp fabric object. + +Signed-off-by: Justin Tee +Link: https://lore.kernel.org/r/20250131000524.163662-5-justintee8345@gmail.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_hbadisc.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c +index 0ad8a10002ce3..5c9bc8af3c2df 100644 +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -5646,6 +5646,7 @@ static struct lpfc_nodelist * + __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) + { + struct lpfc_nodelist *ndlp; ++ struct lpfc_nodelist *np = NULL; + uint32_t data1; + + list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { +@@ -5660,14 +5661,20 @@ __lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1, ndlp->nlp_rpi, + ndlp->active_rrqs_xri_bitmap); +- return ndlp; ++ ++ /* Check for new or potentially stale node */ ++ if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) ++ return ndlp; ++ np = ndlp; + } + } + +- /* FIND node did NOT FOUND */ +- lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, +- "0932 FIND node did x%x NOT FOUND.\n", did); +- return NULL; ++ if (!np) ++ /* FIND node did NOT FOUND */ ++ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, ++ "0932 FIND node did x%x NOT FOUND.\n", did); ++ ++ return np; + } + + struct lpfc_nodelist * +-- +2.39.5 + diff --git a/queue-6.6/scsi-mpi3mr-add-level-check-to-control-event-logging.patch b/queue-6.6/scsi-mpi3mr-add-level-check-to-control-event-logging.patch new file mode 100644 index 0000000000..48882566a4 --- /dev/null +++ b/queue-6.6/scsi-mpi3mr-add-level-check-to-control-event-logging.patch @@ -0,0 +1,37 @@ +From 74bdddfb8a557995d4d0af661cd0f8c33322b3fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Apr 2025 15:45:46 +0530 +Subject: scsi: mpi3mr: Add level check to control event logging + +From: Ranjan Kumar + +[ Upstream commit b0b7ee3b574a72283399b9232f6190be07f220c0 ] + +Ensure event logs are only generated when the debug logging level +MPI3_DEBUG_EVENT is enabled. This prevents unnecessary logging. + +Signed-off-by: Ranjan Kumar +Link: https://lore.kernel.org/r/20250415101546.204018-1-ranjan.kumar@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_fw.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c +index 0d148c39ebcc9..60714a6c26375 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c +@@ -174,6 +174,9 @@ static void mpi3mr_print_event_data(struct mpi3mr_ioc *mrioc, + char *desc = NULL; + u16 event; + ++ if (!(mrioc->logging_level & MPI3_DEBUG_EVENT)) ++ return; ++ + event = event_reply->event; + + switch (event) { +-- +2.39.5 + diff --git a/queue-6.6/scsi-mpt3sas-send-a-diag-reset-if-target-reset-fails.patch b/queue-6.6/scsi-mpt3sas-send-a-diag-reset-if-target-reset-fails.patch new file mode 100644 index 0000000000..e18526d9da --- /dev/null +++ b/queue-6.6/scsi-mpt3sas-send-a-diag-reset-if-target-reset-fails.patch @@ -0,0 +1,64 @@ +From ec93ed3e4b541eb497142fa8d23aa66c15df994a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 17:26:55 -0800 +Subject: scsi: mpt3sas: Send a diag reset if target reset fails + +From: Shivasharan S + +[ Upstream commit 5612d6d51ed2634a033c95de2edec7449409cbb9 ] + +When an IOCTL times out and driver issues a target reset, if firmware +fails the task management elevate the recovery by issuing a diag reset to +controller. + +Signed-off-by: Shivasharan S +Link: https://lore.kernel.org/r/1739410016-27503-5-git-send-email-shivasharan.srikanteshwara@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index e289f18fc7643..daef90ee431f5 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -679,6 +679,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + size_t data_in_sz = 0; + long ret; + u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE; ++ int tm_ret; + + issue_reset = 0; + +@@ -1120,18 +1121,25 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + if (pcie_device && (!ioc->tm_custom_handling) && + (!(mpt3sas_scsih_is_pcie_scsi_device( + pcie_device->device_info)))) +- mpt3sas_scsih_issue_locked_tm(ioc, ++ tm_ret = mpt3sas_scsih_issue_locked_tm(ioc, + le16_to_cpu(mpi_request->FunctionDependent1), + 0, 0, 0, + MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, + 0, pcie_device->reset_timeout, + MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE); + else +- mpt3sas_scsih_issue_locked_tm(ioc, ++ tm_ret = mpt3sas_scsih_issue_locked_tm(ioc, + le16_to_cpu(mpi_request->FunctionDependent1), + 0, 0, 0, + MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, + 0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET); ++ ++ if (tm_ret != SUCCESS) { ++ ioc_info(ioc, ++ "target reset failed, issue hard reset: handle (0x%04x)\n", ++ le16_to_cpu(mpi_request->FunctionDependent1)); ++ mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); ++ } + } else + mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); + } +-- +2.39.5 + diff --git a/queue-6.6/scsi-st-erase-does-not-change-tape-location.patch b/queue-6.6/scsi-st-erase-does-not-change-tape-location.patch new file mode 100644 index 0000000000..bc29c79540 --- /dev/null +++ b/queue-6.6/scsi-st-erase-does-not-change-tape-location.patch @@ -0,0 +1,38 @@ +From 2a0492842a50316f924656a0245f49fb264ba8f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 13:25:15 +0200 +Subject: scsi: st: ERASE does not change tape location +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai Mäkisara + +[ Upstream commit ad77cebf97bd42c93ab4e3bffd09f2b905c1959a ] + +The SCSI ERASE command erases from the current position onwards. Don't +clear the position variables. + +Signed-off-by: Kai Mäkisara +Link: https://lore.kernel.org/r/20250311112516.5548-3-Kai.Makisara@kolumbus.fi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/st.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index 293074f30906f..fb193caa4a3fa 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -2895,7 +2895,6 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon + timeout = STp->long_timeout * 8; + + DEBC_printk(STp, "Erasing tape.\n"); +- fileno = blkno = at_sm = 0; + break; + case MTSETBLK: /* Set block length */ + case MTSETDENSITY: /* Set tape density */ +-- +2.39.5 + diff --git a/queue-6.6/scsi-st-restore-some-drive-settings-after-reset.patch b/queue-6.6/scsi-st-restore-some-drive-settings-after-reset.patch new file mode 100644 index 0000000000..5cfd395aae --- /dev/null +++ b/queue-6.6/scsi-st-restore-some-drive-settings-after-reset.patch @@ -0,0 +1,113 @@ +From d6e01a069a0e586428375504df922c53fc657451 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Jan 2025 21:49:22 +0200 +Subject: scsi: st: Restore some drive settings after reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai Mäkisara + +[ Upstream commit 7081dc75df79696d8322d01821c28e53416c932c ] + +Some of the allowed operations put the tape into a known position to +continue operation assuming only the tape position has changed. But reset +sets partition, density and block size to drive default values. These +should be restored to the values before reset. + +Normally the current block size and density are stored by the drive. If +the settings have been changed, the changed values have to be saved by the +driver across reset. + +Signed-off-by: Kai Mäkisara +Link: https://lore.kernel.org/r/20250120194925.44432-2-Kai.Makisara@kolumbus.fi +Reviewed-by: John Meneghini +Tested-by: John Meneghini +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/st.c | 24 +++++++++++++++++++++--- + drivers/scsi/st.h | 2 ++ + 2 files changed, 23 insertions(+), 3 deletions(-) + +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index fb193caa4a3fa..f9ab45c4bb40d 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -953,7 +953,6 @@ static void reset_state(struct scsi_tape *STp) + STp->partition = find_partition(STp); + if (STp->partition < 0) + STp->partition = 0; +- STp->new_partition = STp->partition; + } + } + +@@ -2927,14 +2926,17 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon + if (cmd_in == MTSETDENSITY) { + (STp->buffer)->b_data[4] = arg; + STp->density_changed = 1; /* At least we tried ;-) */ ++ STp->changed_density = arg; + } else if (cmd_in == SET_DENS_AND_BLK) + (STp->buffer)->b_data[4] = arg >> 24; + else + (STp->buffer)->b_data[4] = STp->density; + if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) { + ltmp = arg & MT_ST_BLKSIZE_MASK; +- if (cmd_in == MTSETBLK) ++ if (cmd_in == MTSETBLK) { + STp->blksize_changed = 1; /* At least we tried ;-) */ ++ STp->changed_blksize = arg; ++ } + } else + ltmp = STp->block_size; + (STp->buffer)->b_data[9] = (ltmp >> 16); +@@ -3635,9 +3637,25 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) + retval = (-EIO); + goto out; + } +- reset_state(STp); ++ reset_state(STp); /* Clears pos_unknown */ + /* remove this when the midlevel properly clears was_reset */ + STp->device->was_reset = 0; ++ ++ /* Fix the device settings after reset, ignore errors */ ++ if (mtc.mt_op == MTREW || mtc.mt_op == MTSEEK || ++ mtc.mt_op == MTEOM) { ++ if (STp->can_partitions) { ++ /* STp->new_partition contains the ++ * latest partition set ++ */ ++ STp->partition = 0; ++ switch_partition(STp); ++ } ++ if (STp->density_changed) ++ st_int_ioctl(STp, MTSETDENSITY, STp->changed_density); ++ if (STp->blksize_changed) ++ st_int_ioctl(STp, MTSETBLK, STp->changed_blksize); ++ } + } + + if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK && +diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h +index 1aaaf5369a40f..6d31b894ee84c 100644 +--- a/drivers/scsi/st.h ++++ b/drivers/scsi/st.h +@@ -165,6 +165,7 @@ struct scsi_tape { + unsigned char compression_changed; + unsigned char drv_buffer; + unsigned char density; ++ unsigned char changed_density; + unsigned char door_locked; + unsigned char autorew_dev; /* auto-rewind device */ + unsigned char rew_at_close; /* rewind necessary at close */ +@@ -172,6 +173,7 @@ struct scsi_tape { + unsigned char cleaning_req; /* cleaning requested? */ + unsigned char first_tur; /* first TEST UNIT READY */ + int block_size; ++ int changed_blksize; + int min_block; + int max_block; + int recover_count; /* From tape opening */ +-- +2.39.5 + diff --git a/queue-6.6/scsi-st-tighten-the-page-format-heuristics-with-mode.patch b/queue-6.6/scsi-st-tighten-the-page-format-heuristics-with-mode.patch new file mode 100644 index 0000000000..af9d01a300 --- /dev/null +++ b/queue-6.6/scsi-st-tighten-the-page-format-heuristics-with-mode.patch @@ -0,0 +1,47 @@ +From 8f4ffb84b8271266d827997b20564c4d856a8f97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 13:25:16 +0200 +Subject: scsi: st: Tighten the page format heuristics with MODE SELECT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kai Mäkisara + +[ Upstream commit 8db816c6f176321e42254badd5c1a8df8bfcfdb4 ] + +In the days when SCSI-2 was emerging, some drives did claim SCSI-2 but did +not correctly implement it. The st driver first tries MODE SELECT with the +page format bit set to set the block descriptor. If not successful, the +non-page format is tried. + +The test only tests the sense code and this triggers also from illegal +parameter in the parameter list. The test is limited to "old" devices and +made more strict to remove false alarms. + +Signed-off-by: Kai Mäkisara +Link: https://lore.kernel.org/r/20250311112516.5548-4-Kai.Makisara@kolumbus.fi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/st.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index 900322bad4f3b..293074f30906f 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -3082,7 +3082,9 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon + cmd_in == MTSETDRVBUFFER || + cmd_in == SET_DENS_AND_BLK) { + if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST && +- !(STp->use_pf & PF_TESTED)) { ++ cmdstatp->sense_hdr.asc == 0x24 && ++ (STp->device)->scsi_level <= SCSI_2 && ++ !(STp->use_pf & PF_TESTED)) { + /* Try the other possible state of Page Format if not + already tried */ + STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED; +-- +2.39.5 + diff --git a/queue-6.6/scsi-target-iscsi-fix-timeout-on-deleted-connection.patch b/queue-6.6/scsi-target-iscsi-fix-timeout-on-deleted-connection.patch new file mode 100644 index 0000000000..73e6fab7bb --- /dev/null +++ b/queue-6.6/scsi-target-iscsi-fix-timeout-on-deleted-connection.patch @@ -0,0 +1,57 @@ +From 26e2eda4cfaa05e566e4967490e7f1e1de13ed7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Dec 2024 13:17:57 +0300 +Subject: scsi: target: iscsi: Fix timeout on deleted connection + +From: Dmitry Bogdanov + +[ Upstream commit 7f533cc5ee4c4436cee51dc58e81dfd9c3384418 ] + +NOPIN response timer may expire on a deleted connection and crash with +such logs: + +Did not receive response to NOPIN on CID: 0, failing connection for I_T Nexus (null),i,0x00023d000125,iqn.2017-01.com.iscsi.target,t,0x3d + +BUG: Kernel NULL pointer dereference on read at 0x00000000 +NIP strlcpy+0x8/0xb0 +LR iscsit_fill_cxn_timeout_err_stats+0x5c/0xc0 [iscsi_target_mod] +Call Trace: + iscsit_handle_nopin_response_timeout+0xfc/0x120 [iscsi_target_mod] + call_timer_fn+0x58/0x1f0 + run_timer_softirq+0x740/0x860 + __do_softirq+0x16c/0x420 + irq_exit+0x188/0x1c0 + timer_interrupt+0x184/0x410 + +That is because nopin response timer may be re-started on nopin timer +expiration. + +Stop nopin timer before stopping the nopin response timer to be sure +that no one of them will be re-started. + +Signed-off-by: Dmitry Bogdanov +Link: https://lore.kernel.org/r/20241224101757.32300-1-d.bogdanov@yadro.com +Reviewed-by: Maurizio Lombardi +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/iscsi/iscsi_target.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index b516c2893420b..b756d4cfecfe9 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4323,8 +4323,8 @@ int iscsit_close_connection( + spin_unlock(&iscsit_global->ts_bitmap_lock); + + iscsit_stop_timers_for_cmds(conn); +- iscsit_stop_nopin_response_timer(conn); + iscsit_stop_nopin_timer(conn); ++ iscsit_stop_nopin_response_timer(conn); + + if (conn->conn_transport->iscsit_wait_conn) + conn->conn_transport->iscsit_wait_conn(conn); +-- +2.39.5 + diff --git a/queue-6.6/scsi-target-spc-fix-loop-traversal-in-spc_rsoc_get_d.patch b/queue-6.6/scsi-target-spc-fix-loop-traversal-in-spc_rsoc_get_d.patch new file mode 100644 index 0000000000..a2cbfe4924 --- /dev/null +++ b/queue-6.6/scsi-target-spc-fix-loop-traversal-in-spc_rsoc_get_d.patch @@ -0,0 +1,68 @@ +From 0e14c58abe23553091cf9b045a2a0931ff40d2d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 16:55:42 +0800 +Subject: scsi: target: spc: Fix loop traversal in spc_rsoc_get_descr() + +From: Chaohai Chen + +[ Upstream commit 04ad06e41d1c74cc323b20a7bd023c47bd0e0c38 ] + +Stop traversing after finding the appropriate descriptor. + +Signed-off-by: Chaohai Chen +Link: https://lore.kernel.org/r/20250124085542.109088-1-wdhh66@163.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_spc.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c +index f110f932ba054..675f774be1d30 100644 +--- a/drivers/target/target_core_spc.c ++++ b/drivers/target/target_core_spc.c +@@ -2151,8 +2151,10 @@ spc_rsoc_get_descr(struct se_cmd *cmd, struct target_opcode_descriptor **opcode) + if (descr->serv_action_valid) + return TCM_INVALID_CDB_FIELD; + +- if (!descr->enabled || descr->enabled(descr, cmd)) ++ if (!descr->enabled || descr->enabled(descr, cmd)) { + *opcode = descr; ++ return TCM_NO_SENSE; ++ } + break; + case 0x2: + /* +@@ -2166,8 +2168,10 @@ spc_rsoc_get_descr(struct se_cmd *cmd, struct target_opcode_descriptor **opcode) + if (descr->serv_action_valid && + descr->service_action == requested_sa) { + if (!descr->enabled || descr->enabled(descr, +- cmd)) ++ cmd)) { + *opcode = descr; ++ return TCM_NO_SENSE; ++ } + } else if (!descr->serv_action_valid) + return TCM_INVALID_CDB_FIELD; + break; +@@ -2180,13 +2184,15 @@ spc_rsoc_get_descr(struct se_cmd *cmd, struct target_opcode_descriptor **opcode) + */ + if (descr->service_action == requested_sa) + if (!descr->enabled || descr->enabled(descr, +- cmd)) ++ cmd)) { + *opcode = descr; ++ return TCM_NO_SENSE; ++ } + break; + } + } + +- return 0; ++ return TCM_NO_SENSE; + } + + static sense_reason_t +-- +2.39.5 + diff --git a/queue-6.6/scsi-ufs-introduce-quirk-to-extend-pa_hibern8time-fo.patch b/queue-6.6/scsi-ufs-introduce-quirk-to-extend-pa_hibern8time-fo.patch new file mode 100644 index 0000000000..9de5222b84 --- /dev/null +++ b/queue-6.6/scsi-ufs-introduce-quirk-to-extend-pa_hibern8time-fo.patch @@ -0,0 +1,101 @@ +From cb96bf9d1b25970fff5977533d26d79325d01d30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Apr 2025 17:46:30 +0530 +Subject: scsi: ufs: Introduce quirk to extend PA_HIBERN8TIME for UFS devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Manish Pandey + +[ Upstream commit 569330a34a31a52c904239439984a59972c11d28 ] + +Samsung UFS devices require additional time in hibern8 mode before +exiting, beyond the negotiated handshaking phase between the host and +device. Introduce a quirk to increase the PA_HIBERN8TIME parameter by +100 µs, a value derived from experiments, to ensure a proper hibernation +process. + +Signed-off-by: Manish Pandey +Link: https://lore.kernel.org/r/20250411121630.21330-3-quic_mapa@quicinc.com +Reviewed-by: Bean Huo +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 29 +++++++++++++++++++++++++++++ + include/ufs/ufs_quirks.h | 6 ++++++ + 2 files changed, 35 insertions(+) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index cb5611cbf4547..2346a1fc72b56 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -257,6 +257,7 @@ static const struct ufs_dev_quirk ufs_fixups[] = { + .model = UFS_ANY_MODEL, + .quirk = UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | + UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE | ++ UFS_DEVICE_QUIRK_PA_HIBER8TIME | + UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS }, + { .wmanufacturerid = UFS_VENDOR_SKHYNIX, + .model = UFS_ANY_MODEL, +@@ -8459,6 +8460,31 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) + return ret; + } + ++/** ++ * ufshcd_quirk_override_pa_h8time - Ensures proper adjustment of PA_HIBERN8TIME. ++ * @hba: per-adapter instance ++ * ++ * Some UFS devices require specific adjustments to the PA_HIBERN8TIME parameter ++ * to ensure proper hibernation timing. This function retrieves the current ++ * PA_HIBERN8TIME value and increments it by 100us. ++ */ ++static void ufshcd_quirk_override_pa_h8time(struct ufs_hba *hba) ++{ ++ u32 pa_h8time; ++ int ret; ++ ++ ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME), &pa_h8time); ++ if (ret) { ++ dev_err(hba->dev, "Failed to get PA_HIBERN8TIME: %d\n", ret); ++ return; ++ } ++ ++ /* Increment by 1 to increase hibernation time by 100 µs */ ++ ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), pa_h8time + 1); ++ if (ret) ++ dev_err(hba->dev, "Failed updating PA_HIBERN8TIME: %d\n", ret); ++} ++ + static void ufshcd_tune_unipro_params(struct ufs_hba *hba) + { + if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { +@@ -8474,6 +8500,9 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba) + + if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE) + ufshcd_quirk_tune_host_pa_tactivate(hba); ++ ++ if (hba->dev_quirks & UFS_DEVICE_QUIRK_PA_HIBER8TIME) ++ ufshcd_quirk_override_pa_h8time(hba); + } + + static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba) +diff --git a/include/ufs/ufs_quirks.h b/include/ufs/ufs_quirks.h +index 41ff44dfa1db3..f52de5ed1b3b6 100644 +--- a/include/ufs/ufs_quirks.h ++++ b/include/ufs/ufs_quirks.h +@@ -107,4 +107,10 @@ struct ufs_dev_quirk { + */ + #define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) + ++/* ++ * Some ufs devices may need more time to be in hibern8 before exiting. ++ * Enable this quirk to give it an additional 100us. ++ */ ++#define UFS_DEVICE_QUIRK_PA_HIBER8TIME (1 << 12) ++ + #endif /* UFS_QUIRKS_H_ */ +-- +2.39.5 + diff --git a/queue-6.6/selftests-bpf-mitigate-sockmap_ktls-disconnect_after.patch b/queue-6.6/selftests-bpf-mitigate-sockmap_ktls-disconnect_after.patch new file mode 100644 index 0000000000..fe70d8eb0e --- /dev/null +++ b/queue-6.6/selftests-bpf-mitigate-sockmap_ktls-disconnect_after.patch @@ -0,0 +1,50 @@ +From 7317689d0bf0480b84b26a5418e9544e9547fe76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 10:02:46 -0700 +Subject: selftests/bpf: Mitigate sockmap_ktls disconnect_after_delete failure + +From: Ihor Solodrai + +[ Upstream commit f2858f308131a09e33afb766cd70119b5b900569 ] + +"sockmap_ktls disconnect_after_delete" test has been failing on BPF CI +after recent merges from netdev: +* https://github.com/kernel-patches/bpf/actions/runs/14458537639 +* https://github.com/kernel-patches/bpf/actions/runs/14457178732 + +It happens because disconnect has been disabled for TLS [1], and it +renders the test case invalid. + +Removing all the test code creates a conflict between bpf and +bpf-next, so for now only remove the offending assert [2]. + +The test will be removed later on bpf-next. + +[1] https://lore.kernel.org/netdev/20250404180334.3224206-1-kuba@kernel.org/ +[2] https://lore.kernel.org/bpf/cfc371285323e1a3f3b006bfcf74e6cf7ad65258@linux.dev/ + +Signed-off-by: Ihor Solodrai +Signed-off-by: Andrii Nakryiko +Reviewed-by: Jiayuan Chen +Link: https://lore.kernel.org/bpf/20250416170246.2438524-1-ihor.solodrai@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c b/tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c +index 2d0796314862a..0a99fd404f6dc 100644 +--- a/tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c ++++ b/tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c +@@ -68,7 +68,6 @@ static void test_sockmap_ktls_disconnect_after_delete(int family, int map) + goto close_cli; + + err = disconnect(cli); +- ASSERT_OK(err, "disconnect"); + + close_cli: + close(cli); +-- +2.39.5 + diff --git a/queue-6.6/selftests-net-have-gro.sh-t-return-a-correct-exit-co.patch b/queue-6.6/selftests-net-have-gro.sh-t-return-a-correct-exit-co.patch new file mode 100644 index 0000000000..959e9161cf --- /dev/null +++ b/queue-6.6/selftests-net-have-gro.sh-t-return-a-correct-exit-co.patch @@ -0,0 +1,37 @@ +From 459668e9aea4509df9e85a5caca8c85cb7961b92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 11:27:23 -0800 +Subject: selftests/net: have `gro.sh -t` return a correct exit code + +From: Kevin Krakauer + +[ Upstream commit 784e6abd99f24024a8998b5916795f0bec9d2fd9 ] + +Modify gro.sh to return a useful exit code when the -t flag is used. It +formerly returned 0 no matter what. + +Tested: Ran `gro.sh -t large` and verified that test failures return 1. +Signed-off-by: Kevin Krakauer +Reviewed-by: Willem de Bruijn +Link: https://patch.msgid.link/20250226192725.621969-2-krakauer@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/gro.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/gro.sh b/tools/testing/selftests/net/gro.sh +index 342ad27f631b1..e771f5f7faa26 100755 +--- a/tools/testing/selftests/net/gro.sh ++++ b/tools/testing/selftests/net/gro.sh +@@ -95,5 +95,6 @@ trap cleanup EXIT + if [[ "${test}" == "all" ]]; then + run_all_tests + else +- run_test "${proto}" "${test}" ++ exit_code=$(run_test "${proto}" "${test}") ++ exit $exit_code + fi; +-- +2.39.5 + diff --git a/queue-6.6/serial-mctrl_gpio-split-disable_ms-into-sync-and-no_.patch b/queue-6.6/serial-mctrl_gpio-split-disable_ms-into-sync-and-no_.patch new file mode 100644 index 0000000000..59132782fd --- /dev/null +++ b/queue-6.6/serial-mctrl_gpio-split-disable_ms-into-sync-and-no_.patch @@ -0,0 +1,247 @@ +From 2ccd56f85a7f84c4d0fff3b0f077d46716f3912a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 07:21:53 +0100 +Subject: serial: mctrl_gpio: split disable_ms into sync and no_sync APIs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexis Lothoré + +[ Upstream commit 1bd2aad57da95f7f2d2bb52f7ad15c0f4993a685 ] + +The following splat has been observed on a SAMA5D27 platform using +atmel_serial: + +BUG: sleeping function called from invalid context at kernel/irq/manage.c:738 +in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 27, name: kworker/u5:0 +preempt_count: 1, expected: 0 +INFO: lockdep is turned off. +irq event stamp: 0 +hardirqs last enabled at (0): [<00000000>] 0x0 +hardirqs last disabled at (0): [] copy_process+0x1c4c/0x7bec +softirqs last enabled at (0): [] copy_process+0x1ca0/0x7bec +softirqs last disabled at (0): [<00000000>] 0x0 +CPU: 0 UID: 0 PID: 27 Comm: kworker/u5:0 Not tainted 6.13.0-rc7+ #74 +Hardware name: Atmel SAMA5 +Workqueue: hci0 hci_power_on [bluetooth] +Call trace: + unwind_backtrace from show_stack+0x18/0x1c + show_stack from dump_stack_lvl+0x44/0x70 + dump_stack_lvl from __might_resched+0x38c/0x598 + __might_resched from disable_irq+0x1c/0x48 + disable_irq from mctrl_gpio_disable_ms+0x74/0xc0 + mctrl_gpio_disable_ms from atmel_disable_ms.part.0+0x80/0x1f4 + atmel_disable_ms.part.0 from atmel_set_termios+0x764/0x11e8 + atmel_set_termios from uart_change_line_settings+0x15c/0x994 + uart_change_line_settings from uart_set_termios+0x2b0/0x668 + uart_set_termios from tty_set_termios+0x600/0x8ec + tty_set_termios from ttyport_set_flow_control+0x188/0x1e0 + ttyport_set_flow_control from wilc_setup+0xd0/0x524 [hci_wilc] + wilc_setup [hci_wilc] from hci_dev_open_sync+0x330/0x203c [bluetooth] + hci_dev_open_sync [bluetooth] from hci_dev_do_open+0x40/0xb0 [bluetooth] + hci_dev_do_open [bluetooth] from hci_power_on+0x12c/0x664 [bluetooth] + hci_power_on [bluetooth] from process_one_work+0x998/0x1a38 + process_one_work from worker_thread+0x6e0/0xfb4 + worker_thread from kthread+0x3d4/0x484 + kthread from ret_from_fork+0x14/0x28 + +This warning is emitted when trying to toggle, at the highest level, +some flow control (with serdev_device_set_flow_control) in a device +driver. At the lowest level, the atmel_serial driver is using +serial_mctrl_gpio lib to enable/disable the corresponding IRQs +accordingly. The warning emitted by CONFIG_DEBUG_ATOMIC_SLEEP is due to +disable_irq (called in mctrl_gpio_disable_ms) being possibly called in +some atomic context (some tty drivers perform modem lines configuration +in regions protected by port lock). + +Split mctrl_gpio_disable_ms into two differents APIs, a non-blocking one +and a blocking one. Replace mctrl_gpio_disable_ms calls with the +relevant version depending on whether the call is protected by some port +lock. + +Suggested-by: Jiri Slaby +Signed-off-by: Alexis Lothoré +Acked-by: Richard Genoud +Link: https://lore.kernel.org/r/20250217-atomic_sleep_mctrl_serial_gpio-v3-1-59324b313eef@bootlin.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + Documentation/driver-api/serial/driver.rst | 2 +- + drivers/tty/serial/8250/8250_port.c | 2 +- + drivers/tty/serial/atmel_serial.c | 2 +- + drivers/tty/serial/imx.c | 2 +- + drivers/tty/serial/serial_mctrl_gpio.c | 34 +++++++++++++++++----- + drivers/tty/serial/serial_mctrl_gpio.h | 17 +++++++++-- + drivers/tty/serial/sh-sci.c | 2 +- + drivers/tty/serial/stm32-usart.c | 2 +- + 8 files changed, 47 insertions(+), 16 deletions(-) + +diff --git a/Documentation/driver-api/serial/driver.rst b/Documentation/driver-api/serial/driver.rst +index 84b43061c11be..60434f2b02863 100644 +--- a/Documentation/driver-api/serial/driver.rst ++++ b/Documentation/driver-api/serial/driver.rst +@@ -103,4 +103,4 @@ Some helpers are provided in order to set/get modem control lines via GPIO. + .. kernel-doc:: drivers/tty/serial/serial_mctrl_gpio.c + :identifiers: mctrl_gpio_init mctrl_gpio_free mctrl_gpio_to_gpiod + mctrl_gpio_set mctrl_gpio_get mctrl_gpio_enable_ms +- mctrl_gpio_disable_ms ++ mctrl_gpio_disable_ms_sync mctrl_gpio_disable_ms_no_sync +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index c2778300e1510..d5ad6cae6b652 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -1676,7 +1676,7 @@ static void serial8250_disable_ms(struct uart_port *port) + if (up->bugs & UART_BUG_NOMSR) + return; + +- mctrl_gpio_disable_ms(up->gpios); ++ mctrl_gpio_disable_ms_no_sync(up->gpios); + + up->ier &= ~UART_IER_MSI; + serial_port_out(port, UART_IER, up->ier); +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index bcca5627afaca..85559d9b35d83 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -698,7 +698,7 @@ static void atmel_disable_ms(struct uart_port *port) + + atmel_port->ms_irq_enabled = false; + +- mctrl_gpio_disable_ms(atmel_port->gpios); ++ mctrl_gpio_disable_ms_no_sync(atmel_port->gpios); + + if (!mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) + idr |= ATMEL_US_CTSIC; +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index 349d4849ba5e3..04809b781f45b 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -1597,7 +1597,7 @@ static void imx_uart_shutdown(struct uart_port *port) + imx_uart_dma_exit(sport); + } + +- mctrl_gpio_disable_ms(sport->gpios); ++ mctrl_gpio_disable_ms_sync(sport->gpios); + + spin_lock_irqsave(&sport->port.lock, flags); + ucr2 = imx_uart_readl(sport, UCR2); +diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c +index 7d5aaa8d422b1..d5fb293dd5a93 100644 +--- a/drivers/tty/serial/serial_mctrl_gpio.c ++++ b/drivers/tty/serial/serial_mctrl_gpio.c +@@ -322,11 +322,7 @@ void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios) + } + EXPORT_SYMBOL_GPL(mctrl_gpio_enable_ms); + +-/** +- * mctrl_gpio_disable_ms - disable irqs and handling of changes to the ms lines +- * @gpios: gpios to disable +- */ +-void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) ++static void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios, bool sync) + { + enum mctrl_gpio_idx i; + +@@ -342,10 +338,34 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) + if (!gpios->irq[i]) + continue; + +- disable_irq(gpios->irq[i]); ++ if (sync) ++ disable_irq(gpios->irq[i]); ++ else ++ disable_irq_nosync(gpios->irq[i]); + } + } +-EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); ++ ++/** ++ * mctrl_gpio_disable_ms_sync - disable irqs and handling of changes to the ms ++ * lines, and wait for any pending IRQ to be processed ++ * @gpios: gpios to disable ++ */ ++void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios) ++{ ++ mctrl_gpio_disable_ms(gpios, true); ++} ++EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms_sync); ++ ++/** ++ * mctrl_gpio_disable_ms_no_sync - disable irqs and handling of changes to the ++ * ms lines, and return immediately ++ * @gpios: gpios to disable ++ */ ++void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios) ++{ ++ mctrl_gpio_disable_ms(gpios, false); ++} ++EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms_no_sync); + + void mctrl_gpio_enable_irq_wake(struct mctrl_gpios *gpios) + { +diff --git a/drivers/tty/serial/serial_mctrl_gpio.h b/drivers/tty/serial/serial_mctrl_gpio.h +index fc76910fb105a..79e97838ebe56 100644 +--- a/drivers/tty/serial/serial_mctrl_gpio.h ++++ b/drivers/tty/serial/serial_mctrl_gpio.h +@@ -87,9 +87,16 @@ void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios); + void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios); + + /* +- * Disable gpio interrupts to report status line changes. ++ * Disable gpio interrupts to report status line changes, and block until ++ * any corresponding IRQ is processed + */ +-void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios); ++void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios); ++ ++/* ++ * Disable gpio interrupts to report status line changes, and return ++ * immediately ++ */ ++void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios); + + /* + * Enable gpio wakeup interrupts to enable wake up source. +@@ -148,7 +155,11 @@ static inline void mctrl_gpio_enable_ms(struct mctrl_gpios *gpios) + { + } + +-static inline void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) ++static inline void mctrl_gpio_disable_ms_sync(struct mctrl_gpios *gpios) ++{ ++} ++ ++static inline void mctrl_gpio_disable_ms_no_sync(struct mctrl_gpios *gpios) + { + } + +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index 4350a69d97d7a..2434eb6e6847d 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -2237,7 +2237,7 @@ static void sci_shutdown(struct uart_port *port) + dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + + s->autorts = false; +- mctrl_gpio_disable_ms(to_sci_port(port)->gpios); ++ mctrl_gpio_disable_ms_sync(to_sci_port(port)->gpios); + + spin_lock_irqsave(&port->lock, flags); + sci_stop_rx(port); +diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c +index 9ef90bb30a47e..b58422ae156c9 100644 +--- a/drivers/tty/serial/stm32-usart.c ++++ b/drivers/tty/serial/stm32-usart.c +@@ -952,7 +952,7 @@ static void stm32_usart_enable_ms(struct uart_port *port) + + static void stm32_usart_disable_ms(struct uart_port *port) + { +- mctrl_gpio_disable_ms(to_stm32_port(port)->gpios); ++ mctrl_gpio_disable_ms_sync(to_stm32_port(port)->gpios); + } + + /* Transmit stop */ +-- +2.39.5 + diff --git a/queue-6.6/serial-sh-sci-update-the-suspend-resume-support.patch b/queue-6.6/serial-sh-sci-update-the-suspend-resume-support.patch new file mode 100644 index 0000000000..793c396b0a --- /dev/null +++ b/queue-6.6/serial-sh-sci-update-the-suspend-resume-support.patch @@ -0,0 +1,164 @@ +From 59e52cfd1011798282ff11c77ed272a6643dbee3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:33:13 +0200 +Subject: serial: sh-sci: Update the suspend/resume support + +From: Claudiu Beznea + +[ Upstream commit 22a6984c5b5df8eab864d7f3e8b94d5a554d31ab ] + +The Renesas RZ/G3S supports a power saving mode where power to most of the +SoC components is turned off. When returning from this power saving mode, +SoC components need to be re-configured. + +The SCIFs on the Renesas RZ/G3S need to be re-configured as well when +returning from this power saving mode. The sh-sci code already configures +the SCIF clocks, power domain and registers by calling uart_resume_port() +in sci_resume(). On suspend path the SCIF UART ports are suspended +accordingly (by calling uart_suspend_port() in sci_suspend()). The only +missing setting is the reset signal. For this assert/de-assert the reset +signal on driver suspend/resume. + +In case the no_console_suspend is specified by the user, the registers need +to be saved on suspend path and restore on resume path. To do this the +sci_console_save()/sci_console_restore() functions were added. There is no +need to cache/restore the status or FIFO registers. Only the control +registers. The registers that will be saved/restored on suspend/resume are +specified by the struct sci_suspend_regs data structure. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20250207113313.545432-1-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/sh-sci.c | 71 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 69 insertions(+), 2 deletions(-) + +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index 2434eb6e6847d..9da7adc4bd9f3 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -104,6 +104,15 @@ struct plat_sci_reg { + u8 offset, size; + }; + ++struct sci_suspend_regs { ++ u16 scsmr; ++ u16 scscr; ++ u16 scfcr; ++ u16 scsptr; ++ u8 scbrr; ++ u8 semr; ++}; ++ + struct sci_port_params { + const struct plat_sci_reg regs[SCIx_NR_REGS]; + unsigned int fifosize; +@@ -134,6 +143,8 @@ struct sci_port { + struct dma_chan *chan_tx; + struct dma_chan *chan_rx; + ++ struct reset_control *rstc; ++ + #ifdef CONFIG_SERIAL_SH_SCI_DMA + struct dma_chan *chan_tx_saved; + struct dma_chan *chan_rx_saved; +@@ -153,6 +164,7 @@ struct sci_port { + int rx_trigger; + struct timer_list rx_fifo_timer; + int rx_fifo_timeout; ++ struct sci_suspend_regs suspend_regs; + u16 hscif_tot; + + bool has_rtscts; +@@ -3325,6 +3337,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, + } + + sp = &sci_ports[id]; ++ sp->rstc = rstc; + *dev_id = id; + + p->type = SCI_OF_TYPE(data); +@@ -3473,13 +3486,57 @@ static int sci_probe(struct platform_device *dev) + return 0; + } + ++static void sci_console_save(struct sci_port *s) ++{ ++ struct sci_suspend_regs *regs = &s->suspend_regs; ++ struct uart_port *port = &s->port; ++ ++ if (sci_getreg(port, SCSMR)->size) ++ regs->scsmr = sci_serial_in(port, SCSMR); ++ if (sci_getreg(port, SCSCR)->size) ++ regs->scscr = sci_serial_in(port, SCSCR); ++ if (sci_getreg(port, SCFCR)->size) ++ regs->scfcr = sci_serial_in(port, SCFCR); ++ if (sci_getreg(port, SCSPTR)->size) ++ regs->scsptr = sci_serial_in(port, SCSPTR); ++ if (sci_getreg(port, SCBRR)->size) ++ regs->scbrr = sci_serial_in(port, SCBRR); ++ if (sci_getreg(port, SEMR)->size) ++ regs->semr = sci_serial_in(port, SEMR); ++} ++ ++static void sci_console_restore(struct sci_port *s) ++{ ++ struct sci_suspend_regs *regs = &s->suspend_regs; ++ struct uart_port *port = &s->port; ++ ++ if (sci_getreg(port, SCSMR)->size) ++ sci_serial_out(port, SCSMR, regs->scsmr); ++ if (sci_getreg(port, SCSCR)->size) ++ sci_serial_out(port, SCSCR, regs->scscr); ++ if (sci_getreg(port, SCFCR)->size) ++ sci_serial_out(port, SCFCR, regs->scfcr); ++ if (sci_getreg(port, SCSPTR)->size) ++ sci_serial_out(port, SCSPTR, regs->scsptr); ++ if (sci_getreg(port, SCBRR)->size) ++ sci_serial_out(port, SCBRR, regs->scbrr); ++ if (sci_getreg(port, SEMR)->size) ++ sci_serial_out(port, SEMR, regs->semr); ++} ++ + static __maybe_unused int sci_suspend(struct device *dev) + { + struct sci_port *sport = dev_get_drvdata(dev); + +- if (sport) ++ if (sport) { + uart_suspend_port(&sci_uart_driver, &sport->port); + ++ if (!console_suspend_enabled && uart_console(&sport->port)) ++ sci_console_save(sport); ++ else ++ return reset_control_assert(sport->rstc); ++ } ++ + return 0; + } + +@@ -3487,8 +3544,18 @@ static __maybe_unused int sci_resume(struct device *dev) + { + struct sci_port *sport = dev_get_drvdata(dev); + +- if (sport) ++ if (sport) { ++ if (!console_suspend_enabled && uart_console(&sport->port)) { ++ sci_console_restore(sport); ++ } else { ++ int ret = reset_control_deassert(sport->rstc); ++ ++ if (ret) ++ return ret; ++ } ++ + uart_resume_port(&sci_uart_driver, &sport->port); ++ } + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 0000000000..238c42ed50 --- /dev/null +++ b/queue-6.6/series @@ -0,0 +1,339 @@ +gpio-pca953x-split-pca953x_restore_context-and-pca95.patch +gpio-pca953x-simplify-code-with-cleanup-helpers.patch +gpio-pca953x-fix-irq-storm-on-system-wake-up.patch +i2c-designware-uniform-initialization-flow-for-polli.patch +i2c-designware-remove-disable-callback.patch +i2c-designware-use-temporary-variable-for-struct-dev.patch +i2c-designware-fix-an-error-handling-path-in-i2c_dw_.patch +phy-renesas-rcar-gen3-usb2-add-support-to-initialize.patch +phy-renesas-rcar-gen3-usb2-move-irq-request-in-probe.patch +phy-renesas-rcar-gen3-usb2-lock-around-hardware-regi.patch +phy-renesas-rcar-gen3-usb2-assert-pll-reset-on-phy-p.patch +cpufreq-add-sm8650-to-cpufreq-dt-platdev-blocklist.patch +nvmem-rockchip-otp-move-read-offset-into-variant-dat.patch +nvmem-rockchip-otp-add-rk3576-variant-data.patch +nvmem-core-verify-cell-s-raw_len.patch +nvmem-core-update-raw_len-if-the-bit-reading-is-requ.patch +nvmem-qfprom-switch-to-4-byte-aligned-reads.patch +scsi-target-iscsi-fix-timeout-on-deleted-connection.patch +scsi-ufs-introduce-quirk-to-extend-pa_hibern8time-fo.patch +virtio_ring-fix-data-race-by-tagging-event_triggered.patch +intel_th-avoid-using-deprecated-page-mapping-index-f.patch +dma-mapping-avoid-potential-unused-data-compilation-.patch +cgroup-fix-compilation-issue-due-to-cgroup_mutex-not.patch +vhost_task-fix-vhost_task_create-documentation.patch +vhost-scsi-protect-vq-log_used-with-vq-mutex.patch +scsi-mpi3mr-add-level-check-to-control-event-logging.patch +net-enetc-refactor-bulk-flipping-of-rx-buffers-to-se.patch +ima-process_measurement-needlessly-takes-inode_lock-.patch +drm-amdgpu-allow-p2p-access-through-xgmi.patch +selftests-bpf-mitigate-sockmap_ktls-disconnect_after.patch +bpf-fix-possible-endless-loop-in-bpf-map-iteration.patch +samples-bpf-fix-compilation-failure-for-samples-bpf-.patch +kconfig-merge_config-use-an-empty-file-as-initfile.patch +s390-vfio-ap-fix-no-ap-queue-sharing-allowed-message.patch +cifs-add-fallback-for-smb2-create-without-file_read_.patch +cifs-fix-querying-and-creating-mf-symlinks-over-smb1.patch +cifs-fix-negotiate-retry-functionality.patch +smb-client-store-original-io-parameters-and-prevent-.patch +fuse-return-eperm-rather-than-enosys-from-link.patch +nfsv4-check-for-delegation-validity-in-nfs_start_del.patch +nfs-don-t-allow-waiting-for-exiting-tasks.patch +sunrpc-don-t-allow-waiting-for-exiting-tasks.patch +arm64-add-support-for-hip09-spectre-bhb-mitigation.patch +tracing-mark-binary-printing-functions-with-__printf.patch +acpi-pnp-add-intel-oc-watchdog-ids-to-non-pnp-device.patch +mailbox-pcc-use-acpi_os_ioremap-instead-of-ioremap.patch +mailbox-use-error-ret-code-of-of_parse_phandle_with_.patch +riscv-allow-nommu-kernels-to-access-all-of-ram.patch +fbdev-fsl-diu-fb-add-missing-device_remove_file.patch +fbcon-use-correct-erase-colour-for-clearing-in-fbcon.patch +fbdev-core-tileblit-implement-missing-margin-clearin.patch +cifs-add-validation-check-for-the-fields-in-smb_aces.patch +cifs-fix-establishing-netbios-session-for-smb2-conne.patch +nfsv4-treat-enetunreach-errors-as-fatal-for-state-re.patch +sunrpc-rpc_clnt_set_transport-must-not-change-the-au.patch +sunrpc-rpcbind-should-never-reset-the-port-to-the-va.patch +spi-rockchip-fix-register-out-of-bounds-access.patch +thermal-drivers-qoriq-power-down-tmu-on-system-suspe.patch +exit-fix-the-usage-of-delay_group_leader-exit_code-i.patch +dql-fix-dql-limit-value-when-reset.patch +lockdep-fix-wait-context-check-on-softirq-for-preemp.patch +objtool-properly-disable-uaccess-validation.patch +pci-dwc-ep-ensure-proper-iteration-over-outbound-map.patch +tools-build-don-t-pass-test-log-files-to-linker.patch +pnfs-flexfiles-report-enetdown-as-a-connection-error.patch +pci-vmd-disable-msi-remapping-bypass-under-xen.patch +ext4-on-a-remount-only-log-the-ro-or-r-w-state-when-.patch +libnvdimm-labels-fix-divide-error-in-nd_label_data_i.patch +mmc-host-wait-for-vdd-to-settle-on-card-power-off.patch +wifi-mt76-only-mark-tx-status-failed-frames-as-acked.patch +wifi-mt76-mt7996-revise-txs-size.patch +x86-stackprotector-64-only-export-__ref_stack_chk_gu.patch +x86-mm-check-return-value-from-memblock_phys_alloc_r.patch +i2c-qup-vote-for-interconnect-bandwidth-to-dram.patch +i2c-pxa-fix-call-balance-of-i2c-clk-handling-routine.patch +btrfs-make-btrfs_discard_workfn-block_group-ref-expl.patch +btrfs-avoid-linker-error-in-btrfs_find_create_tree_b.patch +btrfs-run-btrfs_error_commit_super-early.patch +btrfs-fix-non-empty-delayed-iputs-list-on-unmount-du.patch +btrfs-get-zone-unusable-bytes-while-holding-lock-at-.patch +btrfs-send-return-enametoolong-when-attempting-a-pat.patch +btrfs-zoned-exit-btrfs_can_activate_zone-if-btrfs_fs.patch +drm-amd-display-guard-against-setting-dispclk-low-fo.patch +i3c-master-svc-fix-missing-stop-for-master-request.patch +dlm-make-tcp-still-work-in-multi-link-env.patch +um-store-full-csgsfs-and-ss-register-from-mcontext.patch +um-update-min_low_pfn-to-match-changes-in-uml_reserv.patch +ext4-reorder-capability-check-last.patch +hypfs_create_cpu_files-add-missing-check-for-hypfs_m.patch +scsi-st-tighten-the-page-format-heuristics-with-mode.patch +scsi-st-erase-does-not-change-tape-location.patch +vfio-pci-handle-intx-irq_notconnected.patch +bpf-return-prog-btf_id-without-capable-check.patch +jbd2-do-not-try-to-recover-wiped-journal.patch +tcp-reorganize-tcp_in_ack_event-and-tcp_count_delive.patch +rtc-rv3032-fix-eerd-location.patch +objtool-fix-error-handling-inconsistencies-in-check.patch +thunderbolt-do-not-add-non-active-nvm-if-nvm-upgrade.patch +asoc-mediatek-mt6359-add-stub-for-mt6359_accdet_enab.patch +bpf-allow-pre-ordering-for-bpf-cgroup-progs.patch +kbuild-fix-argument-parsing-in-scripts-config.patch +crypto-octeontx2-suppress-auth-failure-screaming-due.patch +dm-restrict-dm-device-size-to-2-63-512-bytes.patch +net-smc-use-the-correct-ndev-to-find-pnetid-by-pneti.patch +xen-add-support-for-xenserver-6.1-platform-device.patch +pinctrl-tegra-restore-sfsel-bit-when-freeing-pins.patch +mfd-tps65219-remove-tps65219_reg_ti_dev_id-check.patch +drm-amdgpu-update-sriov-video-codec-caps.patch +asoc-sun4i-codec-support-hp-det-gpios-property.patch +f2fs-defer-readonly-check-vs-norecovery.patch +ext4-reject-the-data_err-abort-option-in-nojournal-m.patch +ext4-do-not-convert-the-unwritten-extents-if-data-wr.patch +rdma-uverbs-propagate-errors-from-rdma_lookup_get_uo.patch +posix-timers-add-cond_resched-to-posix_timer_add-sea.patch +timer_list-don-t-use-pk-through-printk.patch +netfilter-conntrack-bound-nf_conntrack-sysctl-writes.patch +arm64-mm-check-pud_type_table-in-pud_bad.patch +mmc-dw_mmc-add-exynos7870-dw-mmc-support.patch +mmc-sdhci-disable-sd-card-clock-before-changing-para.patch +usb-xhci-don-t-change-the-status-of-stalled-tds-on-f.patch +hwmon-dell-smm-increment-the-number-of-fans.patch +printk-check-con_suspend-when-unblanking-a-console.patch +wifi-iwlwifi-fix-debug-actions-order.patch +ipv6-save-dontfrag-in-cork.patch +drm-amd-display-remove-minimum-dispclk-and-apply-oem.patch +drm-amd-display-calculate-the-remain-segments-for-al.patch +drm-amd-display-fix-incorrect-dpcd-configs-while-rep.patch +gfs2-check-for-empty-queue-in-run_queue.patch +auxdisplay-charlcd-partially-revert-move-hwidth-and-.patch +asoc-qcom-sm8250-explicitly-set-format-in-sm8250_be_.patch +iommu-amd-pgtbl_v2-improve-error-handling.patch +cpufreq-tegra186-share-policy-per-cluster.patch +watchdog-aspeed-update-bootstatus-handling.patch +crypto-lzo-fix-compression-buffer-overrun.patch +drm-amdkfd-set-per-process-flags-only-once-cik-vi.patch +arm64-tegra-p2597-fix-gpio-for-vdd-1v8-dis-regulator.patch +arm64-tegra-resize-aperture-for-the-igx-pcie-c5-slot.patch +powerpc-prom_init-fixup-missing-size-cells-on-powerb.patch +alsa-seq-improve-data-consistency-at-polling.patch +tcp-bring-back-numa-dispersion-in-inet_ehash_locks_a.patch +rtc-ds1307-stop-disabling-alarms-on-probe.patch +ieee802154-ca8210-use-proper-setters-and-getters-for.patch +arm-tegra-switch-dsi-b-clock-parent-to-plld-on-tegra.patch +media-c8sectpfe-call-of_node_put-i2c_bus-only-once-i.patch +dm-cache-prevent-bug_on-by-blocking-retries-on-faile.patch +orangefs-do-not-truncate-file-size.patch +drm-gem-test-for-imported-gem-buffers-with-helper.patch +net-phylink-use-pl-link_interface-in-phylink_expects.patch +remoteproc-qcom_wcnss-handle-platforms-with-only-sin.patch +drm-amdgpu-do-not-program-agp-bar-regs-under-sriov-i.patch +drm-amd-display-skip-checking-frl_mode-bit-for-pcon-.patch +media-cx231xx-set-device_caps-for-417.patch +pinctrl-bcm281xx-use-unsigned-int-instead-of-bare-un.patch +net-ethernet-ti-cpsw_new-populate-netdev-of_node.patch +net-pktgen-fix-mpls-maximum-labels-list-parsing.patch +perf-hw_breakpoint-return-eopnotsupp-for-unsupported.patch +alsa-hda-realtek-enable-pc-beep-passthrough-for-hp-e.patch +ipv4-fib-move-fib_valid_key_len-to-rtm_to_fib_config.patch +drm-rockchip-vop2-add-uv-swap-for-cluster-window.patch +media-uvcvideo-add-sanity-check-to-uvc_ioctl_xu_ctrl.patch +media-uvcvideo-handle-uvc-menu-translation-inside-uv.patch +clk-imx8mp-inform-ccf-of-maximum-frequency-of-clocks.patch +x86-bugs-make-spectre-user-default-depend-on-mitigat.patch +hwmon-gpio-fan-add-missing-mutex-locks.patch +arm-at91-pm-fix-at91_suspend_finish-for-zq-calibrati.patch +drm-mediatek-mtk_dpi-add-checks-for-reg_h_fre_con-ex.patch +fpga-altera-cvp-increase-credit-timeout.patch +perf-arm_pmuv3-call-kvm_vcpu_pmu_resync_el0-before-e.patch +soc-apple-rtkit-use-high-prio-work-queue.patch +soc-apple-rtkit-implement-oslog-buffers-properly.patch +wifi-ath12k-report-proper-tx-completion-status-to-ma.patch +pci-brcmstb-expand-inbound-window-size-up-to-64gb.patch +pci-brcmstb-add-a-softdep-to-mip-msi-x-driver.patch +nvme-map-uring_cmd-data-even-if-address-is-0.patch +firmware-arm_ffa-set-dma_mask-for-ffa-devices.patch +net-mlx5-avoid-report-two-health-errors-on-same-synd.patch +selftests-net-have-gro.sh-t-return-a-correct-exit-co.patch +drm-amdkfd-kfd-release_work-possible-circular-lockin.patch +leds-pwm-multicolor-add-check-for-fwnode_property_re.patch +net-ethernet-mtk_ppe_offload-allow-qinq-double-eth_p.patch +net-xgene-v2-remove-incorrect-acpi_ptr-annotation.patch +bonding-report-duplicate-mac-address-in-all-situatio.patch +wifi-ath12k-improve-bss-discovery-with-hidden-ssid-i.patch +soc-ti-k3-socinfo-do-not-use-syscon-helper-to-build-.patch +octeontx2-af-rpm-register-driver-with-pci-subsys-ids.patch +x86-build-fix-broken-copy-command-in-genimage.sh-whe.patch +drm-amd-display-handle-max_downscale_src_width-fail-.patch +asoc-mediatek-mt8188-treat-dmic_gainx_cur-as-non-vol.patch +asoc-mediatek-mt8188-add-reference-for-dmic-clocks.patch +x86-nmi-add-an-emergency-handler-in-nmi_desc-use-it-.patch +vhost-scsi-return-queue-full-for-page-alloc-failures.patch +vdpa-mlx5-fix-mlx5_vdpa_get_config-endianness-on-big.patch +cpuidle-menu-avoid-discarding-useful-information.patch +media-adv7180-disable-test-pattern-control-on-adv718.patch +media-tc358746-improve-calculation-of-the-d-phy-timi.patch +libbpf-fix-out-of-bound-read.patch +dm-fix-unconditional-io-throttle-caused-by-req_prefl.patch +fs-mpage-avoid-negative-shift-for-large-blocksize.patch +net-mlx5-change-pool_next_size-define-value-and-make.patch +x86-kaslr-reduce-kaslr-entropy-on-most-x86-systems.patch +crypto-ahash-set-default-reqsize-from-ahash_alg.patch +crypto-skcipher-zap-type-in-crypto_alloc_sync_skciph.patch +mips-use-arch-specific-syscall-name-match-function.patch +genirq-msi-store-the-iommu-iova-directly-in-msi_desc.patch +mips-pm-cps-use-per-cpu-variables-as-per-cpu-not-per.patch +clocksource-mips-gic-timer-enable-counter-when-cpus-.patch +scsi-mpt3sas-send-a-diag-reset-if-target-reset-fails.patch +wifi-rtw88-fix-rtw_init_vht_cap-for-rtl8814au.patch +wifi-rtw88-fix-rtw_init_ht_cap-for-rtl8814au.patch +wifi-rtw88-fix-rtw_desc_to_mcsrate-to-handle-mcs16-3.patch +wifi-rtw89-fw-propagate-error-code-from-rtw89_h2c_tx.patch +net-pktgen-fix-access-outside-of-user-given-buffer-i.patch +edac-ie31200-work-around-false-positive-build-warnin.patch +bpf-prevent-unsafe-access-to-the-sock-fields-in-the-.patch +i3c-master-svc-flush-fifo-before-sending-dynamic-add.patch +drm-amd-display-add-support-for-disconnected-edp-str.patch +serial-mctrl_gpio-split-disable_ms-into-sync-and-no_.patch +rdma-core-fix-best-page-size-finding-when-it-can-cro.patch +pmdomain-imx-gpcv2-use-proper-helper-for-property-de.patch +can-c_can-use-of_property_present-to-test-existence-.patch +bpf-don-t-do-clean_live_states-when-state-loop_entry.patch +eth-mlx4-don-t-try-to-complete-xdp-frames-in-netpoll.patch +pci-fix-old_size-lower-bound-in-calculate_iosize-too.patch +acpi-hed-always-initialize-before-evged.patch +vxlan-join-leave-mc-group-after-remote-changes.patch +media-test-drivers-vivid-don-t-call-schedule-in-loop.patch +net-mlx5-modify-lsb-bitmask-in-temperature-event-to-.patch +net-mlx5-apply-rate-limiting-to-high-temperature-war.patch +firmware-arm_ffa-reject-higher-major-version-as-inco.patch +asoc-ops-enforce-platform-maximum-on-initial-value.patch +asoc-tas2764-add-reg-defaults-for-tas2764_int_clk_cf.patch +asoc-tas2764-mark-sw_reset-as-volatile.patch +asoc-tas2764-power-up-down-amp-on-mute-ops.patch +asoc-soc-dai-check-return-value-at-snd_soc_dai_set_t.patch +pinctrl-devicetree-do-not-goto-err-when-probing-hogs.patch +smack-recognize-ipv4-cipso-w-o-categories.patch +smack-revert-smackfs-added-check-catlen.patch +kunit-tool-use-qboot-on-qemu-x86_64.patch +kernfs-don-t-re-lock-kernfs_root-kernfs_rwsem-in-ker.patch +kernfs-acquire-kernfs_rwsem-in-kernfs_get_parent_den.patch +kernfs-acquire-kernfs_rwsem-in-kernfs_notify_workfn.patch +media-i2c-imx219-correct-the-minimum-vblanking-value.patch +media-v4l-memset-argument-to-0-before-calling-get_mb.patch +libbpf-fix-ldx-stx-st-co-re-relocation-size-adjustme.patch +net-mlx4_core-avoid-impossible-mlx4_db_alloc-order-v.patch +clk-qcom-ipq5018-allow-it-to-be-bulid-on-arm32.patch +clk-qcom-clk-alpha-pll-do-not-use-random-stack-value.patch +x86-traps-cleanup-and-robustify-decode_bug.patch +sched-reduce-the-default-slice-to-avoid-tasks-gettin.patch +serial-sh-sci-update-the-suspend-resume-support.patch +phy-core-don-t-require-set_mode-callback-for-phy_get.patch +soundwire-amd-change-the-soundwire-wake-enable-disab.patch +drm-amdgpu-set-snoop-bit-for-sdma-for-mi-series.patch +drm-amd-display-don-t-try-aux-transactions-on-discon.patch +drm-amdgpu-reset-psp-cmd-to-null-after-releasing-the.patch +drm-amd-display-update-cr-aux-rd-interval-interpreta.patch +drm-amd-display-initial-psr_version-with-correct-set.patch +drm-amd-display-increase-block_sequence-array-size.patch +drm-amdgpu-enlarge-the-vbios-binary-size-limit.patch +drm-amd-display-dm-drop-hw_support-check-in-amdgpu_d.patch +scsi-target-spc-fix-loop-traversal-in-spc_rsoc_get_d.patch +net-mlx5-extend-ethtool-loopback-selftest-to-support.patch +net-mlx5e-set-the-tx_queue_len-for-pfifo_fast.patch +net-mlx5e-reduce-rep-rxq-depth-to-256-for-ecpf.patch +net-mlx5e-reduce-the-max-log-mpwrq-sz-for-ecpf-and-r.patch +drm-v3d-add-clock-handling.patch +wifi-mac80211-don-t-unconditionally-call-drv_mgd_com.patch +wifi-mac80211-remove-misplaced-drv_mgd_complete_tx-c.patch +net-fec-refactor-mac-reset-to-function.patch +powerpc-pseries-iommu-memory-notifier-incorrectly-ad.patch +arch-powerpc-perf-check-the-instruction-type-before-.patch +ip-fib_rules-fetch-net-from-fib_rule-in-fib-46-_rule.patch +r8152-add-vendor-device-id-pair-for-dell-alienware-a.patch +pstore-change-kmsg_bytes-storage-size-to-u32.patch +leds-trigger-netdev-configure-led-blink-interval-for.patch +ext4-don-t-write-back-data-before-punch-hole-in-nojo.patch +ext4-remove-writable-userspace-mappings-before-trunc.patch +wifi-rtw88-fix-download_firmware_validate-for-rtl881.patch +wifi-rtw88-fix-__rtw_download_firmware-for-rtl8814au.patch +clk-qcom-camcc-sm8250-use-clk_rcg2_shared_ops-for-so.patch +hwmon-xgene-hwmon-use-appropriate-type-for-the-laten.patch +f2fs-introduce-f2fs_base_attr-for-global-sysfs-entri.patch +media-qcom-camss-csid-only-add-tpg-v4l2-ctrl-if-tpg-.patch +net-mlx5e-avoid-warn_on-when-configuring-mqprio-with.patch +vxlan-annotate-fdb-data-races.patch +ipv4-ip_gre-fix-set-but-not-used-warning-in-ipgre_er.patch +r8169-don-t-scan-phy-addresses-0.patch +bridge-mdb-allow-replace-of-a-host-joined-group.patch +ice-treat-dyn_allowed-only-as-suggestion.patch +rcu-handle-quiescent-states-for-preempt_rcu-n-preemp.patch +rcu-handle-unstable-rdp-in-rcu_read_unlock_strict.patch +rcu-fix-header-guard-for-rcu_all_qs.patch +perf-avoid-the-read-if-the-count-is-already-updated.patch +ice-count-combined-queues-using-rx-tx-count.patch +net-mana-fix-warning-in-the-writer-of-client-oob.patch +scsi-lpfc-handle-duplicate-d_ids-in-ndlp-search-by-d.patch +scsi-lpfc-free-phba-irq-in-lpfc_sli4_enable_msi-when.patch +scsi-st-restore-some-drive-settings-after-reset.patch +wifi-ath12k-avoid-napi_sync-before-napi_enable.patch +hid-usbkbd-fix-the-bit-shift-number-for-led_kana.patch +arm64-zynqmp-add-clock-output-names-property-in-cloc.patch +asoc-codecs-pcm3168a-allow-for-24-bit-in-provider-mo.patch +asoc-rt722-sdca-add-some-missing-readable-registers.patch +drm-ast-find-vbios-mode-from-regular-display-size.patch +bpftool-fix-readlink-usage-in-get_fd_type.patch +firmware-arm_scmi-relax-duplicate-name-constraint-ac.patch +perf-amd-ibs-fix-perf_ibs_op.cnt_mask-for-curcnt.patch +perf-amd-ibs-fix-config-to-sample-period-calculation.patch +wifi-rtl8xxxu-retry-firmware-download-on-error.patch +wifi-rtw88-don-t-use-static-local-variable-in-rtw882.patch +wifi-rtw89-add-wiphy_lock-to-work-that-isn-t-held-wi.patch +spi-zynqmp-gqspi-always-acknowledge-interrupts.patch +regulator-ad5398-add-device-tree-support.patch +wifi-ath12k-fix-ath12k_hal_tx_cmd_ext_desc_setup-inf.patch +accel-qaic-mask-out-sr-iov-pci-resources.patch +wifi-ath9k-return-by-of_get_mac_address.patch +wifi-ath12k-fix-end-offset-bit-definition-in-monitor.patch +drm-bridge-adv7511-fill-stream-capabilities.patch +drm-atomic-clarify-the-rules-around-drm_atomic_state.patch +drm-panel-edp-add-starry-116khd024006.patch +drm-add-valid-clones-check.patch +asoc-imx-card-adjust-over-allocation-of-memory-in-im.patch +book3s64-radix-fix-compile-errors-when-config_arch_w.patch +pinctrl-meson-define-the-pull-up-down-resistor-value.patch +asoc-cs42l43-disable-headphone-clamps-during-type-de.patch +asoc-intel-bytcr_rt5640-add-dmi-quirk-for-acer-aspir.patch +alsa-hda-realtek-add-quirk-for-hp-spectre-x360-15-df.patch +nvme-pci-add-quirks-for-device-126f-1001.patch +nvme-pci-add-quirks-for-wdc-blue-sn550-15b7-5009.patch +nvmet-tcp-don-t-restore-null-sk_state_change.patch +io_uring-fdinfo-annotate-racy-sq-cq-head-tail-reads.patch +cifs-fix-and-improve-cifs_query_path_info-and-cifs_q.patch +cifs-fix-changing-times-and-read-only-attr-over-smb1.patch +btrfs-correct-the-order-of-prelim_ref-arguments-in-b.patch +btrfs-avoid-null-pointer-dereference-if-no-valid-csu.patch +tools-ynl-gen-validate-0-len-strings-from-kernel.patch +wifi-iwlwifi-add-support-for-killer-on-mtl.patch +xenbus-allow-pvh-dom0-a-non-local-xenstore.patch +__legitimize_mnt-check-for-mnt_sync_umount-should-be.patch diff --git a/queue-6.6/smack-recognize-ipv4-cipso-w-o-categories.patch b/queue-6.6/smack-recognize-ipv4-cipso-w-o-categories.patch new file mode 100644 index 0000000000..03afdfa37b --- /dev/null +++ b/queue-6.6/smack-recognize-ipv4-cipso-w-o-categories.patch @@ -0,0 +1,75 @@ +From 3e004e9ed3cf304e47873f199d30de822bea18f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2025 02:40:34 +0300 +Subject: smack: recognize ipv4 CIPSO w/o categories + +From: Konstantin Andreev + +[ Upstream commit a158a937d864d0034fea14913c1f09c6d5f574b8 ] + +If SMACK label has CIPSO representation w/o categories, e.g.: + +| # cat /smack/cipso2 +| foo 10 +| @ 250/2 +| ... + +then SMACK does not recognize such CIPSO in input ipv4 packets +and substitues '*' label instead. Audit records may look like + +| lsm=SMACK fn=smack_socket_sock_rcv_skb action=denied +| subject="*" object="_" requested=w pid=0 comm="swapper/1" ... + +This happens in two steps: + +1) security/smack/smackfs.c`smk_set_cipso + does not clear NETLBL_SECATTR_MLS_CAT + from (struct smack_known *)skp->smk_netlabel.flags + on assigning CIPSO w/o categories: + +| rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat); +| skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; + +2) security/smack/smack_lsm.c`smack_from_secattr + can not match skp->smk_netlabel with input packet's + struct netlbl_lsm_secattr *sap + because sap->flags have not NETLBL_SECATTR_MLS_CAT (what is correct) + but skp->smk_netlabel.flags have (what is incorrect): + +| if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) { +| if ((skp->smk_netlabel.flags & +| NETLBL_SECATTR_MLS_CAT) == 0) +| found = 1; +| break; +| } + +This commit sets/clears NETLBL_SECATTR_MLS_CAT in +skp->smk_netlabel.flags according to the presense of CIPSO categories. +The update of smk_netlabel is not atomic, so input packets processing +still may be incorrect during short time while update proceeds. + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smackfs.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 5dd1e164f9b13..d27e8b916bfb9 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -933,6 +933,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, + if (rc >= 0) { + old_cat = skp->smk_netlabel.attr.mls.cat; + rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat); ++ if (ncats.attr.mls.cat) ++ skp->smk_netlabel.flags |= NETLBL_SECATTR_MLS_CAT; ++ else ++ skp->smk_netlabel.flags &= ~(u32)NETLBL_SECATTR_MLS_CAT; + skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; + synchronize_rcu(); + netlbl_catmap_free(old_cat); +-- +2.39.5 + diff --git a/queue-6.6/smack-revert-smackfs-added-check-catlen.patch b/queue-6.6/smack-revert-smackfs-added-check-catlen.patch new file mode 100644 index 0000000000..d69c641ca6 --- /dev/null +++ b/queue-6.6/smack-revert-smackfs-added-check-catlen.patch @@ -0,0 +1,64 @@ +From 3ceb2cb3b07abc43201272e1a66bd727d59d9efa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Jan 2025 02:40:33 +0300 +Subject: smack: Revert "smackfs: Added check catlen" + +From: Konstantin Andreev + +[ Upstream commit c7fb50cecff9cad19fdac5b37337eae4e42b94c7 ] + +This reverts commit ccfd889acb06eab10b98deb4b5eef0ec74157ea0 + +The indicated commit +* does not describe the problem that change tries to solve +* has programming issues +* introduces a bug: forever clears NETLBL_SECATTR_MLS_CAT + in (struct smack_known *)skp->smk_netlabel.flags + +Reverting the commit to reapproach original problem + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smackfs.c | 17 +++-------------- + 1 file changed, 3 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index d27e8b916bfb9..1e35c9f807b2b 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -830,7 +830,7 @@ static int smk_open_cipso(struct inode *inode, struct file *file) + static ssize_t smk_set_cipso(struct file *file, const char __user *buf, + size_t count, loff_t *ppos, int format) + { +- struct netlbl_lsm_catmap *old_cat, *new_cat = NULL; ++ struct netlbl_lsm_catmap *old_cat; + struct smack_known *skp; + struct netlbl_lsm_secattr ncats; + char mapcatset[SMK_CIPSOLEN]; +@@ -917,19 +917,8 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, + + smack_catset_bit(cat, mapcatset); + } +- ncats.flags = 0; +- if (catlen == 0) { +- ncats.attr.mls.cat = NULL; +- ncats.attr.mls.lvl = maplevel; +- new_cat = netlbl_catmap_alloc(GFP_ATOMIC); +- if (new_cat) +- new_cat->next = ncats.attr.mls.cat; +- ncats.attr.mls.cat = new_cat; +- skp->smk_netlabel.flags &= ~(1U << 3); +- rc = 0; +- } else { +- rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); +- } ++ ++ rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); + if (rc >= 0) { + old_cat = skp->smk_netlabel.attr.mls.cat; + rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat); +-- +2.39.5 + diff --git a/queue-6.6/smb-client-store-original-io-parameters-and-prevent-.patch b/queue-6.6/smb-client-store-original-io-parameters-and-prevent-.patch new file mode 100644 index 0000000000..16ddfc69c9 --- /dev/null +++ b/queue-6.6/smb-client-store-original-io-parameters-and-prevent-.patch @@ -0,0 +1,211 @@ +From cb84f59f8c8ce46314f63e6214b3a69cd71c8e6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 31 Mar 2025 21:33:14 +0800 +Subject: smb: client: Store original IO parameters and prevent zero IO sizes + +From: Wang Zhaolong + +[ Upstream commit 287906b20035a04a234d1a3c64f760a5678387be ] + +During mount option processing and negotiation with the server, the +original user-specified rsize/wsize values were being modified directly. +This makes it impossible to recover these values after a connection +reset, leading to potential degraded performance after reconnection. + +The other problem is that When negotiating read and write sizes, there are +cases where the negotiated values might calculate to zero, especially +during reconnection when server->max_read or server->max_write might be +reset. In general, these values come from the negotiation response. +According to MS-SMB2 specification, these values should be at least 65536 +bytes. + +This patch improves IO parameter handling: + +1. Adds vol_rsize and vol_wsize fields to store the original user-specified + values separately from the negotiated values +2. Uses got_rsize/got_wsize flags to determine if values were + user-specified rather than checking for non-zero values, which is more + reliable +3. Adds a prevent_zero_iosize() helper function to ensure IO sizes are + never negotiated down to zero, which could happen in edge cases like + when server->max_read/write is zero + +The changes make the CIFS client more resilient to unusual server +responses and reconnection scenarios, preventing potential failures +when IO sizes are calculated to be zero. + +Signed-off-by: Wang Zhaolong +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/fs_context.c | 2 ++ + fs/smb/client/fs_context.h | 3 +++ + fs/smb/client/smb1ops.c | 6 +++--- + fs/smb/client/smb2ops.c | 27 +++++++++++++++++++-------- + fs/smb/common/smb2pdu.h | 3 +++ + 5 files changed, 30 insertions(+), 11 deletions(-) + +diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c +index d2e291ef104ec..137d03781d526 100644 +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -1249,6 +1249,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, + case Opt_rsize: + ctx->rsize = result.uint_32; + ctx->got_rsize = true; ++ ctx->vol_rsize = ctx->rsize; + break; + case Opt_wsize: + ctx->wsize = result.uint_32; +@@ -1264,6 +1265,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, + ctx->wsize, PAGE_SIZE); + } + } ++ ctx->vol_wsize = ctx->wsize; + break; + case Opt_acregmax: + if (result.uint_32 > CIFS_MAX_ACTIMEO / HZ) { +diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h +index bbd2063ab838d..d0a2043ea4468 100644 +--- a/fs/smb/client/fs_context.h ++++ b/fs/smb/client/fs_context.h +@@ -253,6 +253,9 @@ struct smb3_fs_context { + bool use_client_guid:1; + /* reuse existing guid for multichannel */ + u8 client_guid[SMB2_CLIENT_GUID_SIZE]; ++ /* User-specified original r/wsize value */ ++ unsigned int vol_rsize; ++ unsigned int vol_wsize; + unsigned int bsize; + unsigned int rasize; + unsigned int rsize; +diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c +index 280885dd6bf08..0ba0f680205c1 100644 +--- a/fs/smb/client/smb1ops.c ++++ b/fs/smb/client/smb1ops.c +@@ -437,8 +437,8 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + unsigned int wsize; + + /* start with specified wsize, or default */ +- if (ctx->wsize) +- wsize = ctx->wsize; ++ if (ctx->got_wsize) ++ wsize = ctx->vol_wsize; + else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) + wsize = CIFS_DEFAULT_IOSIZE; + else +@@ -490,7 +490,7 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + else + defsize = server->maxBuf - sizeof(READ_RSP); + +- rsize = ctx->rsize ? ctx->rsize : defsize; ++ rsize = ctx->got_rsize ? ctx->vol_rsize : defsize; + + /* + * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index cead96454bb3d..4e3eacbec96d1 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -431,6 +431,17 @@ smb2_negotiate(const unsigned int xid, + return rc; + } + ++static inline unsigned int ++prevent_zero_iosize(unsigned int size, const char *type) ++{ ++ if (size == 0) { ++ cifs_dbg(VFS, "SMB: Zero %ssize calculated, using minimum value %u\n", ++ type, CIFS_MIN_DEFAULT_IOSIZE); ++ return CIFS_MIN_DEFAULT_IOSIZE; ++ } ++ return size; ++} ++ + static unsigned int + smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + { +@@ -438,12 +449,12 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + unsigned int wsize; + + /* start with specified wsize, or default */ +- wsize = ctx->wsize ? ctx->wsize : CIFS_DEFAULT_IOSIZE; ++ wsize = ctx->got_wsize ? ctx->vol_wsize : CIFS_DEFAULT_IOSIZE; + wsize = min_t(unsigned int, wsize, server->max_write); + if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) + wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); + +- return wsize; ++ return prevent_zero_iosize(wsize, "w"); + } + + static unsigned int +@@ -453,7 +464,7 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + unsigned int wsize; + + /* start with specified wsize, or default */ +- wsize = ctx->wsize ? ctx->wsize : SMB3_DEFAULT_IOSIZE; ++ wsize = ctx->got_wsize ? ctx->vol_wsize : SMB3_DEFAULT_IOSIZE; + wsize = min_t(unsigned int, wsize, server->max_write); + #ifdef CONFIG_CIFS_SMB_DIRECT + if (server->rdma) { +@@ -475,7 +486,7 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) + wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); + +- return wsize; ++ return prevent_zero_iosize(wsize, "w"); + } + + static unsigned int +@@ -485,13 +496,13 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + unsigned int rsize; + + /* start with specified rsize, or default */ +- rsize = ctx->rsize ? ctx->rsize : CIFS_DEFAULT_IOSIZE; ++ rsize = ctx->got_rsize ? ctx->vol_rsize : CIFS_DEFAULT_IOSIZE; + rsize = min_t(unsigned int, rsize, server->max_read); + + if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) + rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); + +- return rsize; ++ return prevent_zero_iosize(rsize, "r"); + } + + static unsigned int +@@ -501,7 +512,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + unsigned int rsize; + + /* start with specified rsize, or default */ +- rsize = ctx->rsize ? ctx->rsize : SMB3_DEFAULT_IOSIZE; ++ rsize = ctx->got_rsize ? ctx->vol_rsize : SMB3_DEFAULT_IOSIZE; + rsize = min_t(unsigned int, rsize, server->max_read); + #ifdef CONFIG_CIFS_SMB_DIRECT + if (server->rdma) { +@@ -524,7 +535,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) + if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) + rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE); + +- return rsize; ++ return prevent_zero_iosize(rsize, "r"); + } + + /* +diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h +index c3ee42188d252..1af827ae757e0 100644 +--- a/fs/smb/common/smb2pdu.h ++++ b/fs/smb/common/smb2pdu.h +@@ -95,6 +95,9 @@ + */ + #define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024) + ++/* According to MS-SMB2 specification The minimum recommended value is 65536.*/ ++#define CIFS_MIN_DEFAULT_IOSIZE (65536) ++ + /* + * SMB2 Header Definition + * +-- +2.39.5 + diff --git a/queue-6.6/soc-apple-rtkit-implement-oslog-buffers-properly.patch b/queue-6.6/soc-apple-rtkit-implement-oslog-buffers-properly.patch new file mode 100644 index 0000000000..cb9c1881c4 --- /dev/null +++ b/queue-6.6/soc-apple-rtkit-implement-oslog-buffers-properly.patch @@ -0,0 +1,156 @@ +From cf82522cb6ddf5f1a0426443f1e1d722b466683c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 19:00:04 +0000 +Subject: soc: apple: rtkit: Implement OSLog buffers properly + +From: Hector Martin + +[ Upstream commit a06398687065e0c334dc5fc4d2778b5b87292e43 ] + +Apparently nobody can figure out where the old logic came from, but it +seems like it has never been actually used on any supported firmware to +this day. OSLog buffers were apparently never requested. + +But starting with 13.3, we actually need this implemented properly for +MTP (and later AOP) to work, so let's actually do that. + +Signed-off-by: Hector Martin +Reviewed-by: Alyssa Rosenzweig +Link: https://lore.kernel.org/r/20250226-apple-soc-misc-v2-2-c3ec37f9021b@svenpeter.dev +Signed-off-by: Sven Peter +Signed-off-by: Sasha Levin +--- + drivers/soc/apple/rtkit-internal.h | 1 + + drivers/soc/apple/rtkit.c | 56 ++++++++++++++++++------------ + 2 files changed, 35 insertions(+), 22 deletions(-) + +diff --git a/drivers/soc/apple/rtkit-internal.h b/drivers/soc/apple/rtkit-internal.h +index 24bd619ec5e48..1da1dfd9cb199 100644 +--- a/drivers/soc/apple/rtkit-internal.h ++++ b/drivers/soc/apple/rtkit-internal.h +@@ -48,6 +48,7 @@ struct apple_rtkit { + + struct apple_rtkit_shmem ioreport_buffer; + struct apple_rtkit_shmem crashlog_buffer; ++ struct apple_rtkit_shmem oslog_buffer; + + struct apple_rtkit_shmem syslog_buffer; + char *syslog_msg_buffer; +diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c +index b9c5281c445ee..2c37216f423d2 100644 +--- a/drivers/soc/apple/rtkit.c ++++ b/drivers/soc/apple/rtkit.c +@@ -66,8 +66,9 @@ enum { + #define APPLE_RTKIT_SYSLOG_MSG_SIZE GENMASK_ULL(31, 24) + + #define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56) +-#define APPLE_RTKIT_OSLOG_INIT 1 +-#define APPLE_RTKIT_OSLOG_ACK 3 ++#define APPLE_RTKIT_OSLOG_BUFFER_REQUEST 1 ++#define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36) ++#define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0) + + #define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11 + #define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12 +@@ -256,15 +257,21 @@ static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk, + struct apple_rtkit_shmem *buffer, + u8 ep, u64 msg) + { +- size_t n_4kpages = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg); + u64 reply; + int err; + ++ /* The different size vs. IOVA shifts look odd but are indeed correct this way */ ++ if (ep == APPLE_RTKIT_EP_OSLOG) { ++ buffer->size = FIELD_GET(APPLE_RTKIT_OSLOG_SIZE, msg); ++ buffer->iova = FIELD_GET(APPLE_RTKIT_OSLOG_IOVA, msg) << 12; ++ } else { ++ buffer->size = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg) << 12; ++ buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg); ++ } ++ + buffer->buffer = NULL; + buffer->iomem = NULL; + buffer->is_mapped = false; +- buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg); +- buffer->size = n_4kpages << 12; + + dev_dbg(rtk->dev, "RTKit: buffer request for 0x%zx bytes at %pad\n", + buffer->size, &buffer->iova); +@@ -289,11 +296,21 @@ static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk, + } + + if (!buffer->is_mapped) { +- reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE, +- APPLE_RTKIT_BUFFER_REQUEST); +- reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, n_4kpages); +- reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, +- buffer->iova); ++ /* oslog uses different fields and needs a shifted IOVA instead of size */ ++ if (ep == APPLE_RTKIT_EP_OSLOG) { ++ reply = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE, ++ APPLE_RTKIT_OSLOG_BUFFER_REQUEST); ++ reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buffer->size); ++ reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA, ++ buffer->iova >> 12); ++ } else { ++ reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE, ++ APPLE_RTKIT_BUFFER_REQUEST); ++ reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, ++ buffer->size >> 12); ++ reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, ++ buffer->iova); ++ } + apple_rtkit_send_message(rtk, ep, reply, NULL, false); + } + +@@ -487,25 +504,18 @@ static void apple_rtkit_syslog_rx(struct apple_rtkit *rtk, u64 msg) + } + } + +-static void apple_rtkit_oslog_rx_init(struct apple_rtkit *rtk, u64 msg) +-{ +- u64 ack; +- +- dev_dbg(rtk->dev, "RTKit: oslog init: msg: 0x%llx\n", msg); +- ack = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE, APPLE_RTKIT_OSLOG_ACK); +- apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_OSLOG, ack, NULL, false); +-} +- + static void apple_rtkit_oslog_rx(struct apple_rtkit *rtk, u64 msg) + { + u8 type = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg); + + switch (type) { +- case APPLE_RTKIT_OSLOG_INIT: +- apple_rtkit_oslog_rx_init(rtk, msg); ++ case APPLE_RTKIT_OSLOG_BUFFER_REQUEST: ++ apple_rtkit_common_rx_get_buffer(rtk, &rtk->oslog_buffer, ++ APPLE_RTKIT_EP_OSLOG, msg); + break; + default: +- dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n", msg); ++ dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n", ++ msg); + } + } + +@@ -787,6 +797,7 @@ int apple_rtkit_reinit(struct apple_rtkit *rtk) + + apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer); + apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer); ++ apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer); + apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer); + + kfree(rtk->syslog_msg_buffer); +@@ -967,6 +978,7 @@ void apple_rtkit_free(struct apple_rtkit *rtk) + + apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer); + apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer); ++ apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer); + apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer); + + kfree(rtk->syslog_msg_buffer); +-- +2.39.5 + diff --git a/queue-6.6/soc-apple-rtkit-use-high-prio-work-queue.patch b/queue-6.6/soc-apple-rtkit-use-high-prio-work-queue.patch new file mode 100644 index 0000000000..9fc009e937 --- /dev/null +++ b/queue-6.6/soc-apple-rtkit-use-high-prio-work-queue.patch @@ -0,0 +1,42 @@ +From 0cd6a5535697d94ded53265678ee3ae119a5407f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Feb 2025 19:00:05 +0000 +Subject: soc: apple: rtkit: Use high prio work queue + +From: Janne Grunau + +[ Upstream commit 22af2fac88fa5dbc310bfe7d0b66d4de3ac47305 ] + +rtkit messages as communication with the DCP firmware for framebuffer +swaps or input events are time critical so use WQ_HIGHPRI to prevent +user space CPU load to increase latency. +With kwin_wayland 6's explicit sync mode user space load was able to +delay the IOMFB rtkit communication enough to miss vsync for surface +swaps. Minimal test scenario is constantly resizing a glxgears +Xwayland window. + +Signed-off-by: Janne Grunau +Reviewed-by: Alyssa Rosenzweig +Link: https://lore.kernel.org/r/20250226-apple-soc-misc-v2-3-c3ec37f9021b@svenpeter.dev +Signed-off-by: Sven Peter +Signed-off-by: Sasha Levin +--- + drivers/soc/apple/rtkit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c +index d9f19dc99da5e..b9c5281c445ee 100644 +--- a/drivers/soc/apple/rtkit.c ++++ b/drivers/soc/apple/rtkit.c +@@ -744,7 +744,7 @@ struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, + rtk->mbox_cl.rx_callback = &apple_rtkit_rx; + rtk->mbox_cl.tx_done = &apple_rtkit_tx_done; + +- rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_MEM_RECLAIM, ++ rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_HIGHPRI | WQ_MEM_RECLAIM, + dev_name(rtk->dev)); + if (!rtk->wq) { + ret = -ENOMEM; +-- +2.39.5 + diff --git a/queue-6.6/soc-ti-k3-socinfo-do-not-use-syscon-helper-to-build-.patch b/queue-6.6/soc-ti-k3-socinfo-do-not-use-syscon-helper-to-build-.patch new file mode 100644 index 0000000000..0934b2c86e --- /dev/null +++ b/queue-6.6/soc-ti-k3-socinfo-do-not-use-syscon-helper-to-build-.patch @@ -0,0 +1,68 @@ +From 60a8468c043d1f9577a7abc372cd45254ae4c9f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Jan 2025 12:17:26 -0600 +Subject: soc: ti: k3-socinfo: Do not use syscon helper to build regmap + +From: Andrew Davis + +[ Upstream commit a5caf03188e44388e8c618dcbe5fffad1a249385 ] + +The syscon helper device_node_to_regmap() is used to fetch a regmap +registered to a device node. It also currently creates this regmap +if the node did not already have a regmap associated with it. This +should only be used on "syscon" nodes. This driver is not such a +device and instead uses device_node_to_regmap() on its own node as +a hacky way to create a regmap for itself. + +This will not work going forward and so we should create our regmap +the normal way by defining our regmap_config, fetching our memory +resource, then using the normal regmap_init_mmio() function. + +Signed-off-by: Andrew Davis +Link: https://lore.kernel.org/r/20250123181726.597144-1-afd@ti.com +Signed-off-by: Nishanth Menon +Signed-off-by: Sasha Levin +--- + drivers/soc/ti/k3-socinfo.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c +index 6ea9b8c7d335c..7a3bdef5a7c0d 100644 +--- a/drivers/soc/ti/k3-socinfo.c ++++ b/drivers/soc/ti/k3-socinfo.c +@@ -63,6 +63,12 @@ k3_chipinfo_partno_to_names(unsigned int partno, + return -EINVAL; + } + ++static const struct regmap_config k3_chipinfo_regmap_cfg = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++}; ++ + static int k3_chipinfo_probe(struct platform_device *pdev) + { + struct device_node *node = pdev->dev.of_node; +@@ -70,13 +76,18 @@ static int k3_chipinfo_probe(struct platform_device *pdev) + struct device *dev = &pdev->dev; + struct soc_device *soc_dev; + struct regmap *regmap; ++ void __iomem *base; + u32 partno_id; + u32 variant; + u32 jtag_id; + u32 mfg; + int ret; + +- regmap = device_node_to_regmap(node); ++ base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ regmap = regmap_init_mmio(dev, base, &k3_chipinfo_regmap_cfg); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + +-- +2.39.5 + diff --git a/queue-6.6/soundwire-amd-change-the-soundwire-wake-enable-disab.patch b/queue-6.6/soundwire-amd-change-the-soundwire-wake-enable-disab.patch new file mode 100644 index 0000000000..171cd919e8 --- /dev/null +++ b/queue-6.6/soundwire-amd-change-the-soundwire-wake-enable-disab.patch @@ -0,0 +1,46 @@ +From 27bb1ecfbd4963949410e5135ca692352bcdb221 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 12:28:36 +0530 +Subject: soundwire: amd: change the soundwire wake enable/disable sequence + +From: Vijendar Mukunda + +[ Upstream commit dcc48a73eae7f791b1a6856ea1bcc4079282c88d ] + +During runtime suspend scenario, SoundWire wake should be enabled and +during system level suspend scenario SoundWire wake should be disabled. + +Implement the SoundWire wake enable/disable sequence as per design flow +for SoundWire poweroff mode. + +Signed-off-by: Vijendar Mukunda +Link: https://lore.kernel.org/r/20250207065841.4718-2-Vijendar.Mukunda@amd.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/soundwire/amd_manager.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c +index 79173ab540a6b..31b203ebbae0c 100644 +--- a/drivers/soundwire/amd_manager.c ++++ b/drivers/soundwire/amd_manager.c +@@ -1138,6 +1138,7 @@ static int __maybe_unused amd_suspend(struct device *dev) + amd_sdw_wake_enable(amd_manager, false); + return amd_sdw_clock_stop(amd_manager); + } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { ++ amd_sdw_wake_enable(amd_manager, false); + /* + * As per hardware programming sequence on AMD platforms, + * clock stop should be invoked first before powering-off +@@ -1165,6 +1166,7 @@ static int __maybe_unused amd_suspend_runtime(struct device *dev) + amd_sdw_wake_enable(amd_manager, true); + return amd_sdw_clock_stop(amd_manager); + } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { ++ amd_sdw_wake_enable(amd_manager, true); + ret = amd_sdw_clock_stop(amd_manager); + if (ret) + return ret; +-- +2.39.5 + diff --git a/queue-6.6/spi-rockchip-fix-register-out-of-bounds-access.patch b/queue-6.6/spi-rockchip-fix-register-out-of-bounds-access.patch new file mode 100644 index 0000000000..5e38582e1e --- /dev/null +++ b/queue-6.6/spi-rockchip-fix-register-out-of-bounds-access.patch @@ -0,0 +1,37 @@ +From 813284f9027aefd76728798d46cc5f6b8cdcbaad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Mar 2025 13:57:53 +0100 +Subject: spi-rockchip: Fix register out of bounds access + +From: Luis de Arquer + +[ Upstream commit 7a874e8b54ea21094f7fd2d428b164394c6cb316 ] + +Do not write native chip select stuff for GPIO chip selects. +GPIOs can be numbered much higher than native CS. +Also, it makes no sense. + +Signed-off-by: Luis de Arquer +Link: https://patch.msgid.link/365ccddfba110549202b3520f4401a6a936e82a8.camel@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-rockchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c +index 1f374cf4d6f65..1615f935c8f03 100644 +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -542,7 +542,7 @@ static int rockchip_spi_config(struct rockchip_spi *rs, + cr0 |= (spi->mode & 0x3U) << CR0_SCPH_OFFSET; + if (spi->mode & SPI_LSB_FIRST) + cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET; +- if (spi->mode & SPI_CS_HIGH) ++ if ((spi->mode & SPI_CS_HIGH) && !(spi_get_csgpiod(spi, 0))) + cr0 |= BIT(spi_get_chipselect(spi, 0)) << CR0_SOI_OFFSET; + + if (xfer->rx_buf && xfer->tx_buf) +-- +2.39.5 + diff --git a/queue-6.6/spi-zynqmp-gqspi-always-acknowledge-interrupts.patch b/queue-6.6/spi-zynqmp-gqspi-always-acknowledge-interrupts.patch new file mode 100644 index 0000000000..e863b08cbb --- /dev/null +++ b/queue-6.6/spi-zynqmp-gqspi-always-acknowledge-interrupts.patch @@ -0,0 +1,72 @@ +From 70ec320a6d697ccb85acffb6145877dd013febe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jan 2025 17:41:30 -0500 +Subject: spi: zynqmp-gqspi: Always acknowledge interrupts + +From: Sean Anderson + +[ Upstream commit 89785306453ce6d949e783f6936821a0b7649ee2 ] + +RXEMPTY can cause an IRQ, even though we may not do anything about it +(such as if we are waiting for more received data). We must still handle +these IRQs because we can tell they were caused by the device. + +Signed-off-by: Sean Anderson +Link: https://patch.msgid.link/20250116224130.2684544-6-sean.anderson@linux.dev +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-zynqmp-gqspi.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c +index 3503e6c0a5c98..b5deb4fe3b832 100644 +--- a/drivers/spi/spi-zynqmp-gqspi.c ++++ b/drivers/spi/spi-zynqmp-gqspi.c +@@ -799,7 +799,6 @@ static void zynqmp_process_dma_irq(struct zynqmp_qspi *xqspi) + static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) + { + struct zynqmp_qspi *xqspi = (struct zynqmp_qspi *)dev_id; +- irqreturn_t ret = IRQ_NONE; + u32 status, mask, dma_status = 0; + + status = zynqmp_gqspi_read(xqspi, GQSPI_ISR_OFST); +@@ -814,27 +813,24 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id) + dma_status); + } + +- if (mask & GQSPI_ISR_TXNOT_FULL_MASK) { ++ if (!mask && !dma_status) ++ return IRQ_NONE; ++ ++ if (mask & GQSPI_ISR_TXNOT_FULL_MASK) + zynqmp_qspi_filltxfifo(xqspi, GQSPI_TX_FIFO_FILL); +- ret = IRQ_HANDLED; +- } + +- if (dma_status & GQSPI_QSPIDMA_DST_I_STS_DONE_MASK) { ++ if (dma_status & GQSPI_QSPIDMA_DST_I_STS_DONE_MASK) + zynqmp_process_dma_irq(xqspi); +- ret = IRQ_HANDLED; +- } else if (!(mask & GQSPI_IER_RXEMPTY_MASK) && +- (mask & GQSPI_IER_GENFIFOEMPTY_MASK)) { ++ else if (!(mask & GQSPI_IER_RXEMPTY_MASK) && ++ (mask & GQSPI_IER_GENFIFOEMPTY_MASK)) + zynqmp_qspi_readrxfifo(xqspi, GQSPI_RX_FIFO_FILL); +- ret = IRQ_HANDLED; +- } + + if (xqspi->bytes_to_receive == 0 && xqspi->bytes_to_transfer == 0 && + ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) { + zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK); + complete(&xqspi->data_completion); +- ret = IRQ_HANDLED; + } +- return ret; ++ return IRQ_HANDLED; + } + + /** +-- +2.39.5 + diff --git a/queue-6.6/sunrpc-don-t-allow-waiting-for-exiting-tasks.patch b/queue-6.6/sunrpc-don-t-allow-waiting-for-exiting-tasks.patch new file mode 100644 index 0000000000..7d70e1aacd --- /dev/null +++ b/queue-6.6/sunrpc-don-t-allow-waiting-for-exiting-tasks.patch @@ -0,0 +1,35 @@ +From ae290131fcdc51639e76dafcd2fed3becb41dd79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Mar 2025 12:52:52 -0400 +Subject: SUNRPC: Don't allow waiting for exiting tasks + +From: Trond Myklebust + +[ Upstream commit 14e41b16e8cb677bb440dca2edba8b041646c742 ] + +Once a task calls exit_signals() it can no longer be signalled. So do +not allow it to do killable waits. + +Reviewed-by: Jeff Layton +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/sched.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 9b45fbdc90cab..73bc39281ef5f 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -276,6 +276,8 @@ EXPORT_SYMBOL_GPL(rpc_destroy_wait_queue); + + static int rpc_wait_bit_killable(struct wait_bit_key *key, int mode) + { ++ if (unlikely(current->flags & PF_EXITING)) ++ return -EINTR; + schedule(); + if (signal_pending_state(mode, current)) + return -ERESTARTSYS; +-- +2.39.5 + diff --git a/queue-6.6/sunrpc-rpc_clnt_set_transport-must-not-change-the-au.patch b/queue-6.6/sunrpc-rpc_clnt_set_transport-must-not-change-the-au.patch new file mode 100644 index 0000000000..ec984afc08 --- /dev/null +++ b/queue-6.6/sunrpc-rpc_clnt_set_transport-must-not-change-the-au.patch @@ -0,0 +1,38 @@ +From edeb5ccce51b70cffe60c09695c0c0f14935a847 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 19:35:01 -0400 +Subject: SUNRPC: rpc_clnt_set_transport() must not change the autobind setting + +From: Trond Myklebust + +[ Upstream commit bf9be373b830a3e48117da5d89bb6145a575f880 ] + +The autobind setting was supposed to be determined in rpc_create(), +since commit c2866763b402 ("SUNRPC: use sockaddr + size when creating +remote transport endpoints"). + +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/clnt.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 142ee6554848a..4ffb2bcaf3648 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -275,9 +275,6 @@ static struct rpc_xprt *rpc_clnt_set_transport(struct rpc_clnt *clnt, + old = rcu_dereference_protected(clnt->cl_xprt, + lockdep_is_held(&clnt->cl_lock)); + +- if (!xprt_bound(xprt)) +- clnt->cl_autobind = 1; +- + clnt->cl_timeout = timeout; + rcu_assign_pointer(clnt->cl_xprt, xprt); + spin_unlock(&clnt->cl_lock); +-- +2.39.5 + diff --git a/queue-6.6/sunrpc-rpcbind-should-never-reset-the-port-to-the-va.patch b/queue-6.6/sunrpc-rpcbind-should-never-reset-the-port-to-the-va.patch new file mode 100644 index 0000000000..abc258e9ad --- /dev/null +++ b/queue-6.6/sunrpc-rpcbind-should-never-reset-the-port-to-the-va.patch @@ -0,0 +1,40 @@ +From 433a0ade8fbb14afa28696e0c460a0c999dad831 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Mar 2025 19:05:48 -0400 +Subject: SUNRPC: rpcbind should never reset the port to the value '0' + +From: Trond Myklebust + +[ Upstream commit 214c13e380ad7636631279f426387f9c4e3c14d9 ] + +If we already had a valid port number for the RPC service, then we +should not allow the rpcbind client to set it to the invalid value '0'. + +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/rpcb_clnt.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index 102c3818bc54d..53bcca365fb1c 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -820,9 +820,10 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) + } + + trace_rpcb_setport(child, map->r_status, map->r_port); +- xprt->ops->set_port(xprt, map->r_port); +- if (map->r_port) ++ if (map->r_port) { ++ xprt->ops->set_port(xprt, map->r_port); + xprt_set_bound(xprt); ++ } + } + + /* +-- +2.39.5 + diff --git a/queue-6.6/tcp-bring-back-numa-dispersion-in-inet_ehash_locks_a.patch b/queue-6.6/tcp-bring-back-numa-dispersion-in-inet_ehash_locks_a.patch new file mode 100644 index 0000000000..f5650cb1c0 --- /dev/null +++ b/queue-6.6/tcp-bring-back-numa-dispersion-in-inet_ehash_locks_a.patch @@ -0,0 +1,105 @@ +From 1420acf34c993d9beb1920cd2835f57adaf1e1a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 13:05:50 +0000 +Subject: tcp: bring back NUMA dispersion in inet_ehash_locks_alloc() + +From: Eric Dumazet + +[ Upstream commit f8ece40786c9342249aa0a1b55e148ee23b2a746 ] + +We have platforms with 6 NUMA nodes and 480 cpus. + +inet_ehash_locks_alloc() currently allocates a single 64KB page +to hold all ehash spinlocks. This adds more pressure on a single node. + +Change inet_ehash_locks_alloc() to use vmalloc() to spread +the spinlocks on all online nodes, driven by NUMA policies. + +At boot time, NUMA policy is interleave=all, meaning that +tcp_hashinfo.ehash_locks gets hash dispersion on all nodes. + +Tested: + +lack5:~# grep inet_ehash_locks_alloc /proc/vmallocinfo +0x00000000d9aec4d1-0x00000000a828b652 69632 inet_ehash_locks_alloc+0x90/0x100 pages=16 vmalloc N0=2 N1=3 N2=3 N3=3 N4=3 N5=2 + +lack5:~# echo 8192 >/proc/sys/net/ipv4/tcp_child_ehash_entries +lack5:~# numactl --interleave=all unshare -n bash -c "grep inet_ehash_locks_alloc /proc/vmallocinfo" +0x000000004e99d30c-0x00000000763f3279 36864 inet_ehash_locks_alloc+0x90/0x100 pages=8 vmalloc N0=1 N1=2 N2=2 N3=1 N4=1 N5=1 +0x00000000d9aec4d1-0x00000000a828b652 69632 inet_ehash_locks_alloc+0x90/0x100 pages=16 vmalloc N0=2 N1=3 N2=3 N3=3 N4=3 N5=2 + +lack5:~# numactl --interleave=0,5 unshare -n bash -c "grep inet_ehash_locks_alloc /proc/vmallocinfo" +0x00000000fd73a33e-0x0000000004b9a177 36864 inet_ehash_locks_alloc+0x90/0x100 pages=8 vmalloc N0=4 N5=4 +0x00000000d9aec4d1-0x00000000a828b652 69632 inet_ehash_locks_alloc+0x90/0x100 pages=16 vmalloc N0=2 N1=3 N2=3 N3=3 N4=3 N5=2 + +lack5:~# echo 1024 >/proc/sys/net/ipv4/tcp_child_ehash_entries +lack5:~# numactl --interleave=all unshare -n bash -c "grep inet_ehash_locks_alloc /proc/vmallocinfo" +0x00000000db07d7a2-0x00000000ad697d29 8192 inet_ehash_locks_alloc+0x90/0x100 pages=1 vmalloc N2=1 +0x00000000d9aec4d1-0x00000000a828b652 69632 inet_ehash_locks_alloc+0x90/0x100 pages=16 vmalloc N0=2 N1=3 N2=3 N3=3 N4=3 N5=2 + +Signed-off-by: Eric Dumazet +Tested-by: Jason Xing +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250305130550.1865988-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_hashtables.c | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) + +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 7967ff7e02f79..60e81f6b1c6d4 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -1231,22 +1231,37 @@ int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo) + { + unsigned int locksz = sizeof(spinlock_t); + unsigned int i, nblocks = 1; ++ spinlock_t *ptr = NULL; + +- if (locksz != 0) { +- /* allocate 2 cache lines or at least one spinlock per cpu */ +- nblocks = max(2U * L1_CACHE_BYTES / locksz, 1U); +- nblocks = roundup_pow_of_two(nblocks * num_possible_cpus()); ++ if (locksz == 0) ++ goto set_mask; + +- /* no more locks than number of hash buckets */ +- nblocks = min(nblocks, hashinfo->ehash_mask + 1); ++ /* Allocate 2 cache lines or at least one spinlock per cpu. */ ++ nblocks = max(2U * L1_CACHE_BYTES / locksz, 1U) * num_possible_cpus(); + +- hashinfo->ehash_locks = kvmalloc_array(nblocks, locksz, GFP_KERNEL); +- if (!hashinfo->ehash_locks) +- return -ENOMEM; ++ /* At least one page per NUMA node. */ ++ nblocks = max(nblocks, num_online_nodes() * PAGE_SIZE / locksz); ++ ++ nblocks = roundup_pow_of_two(nblocks); ++ ++ /* No more locks than number of hash buckets. */ ++ nblocks = min(nblocks, hashinfo->ehash_mask + 1); + +- for (i = 0; i < nblocks; i++) +- spin_lock_init(&hashinfo->ehash_locks[i]); ++ if (num_online_nodes() > 1) { ++ /* Use vmalloc() to allow NUMA policy to spread pages ++ * on all available nodes if desired. ++ */ ++ ptr = vmalloc_array(nblocks, locksz); ++ } ++ if (!ptr) { ++ ptr = kvmalloc_array(nblocks, locksz, GFP_KERNEL); ++ if (!ptr) ++ return -ENOMEM; + } ++ for (i = 0; i < nblocks; i++) ++ spin_lock_init(&ptr[i]); ++ hashinfo->ehash_locks = ptr; ++set_mask: + hashinfo->ehash_locks_mask = nblocks - 1; + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/tcp-reorganize-tcp_in_ack_event-and-tcp_count_delive.patch b/queue-6.6/tcp-reorganize-tcp_in_ack_event-and-tcp_count_delive.patch new file mode 100644 index 0000000000..1631ac42a9 --- /dev/null +++ b/queue-6.6/tcp-reorganize-tcp_in_ack_event-and-tcp_count_delive.patch @@ -0,0 +1,155 @@ +From c39f5ebea6713c908f64e4682c26d144d9a659de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 23:38:41 +0100 +Subject: tcp: reorganize tcp_in_ack_event() and tcp_count_delivered() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 149dfb31615e22271d2525f078c95ea49bc4db24 ] + +- Move tcp_count_delivered() earlier and split tcp_count_delivered_ce() + out of it +- Move tcp_in_ack_event() later +- While at it, remove the inline from tcp_in_ack_event() and let + the compiler to decide + +Accurate ECN's heuristics does not know if there is going +to be ACE field based CE counter increase or not until after +rtx queue has been processed. Only then the number of ACKed +bytes/pkts is available. As CE or not affects presence of +FLAG_ECE, that information for tcp_in_ack_event is not yet +available in the old location of the call to tcp_in_ack_event(). + +Signed-off-by: Ilpo Järvinen +Signed-off-by: Chia-Yu Chang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_input.c | 56 +++++++++++++++++++++++++------------------- + 1 file changed, 32 insertions(+), 24 deletions(-) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 10d38ec0ff5ac..a172248b66783 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -425,6 +425,20 @@ static bool tcp_ecn_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr + return false; + } + ++static void tcp_count_delivered_ce(struct tcp_sock *tp, u32 ecn_count) ++{ ++ tp->delivered_ce += ecn_count; ++} ++ ++/* Updates the delivered and delivered_ce counts */ ++static void tcp_count_delivered(struct tcp_sock *tp, u32 delivered, ++ bool ece_ack) ++{ ++ tp->delivered += delivered; ++ if (ece_ack) ++ tcp_count_delivered_ce(tp, delivered); ++} ++ + /* Buffer size and advertised window tuning. + * + * 1. Tuning sk->sk_sndbuf, when connection enters established state. +@@ -1137,15 +1151,6 @@ void tcp_mark_skb_lost(struct sock *sk, struct sk_buff *skb) + } + } + +-/* Updates the delivered and delivered_ce counts */ +-static void tcp_count_delivered(struct tcp_sock *tp, u32 delivered, +- bool ece_ack) +-{ +- tp->delivered += delivered; +- if (ece_ack) +- tp->delivered_ce += delivered; +-} +- + /* This procedure tags the retransmission queue when SACKs arrive. + * + * We have three tag bits: SACKED(S), RETRANS(R) and LOST(L). +@@ -3816,12 +3821,23 @@ static void tcp_process_tlp_ack(struct sock *sk, u32 ack, int flag) + } + } + +-static inline void tcp_in_ack_event(struct sock *sk, u32 flags) ++static void tcp_in_ack_event(struct sock *sk, int flag) + { + const struct inet_connection_sock *icsk = inet_csk(sk); + +- if (icsk->icsk_ca_ops->in_ack_event) +- icsk->icsk_ca_ops->in_ack_event(sk, flags); ++ if (icsk->icsk_ca_ops->in_ack_event) { ++ u32 ack_ev_flags = 0; ++ ++ if (flag & FLAG_WIN_UPDATE) ++ ack_ev_flags |= CA_ACK_WIN_UPDATE; ++ if (flag & FLAG_SLOWPATH) { ++ ack_ev_flags |= CA_ACK_SLOWPATH; ++ if (flag & FLAG_ECE) ++ ack_ev_flags |= CA_ACK_ECE; ++ } ++ ++ icsk->icsk_ca_ops->in_ack_event(sk, ack_ev_flags); ++ } + } + + /* Congestion control has updated the cwnd already. So if we're in +@@ -3938,12 +3954,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + tcp_snd_una_update(tp, ack); + flag |= FLAG_WIN_UPDATE; + +- tcp_in_ack_event(sk, CA_ACK_WIN_UPDATE); +- + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPACKS); + } else { +- u32 ack_ev_flags = CA_ACK_SLOWPATH; +- + if (ack_seq != TCP_SKB_CB(skb)->end_seq) + flag |= FLAG_DATA; + else +@@ -3955,19 +3967,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una, + &sack_state); + +- if (tcp_ecn_rcv_ecn_echo(tp, tcp_hdr(skb))) { ++ if (tcp_ecn_rcv_ecn_echo(tp, tcp_hdr(skb))) + flag |= FLAG_ECE; +- ack_ev_flags |= CA_ACK_ECE; +- } + + if (sack_state.sack_delivered) + tcp_count_delivered(tp, sack_state.sack_delivered, + flag & FLAG_ECE); +- +- if (flag & FLAG_WIN_UPDATE) +- ack_ev_flags |= CA_ACK_WIN_UPDATE; +- +- tcp_in_ack_event(sk, ack_ev_flags); + } + + /* This is a deviation from RFC3168 since it states that: +@@ -3994,6 +3999,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + + tcp_rack_update_reo_wnd(sk, &rs); + ++ tcp_in_ack_event(sk, flag); ++ + if (tp->tlp_high_seq) + tcp_process_tlp_ack(sk, ack, flag); + +@@ -4025,6 +4032,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + return 1; + + no_queue: ++ tcp_in_ack_event(sk, flag); + /* If data was DSACKed, see if we can undo a cwnd reduction. */ + if (flag & FLAG_DSACKING_ACK) { + tcp_fastretrans_alert(sk, prior_snd_una, num_dupack, &flag, +-- +2.39.5 + diff --git a/queue-6.6/thermal-drivers-qoriq-power-down-tmu-on-system-suspe.patch b/queue-6.6/thermal-drivers-qoriq-power-down-tmu-on-system-suspe.patch new file mode 100644 index 0000000000..dc19a64b3b --- /dev/null +++ b/queue-6.6/thermal-drivers-qoriq-power-down-tmu-on-system-suspe.patch @@ -0,0 +1,63 @@ +From 358345007de23d5eebab80e7523009f9e95ba8a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2024 11:48:59 -0500 +Subject: thermal/drivers/qoriq: Power down TMU on system suspend + +From: Alice Guo + +[ Upstream commit 229f3feb4b0442835b27d519679168bea2de96c2 ] + +Enable power-down of TMU (Thermal Management Unit) for TMU version 2 during +system suspend to save power. Save approximately 4.3mW on VDD_ANA_1P8 on +i.MX93 platforms. + +Signed-off-by: Alice Guo +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241209164859.3758906-2-Frank.Li@nxp.com +Signed-off-by: Daniel Lezcano +Signed-off-by: Sasha Levin +--- + drivers/thermal/qoriq_thermal.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c +index 404f01cca4dab..ff8657afb31d3 100644 +--- a/drivers/thermal/qoriq_thermal.c ++++ b/drivers/thermal/qoriq_thermal.c +@@ -18,6 +18,7 @@ + #define SITES_MAX 16 + #define TMR_DISABLE 0x0 + #define TMR_ME 0x80000000 ++#define TMR_CMD BIT(29) + #define TMR_ALPF 0x0c000000 + #define TMR_ALPF_V2 0x03000000 + #define TMTMIR_DEFAULT 0x0000000f +@@ -356,6 +357,12 @@ static int __maybe_unused qoriq_tmu_suspend(struct device *dev) + if (ret) + return ret; + ++ if (data->ver > TMU_VER1) { ++ ret = regmap_set_bits(data->regmap, REGS_TMR, TMR_CMD); ++ if (ret) ++ return ret; ++ } ++ + clk_disable_unprepare(data->clk); + + return 0; +@@ -370,6 +377,12 @@ static int __maybe_unused qoriq_tmu_resume(struct device *dev) + if (ret) + return ret; + ++ if (data->ver > TMU_VER1) { ++ ret = regmap_clear_bits(data->regmap, REGS_TMR, TMR_CMD); ++ if (ret) ++ return ret; ++ } ++ + /* Enable monitoring */ + return regmap_update_bits(data->regmap, REGS_TMR, TMR_ME, TMR_ME); + } +-- +2.39.5 + diff --git a/queue-6.6/thunderbolt-do-not-add-non-active-nvm-if-nvm-upgrade.patch b/queue-6.6/thunderbolt-do-not-add-non-active-nvm-if-nvm-upgrade.patch new file mode 100644 index 0000000000..8a286a890c --- /dev/null +++ b/queue-6.6/thunderbolt-do-not-add-non-active-nvm-if-nvm-upgrade.patch @@ -0,0 +1,42 @@ +From 922e5ffb64e077b2d3bea7e778184a7bcaaa7673 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Mar 2025 14:56:20 +0200 +Subject: thunderbolt: Do not add non-active NVM if NVM upgrade is disabled for + retimer + +From: Mika Westerberg + +[ Upstream commit ad79c278e478ca8c1a3bf8e7a0afba8f862a48a1 ] + +This is only used to write a new NVM in order to upgrade the retimer +firmware. It does not make sense to expose it if upgrade is disabled. +This also makes it consistent with the router NVM upgrade. + +Signed-off-by: Mika Westerberg +Signed-off-by: Sasha Levin +--- + drivers/thunderbolt/retimer.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c +index 2ee8c5ebca7c3..43146c0685dfa 100644 +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -89,9 +89,11 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt) + if (ret) + goto err_nvm; + +- ret = tb_nvm_add_non_active(nvm, nvm_write); +- if (ret) +- goto err_nvm; ++ if (!rt->no_nvm_upgrade) { ++ ret = tb_nvm_add_non_active(nvm, nvm_write); ++ if (ret) ++ goto err_nvm; ++ } + + rt->nvm = nvm; + return 0; +-- +2.39.5 + diff --git a/queue-6.6/timer_list-don-t-use-pk-through-printk.patch b/queue-6.6/timer_list-don-t-use-pk-through-printk.patch new file mode 100644 index 0000000000..726906d6ca --- /dev/null +++ b/queue-6.6/timer_list-don-t-use-pk-through-printk.patch @@ -0,0 +1,65 @@ +From 61053ca8b74e3b44e0208f5f89383515c367a265 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 10:54:47 +0100 +Subject: timer_list: Don't use %pK through printk() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit a52067c24ccf6ee4c85acffa0f155e9714f9adce ] + +This reverts commit f590308536db ("timer debug: Hide kernel addresses via +%pK in /proc/timer_list") + +The timer list helper SEQ_printf() uses either the real seq_printf() for +procfs output or vprintk() to print to the kernel log, when invoked from +SysRq-q. It uses %pK for printing pointers. + +In the past %pK was prefered over %p as it would not leak raw pointer +values into the kernel log. Since commit ad67b74d2469 ("printk: hash +addresses printed with %p") the regular %p has been improved to avoid this +issue. + +Furthermore, restricted pointers ("%pK") were never meant to be used +through printk(). They can still unintentionally leak raw pointers or +acquire sleeping looks in atomic contexts. + +Switch to the regular pointer formatting which is safer, easier to reason +about and sufficient here. + +Signed-off-by: Thomas Weißschuh +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/lkml/20250113171731-dc10e3c1-da64-4af0-b767-7c7070468023@linutronix.de/ +Link: https://lore.kernel.org/all/20250311-restricted-pointers-timer-v1-1-6626b91e54ab@linutronix.de +Signed-off-by: Sasha Levin +--- + kernel/time/timer_list.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c +index ed7d6ad694fba..20a5e6962b696 100644 +--- a/kernel/time/timer_list.c ++++ b/kernel/time/timer_list.c +@@ -46,7 +46,7 @@ static void + print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer, + int idx, u64 now) + { +- SEQ_printf(m, " #%d: <%pK>, %ps", idx, taddr, timer->function); ++ SEQ_printf(m, " #%d: <%p>, %ps", idx, taddr, timer->function); + SEQ_printf(m, ", S:%02x", timer->state); + SEQ_printf(m, "\n"); + SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n", +@@ -98,7 +98,7 @@ print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base, + static void + print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) + { +- SEQ_printf(m, " .base: %pK\n", base); ++ SEQ_printf(m, " .base: %p\n", base); + SEQ_printf(m, " .index: %d\n", base->index); + + SEQ_printf(m, " .resolution: %u nsecs\n", hrtimer_resolution); +-- +2.39.5 + diff --git a/queue-6.6/tools-build-don-t-pass-test-log-files-to-linker.patch b/queue-6.6/tools-build-don-t-pass-test-log-files-to-linker.patch new file mode 100644 index 0000000000..60bb7d8e3f --- /dev/null +++ b/queue-6.6/tools-build-don-t-pass-test-log-files-to-linker.patch @@ -0,0 +1,48 @@ +From 2dd88d01762eb0797993fc5ff6f2623130b43ff2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 14:36:23 -0700 +Subject: tools/build: Don't pass test log files to linker + +From: Ian Rogers + +[ Upstream commit 935e7cb5bb80106ff4f2fe39640f430134ef8cd8 ] + +Separate test log files from object files. Depend on test log output +but don't pass to the linker. + +Reviewed-by: James Clark +Signed-off-by: Ian Rogers +Link: https://lore.kernel.org/r/20250311213628.569562-2-irogers@google.com +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/build/Makefile.build | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build +index fac42486a8cf0..27f4ee9cb4db4 100644 +--- a/tools/build/Makefile.build ++++ b/tools/build/Makefile.build +@@ -141,6 +141,10 @@ objprefix := $(subst ./,,$(OUTPUT)$(dir)/) + obj-y := $(addprefix $(objprefix),$(obj-y)) + subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y)) + ++# Separate out test log files from real build objects. ++test-y := $(filter %_log, $(obj-y)) ++obj-y := $(filter-out %_log, $(obj-y)) ++ + # Final '$(obj)-in.o' object + in-target := $(objprefix)$(obj)-in.o + +@@ -151,7 +155,7 @@ $(subdir-y): + + $(sort $(subdir-obj-y)): $(subdir-y) ; + +-$(in-target): $(obj-y) FORCE ++$(in-target): $(obj-y) $(test-y) FORCE + $(call rule_mkdir) + $(call if_changed,$(host)ld_multi) + +-- +2.39.5 + diff --git a/queue-6.6/tools-ynl-gen-validate-0-len-strings-from-kernel.patch b/queue-6.6/tools-ynl-gen-validate-0-len-strings-from-kernel.patch new file mode 100644 index 0000000000..c5e1762595 --- /dev/null +++ b/queue-6.6/tools-ynl-gen-validate-0-len-strings-from-kernel.patch @@ -0,0 +1,38 @@ +From 46c12b6743797019a6efdaea415f22ee8002dc09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 May 2025 21:30:50 -0700 +Subject: tools: ynl-gen: validate 0 len strings from kernel + +From: David Wei + +[ Upstream commit 4720f9707c783f642332dee3d56dccaefa850e42 ] + +Strings from the kernel are guaranteed to be null terminated and +ynl_attr_validate() checks for this. But it doesn't check if the string +has a len of 0, which would cause problems when trying to access +data[len - 1]. Fix this by checking that len is positive. + +Signed-off-by: David Wei +Link: https://patch.msgid.link/20250503043050.861238-1-dw@davidwei.uk +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + tools/net/ynl/lib/ynl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c +index ae61ae5b02bf8..0871f86c6b666 100644 +--- a/tools/net/ynl/lib/ynl.c ++++ b/tools/net/ynl/lib/ynl.c +@@ -368,7 +368,7 @@ int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr) + "Invalid attribute (binary %s)", policy->name); + return -1; + case YNL_PT_NUL_STR: +- if ((!policy->len || len <= policy->len) && !data[len - 1]) ++ if (len && (!policy->len || len <= policy->len) && !data[len - 1]) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (string %s)", policy->name); +-- +2.39.5 + diff --git a/queue-6.6/tracing-mark-binary-printing-functions-with-__printf.patch b/queue-6.6/tracing-mark-binary-printing-functions-with-__printf.patch new file mode 100644 index 0000000000..84822d61ba --- /dev/null +++ b/queue-6.6/tracing-mark-binary-printing-functions-with-__printf.patch @@ -0,0 +1,158 @@ +From ecb9690b74aba57d50028257c273ded3388f31e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Mar 2025 16:40:49 +0200 +Subject: tracing: Mark binary printing functions with __printf() attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Shevchenko + +[ Upstream commit 196a062641fe68d9bfe0ad36b6cd7628c99ad22c ] + +Binary printing functions are using printf() type of format, and compiler +is not happy about them as is: + +kernel/trace/trace.c:3292:9: error: function ‘trace_vbprintk’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] +kernel/trace/trace_seq.c:182:9: error: function ‘trace_seq_bprintf’ might be a candidate for ‘gnu_printf’ format attribute [-Werror=suggest-attribute=format] + +Fix the compilation errors by adding __printf() attribute. + +While at it, move existing __printf() attributes from the implementations +to the declarations. IT also fixes incorrect attribute parameters that are +used for trace_array_printk(). + +Signed-off-by: Andy Shevchenko +Reviewed-by: Kees Cook +Reviewed-by: Petr Mladek +Link: https://lore.kernel.org/r/20250321144822.324050-4-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + include/linux/trace.h | 4 ++-- + include/linux/trace_seq.h | 8 ++++---- + kernel/trace/trace.c | 11 +++-------- + kernel/trace/trace.h | 16 +++++++++------- + 4 files changed, 18 insertions(+), 21 deletions(-) + +diff --git a/include/linux/trace.h b/include/linux/trace.h +index fdcd76b7be83d..7eaad857dee04 100644 +--- a/include/linux/trace.h ++++ b/include/linux/trace.h +@@ -72,8 +72,8 @@ static inline int unregister_ftrace_export(struct trace_export *export) + static inline void trace_printk_init_buffers(void) + { + } +-static inline int trace_array_printk(struct trace_array *tr, unsigned long ip, +- const char *fmt, ...) ++static inline __printf(3, 4) ++int trace_array_printk(struct trace_array *tr, unsigned long ip, const char *fmt, ...) + { + return 0; + } +diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h +index 3691e0e76a1a2..62147eecf931d 100644 +--- a/include/linux/trace_seq.h ++++ b/include/linux/trace_seq.h +@@ -79,8 +79,8 @@ extern __printf(2, 3) + void trace_seq_printf(struct trace_seq *s, const char *fmt, ...); + extern __printf(2, 0) + void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args); +-extern void +-trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); ++extern __printf(2, 0) ++void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); + extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); + extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, + int cnt); +@@ -104,8 +104,8 @@ static inline __printf(2, 3) + void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) + { + } +-static inline void +-trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) ++static inline __printf(2, 0) ++void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary) + { + } + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 95868c3157300..43d19b69c635b 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -3487,10 +3487,9 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) + } + EXPORT_SYMBOL_GPL(trace_vbprintk); + +-__printf(3, 0) +-static int +-__trace_array_vprintk(struct trace_buffer *buffer, +- unsigned long ip, const char *fmt, va_list args) ++static __printf(3, 0) ++int __trace_array_vprintk(struct trace_buffer *buffer, ++ unsigned long ip, const char *fmt, va_list args) + { + struct trace_event_call *call = &event_print; + struct ring_buffer_event *event; +@@ -3543,7 +3542,6 @@ __trace_array_vprintk(struct trace_buffer *buffer, + return len; + } + +-__printf(3, 0) + int trace_array_vprintk(struct trace_array *tr, + unsigned long ip, const char *fmt, va_list args) + { +@@ -3573,7 +3571,6 @@ int trace_array_vprintk(struct trace_array *tr, + * Note, trace_array_init_printk() must be called on @tr before this + * can be used. + */ +-__printf(3, 0) + int trace_array_printk(struct trace_array *tr, + unsigned long ip, const char *fmt, ...) + { +@@ -3618,7 +3615,6 @@ int trace_array_init_printk(struct trace_array *tr) + } + EXPORT_SYMBOL_GPL(trace_array_init_printk); + +-__printf(3, 4) + int trace_array_printk_buf(struct trace_buffer *buffer, + unsigned long ip, const char *fmt, ...) + { +@@ -3634,7 +3630,6 @@ int trace_array_printk_buf(struct trace_buffer *buffer, + return ret; + } + +-__printf(2, 0) + int trace_vprintk(unsigned long ip, const char *fmt, va_list args) + { + return trace_array_vprintk(&global_trace, ip, fmt, args); +diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h +index db0d2641125e7..faf892aecdf49 100644 +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -800,13 +800,15 @@ static inline void __init disable_tracing_selftest(const char *reason) + + extern void *head_page(struct trace_array_cpu *data); + extern unsigned long long ns2usecs(u64 nsec); +-extern int +-trace_vbprintk(unsigned long ip, const char *fmt, va_list args); +-extern int +-trace_vprintk(unsigned long ip, const char *fmt, va_list args); +-extern int +-trace_array_vprintk(struct trace_array *tr, +- unsigned long ip, const char *fmt, va_list args); ++ ++__printf(2, 0) ++int trace_vbprintk(unsigned long ip, const char *fmt, va_list args); ++__printf(2, 0) ++int trace_vprintk(unsigned long ip, const char *fmt, va_list args); ++__printf(3, 0) ++int trace_array_vprintk(struct trace_array *tr, ++ unsigned long ip, const char *fmt, va_list args); ++__printf(3, 4) + int trace_array_printk_buf(struct trace_buffer *buffer, + unsigned long ip, const char *fmt, ...); + void trace_printk_seq(struct trace_seq *s); +-- +2.39.5 + diff --git a/queue-6.6/um-store-full-csgsfs-and-ss-register-from-mcontext.patch b/queue-6.6/um-store-full-csgsfs-and-ss-register-from-mcontext.patch new file mode 100644 index 0000000000..1ec28f57be --- /dev/null +++ b/queue-6.6/um-store-full-csgsfs-and-ss-register-from-mcontext.patch @@ -0,0 +1,40 @@ +From d774f0918303c0c6ea8dd3243ab41e3aebf3be97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Feb 2025 19:18:19 +0100 +Subject: um: Store full CSGSFS and SS register from mcontext + +From: Benjamin Berg + +[ Upstream commit cef721e0d53d2b64f2ba177c63a0dfdd7c0daf17 ] + +Doing this allows using registers as retrieved from an mcontext to be +pushed to a process using PTRACE_SETREGS. + +It is not entirely clear to me why CSGSFS was masked. Doing so creates +issues when using the mcontext as process state in seccomp and simply +copying the register appears to work perfectly fine for ptrace. + +Signed-off-by: Benjamin Berg +Link: https://patch.msgid.link/20250224181827.647129-2-benjamin@sipsolutions.net +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/x86/um/os-Linux/mcontext.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/um/os-Linux/mcontext.c b/arch/x86/um/os-Linux/mcontext.c +index 49c3744cac371..81b9d1f9f4e68 100644 +--- a/arch/x86/um/os-Linux/mcontext.c ++++ b/arch/x86/um/os-Linux/mcontext.c +@@ -26,7 +26,6 @@ void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) + COPY(RIP); + COPY2(EFLAGS, EFL); + COPY2(CS, CSGSFS); +- regs->gp[CS / sizeof(unsigned long)] &= 0xffff; +- regs->gp[CS / sizeof(unsigned long)] |= 3; ++ regs->gp[SS / sizeof(unsigned long)] = mc->gregs[REG_CSGSFS] >> 48; + #endif + } +-- +2.39.5 + diff --git a/queue-6.6/um-update-min_low_pfn-to-match-changes-in-uml_reserv.patch b/queue-6.6/um-update-min_low_pfn-to-match-changes-in-uml_reserv.patch new file mode 100644 index 0000000000..2ab4077a60 --- /dev/null +++ b/queue-6.6/um-update-min_low_pfn-to-match-changes-in-uml_reserv.patch @@ -0,0 +1,36 @@ +From cb7e233d61b549eed8e248b36203927b77e69ca2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Feb 2025 12:18:55 +0800 +Subject: um: Update min_low_pfn to match changes in uml_reserved + +From: Tiwei Bie + +[ Upstream commit e82cf3051e6193f61e03898f8dba035199064d36 ] + +When uml_reserved is updated, min_low_pfn must also be updated +accordingly. Otherwise, min_low_pfn will not accurately reflect +the lowest available PFN. + +Signed-off-by: Tiwei Bie +Link: https://patch.msgid.link/20250221041855.1156109-1-tiwei.btw@antgroup.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/kernel/mem.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c +index 38d5a71a579bc..f6c766b2bdf5e 100644 +--- a/arch/um/kernel/mem.c ++++ b/arch/um/kernel/mem.c +@@ -68,6 +68,7 @@ void __init mem_init(void) + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); + memblock_free((void *)brk_end, uml_reserved - brk_end); + uml_reserved = brk_end; ++ min_low_pfn = PFN_UP(__pa(uml_reserved)); + + /* this will put all low memory onto the freelists */ + memblock_free_all(); +-- +2.39.5 + diff --git a/queue-6.6/usb-xhci-don-t-change-the-status-of-stalled-tds-on-f.patch b/queue-6.6/usb-xhci-don-t-change-the-status-of-stalled-tds-on-f.patch new file mode 100644 index 0000000000..fbf9b43cdc --- /dev/null +++ b/queue-6.6/usb-xhci-don-t-change-the-status-of-stalled-tds-on-f.patch @@ -0,0 +1,68 @@ +From 346e0201f0623091bc1e2eb33a29b90629fe8bd5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 17:45:50 +0200 +Subject: usb: xhci: Don't change the status of stalled TDs on failed Stop EP + +From: Michal Pecio + +[ Upstream commit dfc88357b6b6356dadea06b2c0bc8041f5e11720 ] + +When the device stalls an endpoint, current TD is assigned -EPIPE +status and Reset Endpoint is queued. If a Stop Endpoint is pending +at the time, it will run before Reset Endpoint and fail due to the +stall. Its handler will change TD's status to -EPROTO before Reset +Endpoint handler runs and initiates giveback. + +Check if the stall has already been handled and don't try to do it +again. Since xhci_handle_halted_endpoint() performs this check too, +not overwriting td->status is the only difference. + +I haven't seen this case yet, but I have seen a related one where +the xHC has already executed Reset Endpoint, EP Context state is +now Stopped and EP_HALTED is set. If the xHC took a bit longer to +execute Reset Endpoint, said case would become this one. + +Signed-off-by: Michal Pecio +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250311154551.4035726-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-ring.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 5a53280fa2edf..44352df58c9e4 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1180,7 +1180,14 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + */ + switch (GET_EP_CTX_STATE(ep_ctx)) { + case EP_STATE_HALTED: +- xhci_dbg(xhci, "Stop ep completion raced with stall, reset ep\n"); ++ xhci_dbg(xhci, "Stop ep completion raced with stall\n"); ++ /* ++ * If the halt happened before Stop Endpoint failed, its transfer event ++ * should have already been handled and Reset Endpoint should be pending. ++ */ ++ if (ep->ep_state & EP_HALTED) ++ goto reset_done; ++ + if (ep->ep_state & EP_HAS_STREAMS) { + reset_type = EP_SOFT_RESET; + } else { +@@ -1191,8 +1198,11 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + } + /* reset ep, reset handler cleans up cancelled tds */ + err = xhci_handle_halted_endpoint(xhci, ep, td, reset_type); ++ xhci_dbg(xhci, "Stop ep completion resetting ep, status %d\n", err); + if (err) + break; ++reset_done: ++ /* Reset EP handler will clean up cancelled TDs */ + ep->ep_state &= ~EP_STOP_CMD_PENDING; + return; + case EP_STATE_STOPPED: +-- +2.39.5 + diff --git a/queue-6.6/vdpa-mlx5-fix-mlx5_vdpa_get_config-endianness-on-big.patch b/queue-6.6/vdpa-mlx5-fix-mlx5_vdpa_get_config-endianness-on-big.patch new file mode 100644 index 0000000000..ba54085d87 --- /dev/null +++ b/queue-6.6/vdpa-mlx5-fix-mlx5_vdpa_get_config-endianness-on-big.patch @@ -0,0 +1,52 @@ +From 2eeea1d9cda7bbd7ee0199fafb6864adb1b7fbf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 11:31:27 -0600 +Subject: vdpa/mlx5: Fix mlx5_vdpa_get_config() endianness on big-endian + machines +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Konstantin Shkolnyy + +[ Upstream commit 439252e167ac45a5d46f573aac1da7d8f3e051ad ] + +mlx5_vdpa_dev_add() doesn’t initialize mvdev->actual_features. It’s +initialized later by mlx5_vdpa_set_driver_features(). However, +mlx5_vdpa_get_config() depends on the VIRTIO_F_VERSION_1 flag in +actual_features, to return data with correct endianness. When it’s called +before mlx5_vdpa_set_driver_features(), the data are incorrectly returned +as big-endian on big-endian machines, while QEMU then interprets them as +little-endian. + +The fix is to initialize this VIRTIO_F_VERSION_1 as early as possible, +especially considering that mlx5_vdpa_dev_add() insists on this flag to +always be set anyway. + +Signed-off-by: Konstantin Shkolnyy +Message-Id: <20250204173127.166673-1-kshk@linux.ibm.com> +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Dragos Tatulea +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index b56aae3f7be37..9b8b70ffde5a0 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -3420,6 +3420,9 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, + ndev->mvdev.max_vqs = max_vqs; + mvdev = &ndev->mvdev; + mvdev->mdev = mdev; ++ /* cpu_to_mlx5vdpa16() below depends on this flag */ ++ mvdev->actual_features = ++ (device_features & BIT_ULL(VIRTIO_F_VERSION_1)); + + ndev->vqs = kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL); + ndev->event_cbs = kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL); +-- +2.39.5 + diff --git a/queue-6.6/vfio-pci-handle-intx-irq_notconnected.patch b/queue-6.6/vfio-pci-handle-intx-irq_notconnected.patch new file mode 100644 index 0000000000..53351581bd --- /dev/null +++ b/queue-6.6/vfio-pci-handle-intx-irq_notconnected.patch @@ -0,0 +1,84 @@ +From 033f3620d932002a7240beb1fe84efad28f7ef52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 17:06:21 -0600 +Subject: vfio/pci: Handle INTx IRQ_NOTCONNECTED + +From: Alex Williamson + +[ Upstream commit 860be250fc32de9cb24154bf21b4e36f40925707 ] + +Some systems report INTx as not routed by setting pdev->irq to +IRQ_NOTCONNECTED, resulting in a -ENOTCONN error when trying to +setup eventfd signaling. Include this in the set of conditions +for which the PIN register is virtualized to zero. + +Additionally consolidate vfio_pci_get_irq_count() to use this +virtualized value in reporting INTx support via ioctl and sanity +checking ioctl paths since pdev->irq is re-used when the device +is in MSI mode. + +The combination of these results in both the config space of the +device and the ioctl interface behaving as if the device does not +support INTx. + +Reviewed-by: Kevin Tian +Link: https://lore.kernel.org/r/20250311230623.1264283-1-alex.williamson@redhat.com +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci_config.c | 3 ++- + drivers/vfio/pci/vfio_pci_core.c | 10 +--------- + drivers/vfio/pci/vfio_pci_intrs.c | 2 +- + 3 files changed, 4 insertions(+), 11 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index a2ad4f7c716bf..d9eb8733a324b 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -1813,7 +1813,8 @@ int vfio_config_init(struct vfio_pci_core_device *vdev) + cpu_to_le16(PCI_COMMAND_MEMORY); + } + +- if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx) ++ if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx || ++ vdev->pdev->irq == IRQ_NOTCONNECTED) + vconfig[PCI_INTERRUPT_PIN] = 0; + + ret = vfio_cap_init(vdev); +diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c +index a8f259bc2f4d0..fa168b4342395 100644 +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -731,15 +731,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable); + static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type) + { + if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) { +- u8 pin; +- +- if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || +- vdev->nointx || vdev->pdev->is_virtfn) +- return 0; +- +- pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); +- +- return pin ? 1 : 0; ++ return vdev->vconfig[PCI_INTERRUPT_PIN] ? 1 : 0; + } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) { + u8 pos; + u16 flags; +diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c +index 620134041b488..c4322faca2bd5 100644 +--- a/drivers/vfio/pci/vfio_pci_intrs.c ++++ b/drivers/vfio/pci/vfio_pci_intrs.c +@@ -269,7 +269,7 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev, + if (!is_irq_none(vdev)) + return -EINVAL; + +- if (!pdev->irq) ++ if (!pdev->irq || pdev->irq == IRQ_NOTCONNECTED) + return -ENODEV; + + name = kasprintf(GFP_KERNEL_ACCOUNT, "vfio-intx(%s)", pci_name(pdev)); +-- +2.39.5 + diff --git a/queue-6.6/vhost-scsi-protect-vq-log_used-with-vq-mutex.patch b/queue-6.6/vhost-scsi-protect-vq-log_used-with-vq-mutex.patch new file mode 100644 index 0000000000..2e39b4107a --- /dev/null +++ b/queue-6.6/vhost-scsi-protect-vq-log_used-with-vq-mutex.patch @@ -0,0 +1,82 @@ +From 906aa17a80802c779e9ec81b82cd7a9237b95183 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Apr 2025 23:29:46 -0700 +Subject: vhost-scsi: protect vq->log_used with vq->mutex + +From: Dongli Zhang + +[ Upstream commit f591cf9fce724e5075cc67488c43c6e39e8cbe27 ] + +The vhost-scsi completion path may access vq->log_base when vq->log_used is +already set to false. + + vhost-thread QEMU-thread + +vhost_scsi_complete_cmd_work() +-> vhost_add_used() + -> vhost_add_used_n() + if (unlikely(vq->log_used)) + QEMU disables vq->log_used + via VHOST_SET_VRING_ADDR. + mutex_lock(&vq->mutex); + vq->log_used = false now! + mutex_unlock(&vq->mutex); + + QEMU gfree(vq->log_base) + log_used() + -> log_write(vq->log_base) + +Assuming the VMM is QEMU. The vq->log_base is from QEMU userpace and can be +reclaimed via gfree(). As a result, this causes invalid memory writes to +QEMU userspace. + +The control queue path has the same issue. + +Signed-off-by: Dongli Zhang +Acked-by: Jason Wang +Reviewed-by: Mike Christie +Message-Id: <20250403063028.16045-2-dongli.zhang@oracle.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vhost/scsi.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c +index 8d8a22504d71f..724dd69c86489 100644 +--- a/drivers/vhost/scsi.c ++++ b/drivers/vhost/scsi.c +@@ -560,6 +560,9 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) + int ret; + + llnode = llist_del_all(&svq->completion_list); ++ ++ mutex_lock(&svq->vq.mutex); ++ + llist_for_each_entry_safe(cmd, t, llnode, tvc_completion_list) { + se_cmd = &cmd->tvc_se_cmd; + +@@ -593,6 +596,8 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) + vhost_scsi_release_cmd_res(se_cmd); + } + ++ mutex_unlock(&svq->vq.mutex); ++ + if (signal) + vhost_signal(&svq->vs->dev, &svq->vq); + } +@@ -1301,8 +1306,11 @@ static void vhost_scsi_tmf_resp_work(struct vhost_work *work) + resp_code = VIRTIO_SCSI_S_FUNCTION_REJECTED; + } + ++ mutex_lock(&tmf->svq->vq.mutex); + vhost_scsi_send_tmf_resp(tmf->vhost, &tmf->svq->vq, tmf->in_iovs, + tmf->vq_desc, &tmf->resp_iov, resp_code); ++ mutex_unlock(&tmf->svq->vq.mutex); ++ + vhost_scsi_release_tmf_res(tmf); + } + +-- +2.39.5 + diff --git a/queue-6.6/vhost-scsi-return-queue-full-for-page-alloc-failures.patch b/queue-6.6/vhost-scsi-return-queue-full-for-page-alloc-failures.patch new file mode 100644 index 0000000000..daab6073e0 --- /dev/null +++ b/queue-6.6/vhost-scsi-return-queue-full-for-page-alloc-failures.patch @@ -0,0 +1,79 @@ +From 1f72878c087fb452ee3bee18ef9cd6efcbc2b443 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Dec 2024 13:15:11 -0600 +Subject: vhost-scsi: Return queue full for page alloc failures during copy + +From: Mike Christie + +[ Upstream commit 891b99eab0f89dbe08d216f4ab71acbeaf7a3102 ] + +This has us return queue full if we can't allocate a page during the +copy operation so the initiator can retry. + +Signed-off-by: Mike Christie +Message-Id: <20241203191705.19431-5-michael.christie@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Stefan Hajnoczi +Signed-off-by: Sasha Levin +--- + drivers/vhost/scsi.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c +index 724dd69c86489..6623515111574 100644 +--- a/drivers/vhost/scsi.c ++++ b/drivers/vhost/scsi.c +@@ -751,7 +751,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter, + size_t len = iov_iter_count(iter); + unsigned int nbytes = 0; + struct page *page; +- int i; ++ int i, ret; + + if (cmd->tvc_data_direction == DMA_FROM_DEVICE) { + cmd->saved_iter_addr = dup_iter(&cmd->saved_iter, iter, +@@ -764,6 +764,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter, + page = alloc_page(GFP_KERNEL); + if (!page) { + i--; ++ ret = -ENOMEM; + goto err; + } + +@@ -771,8 +772,10 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter, + sg_set_page(&sg[i], page, nbytes, 0); + + if (cmd->tvc_data_direction == DMA_TO_DEVICE && +- copy_page_from_iter(page, 0, nbytes, iter) != nbytes) ++ copy_page_from_iter(page, 0, nbytes, iter) != nbytes) { ++ ret = -EFAULT; + goto err; ++ } + + len -= nbytes; + } +@@ -787,7 +790,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter, + for (; i >= 0; i--) + __free_page(sg_page(&sg[i])); + kfree(cmd->saved_iter_addr); +- return -ENOMEM; ++ return ret; + } + + static int +@@ -1226,9 +1229,9 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) + " %d\n", cmd, exp_data_len, prot_bytes, data_direction); + + if (data_direction != DMA_NONE) { +- if (unlikely(vhost_scsi_mapal(cmd, prot_bytes, +- &prot_iter, exp_data_len, +- &data_iter))) { ++ ret = vhost_scsi_mapal(cmd, prot_bytes, &prot_iter, ++ exp_data_len, &data_iter); ++ if (unlikely(ret)) { + vq_err(vq, "Failed to map iov to sgl\n"); + vhost_scsi_release_cmd_res(&cmd->tvc_se_cmd); + goto err; +-- +2.39.5 + diff --git a/queue-6.6/vhost_task-fix-vhost_task_create-documentation.patch b/queue-6.6/vhost_task-fix-vhost_task_create-documentation.patch new file mode 100644 index 0000000000..15d04d1f38 --- /dev/null +++ b/queue-6.6/vhost_task-fix-vhost_task_create-documentation.patch @@ -0,0 +1,40 @@ +From 83ca6dbb36636f8d826d1a33faab9884051f796c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Mar 2025 13:44:35 +0100 +Subject: vhost_task: fix vhost_task_create() documentation + +From: Stefano Garzarella + +[ Upstream commit fec0abf52609c20279243699d08b660c142ce0aa ] + +Commit cb380909ae3b ("vhost: return task creation error instead of NULL") +changed the return value of vhost_task_create(), but did not update the +documentation. + +Reflect the change in the documentation: on an error, vhost_task_create() +returns an ERR_PTR() and no longer NULL. + +Signed-off-by: Stefano Garzarella +Message-Id: <20250327124435.142831-1-sgarzare@redhat.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + kernel/vhost_task.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c +index 8800f5acc0071..0e4455742190c 100644 +--- a/kernel/vhost_task.c ++++ b/kernel/vhost_task.c +@@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(vhost_task_stop); + * @arg: data to be passed to fn and handled_kill + * @name: the thread's name + * +- * This returns a specialized task for use by the vhost layer or NULL on ++ * This returns a specialized task for use by the vhost layer or ERR_PTR() on + * failure. The returned task is inactive, and the caller must fire it up + * through vhost_task_start(). + */ +-- +2.39.5 + diff --git a/queue-6.6/virtio_ring-fix-data-race-by-tagging-event_triggered.patch b/queue-6.6/virtio_ring-fix-data-race-by-tagging-event_triggered.patch new file mode 100644 index 0000000000..017335157b --- /dev/null +++ b/queue-6.6/virtio_ring-fix-data-race-by-tagging-event_triggered.patch @@ -0,0 +1,71 @@ +From 8459f3869f5039834683de2797a40b68031f8485 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Mar 2025 21:04:12 +0800 +Subject: virtio_ring: Fix data race by tagging event_triggered as racy for + KCSAN + +From: Zhongqiu Han + +[ Upstream commit 2e2f925fe737576df2373931c95e1a2b66efdfef ] + +syzbot reports a data-race when accessing the event_triggered, here is the +simplified stack when the issue occurred: + +================================================================== +BUG: KCSAN: data-race in virtqueue_disable_cb / virtqueue_enable_cb_delayed + +write to 0xffff8881025bc452 of 1 bytes by task 3288 on cpu 0: + virtqueue_enable_cb_delayed+0x42/0x3c0 drivers/virtio/virtio_ring.c:2653 + start_xmit+0x230/0x1310 drivers/net/virtio_net.c:3264 + __netdev_start_xmit include/linux/netdevice.h:5151 [inline] + netdev_start_xmit include/linux/netdevice.h:5160 [inline] + xmit_one net/core/dev.c:3800 [inline] + +read to 0xffff8881025bc452 of 1 bytes by interrupt on cpu 1: + virtqueue_disable_cb_split drivers/virtio/virtio_ring.c:880 [inline] + virtqueue_disable_cb+0x92/0x180 drivers/virtio/virtio_ring.c:2566 + skb_xmit_done+0x5f/0x140 drivers/net/virtio_net.c:777 + vring_interrupt+0x161/0x190 drivers/virtio/virtio_ring.c:2715 + __handle_irq_event_percpu+0x95/0x490 kernel/irq/handle.c:158 + handle_irq_event_percpu kernel/irq/handle.c:193 [inline] + +value changed: 0x01 -> 0x00 +================================================================== + +When the data race occurs, the function virtqueue_enable_cb_delayed() sets +event_triggered to false, and virtqueue_disable_cb_split/packed() reads it +as false due to the race condition. Since event_triggered is an unreliable +hint used for optimization, this should only cause the driver temporarily +suggest that the device not send an interrupt notification when the event +index is used. + +Fix this KCSAN reported data-race issue by explicitly tagging the access as +data_racy. + +Reported-by: syzbot+efe683d57990864b8c8e@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/67c7761a.050a0220.15b4b9.0018.GAE@google.com/ +Signed-off-by: Zhongqiu Han +Message-Id: <20250312130412.3516307-1-quic_zhonhan@quicinc.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_ring.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 80669e05bf0ee..c5f04234d9511 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -2530,7 +2530,7 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) + struct vring_virtqueue *vq = to_vvq(_vq); + + if (vq->event_triggered) +- vq->event_triggered = false; ++ data_race(vq->event_triggered = false); + + return vq->packed_ring ? virtqueue_enable_cb_delayed_packed(_vq) : + virtqueue_enable_cb_delayed_split(_vq); +-- +2.39.5 + diff --git a/queue-6.6/vxlan-annotate-fdb-data-races.patch b/queue-6.6/vxlan-annotate-fdb-data-races.patch new file mode 100644 index 0000000000..2e09bb331f --- /dev/null +++ b/queue-6.6/vxlan-annotate-fdb-data-races.patch @@ -0,0 +1,144 @@ +From a25f658733b3105b7a7b7dabc3f19886044b9d2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 16:55:42 +0200 +Subject: vxlan: Annotate FDB data races + +From: Ido Schimmel + +[ Upstream commit f6205f8215f12a96518ac9469ff76294ae7bd612 ] + +The 'used' and 'updated' fields in the FDB entry structure can be +accessed concurrently by multiple threads, leading to reports such as +[1]. Can be reproduced using [2]. + +Suppress these reports by annotating these accesses using +READ_ONCE() / WRITE_ONCE(). + +[1] +BUG: KCSAN: data-race in vxlan_xmit / vxlan_xmit + +write to 0xffff942604d263a8 of 8 bytes by task 286 on cpu 0: + vxlan_xmit+0xb29/0x2380 + dev_hard_start_xmit+0x84/0x2f0 + __dev_queue_xmit+0x45a/0x1650 + packet_xmit+0x100/0x150 + packet_sendmsg+0x2114/0x2ac0 + __sys_sendto+0x318/0x330 + __x64_sys_sendto+0x76/0x90 + x64_sys_call+0x14e8/0x1c00 + do_syscall_64+0x9e/0x1a0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +read to 0xffff942604d263a8 of 8 bytes by task 287 on cpu 2: + vxlan_xmit+0xadf/0x2380 + dev_hard_start_xmit+0x84/0x2f0 + __dev_queue_xmit+0x45a/0x1650 + packet_xmit+0x100/0x150 + packet_sendmsg+0x2114/0x2ac0 + __sys_sendto+0x318/0x330 + __x64_sys_sendto+0x76/0x90 + x64_sys_call+0x14e8/0x1c00 + do_syscall_64+0x9e/0x1a0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +value changed: 0x00000000fffbac6e -> 0x00000000fffbac6f + +Reported by Kernel Concurrency Sanitizer on: +CPU: 2 UID: 0 PID: 287 Comm: mausezahn Not tainted 6.13.0-rc7-01544-gb4b270f11a02 #5 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 + +[2] + #!/bin/bash + + set +H + echo whitelist > /sys/kernel/debug/kcsan + echo !vxlan_xmit > /sys/kernel/debug/kcsan + + ip link add name vx0 up type vxlan id 10010 dstport 4789 local 192.0.2.1 + bridge fdb add 00:11:22:33:44:55 dev vx0 self static dst 198.51.100.1 + taskset -c 0 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q & + taskset -c 2 mausezahn vx0 -a own -b 00:11:22:33:44:55 -c 0 -q & + +Reviewed-by: Petr Machata +Signed-off-by: Ido Schimmel +Reviewed-by: Eric Dumazet +Reviewed-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20250204145549.1216254-2-idosch@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index 822cf49d82676..2ed879a0abc6c 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -227,9 +227,9 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan, + be32_to_cpu(fdb->vni))) + goto nla_put_failure; + +- ci.ndm_used = jiffies_to_clock_t(now - fdb->used); ++ ci.ndm_used = jiffies_to_clock_t(now - READ_ONCE(fdb->used)); + ci.ndm_confirmed = 0; +- ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated); ++ ci.ndm_updated = jiffies_to_clock_t(now - READ_ONCE(fdb->updated)); + ci.ndm_refcnt = 0; + + if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci)) +@@ -435,8 +435,8 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan, + struct vxlan_fdb *f; + + f = __vxlan_find_mac(vxlan, mac, vni); +- if (f && f->used != jiffies) +- f->used = jiffies; ++ if (f && READ_ONCE(f->used) != jiffies) ++ WRITE_ONCE(f->used, jiffies); + + return f; + } +@@ -1010,12 +1010,12 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan, + !(f->flags & NTF_VXLAN_ADDED_BY_USER)) { + if (f->state != state) { + f->state = state; +- f->updated = jiffies; ++ WRITE_ONCE(f->updated, jiffies); + notify = 1; + } + if (f->flags != fdb_flags) { + f->flags = fdb_flags; +- f->updated = jiffies; ++ WRITE_ONCE(f->updated, jiffies); + notify = 1; + } + } +@@ -1049,7 +1049,7 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan, + } + + if (ndm_flags & NTF_USE) +- f->used = jiffies; ++ WRITE_ONCE(f->used, jiffies); + + if (notify) { + if (rd == NULL) +@@ -1478,7 +1478,7 @@ static bool vxlan_snoop(struct net_device *dev, + src_mac, &rdst->remote_ip.sa, &src_ip->sa); + + rdst->remote_ip = *src_ip; +- f->updated = jiffies; ++ WRITE_ONCE(f->updated, jiffies); + vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH, true, NULL); + } else { + u32 hash_index = fdb_head_index(vxlan, src_mac, vni); +@@ -2920,7 +2920,7 @@ static void vxlan_cleanup(struct timer_list *t) + if (f->flags & NTF_EXT_LEARNED) + continue; + +- timeout = f->used + vxlan->cfg.age_interval * HZ; ++ timeout = READ_ONCE(f->used) + vxlan->cfg.age_interval * HZ; + if (time_before_eq(timeout, jiffies)) { + netdev_dbg(vxlan->dev, + "garbage collect %pM\n", +-- +2.39.5 + diff --git a/queue-6.6/vxlan-join-leave-mc-group-after-remote-changes.patch b/queue-6.6/vxlan-join-leave-mc-group-after-remote-changes.patch new file mode 100644 index 0000000000..9d2944e110 --- /dev/null +++ b/queue-6.6/vxlan-join-leave-mc-group-after-remote-changes.patch @@ -0,0 +1,113 @@ +From 7a6c0b39f8ae0bccdd6495bbd760c699dad1a071 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Feb 2025 17:18:21 +0100 +Subject: vxlan: Join / leave MC group after remote changes + +From: Petr Machata + +[ Upstream commit d42d543368343c0449a4e433b5f02e063a86209c ] + +When a vxlan netdevice is brought up, if its default remote is a multicast +address, the device joins the indicated group. + +Therefore when the multicast remote address changes, the device should +leave the current group and subscribe to the new one. Similarly when the +interface used for endpoint communication is changed in a situation when +multicast remote is configured. This is currently not done. + +Both vxlan_igmp_join() and vxlan_igmp_leave() can however fail. So it is +possible that with such fix, the netdevice will end up in an inconsistent +situation where the old group is not joined anymore, but joining the new +group fails. Should we join the new group first, and leave the old one +second, we might end up in the opposite situation, where both groups are +joined. Undoing any of this during rollback is going to be similarly +problematic. + +One solution would be to just forbid the change when the netdevice is up. +However in vnifilter mode, changing the group address is allowed, and these +problems are simply ignored (see vxlan_vni_update_group()): + + # ip link add name br up type bridge vlan_filtering 1 + # ip link add vx1 up master br type vxlan external vnifilter local 192.0.2.1 dev lo dstport 4789 + # bridge vni add dev vx1 vni 200 group 224.0.0.1 + # tcpdump -i lo & + # bridge vni add dev vx1 vni 200 group 224.0.0.2 + 18:55:46.523438 IP 0.0.0.0 > 224.0.0.22: igmp v3 report, 1 group record(s) + 18:55:46.943447 IP 0.0.0.0 > 224.0.0.22: igmp v3 report, 1 group record(s) + # bridge vni + dev vni group/remote + vx1 200 224.0.0.2 + +Having two different modes of operation for conceptually the same interface +is silly, so in this patch, just do what the vnifilter code does and deal +with the errors by crossing fingers real hard. + +The vnifilter code leaves old before joining new, and in case of join / +leave failures does not roll back the configuration changes that have +already been applied, but bails out of joining if it could not leave. Do +the same here: leave before join, apply changes unconditionally and do not +attempt to join if we couldn't leave. + +Signed-off-by: Petr Machata +Reviewed-by: Ido Schimmel +Reviewed-by: Nikolay Aleksandrov +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index 64db3e98a1b66..822cf49d82676 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -4240,6 +4240,7 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], + struct netlink_ext_ack *extack) + { + struct vxlan_dev *vxlan = netdev_priv(dev); ++ bool rem_ip_changed, change_igmp; + struct net_device *lowerdev; + struct vxlan_config conf; + struct vxlan_rdst *dst; +@@ -4263,8 +4264,13 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], + if (err) + return err; + ++ rem_ip_changed = !vxlan_addr_equal(&conf.remote_ip, &dst->remote_ip); ++ change_igmp = vxlan->dev->flags & IFF_UP && ++ (rem_ip_changed || ++ dst->remote_ifindex != conf.remote_ifindex); ++ + /* handle default dst entry */ +- if (!vxlan_addr_equal(&conf.remote_ip, &dst->remote_ip)) { ++ if (rem_ip_changed) { + u32 hash_index = fdb_head_index(vxlan, all_zeros_mac, conf.vni); + + spin_lock_bh(&vxlan->hash_lock[hash_index]); +@@ -4308,6 +4314,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], + } + } + ++ if (change_igmp && vxlan_addr_multicast(&dst->remote_ip)) ++ err = vxlan_multicast_leave(vxlan); ++ + if (conf.age_interval != vxlan->cfg.age_interval) + mod_timer(&vxlan->age_timer, jiffies); + +@@ -4315,7 +4324,12 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], + if (lowerdev && lowerdev != dst->remote_dev) + dst->remote_dev = lowerdev; + vxlan_config_apply(dev, &conf, lowerdev, vxlan->net, true); +- return 0; ++ ++ if (!err && change_igmp && ++ vxlan_addr_multicast(&dst->remote_ip)) ++ err = vxlan_multicast_join(vxlan); ++ ++ return err; + } + + static void vxlan_dellink(struct net_device *dev, struct list_head *head) +-- +2.39.5 + diff --git a/queue-6.6/watchdog-aspeed-update-bootstatus-handling.patch b/queue-6.6/watchdog-aspeed-update-bootstatus-handling.patch new file mode 100644 index 0000000000..39dfca8e86 --- /dev/null +++ b/queue-6.6/watchdog-aspeed-update-bootstatus-handling.patch @@ -0,0 +1,182 @@ +From 88f04e0d22c7584115a5ca0d80451520b7cf43e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 17:37:37 +0800 +Subject: watchdog: aspeed: Update bootstatus handling + +From: Chin-Ting Kuo + +[ Upstream commit 5c03f9f4d36292150c14ebd90788c4d3273ed9dc ] + +The boot status in the watchdog device struct is updated during +controller probe stage. Application layer can get the boot status +through the command, cat /sys/class/watchdog/watchdogX/bootstatus. +The bootstatus can be, +WDIOF_CARDRESET => System is reset due to WDT timeout occurs. +Others => Other reset events, e.g., power on reset. + +On ASPEED platforms, boot status is recorded in the SCU registers. +- AST2400: Only a bit is used to represent system reset triggered by + any WDT controller. +- AST2500/AST2600: System reset triggered by different WDT controllers + can be distinguished by different SCU bits. + +Besides, on AST2400 and AST2500, since alternating boot event is +also triggered by using WDT timeout mechanism, it is classified +as WDIOF_CARDRESET. + +Signed-off-by: Chin-Ting Kuo +Reviewed-by: Andrew Jeffery +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20250113093737.845097-2-chin-ting_kuo@aspeedtech.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/aspeed_wdt.c | 81 ++++++++++++++++++++++++++++++++++- + 1 file changed, 79 insertions(+), 2 deletions(-) + +diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c +index b72a858bbac70..7bc0fb1df1e00 100644 +--- a/drivers/watchdog/aspeed_wdt.c ++++ b/drivers/watchdog/aspeed_wdt.c +@@ -11,21 +11,30 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include + #include + + static bool nowayout = WATCHDOG_NOWAYOUT; + module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); ++struct aspeed_wdt_scu { ++ const char *compatible; ++ u32 reset_status_reg; ++ u32 wdt_reset_mask; ++ u32 wdt_reset_mask_shift; ++}; + + struct aspeed_wdt_config { + u32 ext_pulse_width_mask; + u32 irq_shift; + u32 irq_mask; ++ struct aspeed_wdt_scu scu; + }; + + struct aspeed_wdt { +@@ -39,18 +48,36 @@ static const struct aspeed_wdt_config ast2400_config = { + .ext_pulse_width_mask = 0xff, + .irq_shift = 0, + .irq_mask = 0, ++ .scu = { ++ .compatible = "aspeed,ast2400-scu", ++ .reset_status_reg = 0x3c, ++ .wdt_reset_mask = 0x1, ++ .wdt_reset_mask_shift = 1, ++ }, + }; + + static const struct aspeed_wdt_config ast2500_config = { + .ext_pulse_width_mask = 0xfffff, + .irq_shift = 12, + .irq_mask = GENMASK(31, 12), ++ .scu = { ++ .compatible = "aspeed,ast2500-scu", ++ .reset_status_reg = 0x3c, ++ .wdt_reset_mask = 0x1, ++ .wdt_reset_mask_shift = 2, ++ }, + }; + + static const struct aspeed_wdt_config ast2600_config = { + .ext_pulse_width_mask = 0xfffff, + .irq_shift = 0, + .irq_mask = GENMASK(31, 10), ++ .scu = { ++ .compatible = "aspeed,ast2600-scu", ++ .reset_status_reg = 0x74, ++ .wdt_reset_mask = 0xf, ++ .wdt_reset_mask_shift = 16, ++ }, + }; + + static const struct of_device_id aspeed_wdt_of_table[] = { +@@ -211,6 +238,56 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd, + return 0; + } + ++static void aspeed_wdt_update_bootstatus(struct platform_device *pdev, ++ struct aspeed_wdt *wdt) ++{ ++ const struct resource *res; ++ struct aspeed_wdt_scu scu = wdt->cfg->scu; ++ struct regmap *scu_base; ++ u32 reset_mask_width; ++ u32 reset_mask_shift; ++ u32 idx = 0; ++ u32 status; ++ int ret; ++ ++ if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); ++ } ++ ++ scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); ++ if (IS_ERR(scu_base)) { ++ wdt->wdd.bootstatus = WDIOS_UNKNOWN; ++ return; ++ } ++ ++ ret = regmap_read(scu_base, scu.reset_status_reg, &status); ++ if (ret) { ++ wdt->wdd.bootstatus = WDIOS_UNKNOWN; ++ return; ++ } ++ ++ reset_mask_width = hweight32(scu.wdt_reset_mask); ++ reset_mask_shift = scu.wdt_reset_mask_shift + ++ reset_mask_width * idx; ++ ++ if (status & (scu.wdt_reset_mask << reset_mask_shift)) ++ wdt->wdd.bootstatus = WDIOF_CARDRESET; ++ ++ /* clear wdt reset event flag */ ++ if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt") || ++ of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-wdt")) { ++ ret = regmap_read(scu_base, scu.reset_status_reg, &status); ++ if (!ret) { ++ status &= ~(scu.wdt_reset_mask << reset_mask_shift); ++ regmap_write(scu_base, scu.reset_status_reg, status); ++ } ++ } else { ++ regmap_write(scu_base, scu.reset_status_reg, ++ scu.wdt_reset_mask << reset_mask_shift); ++ } ++} ++ + /* access_cs0 shows if cs0 is accessible, hence the reverted bit */ + static ssize_t access_cs0_show(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -447,10 +524,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev) + writel(duration - 1, wdt->base + WDT_RESET_WIDTH); + } + ++ aspeed_wdt_update_bootstatus(pdev, wdt); ++ + status = readl(wdt->base + WDT_TIMEOUT_STATUS); + if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY) { +- wdt->wdd.bootstatus = WDIOF_CARDRESET; +- + if (of_device_is_compatible(np, "aspeed,ast2400-wdt") || + of_device_is_compatible(np, "aspeed,ast2500-wdt")) + wdt->wdd.groups = bswitch_groups; +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-avoid-napi_sync-before-napi_enable.patch b/queue-6.6/wifi-ath12k-avoid-napi_sync-before-napi_enable.patch new file mode 100644 index 0000000000..9403364389 --- /dev/null +++ b/queue-6.6/wifi-ath12k-avoid-napi_sync-before-napi_enable.patch @@ -0,0 +1,78 @@ +From cc0d264146fed0f38e68caed1a0fa502f45bb17e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 14:30:58 +0530 +Subject: wifi: ath12k: Avoid napi_sync() before napi_enable() + +From: Avula Sri Charan + +[ Upstream commit 268c73d470a5790a492a2fc2ded084b909d144f3 ] + +In case of MHI error a reset work will be queued which will try +napi_disable() after napi_synchronize(). + +As the napi will be only enabled after qmi_firmware_ready event, +trying napi_synchronize() before napi_enable() will result in +indefinite sleep in case of a firmware crash in QMI init sequence. + +To avoid this, introduce napi_enabled flag to check if napi is enabled +or not before calling napi_synchronize(). + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Avula Sri Charan +Signed-off-by: Tamizh Chelvam Raja +Reviewed-by: Aditya Kumar Singh +Link: https://patch.msgid.link/20250124090058.3194299-1-quic_tamizhr@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/core.h | 1 + + drivers/net/wireless/ath/ath12k/pci.c | 13 ++++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h +index 33f4706af880d..18dfd7aab610c 100644 +--- a/drivers/net/wireless/ath/ath12k/core.h ++++ b/drivers/net/wireless/ath/ath12k/core.h +@@ -125,6 +125,7 @@ struct ath12k_ext_irq_grp { + u32 num_irq; + u32 grp_id; + u64 timestamp; ++ bool napi_enabled; + struct napi_struct napi; + struct net_device napi_ndev; + }; +diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c +index 041a9602f0e15..5fd80f90ecafe 100644 +--- a/drivers/net/wireless/ath/ath12k/pci.c ++++ b/drivers/net/wireless/ath/ath12k/pci.c +@@ -442,8 +442,11 @@ static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) + + ath12k_pci_ext_grp_disable(irq_grp); + +- napi_synchronize(&irq_grp->napi); +- napi_disable(&irq_grp->napi); ++ if (irq_grp->napi_enabled) { ++ napi_synchronize(&irq_grp->napi); ++ napi_disable(&irq_grp->napi); ++ irq_grp->napi_enabled = false; ++ } + } + } + +@@ -976,7 +979,11 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab) + for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { + struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; + +- napi_enable(&irq_grp->napi); ++ if (!irq_grp->napi_enabled) { ++ napi_enable(&irq_grp->napi); ++ irq_grp->napi_enabled = true; ++ } ++ + ath12k_pci_ext_grp_enable(irq_grp); + } + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-fix-ath12k_hal_tx_cmd_ext_desc_setup-inf.patch b/queue-6.6/wifi-ath12k-fix-ath12k_hal_tx_cmd_ext_desc_setup-inf.patch new file mode 100644 index 0000000000..9972f3b8dd --- /dev/null +++ b/queue-6.6/wifi-ath12k-fix-ath12k_hal_tx_cmd_ext_desc_setup-inf.patch @@ -0,0 +1,41 @@ +From 8fc19596d3f52f0d5bbe14ab99f2d919a5b79201 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Jan 2025 08:13:06 +0100 +Subject: wifi: ath12k: fix ath12k_hal_tx_cmd_ext_desc_setup() info1 override + +From: Nicolas Escande + +[ Upstream commit df11edfba49e5fb69f4c9e7cb76082b89c417f78 ] + +Since inception there is an obvious typo laying around in +ath12k_hal_tx_cmd_ext_desc_setup(). Instead of initializing + adding +flags to tcl_ext_cmd->info1, we initialize + override. This will be needed +in the future to make broadcast frames work with ethernet encapsulation. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Nicolas Escande +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250127071306.1454699-1-nico.escande@gmail.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_tx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c +index 25a9d4c4fae76..474e0d4d406ea 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c +@@ -118,7 +118,7 @@ static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd, + le32_encode_bits(ti->data_len, + HAL_TX_MSDU_EXT_INFO1_BUF_LEN); + +- tcl_ext_cmd->info1 = le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | ++ tcl_ext_cmd->info1 |= le32_encode_bits(1, HAL_TX_MSDU_EXT_INFO1_EXTN_OVERRIDE) | + le32_encode_bits(ti->encap_type, + HAL_TX_MSDU_EXT_INFO1_ENCAP_TYPE) | + le32_encode_bits(ti->encrypt_type, +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-fix-end-offset-bit-definition-in-monitor.patch b/queue-6.6/wifi-ath12k-fix-end-offset-bit-definition-in-monitor.patch new file mode 100644 index 0000000000..416ca22971 --- /dev/null +++ b/queue-6.6/wifi-ath12k-fix-end-offset-bit-definition-in-monitor.patch @@ -0,0 +1,43 @@ +From a62068747059db323fd23693c9ec6d467063c4a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Dec 2024 11:31:25 +0530 +Subject: wifi: ath12k: Fix end offset bit definition in monitor ring + descriptor + +From: P Praneesh + +[ Upstream commit 6788a666000d600bd8f2e9f991cad9cc805e7f01 ] + +End offset for the monitor destination ring descriptor is defined as +16 bits, while the firmware definition specifies only 12 bits. +The remaining bits (bit 12 to bit 15) are reserved and may contain +junk values, leading to invalid information retrieval. Fix this issue +by updating the correct genmask values. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Signed-off-by: P Praneesh +Link: https://patch.msgid.link/20241223060132.3506372-8-quic_ppranees@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/hal_desc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/hal_desc.h b/drivers/net/wireless/ath/ath12k/hal_desc.h +index 6c17adc6d60b5..1bb840c2bef57 100644 +--- a/drivers/net/wireless/ath/ath12k/hal_desc.h ++++ b/drivers/net/wireless/ath/ath12k/hal_desc.h +@@ -2918,7 +2918,7 @@ struct hal_mon_buf_ring { + + #define HAL_MON_DEST_COOKIE_BUF_ID GENMASK(17, 0) + +-#define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(15, 0) ++#define HAL_MON_DEST_INFO0_END_OFFSET GENMASK(11, 0) + #define HAL_MON_DEST_INFO0_FLUSH_DETECTED BIT(16) + #define HAL_MON_DEST_INFO0_END_OF_PPDU BIT(17) + #define HAL_MON_DEST_INFO0_INITIATOR BIT(18) +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-improve-bss-discovery-with-hidden-ssid-i.patch b/queue-6.6/wifi-ath12k-improve-bss-discovery-with-hidden-ssid-i.patch new file mode 100644 index 0000000000..d5acabad85 --- /dev/null +++ b/queue-6.6/wifi-ath12k-improve-bss-discovery-with-hidden-ssid-i.patch @@ -0,0 +1,59 @@ +From 9ed925d8ea6a6903470b3e4d2fb4dfe8963d7a9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 11:30:05 +0530 +Subject: wifi: ath12k: Improve BSS discovery with hidden SSID in 6 GHz band + +From: Ramasamy Kaliappan + +[ Upstream commit 27d38bdfd416f4db70e09c3bef3b030c86fd235a ] + +Currently, sometimes, the station is unable to identify the configured +AP SSID in its scan results when the AP is not broadcasting its name +publicly and has a hidden SSID. + +Currently, channel dwell time for an ath12k station is 30 ms. Sometimes, +station can send broadcast probe request to AP close to the end of dwell +time. In some of these cases, before AP sends a response to the received +probe request, the dwell time on the station side would come to an end. +So, the station will move to scan next channel and will not be able to +acknowledge the unicast probe response. + +Resolve this issue by increasing station's channel dwell time to 70 ms, +so that the it remains on the same channel for a longer period. This +would increase the station's chance of receiving probe response from the +AP. The station will then send a response acknowledgment back to the AP, +thus leading to successful scan and BSS discovery. + +With an increased dwell time, scan would take longer than it takes now. +But, this fix is an improvement for hidden SSID scan issue. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Ramasamy Kaliappan +Signed-off-by: Roopni Devanathan +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250207060005.153835-1-quic_rdevanat@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/wmi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index c977dfbae0a46..d87d5980325e8 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -2115,8 +2115,8 @@ void ath12k_wmi_start_scan_init(struct ath12k *ar, + arg->dwell_time_active = 50; + arg->dwell_time_active_2g = 0; + arg->dwell_time_passive = 150; +- arg->dwell_time_active_6g = 40; +- arg->dwell_time_passive_6g = 30; ++ arg->dwell_time_active_6g = 70; ++ arg->dwell_time_passive_6g = 70; + arg->min_rest_time = 50; + arg->max_rest_time = 500; + arg->repeat_probe_time = 0; +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-report-proper-tx-completion-status-to-ma.patch b/queue-6.6/wifi-ath12k-report-proper-tx-completion-status-to-ma.patch new file mode 100644 index 0000000000..1ab2b6eb00 --- /dev/null +++ b/queue-6.6/wifi-ath12k-report-proper-tx-completion-status-to-ma.patch @@ -0,0 +1,56 @@ +From c79fa87410ce05ccee1cfc8d190fa8242bc269ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Nov 2024 23:04:32 +0530 +Subject: wifi: ath12k: Report proper tx completion status to mac80211 + +From: Vinith Kumar R + +[ Upstream commit d2d9c9b8de725e1006d3aa3d18678a732f5d3584 ] + +Currently Tx completion for few exception packets are received from +firmware and the tx status updated to mac80211. The tx status values of +HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP and HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL +are considered as tx failure and reported as tx failure to mac80211. +But these failure status is due to internal firmware tx drop and these +packets were not tried to transmit in the air. +In case of mesh this invalid tx status report might trigger mpath broken +issue due to increase in mpath fail average. +So do not report these tx status as tx failure instead free the skb +by calling ieee80211_free_txskb(), and that will be accounted as dropped +frame. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Vinith Kumar R +Signed-off-by: Tamizh Chelvam Raja +Acked-by: Jeff Johnson +Link: https://patch.msgid.link/20241122173432.2064858-1-quic_tamizhr@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_tx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_tx.c b/drivers/net/wireless/ath/ath12k/dp_tx.c +index e025e4d0e7678..25a9d4c4fae76 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_tx.c +@@ -422,13 +422,13 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, + + switch (wbm_status) { + case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK: +- case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: +- case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: + ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK); + ts.ack_rssi = le32_get_bits(status_desc->info2, + HTT_TX_WBM_COMP_INFO2_ACK_RSSI); + ath12k_dp_tx_htt_tx_complete_buf(ab, msdu, tx_ring, &ts); + break; ++ case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP: ++ case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: + case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: + ath12k_dp_tx_free_txbuf(ab, msdu, mac_id, tx_ring); +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath9k-return-by-of_get_mac_address.patch b/queue-6.6/wifi-ath9k-return-by-of_get_mac_address.patch new file mode 100644 index 0000000000..cf5c21d02d --- /dev/null +++ b/queue-6.6/wifi-ath9k-return-by-of_get_mac_address.patch @@ -0,0 +1,46 @@ +From 51a5c0b21e6b6147752bef8b1be3a8a251f2e8fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 14:23:26 -0800 +Subject: wifi: ath9k: return by of_get_mac_address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rosen Penev + +[ Upstream commit dfffb317519f88534bb82797f055f0a2fd867e7b ] + +When using nvmem, ath9k could potentially be loaded before nvmem, which +loads after mtd. This is an issue if DT contains an nvmem mac address. + +If nvmem is not ready in time for ath9k, -EPROBE_DEFER is returned. Pass +it to _probe so that ath9k can properly grab a potentially present MAC +address. + +Signed-off-by: Rosen Penev +Acked-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20241105222326.194417-1-rosenp@gmail.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath9k/init.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c +index 4f00400c7ffb8..58386906598a7 100644 +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -691,7 +691,9 @@ static int ath9k_of_init(struct ath_softc *sc) + ah->ah_flags |= AH_NO_EEP_SWAP; + } + +- of_get_mac_address(np, common->macaddr); ++ ret = of_get_mac_address(np, common->macaddr); ++ if (ret == -EPROBE_DEFER) ++ return ret; + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-iwlwifi-add-support-for-killer-on-mtl.patch b/queue-6.6/wifi-iwlwifi-add-support-for-killer-on-mtl.patch new file mode 100644 index 0000000000..f25cc38edf --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-add-support-for-killer-on-mtl.patch @@ -0,0 +1,36 @@ +From 89fc5615c5d6cdf68dd77d45451972ef57ba4c91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 May 2025 21:42:59 +0200 +Subject: wifi: iwlwifi: add support for Killer on MTL + +From: Johannes Berg + +[ Upstream commit ebedf8b7f05b9c886d68d63025db8d1b12343157 ] + +For now, we need another entry for these devices, this +will be changed completely for 6.16. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219926 +Link: https://patch.msgid.link/20250506214258.2efbdc9e9a82.I31915ec252bd1c74bd53b89a0e214e42a74b6f2e@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +index 4a2de79f2e864..c01a9a6f06a4d 100644 +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -580,6 +580,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { + IWL_DEV_INFO(0x7A70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + IWL_DEV_INFO(0x7AF0, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), + IWL_DEV_INFO(0x7AF0, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), ++ IWL_DEV_INFO(0x7F70, 0x1691, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690s_name), ++ IWL_DEV_INFO(0x7F70, 0x1692, iwlax411_2ax_cfg_so_gf4_a0, iwl_ax411_killer_1690i_name), + + IWL_DEV_INFO(0x271C, 0x0214, iwl9260_2ac_cfg, iwl9260_1_name), + IWL_DEV_INFO(0x7E40, 0x1691, iwl_cfg_ma, iwl_ax411_killer_1690s_name), +-- +2.39.5 + diff --git a/queue-6.6/wifi-iwlwifi-fix-debug-actions-order.patch b/queue-6.6/wifi-iwlwifi-fix-debug-actions-order.patch new file mode 100644 index 0000000000..899a85dc92 --- /dev/null +++ b/queue-6.6/wifi-iwlwifi-fix-debug-actions-order.patch @@ -0,0 +1,74 @@ +From db76757dd3dfb10f1f1ea5975c4119c24cc35ae1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Mar 2025 23:19:18 +0200 +Subject: wifi: iwlwifi: fix debug actions order + +From: Johannes Berg + +[ Upstream commit eb29b4ffafb20281624dcd2cbb768d6f30edf600 ] + +The order of actions taken for debug was implemented incorrectly. +Now we implemented the dump split and do the FW reset only in the +middle of the dump (rather than the FW killing itself on error.) +As a result, some of the actions taken when applying the config +will now crash the device, so we need to fix the order. + +Signed-off-by: Johannes Berg +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250308231427.6de7fa8e63ed.I40632c48e2a67a8aca05def572a934b88ce7934b@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +index a97ed7cbe4d14..d588e4cd808d8 100644 +--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +@@ -1,6 +1,6 @@ + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + /* +- * Copyright (C) 2018-2024 Intel Corporation ++ * Copyright (C) 2018-2025 Intel Corporation + */ + #include + #include "iwl-drv.h" +@@ -1382,15 +1382,15 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, + switch (tp_id) { + case IWL_FW_INI_TIME_POINT_EARLY: + iwl_dbg_tlv_init_cfg(fwrt); +- iwl_dbg_tlv_apply_config(fwrt, conf_list); + iwl_dbg_tlv_update_drams(fwrt); + iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); ++ iwl_dbg_tlv_apply_config(fwrt, conf_list); + break; + case IWL_FW_INI_TIME_POINT_AFTER_ALIVE: + iwl_dbg_tlv_apply_buffers(fwrt); + iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); +- iwl_dbg_tlv_apply_config(fwrt, conf_list); + iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); ++ iwl_dbg_tlv_apply_config(fwrt, conf_list); + break; + case IWL_FW_INI_TIME_POINT_PERIODIC: + iwl_dbg_tlv_set_periodic_trigs(fwrt); +@@ -1400,14 +1400,14 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt, + case IWL_FW_INI_TIME_POINT_MISSED_BEACONS: + case IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFICATION: + iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); +- iwl_dbg_tlv_apply_config(fwrt, conf_list); + iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, + iwl_dbg_tlv_check_fw_pkt); ++ iwl_dbg_tlv_apply_config(fwrt, conf_list); + break; + default: + iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list); +- iwl_dbg_tlv_apply_config(fwrt, conf_list); + iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL); ++ iwl_dbg_tlv_apply_config(fwrt, conf_list); + break; + } + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-mac80211-don-t-unconditionally-call-drv_mgd_com.patch b/queue-6.6/wifi-mac80211-don-t-unconditionally-call-drv_mgd_com.patch new file mode 100644 index 0000000000..20f36946f6 --- /dev/null +++ b/queue-6.6/wifi-mac80211-don-t-unconditionally-call-drv_mgd_com.patch @@ -0,0 +1,39 @@ +From 99b312d582fa783136af146b3b9b99f7650595ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 11:39:22 +0200 +Subject: wifi: mac80211: don't unconditionally call drv_mgd_complete_tx() + +From: Johannes Berg + +[ Upstream commit 1798271b3604b902d45033ec569f2bf77e94ecc2 ] + +We might not have called drv_mgd_prepare_tx(), so only call +drv_mgd_complete_tx() under the same conditions. + +Signed-off-by: Johannes Berg +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250205110958.e091fc39a351.Ie6a3cdca070612a0aa4b3c6914ab9ed602d1f456@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mlme.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 42e2c84ed2484..37163d84104fa 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2959,7 +2959,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, + if (tx) + ieee80211_flush_queues(local, sdata, false); + +- drv_mgd_complete_tx(sdata->local, sdata, &info); ++ if (tx || frame_buf) ++ drv_mgd_complete_tx(sdata->local, sdata, &info); + + /* clear AP addr only after building the needed mgmt frames */ + eth_zero_addr(sdata->deflink.u.mgd.bssid); +-- +2.39.5 + diff --git a/queue-6.6/wifi-mac80211-remove-misplaced-drv_mgd_complete_tx-c.patch b/queue-6.6/wifi-mac80211-remove-misplaced-drv_mgd_complete_tx-c.patch new file mode 100644 index 0000000000..9e9077337a --- /dev/null +++ b/queue-6.6/wifi-mac80211-remove-misplaced-drv_mgd_complete_tx-c.patch @@ -0,0 +1,41 @@ +From 2261f613578e42ac8c219a8dbfe0c7738e63a7ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 11:39:21 +0200 +Subject: wifi: mac80211: remove misplaced drv_mgd_complete_tx() call + +From: Johannes Berg + +[ Upstream commit f4995cdc4d02d0abc8e9fcccad5c71ce676c1e3f ] + +In the original commit 15fae3410f1d ("mac80211: notify driver on +mgd TX completion") I evidently made a mistake and placed the +call in the "associated" if, rather than the "assoc_data". Later +I noticed the missing call and placed it in commit c042600c17d8 +("wifi: mac80211: adding missing drv_mgd_complete_tx() call"), +but didn't remove the wrong one. Remove it now. + +Signed-off-by: Johannes Berg +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Miri Korenblit +Link: https://patch.msgid.link/20250205110958.6ed954179bbf.Id8ef8835b7e6da3bf913c76f77d201017dc8a3c9@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mlme.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 37163d84104fa..2c7e139efd532 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -7822,7 +7822,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, + ieee80211_report_disconnect(sdata, frame_buf, + sizeof(frame_buf), true, + req->reason_code, false); +- drv_mgd_complete_tx(sdata->local, sdata, &info); + return 0; + } + +-- +2.39.5 + diff --git a/queue-6.6/wifi-mt76-mt7996-revise-txs-size.patch b/queue-6.6/wifi-mt76-mt7996-revise-txs-size.patch new file mode 100644 index 0000000000..b956e41bbf --- /dev/null +++ b/queue-6.6/wifi-mt76-mt7996-revise-txs-size.patch @@ -0,0 +1,61 @@ +From fe7b8fbaa4ef36bb29ee86881b74f32b3fbf8eba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 11:36:38 +0100 +Subject: wifi: mt76: mt7996: revise TXS size + +From: Benjamin Lin + +[ Upstream commit 593c829b4326f7b3b15a69e97c9044ecbad3c319 ] + +Size of MPDU/PPDU TXS is 12 DWs. +In mt7996/mt7992, last 4 DWs are reserved, so TXS size was mistakenly +considered to be 8 DWs. However, in mt7990, 9th DW of TXS starts to be used. + +Signed-off-by: Benjamin Lin +Link: https://patch.msgid.link/20250311103646.43346-1-nbd@nbd.name +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h | 3 +++ + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 4 ++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +index 87bfa441a9374..4979012d5abfa 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +@@ -280,6 +280,9 @@ enum tx_mgnt_type { + #define MT_TXFREE_INFO_COUNT GENMASK(27, 24) + #define MT_TXFREE_INFO_STAT GENMASK(29, 28) + ++#define MT_TXS_HDR_SIZE 4 /* Unit: DW */ ++#define MT_TXS_SIZE 12 /* Unit: DW */ ++ + #define MT_TXS0_BW GENMASK(31, 29) + #define MT_TXS0_TID GENMASK(28, 26) + #define MT_TXS0_AMPDU BIT(25) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 73d46ec1181ae..35d9673ec0d8f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -1354,7 +1354,7 @@ bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len) + mt7996_mac_tx_free(dev, data, len); + return false; + case PKT_TYPE_TXS: +- for (rxd += 4; rxd + 8 <= end; rxd += 8) ++ for (rxd += MT_TXS_HDR_SIZE; rxd + MT_TXS_SIZE <= end; rxd += MT_TXS_SIZE) + mt7996_mac_add_txs(dev, rxd); + return false; + case PKT_TYPE_RX_FW_MONITOR: +@@ -1391,7 +1391,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, + mt7996_mcu_rx_event(dev, skb); + break; + case PKT_TYPE_TXS: +- for (rxd += 4; rxd + 8 <= end; rxd += 8) ++ for (rxd += MT_TXS_HDR_SIZE; rxd + MT_TXS_SIZE <= end; rxd += MT_TXS_SIZE) + mt7996_mac_add_txs(dev, rxd); + dev_kfree_skb(skb); + break; +-- +2.39.5 + diff --git a/queue-6.6/wifi-mt76-only-mark-tx-status-failed-frames-as-acked.patch b/queue-6.6/wifi-mt76-only-mark-tx-status-failed-frames-as-acked.patch new file mode 100644 index 0000000000..9ffd2ace11 --- /dev/null +++ b/queue-6.6/wifi-mt76-only-mark-tx-status-failed-frames-as-acked.patch @@ -0,0 +1,111 @@ +From e03df82096edb94b155e3bde2d697f0a767606f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Mar 2025 11:36:43 +0100 +Subject: wifi: mt76: only mark tx-status-failed frames as ACKed on mt76x0/2 + +From: Felix Fietkau + +[ Upstream commit 0c5a89ceddc1728a40cb3313948401dd70e3c649 ] + +The interrupt status polling is unreliable, which can cause status events +to get lost. On all newer chips, txs-timeout is an indication that the +packet was either never sent, or never acked. +Fixes issues with inactivity polling. + +Link: https://patch.msgid.link/20250311103646.43346-6-nbd@nbd.name +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + + drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 3 ++- + drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 3 ++- + drivers/net/wireless/mediatek/mt76/mt76x2/pci.c | 3 ++- + drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 3 ++- + drivers/net/wireless/mediatek/mt76/tx.c | 3 ++- + 6 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 8b620d4fed439..df0ea638370b5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -439,6 +439,7 @@ struct mt76_hw_cap { + #define MT_DRV_RX_DMA_HDR BIT(3) + #define MT_DRV_HW_MGMT_TXQ BIT(4) + #define MT_DRV_AMSDU_OFFLOAD BIT(5) ++#define MT_DRV_IGNORE_TXS_FAILED BIT(6) + + struct mt76_driver_ops { + u32 drv_flags; +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +index 9277ff38b7a22..57ae362dad50b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +@@ -152,7 +152,8 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) + static const struct mt76_driver_ops drv_ops = { + .txwi_size = sizeof(struct mt76x02_txwi), + .drv_flags = MT_DRV_TX_ALIGNED4_SKBS | +- MT_DRV_SW_RX_AIRTIME, ++ MT_DRV_SW_RX_AIRTIME | ++ MT_DRV_IGNORE_TXS_FAILED, + .survey_flags = SURVEY_INFO_TIME_TX, + .update_survey = mt76x02_update_channel, + .tx_prepare_skb = mt76x02_tx_prepare_skb, +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +index 0422c332354a1..520fd46227a7b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +@@ -210,7 +210,8 @@ static int mt76x0u_probe(struct usb_interface *usb_intf, + const struct usb_device_id *id) + { + static const struct mt76_driver_ops drv_ops = { +- .drv_flags = MT_DRV_SW_RX_AIRTIME, ++ .drv_flags = MT_DRV_SW_RX_AIRTIME | ++ MT_DRV_IGNORE_TXS_FAILED, + .survey_flags = SURVEY_INFO_TIME_TX, + .update_survey = mt76x02_update_channel, + .tx_prepare_skb = mt76x02u_tx_prepare_skb, +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +index df85ebc6e1df0..7e2475b3c278e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +@@ -22,7 +22,8 @@ mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id) + static const struct mt76_driver_ops drv_ops = { + .txwi_size = sizeof(struct mt76x02_txwi), + .drv_flags = MT_DRV_TX_ALIGNED4_SKBS | +- MT_DRV_SW_RX_AIRTIME, ++ MT_DRV_SW_RX_AIRTIME | ++ MT_DRV_IGNORE_TXS_FAILED, + .survey_flags = SURVEY_INFO_TIME_TX, + .update_survey = mt76x02_update_channel, + .tx_prepare_skb = mt76x02_tx_prepare_skb, +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +index d804309992196..70d3895762b4c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +@@ -29,7 +29,8 @@ static int mt76x2u_probe(struct usb_interface *intf, + const struct usb_device_id *id) + { + static const struct mt76_driver_ops drv_ops = { +- .drv_flags = MT_DRV_SW_RX_AIRTIME, ++ .drv_flags = MT_DRV_SW_RX_AIRTIME | ++ MT_DRV_IGNORE_TXS_FAILED, + .survey_flags = SURVEY_INFO_TIME_TX, + .update_survey = mt76x02_update_channel, + .tx_prepare_skb = mt76x02u_tx_prepare_skb, +diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c +index 1809b03292c3d..47cdccdbed6aa 100644 +--- a/drivers/net/wireless/mediatek/mt76/tx.c ++++ b/drivers/net/wireless/mediatek/mt76/tx.c +@@ -100,7 +100,8 @@ __mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, u8 flags, + return; + + /* Tx status can be unreliable. if it fails, mark the frame as ACKed */ +- if (flags & MT_TX_CB_TXS_FAILED) { ++ if (flags & MT_TX_CB_TXS_FAILED && ++ (dev->drv->drv_flags & MT_DRV_IGNORE_TXS_FAILED)) { + info->status.rates[0].count = 0; + info->status.rates[0].idx = -1; + info->flags |= IEEE80211_TX_STAT_ACK; +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtl8xxxu-retry-firmware-download-on-error.patch b/queue-6.6/wifi-rtl8xxxu-retry-firmware-download-on-error.patch new file mode 100644 index 0000000000..9d749e1f91 --- /dev/null +++ b/queue-6.6/wifi-rtl8xxxu-retry-firmware-download-on-error.patch @@ -0,0 +1,67 @@ +From bae595810dd3e7c0fcd96b794bd60adb12437ce6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Jan 2025 20:48:28 +0100 +Subject: wifi: rtl8xxxu: retry firmware download on error + +From: Soeren Moch + +[ Upstream commit 3d3e28feca7ac8c6cf2a390dbbe1f97e3feb7f36 ] + +Occasionally there is an EPROTO error during firmware download. +This error is converted to EAGAIN in the download function. +But nobody tries again and so device probe fails. + +Implement download retry to fix this. + +This error was observed (and fix tested) on a tbs2910 board [1] +with an embedded RTL8188EU (0bda:8179) device behind a USB hub. + +[1] arch/arm/boot/dts/nxp/imx/imx6q-tbs2910.dts + +Signed-off-by: Soeren Moch +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20250127194828.599379-1-smoch@web.de +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +index 6e47dde938909..05e77d2bda373 100644 +--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c ++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +@@ -900,9 +900,10 @@ rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len) + return len; + + write_error: +- dev_info(&udev->dev, +- "%s: Failed to write block at addr: %04x size: %04x\n", +- __func__, addr, blocksize); ++ if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE) ++ dev_info(&udev->dev, ++ "%s: Failed to write block at addr: %04x size: %04x\n", ++ __func__, addr, blocksize); + return -EAGAIN; + } + +@@ -4073,8 +4074,14 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw) + */ + rtl8xxxu_write16(priv, REG_TRXFF_BNDY + 2, fops->trxff_boundary); + +- ret = rtl8xxxu_download_firmware(priv); +- dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret); ++ for (int retry = 5; retry >= 0 ; retry--) { ++ ret = rtl8xxxu_download_firmware(priv); ++ dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret); ++ if (ret != -EAGAIN) ++ break; ++ if (retry) ++ dev_dbg(dev, "%s: retry firmware download\n", __func__); ++ } + if (ret) + goto exit; + ret = rtl8xxxu_start_firmware(priv); +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-don-t-use-static-local-variable-in-rtw882.patch b/queue-6.6/wifi-rtw88-don-t-use-static-local-variable-in-rtw882.patch new file mode 100644 index 0000000000..2e8c8e2126 --- /dev/null +++ b/queue-6.6/wifi-rtw88-don-t-use-static-local-variable-in-rtw882.patch @@ -0,0 +1,78 @@ +From 6ec50c7e59857c1a576045cb1adf16ed53d23b1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Jan 2025 16:03:11 +0200 +Subject: wifi: rtw88: Don't use static local variable in + rtw8822b_set_tx_power_index_by_rate + +From: Bitterblue Smith + +[ Upstream commit 00451eb3bec763f708e7e58326468c1e575e5a66 ] + +Some users want to plug two identical USB devices at the same time. +This static variable could theoretically cause them to use incorrect +TX power values. + +Move the variable to the caller and pass a pointer to it to +rtw8822b_set_tx_power_index_by_rate(). + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/8a60f581-0ab5-4d98-a97d-dd83b605008f@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +index 3017a9760da8d..99318a82b43f4 100644 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -975,11 +975,11 @@ static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, + } + + static void +-rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) ++rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, ++ u8 rs, u32 *phy_pwr_idx) + { + struct rtw_hal *hal = &rtwdev->hal; + static const u32 offset_txagc[2] = {0x1d00, 0x1d80}; +- static u32 phy_pwr_idx; + u8 rate, rate_idx, pwr_index, shift; + int j; + +@@ -987,12 +987,12 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + shift = rate & 0x3; +- phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); ++ *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); + if (shift == 0x3) { + rate_idx = rate & 0xfc; + rtw_write32(rtwdev, offset_txagc[path] + rate_idx, +- phy_pwr_idx); +- phy_pwr_idx = 0; ++ *phy_pwr_idx); ++ *phy_pwr_idx = 0; + } + } + } +@@ -1000,11 +1000,13 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) + static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev) + { + struct rtw_hal *hal = &rtwdev->hal; ++ u32 phy_pwr_idx = 0; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) +- rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs); ++ rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs, ++ &phy_pwr_idx); + } + } + +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-fix-__rtw_download_firmware-for-rtl8814au.patch b/queue-6.6/wifi-rtw88-fix-__rtw_download_firmware-for-rtl8814au.patch new file mode 100644 index 0000000000..4f1d989ad1 --- /dev/null +++ b/queue-6.6/wifi-rtw88-fix-__rtw_download_firmware-for-rtl8814au.patch @@ -0,0 +1,49 @@ +From e75921eeb952b8771ca5f7df7553d1ae6e85f841 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 20:36:56 +0200 +Subject: wifi: rtw88: Fix __rtw_download_firmware() for RTL8814AU + +From: Bitterblue Smith + +[ Upstream commit 8425f5c8f04dbcf11ade78f984a494fc0b90e7a0 ] + +Don't call ltecoex_read_reg() and ltecoex_reg_write() when the +ltecoex_addr member of struct rtw_chip_info is NULL. The RTL8814AU +doesn't have this feature. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/55b5641f-094e-4f94-9f79-ac053733f2cf@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/mac.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c +index 0c1c1ff31085c..929182424b8b8 100644 +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -783,7 +783,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, + if (!check_firmware_size(data, size)) + return -EINVAL; + +- if (!ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) ++ if (rtwdev->chip->ltecoex_addr && ++ !ltecoex_read_reg(rtwdev, 0x38, <ecoex_bckp)) + return -EBUSY; + + wlan_cpu_enable(rtwdev, false); +@@ -801,7 +802,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev, + + wlan_cpu_enable(rtwdev, true); + +- if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { ++ if (rtwdev->chip->ltecoex_addr && ++ !ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) { + ret = -EBUSY; + goto dlfw_fail; + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-fix-download_firmware_validate-for-rtl881.patch b/queue-6.6/wifi-rtw88-fix-download_firmware_validate-for-rtl881.patch new file mode 100644 index 0000000000..6c4039ac06 --- /dev/null +++ b/queue-6.6/wifi-rtw88-fix-download_firmware_validate-for-rtl881.patch @@ -0,0 +1,49 @@ +From 49dc708ab2239a5bf5a79fe2f0a0301373d8bde0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 20:37:36 +0200 +Subject: wifi: rtw88: Fix download_firmware_validate() for RTL8814AU + +From: Bitterblue Smith + +[ Upstream commit 9e8243025cc06abc975c876dffda052073207ab3 ] + +After the firmware is uploaded, download_firmware_validate() checks some +bits in REG_MCUFW_CTRL to see if everything went okay. The +RTL8814AU power on sequence sets bits 13 and 12 to 2, which this +function does not expect, so it thinks the firmware upload failed. + +Make download_firmware_validate() ignore bits 13 and 12. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/049d2887-22fc-47b7-9e59-62627cb525f8@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/reg.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h +index 7c6c11d50ff30..0e76bc07bddef 100644 +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -108,6 +108,7 @@ + #define BIT_SHIFT_ROM_PGE 16 + #define BIT_FW_INIT_RDY BIT(15) + #define BIT_FW_DW_RDY BIT(14) ++#define BIT_CPU_CLK_SEL (BIT(12) | BIT(13)) + #define BIT_RPWM_TOGGLE BIT(7) + #define BIT_RAM_DL_SEL BIT(7) /* legacy only */ + #define BIT_DMEM_CHKSUM_OK BIT(6) +@@ -125,7 +126,7 @@ + BIT_CHECK_SUM_OK) + #define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ + BIT_WINTINI_RDY | BIT_RAM_DL_SEL) +-#define FW_READY_MASK 0xffff ++#define FW_READY_MASK (0xffff & ~BIT_CPU_CLK_SEL) + + #define REG_MCU_TST_CFG 0x84 + #define VAL_FW_TRIGGER 0x1 +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-fix-rtw_desc_to_mcsrate-to-handle-mcs16-3.patch b/queue-6.6/wifi-rtw88-fix-rtw_desc_to_mcsrate-to-handle-mcs16-3.patch new file mode 100644 index 0000000000..ec959de657 --- /dev/null +++ b/queue-6.6/wifi-rtw88-fix-rtw_desc_to_mcsrate-to-handle-mcs16-3.patch @@ -0,0 +1,42 @@ +From 6002451f2d277842d261f8c9f0e18bbc190ce93f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 01:29:52 +0200 +Subject: wifi: rtw88: Fix rtw_desc_to_mcsrate() to handle MCS16-31 + +From: Bitterblue Smith + +[ Upstream commit 86d04f8f991a0509e318fe886d5a1cf795736c7d ] + +This function translates the rate number reported by the hardware into +something mac80211 can understand. It was ignoring the 3SS and 4SS HT +rates. Translate them too. + +Also set *nss to 0 for the HT rates, just to make sure it's +initialised. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/d0a5a86b-4869-47f6-a5a7-01c0f987cc7f@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/util.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c +index e222d3c01a77e..66819f6944055 100644 +--- a/drivers/net/wireless/realtek/rtw88/util.c ++++ b/drivers/net/wireless/realtek/rtw88/util.c +@@ -101,7 +101,8 @@ void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) + *nss = 4; + *mcs = rate - DESC_RATEVHT4SS_MCS0; + } else if (rate >= DESC_RATEMCS0 && +- rate <= DESC_RATEMCS15) { ++ rate <= DESC_RATEMCS31) { ++ *nss = 0; + *mcs = rate - DESC_RATEMCS0; + } + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-fix-rtw_init_ht_cap-for-rtl8814au.patch b/queue-6.6/wifi-rtw88-fix-rtw_init_ht_cap-for-rtl8814au.patch new file mode 100644 index 0000000000..f1ea944720 --- /dev/null +++ b/queue-6.6/wifi-rtw88-fix-rtw_init_ht_cap-for-rtl8814au.patch @@ -0,0 +1,59 @@ +From d44b11b93f983ba992a1cb2a3b3ae1ea7d20f590 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 01:30:22 +0200 +Subject: wifi: rtw88: Fix rtw_init_ht_cap() for RTL8814AU + +From: Bitterblue Smith + +[ Upstream commit c7eea1ba05ca5b0dbf77a27cf2e1e6e2fb3c0043 ] + +Set the RX mask and the highest RX rate according to the number of +spatial streams the chip can receive. For RTL8814AU that is 3. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/4e786f50-ed1c-4387-8b28-e6ff00e35e81@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/main.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index 557526e0eb7f3..0d0b5123b5fe2 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1544,6 +1544,7 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_efuse *efuse = &rtwdev->efuse; ++ int i; + + ht_cap->ht_supported = true; + ht_cap->cap = 0; +@@ -1563,17 +1564,11 @@ static void rtw_init_ht_cap(struct rtw_dev *rtwdev, + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + ht_cap->ampdu_density = chip->ampdu_density; + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; +- if (efuse->hw_cap.nss > 1) { +- ht_cap->mcs.rx_mask[0] = 0xFF; +- ht_cap->mcs.rx_mask[1] = 0xFF; +- ht_cap->mcs.rx_mask[4] = 0x01; +- ht_cap->mcs.rx_highest = cpu_to_le16(300); +- } else { +- ht_cap->mcs.rx_mask[0] = 0xFF; +- ht_cap->mcs.rx_mask[1] = 0x00; +- ht_cap->mcs.rx_mask[4] = 0x01; +- ht_cap->mcs.rx_highest = cpu_to_le16(150); +- } ++ ++ for (i = 0; i < efuse->hw_cap.nss; i++) ++ ht_cap->mcs.rx_mask[i] = 0xFF; ++ ht_cap->mcs.rx_mask[4] = 0x01; ++ ht_cap->mcs.rx_highest = cpu_to_le16(150 * efuse->hw_cap.nss); + } + + static void rtw_init_vht_cap(struct rtw_dev *rtwdev, +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-fix-rtw_init_vht_cap-for-rtl8814au.patch b/queue-6.6/wifi-rtw88-fix-rtw_init_vht_cap-for-rtl8814au.patch new file mode 100644 index 0000000000..7244e2e329 --- /dev/null +++ b/queue-6.6/wifi-rtw88-fix-rtw_init_vht_cap-for-rtl8814au.patch @@ -0,0 +1,68 @@ +From 52fe8c15ba31d148a7787506b35923b68cb9a5f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Feb 2025 01:30:48 +0200 +Subject: wifi: rtw88: Fix rtw_init_vht_cap() for RTL8814AU + +From: Bitterblue Smith + +[ Upstream commit 6be7544d19fcfcb729495e793bc6181f85bb8949 ] + +Set the MCS maps and the highest rates according to the number of +spatial streams the chip has. For RTL8814AU that is 3. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/e86aa009-b5bf-4b3a-8112-ea5e3cd49465@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/main.c | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c +index b90ea6c88b15d..557526e0eb7f3 100644 +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1580,8 +1580,9 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev, + struct ieee80211_sta_vht_cap *vht_cap) + { + struct rtw_efuse *efuse = &rtwdev->efuse; +- u16 mcs_map; ++ u16 mcs_map = 0; + __le16 highest; ++ int i; + + if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE && + efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT) +@@ -1604,21 +1605,15 @@ static void rtw_init_vht_cap(struct rtw_dev *rtwdev, + if (rtw_chip_has_rx_ldpc(rtwdev)) + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + +- mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | +- IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; +- if (efuse->hw_cap.nss > 1) { +- highest = cpu_to_le16(780); +- mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2; +- } else { +- highest = cpu_to_le16(390); +- mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2; ++ for (i = 0; i < 8; i++) { ++ if (i < efuse->hw_cap.nss) ++ mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); + } + ++ highest = cpu_to_le16(390 * efuse->hw_cap.nss); ++ + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); + vht_cap->vht_mcs.rx_highest = highest; +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw89-add-wiphy_lock-to-work-that-isn-t-held-wi.patch b/queue-6.6/wifi-rtw89-add-wiphy_lock-to-work-that-isn-t-held-wi.patch new file mode 100644 index 0000000000..be61c2fb38 --- /dev/null +++ b/queue-6.6/wifi-rtw89-add-wiphy_lock-to-work-that-isn-t-held-wi.patch @@ -0,0 +1,72 @@ +From 872006447684e54ceb55893158412710bcc1df26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Jan 2025 14:03:01 +0800 +Subject: wifi: rtw89: add wiphy_lock() to work that isn't held wiphy_lock() + yet + +From: Ping-Ke Shih + +[ Upstream commit ebfc9199df05d37b67f4d1b7ee997193f3d2e7c8 ] + +To ensure where are protected by driver mutex can also be protected by +wiphy_lock(), so afterward we can remove driver mutex safely. + +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20250122060310.31976-2-pkshih@realtek.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/regd.c | 2 ++ + drivers/net/wireless/realtek/rtw89/ser.c | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c +index 9e2328db18656..91f0895d9f540 100644 +--- a/drivers/net/wireless/realtek/rtw89/regd.c ++++ b/drivers/net/wireless/realtek/rtw89/regd.c +@@ -451,6 +451,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtw89_dev *rtwdev = hw->priv; + ++ wiphy_lock(wiphy); + mutex_lock(&rtwdev->mutex); + rtw89_leave_ps_mode(rtwdev); + +@@ -468,6 +469,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request + + exit: + mutex_unlock(&rtwdev->mutex); ++ wiphy_unlock(wiphy); + } + + static void __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev) +diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c +index 01b17b8f4ff9d..45165cf3e824e 100644 +--- a/drivers/net/wireless/realtek/rtw89/ser.c ++++ b/drivers/net/wireless/realtek/rtw89/ser.c +@@ -156,9 +156,11 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt) + rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n", + ser_st_name(ser), ser_ev_name(ser, evt)); + ++ wiphy_lock(rtwdev->hw->wiphy); + mutex_lock(&rtwdev->mutex); + rtw89_leave_lps(rtwdev); + mutex_unlock(&rtwdev->mutex); ++ wiphy_unlock(rtwdev->hw->wiphy); + + ser->st_tbl[ser->state].st_func(ser, evt); + } +@@ -676,9 +678,11 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt) + + switch (evt) { + case SER_EV_STATE_IN: ++ wiphy_lock(rtwdev->hw->wiphy); + mutex_lock(&rtwdev->mutex); + ser_l2_reset_st_pre_hdl(ser); + mutex_unlock(&rtwdev->mutex); ++ wiphy_unlock(rtwdev->hw->wiphy); + + ieee80211_restart_hw(rtwdev->hw); + ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT); +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw89-fw-propagate-error-code-from-rtw89_h2c_tx.patch b/queue-6.6/wifi-rtw89-fw-propagate-error-code-from-rtw89_h2c_tx.patch new file mode 100644 index 0000000000..200557eb74 --- /dev/null +++ b/queue-6.6/wifi-rtw89-fw-propagate-error-code-from-rtw89_h2c_tx.patch @@ -0,0 +1,42 @@ +From d8e5511d8c20c8f6290f274eb58c3062ae586886 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Feb 2025 14:43:06 +0800 +Subject: wifi: rtw89: fw: propagate error code from rtw89_h2c_tx() + +From: Ping-Ke Shih + +[ Upstream commit 56e1acaa0f80620b8e2c3410db35b4b975782b0a ] + +The error code should be propagated to callers during downloading firmware +header and body. Remove unnecessary assignment of -1. + +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20250217064308.43559-4-pkshih@realtek.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/fw.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c +index a8e2efae6e526..89b0a7970508e 100644 +--- a/drivers/net/wireless/realtek/rtw89/fw.c ++++ b/drivers/net/wireless/realtek/rtw89/fw.c +@@ -755,7 +755,6 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 l + ret = rtw89_h2c_tx(rtwdev, skb, false); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); +- ret = -1; + goto fail; + } + +@@ -816,7 +815,6 @@ static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, + ret = rtw89_h2c_tx(rtwdev, skb, true); + if (ret) { + rtw89_err(rtwdev, "failed to send h2c\n"); +- ret = -1; + goto fail; + } + +-- +2.39.5 + diff --git a/queue-6.6/x86-bugs-make-spectre-user-default-depend-on-mitigat.patch b/queue-6.6/x86-bugs-make-spectre-user-default-depend-on-mitigat.patch new file mode 100644 index 0000000000..7f486bc7d6 --- /dev/null +++ b/queue-6.6/x86-bugs-make-spectre-user-default-depend-on-mitigat.patch @@ -0,0 +1,96 @@ +From 5fd83d32d8b2cfba9a9677b7aed11adf9424f126 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Oct 2024 04:06:17 -0700 +Subject: x86/bugs: Make spectre user default depend on MITIGATION_SPECTRE_V2 + +From: Breno Leitao + +[ Upstream commit 98fdaeb296f51ef08e727a7cc72e5b5c864c4f4d ] + +Change the default value of spectre v2 in user mode to respect the +CONFIG_MITIGATION_SPECTRE_V2 config option. + +Currently, user mode spectre v2 is set to auto +(SPECTRE_V2_USER_CMD_AUTO) by default, even if +CONFIG_MITIGATION_SPECTRE_V2 is disabled. + +Set the spectre_v2 value to auto (SPECTRE_V2_USER_CMD_AUTO) if the +Spectre v2 config (CONFIG_MITIGATION_SPECTRE_V2) is enabled, otherwise +set the value to none (SPECTRE_V2_USER_CMD_NONE). + +Important to say the command line argument "spectre_v2_user" overwrites +the default value in both cases. + +When CONFIG_MITIGATION_SPECTRE_V2 is not set, users have the flexibility +to opt-in for specific mitigations independently. In this scenario, +setting spectre_v2= will not enable spectre_v2_user=, and command line +options spectre_v2_user and spectre_v2 are independent when +CONFIG_MITIGATION_SPECTRE_V2=n. + +Signed-off-by: Breno Leitao +Signed-off-by: Ingo Molnar +Reviewed-by: Pawan Gupta +Acked-by: Josh Poimboeuf +Cc: Peter Zijlstra +Cc: David Kaplan +Link: https://lore.kernel.org/r/20241031-x86_bugs_last_v2-v2-2-b7ff1dab840e@debian.org +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/kernel-parameters.txt | 2 ++ + arch/x86/kernel/cpu/bugs.c | 10 +++++++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index f95734ceb82b8..315a817e33804 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -5978,6 +5978,8 @@ + + Selecting 'on' will also enable the mitigation + against user space to user space task attacks. ++ Selecting specific mitigation does not force enable ++ user mitigations. + + Selecting 'off' will disable both the kernel and + the user space protections. +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c +index 07b45bbf6348d..e9c4bcb38f458 100644 +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -1442,9 +1442,13 @@ static __ro_after_init enum spectre_v2_mitigation_cmd spectre_v2_cmd; + static enum spectre_v2_user_cmd __init + spectre_v2_parse_user_cmdline(void) + { ++ enum spectre_v2_user_cmd mode; + char arg[20]; + int ret, i; + ++ mode = IS_ENABLED(CONFIG_MITIGATION_SPECTRE_V2) ? ++ SPECTRE_V2_USER_CMD_AUTO : SPECTRE_V2_USER_CMD_NONE; ++ + switch (spectre_v2_cmd) { + case SPECTRE_V2_CMD_NONE: + return SPECTRE_V2_USER_CMD_NONE; +@@ -1457,7 +1461,7 @@ spectre_v2_parse_user_cmdline(void) + ret = cmdline_find_option(boot_command_line, "spectre_v2_user", + arg, sizeof(arg)); + if (ret < 0) +- return SPECTRE_V2_USER_CMD_AUTO; ++ return mode; + + for (i = 0; i < ARRAY_SIZE(v2_user_options); i++) { + if (match_option(arg, ret, v2_user_options[i].option)) { +@@ -1467,8 +1471,8 @@ spectre_v2_parse_user_cmdline(void) + } + } + +- pr_err("Unknown user space protection option (%s). Switching to AUTO select\n", arg); +- return SPECTRE_V2_USER_CMD_AUTO; ++ pr_err("Unknown user space protection option (%s). Switching to default\n", arg); ++ return mode; + } + + static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +-- +2.39.5 + diff --git a/queue-6.6/x86-build-fix-broken-copy-command-in-genimage.sh-whe.patch b/queue-6.6/x86-build-fix-broken-copy-command-in-genimage.sh-whe.patch new file mode 100644 index 0000000000..5cbbf73206 --- /dev/null +++ b/queue-6.6/x86-build-fix-broken-copy-command-in-genimage.sh-whe.patch @@ -0,0 +1,58 @@ +From 074035905c7ae117520e1b595a582c3755dd6103 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 12:05:00 +0000 +Subject: x86/build: Fix broken copy command in genimage.sh when making + isoimage + +From: Nir Lichtman + +[ Upstream commit e451630226bd09dc730eedb4e32cab1cc7155ae8 ] + +Problem: Currently when running the "make isoimage" command there is an +error related to wrong parameters passed to the cp command: + + "cp: missing destination file operand after 'arch/x86/boot/isoimage/'" + +This is caused because FDINITRDS is an empty array. + +Solution: Check if FDINITRDS is empty before executing the "cp" command, +similar to how it is done in the case of hdimage. + +Signed-off-by: Nir Lichtman +Signed-off-by: Ingo Molnar +Cc: "H. Peter Anvin" +Cc: Ard Biesheuvel +Cc: Masahiro Yamada +Cc: Michal Marek +Link: https://lore.kernel.org/r/20250110120500.GA923218@lichtman.org +Signed-off-by: Sasha Levin +--- + arch/x86/boot/genimage.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/boot/genimage.sh b/arch/x86/boot/genimage.sh +index c9299aeb7333e..3882ead513f74 100644 +--- a/arch/x86/boot/genimage.sh ++++ b/arch/x86/boot/genimage.sh +@@ -22,6 +22,7 @@ + # This script requires: + # bash + # syslinux ++# genisoimage + # mtools (for fdimage* and hdimage) + # edk2/OVMF (for hdimage) + # +@@ -251,7 +252,9 @@ geniso() { + cp "$isolinux" "$ldlinux" "$tmp_dir" + cp "$FBZIMAGE" "$tmp_dir"/linux + echo default linux "$KCMDLINE" > "$tmp_dir"/isolinux.cfg +- cp "${FDINITRDS[@]}" "$tmp_dir"/ ++ if [ ${#FDINITRDS[@]} -gt 0 ]; then ++ cp "${FDINITRDS[@]}" "$tmp_dir"/ ++ fi + genisoimage -J -r -appid 'LINUX_BOOT' -input-charset=utf-8 \ + -quiet -o "$FIMAGE" -b isolinux.bin \ + -c boot.cat -no-emul-boot -boot-load-size 4 \ +-- +2.39.5 + diff --git a/queue-6.6/x86-kaslr-reduce-kaslr-entropy-on-most-x86-systems.patch b/queue-6.6/x86-kaslr-reduce-kaslr-entropy-on-most-x86-systems.patch new file mode 100644 index 0000000000..632fb2bb07 --- /dev/null +++ b/queue-6.6/x86-kaslr-reduce-kaslr-entropy-on-most-x86-systems.patch @@ -0,0 +1,88 @@ +From b4ed5530fed48ad7e9a27e63b5010ff602efb8c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 10:42:34 +1100 +Subject: x86/kaslr: Reduce KASLR entropy on most x86 systems + +From: Balbir Singh + +[ Upstream commit 7ffb791423c7c518269a9aad35039ef824a40adb ] + +When CONFIG_PCI_P2PDMA=y (which is basically enabled on all +large x86 distros), it maps the PFN's via a ZONE_DEVICE +mapping using devm_memremap_pages(). The mapped virtual +address range corresponds to the pci_resource_start() +of the BAR address and size corresponding to the BAR length. + +When KASLR is enabled, the direct map range of the kernel is +reduced to the size of physical memory plus additional padding. +If the BAR address is beyond this limit, PCI peer to peer DMA +mappings fail. + +Fix this by not shrinking the size of the direct map when +CONFIG_PCI_P2PDMA=y. + +This reduces the total available entropy, but it's better than +the current work around of having to disable KASLR completely. + +[ mingo: Clarified the changelog to point out the broad impact ... ] + +Signed-off-by: Balbir Singh +Signed-off-by: Ingo Molnar +Reviewed-by: Kees Cook +Acked-by: Bjorn Helgaas # drivers/pci/Kconfig +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Andy Lutomirski +Link: https://lore.kernel.org/lkml/20250206023201.1481957-1-balbirs@nvidia.com/ +Link: https://lore.kernel.org/r/20250206234234.1912585-1-balbirs@nvidia.com +-- + arch/x86/mm/kaslr.c | 10 ++++++++-- + drivers/pci/Kconfig | 6 ++++++ + 2 files changed, 14 insertions(+), 2 deletions(-) +Signed-off-by: Sasha Levin +--- + arch/x86/mm/kaslr.c | 10 ++++++++-- + drivers/pci/Kconfig | 6 ++++++ + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c +index 230f1dee4f095..e0b0ec0f82457 100644 +--- a/arch/x86/mm/kaslr.c ++++ b/arch/x86/mm/kaslr.c +@@ -109,8 +109,14 @@ void __init kernel_randomize_memory(void) + memory_tb = DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) + + CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING; + +- /* Adapt physical memory region size based on available memory */ +- if (memory_tb < kaslr_regions[0].size_tb) ++ /* ++ * Adapt physical memory region size based on available memory, ++ * except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the ++ * device BAR space assuming the direct map space is large enough ++ * for creating a ZONE_DEVICE mapping in the direct map corresponding ++ * to the physical BAR address. ++ */ ++ if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb)) + kaslr_regions[0].size_tb = memory_tb; + + /* +diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig +index e9ae66cc4189b..a3927daebeb02 100644 +--- a/drivers/pci/Kconfig ++++ b/drivers/pci/Kconfig +@@ -180,6 +180,12 @@ config PCI_P2PDMA + P2P DMA transactions must be between devices behind the same root + port. + ++ Enabling this option will reduce the entropy of x86 KASLR memory ++ regions. For example - on a 46 bit system, the entropy goes down ++ from 16 bits to 15 bits. The actual reduction in entropy depends ++ on the physical address bits, on processor features, kernel config ++ (5 level page table) and physical memory present on the system. ++ + If unsure, say N. + + config PCI_LABEL +-- +2.39.5 + diff --git a/queue-6.6/x86-mm-check-return-value-from-memblock_phys_alloc_r.patch b/queue-6.6/x86-mm-check-return-value-from-memblock_phys_alloc_r.patch new file mode 100644 index 0000000000..79d41cad90 --- /dev/null +++ b/queue-6.6/x86-mm-check-return-value-from-memblock_phys_alloc_r.patch @@ -0,0 +1,53 @@ +From dae1c69c978d403459459cfae9c1efe37d925861 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Nov 2024 20:36:59 +0300 +Subject: x86/mm: Check return value from memblock_phys_alloc_range() + +From: Philip Redkin + +[ Upstream commit 631ca8909fd5c62b9fda9edda93924311a78a9c4 ] + +At least with CONFIG_PHYSICAL_START=0x100000, if there is < 4 MiB of +contiguous free memory available at this point, the kernel will crash +and burn because memblock_phys_alloc_range() returns 0 on failure, +which leads memblock_phys_free() to throw the first 4 MiB of physical +memory to the wolves. + +At a minimum it should fail gracefully with a meaningful diagnostic, +but in fact everything seems to work fine without the weird reserve +allocation. + +Signed-off-by: Philip Redkin +Signed-off-by: Ingo Molnar +Cc: Dave Hansen +Cc: Rik van Riel +Cc: "H. Peter Anvin" +Link: https://lore.kernel.org/r/94b3e98f-96a7-3560-1f76-349eb95ccf7f@rarity.fan +Signed-off-by: Sasha Levin +--- + arch/x86/mm/init.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 71d29dd7ad761..6cbb5974e4f9e 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -644,8 +644,13 @@ static void __init memory_map_top_down(unsigned long map_start, + */ + addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE, map_start, + map_end); +- memblock_phys_free(addr, PMD_SIZE); +- real_end = addr + PMD_SIZE; ++ if (!addr) { ++ pr_warn("Failed to release memory for alloc_low_pages()"); ++ real_end = max(map_start, ALIGN_DOWN(map_end, PMD_SIZE)); ++ } else { ++ memblock_phys_free(addr, PMD_SIZE); ++ real_end = addr + PMD_SIZE; ++ } + + /* step_size need to be small so pgt_buf from BRK could cover it */ + step_size = PMD_SIZE; +-- +2.39.5 + diff --git a/queue-6.6/x86-nmi-add-an-emergency-handler-in-nmi_desc-use-it-.patch b/queue-6.6/x86-nmi-add-an-emergency-handler-in-nmi_desc-use-it-.patch new file mode 100644 index 0000000000..0982c3ddac --- /dev/null +++ b/queue-6.6/x86-nmi-add-an-emergency-handler-in-nmi_desc-use-it-.patch @@ -0,0 +1,173 @@ +From 3076c77ed2bc2436d9163c75ff9a33cc6e0cd396 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 14:18:44 -0500 +Subject: x86/nmi: Add an emergency handler in nmi_desc & use it in + nmi_shootdown_cpus() + +From: Waiman Long + +[ Upstream commit fe37c699ae3eed6e02ee55fbf5cb9ceb7fcfd76c ] + +Depending on the type of panics, it was found that the +__register_nmi_handler() function can be called in NMI context from +nmi_shootdown_cpus() leading to a lockdep splat: + + WARNING: inconsistent lock state + inconsistent {INITIAL USE} -> {IN-NMI} usage. + + lock(&nmi_desc[0].lock); + + lock(&nmi_desc[0].lock); + + Call Trace: + _raw_spin_lock_irqsave + __register_nmi_handler + nmi_shootdown_cpus + kdump_nmi_shootdown_cpus + native_machine_crash_shutdown + __crash_kexec + +In this particular case, the following panic message was printed before: + + Kernel panic - not syncing: Fatal hardware error! + +This message seemed to be given out from __ghes_panic() running in +NMI context. + +The __register_nmi_handler() function which takes the nmi_desc lock +with irq disabled shouldn't be called from NMI context as this can +lead to deadlock. + +The nmi_shootdown_cpus() function can only be invoked once. After the +first invocation, all other CPUs should be stuck in the newly added +crash_nmi_callback() and cannot respond to a second NMI. + +Fix it by adding a new emergency NMI handler to the nmi_desc +structure and provide a new set_emergency_nmi_handler() helper to set +crash_nmi_callback() in any context. The new emergency handler will +preempt other handlers in the linked list. That will eliminate the need +to take any lock and serve the panic in NMI use case. + +Signed-off-by: Waiman Long +Signed-off-by: Ingo Molnar +Acked-by: Rik van Riel +Cc: Thomas Gleixner +Link: https://lore.kernel.org/r/20250206191844.131700-1-longman@redhat.com +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/nmi.h | 2 ++ + arch/x86/kernel/nmi.c | 42 ++++++++++++++++++++++++++++++++++++++ + arch/x86/kernel/reboot.c | 10 +++------ + 3 files changed, 47 insertions(+), 7 deletions(-) + +diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h +index 5c5f1e56c4048..6f3d145670a95 100644 +--- a/arch/x86/include/asm/nmi.h ++++ b/arch/x86/include/asm/nmi.h +@@ -59,6 +59,8 @@ int __register_nmi_handler(unsigned int, struct nmiaction *); + + void unregister_nmi_handler(unsigned int, const char *); + ++void set_emergency_nmi_handler(unsigned int type, nmi_handler_t handler); ++ + void stop_nmi(void); + void restart_nmi(void); + void local_touch_nmi(void); +diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c +index 6da2cfa23c293..35fd5f1444fdb 100644 +--- a/arch/x86/kernel/nmi.c ++++ b/arch/x86/kernel/nmi.c +@@ -39,8 +39,12 @@ + #define CREATE_TRACE_POINTS + #include + ++/* ++ * An emergency handler can be set in any context including NMI ++ */ + struct nmi_desc { + raw_spinlock_t lock; ++ nmi_handler_t emerg_handler; + struct list_head head; + }; + +@@ -131,9 +135,22 @@ static void nmi_check_duration(struct nmiaction *action, u64 duration) + static int nmi_handle(unsigned int type, struct pt_regs *regs) + { + struct nmi_desc *desc = nmi_to_desc(type); ++ nmi_handler_t ehandler; + struct nmiaction *a; + int handled=0; + ++ /* ++ * Call the emergency handler, if set ++ * ++ * In the case of crash_nmi_callback() emergency handler, it will ++ * return in the case of the crashing CPU to enable it to complete ++ * other necessary crashing actions ASAP. Other handlers in the ++ * linked list won't need to be run. ++ */ ++ ehandler = desc->emerg_handler; ++ if (ehandler) ++ return ehandler(type, regs); ++ + rcu_read_lock(); + + /* +@@ -223,6 +240,31 @@ void unregister_nmi_handler(unsigned int type, const char *name) + } + EXPORT_SYMBOL_GPL(unregister_nmi_handler); + ++/** ++ * set_emergency_nmi_handler - Set emergency handler ++ * @type: NMI type ++ * @handler: the emergency handler to be stored ++ * ++ * Set an emergency NMI handler which, if set, will preempt all the other ++ * handlers in the linked list. If a NULL handler is passed in, it will clear ++ * it. It is expected that concurrent calls to this function will not happen ++ * or the system is screwed beyond repair. ++ */ ++void set_emergency_nmi_handler(unsigned int type, nmi_handler_t handler) ++{ ++ struct nmi_desc *desc = nmi_to_desc(type); ++ ++ if (WARN_ON_ONCE(desc->emerg_handler == handler)) ++ return; ++ desc->emerg_handler = handler; ++ ++ /* ++ * Ensure the emergency handler is visible to other CPUs before ++ * function return ++ */ ++ smp_wmb(); ++} ++ + static void + pci_serr_error(unsigned char reason, struct pt_regs *regs) + { +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 830425e6d38e2..456e61070a730 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -908,15 +908,11 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback) + shootdown_callback = callback; + + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); +- /* Would it be better to replace the trap vector here? */ +- if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback, +- NMI_FLAG_FIRST, "crash")) +- return; /* Return what? */ ++ + /* +- * Ensure the new callback function is set before sending +- * out the NMI ++ * Set emergency handler to preempt other handlers. + */ +- wmb(); ++ set_emergency_nmi_handler(NMI_LOCAL, crash_nmi_callback); + + apic_send_IPI_allbutself(NMI_VECTOR); + +-- +2.39.5 + diff --git a/queue-6.6/x86-stackprotector-64-only-export-__ref_stack_chk_gu.patch b/queue-6.6/x86-stackprotector-64-only-export-__ref_stack_chk_gu.patch new file mode 100644 index 0000000000..300794189e --- /dev/null +++ b/queue-6.6/x86-stackprotector-64-only-export-__ref_stack_chk_gu.patch @@ -0,0 +1,45 @@ +From 4691ab8a8baaf9090349b22cc371b3d13f2fa897 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Mar 2025 12:48:49 +0100 +Subject: x86/stackprotector/64: Only export __ref_stack_chk_guard on + CONFIG_SMP +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ingo Molnar + +[ Upstream commit 91d5451d97ce35cbd510277fa3b7abf9caa4e34d ] + +The __ref_stack_chk_guard symbol doesn't exist on UP: + + :4:15: error: ‘__ref_stack_chk_guard’ undeclared here (not in a function) + +Fix the #ifdef around the entry.S export. + +Signed-off-by: Ingo Molnar +Cc: Brian Gerst +Cc: Ard Biesheuvel +Cc: Uros Bizjak +Link: https://lore.kernel.org/r/20250123190747.745588-8-brgerst@gmail.com +Signed-off-by: Sasha Levin +--- + arch/x86/entry/entry.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S +index 78fd2442b49dc..ad292c0d971a3 100644 +--- a/arch/x86/entry/entry.S ++++ b/arch/x86/entry/entry.S +@@ -59,7 +59,7 @@ EXPORT_SYMBOL_GPL(mds_verw_sel); + * entirely in the C code, and use an alias emitted by the linker script + * instead. + */ +-#ifdef CONFIG_STACKPROTECTOR ++#if defined(CONFIG_STACKPROTECTOR) && defined(CONFIG_SMP) + EXPORT_SYMBOL(__ref_stack_chk_guard); + #endif + #endif +-- +2.39.5 + diff --git a/queue-6.6/x86-traps-cleanup-and-robustify-decode_bug.patch b/queue-6.6/x86-traps-cleanup-and-robustify-decode_bug.patch new file mode 100644 index 0000000000..ea548fb3e3 --- /dev/null +++ b/queue-6.6/x86-traps-cleanup-and-robustify-decode_bug.patch @@ -0,0 +1,192 @@ +From 0f50ae153c517be4b17cab11dd6571aa19725555 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:15:36 +0100 +Subject: x86/traps: Cleanup and robustify decode_bug() + +From: Peter Zijlstra + +[ Upstream commit c20ad96c9a8f0aeaf4e4057730a22de2657ad0c2 ] + +Notably, don't attempt to decode an immediate when MOD == 3. + +Additionally have it return the instruction length, such that WARN +like bugs can more reliably skip to the correct instruction. + +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Sami Tolvanen +Link: https://lore.kernel.org/r/20250207122546.721120726@infradead.org +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/bug.h | 5 ++- + arch/x86/include/asm/ibt.h | 4 +- + arch/x86/kernel/traps.c | 82 ++++++++++++++++++++++++++++---------- + 3 files changed, 65 insertions(+), 26 deletions(-) + +diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h +index 806649c7f23dc..9a0f29be1a9ea 100644 +--- a/arch/x86/include/asm/bug.h ++++ b/arch/x86/include/asm/bug.h +@@ -22,8 +22,9 @@ + #define SECOND_BYTE_OPCODE_UD2 0x0b + + #define BUG_NONE 0xffff +-#define BUG_UD1 0xfffe +-#define BUG_UD2 0xfffd ++#define BUG_UD2 0xfffe ++#define BUG_UD1 0xfffd ++#define BUG_UD1_UBSAN 0xfffc + + #ifdef CONFIG_GENERIC_BUG + +diff --git a/arch/x86/include/asm/ibt.h b/arch/x86/include/asm/ibt.h +index 1e59581d500ca..b778ae6e67ee8 100644 +--- a/arch/x86/include/asm/ibt.h ++++ b/arch/x86/include/asm/ibt.h +@@ -41,7 +41,7 @@ + _ASM_PTR fname "\n\t" \ + ".popsection\n\t" + +-static inline __attribute_const__ u32 gen_endbr(void) ++static __always_inline __attribute_const__ u32 gen_endbr(void) + { + u32 endbr; + +@@ -56,7 +56,7 @@ static inline __attribute_const__ u32 gen_endbr(void) + return endbr; + } + +-static inline __attribute_const__ u32 gen_endbr_poison(void) ++static __always_inline __attribute_const__ u32 gen_endbr_poison(void) + { + /* + * 4 byte NOP that isn't NOP4 (in fact it is OSP NOP3), such that it +diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c +index d8d9bc5a9b328..8718d58dd0fbe 100644 +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -92,10 +92,17 @@ __always_inline int is_valid_bugaddr(unsigned long addr) + + /* + * Check for UD1 or UD2, accounting for Address Size Override Prefixes. +- * If it's a UD1, get the ModRM byte to pass along to UBSan. ++ * If it's a UD1, further decode to determine its use: ++ * ++ * UBSan{0}: 67 0f b9 00 ud1 (%eax),%eax ++ * UBSan{10}: 67 0f b9 40 10 ud1 0x10(%eax),%eax ++ * static_call: 0f b9 cc ud1 %esp,%ecx ++ * ++ * Notably UBSAN uses EAX, static_call uses ECX. + */ +-__always_inline int decode_bug(unsigned long addr, u32 *imm) ++__always_inline int decode_bug(unsigned long addr, s32 *imm, int *len) + { ++ unsigned long start = addr; + u8 v; + + if (addr < TASK_SIZE_MAX) +@@ -108,24 +115,42 @@ __always_inline int decode_bug(unsigned long addr, u32 *imm) + return BUG_NONE; + + v = *(u8 *)(addr++); +- if (v == SECOND_BYTE_OPCODE_UD2) ++ if (v == SECOND_BYTE_OPCODE_UD2) { ++ *len = addr - start; + return BUG_UD2; ++ } + +- if (!IS_ENABLED(CONFIG_UBSAN_TRAP) || v != SECOND_BYTE_OPCODE_UD1) ++ if (v != SECOND_BYTE_OPCODE_UD1) + return BUG_NONE; + +- /* Retrieve the immediate (type value) for the UBSAN UD1 */ +- v = *(u8 *)(addr++); +- if (X86_MODRM_RM(v) == 4) +- addr++; +- + *imm = 0; +- if (X86_MODRM_MOD(v) == 1) +- *imm = *(u8 *)addr; +- else if (X86_MODRM_MOD(v) == 2) +- *imm = *(u32 *)addr; +- else +- WARN_ONCE(1, "Unexpected MODRM_MOD: %u\n", X86_MODRM_MOD(v)); ++ v = *(u8 *)(addr++); /* ModRM */ ++ ++ if (X86_MODRM_MOD(v) != 3 && X86_MODRM_RM(v) == 4) ++ addr++; /* SIB */ ++ ++ /* Decode immediate, if present */ ++ switch (X86_MODRM_MOD(v)) { ++ case 0: if (X86_MODRM_RM(v) == 5) ++ addr += 4; /* RIP + disp32 */ ++ break; ++ ++ case 1: *imm = *(s8 *)addr; ++ addr += 1; ++ break; ++ ++ case 2: *imm = *(s32 *)addr; ++ addr += 4; ++ break; ++ ++ case 3: break; ++ } ++ ++ /* record instruction length */ ++ *len = addr - start; ++ ++ if (X86_MODRM_REG(v) == 0) /* EAX */ ++ return BUG_UD1_UBSAN; + + return BUG_UD1; + } +@@ -256,10 +281,10 @@ static inline void handle_invalid_op(struct pt_regs *regs) + static noinstr bool handle_bug(struct pt_regs *regs) + { + bool handled = false; +- int ud_type; +- u32 imm; ++ int ud_type, ud_len; ++ s32 ud_imm; + +- ud_type = decode_bug(regs->ip, &imm); ++ ud_type = decode_bug(regs->ip, &ud_imm, &ud_len); + if (ud_type == BUG_NONE) + return handled; + +@@ -279,15 +304,28 @@ static noinstr bool handle_bug(struct pt_regs *regs) + */ + if (regs->flags & X86_EFLAGS_IF) + raw_local_irq_enable(); +- if (ud_type == BUG_UD2) { ++ ++ switch (ud_type) { ++ case BUG_UD2: + if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN || + handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) { +- regs->ip += LEN_UD2; ++ regs->ip += ud_len; + handled = true; + } +- } else if (IS_ENABLED(CONFIG_UBSAN_TRAP)) { +- pr_crit("%s at %pS\n", report_ubsan_failure(regs, imm), (void *)regs->ip); ++ break; ++ ++ case BUG_UD1_UBSAN: ++ if (IS_ENABLED(CONFIG_UBSAN_TRAP)) { ++ pr_crit("%s at %pS\n", ++ report_ubsan_failure(regs, ud_imm), ++ (void *)regs->ip); ++ } ++ break; ++ ++ default: ++ break; + } ++ + if (regs->flags & X86_EFLAGS_IF) + raw_local_irq_disable(); + instrumentation_end(); +-- +2.39.5 + diff --git a/queue-6.6/xen-add-support-for-xenserver-6.1-platform-device.patch b/queue-6.6/xen-add-support-for-xenserver-6.1-platform-device.patch new file mode 100644 index 0000000000..a0a5f8f8aa --- /dev/null +++ b/queue-6.6/xen-add-support-for-xenserver-6.1-platform-device.patch @@ -0,0 +1,65 @@ +From 9159998f0ea24d8e2bbd0b44be9092359c4e33fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Feb 2025 14:50:15 +0000 +Subject: xen: Add support for XenServer 6.1 platform device + +From: Frediano Ziglio + +[ Upstream commit 2356f15caefc0cc63d9cc5122641754f76ef9b25 ] + +On XenServer on Windows machine a platform device with ID 2 instead of +1 is used. + +This device is mainly identical to device 1 but due to some Windows +update behaviour it was decided to use a device with a different ID. + +This causes compatibility issues with Linux which expects, if Xen +is detected, to find a Xen platform device (5853:0001) otherwise code +will crash due to some missing initialization (specifically grant +tables). Specifically from dmesg + + RIP: 0010:gnttab_expand+0x29/0x210 + Code: 90 0f 1f 44 00 00 55 31 d2 48 89 e5 41 57 41 56 41 55 41 89 fd + 41 54 53 48 83 ec 10 48 8b 05 7e 9a 49 02 44 8b 35 a7 9a 49 02 + <8b> 48 04 8d 44 39 ff f7 f1 45 8d 24 06 89 c3 e8 43 fe ff ff + 44 39 + RSP: 0000:ffffba34c01fbc88 EFLAGS: 00010086 + ... + +The device 2 is presented by Xapi adding device specification to +Qemu command line. + +Signed-off-by: Frediano Ziglio +Acked-by: Juergen Gross +Message-ID: <20250227145016.25350-1-frediano.ziglio@cloud.com> +Signed-off-by: Juergen Gross +Signed-off-by: Sasha Levin +--- + drivers/xen/platform-pci.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c +index 544d3f9010b92..1db82da56db62 100644 +--- a/drivers/xen/platform-pci.c ++++ b/drivers/xen/platform-pci.c +@@ -26,6 +26,8 @@ + + #define DRV_NAME "xen-platform-pci" + ++#define PCI_DEVICE_ID_XEN_PLATFORM_XS61 0x0002 ++ + static unsigned long platform_mmio; + static unsigned long platform_mmio_alloc; + static unsigned long platform_mmiolen; +@@ -174,6 +176,8 @@ static int platform_pci_probe(struct pci_dev *pdev, + static const struct pci_device_id platform_pci_tbl[] = { + {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_XEN, PCI_DEVICE_ID_XEN_PLATFORM_XS61, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} + }; + +-- +2.39.5 + diff --git a/queue-6.6/xenbus-allow-pvh-dom0-a-non-local-xenstore.patch b/queue-6.6/xenbus-allow-pvh-dom0-a-non-local-xenstore.patch new file mode 100644 index 0000000000..4643c3e9cc --- /dev/null +++ b/queue-6.6/xenbus-allow-pvh-dom0-a-non-local-xenstore.patch @@ -0,0 +1,69 @@ +From 626abc0e7403085dbd2067a8a00acc4e164999f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 May 2025 16:44:56 -0400 +Subject: xenbus: Allow PVH dom0 a non-local xenstore + +From: Jason Andryuk + +[ Upstream commit 90989869baae47ee2aa3bcb6f6eb9fbbe4287958 ] + +Make xenbus_init() allow a non-local xenstore for a PVH dom0 - it is +currently forced to XS_LOCAL. With Hyperlaunch booting dom0 and a +xenstore stubdom, dom0 can be handled as a regular XS_HVM following the +late init path. + +Ideally we'd drop the use of xen_initial_domain() and just check for the +event channel instead. However, ARM has a xen,enhanced no-xenstore +mode, where the event channel and PFN would both be 0. Retain the +xen_initial_domain() check, and use that for an additional check when +the event channel is 0. + +Check the full 64bit HVM_PARAM_STORE_EVTCHN value to catch the off +chance that high bits are set for the 32bit event channel. + +Signed-off-by: Jason Andryuk +Change-Id: I5506da42e4c6b8e85079fefb2f193c8de17c7437 +Reviewed-by: Stefano Stabellini +Signed-off-by: Juergen Gross +Message-ID: <20250506204456.5220-1-jason.andryuk@amd.com> +Signed-off-by: Sasha Levin +--- + drivers/xen/xenbus/xenbus_probe.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index 25164d56c9d99..d3b6908110c6f 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -966,9 +966,15 @@ static int __init xenbus_init(void) + if (xen_pv_domain()) + xen_store_domain_type = XS_PV; + if (xen_hvm_domain()) ++ { + xen_store_domain_type = XS_HVM; +- if (xen_hvm_domain() && xen_initial_domain()) +- xen_store_domain_type = XS_LOCAL; ++ err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); ++ if (err) ++ goto out_error; ++ xen_store_evtchn = (int)v; ++ if (!v && xen_initial_domain()) ++ xen_store_domain_type = XS_LOCAL; ++ } + if (xen_pv_domain() && !xen_start_info->store_evtchn) + xen_store_domain_type = XS_LOCAL; + if (xen_pv_domain() && xen_start_info->store_evtchn) +@@ -987,10 +993,6 @@ static int __init xenbus_init(void) + xen_store_interface = gfn_to_virt(xen_store_gfn); + break; + case XS_HVM: +- err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); +- if (err) +- goto out_error; +- xen_store_evtchn = (int)v; + err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); + if (err) + goto out_error; +-- +2.39.5 +