From: Sasha Levin Date: Fri, 3 Jan 2025 00:40:45 +0000 (-0500) Subject: Fixes for 6.6 X-Git-Tag: v5.4.289~77 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=478bcf4e39095d5d7b652fea0d7910dda870f950;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch new file mode 100644 index 00000000000..13209b031a7 --- /dev/null +++ b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch @@ -0,0 +1,61 @@ +From f722ad002a20ec14ae8d61938daa7e7eec0db911 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jul 2024 17:26:58 +0800 +Subject: ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11 + +From: Yicong Yang + +[ Upstream commit f3b78b470f28bb2a3a40e88bdf5c6de6a35a9b76 ] + +HiSilicon HIP10/11 platforms using the same SMMU PMCG with HIP09 +and thus suffers the same erratum. List them in the PMCG platform +information list without introducing a new SMMU PMCG Model. + +Update the silicon-errata.rst as well. + +Signed-off-by: Yicong Yang +Link: https://lore.kernel.org/r/20240731092658.11012-1-yangyicong@huawei.com +Signed-off-by: Will Deacon +Stable-dep-of: c2b46ae02270 ("ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A") +Signed-off-by: Sasha Levin +--- + Documentation/arch/arm64/silicon-errata.rst | 4 ++-- + drivers/acpi/arm64/iort.c | 7 +++++++ + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst +index 3cf806733083..f4e6afd59630 100644 +--- a/Documentation/arch/arm64/silicon-errata.rst ++++ b/Documentation/arch/arm64/silicon-errata.rst +@@ -244,8 +244,8 @@ stable kernels. + +----------------+-----------------+-----------------+-----------------------------+ + | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | + +----------------+-----------------+-----------------+-----------------------------+ +-| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | +-| | Hip09 SMMU PMCG | | | ++| Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | ++| | ,11} SMMU PMCG | | | + +----------------+-----------------+-----------------+-----------------------------+ + +----------------+-----------------+-----------------+-----------------------------+ + | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c +index 6496ff5a6ba2..b1f483845bc0 100644 +--- a/drivers/acpi/arm64/iort.c ++++ b/drivers/acpi/arm64/iort.c +@@ -1712,6 +1712,13 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = { + /* HiSilicon Hip09 Platform */ + {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */ ++ {"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP10C ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP11 ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, + { } + }; + +-- +2.39.5 + diff --git a/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 new file mode 100644 index 00000000000..02bdb874d65 --- /dev/null +++ b/queue-6.6/acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 @@ -0,0 +1,58 @@ +From 219e4ff0f335a4c1ca2acb07031a441597094b69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 09:33:31 +0800 +Subject: ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A + +From: Qinxin Xia + +[ Upstream commit c2b46ae022704a2d845e59461fa24431ad627022 ] + +HiSilicon HIP09A platforms using the same SMMU PMCG with HIP09 +and thus suffers the same erratum. List them in the PMCG platform +information list without introducing a new SMMU PMCG Model. + +Update the silicon-errata.rst as well. + +Reviewed-by: Yicong Yang +Acked-by: Hanjun Guo +Signed-off-by: Qinxin Xia +Link: https://lore.kernel.org/r/20241205013331.1484017-1-xiaqinxin@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + Documentation/arch/arm64/silicon-errata.rst | 5 +++-- + drivers/acpi/arm64/iort.c | 2 ++ + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst +index f4e6afd59630..8209c7a7c397 100644 +--- a/Documentation/arch/arm64/silicon-errata.rst ++++ b/Documentation/arch/arm64/silicon-errata.rst +@@ -244,8 +244,9 @@ stable kernels. + +----------------+-----------------+-----------------+-----------------------------+ + | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | + +----------------+-----------------+-----------------+-----------------------------+ +-| Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | +-| | ,11} SMMU PMCG | | | ++| Hisilicon | Hip{08,09,09A,10| #162001900 | N/A | ++| | ,10C,11} | | | ++| | SMMU PMCG | | | + +----------------+-----------------+-----------------+-----------------------------+ + +----------------+-----------------+-----------------+-----------------------------+ + | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c +index b1f483845bc0..1a31106a14e4 100644 +--- a/drivers/acpi/arm64/iort.c ++++ b/drivers/acpi/arm64/iort.c +@@ -1712,6 +1712,8 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = { + /* HiSilicon Hip09 Platform */ + {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, ++ {"HISI ", "HIP09A ", 0, ACPI_SIG_IORT, greater_than_or_equal, ++ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, + /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */ + {"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, +-- +2.39.5 + diff --git a/queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch b/queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch new file mode 100644 index 00000000000..2e75b48ff82 --- /dev/null +++ b/queue-6.6/acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch @@ -0,0 +1,53 @@ +From 1e4eaa4ab92e9c9b056cc896f4733608baaa67c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 17:26:10 +0100 +Subject: ACPI: PCC: Add PCC shared memory region command and status bitfields + +From: Sudeep Holla + +[ Upstream commit 55d235ebb684b993b3247740c1c8e273f8af4a54 ] + +Define the common macros to use when referring to various bitfields in +the PCC generic communications channel command and status fields. + +Currently different drivers that need to use these bitfields have defined +these locally. This common macro is intended to consolidate and replace +those. + +Cc: "Rafael J. Wysocki" +Link: https://lore.kernel.org/r/20230927-pcc_defines-v2-1-0b8ffeaef2e5@arm.com +Signed-off-by: Sudeep Holla +Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK") +Signed-off-by: Sasha Levin +--- + include/acpi/pcc.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h +index 73e806fe7ce7..9b373d172a77 100644 +--- a/include/acpi/pcc.h ++++ b/include/acpi/pcc.h +@@ -18,7 +18,20 @@ struct pcc_mbox_chan { + u16 min_turnaround_time; + }; + ++/* Generic Communications Channel Shared Memory Region */ ++#define PCC_SIGNATURE 0x50434300 ++/* Generic Communications Channel Command Field */ ++#define PCC_CMD_GENERATE_DB_INTR BIT(15) ++/* Generic Communications Channel Status Field */ ++#define PCC_STATUS_CMD_COMPLETE BIT(0) ++#define PCC_STATUS_SCI_DOORBELL BIT(1) ++#define PCC_STATUS_ERROR BIT(2) ++#define PCC_STATUS_PLATFORM_NOTIFY BIT(3) ++/* Initiator Responder Communications Channel Flags */ ++#define PCC_CMD_COMPLETION_NOTIFY BIT(0) ++ + #define MAX_PCC_SUBSPACES 256 ++ + #ifdef CONFIG_PCC + extern struct pcc_mbox_chan * + pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id); +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch b/queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch new file mode 100644 index 00000000000..a5bd16c6739 --- /dev/null +++ b/queue-6.6/alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch @@ -0,0 +1,36 @@ +From d430bff8d1ad1c55b9a166d2f135161b1856a410 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 10:45:42 +0100 +Subject: ALSA: ump: Don't open legacy substream for an inactive group + +From: Takashi Iwai + +[ Upstream commit 3978d53df7236f0a517c2abeb43ddf6ac162cdd8 ] + +When a UMP Group is inactive, we shouldn't allow users to access it +via the legacy MIDI access. Add the group active flag check and +return -ENODEV if it's inactive. + +Link: https://patch.msgid.link/20241129094546.32119-2-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/ump.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index ada2625ce78f..5a4a7d0b7cca 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -1081,6 +1081,8 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) + guard(mutex)(&ump->open_mutex); + if (ump->legacy_substreams[dir][group]) + return -EBUSY; ++ if (!ump->groups[group].active) ++ return -ENODEV; + if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { + if (!ump->legacy_out_opens) { + err = snd_rawmidi_kernel_open(&ump->core, 0, +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch b/queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch new file mode 100644 index 00000000000..b460a5ec6d2 --- /dev/null +++ b/queue-6.6/alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch @@ -0,0 +1,39 @@ +From 975842b3cc61445f192b393fb47d43772a8ad954 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 10:45:43 +0100 +Subject: ALSA: ump: Indicate the inactive group in legacy substream names + +From: Takashi Iwai + +[ Upstream commit e29e504e7890b9ee438ca6370d0180d607c473f9 ] + +Since the legacy rawmidi has no proper way to know the inactive group, +indicate it in the rawmidi substream names with "[Inactive]" suffix +when the corresponding UMP group is inactive. + +Link: https://patch.msgid.link/20241129094546.32119-3-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/ump.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index 5a4a7d0b7cca..bb94f119869a 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -1245,8 +1245,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, + name = ump->groups[idx].name; + if (!*name) + name = ump->info.name; +- snprintf(s->name, sizeof(s->name), "Group %d (%.16s)", +- idx + 1, name); ++ snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", ++ idx + 1, name, ++ ump->groups[idx].active ? "" : " [Inactive]"); + } + } + +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch b/queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch new file mode 100644 index 00000000000..fca16cc1551 --- /dev/null +++ b/queue-6.6/alsa-ump-shut-up-truncated-string-warning.patch @@ -0,0 +1,44 @@ +From 43291c3b4ed4e1a1b0cdfdad881faada94da2d8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Nov 2024 10:00:08 +0100 +Subject: ALSA: ump: Shut up truncated string warning + +From: Takashi Iwai + +[ Upstream commit ed990c07af70d286f5736021c6e25d8df6f2f7b0 ] + +The recent change for the legacy substream name update brought a +compile warning for some compilers due to the nature of snprintf(). +Use scnprintf() to shut up the warning since the truncation is +intentional. + +Fixes: e29e504e7890 ("ALSA: ump: Indicate the inactive group in legacy substream names") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202411300103.FrGuTAYp-lkp@intel.com/ +Link: https://patch.msgid.link/20241130090009.19849-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/ump.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index 4aec90dac07e..32d27e58416a 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -1251,9 +1251,9 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, + name = ump->groups[idx].name; + if (!*name) + name = ump->info.name; +- snprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", +- idx + 1, name, +- ump->groups[idx].active ? "" : " [Inactive]"); ++ scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s", ++ idx + 1, name, ++ ump->groups[idx].active ? "" : " [Inactive]"); + } + } + +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch b/queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch new file mode 100644 index 00000000000..90293ee6001 --- /dev/null +++ b/queue-6.6/alsa-ump-update-legacy-substream-names-upon-fb-info-.patch @@ -0,0 +1,87 @@ +From 5182d79632c10ae484000c014ca9b83dab075f71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 10:45:44 +0100 +Subject: ALSA: ump: Update legacy substream names upon FB info update + +From: Takashi Iwai + +[ Upstream commit edad3f9519fcacb926d0e3f3217aecaf628a593f ] + +The legacy rawmidi substreams should be updated when UMP FB Info or +UMP FB Name are received, too. + +Link: https://patch.msgid.link/20241129094546.32119-4-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/ump.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index bb94f119869a..4aec90dac07e 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -37,6 +37,7 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + u32 *buffer, int count); + static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, + int words); ++static void update_legacy_names(struct snd_ump_endpoint *ump); + #else + static inline int process_legacy_output(struct snd_ump_endpoint *ump, + u32 *buffer, int count) +@@ -47,6 +48,9 @@ static inline void process_legacy_input(struct snd_ump_endpoint *ump, + const u32 *src, int words) + { + } ++static inline void update_legacy_names(struct snd_ump_endpoint *ump) ++{ ++} + #endif + + static const struct snd_rawmidi_global_ops snd_ump_rawmidi_ops = { +@@ -850,6 +854,7 @@ static int ump_handle_fb_info_msg(struct snd_ump_endpoint *ump, + fill_fb_info(ump, &fb->info, buf); + if (ump->parsed) { + snd_ump_update_group_attrs(ump); ++ update_legacy_names(ump); + seq_notify_fb_change(ump, fb); + } + } +@@ -882,6 +887,7 @@ static int ump_handle_fb_name_msg(struct snd_ump_endpoint *ump, + /* notify the FB name update to sequencer, too */ + if (ret > 0 && ump->parsed) { + snd_ump_update_group_attrs(ump); ++ update_legacy_names(ump); + seq_notify_fb_change(ump, fb); + } + return ret; +@@ -1251,6 +1257,14 @@ static void fill_substream_names(struct snd_ump_endpoint *ump, + } + } + ++static void update_legacy_names(struct snd_ump_endpoint *ump) ++{ ++ struct snd_rawmidi *rmidi = ump->legacy_rmidi; ++ ++ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); ++ fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); ++} ++ + int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + char *id, int device) + { +@@ -1287,10 +1301,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, + rmidi->ops = &snd_ump_legacy_ops; + rmidi->private_data = ump; + ump->legacy_rmidi = rmidi; +- if (input) +- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT); +- if (output) +- fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT); ++ update_legacy_names(ump); + + ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id); + return 0; +-- +2.39.5 + diff --git a/queue-6.6/alsa-ump-use-guard-for-locking.patch b/queue-6.6/alsa-ump-use-guard-for-locking.patch new file mode 100644 index 00000000000..277272660cf --- /dev/null +++ b/queue-6.6/alsa-ump-use-guard-for-locking.patch @@ -0,0 +1,129 @@ +From 891e572af18fce844430490b2c019dd6f6d30022 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Feb 2024 09:52:43 +0100 +Subject: ALSA: ump: Use guard() for locking + +From: Takashi Iwai + +[ Upstream commit 631896f7eaaf8cf8c639b065d3c9fbaa66da5d32 ] + +We can simplify the code gracefully with new guard() macro and co for +automatic cleanup of locks. + +Only the code refactoring, and no functional changes. + +Signed-off-by: Takashi Iwai +Link: https://lore.kernel.org/r/20240227085306.9764-2-tiwai@suse.de +Stable-dep-of: 3978d53df723 ("ALSA: ump: Don't open legacy substream for an inactive group") +Signed-off-by: Sasha Levin +--- + sound/core/ump.c | 35 ++++++++++++----------------------- + 1 file changed, 12 insertions(+), 23 deletions(-) + +diff --git a/sound/core/ump.c b/sound/core/ump.c +index 83856b2f88b8..ada2625ce78f 100644 +--- a/sound/core/ump.c ++++ b/sound/core/ump.c +@@ -1076,13 +1076,11 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) + struct snd_ump_endpoint *ump = substream->rmidi->private_data; + int dir = substream->stream; + int group = ump->legacy_mapping[substream->number]; +- int err = 0; ++ int err; + +- mutex_lock(&ump->open_mutex); +- if (ump->legacy_substreams[dir][group]) { +- err = -EBUSY; +- goto unlock; +- } ++ guard(mutex)(&ump->open_mutex); ++ if (ump->legacy_substreams[dir][group]) ++ return -EBUSY; + if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { + if (!ump->legacy_out_opens) { + err = snd_rawmidi_kernel_open(&ump->core, 0, +@@ -1090,17 +1088,14 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) + SNDRV_RAWMIDI_LFLG_APPEND, + &ump->legacy_out_rfile); + if (err < 0) +- goto unlock; ++ return err; + } + ump->legacy_out_opens++; + snd_ump_convert_reset(&ump->out_cvts[group]); + } +- spin_lock_irq(&ump->legacy_locks[dir]); ++ guard(spinlock_irq)(&ump->legacy_locks[dir]); + ump->legacy_substreams[dir][group] = substream; +- spin_unlock_irq(&ump->legacy_locks[dir]); +- unlock: +- mutex_unlock(&ump->open_mutex); +- return err; ++ return 0; + } + + static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream) +@@ -1109,15 +1104,13 @@ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream) + int dir = substream->stream; + int group = ump->legacy_mapping[substream->number]; + +- mutex_lock(&ump->open_mutex); +- spin_lock_irq(&ump->legacy_locks[dir]); +- ump->legacy_substreams[dir][group] = NULL; +- spin_unlock_irq(&ump->legacy_locks[dir]); ++ guard(mutex)(&ump->open_mutex); ++ scoped_guard(spinlock_irq, &ump->legacy_locks[dir]) ++ ump->legacy_substreams[dir][group] = NULL; + if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { + if (!--ump->legacy_out_opens) + snd_rawmidi_kernel_release(&ump->legacy_out_rfile); + } +- mutex_unlock(&ump->open_mutex); + return 0; + } + +@@ -1169,12 +1162,11 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + const int dir = SNDRV_RAWMIDI_STREAM_OUTPUT; + unsigned char c; + int group, size = 0; +- unsigned long flags; + + if (!ump->out_cvts || !ump->legacy_out_opens) + return 0; + +- spin_lock_irqsave(&ump->legacy_locks[dir], flags); ++ guard(spinlock_irqsave)(&ump->legacy_locks[dir]); + for (group = 0; group < SNDRV_UMP_MAX_GROUPS; group++) { + substream = ump->legacy_substreams[dir][group]; + if (!substream) +@@ -1190,7 +1182,6 @@ static int process_legacy_output(struct snd_ump_endpoint *ump, + break; + } + } +- spin_unlock_irqrestore(&ump->legacy_locks[dir], flags); + return size; + } + +@@ -1200,18 +1191,16 @@ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, + struct snd_rawmidi_substream *substream; + unsigned char buf[16]; + unsigned char group; +- unsigned long flags; + const int dir = SNDRV_RAWMIDI_STREAM_INPUT; + int size; + + size = snd_ump_convert_from_ump(src, buf, &group); + if (size <= 0) + return; +- spin_lock_irqsave(&ump->legacy_locks[dir], flags); ++ guard(spinlock_irqsave)(&ump->legacy_locks[dir]); + substream = ump->legacy_substreams[dir][group]; + if (substream) + snd_rawmidi_receive(substream, buf, size); +- spin_unlock_irqrestore(&ump->legacy_locks[dir], flags); + } + + /* Fill ump->legacy_mapping[] for groups to be used for legacy rawmidi */ +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch b/queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch new file mode 100644 index 00000000000..c680ac556a5 --- /dev/null +++ b/queue-6.6/bluetooth-add-support-ittim-pe50-m75c.patch @@ -0,0 +1,73 @@ +From 184b333323b8b36407b7bdf782d4aef6849afc89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Sep 2023 16:31:47 +0800 +Subject: Bluetooth: Add support ITTIM PE50-M75C + +From: Jingyang Wang + +[ Upstream commit 00b1c3c4b682ba4b4f9fc46e047b537e668576af ] + +-Device(35f5:7922) from /sys/kernel/debug/usb/devices +P: Vendor=35f5 ProdID=7922 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us + +Signed-off-by: Jingyang Wang +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index fe5e30662017..6b0d9d9f3004 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -658,6 +658,9 @@ static const struct usb_device_id quirks_table[] = { + { USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* Additional Realtek 8723AE Bluetooth devices */ + { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch b/queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch new file mode 100644 index 00000000000..fcf929b6ffb --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-callback-function-in-btusb-suspe.patch @@ -0,0 +1,60 @@ +From f9068b5e32f698660cc1771b504d36044afe34b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jul 2024 14:01:12 +0800 +Subject: Bluetooth: btusb: add callback function in btusb suspend/resume + +From: Chris Lu + +[ Upstream commit 95f92928ad2215b5f524903e67eebd8e14f99564 ] + +Add suspend/resum callback function in btusb_data which are reserved +for vendor specific usage during suspend/resume. hdev->suspend will be +added before stop traffic in btusb_suspend and hdev-> resume will be +added after resubmit urb in btusb_resume. + +Signed-off-by: Chris Lu +Signed-off-by: Sean Wang +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: cea1805f165c ("Bluetooth: btusb: mediatek: add callback function in btusb_disconnect") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 67577933835f..19d371aa8317 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -892,6 +892,9 @@ struct btusb_data { + + int (*setup_on_usb)(struct hci_dev *hdev); + ++ int (*suspend)(struct hci_dev *hdev); ++ int (*resume)(struct hci_dev *hdev); ++ + int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + unsigned cmd_timeout_cnt; + +@@ -4691,6 +4694,9 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) + + cancel_work_sync(&data->work); + ++ if (data->suspend) ++ data->suspend(data->hdev); ++ + btusb_stop_traffic(data); + usb_kill_anchored_urbs(&data->tx_anchor); + +@@ -4794,6 +4800,9 @@ static int btusb_resume(struct usb_interface *intf) + btusb_submit_isoc_urb(hdev, GFP_NOIO); + } + ++ if (data->resume) ++ data->resume(hdev); ++ + spin_lock_irq(&data->txlock); + play_deferred(data); + clear_bit(BTUSB_SUSPENDING, &data->flags); +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch new file mode 100644 index 00000000000..e968ada9524 --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch @@ -0,0 +1,77 @@ +From b64aa42650bf5ef9023d886e77c0ee886c348c87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Oct 2024 11:18:18 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925 + +From: Hao Qin + +[ Upstream commit faa5fd605d2081b6c9fa2355b59582d4ccd24b16 ] + +Add VID 0489 & PID e111 for MediaTek MT7925 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=02 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0489 ProdID=e111 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us + +Signed-off-by: Hao Qin +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index dc0bba7f4028..67577933835f 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -681,6 +681,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_VALID_LE_STATES }, + + /* Additional MediaTek MT7925 Bluetooth devices */ ++ { USB_DEVICE(0x0489, 0xe111), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch b/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch new file mode 100644 index 00000000000..9522e7f3bdc --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch @@ -0,0 +1,82 @@ +From b1df58d95e1d8cc079b8f4953566371ddb663fef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Jan 2024 15:27:38 +0800 +Subject: Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925 + +From: Ulrik Strid + +[ Upstream commit 560ff4bc99070bfb493018b6b7045af269a008a4 ] + +Add VID 13d3 & PID 3602 for MediaTek MT7925 USB Bluetooth chip. + +The information in /sys/kernel/debug/usb/devices about the Bluetooth +device is listed as the below. + +T: Bus=07 Lev=01 Prnt=01 Port=10 Cnt=02 Dev#= 2 Spd=480 MxCh= 0 +D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3602 Rev= 1.00 +S: Manufacturer=MediaTek Inc. +S: Product=Wireless_Device +S: SerialNumber=000000000 +C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA +A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms +E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms +I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us +I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) +E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us +E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us + +Signed-off-by: Ulrik Strid +Signed-off-by: Deren Wu +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 6b0d9d9f3004..fd57a02046ae 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -662,6 +662,11 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, + ++ /* Additional MediaTek MT7925 Bluetooth devices */ ++ { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ + /* Additional Realtek 8723AE Bluetooth devices */ + { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, + { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch b/queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch new file mode 100644 index 00000000000..c0704bbe073 --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch @@ -0,0 +1,73 @@ +From dbdcdcf08d4fbde15da656d08ba5f5ba92933c88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 14:51:56 +0800 +Subject: Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925 + +From: Jiande Lu + +[ Upstream commit 129d329286f624b0ccd66e904a2c27eb4d5196e5 ] + +Add HW IDs for wireless module specific to Acer/ASUS +notebook models to ensure proper recognition and functionality. +These HW IDs are extracted from Windows driver inf file. +Note some HW IDs without official drivers, still in testing phase. +Thus, we update module HW ID and test ensure consistent boot success. + +Signed-off-by: Jiande Lu +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: faa5fd605d20 ("Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index fd57a02046ae..dc0bba7f4028 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -620,6 +620,9 @@ static const struct usb_device_id quirks_table[] = { + { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3606), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* MediaTek MT7922A Bluetooth devices */ + { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | +@@ -661,11 +664,32 @@ static const struct usb_device_id quirks_table[] = { + { USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3615), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3605), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3607), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* Additional MediaTek MT7925 Bluetooth devices */ ++ { USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + { USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, ++ { USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK | ++ BTUSB_WIDEBAND_SPEECH | ++ BTUSB_VALID_LE_STATES }, + + /* Additional Realtek 8723AE Bluetooth devices */ + { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK }, +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch b/queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch new file mode 100644 index 00000000000..7396f0c7dce --- /dev/null +++ b/queue-6.6/bluetooth-btusb-mediatek-add-callback-function-in-bt.patch @@ -0,0 +1,44 @@ +From 4e6ef6c7bcc35f825199ae135a5d8d90deecc447 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 16:47:03 +0800 +Subject: Bluetooth: btusb: mediatek: add callback function in btusb_disconnect + +From: Chris Lu + +[ Upstream commit cea1805f165cdd783dd21f26df957118cb8641b4 ] + +Add disconnect callback function in btusb_disconnect which is reserved +for vendor specific usage before deregister hci in btusb_disconnect. + +Signed-off-by: Chris Lu +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 19d371aa8317..c80b5aa7628a 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -894,6 +894,7 @@ struct btusb_data { + + int (*suspend)(struct hci_dev *hdev); + int (*resume)(struct hci_dev *hdev); ++ int (*disconnect)(struct hci_dev *hdev); + + int oob_wake_irq; /* irq for out-of-band wake-on-bt */ + unsigned cmd_timeout_cnt; +@@ -4646,6 +4647,9 @@ static void btusb_disconnect(struct usb_interface *intf) + if (data->diag) + usb_set_intfdata(data->diag, NULL); + ++ if (data->disconnect) ++ data->disconnect(hdev); ++ + hci_unregister_dev(hdev); + + if (intf == data->intf) { +-- +2.39.5 + diff --git a/queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch b/queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch new file mode 100644 index 00000000000..687e821b13e --- /dev/null +++ b/queue-6.6/bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch @@ -0,0 +1,62 @@ +From 8312de9db3bbe5da4de70dbdbbdf812b9f251838 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 09:21:25 +0200 +Subject: Bluetooth: hci_conn: Reduce hci_conn_drop() calls in two functions + +From: Markus Elfring + +[ Upstream commit d96b543c6f3b78b6440b68b5a5bbface553eff28 ] + +An hci_conn_drop() call was immediately used after a null pointer check +for an hci_conn_link() call in two function implementations. +Thus call such a function only once instead directly before the checks. + +This issue was transformed by using the Coccinelle software. + +Signed-off-by: Markus Elfring +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/hci_conn.c | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c +index 6178ae8feafc..549ee9e87d63 100644 +--- a/net/bluetooth/hci_conn.c ++++ b/net/bluetooth/hci_conn.c +@@ -2178,13 +2178,9 @@ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst, + conn->iso_qos.bcast.big); + if (parent && parent != conn) { + link = hci_conn_link(parent, conn); +- if (!link) { +- hci_conn_drop(conn); +- return ERR_PTR(-ENOLINK); +- } +- +- /* Link takes the refcount */ + hci_conn_drop(conn); ++ if (!link) ++ return ERR_PTR(-ENOLINK); + } + + return conn; +@@ -2274,15 +2270,12 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst, + } + + link = hci_conn_link(le, cis); ++ hci_conn_drop(cis); + if (!link) { + hci_conn_drop(le); +- hci_conn_drop(cis); + return ERR_PTR(-ENOLINK); + } + +- /* Link takes the refcount */ +- hci_conn_drop(cis); +- + cis->state = BT_CONNECT; + + hci_le_create_cis_pending(hdev); +-- +2.39.5 + diff --git a/queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch b/queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch new file mode 100644 index 00000000000..2bea454d4b2 --- /dev/null +++ b/queue-6.6/btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch @@ -0,0 +1,79 @@ +From bc8fa542679b56ee1a982cac0fd5d7d2c59970ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2024 16:08:07 +0000 +Subject: btrfs: fix use-after-free when COWing tree bock and tracing is + enabled + +From: Filipe Manana + +[ Upstream commit 44f52bbe96dfdbe4aca3818a2534520082a07040 ] + +When a COWing a tree block, at btrfs_cow_block(), and we have the +tracepoint trace_btrfs_cow_block() enabled and preemption is also enabled +(CONFIG_PREEMPT=y), we can trigger a use-after-free in the COWed extent +buffer while inside the tracepoint code. This is because in some paths +that call btrfs_cow_block(), such as btrfs_search_slot(), we are holding +the last reference on the extent buffer @buf so btrfs_force_cow_block() +drops the last reference on the @buf extent buffer when it calls +free_extent_buffer_stale(buf), which schedules the release of the extent +buffer with RCU. This means that if we are on a kernel with preemption, +the current task may be preempted before calling trace_btrfs_cow_block() +and the extent buffer already released by the time trace_btrfs_cow_block() +is called, resulting in a use-after-free. + +Fix this by moving the trace_btrfs_cow_block() from btrfs_cow_block() to +btrfs_force_cow_block() before the COWed extent buffer is freed. +This also has a side effect of invoking the tracepoint in the tree defrag +code, at defrag.c:btrfs_realloc_node(), since btrfs_force_cow_block() is +called there, but this is fine and it was actually missing there. + +Reported-by: syzbot+8517da8635307182c8a5@syzkaller.appspotmail.com +Link: https://lore.kernel.org/linux-btrfs/6759a9b9.050a0220.1ac542.000d.GAE@google.com/ +CC: stable@vger.kernel.org # 5.4+ +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 62032d3fda85..4b21ca49b666 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -660,6 +660,8 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans, + return ret; + } + } ++ ++ trace_btrfs_cow_block(root, buf, cow); + if (unlock_orig) + btrfs_tree_unlock(buf); + free_extent_buffer_stale(buf); +@@ -711,7 +713,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + { + struct btrfs_fs_info *fs_info = root->fs_info; + u64 search_start; +- int ret; + + if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { + btrfs_abort_transaction(trans, -EUCLEAN); +@@ -752,12 +753,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + * Also We don't care about the error, as it's handled internally. + */ + btrfs_qgroup_trace_subtree_after_cow(trans, root, buf); +- ret = btrfs_force_cow_block(trans, root, buf, parent, parent_slot, +- cow_ret, search_start, 0, nest); +- +- trace_btrfs_cow_block(root, buf, *cow_ret); +- +- return ret; ++ return btrfs_force_cow_block(trans, root, buf, parent, parent_slot, ++ cow_ret, search_start, 0, nest); + } + ALLOW_ERROR_INJECTION(btrfs_cow_block, ERRNO); + +-- +2.39.5 + diff --git a/queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch b/queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch new file mode 100644 index 00000000000..1a7afd9205a --- /dev/null +++ b/queue-6.6/btrfs-rename-and-export-__btrfs_cow_block.patch @@ -0,0 +1,106 @@ +From 477a23fee0d5df1f4183e52713f466cb097eb15d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Sep 2023 12:09:26 +0100 +Subject: btrfs: rename and export __btrfs_cow_block() + +From: Filipe Manana + +[ Upstream commit 95f93bc4cbcac6121a5ee85cd5019ee8e7447e0b ] + +Rename and export __btrfs_cow_block() as btrfs_force_cow_block(). This is +to allow to move defrag specific code out of ctree.c and into defrag.c in +one of the next patches. + +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: 44f52bbe96df ("btrfs: fix use-after-free when COWing tree bock and tracing is enabled") +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 30 +++++++++++++++--------------- + fs/btrfs/ctree.h | 7 +++++++ + 2 files changed, 22 insertions(+), 15 deletions(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 25c902e7556d..62032d3fda85 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -526,13 +526,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, + * bytes the allocator should try to find free next to the block it returns. + * This is just a hint and may be ignored by the allocator. + */ +-static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct extent_buffer *buf, +- struct extent_buffer *parent, int parent_slot, +- struct extent_buffer **cow_ret, +- u64 search_start, u64 empty_size, +- enum btrfs_lock_nesting nest) ++int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct extent_buffer *buf, ++ struct extent_buffer *parent, int parent_slot, ++ struct extent_buffer **cow_ret, ++ u64 search_start, u64 empty_size, ++ enum btrfs_lock_nesting nest) + { + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_disk_key disk_key; +@@ -699,7 +699,7 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, + } + + /* +- * cows a single block, see __btrfs_cow_block for the real work. ++ * COWs a single block, see btrfs_force_cow_block() for the real work. + * This version of it has extra checks so that a block isn't COWed more than + * once per transaction, as long as it hasn't been written yet + */ +@@ -752,8 +752,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, + * Also We don't care about the error, as it's handled internally. + */ + btrfs_qgroup_trace_subtree_after_cow(trans, root, buf); +- ret = __btrfs_cow_block(trans, root, buf, parent, +- parent_slot, cow_ret, search_start, 0, nest); ++ ret = btrfs_force_cow_block(trans, root, buf, parent, parent_slot, ++ cow_ret, search_start, 0, nest); + + trace_btrfs_cow_block(root, buf, *cow_ret); + +@@ -904,11 +904,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + search_start = last_block; + + btrfs_tree_lock(cur); +- err = __btrfs_cow_block(trans, root, cur, parent, i, +- &cur, search_start, +- min(16 * blocksize, +- (end_slot - i) * blocksize), +- BTRFS_NESTING_COW); ++ err = btrfs_force_cow_block(trans, root, cur, parent, i, ++ &cur, search_start, ++ min(16 * blocksize, ++ (end_slot - i) * blocksize), ++ BTRFS_NESTING_COW); + if (err) { + btrfs_tree_unlock(cur); + free_extent_buffer(cur); +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index f7bb4c34b984..7df3ed2945b0 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -538,6 +538,13 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans, + struct extent_buffer *parent, int parent_slot, + struct extent_buffer **cow_ret, + enum btrfs_lock_nesting nest); ++int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct extent_buffer *buf, ++ struct extent_buffer *parent, int parent_slot, ++ struct extent_buffer **cow_ret, ++ u64 search_start, u64 empty_size, ++ enum btrfs_lock_nesting nest); + int btrfs_copy_root(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, +-- +2.39.5 + diff --git a/queue-6.6/cleanup-add-conditional-guard-support.patch b/queue-6.6/cleanup-add-conditional-guard-support.patch new file mode 100644 index 00000000000..a8f8fa653bd --- /dev/null +++ b/queue-6.6/cleanup-add-conditional-guard-support.patch @@ -0,0 +1,225 @@ +From c18818f7036946b3477c4c02fbc20075266cbc07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 17 Sep 2023 13:22:17 +0200 +Subject: cleanup: Add conditional guard support + +From: Peter Zijlstra + +[ Upstream commit e4ab322fbaaaf84b23d6cb0e3317a7f68baf36dc ] + +Adds: + + - DEFINE_GUARD_COND() / DEFINE_LOCK_GUARD_1_COND() to extend existing + guards with conditional lock primitives, eg. mutex_trylock(), + mutex_lock_interruptible(). + + nb. both primitives allow NULL 'locks', which cause the lock to + fail (obviously). + + - extends scoped_guard() to not take the body when the the + conditional guard 'fails'. eg. + + scoped_guard (mutex_intr, &task->signal_cred_guard_mutex) { + ... + } + + will only execute the body when the mutex is held. + + - provides scoped_cond_guard(name, fail, args...); which extends + scoped_guard() to do fail when the lock-acquire fails. + +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20231102110706.460851167%40infradead.org +Stable-dep-of: fcc22ac5baf0 ("cleanup: Adjust scoped_guard() macros to avoid potential warning") +Signed-off-by: Sasha Levin +--- + include/linux/cleanup.h | 52 +++++++++++++++++++++++++++++++++++++--- + include/linux/mutex.h | 3 ++- + include/linux/rwsem.h | 8 +++---- + include/linux/spinlock.h | 15 ++++++++++++ + 4 files changed, 70 insertions(+), 8 deletions(-) + +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index 53f1a7a932b0..6d7bfa899df0 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -92,25 +92,55 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + * trivial wrapper around DEFINE_CLASS() above specifically + * for locks. + * ++ * DEFINE_GUARD_COND(name, ext, condlock) ++ * wrapper around EXTEND_CLASS above to add conditional lock ++ * variants to a base class, eg. mutex_trylock() or ++ * mutex_lock_interruptible(). ++ * + * guard(name): +- * an anonymous instance of the (guard) class ++ * an anonymous instance of the (guard) class, not recommended for ++ * conditional locks. + * + * scoped_guard (name, args...) { }: + * similar to CLASS(name, scope)(args), except the variable (with the + * explicit name 'scope') is declard in a for-loop such that its scope is + * bound to the next (compound) statement. + * ++ * for conditional locks the loop body is skipped when the lock is not ++ * acquired. ++ * ++ * scoped_cond_guard (name, fail, args...) { }: ++ * similar to scoped_guard(), except it does fail when the lock ++ * acquire fails. ++ * + */ + + #define DEFINE_GUARD(_name, _type, _lock, _unlock) \ +- DEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T) ++ DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \ ++ static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \ ++ { return *_T; } ++ ++#define DEFINE_GUARD_COND(_name, _ext, _condlock) \ ++ EXTEND_CLASS(_name, _ext, \ ++ ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \ ++ class_##_name##_t _T) \ ++ static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \ ++ { return class_##_name##_lock_ptr(_T); } + + #define guard(_name) \ + CLASS(_name, __UNIQUE_ID(guard)) + ++#define __guard_ptr(_name) class_##_name##_lock_ptr ++ + #define scoped_guard(_name, args...) \ + for (CLASS(_name, scope)(args), \ +- *done = NULL; !done; done = (void *)1) ++ *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1) ++ ++#define scoped_cond_guard(_name, _fail, args...) \ ++ for (CLASS(_name, scope)(args), \ ++ *done = NULL; !done; done = (void *)1) \ ++ if (!__guard_ptr(_name)(&scope)) _fail; \ ++ else + + /* + * Additional helper macros for generating lock guards with types, either for +@@ -119,6 +149,7 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + * + * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...) + * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...) ++ * DEFINE_LOCK_GUARD_1_COND(name, ext, condlock) + * + * will result in the following type: + * +@@ -140,6 +171,11 @@ typedef struct { \ + static inline void class_##_name##_destructor(class_##_name##_t *_T) \ + { \ + if (_T->lock) { _unlock; } \ ++} \ ++ \ ++static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T) \ ++{ \ ++ return _T->lock; \ + } + + +@@ -168,4 +204,14 @@ __DEFINE_LOCK_GUARD_1(_name, _type, _lock) + __DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ + __DEFINE_LOCK_GUARD_0(_name, _lock) + ++#define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock) \ ++ EXTEND_CLASS(_name, _ext, \ ++ ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\ ++ if (_T->lock && !(_condlock)) _T->lock = NULL; \ ++ _t; }), \ ++ typeof_member(class_##_name##_t, lock) l) \ ++ static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \ ++ { return class_##_name##_lock_ptr(_T); } ++ ++ + #endif /* __LINUX_GUARDS_H */ +diff --git a/include/linux/mutex.h b/include/linux/mutex.h +index 5b5630e58407..e1c323c7d75b 100644 +--- a/include/linux/mutex.h ++++ b/include/linux/mutex.h +@@ -248,6 +248,7 @@ extern void mutex_unlock(struct mutex *lock); + extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); + + DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) +-DEFINE_FREE(mutex, struct mutex *, if (_T) mutex_unlock(_T)) ++DEFINE_GUARD_COND(mutex, _try, mutex_trylock(_T)) ++DEFINE_GUARD_COND(mutex, _intr, mutex_lock_interruptible(_T) == 0) + + #endif /* __LINUX_MUTEX_H */ +diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h +index 1dd530ce8b45..9c29689ff505 100644 +--- a/include/linux/rwsem.h ++++ b/include/linux/rwsem.h +@@ -203,11 +203,11 @@ extern void up_read(struct rw_semaphore *sem); + extern void up_write(struct rw_semaphore *sem); + + DEFINE_GUARD(rwsem_read, struct rw_semaphore *, down_read(_T), up_read(_T)) +-DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) +- +-DEFINE_FREE(up_read, struct rw_semaphore *, if (_T) up_read(_T)) +-DEFINE_FREE(up_write, struct rw_semaphore *, if (_T) up_write(_T)) ++DEFINE_GUARD_COND(rwsem_read, _try, down_read_trylock(_T)) ++DEFINE_GUARD_COND(rwsem_read, _intr, down_read_interruptible(_T) == 0) + ++DEFINE_GUARD(rwsem_write, struct rw_semaphore *, down_write(_T), up_write(_T)) ++DEFINE_GUARD_COND(rwsem_write, _try, down_write_trylock(_T)) + + /* + * downgrade write lock to read lock +diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h +index 31d3d747a9db..ceb56b39c70f 100644 +--- a/include/linux/spinlock.h ++++ b/include/linux/spinlock.h +@@ -507,6 +507,8 @@ DEFINE_LOCK_GUARD_1(raw_spinlock, raw_spinlock_t, + raw_spin_lock(_T->lock), + raw_spin_unlock(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock, _try, raw_spin_trylock(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(raw_spinlock_nested, raw_spinlock_t, + raw_spin_lock_nested(_T->lock, SINGLE_DEPTH_NESTING), + raw_spin_unlock(_T->lock)) +@@ -515,23 +517,36 @@ DEFINE_LOCK_GUARD_1(raw_spinlock_irq, raw_spinlock_t, + raw_spin_lock_irq(_T->lock), + raw_spin_unlock_irq(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irq, _try, raw_spin_trylock_irq(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(raw_spinlock_irqsave, raw_spinlock_t, + raw_spin_lock_irqsave(_T->lock, _T->flags), + raw_spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + ++DEFINE_LOCK_GUARD_1_COND(raw_spinlock_irqsave, _try, ++ raw_spin_trylock_irqsave(_T->lock, _T->flags)) ++ + DEFINE_LOCK_GUARD_1(spinlock, spinlock_t, + spin_lock(_T->lock), + spin_unlock(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(spinlock, _try, spin_trylock(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(spinlock_irq, spinlock_t, + spin_lock_irq(_T->lock), + spin_unlock_irq(_T->lock)) + ++DEFINE_LOCK_GUARD_1_COND(spinlock_irq, _try, ++ spin_trylock_irq(_T->lock)) ++ + DEFINE_LOCK_GUARD_1(spinlock_irqsave, spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + ++DEFINE_LOCK_GUARD_1_COND(spinlock_irqsave, _try, ++ spin_trylock_irqsave(_T->lock, _T->flags)) ++ + #undef __LINUX_INSIDE_SPINLOCK_H + #endif /* __LINUX_SPINLOCK_H */ +-- +2.39.5 + diff --git a/queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch b/queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch new file mode 100644 index 00000000000..7895f6747d7 --- /dev/null +++ b/queue-6.6/cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch @@ -0,0 +1,171 @@ +From d81bc8e1b23a893d4199e396baa46e4267026c6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Oct 2024 13:38:14 +0200 +Subject: cleanup: Adjust scoped_guard() macros to avoid potential warning + +From: Przemek Kitszel + +[ Upstream commit fcc22ac5baf06dd17193de44b60dbceea6461983 ] + +Change scoped_guard() and scoped_cond_guard() macros to make reasoning +about them easier for static analysis tools (smatch, compiler +diagnostics), especially to enable them to tell if the given usage of +scoped_guard() is with a conditional lock class (interruptible-locks, +try-locks) or not (like simple mutex_lock()). + +Add compile-time error if scoped_cond_guard() is used for non-conditional +lock class. + +Beyond easier tooling and a little shrink reported by bloat-o-meter +this patch enables developer to write code like: + +int foo(struct my_drv *adapter) +{ + scoped_guard(spinlock, &adapter->some_spinlock) + return adapter->spinlock_protected_var; +} + +Current scoped_guard() implementation does not support that, +due to compiler complaining: +error: control reaches end of non-void function [-Werror=return-type] + +Technical stuff about the change: +scoped_guard() macro uses common idiom of using "for" statement to declare +a scoped variable. Unfortunately, current logic is too hard for compiler +diagnostics to be sure that there is exactly one loop step; fix that. + +To make any loop so trivial that there is no above warning, it must not +depend on any non-const variable to tell if there are more steps. There is +no obvious solution for that in C, but one could use the compound +statement expression with "goto" jumping past the "loop", effectively +leaving only the subscope part of the loop semantics. + +More impl details: +one more level of macro indirection is now needed to avoid duplicating +label names; +I didn't spot any other place that is using the +"for (...; goto label) if (0) label: break;" idiom, so it's not packed for +reuse beyond scoped_guard() family, what makes actual macros code cleaner. + +There was also a need to introduce const true/false variable per lock +class, it is used to aid compiler diagnostics reasoning about "exactly +1 step" loops (note that converting that to function would undo the whole +benefit). + +Big thanks to Andy Shevchenko for help on this patch, both internal and +public, ranging from whitespace/formatting, through commit message +clarifications, general improvements, ending with presenting alternative +approaches - all despite not even liking the idea. + +Big thanks to Dmitry Torokhov for the idea of compile-time check for +scoped_cond_guard() (to use it only with conditional locsk), and general +improvements for the patch. + +Big thanks to David Lechner for idea to cover also scoped_cond_guard(). + +Signed-off-by: Przemek Kitszel +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dmitry Torokhov +Link: https://lkml.kernel.org/r/20241018113823.171256-1-przemyslaw.kitszel@intel.com +Signed-off-by: Sasha Levin +--- + include/linux/cleanup.h | 52 +++++++++++++++++++++++++++++++++-------- + 1 file changed, 42 insertions(+), 10 deletions(-) + +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index 6d7bfa899df0..f0c6d1d45e67 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -113,14 +113,20 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + * similar to scoped_guard(), except it does fail when the lock + * acquire fails. + * ++ * Only for conditional locks. + */ + ++#define __DEFINE_CLASS_IS_CONDITIONAL(_name, _is_cond) \ ++static __maybe_unused const bool class_##_name##_is_conditional = _is_cond ++ + #define DEFINE_GUARD(_name, _type, _lock, _unlock) \ ++ __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \ + static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \ + { return *_T; } + + #define DEFINE_GUARD_COND(_name, _ext, _condlock) \ ++ __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \ + EXTEND_CLASS(_name, _ext, \ + ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \ + class_##_name##_t _T) \ +@@ -131,17 +137,40 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + CLASS(_name, __UNIQUE_ID(guard)) + + #define __guard_ptr(_name) class_##_name##_lock_ptr ++#define __is_cond_ptr(_name) class_##_name##_is_conditional + +-#define scoped_guard(_name, args...) \ +- for (CLASS(_name, scope)(args), \ +- *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1) +- +-#define scoped_cond_guard(_name, _fail, args...) \ +- for (CLASS(_name, scope)(args), \ +- *done = NULL; !done; done = (void *)1) \ +- if (!__guard_ptr(_name)(&scope)) _fail; \ +- else +- ++/* ++ * Helper macro for scoped_guard(). ++ * ++ * Note that the "!__is_cond_ptr(_name)" part of the condition ensures that ++ * compiler would be sure that for the unconditional locks the body of the ++ * loop (caller-provided code glued to the else clause) could not be skipped. ++ * It is needed because the other part - "__guard_ptr(_name)(&scope)" - is too ++ * hard to deduce (even if could be proven true for unconditional locks). ++ */ ++#define __scoped_guard(_name, _label, args...) \ ++ for (CLASS(_name, scope)(args); \ ++ __guard_ptr(_name)(&scope) || !__is_cond_ptr(_name); \ ++ ({ goto _label; })) \ ++ if (0) { \ ++_label: \ ++ break; \ ++ } else ++ ++#define scoped_guard(_name, args...) \ ++ __scoped_guard(_name, __UNIQUE_ID(label), args) ++ ++#define __scoped_cond_guard(_name, _fail, _label, args...) \ ++ for (CLASS(_name, scope)(args); true; ({ goto _label; })) \ ++ if (!__guard_ptr(_name)(&scope)) { \ ++ BUILD_BUG_ON(!__is_cond_ptr(_name)); \ ++ _fail; \ ++_label: \ ++ break; \ ++ } else ++ ++#define scoped_cond_guard(_name, _fail, args...) \ ++ __scoped_cond_guard(_name, _fail, __UNIQUE_ID(label), args) + /* + * Additional helper macros for generating lock guards with types, either for + * locks that don't have a native type (eg. RCU, preempt) or those that need a +@@ -197,14 +226,17 @@ static inline class_##_name##_t class_##_name##_constructor(void) \ + } + + #define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...) \ ++__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__) \ + __DEFINE_LOCK_GUARD_1(_name, _type, _lock) + + #define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...) \ ++__DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + __DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__) \ + __DEFINE_LOCK_GUARD_0(_name, _lock) + + #define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock) \ ++ __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \ + EXTEND_CLASS(_name, _ext, \ + ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\ + if (_T->lock && !(_condlock)) _T->lock = NULL; \ +-- +2.39.5 + diff --git a/queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch b/queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch new file mode 100644 index 00000000000..2ddeb2cb08e --- /dev/null +++ b/queue-6.6/cleanup-remove-address-space-of-returned-pointer.patch @@ -0,0 +1,60 @@ +From 8a8b512523945efc15399f4dfa0df9606970dfd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 09:41:15 +0200 +Subject: cleanup: Remove address space of returned pointer + +From: Uros Bizjak + +[ Upstream commit f730fd535fc51573f982fad629f2fc6b4a0cde2f ] + +Guard functions in local_lock.h are defined using DEFINE_GUARD() and +DEFINE_LOCK_GUARD_1() macros having lock type defined as pointer in +the percpu address space. The functions, defined by these macros +return value in generic address space, causing: + +cleanup.h:157:18: error: return from pointer to non-enclosed address space + +and + +cleanup.h:214:18: error: return from pointer to non-enclosed address space + +when strict percpu checks are enabled. + +Add explicit casts to remove address space of the returned pointer. + +Found by GCC's named address space checks. + +Fixes: e4ab322fbaaa ("cleanup: Add conditional guard support") +Signed-off-by: Uros Bizjak +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20240819074124.143565-1-ubizjak@gmail.com +Signed-off-by: Sasha Levin +--- + include/linux/cleanup.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index f0c6d1d45e67..64b8600eb8c0 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -123,7 +123,7 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond + __DEFINE_CLASS_IS_CONDITIONAL(_name, false); \ + DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \ + static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \ +- { return *_T; } ++ { return (void *)(__force unsigned long)*_T; } + + #define DEFINE_GUARD_COND(_name, _ext, _condlock) \ + __DEFINE_CLASS_IS_CONDITIONAL(_name##_ext, true); \ +@@ -204,7 +204,7 @@ static inline void class_##_name##_destructor(class_##_name##_t *_T) \ + \ + static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T) \ + { \ +- return _T->lock; \ ++ return (void *)(__force unsigned long)_T->lock; \ + } + + +-- +2.39.5 + diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch b/queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch new file mode 100644 index 00000000000..9abbc9440f8 --- /dev/null +++ b/queue-6.6/clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch @@ -0,0 +1,61 @@ +From 3e6fca922bedf3a475677799ba01c2dc75fc3316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Oct 2024 11:35:01 +0530 +Subject: clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for + ipq9574 + +From: Devi Priya + +[ Upstream commit 79dfed29aa3f714e0a94a39b2bfe9ac14ce19a6a ] + +Add support for NSS Huayra alpha pll found on ipq9574 SoCs. +Programming sequence is the same as that of Huayra type Alpha PLL, +so we can re-use the same. + +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Devi Priya +Link: https://lore.kernel.org/r/20241028060506.246606-2-quic_srichara@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-alpha-pll.c | 11 +++++++++++ + drivers/clk/qcom/clk-alpha-pll.h | 1 + + 2 files changed, 12 insertions(+) + +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 87040b949eb4..ce44dbfd47e2 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -243,6 +243,17 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { + [PLL_OFF_OPMODE] = 0x30, + [PLL_OFF_STATUS] = 0x3c, + }, ++ [CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] = { ++ [PLL_OFF_L_VAL] = 0x04, ++ [PLL_OFF_ALPHA_VAL] = 0x08, ++ [PLL_OFF_TEST_CTL] = 0x0c, ++ [PLL_OFF_TEST_CTL_U] = 0x10, ++ [PLL_OFF_USER_CTL] = 0x14, ++ [PLL_OFF_CONFIG_CTL] = 0x18, ++ [PLL_OFF_CONFIG_CTL_U] = 0x1c, ++ [PLL_OFF_STATUS] = 0x20, ++ }, ++ + }; + EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); + +diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h +index f50de33a045d..52dc5b9b546a 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.h ++++ b/drivers/clk/qcom/clk-alpha-pll.h +@@ -29,6 +29,7 @@ enum { + CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, + CLK_ALPHA_PLL_TYPE_STROMER, + CLK_ALPHA_PLL_TYPE_STROMER_PLUS, ++ CLK_ALPHA_PLL_TYPE_NSS_HUAYRA, + CLK_ALPHA_PLL_TYPE_MAX, + }; + +-- +2.39.5 + diff --git a/queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch b/queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch new file mode 100644 index 00000000000..e5c2f10de06 --- /dev/null +++ b/queue-6.6/clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch @@ -0,0 +1,96 @@ +From a95f1dad014dbec897f674977adbf57e85a97296 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 20:34:41 +0200 +Subject: clk: qcom: clk-alpha-pll: Add support for zonda ole pll configure + +From: Rajendra Nayak + +[ Upstream commit c32f4f4ae1c6035b44bb4ca7a41fa4fd51244597 ] + +Zonda ole pll has as extra PLL_OFF_CONFIG_CTL_U2 register, hence add +support for it. + +Signed-off-by: Rajendra Nayak +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20240202-x1e80100-clock-controllers-v4-6-7fb08c861c7c@linaro.org +Signed-off-by: Bjorn Andersson +Stable-dep-of: 79dfed29aa3f ("clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574") +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-alpha-pll.c | 16 ++++++++++++++++ + drivers/clk/qcom/clk-alpha-pll.h | 4 ++++ + 2 files changed, 20 insertions(+) + +diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c +index 8b3e5f84e89a..87040b949eb4 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.c ++++ b/drivers/clk/qcom/clk-alpha-pll.c +@@ -52,6 +52,7 @@ + #define PLL_CONFIG_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL]) + #define PLL_CONFIG_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U]) + #define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1]) ++#define PLL_CONFIG_CTL_U2(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U2]) + #define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL]) + #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U]) + #define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1]) +@@ -227,6 +228,21 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { + [PLL_OFF_ALPHA_VAL] = 0x24, + [PLL_OFF_ALPHA_VAL_U] = 0x28, + }, ++ [CLK_ALPHA_PLL_TYPE_ZONDA_OLE] = { ++ [PLL_OFF_L_VAL] = 0x04, ++ [PLL_OFF_ALPHA_VAL] = 0x08, ++ [PLL_OFF_USER_CTL] = 0x0c, ++ [PLL_OFF_USER_CTL_U] = 0x10, ++ [PLL_OFF_CONFIG_CTL] = 0x14, ++ [PLL_OFF_CONFIG_CTL_U] = 0x18, ++ [PLL_OFF_CONFIG_CTL_U1] = 0x1c, ++ [PLL_OFF_CONFIG_CTL_U2] = 0x20, ++ [PLL_OFF_TEST_CTL] = 0x24, ++ [PLL_OFF_TEST_CTL_U] = 0x28, ++ [PLL_OFF_TEST_CTL_U1] = 0x2c, ++ [PLL_OFF_OPMODE] = 0x30, ++ [PLL_OFF_STATUS] = 0x3c, ++ }, + }; + EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); + +diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h +index 3fd0ef41c72c..f50de33a045d 100644 +--- a/drivers/clk/qcom/clk-alpha-pll.h ++++ b/drivers/clk/qcom/clk-alpha-pll.h +@@ -21,6 +21,7 @@ enum { + CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, + CLK_ALPHA_PLL_TYPE_AGERA, + CLK_ALPHA_PLL_TYPE_ZONDA, ++ CLK_ALPHA_PLL_TYPE_ZONDA_OLE, + CLK_ALPHA_PLL_TYPE_LUCID_EVO, + CLK_ALPHA_PLL_TYPE_LUCID_OLE, + CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, +@@ -42,6 +43,7 @@ enum { + PLL_OFF_CONFIG_CTL, + PLL_OFF_CONFIG_CTL_U, + PLL_OFF_CONFIG_CTL_U1, ++ PLL_OFF_CONFIG_CTL_U2, + PLL_OFF_TEST_CTL, + PLL_OFF_TEST_CTL_U, + PLL_OFF_TEST_CTL_U1, +@@ -119,6 +121,7 @@ struct alpha_pll_config { + u32 config_ctl_val; + u32 config_ctl_hi_val; + u32 config_ctl_hi1_val; ++ u32 config_ctl_hi2_val; + u32 user_ctl_val; + u32 user_ctl_hi_val; + u32 user_ctl_hi1_val; +@@ -173,6 +176,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops; + + extern const struct clk_ops clk_alpha_pll_zonda_ops; + #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops ++#define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops + + extern const struct clk_ops clk_alpha_pll_lucid_evo_ops; + extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops; +-- +2.39.5 + diff --git a/queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch b/queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch new file mode 100644 index 00000000000..482cf5c3b75 --- /dev/null +++ b/queue-6.6/crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch @@ -0,0 +1,93 @@ +From 18bafd95480493a14aa3c863daf98b98f5030da3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 21:59:21 -0400 +Subject: crypto: ecc - Prevent ecc_digits_from_bytes from reading too many + bytes + +From: Stefan Berger + +[ Upstream commit c6ab5c915da460c0397960af3c308386c3f3247b ] + +Prevent ecc_digits_from_bytes from reading too many bytes from the input +byte array in case an insufficient number of bytes is provided to fill the +output digit array of ndigits. Therefore, initialize the most significant +digits with 0 to avoid trying to read too many bytes later on. Convert the +function into a regular function since it is getting too big for an inline +function. + +If too many bytes are provided on the input byte array the extra bytes +are ignored since the input variable 'ndigits' limits the number of digits +that will be filled. + +Fixes: d67c96fb97b5 ("crypto: ecdsa - Convert byte arrays with key coordinates to digits") +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Stefan Berger +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ecc.c | 22 ++++++++++++++++++++++ + include/crypto/internal/ecc.h | 15 ++------------- + 2 files changed, 24 insertions(+), 13 deletions(-) + +diff --git a/crypto/ecc.c b/crypto/ecc.c +index f53fb4d6af99..21504280aca2 100644 +--- a/crypto/ecc.c ++++ b/crypto/ecc.c +@@ -66,6 +66,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id) + } + EXPORT_SYMBOL(ecc_get_curve); + ++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, ++ u64 *out, unsigned int ndigits) ++{ ++ int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64)); ++ unsigned int o = nbytes & 7; ++ __be64 msd = 0; ++ ++ /* diff > 0: not enough input bytes: set most significant digits to 0 */ ++ if (diff > 0) { ++ ndigits -= diff; ++ memset(&out[ndigits - 1], 0, diff * sizeof(u64)); ++ } ++ ++ if (o) { ++ memcpy((u8 *)&msd + sizeof(msd) - o, in, o); ++ out[--ndigits] = be64_to_cpu(msd); ++ in += o; ++ } ++ ecc_swap_digits(in, out, ndigits); ++} ++EXPORT_SYMBOL(ecc_digits_from_bytes); ++ + static u64 *ecc_alloc_digits_space(unsigned int ndigits) + { + size_t len = ndigits * sizeof(u64); +diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h +index ab722a8986b7..c0b8be63cbde 100644 +--- a/include/crypto/internal/ecc.h ++++ b/include/crypto/internal/ecc.h +@@ -63,19 +63,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit + * @out Output digits array + * @ndigits: Number of digits to create from byte array + */ +-static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, +- u64 *out, unsigned int ndigits) +-{ +- unsigned int o = nbytes & 7; +- __be64 msd = 0; +- +- if (o) { +- memcpy((u8 *)&msd + sizeof(msd) - o, in, o); +- out[--ndigits] = be64_to_cpu(msd); +- in += o; +- } +- ecc_swap_digits(in, out, ndigits); +-} ++void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, ++ u64 *out, unsigned int ndigits); + + /** + * ecc_is_key_valid() - Validate a given ECDH private key +-- +2.39.5 + diff --git a/queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch b/queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch new file mode 100644 index 00000000000..767ab01106c --- /dev/null +++ b/queue-6.6/crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch @@ -0,0 +1,82 @@ +From bff91a5e31a75df1b810958068278ff04294b171 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Sep 2024 16:30:24 +0200 +Subject: crypto: ecdsa - Avoid signed integer overflow on signature decoding + +From: Lukas Wunner + +[ Upstream commit 3b0565c703503f832d6cd7ba805aafa3b330cb9d ] + +When extracting a signature component r or s from an ASN.1-encoded +integer, ecdsa_get_signature_rs() subtracts the expected length +"bufsize" from the ASN.1 length "vlen" (both of unsigned type size_t) +and stores the result in "diff" (of signed type ssize_t). + +This results in a signed integer overflow if vlen > SSIZE_MAX + bufsize. + +The kernel is compiled with -fno-strict-overflow, which implies -fwrapv, +meaning signed integer overflow is not undefined behavior. And the +function does check for overflow: + + if (-diff >= bufsize) + return -EINVAL; + +So the code is fine in principle but not very obvious. In the future it +might trigger a false-positive with CONFIG_UBSAN_SIGNED_WRAP=y. + +Avoid by comparing the two unsigned variables directly and erroring out +if "vlen" is too large. + +Signed-off-by: Lukas Wunner +Reviewed-by: Stefan Berger +Reviewed-by: Jonathan Cameron +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ecdsa.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c +index 28441311af36..da04df3c8ecf 100644 +--- a/crypto/ecdsa.c ++++ b/crypto/ecdsa.c +@@ -36,29 +36,24 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen, unsigned int ndigits) + { + size_t bufsize = ndigits * sizeof(u64); +- ssize_t diff = vlen - bufsize; + const char *d = value; + +- if (!value || !vlen) ++ if (!value || !vlen || vlen > bufsize + 1) + return -EINVAL; + +- /* diff = 0: 'value' has exacly the right size +- * diff > 0: 'value' has too many bytes; one leading zero is allowed that +- * makes the value a positive integer; error on more +- * diff < 0: 'value' is missing leading zeros ++ /* ++ * vlen may be 1 byte larger than bufsize due to a leading zero byte ++ * (necessary if the most significant bit of the integer is set). + */ +- if (diff > 0) { ++ if (vlen > bufsize) { + /* skip over leading zeros that make 'value' a positive int */ + if (*d == 0) { + vlen -= 1; +- diff--; + d++; +- } +- if (diff) ++ } else { + return -EINVAL; ++ } + } +- if (-diff >= bufsize) +- return -EINVAL; + + ecc_digits_from_bytes(d, vlen, dest, ndigits); + +-- +2.39.5 + diff --git a/queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch b/queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch new file mode 100644 index 00000000000..c3e1d67d97d --- /dev/null +++ b/queue-6.6/crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch @@ -0,0 +1,102 @@ +From 966f3aba5338678e38a7fec2811bda90f75ebaf4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 10:18:45 -0400 +Subject: crypto: ecdsa - Convert byte arrays with key coordinates to digits + +From: Stefan Berger + +[ Upstream commit d67c96fb97b5811e15c881d5cb72e293faa5f8e1 ] + +For NIST P192/256/384 the public key's x and y parameters could be copied +directly from a given array since both parameters filled 'ndigits' of +digits (a 'digit' is a u64). For support of NIST P521 the key parameters +need to have leading zeros prepended to the most significant digit since +only 2 bytes of the most significant digit are provided. + +Therefore, implement ecc_digits_from_bytes to convert a byte array into an +array of digits and use this function in ecdsa_set_pub_key where an input +byte array needs to be converted into digits. + +Suggested-by: Lukas Wunner +Tested-by: Lukas Wunner +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Stefan Berger +Signed-off-by: Herbert Xu +Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding") +Signed-off-by: Sasha Levin +--- + crypto/ecdsa.c | 14 +++++++++----- + include/crypto/internal/ecc.h | 21 +++++++++++++++++++++ + 2 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c +index 3f9ec273a121..e819d0983bd3 100644 +--- a/crypto/ecdsa.c ++++ b/crypto/ecdsa.c +@@ -222,9 +222,8 @@ static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) + static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) + { + struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); ++ unsigned int digitlen, ndigits; + const unsigned char *d = key; +- const u64 *digits = (const u64 *)&d[1]; +- unsigned int ndigits; + int ret; + + ret = ecdsa_ecc_ctx_reset(ctx); +@@ -238,12 +237,17 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsig + return -EINVAL; + + keylen--; +- ndigits = (keylen >> 1) / sizeof(u64); ++ digitlen = keylen >> 1; ++ ++ ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); + if (ndigits != ctx->curve->g.ndigits) + return -EINVAL; + +- ecc_swap_digits(digits, ctx->pub_key.x, ndigits); +- ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); ++ d++; ++ ++ ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); ++ ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); ++ + ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); + + ctx->pub_key_set = ret == 0; +diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h +index 4f6c1a68882f..ab722a8986b7 100644 +--- a/include/crypto/internal/ecc.h ++++ b/include/crypto/internal/ecc.h +@@ -56,6 +56,27 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit + out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); + } + ++/** ++ * ecc_digits_from_bytes() - Create ndigits-sized digits array from byte array ++ * @in: Input byte array ++ * @nbytes Size of input byte array ++ * @out Output digits array ++ * @ndigits: Number of digits to create from byte array ++ */ ++static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, ++ u64 *out, unsigned int ndigits) ++{ ++ unsigned int o = nbytes & 7; ++ __be64 msd = 0; ++ ++ if (o) { ++ memcpy((u8 *)&msd + sizeof(msd) - o, in, o); ++ out[--ndigits] = be64_to_cpu(msd); ++ in += o; ++ } ++ ecc_swap_digits(in, out, ndigits); ++} ++ + /** + * ecc_is_key_valid() - Validate a given ECDH private key + * +-- +2.39.5 + diff --git a/queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch b/queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch new file mode 100644 index 00000000000..b294ec35c24 --- /dev/null +++ b/queue-6.6/crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch @@ -0,0 +1,78 @@ +From 6bbf61bedb7d51bc6aed1110b9c58e0fc950b14c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 10:18:53 -0400 +Subject: crypto: ecdsa - Rename keylen to bufsize where necessary + +From: Stefan Berger + +[ Upstream commit 703ca5cda1ea04735e48882a7cccff97d57656c3 ] + +In cases where 'keylen' was referring to the size of the buffer used by +a curve's digits, it does not reflect the purpose of the variable anymore +once NIST P521 is used. What it refers to then is the size of the buffer, +which may be a few bytes larger than the size a coordinate of a key. +Therefore, rename keylen to bufsize where appropriate. + +Tested-by: Lukas Wunner +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Stefan Berger +Signed-off-by: Herbert Xu +Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding") +Signed-off-by: Sasha Levin +--- + crypto/ecdsa.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c +index e819d0983bd3..142bed98fa97 100644 +--- a/crypto/ecdsa.c ++++ b/crypto/ecdsa.c +@@ -35,8 +35,8 @@ struct ecdsa_signature_ctx { + static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen, unsigned int ndigits) + { +- size_t keylen = ndigits * sizeof(u64); +- ssize_t diff = vlen - keylen; ++ size_t bufsize = ndigits * sizeof(u64); ++ ssize_t diff = vlen - bufsize; + const char *d = value; + u8 rs[ECC_MAX_BYTES]; + +@@ -58,7 +58,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + if (diff) + return -EINVAL; + } +- if (-diff >= keylen) ++ if (-diff >= bufsize) + return -EINVAL; + + if (diff) { +@@ -138,7 +138,7 @@ static int ecdsa_verify(struct akcipher_request *req) + { + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); +- size_t keylen = ctx->curve->g.ndigits * sizeof(u64); ++ size_t bufsize = ctx->curve->g.ndigits * sizeof(u64); + struct ecdsa_signature_ctx sig_ctx = { + .curve = ctx->curve, + }; +@@ -165,14 +165,14 @@ static int ecdsa_verify(struct akcipher_request *req) + goto error; + + /* if the hash is shorter then we will add leading zeros to fit to ndigits */ +- diff = keylen - req->dst_len; ++ diff = bufsize - req->dst_len; + if (diff >= 0) { + if (diff) + memset(rawhash, 0, diff); + memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len); + } else if (diff < 0) { + /* given hash is longer, we take the left-most bytes */ +- memcpy(&rawhash, buffer + req->src_len, keylen); ++ memcpy(&rawhash, buffer + req->src_len, bufsize); + } + + ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits); +-- +2.39.5 + diff --git a/queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch b/queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch new file mode 100644 index 00000000000..389c9912640 --- /dev/null +++ b/queue-6.6/crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch @@ -0,0 +1,64 @@ +From 25239e3755b80ba5f1c7adb673d3d3b1e8007fc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 19:08:27 -0400 +Subject: crypto: ecdsa - Use ecc_digits_from_bytes to convert signature + +From: Stefan Berger + +[ Upstream commit 546ce0bdc91afd9f5c4c67d9fc4733e0fc7086d1 ] + +Since ecc_digits_from_bytes will provide zeros when an insufficient number +of bytes are passed in the input byte array, use it to convert the r and s +components of the signature to digits directly from the input byte +array. This avoids going through an intermediate byte array that has the +first few bytes filled with zeros. + +Signed-off-by: Stefan Berger +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Herbert Xu +Stable-dep-of: 3b0565c70350 ("crypto: ecdsa - Avoid signed integer overflow on signature decoding") +Signed-off-by: Sasha Levin +--- + crypto/ecdsa.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c +index 142bed98fa97..28441311af36 100644 +--- a/crypto/ecdsa.c ++++ b/crypto/ecdsa.c +@@ -38,7 +38,6 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + size_t bufsize = ndigits * sizeof(u64); + ssize_t diff = vlen - bufsize; + const char *d = value; +- u8 rs[ECC_MAX_BYTES]; + + if (!value || !vlen) + return -EINVAL; +@@ -46,7 +45,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + /* diff = 0: 'value' has exacly the right size + * diff > 0: 'value' has too many bytes; one leading zero is allowed that + * makes the value a positive integer; error on more +- * diff < 0: 'value' is missing leading zeros, which we add ++ * diff < 0: 'value' is missing leading zeros + */ + if (diff > 0) { + /* skip over leading zeros that make 'value' a positive int */ +@@ -61,14 +60,7 @@ static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + if (-diff >= bufsize) + return -EINVAL; + +- if (diff) { +- /* leading zeros not given in 'value' */ +- memset(rs, 0, -diff); +- } +- +- memcpy(&rs[-diff], d, vlen); +- +- ecc_swap_digits((u64 *)rs, dest, ndigits); ++ ecc_digits_from_bytes(d, vlen, dest, ndigits); + + return 0; + } +-- +2.39.5 + diff --git a/queue-6.6/docs-media-update-location-of-the-media-patches.patch b/queue-6.6/docs-media-update-location-of-the-media-patches.patch new file mode 100644 index 00000000000..33e63c8799e --- /dev/null +++ b/queue-6.6/docs-media-update-location-of-the-media-patches.patch @@ -0,0 +1,52 @@ +From d59373db606b374e6108c4107d48b0eaf9506573 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Nov 2024 07:05:54 +0100 +Subject: docs: media: update location of the media patches + +From: Mauro Carvalho Chehab + +[ Upstream commit 72ad4ff638047bbbdf3232178fea4bec1f429319 ] + +Due to recent changes on the way we're maintaining media, the +location of the main tree was updated. + +Change docs accordingly. + +Cc: stable@vger.kernel.org +Signed-off-by: Mauro Carvalho Chehab +Reviewed-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/media/building.rst | 2 +- + Documentation/admin-guide/media/saa7134.rst | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Documentation/admin-guide/media/building.rst b/Documentation/admin-guide/media/building.rst +index a06473429916..7a413ba07f93 100644 +--- a/Documentation/admin-guide/media/building.rst ++++ b/Documentation/admin-guide/media/building.rst +@@ -15,7 +15,7 @@ Please notice, however, that, if: + + you should use the main media development tree ``master`` branch: + +- https://git.linuxtv.org/media_tree.git/ ++ https://git.linuxtv.org/media.git/ + + In this case, you may find some useful information at the + `LinuxTv wiki pages `_: +diff --git a/Documentation/admin-guide/media/saa7134.rst b/Documentation/admin-guide/media/saa7134.rst +index 51eae7eb5ab7..18d7cbc897db 100644 +--- a/Documentation/admin-guide/media/saa7134.rst ++++ b/Documentation/admin-guide/media/saa7134.rst +@@ -67,7 +67,7 @@ Changes / Fixes + Please mail to linux-media AT vger.kernel.org unified diffs against + the linux media git tree: + +- https://git.linuxtv.org/media_tree.git/ ++ https://git.linuxtv.org/media.git/ + + This is done by committing a patch at a clone of the git tree and + submitting the patch using ``git send-email``. Don't forget to +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-fix-dsc-re-computing.patch b/queue-6.6/drm-amd-display-fix-dsc-re-computing.patch new file mode 100644 index 00000000000..41ad0e733df --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-dsc-re-computing.patch @@ -0,0 +1,74 @@ +From 6c2f9aa834ccdc6080a18cd85574238abe914960 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Apr 2024 13:53:52 -0400 +Subject: drm/amd/display: Fix DSC-re-computing + +From: Agustin Gutierrez + +[ Upstream commit b9b5a82c532109a09f4340ef5cabdfdbb0691a9d ] + +[Why] +This fixes a bug introduced by commit c53655545141 ("drm/amd/display: dsc +mst re-compute pbn for changes on hub"). +The change caused light-up issues with a second display that required +DSC on some MST docks. + +[How] +Use Virtual DPCD for DSC caps in MST case. + +[Limitations] +This change only affects MST DSC devices that follow specifications +additional changes are required to check for old MST DSC devices such as +ones which do not check for Virtual DPCD registers. + +Reviewed-by: Swapnil Patel +Reviewed-by: Hersen Wu +Acked-by: Tom Chung +Signed-off-by: Agustin Gutierrez +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Stable-dep-of: 4641169a8c95 ("drm/amd/display: Fix incorrect DSC recompute trigger") +Signed-off-by: Sasha Levin +--- + .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index 9ec9792f115a..b4bbd3be35a6 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1219,10 +1219,6 @@ static bool is_dsc_need_re_compute( + if (dc_link->type != dc_connection_mst_branch) + return false; + +- if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || +- dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) +- return false; +- + for (i = 0; i < MAX_PIPES; i++) + stream_on_link[i] = NULL; + +@@ -1240,7 +1236,19 @@ static bool is_dsc_need_re_compute( + continue; + + aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context; +- if (!aconnector) ++ if (!aconnector || !aconnector->dsc_aux) ++ continue; ++ ++ /* ++ * Check if cached virtual MST DSC caps are available and DSC is supported ++ * this change takes care of newer MST DSC capable devices that report their ++ * DPCD caps as per specifications in their Virtual DPCD registers. ++ ++ * TODO: implement the check for older MST DSC devices that do not conform to ++ * specifications. ++ */ ++ if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported || ++ aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) + continue; + + stream_on_link[new_stream_on_link_num] = aconnector; +-- +2.39.5 + diff --git a/queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch b/queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch new file mode 100644 index 00000000000..40555ac16fd --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch @@ -0,0 +1,42 @@ +From 13ffe0d08973db083440582b0886462bb6b16b2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Sep 2024 16:56:45 -0400 +Subject: drm/amd/display: Fix incorrect DSC recompute trigger + +From: Fangzhi Zuo + +[ Upstream commit 4641169a8c95d9efc35d2d3c55c3948f3b375ff9 ] + +A stream without dsc_aux should not be eliminated from +the dsc determination. Whether it needs a dsc recompute depends on +whether its mode has changed or not. Eliminating such a no-dsc stream +from the dsc determination policy will end up with inconsistencies +in the new dc_state when compared to the current dc_state, +triggering a dsc recompute that should not have happened. + +Reviewed-by: Rodrigo Siqueira +Signed-off-by: Fangzhi Zuo +Signed-off-by: Aurabindo Pillai +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +index b4bbd3be35a6..385a5a75fdf8 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +@@ -1236,7 +1236,7 @@ static bool is_dsc_need_re_compute( + continue; + + aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context; +- if (!aconnector || !aconnector->dsc_aux) ++ if (!aconnector) + continue; + + /* +-- +2.39.5 + diff --git a/queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch b/queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch new file mode 100644 index 00000000000..509fdbd2d50 --- /dev/null +++ b/queue-6.6/drm-radeon-delay-connector-detecting-when-hpd-singal.patch @@ -0,0 +1,47 @@ +From 20430c3e75a06c4736598de02404f768653d953a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 May 2024 16:57:58 +0800 +Subject: drm/radeon: Delay Connector detecting when HPD singals is unstable + +From: Shixiong Ou + +[ Upstream commit 949658cb9b69ab9d22a42a662b2fdc7085689ed8 ] + +In some causes, HPD signals will jitter when plugging in +or unplugging HDMI. + +Rescheduling the hotplug work for a second when EDID may still be +readable but HDP is disconnected, and fixes this issue. + +Signed-off-by: Shixiong Ou +Signed-off-by: Alex Deucher +Stable-dep-of: 979bfe291b5b ("Revert "drm/radeon: Delay Connector detecting when HPD singals is unstable"") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/radeon_connectors.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index b84b58926106..cf0114ca59a4 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1267,6 +1267,16 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) + goto exit; + } + } ++ ++ if (dret && radeon_connector->hpd.hpd != RADEON_HPD_NONE && ++ !radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && ++ connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) { ++ DRM_DEBUG_KMS("EDID is readable when HPD disconnected\n"); ++ schedule_delayed_work(&rdev->hotplug_work, msecs_to_jiffies(1000)); ++ ret = connector_status_disconnected; ++ goto exit; ++ } ++ + if (dret) { + radeon_connector->detected_by_load = false; + radeon_connector_free_edid(connector); +-- +2.39.5 + diff --git a/queue-6.6/ext4-convert-to-new-timestamp-accessors.patch b/queue-6.6/ext4-convert-to-new-timestamp-accessors.patch new file mode 100644 index 00000000000..1806adaffe4 --- /dev/null +++ b/queue-6.6/ext4-convert-to-new-timestamp-accessors.patch @@ -0,0 +1,351 @@ +From e75b016ff152c27764f4ffd046391b6b9577e58b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 14:52:20 -0400 +Subject: ext4: convert to new timestamp accessors + +From: Jeff Layton + +[ Upstream commit b898ab233611f7903d88c0b10f8145e1c15d3642 ] + +Convert to using the new inode timestamp accessor functions. + +Signed-off-by: Jeff Layton +Link: https://lore.kernel.org/r/20231004185347.80880-33-jlayton@kernel.org +Signed-off-by: Christian Brauner +Stable-dep-of: c7fc0366c656 ("ext4: partial zero eof block on unaligned inode size extension") +Signed-off-by: Sasha Levin +--- + fs/ext4/ext4.h | 20 +++++++++++++++----- + fs/ext4/extents.c | 11 ++++++----- + fs/ext4/ialloc.c | 4 ++-- + fs/ext4/inline.c | 4 ++-- + fs/ext4/inode.c | 19 ++++++++++--------- + fs/ext4/ioctl.c | 13 +++++++++++-- + fs/ext4/namei.c | 10 +++++----- + fs/ext4/super.c | 2 +- + fs/ext4/xattr.c | 8 ++++---- + 9 files changed, 56 insertions(+), 35 deletions(-) + +diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h +index 3db01b933c3e..60455c84a937 100644 +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -891,10 +891,13 @@ do { \ + (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (ts).tv_sec, S32_MIN, S32_MAX)); \ + } while (0) + +-#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ +- EXT4_INODE_SET_XTIME_VAL(xtime, inode, raw_inode, (inode)->xtime) ++#define EXT4_INODE_SET_ATIME(inode, raw_inode) \ ++ EXT4_INODE_SET_XTIME_VAL(i_atime, inode, raw_inode, inode_get_atime(inode)) + +-#define EXT4_INODE_SET_CTIME(inode, raw_inode) \ ++#define EXT4_INODE_SET_MTIME(inode, raw_inode) \ ++ EXT4_INODE_SET_XTIME_VAL(i_mtime, inode, raw_inode, inode_get_mtime(inode)) ++ ++#define EXT4_INODE_SET_CTIME(inode, raw_inode) \ + EXT4_INODE_SET_XTIME_VAL(i_ctime, inode, raw_inode, inode_get_ctime(inode)) + + #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ +@@ -910,9 +913,16 @@ do { \ + .tv_sec = (signed)le32_to_cpu((raw_inode)->xtime) \ + }) + +-#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode) \ ++#define EXT4_INODE_GET_ATIME(inode, raw_inode) \ ++do { \ ++ inode_set_atime_to_ts(inode, \ ++ EXT4_INODE_GET_XTIME_VAL(i_atime, inode, raw_inode)); \ ++} while (0) ++ ++#define EXT4_INODE_GET_MTIME(inode, raw_inode) \ + do { \ +- (inode)->xtime = EXT4_INODE_GET_XTIME_VAL(xtime, inode, raw_inode); \ ++ inode_set_mtime_to_ts(inode, \ ++ EXT4_INODE_GET_XTIME_VAL(i_mtime, inode, raw_inode)); \ + } while (0) + + #define EXT4_INODE_GET_CTIME(inode, raw_inode) \ +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 5ea75af6ca22..f2341d99d09f 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4532,7 +4532,8 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + if (epos > new_size) + epos = new_size; + if (ext4_update_inode_size(inode, epos) & 0x1) +- inode->i_mtime = inode_get_ctime(inode); ++ inode_set_mtime_to_ts(inode, ++ inode_get_ctime(inode)); + } + ret2 = ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); +@@ -4670,7 +4671,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, + + /* Now release the pages and zero block aligned part of pages */ + truncate_pagecache_range(inode, start, end - 1); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + + ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size, + flags); +@@ -4695,7 +4696,7 @@ static long ext4_zero_range(struct file *file, loff_t offset, + goto out_mutex; + } + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + if (new_size) + ext4_update_inode_size(inode, new_size); + ret = ext4_mark_inode_dirty(handle, inode); +@@ -5431,7 +5432,7 @@ static int ext4_collapse_range(struct file *file, loff_t offset, loff_t len) + up_write(&EXT4_I(inode)->i_data_sem); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret = ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); + +@@ -5541,7 +5542,7 @@ static int ext4_insert_range(struct file *file, loff_t offset, loff_t len) + /* Expand file to avoid data loss if there is error while shifting */ + inode->i_size += len; + EXT4_I(inode)->i_disksize += len; +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret = ext4_mark_inode_dirty(handle, inode); + if (ret) + goto out_stop; +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index d4d0ad689d3c..52f2959d29e6 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -1255,8 +1255,8 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap, + inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); + /* This is the optimal IO size (for stat), not the fs block size */ + inode->i_blocks = 0; +- inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode); +- ei->i_crtime = inode->i_mtime; ++ simple_inode_init_ts(inode); ++ ei->i_crtime = inode_get_mtime(inode); + + memset(ei->i_data, 0, sizeof(ei->i_data)); + ei->i_dir_start_lookup = 0; +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index cb65052ee3de..3f363276ddd3 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1037,7 +1037,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, + * happen is that the times are slightly out of date + * and/or different from the directory change time. + */ +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + inode_inc_iversion(dir); + return 1; +@@ -2010,7 +2010,7 @@ int ext4_inline_data_truncate(struct inode *inode, int *has_inline) + ext4_orphan_del(handle, inode); + + if (err == 0) { +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err = ext4_mark_inode_dirty(handle, inode); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 18ec9106c5b0..04f25a04f35a 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4055,7 +4055,7 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length) + if (IS_SYNC(inode)) + ext4_handle_sync(handle); + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + ret2 = ext4_mark_inode_dirty(handle, inode); + if (unlikely(ret2)) + ret = ret2; +@@ -4215,7 +4215,7 @@ int ext4_truncate(struct inode *inode) + if (inode->i_nlink) + ext4_orphan_del(handle, inode); + +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err2 = ext4_mark_inode_dirty(handle, inode); + if (unlikely(err2 && !err)) + err = err2; +@@ -4319,8 +4319,8 @@ static int ext4_fill_raw_inode(struct inode *inode, struct ext4_inode *raw_inode + raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); + + EXT4_INODE_SET_CTIME(inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_SET_MTIME(inode, raw_inode); ++ EXT4_INODE_SET_ATIME(inode, raw_inode); + EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); + + raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); +@@ -4928,8 +4928,8 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + } + + EXT4_INODE_GET_CTIME(inode, raw_inode); +- EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_GET_ATIME(inode, raw_inode); ++ EXT4_INODE_GET_MTIME(inode, raw_inode); + EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); + + if (likely(!test_opt2(inode->i_sb, HURD_COMPAT))) { +@@ -5054,8 +5054,8 @@ static void __ext4_update_other_inode_time(struct super_block *sb, + + spin_lock(&ei->i_raw_lock); + EXT4_INODE_SET_CTIME(inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); +- EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); ++ EXT4_INODE_SET_MTIME(inode, raw_inode); ++ EXT4_INODE_SET_ATIME(inode, raw_inode); + ext4_inode_csum_set(inode, raw_inode, ei); + spin_unlock(&ei->i_raw_lock); + trace_ext4_other_inode_update_time(inode, orig_ino); +@@ -5451,7 +5451,8 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + * update c/mtime in shrink case below + */ + if (!shrink) +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, ++ inode_set_ctime_current(inode)); + + if (shrink) + ext4_fc_track_range(handle, inode, +diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c +index 0bfe2ce589e2..4f931f80cb34 100644 +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -312,13 +312,22 @@ static void swap_inode_data(struct inode *inode1, struct inode *inode2) + struct ext4_inode_info *ei1; + struct ext4_inode_info *ei2; + unsigned long tmp; ++ struct timespec64 ts1, ts2; + + ei1 = EXT4_I(inode1); + ei2 = EXT4_I(inode2); + + swap(inode1->i_version, inode2->i_version); +- swap(inode1->i_atime, inode2->i_atime); +- swap(inode1->i_mtime, inode2->i_mtime); ++ ++ ts1 = inode_get_atime(inode1); ++ ts2 = inode_get_atime(inode2); ++ inode_set_atime_to_ts(inode1, ts2); ++ inode_set_atime_to_ts(inode2, ts1); ++ ++ ts1 = inode_get_mtime(inode1); ++ ts2 = inode_get_mtime(inode2); ++ inode_set_mtime_to_ts(inode1, ts2); ++ inode_set_mtime_to_ts(inode2, ts1); + + memswap(ei1->i_data, ei2->i_data, sizeof(ei1->i_data)); + tmp = ei1->i_flags & EXT4_FL_SHOULD_SWAP; +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 4de1f61bba76..96a048d3f51b 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2210,7 +2210,7 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, + * happen is that the times are slightly out of date + * and/or different from the directory change time. + */ +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + inode_inc_iversion(dir); + err2 = ext4_mark_inode_dirty(handle, dir); +@@ -3248,7 +3248,7 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) + * recovery. */ + inode->i_size = 0; + ext4_orphan_add(handle, inode); +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + inode_set_ctime_current(inode); + retval = ext4_mark_inode_dirty(handle, inode); + if (retval) +@@ -3323,7 +3323,7 @@ int __ext4_unlink(struct inode *dir, const struct qstr *d_name, + retval = ext4_delete_entry(handle, dir, de, bh); + if (retval) + goto out_handle; +- dir->i_mtime = inode_set_ctime_current(dir); ++ inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); + ext4_update_dx_flag(dir); + retval = ext4_mark_inode_dirty(handle, dir); + if (retval) +@@ -3691,7 +3691,7 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, + if (ext4_has_feature_filetype(ent->dir->i_sb)) + ent->de->file_type = file_type; + inode_inc_iversion(ent->dir); +- ent->dir->i_mtime = inode_set_ctime_current(ent->dir); ++ inode_set_mtime_to_ts(ent->dir, inode_set_ctime_current(ent->dir)); + retval = ext4_mark_inode_dirty(handle, ent->dir); + BUFFER_TRACE(ent->bh, "call ext4_handle_dirty_metadata"); + if (!ent->inlined) { +@@ -4006,7 +4006,7 @@ static int ext4_rename(struct mnt_idmap *idmap, struct inode *old_dir, + ext4_dec_count(new.inode); + inode_set_ctime_current(new.inode); + } +- old.dir->i_mtime = inode_set_ctime_current(old.dir); ++ inode_set_mtime_to_ts(old.dir, inode_set_ctime_current(old.dir)); + ext4_update_dx_flag(old.dir); + if (old.dir_bh) { + retval = ext4_rename_dir_finish(handle, &old, new.dir->i_ino); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 2346ef071b24..71ced0ada9a2 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -7180,7 +7180,7 @@ static int ext4_quota_off(struct super_block *sb, int type) + } + EXT4_I(inode)->i_flags &= ~(EXT4_NOATIME_FL | EXT4_IMMUTABLE_FL); + inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE); +- inode->i_mtime = inode_set_ctime_current(inode); ++ inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); + err = ext4_mark_inode_dirty(handle, inode); + ext4_journal_stop(handle); + out_unlock: +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index f40785bc4e55..df5ab1a75fc4 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -356,7 +356,7 @@ ext4_xattr_inode_hash(struct ext4_sb_info *sbi, const void *buffer, size_t size) + + static u64 ext4_xattr_inode_get_ref(struct inode *ea_inode) + { +- return ((u64) inode_get_ctime(ea_inode).tv_sec << 32) | ++ return ((u64) inode_get_ctime_sec(ea_inode) << 32) | + (u32) inode_peek_iversion_raw(ea_inode); + } + +@@ -368,12 +368,12 @@ static void ext4_xattr_inode_set_ref(struct inode *ea_inode, u64 ref_count) + + static u32 ext4_xattr_inode_get_hash(struct inode *ea_inode) + { +- return (u32)ea_inode->i_atime.tv_sec; ++ return (u32) inode_get_atime_sec(ea_inode); + } + + static void ext4_xattr_inode_set_hash(struct inode *ea_inode, u32 hash) + { +- ea_inode->i_atime.tv_sec = hash; ++ inode_set_atime(ea_inode, hash, 0); + } + + /* +@@ -418,7 +418,7 @@ static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size) + return ret; + } + +-#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode)->i_mtime.tv_sec) ++#define EXT4_XATTR_INODE_GET_PARENT(inode) ((__u32)(inode_get_mtime_sec(inode))) + + static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, + u32 ea_inode_hash, struct inode **ea_inode) +-- +2.39.5 + diff --git a/queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch b/queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch new file mode 100644 index 00000000000..c09f2a71e2b --- /dev/null +++ b/queue-6.6/ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch @@ -0,0 +1,179 @@ +From b4c61306206b6b231fc73a688d1b6a45c019d998 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Sep 2024 12:07:40 -0400 +Subject: ext4: partial zero eof block on unaligned inode size extension + +From: Brian Foster + +[ Upstream commit c7fc0366c65628fd69bfc310affec4918199aae2 ] + +Using mapped writes, it's technically possible to expose stale +post-eof data on a truncate up operation. Consider the following +example: + +$ xfs_io -fc "pwrite 0 2k" -c "mmap 0 4k" -c "mwrite 2k 2k" \ + -c "truncate 8k" -c "pread -v 2k 16" +... +00000800: 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXXXXXXXX +... + +This shows that the post-eof data written via mwrite lands within +EOF after a truncate up. While this is deliberate of the test case, +behavior is somewhat unpredictable because writeback does post-eof +zeroing, and writeback can occur at any time in the background. For +example, an fsync inserted between the mwrite and truncate causes +the subsequent read to instead return zeroes. This basically means +that there is a race window in this situation between any subsequent +extending operation and writeback that dictates whether post-eof +data is exposed to the file or zeroed. + +To prevent this problem, perform partial block zeroing as part of +the various inode size extending operations that are susceptible to +it. For truncate extension, zero around the original eof similar to +how truncate down does partial zeroing of the new eof. For extension +via writes and fallocate related operations, zero the newly exposed +range of the file to cover any partial zeroing that must occur at +the original and new eof blocks. + +Signed-off-by: Brian Foster +Link: https://patch.msgid.link/20240919160741.208162-2-bfoster@redhat.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/extents.c | 7 ++++++- + fs/ext4/inode.c | 51 +++++++++++++++++++++++++++++++++-------------- + 2 files changed, 42 insertions(+), 16 deletions(-) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index f2341d99d09f..32218ac7f50f 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4475,7 +4475,7 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + int depth = 0; + struct ext4_map_blocks map; + unsigned int credits; +- loff_t epos; ++ loff_t epos, old_size = i_size_read(inode); + + BUG_ON(!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)); + map.m_lblk = offset; +@@ -4534,6 +4534,11 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset, + if (ext4_update_inode_size(inode, epos) & 0x1) + inode_set_mtime_to_ts(inode, + inode_get_ctime(inode)); ++ if (epos > old_size) { ++ pagecache_isize_extended(inode, old_size, epos); ++ ext4_zero_partial_blocks(handle, inode, ++ old_size, epos - old_size); ++ } + } + ret2 = ext4_mark_inode_dirty(handle, inode); + ext4_update_inode_fsync_trans(handle, inode, 1); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 04f25a04f35a..19d7bcf16ebb 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1328,8 +1328,10 @@ static int ext4_write_end(struct file *file, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos && !verity) ++ if (old_size < pos && !verity) { + pagecache_isize_extended(inode, old_size, pos); ++ ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); ++ } + /* + * Don't mark the inode dirty under folio lock. First, it unnecessarily + * makes the holding time of folio lock longer. Second, it forces lock +@@ -1445,8 +1447,10 @@ static int ext4_journalled_write_end(struct file *file, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos && !verity) ++ if (old_size < pos && !verity) { + pagecache_isize_extended(inode, old_size, pos); ++ ext4_zero_partial_blocks(handle, inode, old_size, pos - old_size); ++ } + + if (size_changed) { + ret2 = ext4_mark_inode_dirty(handle, inode); +@@ -2971,7 +2975,8 @@ static int ext4_da_do_write_end(struct address_space *mapping, + struct inode *inode = mapping->host; + loff_t old_size = inode->i_size; + bool disksize_changed = false; +- loff_t new_i_size; ++ loff_t new_i_size, zero_len = 0; ++ handle_t *handle; + + if (unlikely(!folio_buffers(folio))) { + folio_unlock(folio); +@@ -3015,18 +3020,21 @@ static int ext4_da_do_write_end(struct address_space *mapping, + folio_unlock(folio); + folio_put(folio); + +- if (old_size < pos) ++ if (pos > old_size) { + pagecache_isize_extended(inode, old_size, pos); ++ zero_len = pos - old_size; ++ } + +- if (disksize_changed) { +- handle_t *handle; ++ if (!disksize_changed && !zero_len) ++ return copied; + +- handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); +- if (IS_ERR(handle)) +- return PTR_ERR(handle); +- ext4_mark_inode_dirty(handle, inode); +- ext4_journal_stop(handle); +- } ++ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); ++ if (IS_ERR(handle)) ++ return PTR_ERR(handle); ++ if (zero_len) ++ ext4_zero_partial_blocks(handle, inode, old_size, zero_len); ++ ext4_mark_inode_dirty(handle, inode); ++ ext4_journal_stop(handle); + + return copied; + } +@@ -5437,6 +5445,14 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + } + + if (attr->ia_size != inode->i_size) { ++ /* attach jbd2 jinode for EOF folio tail zeroing */ ++ if (attr->ia_size & (inode->i_sb->s_blocksize - 1) || ++ oldsize & (inode->i_sb->s_blocksize - 1)) { ++ error = ext4_inode_attach_jinode(inode); ++ if (error) ++ goto err_out; ++ } ++ + handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); +@@ -5447,12 +5463,17 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + orphan = 1; + } + /* +- * Update c/mtime on truncate up, ext4_truncate() will +- * update c/mtime in shrink case below ++ * Update c/mtime and tail zero the EOF folio on ++ * truncate up. ext4_truncate() handles the shrink case ++ * below. + */ +- if (!shrink) ++ if (!shrink) { + inode_set_mtime_to_ts(inode, + inode_set_ctime_current(inode)); ++ if (oldsize & (inode->i_sb->s_blocksize - 1)) ++ ext4_block_truncate_page(handle, ++ inode->i_mapping, oldsize); ++ } + + if (shrink) + ext4_fc_track_range(handle, inode, +-- +2.39.5 + diff --git a/queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch b/queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch new file mode 100644 index 00000000000..902a9b6f29c --- /dev/null +++ b/queue-6.6/fs-ntfs3-fix-warning-in-ni_fiemap.patch @@ -0,0 +1,293 @@ +From ffe61420d97aacd8aa85cd89c8272ec22e62b5c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 10:48:15 +0300 +Subject: fs/ntfs3: Fix warning in ni_fiemap + +From: Konstantin Komarov + +[ Upstream commit e2705dd3d16d1000f1fd8193d82447065de8c899 ] + +Use local runs_tree instead of cached. This way excludes rw_semaphore lock. + +Reported-by: syzbot+1c25748a40fe79b8a119@syzkaller.appspotmail.com +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/attrib.c | 9 ++-- + fs/ntfs3/frecord.c | 103 +++++++-------------------------------------- + fs/ntfs3/ntfs_fs.h | 3 +- + 3 files changed, 21 insertions(+), 94 deletions(-) + +diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c +index 582628b9b796..e25989dd2c6b 100644 +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -978,7 +978,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + + /* Check for compressed frame. */ + err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT, +- &hint); ++ &hint, run); + if (err) + goto out; + +@@ -1534,16 +1534,16 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, + * attr_is_frame_compressed - Used to detect compressed frame. + * + * attr - base (primary) attribute segment. ++ * run - run to use, usually == &ni->file.run. + * Only base segments contains valid 'attr->nres.c_unit' + */ + int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, +- CLST frame, CLST *clst_data) ++ CLST frame, CLST *clst_data, struct runs_tree *run) + { + int err; + u32 clst_frame; + CLST clen, lcn, vcn, alen, slen, vcn_next; + size_t idx; +- struct runs_tree *run; + + *clst_data = 0; + +@@ -1555,7 +1555,6 @@ int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, + + clst_frame = 1u << attr->nres.c_unit; + vcn = frame * clst_frame; +- run = &ni->file.run; + + if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) { + err = attr_load_runs_vcn(ni, attr->type, attr_name(attr), +@@ -1691,7 +1690,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + if (err) + goto out; + +- err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data); ++ err = attr_is_frame_compressed(ni, attr_b, frame, &clst_data, run); + if (err) + goto out; + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 12e03feb3074..3c876c468c2c 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1900,46 +1900,6 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, + return REPARSE_LINK; + } + +-/* +- * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent +- * but it uses 'fe_k' instead of fieinfo->fi_extents_start +- */ +-static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo, +- struct fiemap_extent *fe_k, u64 logical, +- u64 phys, u64 len, u32 flags) +-{ +- struct fiemap_extent extent; +- +- /* only count the extents */ +- if (fieinfo->fi_extents_max == 0) { +- fieinfo->fi_extents_mapped++; +- return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; +- } +- +- if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max) +- return 1; +- +- if (flags & FIEMAP_EXTENT_DELALLOC) +- flags |= FIEMAP_EXTENT_UNKNOWN; +- if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED) +- flags |= FIEMAP_EXTENT_ENCODED; +- if (flags & (FIEMAP_EXTENT_DATA_TAIL | FIEMAP_EXTENT_DATA_INLINE)) +- flags |= FIEMAP_EXTENT_NOT_ALIGNED; +- +- memset(&extent, 0, sizeof(extent)); +- extent.fe_logical = logical; +- extent.fe_physical = phys; +- extent.fe_length = len; +- extent.fe_flags = flags; +- +- memcpy(fe_k + fieinfo->fi_extents_mapped, &extent, sizeof(extent)); +- +- fieinfo->fi_extents_mapped++; +- if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max) +- return 1; +- return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; +-} +- + /* + * ni_fiemap - Helper for file_fiemap(). + * +@@ -1950,11 +1910,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + __u64 vbo, __u64 len) + { + int err = 0; +- struct fiemap_extent *fe_k = NULL; + struct ntfs_sb_info *sbi = ni->mi.sbi; + u8 cluster_bits = sbi->cluster_bits; +- struct runs_tree *run; +- struct rw_semaphore *run_lock; ++ struct runs_tree run; + struct ATTRIB *attr; + CLST vcn = vbo >> cluster_bits; + CLST lcn, clen; +@@ -1965,13 +1923,11 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + u32 flags; + bool ok; + ++ run_init(&run); + if (S_ISDIR(ni->vfs_inode.i_mode)) { +- run = &ni->dir.alloc_run; + attr = ni_find_attr(ni, NULL, NULL, ATTR_ALLOC, I30_NAME, + ARRAY_SIZE(I30_NAME), NULL, NULL); +- run_lock = &ni->dir.run_lock; + } else { +- run = &ni->file.run; + attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, + NULL); + if (!attr) { +@@ -1986,7 +1942,6 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + "fiemap is not supported for compressed file (cp -r)"); + goto out; + } +- run_lock = &ni->file.run_lock; + } + + if (!attr || !attr->non_res) { +@@ -1998,51 +1953,33 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + goto out; + } + +- /* +- * To avoid lock problems replace pointer to user memory by pointer to kernel memory. +- */ +- fe_k = kmalloc_array(fieinfo->fi_extents_max, +- sizeof(struct fiemap_extent), +- GFP_NOFS | __GFP_ZERO); +- if (!fe_k) { +- err = -ENOMEM; +- goto out; +- } +- + end = vbo + len; + alloc_size = le64_to_cpu(attr->nres.alloc_size); + if (end > alloc_size) + end = alloc_size; + +- down_read(run_lock); + + while (vbo < end) { + if (idx == -1) { +- ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx); ++ ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); + } else { + CLST vcn_next = vcn; + +- ok = run_get_entry(run, ++idx, &vcn, &lcn, &clen) && ++ ok = run_get_entry(&run, ++idx, &vcn, &lcn, &clen) && + vcn == vcn_next; + if (!ok) + vcn = vcn_next; + } + + if (!ok) { +- up_read(run_lock); +- down_write(run_lock); +- + err = attr_load_runs_vcn(ni, attr->type, + attr_name(attr), +- attr->name_len, run, vcn); +- +- up_write(run_lock); +- down_read(run_lock); ++ attr->name_len, &run, vcn); + + if (err) + break; + +- ok = run_lookup_entry(run, vcn, &lcn, &clen, &idx); ++ ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); + + if (!ok) { + err = -EINVAL; +@@ -2067,8 +2004,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + } else if (is_attr_compressed(attr)) { + CLST clst_data; + +- err = attr_is_frame_compressed( +- ni, attr, vcn >> attr->nres.c_unit, &clst_data); ++ err = attr_is_frame_compressed(ni, attr, ++ vcn >> attr->nres.c_unit, ++ &clst_data, &run); + if (err) + break; + if (clst_data < NTFS_LZNT_CLUSTERS) +@@ -2097,8 +2035,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + if (vbo + dlen >= end) + flags |= FIEMAP_EXTENT_LAST; + +- err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, +- dlen, flags); ++ err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, ++ flags); + + if (err < 0) + break; +@@ -2119,8 +2057,7 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + if (vbo + bytes >= end) + flags |= FIEMAP_EXTENT_LAST; + +- err = fiemap_fill_next_extent_k(fieinfo, fe_k, vbo, lbo, bytes, +- flags); ++ err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); + if (err < 0) + break; + if (err == 1) { +@@ -2131,19 +2068,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, + vbo += bytes; + } + +- up_read(run_lock); +- +- /* +- * Copy to user memory out of lock +- */ +- if (copy_to_user(fieinfo->fi_extents_start, fe_k, +- fieinfo->fi_extents_max * +- sizeof(struct fiemap_extent))) { +- err = -EFAULT; +- } +- + out: +- kfree(fe_k); ++ run_close(&run); + return err; + } + +@@ -2674,7 +2600,8 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, + down_write(&ni->file.run_lock); + run_truncate_around(run, le64_to_cpu(attr->nres.svcn)); + frame = frame_vbo >> (cluster_bits + NTFS_LZNT_CUNIT); +- err = attr_is_frame_compressed(ni, attr, frame, &clst_data); ++ err = attr_is_frame_compressed(ni, attr, frame, &clst_data, ++ run); + up_write(&ni->file.run_lock); + if (err) + goto out1; +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index cfe9d3bf07f9..c98e6868bfba 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -446,7 +446,8 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, + struct runs_tree *run, u64 frame, u64 frames, + u8 frame_bits, u32 *ondisk_size, u64 *vbo_data); + int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, +- CLST frame, CLST *clst_data); ++ CLST frame, CLST *clst_data, ++ struct runs_tree *run); + int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + u64 new_valid); + int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes); +-- +2.39.5 + diff --git a/queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch b/queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch new file mode 100644 index 00000000000..3c16cd287e0 --- /dev/null +++ b/queue-6.6/fs-ntfs3-implement-fallocate-for-compressed-files.patch @@ -0,0 +1,93 @@ +From 3e0d6209482e390039e43b4f876faf149173a248 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jul 2024 17:45:12 +0300 +Subject: fs/ntfs3: Implement fallocate for compressed files + +From: Konstantin Komarov + +[ Upstream commit 9a2d6a40b8a1a6fa62eaf47ceee10a5eef62284c ] + +Signed-off-by: Konstantin Komarov +Stable-dep-of: e2705dd3d16d ("fs/ntfs3: Fix warning in ni_fiemap") +Signed-off-by: Sasha Levin +--- + fs/ntfs3/attrib.c | 25 +++++++++++++++---------- + fs/ntfs3/inode.c | 3 ++- + 2 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c +index fc6cea60044e..582628b9b796 100644 +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -977,15 +977,17 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + goto out; + + /* Check for compressed frame. */ +- err = attr_is_frame_compressed(ni, attr, vcn >> NTFS_LZNT_CUNIT, &hint); ++ err = attr_is_frame_compressed(ni, attr_b, vcn >> NTFS_LZNT_CUNIT, ++ &hint); + if (err) + goto out; + + if (hint) { + /* if frame is compressed - don't touch it. */ + *lcn = COMPRESSED_LCN; +- *len = hint; +- err = -EOPNOTSUPP; ++ /* length to the end of frame. */ ++ *len = NTFS_LZNT_CLUSTERS - (vcn & (NTFS_LZNT_CLUSTERS - 1)); ++ err = 0; + goto out; + } + +@@ -1028,16 +1030,16 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, + + /* Check if 'vcn' and 'vcn0' in different attribute segments. */ + if (vcn < svcn || evcn1 <= vcn) { +- /* Load attribute for truncated vcn. */ +- attr = ni_find_attr(ni, attr_b, &le, ATTR_DATA, NULL, 0, +- &vcn, &mi); +- if (!attr) { ++ struct ATTRIB *attr2; ++ /* Load runs for truncated vcn. */ ++ attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL, ++ 0, &vcn, &mi); ++ if (!attr2) { + err = -EINVAL; + goto out; + } +- svcn = le64_to_cpu(attr->nres.svcn); +- evcn1 = le64_to_cpu(attr->nres.evcn) + 1; +- err = attr_load_runs(attr, ni, run, NULL); ++ evcn1 = le64_to_cpu(attr2->nres.evcn) + 1; ++ err = attr_load_runs(attr2, ni, run, NULL); + if (err) + goto out; + } +@@ -1530,6 +1532,9 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct ATTRIB *attr, + + /* + * attr_is_frame_compressed - Used to detect compressed frame. ++ * ++ * attr - base (primary) attribute segment. ++ * Only base segments contains valid 'attr->nres.c_unit' + */ + int attr_is_frame_compressed(struct ntfs_inode *ni, struct ATTRIB *attr, + CLST frame, CLST *clst_data) +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 52b80fd15914..af7c0cbba74e 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -604,7 +604,8 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo, + + bytes = ((u64)len << cluster_bits) - off; + +- if (lcn == SPARSE_LCN) { ++ if (lcn >= sbi->used.bitmap.nbits) { ++ /* This case includes resident/compressed/sparse. */ + if (!create) { + if (bh->b_size > bytes) + bh->b_size = bytes; +-- +2.39.5 + diff --git a/queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch b/queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch new file mode 100644 index 00000000000..8023144eab2 --- /dev/null +++ b/queue-6.6/fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch @@ -0,0 +1,248 @@ +From 5e439435fd1e50f0f2fc17e194fe5602c41bf82a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2024 11:05:13 +0100 +Subject: fs/smb/client: implement chmod() for SMB3 POSIX Extensions + +From: Ralph Boehme + +[ Upstream commit d413eabff18d640031fc955d107ad9c03c3bf9f1 ] + +The NT ACL format for an SMB3 POSIX Extensions chmod() is a single ACE with the +magic S-1-5-88-3-mode SID: + + NT Security Descriptor + Revision: 1 + Type: 0x8004, Self Relative, DACL Present + Offset to owner SID: 56 + Offset to group SID: 124 + Offset to SACL: 0 + Offset to DACL: 20 + Owner: S-1-5-21-3177838999-3893657415-1037673384-1000 + Group: S-1-22-2-1000 + NT User (DACL) ACL + Revision: NT4 (2) + Size: 36 + Num ACEs: 1 + NT ACE: S-1-5-88-3-438, flags 0x00, Access Allowed, mask 0x00000000 + Type: Access Allowed + NT ACE Flags: 0x00 + Size: 28 + Access required: 0x00000000 + SID: S-1-5-88-3-438 + +Owner and Group should be NULL, but the server is not required to fail the +request if they are present. + +Signed-off-by: Ralph Boehme +Cc: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 50 +++++++++++++++++++++++---------------- + fs/smb/client/cifsproto.h | 4 +++- + fs/smb/client/inode.c | 4 +++- + fs/smb/client/smb2pdu.c | 2 +- + 4 files changed, 37 insertions(+), 23 deletions(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index e2ec1d934335..bff8d0dd74fe 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -885,12 +885,17 @@ unsigned int setup_authusers_ACE(struct smb_ace *pntace) + * Fill in the special SID based on the mode. See + * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx + */ +-unsigned int setup_special_mode_ACE(struct smb_ace *pntace, __u64 nmode) ++unsigned int setup_special_mode_ACE(struct smb_ace *pntace, ++ bool posix, ++ __u64 nmode) + { + int i; + unsigned int ace_size = 28; + +- pntace->type = ACCESS_DENIED_ACE_TYPE; ++ if (posix) ++ pntace->type = ACCESS_ALLOWED_ACE_TYPE; ++ else ++ pntace->type = ACCESS_DENIED_ACE_TYPE; + pntace->flags = 0x0; + pntace->access_req = 0; + pntace->sid.num_subauth = 3; +@@ -933,7 +938,8 @@ static void populate_new_aces(char *nacl_base, + struct smb_sid *pownersid, + struct smb_sid *pgrpsid, + __u64 *pnmode, u32 *pnum_aces, u16 *pnsize, +- bool modefromsid) ++ bool modefromsid, ++ bool posix) + { + __u64 nmode; + u32 num_aces = 0; +@@ -950,13 +956,15 @@ static void populate_new_aces(char *nacl_base, + num_aces = *pnum_aces; + nsize = *pnsize; + +- if (modefromsid) { +- pnntace = (struct smb_ace *) (nacl_base + nsize); +- nsize += setup_special_mode_ACE(pnntace, nmode); +- num_aces++; ++ if (modefromsid || posix) { + pnntace = (struct smb_ace *) (nacl_base + nsize); +- nsize += setup_authusers_ACE(pnntace); ++ nsize += setup_special_mode_ACE(pnntace, posix, nmode); + num_aces++; ++ if (modefromsid) { ++ pnntace = (struct smb_ace *) (nacl_base + nsize); ++ nsize += setup_authusers_ACE(pnntace); ++ num_aces++; ++ } + goto set_size; + } + +@@ -1076,7 +1084,7 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p + + static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + struct smb_sid *pownersid, struct smb_sid *pgrpsid, +- __u64 *pnmode, bool mode_from_sid) ++ __u64 *pnmode, bool mode_from_sid, bool posix) + { + int i; + u16 size = 0; +@@ -1094,11 +1102,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + nsize = sizeof(struct smb_acl); + + /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */ +- if (!pdacl) { ++ if (!pdacl || posix) { + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + goto finalize_dacl; + } + +@@ -1115,7 +1123,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + + new_aces_set = true; + } +@@ -1144,7 +1152,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + populate_new_aces(nacl_base, + pownersid, pgrpsid, + pnmode, &num_aces, &nsize, +- mode_from_sid); ++ mode_from_sid, posix); + + new_aces_set = true; + } +@@ -1251,7 +1259,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + /* Convert permission bits from mode to equivalent CIFS ACL */ + static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid, +- bool mode_from_sid, bool id_from_sid, int *aclflag) ++ bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag) + { + int rc = 0; + __u32 dacloffset; +@@ -1288,7 +1296,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + ndacl_ptr->num_aces = cpu_to_le32(0); + + rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr, +- pnmode, mode_from_sid); ++ pnmode, mode_from_sid, posix); + + sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); + /* copy the non-dacl portion of secdesc */ +@@ -1587,6 +1595,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); + struct smb_version_operations *ops; + bool mode_from_sid, id_from_sid; ++ bool posix = tlink_tcon(tlink)->posix_extensions; + const u32 info = 0; + + if (IS_ERR(tlink)) +@@ -1622,12 +1631,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + id_from_sid = false; + + /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */ +- nsecdesclen = secdesclen; + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ +- if (mode_from_sid) +- nsecdesclen += 2 * sizeof(struct smb_ace); ++ if (posix) ++ nsecdesclen = 1 * sizeof(struct smb_ace); ++ else if (mode_from_sid) ++ nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace)); + else /* cifsacl */ +- nsecdesclen += 5 * sizeof(struct smb_ace); ++ nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace)); + } else { /* chown */ + /* When ownership changes, changes new owner sid length could be different */ + nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); +@@ -1657,7 +1667,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + } + + rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid, +- mode_from_sid, id_from_sid, &aclflag); ++ mode_from_sid, id_from_sid, posix, &aclflag); + + cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); + +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 6399dbd04625..a151ffffc6f3 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -242,7 +242,9 @@ extern int cifs_set_acl(struct mnt_idmap *idmap, + extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, + const char *path, int flag); + extern unsigned int setup_authusers_ACE(struct smb_ace *pace); +-extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, __u64 nmode); ++extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, ++ bool posix, ++ __u64 nmode); + extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace); + + extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index ce7e0aed8f7d..b3e59a7c7120 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -3087,6 +3087,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) + int rc = -EACCES; + __u32 dosattr = 0; + __u64 mode = NO_CHANGE_64; ++ bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions; + + xid = get_xid(); + +@@ -3177,7 +3178,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) + mode = attrs->ia_mode; + rc = 0; + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || +- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { ++ (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) || ++ posix) { + rc = id_mode_to_cifs_acl(inode, full_path, &mode, + INVALID_UID, INVALID_GID); + if (rc) { +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 101c80f22d77..c012fbc2638e 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -2672,7 +2672,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) + ptr += sizeof(struct smb3_acl); + + /* create one ACE to hold the mode embedded in reserved special SID */ +- acelen = setup_special_mode_ACE((struct smb_ace *)ptr, (__u64)mode); ++ acelen = setup_special_mode_ACE((struct smb_ace *)ptr, false, (__u64)mode); + ptr += acelen; + acl_size = acelen + sizeof(struct smb3_acl); + ace_count = 1; +-- +2.39.5 + diff --git a/queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch b/queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch new file mode 100644 index 00000000000..1144a2b2acf --- /dev/null +++ b/queue-6.6/i2c-i801-add-support-for-intel-arrow-lake-h.patch @@ -0,0 +1,76 @@ +From 7cd35e4a4c0091571c1de2b63531060d4ffb49d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Jun 2024 13:18:01 +0300 +Subject: i2c: i801: Add support for Intel Arrow Lake-H + +From: Jarkko Nikula + +[ Upstream commit f0eda4ddb2146a9f29d31b54c396f741bd0c82f1 ] + +Add SMBus PCI ID on Intel Arrow Lake-H. + +Signed-off-by: Jarkko Nikula +Signed-off-by: Andi Shyti +Stable-dep-of: bd492b583712 ("i2c: i801: Add support for Intel Panther Lake") +Signed-off-by: Sasha Levin +--- + Documentation/i2c/busses/i2c-i801.rst | 1 + + drivers/i2c/busses/Kconfig | 1 + + drivers/i2c/busses/i2c-i801.c | 3 +++ + 3 files changed, 5 insertions(+) + +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index 10eced6c2e46..c840b597912c 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -48,6 +48,7 @@ Supported adapters: + * Intel Raptor Lake (PCH) + * Intel Meteor Lake (SOC and PCH) + * Intel Birch Stream (SOC) ++ * Intel Arrow Lake (SOC) + + Datasheets: Publicly available at the Intel website + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 97d27e01a6ee..0dc3c91f52a8 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -159,6 +159,7 @@ config I2C_I801 + Raptor Lake (PCH) + Meteor Lake (SOC and PCH) + Birch Stream (SOC) ++ Arrow Lake (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 2b8bcd121ffa..ed943f303cdb 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -80,6 +80,7 @@ + * Meteor Lake SoC-S (SOC) 0xae22 32 hard yes yes yes + * Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes + * Birch Stream (SOC) 0x5796 32 hard yes yes yes ++ * Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -234,6 +235,7 @@ + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS 0x54a3 + #define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS 0x5796 + #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS 0x5ad4 ++#define PCI_DEVICE_ID_INTEL_ARROW_LAKE_H_SMBUS 0x7722 + #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS 0x7a23 + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS 0x7aa3 + #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS 0x7e22 +@@ -1046,6 +1048,7 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +-- +2.39.5 + diff --git a/queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch b/queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch new file mode 100644 index 00000000000..d56fec0bdcb --- /dev/null +++ b/queue-6.6/i2c-i801-add-support-for-intel-panther-lake.patch @@ -0,0 +1,78 @@ +From 844c2a3603523a5da2bb6a996dc26d275fe84a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 16:27:19 +0300 +Subject: i2c: i801: Add support for Intel Panther Lake + +From: Jarkko Nikula + +[ Upstream commit bd492b58371295d3ae26162b9666be584abad68a ] + +Add SMBus PCI IDs on Intel Panther Lake-P and -U. + +Signed-off-by: Jarkko Nikula +Signed-off-by: Andi Shyti +Signed-off-by: Sasha Levin +--- + Documentation/i2c/busses/i2c-i801.rst | 1 + + drivers/i2c/busses/Kconfig | 1 + + drivers/i2c/busses/i2c-i801.c | 6 ++++++ + 3 files changed, 8 insertions(+) + +diff --git a/Documentation/i2c/busses/i2c-i801.rst b/Documentation/i2c/busses/i2c-i801.rst +index c840b597912c..47e8ac5b7099 100644 +--- a/Documentation/i2c/busses/i2c-i801.rst ++++ b/Documentation/i2c/busses/i2c-i801.rst +@@ -49,6 +49,7 @@ Supported adapters: + * Intel Meteor Lake (SOC and PCH) + * Intel Birch Stream (SOC) + * Intel Arrow Lake (SOC) ++ * Intel Panther Lake (SOC) + + Datasheets: Publicly available at the Intel website + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 0dc3c91f52a8..982007a112c2 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -160,6 +160,7 @@ config I2C_I801 + Meteor Lake (SOC and PCH) + Birch Stream (SOC) + Arrow Lake (SOC) ++ Panther Lake (SOC) + + This driver can also be built as a module. If so, the module + will be called i2c-i801. +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index ed943f303cdb..18c04f5e41d9 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -81,6 +81,8 @@ + * Meteor Lake PCH-S (PCH) 0x7f23 32 hard yes yes yes + * Birch Stream (SOC) 0x5796 32 hard yes yes yes + * Arrow Lake-H (SOC) 0x7722 32 hard yes yes yes ++ * Panther Lake-H (SOC) 0xe322 32 hard yes yes yes ++ * Panther Lake-P (SOC) 0xe422 32 hard yes yes yes + * + * Features supported by this driver: + * Software PEC no +@@ -258,6 +260,8 @@ + #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS 0xa323 + #define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS 0xa3a3 + #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_SOC_S_SMBUS 0xae22 ++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_H_SMBUS 0xe322 ++#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_P_SMBUS 0xe422 + + struct i801_mux_config { + char *gpio_chip; +@@ -1049,6 +1053,8 @@ static const struct pci_device_id i801_ids[] = { + { PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, ++ { PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS, FEATURES_ICH5 | FEATURE_TCO_CNL) }, + { 0, } + }; + +-- +2.39.5 + diff --git a/queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch b/queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch new file mode 100644 index 00000000000..812942e4af6 --- /dev/null +++ b/queue-6.6/iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch @@ -0,0 +1,152 @@ +From 1c8ce48a99bfd64f85b9e2ecce2ed846805075d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Feb 2024 17:27:28 +0000 +Subject: iio: adc: ad7192: Convert from of specific to fwnode property + handling + +From: Jonathan Cameron + +[ Upstream commit c3708c829a0662af429897a90aed46b70f14a50b ] + +Enables use of with other firmwware types. +Removes a case of device tree specific handlers that might get copied +into new drivers. + +Cc: Alisa-Dariana Roman +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20240218172731.1023367-6-jic23@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: b7f99fa1b64a ("iio: adc: ad7192: properly check spi_get_device_match_data()") +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/ad7192.c | 38 +++++++++++++++++++------------------- + 1 file changed, 19 insertions(+), 19 deletions(-) + +diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c +index b64fd365f83f..ecaf87af539b 100644 +--- a/drivers/iio/adc/ad7192.c ++++ b/drivers/iio/adc/ad7192.c +@@ -16,7 +16,9 @@ + #include + #include + #include +-#include ++#include ++#include ++#include + + #include + #include +@@ -360,19 +362,19 @@ static inline bool ad7192_valid_external_frequency(u32 freq) + freq <= AD7192_EXT_FREQ_MHZ_MAX); + } + +-static int ad7192_of_clock_select(struct ad7192_state *st) ++static int ad7192_clock_select(struct ad7192_state *st) + { +- struct device_node *np = st->sd.spi->dev.of_node; ++ struct device *dev = &st->sd.spi->dev; + unsigned int clock_sel; + + clock_sel = AD7192_CLK_INT; + + /* use internal clock */ + if (!st->mclk) { +- if (of_property_read_bool(np, "adi,int-clock-output-enable")) ++ if (device_property_read_bool(dev, "adi,int-clock-output-enable")) + clock_sel = AD7192_CLK_INT_CO; + } else { +- if (of_property_read_bool(np, "adi,clock-xtal")) ++ if (device_property_read_bool(dev, "adi,clock-xtal")) + clock_sel = AD7192_CLK_EXT_MCLK1_2; + else + clock_sel = AD7192_CLK_EXT_MCLK2; +@@ -381,7 +383,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st) + return clock_sel; + } + +-static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) ++static int ad7192_setup(struct iio_dev *indio_dev, struct device *dev) + { + struct ad7192_state *st = iio_priv(indio_dev); + bool rej60_en, refin2_en; +@@ -403,7 +405,7 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) + id &= AD7192_ID_MASK; + + if (id != st->chip_info->chip_id) +- dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X != 0x%X)\n", ++ dev_warn(dev, "device ID query failed (0x%X != 0x%X)\n", + id, st->chip_info->chip_id); + + st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) | +@@ -412,31 +414,31 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np) + + st->conf = AD7192_CONF_GAIN(0); + +- rej60_en = of_property_read_bool(np, "adi,rejection-60-Hz-enable"); ++ rej60_en = device_property_read_bool(dev, "adi,rejection-60-Hz-enable"); + if (rej60_en) + st->mode |= AD7192_MODE_REJ60; + +- refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable"); ++ refin2_en = device_property_read_bool(dev, "adi,refin2-pins-enable"); + if (refin2_en && st->chip_info->chip_id != CHIPID_AD7195) + st->conf |= AD7192_CONF_REFSEL; + + st->conf &= ~AD7192_CONF_CHOP; + st->f_order = AD7192_NO_SYNC_FILTER; + +- buf_en = of_property_read_bool(np, "adi,buffer-enable"); ++ buf_en = device_property_read_bool(dev, "adi,buffer-enable"); + if (buf_en) + st->conf |= AD7192_CONF_BUF; + +- bipolar = of_property_read_bool(np, "bipolar"); ++ bipolar = device_property_read_bool(dev, "bipolar"); + if (!bipolar) + st->conf |= AD7192_CONF_UNIPOLAR; + +- burnout_curr_en = of_property_read_bool(np, +- "adi,burnout-currents-enable"); ++ burnout_curr_en = device_property_read_bool(dev, ++ "adi,burnout-currents-enable"); + if (burnout_curr_en && buf_en) { + st->conf |= AD7192_CONF_BURN; + } else if (burnout_curr_en) { +- dev_warn(&st->sd.spi->dev, ++ dev_warn(dev, + "Can't enable burnout currents: see CHOP or buffer\n"); + } + +@@ -1036,9 +1038,7 @@ static int ad7192_probe(struct spi_device *spi) + } + st->int_vref_mv = ret / 1000; + +- st->chip_info = of_device_get_match_data(&spi->dev); +- if (!st->chip_info) +- st->chip_info = (void *)spi_get_device_id(spi)->driver_data; ++ st->chip_info = spi_get_device_match_data(spi); + indio_dev->name = st->chip_info->name; + indio_dev->modes = INDIO_DIRECT_MODE; + +@@ -1065,7 +1065,7 @@ static int ad7192_probe(struct spi_device *spi) + if (IS_ERR(st->mclk)) + return PTR_ERR(st->mclk); + +- st->clock_sel = ad7192_of_clock_select(st); ++ st->clock_sel = ad7192_clock_select(st); + + if (st->clock_sel == AD7192_CLK_EXT_MCLK1_2 || + st->clock_sel == AD7192_CLK_EXT_MCLK2) { +@@ -1077,7 +1077,7 @@ static int ad7192_probe(struct spi_device *spi) + } + } + +- ret = ad7192_setup(indio_dev, spi->dev.of_node); ++ ret = ad7192_setup(indio_dev, &spi->dev); + if (ret) + return ret; + +-- +2.39.5 + diff --git a/queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch b/queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch new file mode 100644 index 00000000000..4200804b2a6 --- /dev/null +++ b/queue-6.6/iio-adc-ad7192-properly-check-spi_get_device_match_d.patch @@ -0,0 +1,37 @@ +From 26f3ccd0be7348ec261a5bf86ee500214c3c43b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Oct 2024 17:01:21 +0200 +Subject: iio: adc: ad7192: properly check spi_get_device_match_data() + +From: Nuno Sa + +[ Upstream commit b7f99fa1b64af2f696b13cec581cb4cd7d3982b8 ] + +spi_get_device_match_data() can return a NULL pointer. Hence, let's +check for it. + +Signed-off-by: Nuno Sa +Link: https://patch.msgid.link/20241014-fix-error-check-v1-1-089e1003d12f@analog.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/adc/ad7192.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c +index ecaf87af539b..fa6810aa6a4a 100644 +--- a/drivers/iio/adc/ad7192.c ++++ b/drivers/iio/adc/ad7192.c +@@ -1039,6 +1039,9 @@ static int ad7192_probe(struct spi_device *spi) + st->int_vref_mv = ret / 1000; + + st->chip_info = spi_get_device_match_data(spi); ++ if (!st->chip_info) ++ return -ENODEV; ++ + indio_dev->name = st->chip_info->name; + indio_dev->modes = INDIO_DIRECT_MODE; + +-- +2.39.5 + diff --git a/queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch b/queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch new file mode 100644 index 00000000000..5d757b16322 --- /dev/null +++ b/queue-6.6/mailbox-pcc-add-support-for-platform-notification-ha.patch @@ -0,0 +1,141 @@ +From 28f65e8200c4ee0a9a3f9bf6295026d76794cf61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 14:38:26 +0800 +Subject: mailbox: pcc: Add support for platform notification handling + +From: Huisong Li + +[ Upstream commit 60c40b06fa68694dd08a1a0038ea8b9de3f3b1ca ] + +Currently, PCC driver doesn't support the processing of platform +notification for type 4 PCC subspaces. + +According to ACPI specification, if platform sends a notification +to OSPM, it must clear the command complete bit and trigger platform +interrupt. OSPM needs to check whether the command complete bit is +cleared, clear platform interrupt, process command, and then set the +command complete and ring doorbell to the Platform. + +Let us stash the value of the pcc type and use the same while processing +the interrupt of the channel. We also need to set the command complete +bit and ring doorbell in the interrupt handler for the type 4 channel to +complete the communication flow after processing the notification from +the Platform. + +Signed-off-by: Huisong Li +Reviewed-by: Hanjun Guo +Link: https://lore.kernel.org/r/20230801063827.25336-2-lihuisong@huawei.com +Signed-off-by: Sudeep Holla +Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK") +Signed-off-by: Sasha Levin +--- + drivers/mailbox/pcc.c | 50 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index a44d4b3e5beb..80310b48bfb6 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -91,6 +91,7 @@ struct pcc_chan_reg { + * @cmd_update: PCC register bundle for the command complete update register + * @error: PCC register bundle for the error status register + * @plat_irq: platform interrupt ++ * @type: PCC subspace type + */ + struct pcc_chan_info { + struct pcc_mbox_chan chan; +@@ -100,12 +101,15 @@ struct pcc_chan_info { + struct pcc_chan_reg cmd_update; + struct pcc_chan_reg error; + int plat_irq; ++ u8 type; + }; + + #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan) + static struct pcc_chan_info *chan_info; + static int pcc_chan_count; + ++static int pcc_send_data(struct mbox_chan *chan, void *data); ++ + /* + * PCC can be used with perf critical drivers such as CPPC + * So it makes sense to locally cache the virtual address and +@@ -221,6 +225,34 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags) + return acpi_register_gsi(NULL, interrupt, trigger, polarity); + } + ++static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) ++{ ++ u64 val; ++ int ret; ++ ++ ret = pcc_chan_reg_read(&pchan->cmd_complete, &val); ++ if (ret) ++ return false; ++ ++ if (!pchan->cmd_complete.gas) ++ return true; ++ ++ /* ++ * Judge if the channel respond the interrupt based on the value of ++ * command complete. ++ */ ++ val &= pchan->cmd_complete.status_mask; ++ /* ++ * If this is PCC slave subspace channel, and the command complete ++ * bit 0 indicates that Platform is sending a notification and OSPM ++ * needs to respond this interrupt to process this command. ++ */ ++ if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) ++ return !val; ++ ++ return !!val; ++} ++ + /** + * pcc_mbox_irq - PCC mailbox interrupt handler + * @irq: interrupt number +@@ -236,17 +268,9 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + int ret; + + pchan = chan->con_priv; +- +- ret = pcc_chan_reg_read(&pchan->cmd_complete, &val); +- if (ret) ++ if (!pcc_mbox_cmd_complete_check(pchan)) + return IRQ_NONE; + +- if (val) { /* Ensure GAS exists and value is non-zero */ +- val &= pchan->cmd_complete.status_mask; +- if (!val) +- return IRQ_NONE; +- } +- + ret = pcc_chan_reg_read(&pchan->error, &val); + if (ret) + return IRQ_NONE; +@@ -262,6 +286,13 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + + mbox_chan_received_data(chan, NULL); + ++ /* ++ * The PCC slave subspace channel needs to set the command complete bit ++ * and ring doorbell after processing message. ++ */ ++ if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) ++ pcc_send_data(chan, NULL); ++ + return IRQ_HANDLED; + } + +@@ -698,6 +729,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) + + pcc_parse_subspace_shmem(pchan, pcct_entry); + ++ pchan->type = pcct_entry->type; + pcct_entry = (struct acpi_subtable_header *) + ((unsigned long) pcct_entry + pcct_entry->length); + } +-- +2.39.5 + diff --git a/queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch b/queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch new file mode 100644 index 00000000000..431701f3421 --- /dev/null +++ b/queue-6.6/mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch @@ -0,0 +1,166 @@ +From 1ae935579de9c7756e39fd4620fd39b6a6e185f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Nov 2024 14:02:14 -0500 +Subject: mailbox: pcc: Check before sending MCTP PCC response ACK + +From: Adam Young + +[ Upstream commit 7f9e19f207be0c534d517d65e01417ba968cdd34 ] + +Type 4 PCC channels have an option to send back a response +to the platform when they are done processing the request. +The flag to indicate whether or not to respond is inside +the message body, and thus is not available to the pcc +mailbox. + +If the flag is not set, still set command completion +bit after processing message. + +In order to read the flag, this patch maps the shared +buffer to virtual memory. To avoid duplication of mapping +the shared buffer is then made available to be used by +the driver that uses the mailbox. + +Signed-off-by: Adam Young +Cc: Sudeep Holla +Signed-off-by: Jassi Brar +Signed-off-by: Sasha Levin +--- + drivers/mailbox/pcc.c | 61 +++++++++++++++++++++++++++++++++++++------ + include/acpi/pcc.h | 7 +++++ + 2 files changed, 60 insertions(+), 8 deletions(-) + +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index 94885e411085..82102a4c5d68 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -269,6 +269,35 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) + return !!val; + } + ++static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan) ++{ ++ struct acpi_pcct_ext_pcc_shared_memory pcc_hdr; ++ ++ if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) ++ return; ++ /* If the memory region has not been mapped, we cannot ++ * determine if we need to send the message, but we still ++ * need to set the cmd_update flag before returning. ++ */ ++ if (pchan->chan.shmem == NULL) { ++ pcc_chan_reg_read_modify_write(&pchan->cmd_update); ++ return; ++ } ++ memcpy_fromio(&pcc_hdr, pchan->chan.shmem, ++ sizeof(struct acpi_pcct_ext_pcc_shared_memory)); ++ /* ++ * The PCC slave subspace channel needs to set the command complete bit ++ * after processing message. If the PCC_ACK_FLAG is set, it should also ++ * ring the doorbell. ++ * ++ * The PCC master subspace channel clears chan_in_use to free channel. ++ */ ++ if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK) ++ pcc_send_data(chan, NULL); ++ else ++ pcc_chan_reg_read_modify_write(&pchan->cmd_update); ++} ++ + /** + * pcc_mbox_irq - PCC mailbox interrupt handler + * @irq: interrupt number +@@ -306,14 +335,7 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + + mbox_chan_received_data(chan, NULL); + +- /* +- * The PCC slave subspace channel needs to set the command complete bit +- * and ring doorbell after processing message. +- * +- * The PCC master subspace channel clears chan_in_use to free channel. +- */ +- if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) +- pcc_send_data(chan, NULL); ++ check_and_ack(pchan, chan); + pchan->chan_in_use = false; + + return IRQ_HANDLED; +@@ -365,14 +387,37 @@ EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); + void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan) + { + struct mbox_chan *chan = pchan->mchan; ++ struct pcc_chan_info *pchan_info; ++ struct pcc_mbox_chan *pcc_mbox_chan; + + if (!chan || !chan->cl) + return; ++ pchan_info = chan->con_priv; ++ pcc_mbox_chan = &pchan_info->chan; ++ if (pcc_mbox_chan->shmem) { ++ iounmap(pcc_mbox_chan->shmem); ++ pcc_mbox_chan->shmem = NULL; ++ } + + mbox_free_channel(chan); + } + EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); + ++int pcc_mbox_ioremap(struct mbox_chan *chan) ++{ ++ struct pcc_chan_info *pchan_info; ++ struct pcc_mbox_chan *pcc_mbox_chan; ++ ++ if (!chan || !chan->cl) ++ 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); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcc_mbox_ioremap); ++ + /** + * pcc_send_data - Called from Mailbox Controller code. Used + * here only to ring the channel doorbell. The PCC client +diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h +index 9b373d172a77..699c1a37b8e7 100644 +--- a/include/acpi/pcc.h ++++ b/include/acpi/pcc.h +@@ -12,6 +12,7 @@ + struct pcc_mbox_chan { + struct mbox_chan *mchan; + u64 shmem_base_addr; ++ void __iomem *shmem; + u64 shmem_size; + u32 latency; + u32 max_access_rate; +@@ -31,11 +32,13 @@ struct pcc_mbox_chan { + #define PCC_CMD_COMPLETION_NOTIFY BIT(0) + + #define MAX_PCC_SUBSPACES 256 ++#define PCC_ACK_FLAG_MASK 0x1 + + #ifdef CONFIG_PCC + extern struct pcc_mbox_chan * + pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id); + extern void pcc_mbox_free_channel(struct pcc_mbox_chan *chan); ++extern int pcc_mbox_ioremap(struct mbox_chan *chan); + #else + static inline struct pcc_mbox_chan * + pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) +@@ -43,6 +46,10 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) + return ERR_PTR(-ENODEV); + } + static inline void pcc_mbox_free_channel(struct pcc_mbox_chan *chan) { } ++static inline int pcc_mbox_ioremap(struct mbox_chan *chan) ++{ ++ return 0; ++}; + #endif + + #endif /* _PCC_H */ +-- +2.39.5 + diff --git a/queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch b/queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch new file mode 100644 index 00000000000..a93ab4aa667 --- /dev/null +++ b/queue-6.6/mailbox-pcc-support-shared-interrupt-for-multiple-su.patch @@ -0,0 +1,178 @@ +From d279bdd1a39fd44f0bc58f7088cb00359906a01d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Aug 2023 14:38:27 +0800 +Subject: mailbox: pcc: Support shared interrupt for multiple subspaces + +From: Huisong Li + +[ Upstream commit 3db174e478cb0bb34888c20a531608b70aec9c1f ] + +If the platform acknowledge interrupt is level triggered, then it can +be shared by multiple subspaces provided each one has a unique platform +interrupt ack preserve and ack set masks. + +If it can be shared, then we can request the irq with IRQF_SHARED and +IRQF_ONESHOT flags. The first one indicating it can be shared and the +latter one to keep the interrupt disabled until the hardirq handler +finished. + +Further, since there is no way to detect if the interrupt is for a given +channel as the interrupt ack preserve and ack set masks are for clearing +the interrupt and not for reading the status(in case Irq Ack register +may be write-only on some platforms), we need a way to identify if the +given channel is in use and expecting the interrupt. + +PCC type0, type1 and type5 do not support shared level triggered interrupt. +The methods of determining whether a given channel for remaining types +should respond to an interrupt are as follows: + - type2: Whether the interrupt belongs to a given channel is only + determined by the status field in Generic Communications Channel + Shared Memory Region, which is done in rx_callback of PCC client. + - type3: This channel checks chan_in_use flag first and then checks the + command complete bit(value '1' indicates that the command has + been completed). + - type4: Platform ensure that the default value of the command complete + bit corresponding to the type4 channel is '1'. This command + complete bit is '0' when receive a platform notification. + +The new field, 'chan_in_use' is used by the type only support the +communication from OSPM to Platform (like type3) and should be completely +ignored by other types so as to avoid too many type unnecessary checks in +IRQ handler. + +Signed-off-by: Huisong Li +Reviewed-by: Hanjun Guo +Link: https://lore.kernel.org/r/20230801063827.25336-3-lihuisong@huawei.com +Signed-off-by: Sudeep Holla +Stable-dep-of: 7f9e19f207be ("mailbox: pcc: Check before sending MCTP PCC response ACK") +Signed-off-by: Sasha Levin +--- + drivers/mailbox/pcc.c | 43 ++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 40 insertions(+), 3 deletions(-) + +diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c +index 80310b48bfb6..94885e411085 100644 +--- a/drivers/mailbox/pcc.c ++++ b/drivers/mailbox/pcc.c +@@ -92,6 +92,13 @@ struct pcc_chan_reg { + * @error: PCC register bundle for the error status register + * @plat_irq: platform interrupt + * @type: PCC subspace type ++ * @plat_irq_flags: platform interrupt flags ++ * @chan_in_use: this flag is used just to check if the interrupt needs ++ * handling when it is shared. Since only one transfer can occur ++ * at a time and mailbox takes care of locking, this flag can be ++ * accessed without a lock. Note: the type only support the ++ * communication from OSPM to Platform, like type3, use it, and ++ * other types completely ignore it. + */ + struct pcc_chan_info { + struct pcc_mbox_chan chan; +@@ -102,6 +109,8 @@ struct pcc_chan_info { + struct pcc_chan_reg error; + int plat_irq; + u8 type; ++ unsigned int plat_irq_flags; ++ bool chan_in_use; + }; + + #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan) +@@ -225,6 +234,12 @@ static int pcc_map_interrupt(u32 interrupt, u32 flags) + return acpi_register_gsi(NULL, interrupt, trigger, polarity); + } + ++static bool pcc_chan_plat_irq_can_be_shared(struct pcc_chan_info *pchan) ++{ ++ return (pchan->plat_irq_flags & ACPI_PCCT_INTERRUPT_MODE) == ++ ACPI_LEVEL_SENSITIVE; ++} ++ + static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) + { + u64 val; +@@ -242,6 +257,7 @@ static bool pcc_mbox_cmd_complete_check(struct pcc_chan_info *pchan) + * command complete. + */ + val &= pchan->cmd_complete.status_mask; ++ + /* + * If this is PCC slave subspace channel, and the command complete + * bit 0 indicates that Platform is sending a notification and OSPM +@@ -268,6 +284,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + int ret; + + pchan = chan->con_priv; ++ if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE && ++ !pchan->chan_in_use) ++ return IRQ_NONE; ++ + if (!pcc_mbox_cmd_complete_check(pchan)) + return IRQ_NONE; + +@@ -289,9 +309,12 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) + /* + * The PCC slave subspace channel needs to set the command complete bit + * and ring doorbell after processing message. ++ * ++ * The PCC master subspace channel clears chan_in_use to free channel. + */ + if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) + pcc_send_data(chan, NULL); ++ pchan->chan_in_use = false; + + return IRQ_HANDLED; + } +@@ -371,7 +394,11 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) + if (ret) + return ret; + +- return pcc_chan_reg_read_modify_write(&pchan->db); ++ ret = pcc_chan_reg_read_modify_write(&pchan->db); ++ if (!ret && pchan->plat_irq > 0) ++ pchan->chan_in_use = true; ++ ++ return ret; + } + + /** +@@ -384,11 +411,14 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) + static int pcc_startup(struct mbox_chan *chan) + { + struct pcc_chan_info *pchan = chan->con_priv; ++ unsigned long irqflags; + int rc; + + if (pchan->plat_irq > 0) { +- rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, 0, +- MBOX_IRQ_NAME, chan); ++ irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ? ++ IRQF_SHARED | IRQF_ONESHOT : 0; ++ rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, ++ irqflags, MBOX_IRQ_NAME, chan); + if (unlikely(rc)) { + dev_err(chan->mbox->dev, "failed to register PCC interrupt %d\n", + pchan->plat_irq); +@@ -494,6 +524,7 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, + pcct_ss->platform_interrupt); + return -EINVAL; + } ++ pchan->plat_irq_flags = pcct_ss->flags; + + if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) { + struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss; +@@ -515,6 +546,12 @@ static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan, + "PLAT IRQ ACK"); + } + ++ if (pcc_chan_plat_irq_can_be_shared(pchan) && ++ !pchan->plat_irq_ack.gas) { ++ pr_err("PCC subspace has level IRQ with no ACK register\n"); ++ return -EINVAL; ++ } ++ + return ret; + } + +-- +2.39.5 + diff --git a/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch new file mode 100644 index 00000000000..aeb136d19c8 --- /dev/null +++ b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch @@ -0,0 +1,49 @@ +From 2e7152f3794ef1552c3b5f699e81a051ae578323 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 15 Jan 2023 22:52:10 +0200 +Subject: media: uvcvideo: Force UVC version to 1.0a for 0408:4035 + +From: Laurent Pinchart + +[ Upstream commit c397e8c45d911443b4ab60084fb723edf2a5b604 ] + +The Quanta ACER HD User Facing camera reports a UVC 1.50 version, but +implements UVC 1.0a as shown by the UVC probe control being 26 bytes +long. Force the UVC version for that device. + +Reported-by: Giuliano Lotta +Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2000947 +Link: https://lore.kernel.org/r/20230115205210.20077-1-laurent.pinchart@ideasonboard.com +Tested-by: Giuliano Lotta +Signed-off-by: Laurent Pinchart +Stable-dep-of: c9df99302fff ("media: uvcvideo: Force UVC version to 1.0a for 0408:4033") +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_driver.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index 5a3e933df633..adf1abce5333 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2519,6 +2519,17 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, ++ /* Quanta ACER HD User Facing */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x0408, ++ .idProduct = 0x4035, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){ ++ .uvc_version = 0x010a, ++ } }, + /* LogiLink Wireless Webcam */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, +-- +2.39.5 + diff --git a/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 new file mode 100644 index 00000000000..caac9d571b9 --- /dev/null +++ b/queue-6.6/media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 @@ -0,0 +1,50 @@ +From 20279b06e3f4153f8a5bbf4b6e579826b1f7491c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Sep 2024 13:33:29 +0000 +Subject: media: uvcvideo: Force UVC version to 1.0a for 0408:4033 + +From: Ricardo Ribalda + +[ Upstream commit c9df99302fff53b6007666136b9f43fbac7ee3d8 ] + +The Quanta ACER HD User Facing camera reports a UVC 1.50 version, but +implements UVC 1.0a as shown by the UVC probe control being 26 bytes +long. Force the UVC version for that device. + +Reported-by: Giuliano Lotta +Closes: https://lore.kernel.org/linux-media/fce4f906-d69b-417d-9f13-bf69fe5c81e3@koyu.space/ +Signed-off-by: Ricardo Ribalda +Reviewed-by: Laurent Pinchart +Link: https://lore.kernel.org/r/20240924-uvc-quanta-v1-1-2de023863767@chromium.org +Signed-off-by: Laurent Pinchart +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/usb/uvc/uvc_driver.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c +index adf1abce5333..1b05890f99f4 100644 +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -2520,6 +2520,17 @@ static const struct usb_device_id uvc_ids[] = { + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, + /* Quanta ACER HD User Facing */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x0408, ++ .idProduct = 0x4033, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = UVC_PC_PROTOCOL_15, ++ .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){ ++ .uvc_version = 0x010a, ++ } }, ++ /* Quanta ACER HD User Facing */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0408, +-- +2.39.5 + diff --git a/queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch b/queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch new file mode 100644 index 00000000000..bba3231a290 --- /dev/null +++ b/queue-6.6/memblock-allow-zero-threshold-in-validate_numa_conve.patch @@ -0,0 +1,47 @@ +From 941ae9f40f17bb4178fc34ce43def7359e99afe1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Nov 2024 11:13:47 +0200 +Subject: memblock: allow zero threshold in validate_numa_converage() + +From: Mike Rapoport (Microsoft) + +[ Upstream commit 9cdc6423acb49055efb444ecd895d853a70ef931 ] + +Currently memblock validate_numa_converage() returns false negative when +threshold set to zero. + +Make the check if the memory size with invalid node ID is greater than +the threshold exclusive to fix that. + +Link: https://lore.kernel.org/all/Z0mIDBD4KLyxyOCm@kernel.org/ +Signed-off-by: Mike Rapoport (Microsoft) +Signed-off-by: Sasha Levin +--- + mm/memblock.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/mm/memblock.c b/mm/memblock.c +index 3a3ab73546f5..87a2b4340ce4 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -738,7 +738,7 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) + /** + * memblock_validate_numa_coverage - check if amount of memory with + * no node ID assigned is less than a threshold +- * @threshold_bytes: maximal number of pages that can have unassigned node ++ * @threshold_bytes: maximal memory size that can have unassigned node + * ID (in bytes). + * + * A buggy firmware may report memory that does not belong to any node. +@@ -758,7 +758,7 @@ bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_byt + nr_pages += end_pfn - start_pfn; + } + +- if ((nr_pages << PAGE_SHIFT) >= threshold_bytes) { ++ if ((nr_pages << PAGE_SHIFT) > threshold_bytes) { + mem_size_mb = memblock_phys_mem_size() >> 20; + pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n", + (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb); +-- +2.39.5 + diff --git a/queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch b/queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch new file mode 100644 index 00000000000..6d9ff834019 --- /dev/null +++ b/queue-6.6/memblock-make-memblock_set_node-also-warn-about-use-.patch @@ -0,0 +1,59 @@ +From 270445a91055004fc3c93507fb72aa18bc500622 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 09:39:10 +0200 +Subject: memblock: make memblock_set_node() also warn about use of + MAX_NUMNODES + +From: Jan Beulich + +[ Upstream commit e0eec24e2e199873f43df99ec39773ad3af2bff7 ] + +On an (old) x86 system with SRAT just covering space above 4Gb: + + ACPI: SRAT: Node 0 PXM 0 [mem 0x100000000-0xfffffffff] hotplug + +the commit referenced below leads to this NUMA configuration no longer +being refused by a CONFIG_NUMA=y kernel (previously + + NUMA: nodes only cover 6144MB of your 8185MB e820 RAM. Not used. + No NUMA configuration found + Faking a node at [mem 0x0000000000000000-0x000000027fffffff] + +was seen in the log directly after the message quoted above), because of +memblock_validate_numa_coverage() checking for NUMA_NO_NODE (only). This +in turn led to memblock_alloc_range_nid()'s warning about MAX_NUMNODES +triggering, followed by a NULL deref in memmap_init() when trying to +access node 64's (NODE_SHIFT=6) node data. + +To compensate said change, make memblock_set_node() warn on and adjust +a passed in value of MAX_NUMNODES, just like various other functions +already do. + +Fixes: ff6c3d81f2e8 ("NUMA: optimize detection of memory with no node id assigned by firmware") +Signed-off-by: Jan Beulich +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/1c8a058c-5365-4f27-a9f1-3aeb7fb3e7b2@suse.com +Signed-off-by: Mike Rapoport (IBM) +Signed-off-by: Sasha Levin +--- + mm/memblock.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/mm/memblock.c b/mm/memblock.c +index 87a2b4340ce4..ba64b47b7c3b 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -1321,6 +1321,10 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, + int start_rgn, end_rgn; + int i, ret; + ++ if (WARN_ONCE(nid == MAX_NUMNODES, ++ "Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n")) ++ nid = NUMA_NO_NODE; ++ + ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn); + if (ret) + return ret; +-- +2.39.5 + diff --git a/queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch b/queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch new file mode 100644 index 00000000000..98215deedee --- /dev/null +++ b/queue-6.6/net-mlx5-unique-names-for-per-device-caches.patch @@ -0,0 +1,53 @@ +From 721f3e5169b81d063d4ad9b7da713fd6c327e9e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Oct 2024 15:41:46 +0200 +Subject: net/mlx5: unique names for per device caches + +From: Sebastian Ott + +[ Upstream commit 25872a079bbbe952eb660249cc9f40fa75623e68 ] + +Add the device name to the per device kmem_cache names to +ensure their uniqueness. This fixes warnings like this: +"kmem_cache of name 'mlx5_fs_fgs' already exists". + +Signed-off-by: Sebastian Ott +Reviewed-by: Breno Leitao +Reviewed-by: Tariq Toukan +Link: https://patch.msgid.link/20241023134146.28448-1-sebott@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 991250f44c2e..474e63d02ba4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -3478,6 +3478,7 @@ void mlx5_fs_core_free(struct mlx5_core_dev *dev) + int mlx5_fs_core_alloc(struct mlx5_core_dev *dev) + { + struct mlx5_flow_steering *steering; ++ char name[80]; + int err = 0; + + err = mlx5_init_fc_stats(dev); +@@ -3502,10 +3503,12 @@ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev) + else + steering->mode = MLX5_FLOW_STEERING_MODE_DMFS; + +- steering->fgs_cache = kmem_cache_create("mlx5_fs_fgs", ++ snprintf(name, sizeof(name), "%s-mlx5_fs_fgs", dev_name(dev->device)); ++ steering->fgs_cache = kmem_cache_create(name, + sizeof(struct mlx5_flow_group), 0, + 0, NULL); +- steering->ftes_cache = kmem_cache_create("mlx5_fs_ftes", sizeof(struct fs_fte), 0, ++ snprintf(name, sizeof(name), "%s-mlx5_fs_ftes", dev_name(dev->device)); ++ steering->ftes_cache = kmem_cache_create(name, sizeof(struct fs_fte), 0, + 0, NULL); + if (!steering->ftes_cache || !steering->fgs_cache) { + err = -ENOMEM; +-- +2.39.5 + diff --git a/queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch b/queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch new file mode 100644 index 00000000000..5774fdd6f4d --- /dev/null +++ b/queue-6.6/net-renesas-rswitch-fix-possible-early-skb-release.patch @@ -0,0 +1,55 @@ +From 57cbeb68793bc58579168fd56ad00fc64cf6178e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Dec 2024 14:50:01 +0500 +Subject: net: renesas: rswitch: fix possible early skb release + +From: Nikita Yushchenko + +[ Upstream commit 5cb099902b6b6292b3a85ffa1bb844e0ba195945 ] + +When sending frame split into multiple descriptors, hardware processes +descriptors one by one, including writing back DT values. The first +descriptor could be already marked as completed when processing of +next descriptors for the same frame is still in progress. + +Although only the last descriptor is configured to generate interrupt, +completion of the first descriptor could be noticed by the driver when +handling interrupt for the previous frame. + +Currently, driver stores skb in the entry that corresponds to the first +descriptor. This results into skb could be unmapped and freed when +hardware did not complete the send yet. This opens a window for +corrupting the data being sent. + +Fix this by saving skb in the entry that corresponds to the last +descriptor used to send the frame. + +Fixes: d2c96b9d5f83 ("net: rswitch: Add jumbo frames handling for TX") +Signed-off-by: Nikita Yushchenko +Reviewed-by: Yoshihiro Shimoda +Link: https://patch.msgid.link/20241208095004.69468-2-nikita.yoush@cogentembedded.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/renesas/rswitch.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c +index 54aa56c84133..2f483531d95c 100644 +--- a/drivers/net/ethernet/renesas/rswitch.c ++++ b/drivers/net/ethernet/renesas/rswitch.c +@@ -1632,8 +1632,9 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd + if (dma_mapping_error(ndev->dev.parent, dma_addr_orig)) + goto err_kfree; + +- gq->skbs[gq->cur] = skb; +- gq->unmap_addrs[gq->cur] = dma_addr_orig; ++ /* Stored the skb at the last descriptor to avoid skb free before hardware completes send */ ++ gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb; ++ gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig; + + dma_wmb(); + +-- +2.39.5 + diff --git a/queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch b/queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch new file mode 100644 index 00000000000..096c6efa5ce --- /dev/null +++ b/queue-6.6/numa-optimize-detection-of-memory-with-no-node-id-as.patch @@ -0,0 +1,208 @@ +From bb76e557e6106339bddd8a8e0bc858e8d46d9702 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 10:03:29 +0800 +Subject: NUMA: optimize detection of memory with no node id assigned by + firmware + +From: Liam Ni + +[ Upstream commit ff6c3d81f2e86b63a3a530683f89ef393882782a ] + +Sanity check that makes sure the nodes cover all memory loops over +numa_meminfo to count the pages that have node id assigned by the +firmware, then loops again over memblock.memory to find the total amount +of memory and in the end checks that the difference between the total +memory and memory that covered by nodes is less than some threshold. +Worse, the loop over numa_meminfo calls __absent_pages_in_range() that +also partially traverses memblock.memory. + +It's much simpler and more efficient to have a single traversal of +memblock.memory that verifies that amount of memory not covered by nodes +is less than a threshold. + +Introduce memblock_validate_numa_coverage() that does exactly that and use +it instead of numa_meminfo_cover_memory(). + +Link: https://lkml.kernel.org/r/20231026020329.327329-1-zhiguangni01@gmail.com +Signed-off-by: Liam Ni +Reviewed-by: Mike Rapoport (IBM) +Cc: Andy Lutomirski +Cc: Bibo Mao +Cc: Binbin Zhou +Cc: Borislav Petkov +Cc: Dave Hansen +Cc: Feiyang Chen +Cc: "H. Peter Anvin" +Cc: Huacai Chen +Cc: Ingo Molnar +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: WANG Xuerui +Signed-off-by: Andrew Morton +Stable-dep-of: 9cdc6423acb4 ("memblock: allow zero threshold in validate_numa_converage()") +Signed-off-by: Sasha Levin +--- + arch/loongarch/kernel/numa.c | 28 +--------------------------- + arch/x86/mm/numa.c | 34 ++-------------------------------- + include/linux/memblock.h | 1 + + mm/memblock.c | 34 ++++++++++++++++++++++++++++++++++ + 4 files changed, 38 insertions(+), 59 deletions(-) + +diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c +index 6e65ff12d5c7..8fe21f868f72 100644 +--- a/arch/loongarch/kernel/numa.c ++++ b/arch/loongarch/kernel/numa.c +@@ -226,32 +226,6 @@ static void __init node_mem_init(unsigned int node) + + #ifdef CONFIG_ACPI_NUMA + +-/* +- * Sanity check to catch more bad NUMA configurations (they are amazingly +- * common). Make sure the nodes cover all memory. +- */ +-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) +-{ +- int i; +- u64 numaram, biosram; +- +- numaram = 0; +- for (i = 0; i < mi->nr_blks; i++) { +- u64 s = mi->blk[i].start >> PAGE_SHIFT; +- u64 e = mi->blk[i].end >> PAGE_SHIFT; +- +- numaram += e - s; +- numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e); +- if ((s64)numaram < 0) +- numaram = 0; +- } +- max_pfn = max_low_pfn; +- biosram = max_pfn - absent_pages_in_range(0, max_pfn); +- +- BUG_ON((s64)(biosram - numaram) >= (1 << (20 - PAGE_SHIFT))); +- return true; +-} +- + static void __init add_node_intersection(u32 node, u64 start, u64 size, u32 type) + { + static unsigned long num_physpages; +@@ -396,7 +370,7 @@ int __init init_numa_memory(void) + return -EINVAL; + + init_node_memblock(); +- if (numa_meminfo_cover_memory(&numa_meminfo) == false) ++ if (!memblock_validate_numa_coverage(SZ_1M)) + return -EINVAL; + + for_each_node_mask(node, node_possible_map) { +diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c +index c7fa5396c0f0..2c67bfc3cf32 100644 +--- a/arch/x86/mm/numa.c ++++ b/arch/x86/mm/numa.c +@@ -448,37 +448,6 @@ int __node_distance(int from, int to) + } + EXPORT_SYMBOL(__node_distance); + +-/* +- * Sanity check to catch more bad NUMA configurations (they are amazingly +- * common). Make sure the nodes cover all memory. +- */ +-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) +-{ +- u64 numaram, e820ram; +- int i; +- +- numaram = 0; +- for (i = 0; i < mi->nr_blks; i++) { +- u64 s = mi->blk[i].start >> PAGE_SHIFT; +- u64 e = mi->blk[i].end >> PAGE_SHIFT; +- numaram += e - s; +- numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e); +- if ((s64)numaram < 0) +- numaram = 0; +- } +- +- e820ram = max_pfn - absent_pages_in_range(0, max_pfn); +- +- /* We seem to lose 3 pages somewhere. Allow 1M of slack. */ +- if ((s64)(e820ram - numaram) >= (1 << (20 - PAGE_SHIFT))) { +- printk(KERN_ERR "NUMA: nodes only cover %LuMB of your %LuMB e820 RAM. Not used.\n", +- (numaram << PAGE_SHIFT) >> 20, +- (e820ram << PAGE_SHIFT) >> 20); +- return false; +- } +- return true; +-} +- + /* + * Mark all currently memblock-reserved physical memory (which covers the + * kernel's own memory ranges) as hot-unswappable. +@@ -584,7 +553,8 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) + return -EINVAL; + } + } +- if (!numa_meminfo_cover_memory(mi)) ++ ++ if (!memblock_validate_numa_coverage(SZ_1M)) + return -EINVAL; + + /* Finally register nodes. */ +diff --git a/include/linux/memblock.h b/include/linux/memblock.h +index ed57c23f80ac..ed64240041e8 100644 +--- a/include/linux/memblock.h ++++ b/include/linux/memblock.h +@@ -122,6 +122,7 @@ unsigned long memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, + phys_addr_t base2, phys_addr_t size2); + bool memblock_overlaps_region(struct memblock_type *type, + phys_addr_t base, phys_addr_t size); ++bool memblock_validate_numa_coverage(unsigned long threshold_bytes); + int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); + int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); + int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); +diff --git a/mm/memblock.c b/mm/memblock.c +index d630f5c2bdb9..3a3ab73546f5 100644 +--- a/mm/memblock.c ++++ b/mm/memblock.c +@@ -735,6 +735,40 @@ int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) + return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0); + } + ++/** ++ * memblock_validate_numa_coverage - check if amount of memory with ++ * no node ID assigned is less than a threshold ++ * @threshold_bytes: maximal number of pages that can have unassigned node ++ * ID (in bytes). ++ * ++ * A buggy firmware may report memory that does not belong to any node. ++ * Check if amount of such memory is below @threshold_bytes. ++ * ++ * Return: true on success, false on failure. ++ */ ++bool __init_memblock memblock_validate_numa_coverage(unsigned long threshold_bytes) ++{ ++ unsigned long nr_pages = 0; ++ unsigned long start_pfn, end_pfn, mem_size_mb; ++ int nid, i; ++ ++ /* calculate lose page */ ++ for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) { ++ if (nid == NUMA_NO_NODE) ++ nr_pages += end_pfn - start_pfn; ++ } ++ ++ if ((nr_pages << PAGE_SHIFT) >= threshold_bytes) { ++ mem_size_mb = memblock_phys_mem_size() >> 20; ++ pr_err("NUMA: no nodes coverage for %luMB of %luMB RAM\n", ++ (nr_pages << PAGE_SHIFT) >> 20, mem_size_mb); ++ return false; ++ } ++ ++ return true; ++} ++ ++ + /** + * memblock_isolate_range - isolate given range into disjoint memblocks + * @type: memblock type to isolate range for +-- +2.39.5 + diff --git a/queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch b/queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch new file mode 100644 index 00000000000..4686dd1a3e6 --- /dev/null +++ b/queue-6.6/nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch @@ -0,0 +1,56 @@ +From 0593b941bfb886c405a1b7a3d239ab75814b1405 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2024 08:33:16 +0530 +Subject: nvme: use helper nvme_ctrl_state in nvme_keep_alive_finish function + +From: Nilay Shroff + +[ Upstream commit 599d9f3a10eec69ef28a90161763e4bd7c9c02bf ] + +We no more need acquiring ctrl->lock before accessing the +NVMe controller state and instead we can now use the helper +nvme_ctrl_state. So replace the use of ctrl->lock from +nvme_keep_alive_finish function with nvme_ctrl_state call. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Nilay Shroff +Signed-off-by: Keith Busch +Stable-dep-of: 84488282166d ("Revert "nvme: make keep-alive synchronous operation"") +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 5b6a6bd4e6e8..ae494c799fc5 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1181,10 +1181,9 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) + static void nvme_keep_alive_finish(struct request *rq, + blk_status_t status, struct nvme_ctrl *ctrl) + { +- unsigned long flags; +- bool startka = false; + unsigned long rtt = jiffies - (rq->deadline - rq->timeout); + unsigned long delay = nvme_keep_alive_work_period(ctrl); ++ enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); + + /* + * Subtract off the keepalive RTT so nvme_keep_alive_work runs +@@ -1207,12 +1206,7 @@ static void nvme_keep_alive_finish(struct request *rq, + + ctrl->ka_last_check_time = jiffies; + ctrl->comp_seen = false; +- spin_lock_irqsave(&ctrl->lock, flags); +- if (ctrl->state == NVME_CTRL_LIVE || +- ctrl->state == NVME_CTRL_CONNECTING) +- startka = true; +- spin_unlock_irqrestore(&ctrl->lock, flags); +- if (startka) ++ if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) + queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); + } + +-- +2.39.5 + diff --git a/queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch b/queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch new file mode 100644 index 00000000000..30c495d884b --- /dev/null +++ b/queue-6.6/of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch @@ -0,0 +1,50 @@ +From ddef21a3f2ca63aa185b216767d52a9a0f63592f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Nov 2024 11:05:37 +0100 +Subject: of: address: Preserve the flags portion on 1:1 dma-ranges mapping + +From: Andrea della Porta + +[ Upstream commit 7f05e20b989ac33c9c0f8c2028ec0a566493548f ] + +A missing or empty dma-ranges in a DT node implies a 1:1 mapping for dma +translations. In this specific case, the current behaviour is to zero out +the entire specifier so that the translation could be carried on as an +offset from zero. This includes address specifier that has flags (e.g. +PCI ranges). + +Once the flags portion has been zeroed, the translation chain is broken +since the mapping functions will check the upcoming address specifier +against mismatching flags, always failing the 1:1 mapping and its entire +purpose of always succeeding. + +Set to zero only the address portion while passing the flags through. + +Fixes: dbbdee94734b ("of/address: Merge all of the bus translation code") +Cc: stable@vger.kernel.org +Signed-off-by: Andrea della Porta +Tested-by: Herve Codina +Link: https://lore.kernel.org/r/e51ae57874e58a9b349c35e2e877425ebc075d7a.1732441813.git.andrea.porta@suse.com +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/address.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/of/address.c b/drivers/of/address.c +index cdefe5a89e5d..34d880a1be0a 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -476,7 +476,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, + } + if (ranges == NULL || rlen == 0) { + offset = of_read_number(addr, na); +- memset(addr, 0, pna * 4); ++ /* set address to zero, pass flags through */ ++ memset(addr + pbus->flag_cells, 0, (pna - pbus->flag_cells) * 4); + pr_debug("empty ranges; 1:1 translation\n"); + goto finish; + } +-- +2.39.5 + diff --git a/queue-6.6/of-address-remove-duplicated-functions.patch b/queue-6.6/of-address-remove-duplicated-functions.patch new file mode 100644 index 00000000000..47f2e95dab0 --- /dev/null +++ b/queue-6.6/of-address-remove-duplicated-functions.patch @@ -0,0 +1,72 @@ +From fccccf70fc3626e9ba04199a02b3b3bcf75b751d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 13:02:17 +0200 +Subject: of: address: Remove duplicated functions + +From: Herve Codina + +[ Upstream commit 3eb030c60835668997d5763b1a0c7938faf169f6 ] + +The recently added of_bus_default_flags_translate() performs the exact +same operation as of_bus_pci_translate() and of_bus_isa_translate(). + +Avoid duplicated code replacing both of_bus_pci_translate() and +of_bus_isa_translate() with of_bus_default_flags_translate(). + +Signed-off-by: Herve Codina +Link: https://lore.kernel.org/r/20231017110221.189299-3-herve.codina@bootlin.com +Signed-off-by: Rob Herring +Stable-dep-of: 7f05e20b989a ("of: address: Preserve the flags portion on 1:1 dma-ranges mapping") +Signed-off-by: Sasha Levin +--- + drivers/of/address.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/drivers/of/address.c b/drivers/of/address.c +index dfd05cb2b2fc..cfe5a11b620a 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -217,10 +217,6 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, + return da - cp; + } + +-static int of_bus_pci_translate(__be32 *addr, u64 offset, int na) +-{ +- return of_bus_default_translate(addr + 1, offset, na - 1); +-} + #endif /* CONFIG_PCI */ + + /* +@@ -344,11 +340,6 @@ static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, + return da - cp; + } + +-static int of_bus_isa_translate(__be32 *addr, u64 offset, int na) +-{ +- return of_bus_default_translate(addr + 1, offset, na - 1); +-} +- + static unsigned int of_bus_isa_get_flags(const __be32 *addr) + { + unsigned int flags = 0; +@@ -379,7 +370,7 @@ static struct of_bus of_busses[] = { + .match = of_bus_pci_match, + .count_cells = of_bus_pci_count_cells, + .map = of_bus_pci_map, +- .translate = of_bus_pci_translate, ++ .translate = of_bus_default_flags_translate, + .has_flags = true, + .get_flags = of_bus_pci_get_flags, + }, +@@ -391,7 +382,7 @@ static struct of_bus of_busses[] = { + .match = of_bus_isa_match, + .count_cells = of_bus_isa_count_cells, + .map = of_bus_isa_map, +- .translate = of_bus_isa_translate, ++ .translate = of_bus_default_flags_translate, + .has_flags = true, + .get_flags = of_bus_isa_get_flags, + }, +-- +2.39.5 + diff --git a/queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch b/queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch new file mode 100644 index 00000000000..6c11cd3c5c1 --- /dev/null +++ b/queue-6.6/of-address-store-number-of-bus-flag-cells-rather-tha.patch @@ -0,0 +1,85 @@ +From f74e92b6f2a72b7613a15cb3338b34e5e65a5246 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 08:53:58 -0500 +Subject: of: address: Store number of bus flag cells rather than bool + +From: Rob Herring + +[ Upstream commit 88696db08b7efa3b6bb722014ea7429e78f6be32 ] + +It is more useful to know how many flags cells a bus has rather than +whether a bus has flags or not as ultimately the number of cells is the +information used. Replace 'has_flags' boolean with 'flag_cells' count. + +Acked-by: Herve Codina +Link: https://lore.kernel.org/r/20231026135358.3564307-2-robh@kernel.org +Signed-off-by: Rob Herring +Stable-dep-of: 7f05e20b989a ("of: address: Preserve the flags portion on 1:1 dma-ranges mapping") +Signed-off-by: Sasha Levin +--- + drivers/of/address.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/of/address.c b/drivers/of/address.c +index cfe5a11b620a..cdefe5a89e5d 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -46,7 +46,7 @@ struct of_bus { + u64 (*map)(__be32 *addr, const __be32 *range, + int na, int ns, int pna); + int (*translate)(__be32 *addr, u64 offset, int na); +- bool has_flags; ++ int flag_cells; + unsigned int (*get_flags)(const __be32 *addr); + }; + +@@ -371,7 +371,7 @@ static struct of_bus of_busses[] = { + .count_cells = of_bus_pci_count_cells, + .map = of_bus_pci_map, + .translate = of_bus_default_flags_translate, +- .has_flags = true, ++ .flag_cells = 1, + .get_flags = of_bus_pci_get_flags, + }, + #endif /* CONFIG_PCI */ +@@ -383,7 +383,7 @@ static struct of_bus of_busses[] = { + .count_cells = of_bus_isa_count_cells, + .map = of_bus_isa_map, + .translate = of_bus_default_flags_translate, +- .has_flags = true, ++ .flag_cells = 1, + .get_flags = of_bus_isa_get_flags, + }, + /* Default with flags cell */ +@@ -394,7 +394,7 @@ static struct of_bus of_busses[] = { + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_flags_map, + .translate = of_bus_default_flags_translate, +- .has_flags = true, ++ .flag_cells = 1, + .get_flags = of_bus_default_flags_get_flags, + }, + /* Default */ +@@ -827,7 +827,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, + int na = parser->na; + int ns = parser->ns; + int np = parser->pna + na + ns; +- int busflag_na = 0; ++ int busflag_na = parser->bus->flag_cells; + + if (!range) + return NULL; +@@ -837,10 +837,6 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, + + range->flags = parser->bus->get_flags(parser->range); + +- /* A extra cell for resource flags */ +- if (parser->bus->has_flags) +- busflag_na = 1; +- + range->bus_addr = of_read_number(parser->range + busflag_na, na - busflag_na); + + if (parser->dma) +-- +2.39.5 + diff --git a/queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch b/queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch new file mode 100644 index 00000000000..cd9b90438db --- /dev/null +++ b/queue-6.6/platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch @@ -0,0 +1,54 @@ +From d7d7a8f08e8fcffaa1277464649e556e30942d4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Dec 2024 11:25:38 +0900 +Subject: platform/x86: mlx-platform: call pci_dev_put() to balance the + refcount +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Joe Hattori + +[ Upstream commit 185e1b1d91e419445d3fd99c1c0376a970438acf ] + +mlxplat_pci_fpga_device_init() calls pci_get_device() but does not +release the refcount on error path. Call pci_dev_put() on the error path +and in mlxplat_pci_fpga_device_exit() to fix this. + +This bug was found by an experimental static analysis tool that I am +developing. + +Fixes: 02daa222fbdd ("platform: mellanox: Add initial support for PCIe based programming logic device") +Signed-off-by: Joe Hattori +Reviewed-by: Vadim Pasternak +Link: https://lore.kernel.org/r/20241216022538.381209-1-joe@pf.is.s.u-tokyo.ac.jp +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/mlx-platform.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c +index a2ffe4157df1..b8d77adc9ea1 100644 +--- a/drivers/platform/x86/mlx-platform.c ++++ b/drivers/platform/x86/mlx-platform.c +@@ -6237,6 +6237,7 @@ mlxplat_pci_fpga_device_init(unsigned int device, const char *res_name, struct p + fail_pci_request_regions: + pci_disable_device(pci_dev); + fail_pci_enable_device: ++ pci_dev_put(pci_dev); + return err; + } + +@@ -6247,6 +6248,7 @@ mlxplat_pci_fpga_device_exit(struct pci_dev *pci_bridge, + iounmap(pci_bridge_addr); + pci_release_regions(pci_bridge); + pci_disable_device(pci_bridge); ++ pci_dev_put(pci_bridge); + } + + static int +-- +2.39.5 + diff --git a/queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch b/queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch new file mode 100644 index 00000000000..e84a4d49a4c --- /dev/null +++ b/queue-6.6/remoteproc-qcom-pas-add-sc7180-adsp.patch @@ -0,0 +1,38 @@ +From e63b122e3dfca70e98f792a1d553123515930966 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Sep 2023 15:02:35 +0500 +Subject: remoteproc: qcom: pas: Add sc7180 adsp + +From: Nikita Travkin + +[ Upstream commit 8de60bbab994bf8165d7d10e974872852da47aa7 ] + +sc7180 has a dedicated ADSP similar to the one found in sm8250. +Add it's compatible to the driver reusing the existing config so +the devices that use the adsp can probe it. + +Signed-off-by: Nikita Travkin +Reviewed-by: Stephen Boyd +Link: https://lore.kernel.org/r/20230907-sc7180-adsp-rproc-v3-2-6515c3fbe0a3@trvn.ru +Signed-off-by: Bjorn Andersson +Stable-dep-of: 009e288c989b ("remoteproc: qcom: pas: enable SAR2130P audio DSP support") +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_pas.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c +index 6235721f2c1a..fd66bb8b23f8 100644 +--- a/drivers/remoteproc/qcom_q6v5_pas.c ++++ b/drivers/remoteproc/qcom_q6v5_pas.c +@@ -1163,6 +1163,7 @@ static const struct of_device_id adsp_of_match[] = { + { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, + { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, + { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, ++ { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, +-- +2.39.5 + diff --git a/queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch b/queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch new file mode 100644 index 00000000000..80f3f49d9c1 --- /dev/null +++ b/queue-6.6/remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch @@ -0,0 +1,150 @@ +From b55068851314683a621ff59dca7d402cc961d28b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 19:08:04 +0200 +Subject: remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP + +From: Tengfei Fan + +[ Upstream commit 9091225ba28c0106d3cd041c7abf5551a94bb524 ] + +Add support for PIL loading on ADSP, CDSP0, CDSP1, GPDSP0 and GPDSP1 on +SA8775p SoCs. + +Signed-off-by: Tengfei Fan +Co-developed-by: Bartosz Golaszewski +Signed-off-by: Bartosz Golaszewski +Link: https://lore.kernel.org/r/20240805-topic-sa8775p-iot-remoteproc-v4-3-86affdc72c04@linaro.org +Signed-off-by: Bjorn Andersson +Stable-dep-of: 009e288c989b ("remoteproc: qcom: pas: enable SAR2130P audio DSP support") +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_pas.c | 92 ++++++++++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c +index fd66bb8b23f8..4a73723e375a 100644 +--- a/drivers/remoteproc/qcom_q6v5_pas.c ++++ b/drivers/remoteproc/qcom_q6v5_pas.c +@@ -786,6 +786,23 @@ static const struct adsp_data adsp_resource_init = { + .ssctl_id = 0x14, + }; + ++static const struct adsp_data sa8775p_adsp_resource = { ++ .crash_reason_smem = 423, ++ .firmware_name = "adsp.mbn", ++ .pas_id = 1, ++ .minidump_id = 5, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "lcx", ++ "lmx", ++ NULL ++ }, ++ .load_state = "adsp", ++ .ssr_name = "lpass", ++ .sysmon_name = "adsp", ++ .ssctl_id = 0x14, ++}; ++ + static const struct adsp_data sdm845_adsp_resource_init = { + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", +@@ -885,6 +902,42 @@ static const struct adsp_data cdsp_resource_init = { + .ssctl_id = 0x17, + }; + ++static const struct adsp_data sa8775p_cdsp0_resource = { ++ .crash_reason_smem = 601, ++ .firmware_name = "cdsp0.mbn", ++ .pas_id = 18, ++ .minidump_id = 7, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ "nsp", ++ NULL ++ }, ++ .load_state = "cdsp", ++ .ssr_name = "cdsp", ++ .sysmon_name = "cdsp", ++ .ssctl_id = 0x17, ++}; ++ ++static const struct adsp_data sa8775p_cdsp1_resource = { ++ .crash_reason_smem = 633, ++ .firmware_name = "cdsp1.mbn", ++ .pas_id = 30, ++ .minidump_id = 20, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ "nsp", ++ NULL ++ }, ++ .load_state = "nsp", ++ .ssr_name = "cdsp1", ++ .sysmon_name = "cdsp1", ++ .ssctl_id = 0x20, ++}; ++ + static const struct adsp_data sdm845_cdsp_resource_init = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", +@@ -987,6 +1040,40 @@ static const struct adsp_data sm8350_cdsp_resource = { + .ssctl_id = 0x17, + }; + ++static const struct adsp_data sa8775p_gpdsp0_resource = { ++ .crash_reason_smem = 640, ++ .firmware_name = "gpdsp0.mbn", ++ .pas_id = 39, ++ .minidump_id = 21, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ NULL ++ }, ++ .load_state = "gpdsp0", ++ .ssr_name = "gpdsp0", ++ .sysmon_name = "gpdsp0", ++ .ssctl_id = 0x21, ++}; ++ ++static const struct adsp_data sa8775p_gpdsp1_resource = { ++ .crash_reason_smem = 641, ++ .firmware_name = "gpdsp1.mbn", ++ .pas_id = 40, ++ .minidump_id = 22, ++ .auto_boot = true, ++ .proxy_pd_names = (char*[]){ ++ "cx", ++ "mxc", ++ NULL ++ }, ++ .load_state = "gpdsp1", ++ .ssr_name = "gpdsp1", ++ .sysmon_name = "gpdsp1", ++ .ssctl_id = 0x22, ++}; ++ + static const struct adsp_data mpss_resource_init = { + .crash_reason_smem = 421, + .firmware_name = "modem.mdt", +@@ -1163,6 +1250,11 @@ static const struct of_device_id adsp_of_match[] = { + { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init }, + { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init }, + { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init }, ++ { .compatible = "qcom,sa8775p-adsp-pas", .data = &sa8775p_adsp_resource}, ++ { .compatible = "qcom,sa8775p-cdsp0-pas", .data = &sa8775p_cdsp0_resource}, ++ { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, ++ { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, ++ { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, + { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, +-- +2.39.5 + diff --git a/queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch b/queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch new file mode 100644 index 00000000000..536169b5de9 --- /dev/null +++ b/queue-6.6/remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch @@ -0,0 +1,36 @@ +From 416a3e630ca586e9f41280d78c3d431ce80dbdf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 27 Oct 2024 01:09:45 +0300 +Subject: remoteproc: qcom: pas: enable SAR2130P audio DSP support + +From: Dmitry Baryshkov + +[ Upstream commit 009e288c989b3fe548a45c82da407d7bd00418a9 ] + +Enable support for the Audio DSP on the Qualcomm SAR2130P platform, +reusing the SM8350 resources. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20241027-sar2130p-adsp-v1-3-bd204e39d24e@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_pas.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c +index 4a73723e375a..fd6bf9e77afc 100644 +--- a/drivers/remoteproc/qcom_q6v5_pas.c ++++ b/drivers/remoteproc/qcom_q6v5_pas.c +@@ -1255,6 +1255,7 @@ static const struct of_device_id adsp_of_match[] = { + { .compatible = "qcom,sa8775p-cdsp1-pas", .data = &sa8775p_cdsp1_resource}, + { .compatible = "qcom,sa8775p-gpdsp0-pas", .data = &sa8775p_gpdsp0_resource}, + { .compatible = "qcom,sa8775p-gpdsp1-pas", .data = &sa8775p_gpdsp1_resource}, ++ { .compatible = "qcom,sar2130p-adsp-pas", .data = &sm8350_adsp_resource}, + { .compatible = "qcom,sc7180-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc7180-mpss-pas", .data = &mpss_resource_init}, + { .compatible = "qcom,sc7280-mpss-pas", .data = &mpss_resource_init}, +-- +2.39.5 + diff --git a/queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch b/queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch new file mode 100644 index 00000000000..8b3929b3ad9 --- /dev/null +++ b/queue-6.6/revert-drm-radeon-delay-connector-detecting-when-hpd.patch @@ -0,0 +1,47 @@ +From ed888cd3d1240ac7f5a6a6324f49f689967a9633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Nov 2024 16:23:45 -0500 +Subject: Revert "drm/radeon: Delay Connector detecting when HPD singals is + unstable" + +From: Alex Deucher + +[ Upstream commit 979bfe291b5b30a9132c2fd433247e677b24c6aa ] + +This reverts commit 949658cb9b69ab9d22a42a662b2fdc7085689ed8. + +This causes a blank screen on boot. + +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3696 +Signed-off-by: Alex Deucher +Cc: Shixiong Ou +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/radeon/radeon_connectors.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index cf0114ca59a4..b84b58926106 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -1267,16 +1267,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) + goto exit; + } + } +- +- if (dret && radeon_connector->hpd.hpd != RADEON_HPD_NONE && +- !radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && +- connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) { +- DRM_DEBUG_KMS("EDID is readable when HPD disconnected\n"); +- schedule_delayed_work(&rdev->hotplug_work, msecs_to_jiffies(1000)); +- ret = connector_status_disconnected; +- goto exit; +- } +- + if (dret) { + radeon_connector->detected_by_load = false; + radeon_connector_free_edid(connector); +-- +2.39.5 + diff --git a/queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch b/queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch new file mode 100644 index 00000000000..7e47820228d --- /dev/null +++ b/queue-6.6/revert-nvme-make-keep-alive-synchronous-operation.patch @@ -0,0 +1,94 @@ +From 97ef7fe1bdc1dbf712e06c443b46867a55e50235 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 11:42:08 +0530 +Subject: Revert "nvme: make keep-alive synchronous operation" + +From: Nilay Shroff + +[ Upstream commit 84488282166de6b6760ada8030e87aaa08bce3aa ] + +This reverts commit d06923670b5a5f609603d4a9fee4dec02d38de9c. + +It was realized that the fix implemented to contain the race condition +among the keep alive task and the fabric shutdown code path in the commit +d06923670b5ia ("nvme: make keep-alive synchronous operation") is not +optimal. The reason being keep-alive runs under the workqueue and making +it synchronous would waste a workqueue context. +Furthermore, we later found that the above race condition is a regression +caused due to the changes implemented in commit a54a93d0e359 ("nvme: move +stopping keep-alive into nvme_uninit_ctrl()"). So we decided to revert the +commit d06923670b5a ("nvme: make keep-alive synchronous operation") and +then fix the regression. + +Link: https://lore.kernel.org/all/196f4013-3bbf-43ff-98b4-9cb2a96c20c2@grimberg.me/ +Reviewed-by: Ming Lei +Signed-off-by: Nilay Shroff +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index ae494c799fc5..4aad16390d47 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1178,9 +1178,10 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) + nvme_keep_alive_work_period(ctrl)); + } + +-static void nvme_keep_alive_finish(struct request *rq, +- blk_status_t status, struct nvme_ctrl *ctrl) ++static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, ++ blk_status_t status) + { ++ struct nvme_ctrl *ctrl = rq->end_io_data; + unsigned long rtt = jiffies - (rq->deadline - rq->timeout); + unsigned long delay = nvme_keep_alive_work_period(ctrl); + enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); +@@ -1197,17 +1198,20 @@ static void nvme_keep_alive_finish(struct request *rq, + delay = 0; + } + ++ blk_mq_free_request(rq); ++ + if (status) { + dev_err(ctrl->device, + "failed nvme_keep_alive_end_io error=%d\n", + status); +- return; ++ return RQ_END_IO_NONE; + } + + ctrl->ka_last_check_time = jiffies; + ctrl->comp_seen = false; + if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) + queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); ++ return RQ_END_IO_NONE; + } + + static void nvme_keep_alive_work(struct work_struct *work) +@@ -1216,7 +1220,6 @@ static void nvme_keep_alive_work(struct work_struct *work) + struct nvme_ctrl, ka_work); + bool comp_seen = ctrl->comp_seen; + struct request *rq; +- blk_status_t status; + + ctrl->ka_last_check_time = jiffies; + +@@ -1239,9 +1242,9 @@ static void nvme_keep_alive_work(struct work_struct *work) + nvme_init_request(rq, &ctrl->ka_cmd); + + rq->timeout = ctrl->kato * HZ; +- status = blk_execute_rq(rq, false); +- nvme_keep_alive_finish(rq, status, ctrl); +- blk_mq_free_request(rq); ++ rq->end_io = nvme_keep_alive_end_io; ++ rq->end_io_data = ctrl; ++ blk_execute_rq_nowait(rq, false); + } + + static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) +-- +2.39.5 + diff --git a/queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch b/queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch new file mode 100644 index 00000000000..26840636026 --- /dev/null +++ b/queue-6.6/revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch @@ -0,0 +1,73 @@ +From 67cff7dc957b3b9d13ad423d755d0788bac5f62e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 19:11:31 +0000 +Subject: Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() + for PMU regs" + +From: Peter Griffin + +[ Upstream commit ccfb765944bb66813398958983cb8141e2624a6b ] + +This reverts commit 746f0770f916e6c48e422d6a34e67eae16707f0e. + +Now that we can register a SoC specific regmap with syscon using +of_syscon_register_regmap() api we can switch back to using +syscon_regmap_lookup_by_phandle() in the client drivers. + +Signed-off-by: Peter Griffin +Reviewed-by: Sam Protsenko +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20241029191131.2329414-1-peter.griffin@linaro.org +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/Kconfig | 1 + + drivers/watchdog/s3c2410_wdt.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +index 4ecf701abe5f..751458959411 100644 +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -512,6 +512,7 @@ config S3C2410_WATCHDOG + tristate "S3C6410/S5Pv210/Exynos Watchdog" + depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST + select WATCHDOG_CORE ++ select MFD_SYSCON if ARCH_EXYNOS + help + Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos + SoCs. This will reboot the system when the timer expires with +diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c +index 0c9c649583d4..0b4bd883ff28 100644 +--- a/drivers/watchdog/s3c2410_wdt.c ++++ b/drivers/watchdog/s3c2410_wdt.c +@@ -23,9 +23,9 @@ + #include + #include + #include ++#include + #include + #include +-#include + + #define S3C2410_WTCON 0x00 + #define S3C2410_WTDAT 0x04 +@@ -640,11 +640,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) + return ret; + + if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { +- wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node, +- "samsung,syscon-phandle"); ++ wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, ++ "samsung,syscon-phandle"); + if (IS_ERR(wdt->pmureg)) + return dev_err_probe(dev, PTR_ERR(wdt->pmureg), +- "PMU regmap lookup failed.\n"); ++ "syscon regmap lookup failed.\n"); + } + + wdt_irq = platform_get_irq(pdev, 0); +-- +2.39.5 + diff --git a/queue-6.6/rust-allow-clippy-needless_lifetimes.patch b/queue-6.6/rust-allow-clippy-needless_lifetimes.patch new file mode 100644 index 00000000000..b5fff9f68b2 --- /dev/null +++ b/queue-6.6/rust-allow-clippy-needless_lifetimes.patch @@ -0,0 +1,61 @@ +From b64fdc48b7eaeece3ef525bb3e950b314f93dcd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 16 Nov 2024 19:15:37 +0100 +Subject: rust: allow `clippy::needless_lifetimes` + +From: Miguel Ojeda + +[ Upstream commit 60fc1e6750133620e404d40b93df5afe32e3e6c6 ] + +In beta Clippy (i.e. Rust 1.83.0), the `needless_lifetimes` lint has +been extended [1] to suggest eliding `impl` lifetimes, e.g. + + error: the following explicit lifetimes could be elided: 'a + --> rust/kernel/list.rs:647:6 + | + 647 | impl<'a, T: ?Sized + ListItem, const ID: u64> FusedIterator for Iter<'a, T, ID> {} + | ^^ ^^ + | + = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes + = note: `-D clippy::needless-lifetimes` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]` + help: elide the lifetimes + | + 647 - impl<'a, T: ?Sized + ListItem, const ID: u64> FusedIterator for Iter<'a, T, ID> {} + 647 + impl, const ID: u64> FusedIterator for Iter<'_, T, ID> {} + +A possibility would have been to clean them -- the RFC patch [2] did +this, while asking if we wanted these cleanups. There is an open issue +[3] in Clippy about being able to differentiate some of the new cases, +e.g. those that do not involve introducing `'_`. Thus it seems others +feel similarly. + +Thus, for the time being, we decided to `allow` the lint. + +Link: https://github.com/rust-lang/rust-clippy/pull/13286 [1] +Link: https://lore.kernel.org/rust-for-linux/20241012231300.397010-1-ojeda@kernel.org/ [2] +Link: https://github.com/rust-lang/rust-clippy/issues/13514 [3] +Reviewed-by: Alice Ryhl +Reviewed-by: Andreas Hindborg +Link: https://lore.kernel.org/r/20241116181538.369355-1-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Sasha Levin +--- + Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile b/Makefile +index 0be58613bfe0..31b4fc9f5ccb 100644 +--- a/Makefile ++++ b/Makefile +@@ -469,6 +469,7 @@ export rust_common_flags := --edition=2021 \ + -Wclippy::let_unit_value -Wclippy::mut_mut \ + -Wclippy::needless_bitwise_bool \ + -Wclippy::needless_continue \ ++ -Aclippy::needless_lifetimes \ + -Wclippy::no_mangle_with_rust_abi \ + -Wclippy::dbg_macro + +-- +2.39.5 + diff --git a/queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch b/queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch new file mode 100644 index 00000000000..8441ec6c997 --- /dev/null +++ b/queue-6.6/rust-relax-most-deny-level-lints-to-warnings.patch @@ -0,0 +1,116 @@ +From 0953c79b5a2e3eb9a0c0752e7d76bbaf0f6f8666 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Jul 2024 18:05:59 +0200 +Subject: rust: relax most deny-level lints to warnings + +From: Miguel Ojeda + +[ Upstream commit f8f88aa25a03ce1e0fc8a9842840988b870f0c37 ] + +Since we are starting to support several Rust toolchains, lints (including +Clippy ones) now may behave differently and lint groups may include +new lints. + +Therefore, to maximize the chances a given version works, relax some +deny-level lints to warnings. It may also make our lives a bit easier +while developing new code or refactoring. + +To be clear, the requirements for in-tree code are still the same, since +Rust code still needs to be warning-free (patches should be clean under +`WERROR=y`) and the set of lints is not changed. + +`unsafe_op_in_unsafe_fn` is left unmodified, i.e. as an error, since it is +becoming the default in the language (warn-by-default in Rust 2024 [1] and +ideally an error later on) and thus it should also be very well tested. In +addition, it is simple enough that it should not have false positives +(unlike e.g. `rust_2018_idioms`'s `explicit_outlives_requirements`). + +`non_ascii_idents` is left unmodified as well, i.e. as an error, since +it is unlikely one gains any productivity during development if it +were a warning (in fact, it may be worse, since it is likely one made +a typo). In addition, it should not have false positives. + +Finally, put the two `-D` ones at the top and take the chance to do one +per line. + +Link: https://github.com/rust-lang/rust/pull/112038 [1] +Reviewed-by: Finn Behrens +Tested-by: Benno Lossin +Tested-by: Andreas Hindborg +Link: https://lore.kernel.org/r/20240709160615.998336-5-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Stable-dep-of: 60fc1e675013 ("rust: allow `clippy::needless_lifetimes`") +Signed-off-by: Sasha Levin +--- + Makefile | 24 +++++++++++++----------- + rust/Makefile | 4 ++-- + 2 files changed, 15 insertions(+), 13 deletions(-) + +diff --git a/Makefile b/Makefile +index ec4d9d1d9b7a..0be58613bfe0 100644 +--- a/Makefile ++++ b/Makefile +@@ -457,17 +457,19 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS) + # host programs. + export rust_common_flags := --edition=2021 \ + -Zbinary_dep_depinfo=y \ +- -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \ +- -Dunreachable_pub -Dnon_ascii_idents \ ++ -Dunsafe_op_in_unsafe_fn \ ++ -Dnon_ascii_idents \ ++ -Wrust_2018_idioms \ ++ -Wunreachable_pub \ + -Wmissing_docs \ +- -Drustdoc::missing_crate_level_docs \ +- -Dclippy::correctness -Dclippy::style \ +- -Dclippy::suspicious -Dclippy::complexity \ +- -Dclippy::perf \ +- -Dclippy::let_unit_value -Dclippy::mut_mut \ +- -Dclippy::needless_bitwise_bool \ +- -Dclippy::needless_continue \ +- -Dclippy::no_mangle_with_rust_abi \ ++ -Wrustdoc::missing_crate_level_docs \ ++ -Wclippy::correctness -Wclippy::style \ ++ -Wclippy::suspicious -Wclippy::complexity \ ++ -Wclippy::perf \ ++ -Wclippy::let_unit_value -Wclippy::mut_mut \ ++ -Wclippy::needless_bitwise_bool \ ++ -Wclippy::needless_continue \ ++ -Wclippy::no_mangle_with_rust_abi \ + -Wclippy::dbg_macro + + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) +@@ -572,7 +574,7 @@ KBUILD_RUSTFLAGS := $(rust_common_flags) \ + -Csymbol-mangling-version=v0 \ + -Crelocation-model=static \ + -Zfunction-sections=n \ +- -Dclippy::float_arithmetic ++ -Wclippy::float_arithmetic + + KBUILD_AFLAGS_KERNEL := + KBUILD_CFLAGS_KERNEL := +diff --git a/rust/Makefile b/rust/Makefile +index 333b9a482473..12b9d78fd25c 100644 +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -422,7 +422,7 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),) + endif + + $(obj)/core.o: private skip_clippy = 1 +-$(obj)/core.o: private skip_flags = -Dunreachable_pub ++$(obj)/core.o: private skip_flags = -Wunreachable_pub + $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) + $(obj)/core.o: private rustc_target_flags = $(core-cfgs) + $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs scripts/target.json FORCE +@@ -433,7 +433,7 @@ $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE + $(call if_changed_dep,rustc_library) + + $(obj)/alloc.o: private skip_clippy = 1 +-$(obj)/alloc.o: private skip_flags = -Dunreachable_pub ++$(obj)/alloc.o: private skip_flags = -Wunreachable_pub + $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) + $(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE + $(call if_changed_dep,rustc_library) +-- +2.39.5 + diff --git a/queue-6.6/sched-initialize-idle-tasks-only-once.patch b/queue-6.6/sched-initialize-idle-tasks-only-once.patch new file mode 100644 index 00000000000..5b5de846604 --- /dev/null +++ b/queue-6.6/sched-initialize-idle-tasks-only-once.patch @@ -0,0 +1,83 @@ +From 1c68684e10d7b59244de0957982a8abfcc6fa994 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Oct 2024 11:43:42 +0100 +Subject: sched: Initialize idle tasks only once + +From: Thomas Gleixner + +[ Upstream commit b23decf8ac9102fc52c4de5196f4dc0a5f3eb80b ] + +Idle tasks are initialized via __sched_fork() twice: + + fork_idle() + copy_process() + sched_fork() + __sched_fork() + init_idle() + __sched_fork() + +Instead of cleaning this up, sched_ext hacked around it. Even when analyis +and solution were provided in a discussion, nobody cared to clean this up. + +init_idle() is also invoked from sched_init() to initialize the boot CPU's +idle task, which requires the __sched_fork() invocation. But this can be +trivially solved by invoking __sched_fork() before init_idle() in +sched_init() and removing the __sched_fork() invocation from init_idle(). + +Do so and clean up the comments explaining this historical leftover. + +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20241028103142.359584747@linutronix.de +Signed-off-by: Sasha Levin +--- + kernel/sched/core.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 228f7c07da72..86606fb9e6bc 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -4488,7 +4488,8 @@ int wake_up_state(struct task_struct *p, unsigned int state) + * Perform scheduler related setup for a newly forked process p. + * p is forked by current. + * +- * __sched_fork() is basic setup used by init_idle() too: ++ * __sched_fork() is basic setup which is also used by sched_init() to ++ * initialize the boot CPU's idle task. + */ + static void __sched_fork(unsigned long clone_flags, struct task_struct *p) + { +@@ -9257,8 +9258,6 @@ void __init init_idle(struct task_struct *idle, int cpu) + struct rq *rq = cpu_rq(cpu); + unsigned long flags; + +- __sched_fork(0, idle); +- + raw_spin_lock_irqsave(&idle->pi_lock, flags); + raw_spin_rq_lock(rq); + +@@ -9273,10 +9272,8 @@ void __init init_idle(struct task_struct *idle, int cpu) + + #ifdef CONFIG_SMP + /* +- * It's possible that init_idle() gets called multiple times on a task, +- * in that case do_set_cpus_allowed() will not do the right thing. +- * +- * And since this is boot we can forgo the serialization. ++ * No validation and serialization required at boot time and for ++ * setting up the idle tasks of not yet online CPUs. + */ + set_cpus_allowed_common(idle, &ac); + #endif +@@ -10105,6 +10102,7 @@ void __init sched_init(void) + * but because we are the idle thread, we just pick up running again + * when this runqueue becomes "idle". + */ ++ __sched_fork(0, current); + init_idle(current, smp_processor_id()); + + calc_load_update = jiffies + LOAD_FREQ; +-- +2.39.5 + diff --git a/queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch b/queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch new file mode 100644 index 00000000000..2684ad827ed --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch @@ -0,0 +1,218 @@ +From 79e22c0c4b2a961b8942f2f788cbf3c7dda7017d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 10:15:27 +0800 +Subject: scsi: hisi_sas: Allocate DFX memory during dump trigger + +From: Yihang Li + +[ Upstream commit 63f0733d07ce60252e885602b39571ade0441015 ] + +Currently, if CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE is enabled, the +memory space used by DFX is allocated during device initialization, which +occupies a large number of memory resources. The memory usage before and +after the driver is loaded is as follows: + +Memory usage before the driver is loaded: +$ free -m + total used free shared buff/cache available +Mem: 867352 2578 864037 11 735 861681 +Swap: 4095 0 4095 + +Memory usage after the driver which include 4 HBAs is loaded: +$ insmod hisi_sas_v3_hw.ko +$ free -m + total used free shared buff/cache available +Mem: 867352 4760 861848 11 743 859495 +Swap: 4095 0 4095 + +The driver with 4 HBAs connected will allocate about 110 MB of memory +without enabling debugfs. + +Therefore, to avoid wasting memory resources, DFX memory is allocated +during dump triggering. The dump may fail due to memory allocation +failure. After this change, each dump costs about 10 MB of memory, and each +dump lasts about 100 ms. + +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1694571327-78697-4-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 93 +++++++++++++------------- + 2 files changed, 46 insertions(+), 49 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 3d511c44c02d..1e4550156b73 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -343,7 +343,7 @@ struct hisi_sas_hw { + u8 reg_index, u8 reg_count, u8 *write_data); + void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, + int delay_ms, int timeout_ms); +- void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); ++ int (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); + int complete_hdr_size; + const struct scsi_host_template *sht; + }; +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 10f048b5a489..cea548655629 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -558,7 +558,7 @@ static int experimental_iopoll_q_cnt; + module_param(experimental_iopoll_q_cnt, int, 0444); + MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0"); + +-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); ++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); + + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { +@@ -3867,37 +3867,6 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + &debugfs_ras_v3_hw_fops); + } + +-static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) +-{ +- int debugfs_dump_index = hisi_hba->debugfs_dump_index; +- struct device *dev = hisi_hba->dev; +- u64 timestamp = local_clock(); +- +- if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { +- dev_warn(dev, "dump count exceeded!\n"); +- return; +- } +- +- do_div(timestamp, NSEC_PER_MSEC); +- hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; +- +- debugfs_snapshot_prepare_v3_hw(hisi_hba); +- +- debugfs_snapshot_global_reg_v3_hw(hisi_hba); +- debugfs_snapshot_port_reg_v3_hw(hisi_hba); +- debugfs_snapshot_axi_reg_v3_hw(hisi_hba); +- debugfs_snapshot_ras_reg_v3_hw(hisi_hba); +- debugfs_snapshot_cq_reg_v3_hw(hisi_hba); +- debugfs_snapshot_dq_reg_v3_hw(hisi_hba); +- debugfs_snapshot_itct_reg_v3_hw(hisi_hba); +- debugfs_snapshot_iost_reg_v3_hw(hisi_hba); +- +- debugfs_create_files_v3_hw(hisi_hba); +- +- debugfs_snapshot_restore_v3_hw(hisi_hba); +- hisi_hba->debugfs_dump_index++; +-} +- + static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +@@ -3905,9 +3874,6 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + struct hisi_hba *hisi_hba = file->f_inode->i_private; + char buf[8]; + +- if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) +- return -EFAULT; +- + if (count > 8) + return -EFAULT; + +@@ -3918,7 +3884,10 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + return -EFAULT; + + down(&hisi_hba->sem); +- debugfs_snapshot_regs_v3_hw(hisi_hba); ++ if (debugfs_snapshot_regs_v3_hw(hisi_hba)) { ++ up(&hisi_hba->sem); ++ return -EFAULT; ++ } + up(&hisi_hba->sem); + + return count; +@@ -4704,7 +4673,7 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + { + const struct hisi_sas_hw *hw = hisi_hba->hw; + struct device *dev = hisi_hba->dev; +- int p, c, d, r, i; ++ int p, c, d, r; + size_t sz; + + for (r = 0; r < DEBUGFS_REGS_NUM; r++) { +@@ -4784,11 +4753,48 @@ static int debugfs_alloc_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + + return 0; + fail: +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) +- debugfs_release_v3_hw(hisi_hba, i); ++ debugfs_release_v3_hw(hisi_hba, dump_index); + return -ENOMEM; + } + ++static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int debugfs_dump_index = hisi_hba->debugfs_dump_index; ++ struct device *dev = hisi_hba->dev; ++ u64 timestamp = local_clock(); ++ ++ if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { ++ dev_warn(dev, "dump count exceeded!\n"); ++ return -EINVAL; ++ } ++ ++ if (debugfs_alloc_v3_hw(hisi_hba, debugfs_dump_index)) { ++ dev_warn(dev, "failed to alloc memory\n"); ++ return -ENOMEM; ++ } ++ ++ do_div(timestamp, NSEC_PER_MSEC); ++ hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; ++ ++ debugfs_snapshot_prepare_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_global_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_port_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_axi_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_ras_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_cq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_dq_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_itct_reg_v3_hw(hisi_hba); ++ debugfs_snapshot_iost_reg_v3_hw(hisi_hba); ++ ++ debugfs_create_files_v3_hw(hisi_hba); ++ ++ debugfs_snapshot_restore_v3_hw(hisi_hba); ++ hisi_hba->debugfs_dump_index++; ++ ++ return 0; ++} ++ + static void debugfs_phy_down_cnt_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct dentry *dir = debugfs_create_dir("phy_down_cnt", +@@ -4875,7 +4881,6 @@ static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) + static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + { + struct device *dev = hisi_hba->dev; +- int i; + + hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), + hisi_sas_debugfs_dir); +@@ -4892,14 +4897,6 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + + debugfs_phy_down_cnt_init_v3_hw(hisi_hba); + debugfs_fifo_init_v3_hw(hisi_hba); +- +- for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { +- if (debugfs_alloc_v3_hw(hisi_hba, i)) { +- debugfs_exit_v3_hw(hisi_hba); +- dev_dbg(dev, "failed to init debugfs!\n"); +- break; +- } +- } + } + + static int +-- +2.39.5 + diff --git a/queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch b/queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch new file mode 100644 index 00000000000..99fc88c6489 --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch @@ -0,0 +1,367 @@ +From 0cc7a12acc537f05cbb27a4d4630a0117826440d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 10:18:21 +0800 +Subject: scsi: hisi_sas: Create all dump files during debugfs initialization + +From: Yihang Li + +[ Upstream commit 9f564f15f88490b484e02442dc4c4b11640ea172 ] + +For the current debugfs of hisi_sas, after user triggers dump, the +driver allocate memory space to save the register information and create +debugfs files to display the saved information. In this process, the +debugfs files created after each dump. + +Therefore, when the dump is triggered while the driver is unbind, the +following hang occurs: + +[67840.853907] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000a0 +[67840.862947] Mem abort info: +[67840.865855] ESR = 0x0000000096000004 +[67840.869713] EC = 0x25: DABT (current EL), IL = 32 bits +[67840.875125] SET = 0, FnV = 0 +[67840.878291] EA = 0, S1PTW = 0 +[67840.881545] FSC = 0x04: level 0 translation fault +[67840.886528] Data abort info: +[67840.889524] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[67840.895117] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[67840.900284] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[67840.905709] user pgtable: 4k pages, 48-bit VAs, pgdp=0000002803a1f000 +[67840.912263] [00000000000000a0] pgd=0000000000000000, p4d=0000000000000000 +[67840.919177] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP +[67840.996435] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[67841.003628] pc : down_write+0x30/0x98 +[67841.007546] lr : start_creating.part.0+0x60/0x198 +[67841.012495] sp : ffff8000b979ba20 +[67841.016046] x29: ffff8000b979ba20 x28: 0000000000000010 x27: 0000000000024b40 +[67841.023412] x26: 0000000000000012 x25: ffff20202b355ae8 x24: ffff20202b35a8c8 +[67841.030779] x23: ffffa36877928208 x22: ffffa368b4972240 x21: ffff8000b979bb18 +[67841.038147] x20: ffff00281dc1e3c0 x19: fffffffffffffffe x18: 0000000000000020 +[67841.045515] x17: 0000000000000000 x16: ffffa368b128a530 x15: ffffffffffffffff +[67841.052888] x14: ffff8000b979bc18 x13: ffffffffffffffff x12: ffff8000b979bb18 +[67841.060263] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffa368b1289b18 +[67841.067640] x8 : 0000000000000012 x7 : 0000000000000000 x6 : 00000000000003a9 +[67841.075014] x5 : 0000000000000000 x4 : ffff002818c5cb00 x3 : 0000000000000001 +[67841.082388] x2 : 0000000000000000 x1 : ffff002818c5cb00 x0 : 00000000000000a0 +[67841.089759] Call trace: +[67841.092456] down_write+0x30/0x98 +[67841.096017] start_creating.part.0+0x60/0x198 +[67841.100613] debugfs_create_dir+0x48/0x1f8 +[67841.104950] debugfs_create_files_v3_hw+0x88/0x348 [hisi_sas_v3_hw] +[67841.111447] debugfs_snapshot_regs_v3_hw+0x708/0x798 [hisi_sas_v3_hw] +[67841.118111] debugfs_trigger_dump_v3_hw_write+0x9c/0x120 [hisi_sas_v3_hw] +[67841.125115] full_proxy_write+0x68/0xc8 +[67841.129175] vfs_write+0xd8/0x3f0 +[67841.132708] ksys_write+0x70/0x108 +[67841.136317] __arm64_sys_write+0x24/0x38 +[67841.140440] invoke_syscall+0x50/0x128 +[67841.144385] el0_svc_common.constprop.0+0xc8/0xf0 +[67841.149273] do_el0_svc+0x24/0x38 +[67841.152773] el0_svc+0x38/0xd8 +[67841.156009] el0t_64_sync_handler+0xc0/0xc8 +[67841.160361] el0t_64_sync+0x1a4/0x1a8 +[67841.164189] Code: b9000882 d2800002 d2800023 f9800011 (c85ffc05) +[67841.170443] ---[ end trace 0000000000000000 ]--- + +To fix this issue, create all directories and files during debugfs +initialization. In this way, the driver only needs to allocate memory +space to save information each time the user triggers dumping. + +Signed-off-by: Yihang Li +Link: https://lore.kernel.org/r/20241008021822.2617339-13-liyihang9@huawei.com +Reviewed-by: Xingui Yang +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 99 ++++++++++++++++++++------ + 1 file changed, 77 insertions(+), 22 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index cea548655629..ff5f86867dbf 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -3560,6 +3560,11 @@ debugfs_to_reg_name_v3_hw(int off, int base_off, + return NULL; + } + ++static bool debugfs_dump_is_generated_v3_hw(void *p) ++{ ++ return p ? true : false; ++} ++ + static void debugfs_print_reg_v3_hw(u32 *regs_val, struct seq_file *s, + const struct hisi_sas_debugfs_reg *reg) + { +@@ -3585,6 +3590,9 @@ static int debugfs_global_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *global = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(global->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(global->data, s, + &debugfs_global_reg); + +@@ -3596,6 +3604,9 @@ static int debugfs_axi_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *axi = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(axi->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(axi->data, s, + &debugfs_axi_reg); + +@@ -3607,6 +3618,9 @@ static int debugfs_ras_v3_hw_show(struct seq_file *s, void *p) + { + struct hisi_sas_debugfs_regs *ras = s->private; + ++ if (!debugfs_dump_is_generated_v3_hw(ras->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(ras->data, s, + &debugfs_ras_reg); + +@@ -3619,6 +3633,9 @@ static int debugfs_port_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_port *port = s->private; + const struct hisi_sas_debugfs_reg *reg_port = &debugfs_port_reg; + ++ if (!debugfs_dump_is_generated_v3_hw(port->data)) ++ return -EPERM; ++ + debugfs_print_reg_v3_hw(port->data, s, reg_port); + + return 0; +@@ -3674,6 +3691,9 @@ static int debugfs_cq_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_cq *debugfs_cq = s->private; + int slot; + ++ if (!debugfs_dump_is_generated_v3_hw(debugfs_cq->complete_hdr)) ++ return -EPERM; ++ + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) + debugfs_cq_show_slot_v3_hw(s, slot, debugfs_cq); + +@@ -3695,8 +3715,12 @@ static void debugfs_dq_show_slot_v3_hw(struct seq_file *s, int slot, + + static int debugfs_dq_v3_hw_show(struct seq_file *s, void *p) + { ++ struct hisi_sas_debugfs_dq *debugfs_dq = s->private; + int slot; + ++ if (!debugfs_dump_is_generated_v3_hw(debugfs_dq->hdr)) ++ return -EPERM; ++ + for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) + debugfs_dq_show_slot_v3_hw(s, slot, s->private); + +@@ -3710,6 +3734,9 @@ static int debugfs_iost_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_iost *iost = debugfs_iost->iost; + int i, max_command_entries = HISI_SAS_MAX_COMMANDS; + ++ if (!debugfs_dump_is_generated_v3_hw(iost)) ++ return -EPERM; ++ + for (i = 0; i < max_command_entries; i++, iost++) { + __le64 *data = &iost->qw0; + +@@ -3729,6 +3756,9 @@ static int debugfs_iost_cache_v3_hw_show(struct seq_file *s, void *p) + int i, tab_idx; + __le64 *iost; + ++ if (!debugfs_dump_is_generated_v3_hw(iost_cache)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, iost_cache++) { + /* + * Data struct of IOST cache: +@@ -3752,6 +3782,9 @@ static int debugfs_itct_v3_hw_show(struct seq_file *s, void *p) + struct hisi_sas_debugfs_itct *debugfs_itct = s->private; + struct hisi_sas_itct *itct = debugfs_itct->itct; + ++ if (!debugfs_dump_is_generated_v3_hw(itct)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { + __le64 *data = &itct->qw0; + +@@ -3771,6 +3804,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + int i, tab_idx; + __le64 *itct; + ++ if (!debugfs_dump_is_generated_v3_hw(itct_cache)) ++ return -EPERM; ++ + for (i = 0; i < HISI_SAS_IOST_ITCT_CACHE_NUM; i++, itct_cache++) { + /* + * Data struct of ITCT cache: +@@ -3788,10 +3824,9 @@ static int debugfs_itct_cache_v3_hw_show(struct seq_file *s, void *p) + } + DEFINE_SHOW_ATTRIBUTE(debugfs_itct_cache_v3_hw); + +-static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) ++static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba, int index) + { + u64 *debugfs_timestamp; +- int dump_index = hisi_hba->debugfs_dump_index; + struct dentry *dump_dentry; + struct dentry *dentry; + char name[256]; +@@ -3799,17 +3834,17 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + int c; + int d; + +- snprintf(name, 256, "%d", dump_index); ++ snprintf(name, 256, "%d", index); + + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); + +- debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; ++ debugfs_timestamp = &hisi_hba->debugfs_timestamp[index]; + + debugfs_create_u64("timestamp", 0400, dump_dentry, + debugfs_timestamp); + + debugfs_create_file("global", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_GLOBAL], + &debugfs_global_v3_hw_fops); + + /* Create port dir and files */ +@@ -3818,7 +3853,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", p); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_port_reg[dump_index][p], ++ &hisi_hba->debugfs_port_reg[index][p], + &debugfs_port_v3_hw_fops); + } + +@@ -3828,7 +3863,7 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", c); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_cq[dump_index][c], ++ &hisi_hba->debugfs_cq[index][c], + &debugfs_cq_v3_hw_fops); + } + +@@ -3838,32 +3873,32 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) + snprintf(name, 256, "%d", d); + + debugfs_create_file(name, 0400, dentry, +- &hisi_hba->debugfs_dq[dump_index][d], ++ &hisi_hba->debugfs_dq[index][d], + &debugfs_dq_v3_hw_fops); + } + + debugfs_create_file("iost", 0400, dump_dentry, +- &hisi_hba->debugfs_iost[dump_index], ++ &hisi_hba->debugfs_iost[index], + &debugfs_iost_v3_hw_fops); + + debugfs_create_file("iost_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_iost_cache[dump_index], ++ &hisi_hba->debugfs_iost_cache[index], + &debugfs_iost_cache_v3_hw_fops); + + debugfs_create_file("itct", 0400, dump_dentry, +- &hisi_hba->debugfs_itct[dump_index], ++ &hisi_hba->debugfs_itct[index], + &debugfs_itct_v3_hw_fops); + + debugfs_create_file("itct_cache", 0400, dump_dentry, +- &hisi_hba->debugfs_itct_cache[dump_index], ++ &hisi_hba->debugfs_itct_cache[index], + &debugfs_itct_cache_v3_hw_fops); + + debugfs_create_file("axi", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_AXI], + &debugfs_axi_v3_hw_fops); + + debugfs_create_file("ras", 0400, dump_dentry, +- &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], ++ &hisi_hba->debugfs_regs[index][DEBUGFS_RAS], + &debugfs_ras_v3_hw_fops); + } + +@@ -4645,22 +4680,34 @@ static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + int i; + + devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); ++ hisi_hba->debugfs_iost_cache[dump_index].cache = NULL; + devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); ++ hisi_hba->debugfs_itct_cache[dump_index].cache = NULL; + devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); ++ hisi_hba->debugfs_iost[dump_index].iost = NULL; + devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); ++ hisi_hba->debugfs_itct[dump_index].itct = NULL; + +- for (i = 0; i < hisi_hba->queue_count; i++) ++ for (i = 0; i < hisi_hba->queue_count; i++) { + devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); ++ hisi_hba->debugfs_dq[dump_index][i].hdr = NULL; ++ } + +- for (i = 0; i < hisi_hba->queue_count; i++) ++ for (i = 0; i < hisi_hba->queue_count; i++) { + devm_kfree(dev, + hisi_hba->debugfs_cq[dump_index][i].complete_hdr); ++ hisi_hba->debugfs_cq[dump_index][i].complete_hdr = NULL; ++ } + +- for (i = 0; i < DEBUGFS_REGS_NUM; i++) ++ for (i = 0; i < DEBUGFS_REGS_NUM; i++) { + devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); ++ hisi_hba->debugfs_regs[dump_index][i].data = NULL; ++ } + +- for (i = 0; i < hisi_hba->n_phy; i++) ++ for (i = 0; i < hisi_hba->n_phy; i++) { + devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); ++ hisi_hba->debugfs_port_reg[dump_index][i].data = NULL; ++ } + } + + static const struct hisi_sas_debugfs_reg *debugfs_reg_array_v3_hw[DEBUGFS_REGS_NUM] = { +@@ -4787,8 +4834,6 @@ static int debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) + debugfs_snapshot_itct_reg_v3_hw(hisi_hba); + debugfs_snapshot_iost_reg_v3_hw(hisi_hba); + +- debugfs_create_files_v3_hw(hisi_hba); +- + debugfs_snapshot_restore_v3_hw(hisi_hba); + hisi_hba->debugfs_dump_index++; + +@@ -4872,6 +4917,17 @@ static void debugfs_bist_init_v3_hw(struct hisi_hba *hisi_hba) + hisi_hba->debugfs_bist_linkrate = SAS_LINK_RATE_1_5_GBPS; + } + ++static void debugfs_dump_init_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ int i; ++ ++ hisi_hba->debugfs_dump_dentry = ++ debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ ++ for (i = 0; i < hisi_sas_debugfs_dump_count; i++) ++ debugfs_create_files_v3_hw(hisi_hba, i); ++} ++ + static void debugfs_exit_v3_hw(struct hisi_hba *hisi_hba) + { + debugfs_remove_recursive(hisi_hba->debugfs_dir); +@@ -4892,8 +4948,7 @@ static void debugfs_init_v3_hw(struct hisi_hba *hisi_hba) + /* create bist structures */ + debugfs_bist_init_v3_hw(hisi_hba); + +- hisi_hba->debugfs_dump_dentry = +- debugfs_create_dir("dump", hisi_hba->debugfs_dir); ++ debugfs_dump_init_v3_hw(hisi_hba); + + debugfs_phy_down_cnt_init_v3_hw(hisi_hba); + debugfs_fifo_init_v3_hw(hisi_hba); +-- +2.39.5 + diff --git a/queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch b/queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch new file mode 100644 index 00000000000..bc50a57a9c9 --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-directly-call-register-snapshot-instea.patch @@ -0,0 +1,108 @@ +From 2887d53cae84d6f45259c6ad9a1bb4cadfa32e18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Sep 2023 10:15:26 +0800 +Subject: scsi: hisi_sas: Directly call register snapshot instead of using + workqueue + +From: Yihang Li + +[ Upstream commit 2ff07b5c6fe9173e7a7de3b23f300d71ad4d8fde ] + +Currently, register information dump is performed via workqueue, regardless +of the trigger mode (automatic or manual). There is a delay in dumping +register through workqueue, the exact register information at trigger time +cannot be obtained. + +Call register snapshot directly instead of through a workqueue. + +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1694571327-78697-3-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: 9f564f15f884 ("scsi: hisi_sas: Create all dump files during debugfs initialization") +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 - + drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 14 +++----------- + 3 files changed, 8 insertions(+), 14 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h +index 9e73e9cbbcfc..3d511c44c02d 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -451,7 +451,6 @@ struct hisi_hba { + const struct hisi_sas_hw *hw; /* Low level hw interface */ + unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; + struct work_struct rst_work; +- struct work_struct debugfs_work; + u32 phy_state; + u32 intr_coal_ticks; /* Time of interrupt coalesce in us */ + u32 intr_coal_count; /* Interrupt count to coalesce */ +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index db9ae206974c..5fdba7b39a1b 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1967,8 +1967,11 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task, + struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct hisi_sas_internal_abort_data *timeout = data; + +- if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) +- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) { ++ down(&hisi_hba->sem); ++ hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); ++ up(&hisi_hba->sem); ++ } + + if (task->task_state_flags & SAS_TASK_STATE_DONE) { + pr_err("Internal abort: timeout %016llx\n", +diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +index 4054659d48f7..10f048b5a489 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -558,7 +558,6 @@ static int experimental_iopoll_q_cnt; + module_param(experimental_iopoll_q_cnt, int, 0444); + MODULE_PARM_DESC(experimental_iopoll_q_cnt, "number of queues to be used as poll mode, def=0"); + +-static void debugfs_work_handler_v3_hw(struct work_struct *work); + static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); + + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) +@@ -3397,7 +3396,6 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev) + hisi_hba = shost_priv(shost); + + INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler); +- INIT_WORK(&hisi_hba->debugfs_work, debugfs_work_handler_v3_hw); + hisi_hba->hw = &hisi_sas_v3_hw; + hisi_hba->pci_dev = pdev; + hisi_hba->dev = dev; +@@ -3919,7 +3917,9 @@ static ssize_t debugfs_trigger_dump_v3_hw_write(struct file *file, + if (buf[0] != '1') + return -EFAULT; + +- queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); ++ down(&hisi_hba->sem); ++ debugfs_snapshot_regs_v3_hw(hisi_hba); ++ up(&hisi_hba->sem); + + return count; + } +@@ -4670,14 +4670,6 @@ static void debugfs_fifo_init_v3_hw(struct hisi_hba *hisi_hba) + } + } + +-static void debugfs_work_handler_v3_hw(struct work_struct *work) +-{ +- struct hisi_hba *hisi_hba = +- container_of(work, struct hisi_hba, debugfs_work); +- +- debugfs_snapshot_regs_v3_hw(hisi_hba); +-} +- + static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) + { + struct device *dev = hisi_hba->dev; +-- +2.39.5 + diff --git a/queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch b/queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch new file mode 100644 index 00000000000..d549419b291 --- /dev/null +++ b/queue-6.6/scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch @@ -0,0 +1,125 @@ +From 0f2f7ea319f6a532f8336eca9a7846846e6d70a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Jan 2024 14:25:44 +0800 +Subject: scsi: hisi_sas: Fix a deadlock issue related to automatic dump + +From: Yihang Li + +[ Upstream commit 3c4f53b2c341ec6428b98cb51a89a09b025d0953 ] + +If we issue a disabling PHY command, the device attached with it will go +offline, if a 2 bit ECC error occurs at the same time, a hung task may be +found: + +[ 4613.652388] INFO: task kworker/u256:0:165233 blocked for more than 120 seconds. +[ 4613.666297] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 4613.674809] task:kworker/u256:0 state:D stack: 0 pid:165233 ppid: 2 flags:0x00000208 +[ 4613.683959] Workqueue: 0000:74:02.0_disco_q sas_revalidate_domain [libsas] +[ 4613.691518] Call trace: +[ 4613.694678] __switch_to+0xf8/0x17c +[ 4613.698872] __schedule+0x660/0xee0 +[ 4613.703063] schedule+0xac/0x240 +[ 4613.706994] schedule_timeout+0x500/0x610 +[ 4613.711705] __down+0x128/0x36c +[ 4613.715548] down+0x240/0x2d0 +[ 4613.719221] hisi_sas_internal_abort_timeout+0x1bc/0x260 [hisi_sas_main] +[ 4613.726618] sas_execute_internal_abort+0x144/0x310 [libsas] +[ 4613.732976] sas_execute_internal_abort_dev+0x44/0x60 [libsas] +[ 4613.739504] hisi_sas_internal_task_abort_dev.isra.0+0xbc/0x1b0 [hisi_sas_main] +[ 4613.747499] hisi_sas_dev_gone+0x174/0x250 [hisi_sas_main] +[ 4613.753682] sas_notify_lldd_dev_gone+0xec/0x2e0 [libsas] +[ 4613.759781] sas_unregister_common_dev+0x4c/0x7a0 [libsas] +[ 4613.765962] sas_destruct_devices+0xb8/0x120 [libsas] +[ 4613.771709] sas_do_revalidate_domain.constprop.0+0x1b8/0x31c [libsas] +[ 4613.778930] sas_revalidate_domain+0x60/0xa4 [libsas] +[ 4613.784716] process_one_work+0x248/0x950 +[ 4613.789424] worker_thread+0x318/0x934 +[ 4613.793878] kthread+0x190/0x200 +[ 4613.797810] ret_from_fork+0x10/0x18 +[ 4613.802121] INFO: task kworker/u256:4:316722 blocked for more than 120 seconds. +[ 4613.816026] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 4613.824538] task:kworker/u256:4 state:D stack: 0 pid:316722 ppid: 2 flags:0x00000208 +[ 4613.833670] Workqueue: 0000:74:02.0 hisi_sas_rst_work_handler [hisi_sas_main] +[ 4613.841491] Call trace: +[ 4613.844647] __switch_to+0xf8/0x17c +[ 4613.848852] __schedule+0x660/0xee0 +[ 4613.853052] schedule+0xac/0x240 +[ 4613.856984] schedule_timeout+0x500/0x610 +[ 4613.861695] __down+0x128/0x36c +[ 4613.865542] down+0x240/0x2d0 +[ 4613.869216] hisi_sas_controller_prereset+0x58/0x1fc [hisi_sas_main] +[ 4613.876324] hisi_sas_rst_work_handler+0x40/0x8c [hisi_sas_main] +[ 4613.883019] process_one_work+0x248/0x950 +[ 4613.887732] worker_thread+0x318/0x934 +[ 4613.892204] kthread+0x190/0x200 +[ 4613.896118] ret_from_fork+0x10/0x18 +[ 4613.900423] INFO: task kworker/u256:1:348985 blocked for more than 121 seconds. +[ 4613.914341] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 4613.922852] task:kworker/u256:1 state:D stack: 0 pid:348985 ppid: 2 flags:0x00000208 +[ 4613.931984] Workqueue: 0000:74:02.0_event_q sas_port_event_worker [libsas] +[ 4613.939549] Call trace: +[ 4613.942702] __switch_to+0xf8/0x17c +[ 4613.946892] __schedule+0x660/0xee0 +[ 4613.951083] schedule+0xac/0x240 +[ 4613.955015] schedule_timeout+0x500/0x610 +[ 4613.959725] wait_for_common+0x200/0x610 +[ 4613.964349] wait_for_completion+0x3c/0x5c +[ 4613.969146] flush_workqueue+0x198/0x790 +[ 4613.973776] sas_porte_broadcast_rcvd+0x1e8/0x320 [libsas] +[ 4613.979960] sas_port_event_worker+0x54/0xa0 [libsas] +[ 4613.985708] process_one_work+0x248/0x950 +[ 4613.990420] worker_thread+0x318/0x934 +[ 4613.994868] kthread+0x190/0x200 +[ 4613.998800] ret_from_fork+0x10/0x18 + +This is because when the device goes offline, we obtain the hisi_hba +semaphore and send the ABORT_DEV command to the device. However, the +internal abort timed out due to the 2 bit ECC error and triggers automatic +dump. In addition, since the hisi_hba semaphore has been obtained, the dump +cannot be executed and the controller cannot be reset. + +Therefore, the deadlocks occur on the following circular dependencies: +hisi_sas_dev_gone() -> down() -> hisi_sas_internal_task_abort_dev() -> ... +-> hisi_sas_internal_abort_timeout() -> down(). + +The deadlock is triggered only when the timeout occurs during device goes +offline. To fix this issue, use .rst_ha_timeout to distinguish the scenario +where a device goes offline from other scenarios. + +Fixes: 2ff07b5c6fe9 ("scsi: hisi_sas: Directly call register snapshot instead of using workqueue") +Signed-off-by: Yihang Li +Signed-off-by: Xiang Chen +Link: https://lore.kernel.org/r/1705904747-62186-2-git-send-email-chenxiang66@hisilicon.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c +index 5fdba7b39a1b..4ce737ddb058 100644 +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1968,9 +1968,17 @@ static bool hisi_sas_internal_abort_timeout(struct sas_task *task, + struct hisi_sas_internal_abort_data *timeout = data; + + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) { +- down(&hisi_hba->sem); ++ /* ++ * If timeout occurs in device gone scenario, to avoid ++ * circular dependency like: ++ * hisi_sas_dev_gone() -> down() -> ... -> ++ * hisi_sas_internal_abort_timeout() -> down(). ++ */ ++ if (!timeout->rst_ha_timeout) ++ down(&hisi_hba->sem); + hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); +- up(&hisi_hba->sem); ++ if (!timeout->rst_ha_timeout) ++ up(&hisi_hba->sem); + } + + if (task->task_state_flags & SAS_TASK_STATE_DONE) { +-- +2.39.5 + diff --git a/queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch b/queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch new file mode 100644 index 00000000000..dddd8755617 --- /dev/null +++ b/queue-6.6/scsi-mpi3mr-start-controller-indexing-from-0.patch @@ -0,0 +1,37 @@ +From f9197247180b4dda5db5de21bc2dfec937f8886f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Nov 2024 01:14:03 +0530 +Subject: scsi: mpi3mr: Start controller indexing from 0 + +From: Ranjan Kumar + +[ Upstream commit 0d32014f1e3e7a7adf1583c45387f26b9bb3a49d ] + +Instead of displaying the controller index starting from '1' make the +driver display the controller index starting from '0'. + +Signed-off-by: Sumit Saxena +Signed-off-by: Ranjan Kumar +Link: https://lore.kernel.org/r/20241110194405.10108-4-ranjan.kumar@broadcom.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_os.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 3f86f1d0a9be..7880675a68db 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -5066,7 +5066,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + mrioc = shost_priv(shost); +- retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL); ++ retval = ida_alloc_range(&mrioc_ida, 0, U8_MAX, GFP_KERNEL); + if (retval < 0) + goto id_alloc_failed; + mrioc->id = (u8)retval; +-- +2.39.5 + diff --git a/queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch b/queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch new file mode 100644 index 00000000000..6780344f435 --- /dev/null +++ b/queue-6.6/scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch @@ -0,0 +1,84 @@ +From 15ca434f10e4bed722e849cb5b3245e3c1a62ea4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Dec 2023 12:03:31 +0800 +Subject: scsi: mpi3mr: Use ida to manage mrioc ID + +From: Guixin Liu + +[ Upstream commit 29b75184f721b16c51ef6e67eec0e40ed88381c7 ] + +To ensure that the same ID is not obtained during concurrent execution of +the probe, an ida is used to manage the mrioc's ID. + +Signed-off-by: Guixin Liu +Link: https://lore.kernel.org/r/20231229040331.52518-1-kanie@linux.alibaba.com +Reviewed-by: Lee Duncan +Reviewed-by: Martin Wilck +Signed-off-by: Martin K. Petersen +Stable-dep-of: 0d32014f1e3e ("scsi: mpi3mr: Start controller indexing from 0") +Signed-off-by: Sasha Levin +--- + drivers/scsi/mpi3mr/mpi3mr_os.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c +index 7f3261923469..3f86f1d0a9be 100644 +--- a/drivers/scsi/mpi3mr/mpi3mr_os.c ++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c +@@ -8,11 +8,12 @@ + */ + + #include "mpi3mr.h" ++#include + + /* global driver scop variables */ + LIST_HEAD(mrioc_list); + DEFINE_SPINLOCK(mrioc_list_lock); +-static int mrioc_ids; ++static DEFINE_IDA(mrioc_ida); + static int warn_non_secure_ctlr; + atomic64_t event_counter; + +@@ -5065,7 +5066,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + + mrioc = shost_priv(shost); +- mrioc->id = mrioc_ids++; ++ retval = ida_alloc_range(&mrioc_ida, 1, U8_MAX, GFP_KERNEL); ++ if (retval < 0) ++ goto id_alloc_failed; ++ mrioc->id = (u8)retval; + sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME); + sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id); + INIT_LIST_HEAD(&mrioc->list); +@@ -5215,9 +5219,11 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) + resource_alloc_failed: + destroy_workqueue(mrioc->fwevt_worker_thread); + fwevtthread_failed: ++ ida_free(&mrioc_ida, mrioc->id); + spin_lock(&mrioc_list_lock); + list_del(&mrioc->list); + spin_unlock(&mrioc_list_lock); ++id_alloc_failed: + scsi_host_put(shost); + shost_failed: + return retval; +@@ -5303,6 +5309,7 @@ static void mpi3mr_remove(struct pci_dev *pdev) + mrioc->sas_hba.num_phys = 0; + } + ++ ida_free(&mrioc_ida, mrioc->id); + spin_lock(&mrioc_list_lock); + list_del(&mrioc->list); + spin_unlock(&mrioc_list_lock); +@@ -5518,6 +5525,7 @@ static void __exit mpi3mr_exit(void) + &driver_attr_event_counter); + pci_unregister_driver(&mpi3mr_pci_driver); + sas_release_transport(mpi3mr_transport_template); ++ ida_destroy(&mrioc_ida); + } + + module_init(mpi3mr_init); +-- +2.39.5 + diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 00000000000..b9df4e32115 --- /dev/null +++ b/queue-6.6/series @@ -0,0 +1,113 @@ +drm-amd-display-fix-dsc-re-computing.patch +drm-amd-display-fix-incorrect-dsc-recompute-trigger.patch +docs-media-update-location-of-the-media-patches.patch +x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch +smb-client-rename-cifs_ntsd-to-smb_ntsd.patch +smb-client-rename-cifs_sid-to-smb_sid.patch +smb-client-rename-cifs_acl-to-smb_acl.patch +smb-client-rename-cifs_ace-to-smb_ace.patch +fs-smb-client-implement-chmod-for-smb3-posix-extensi.patch +smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch +smb-client-fix-use-after-free-of-signing-key.patch +usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch +sched-initialize-idle-tasks-only-once.patch +drm-radeon-delay-connector-detecting-when-hpd-singal.patch +revert-drm-radeon-delay-connector-detecting-when-hpd.patch +rust-relax-most-deny-level-lints-to-warnings.patch +rust-allow-clippy-needless_lifetimes.patch +numa-optimize-detection-of-memory-with-no-node-id-as.patch +memblock-allow-zero-threshold-in-validate_numa_conve.patch +ext4-convert-to-new-timestamp-accessors.patch +ext4-partial-zero-eof-block-on-unaligned-inode-size-.patch +crypto-ecdsa-convert-byte-arrays-with-key-coordinate.patch +crypto-ecdsa-rename-keylen-to-bufsize-where-necessar.patch +crypto-ecdsa-use-ecc_digits_from_bytes-to-convert-si.patch +crypto-ecdsa-avoid-signed-integer-overflow-on-signat.patch +cleanup-add-conditional-guard-support.patch +cleanup-adjust-scoped_guard-macros-to-avoid-potentia.patch +media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch +media-uvcvideo-force-uvc-version-to-1.0a-for-0408-40.patch-10342 +wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch +wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch +wifi-ath12k-optimize-the-mac80211-hw-data-access.patch +wifi-mac80211-add-non-atomic-station-iterator.patch +wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch +wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch +wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch +i2c-i801-add-support-for-intel-arrow-lake-h.patch +i2c-i801-add-support-for-intel-panther-lake.patch +bluetooth-hci_conn-reduce-hci_conn_drop-calls-in-two.patch +bluetooth-add-support-ittim-pe50-m75c.patch +bluetooth-btusb-add-new-vid-pid-13d3-3602-for-mt7925.patch +bluetooth-btusb-add-usb-hw-ids-for-mt7921-mt7922-mt7.patch +bluetooth-btusb-add-new-vid-pid-0489-e111-for-mt7925.patch +scsi-hisi_sas-directly-call-register-snapshot-instea.patch +scsi-hisi_sas-allocate-dfx-memory-during-dump-trigge.patch +scsi-hisi_sas-create-all-dump-files-during-debugfs-i.patch +clk-qcom-clk-alpha-pll-add-support-for-zonda-ole-pll.patch +clk-qcom-clk-alpha-pll-add-nss-huayra-alpha-pll-supp.patch +mailbox-pcc-add-support-for-platform-notification-ha.patch +mailbox-pcc-support-shared-interrupt-for-multiple-su.patch +acpi-pcc-add-pcc-shared-memory-region-command-and-st.patch +mailbox-pcc-check-before-sending-mctp-pcc-response-a.patch +remoteproc-qcom-pas-add-sc7180-adsp.patch +remoteproc-qcom-pas-add-support-for-sa8775p-adsp-cds.patch +remoteproc-qcom-pas-enable-sar2130p-audio-dsp-suppor.patch +fs-ntfs3-implement-fallocate-for-compressed-files.patch +fs-ntfs3-fix-warning-in-ni_fiemap.patch +usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch +usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch +usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch +iio-adc-ad7192-convert-from-of-specific-to-fwnode-pr.patch +iio-adc-ad7192-properly-check-spi_get_device_match_d.patch +usb-typec-ucsi-add-callback-for-connector-status-upd.patch +usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch +usb-typec-ucsi-add-update_connector-callback.patch +usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch +usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch +nvme-use-helper-nvme_ctrl_state-in-nvme_keep_alive_f.patch +revert-nvme-make-keep-alive-synchronous-operation.patch +net-mlx5-unique-names-for-per-device-caches.patch +softirq-allow-raising-sched_softirq-from-smp-call-fu.patch +net-renesas-rswitch-fix-possible-early-skb-release.patch +xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch +usb-xhci-limit-stop-endpoint-retries.patch +xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch +thunderbolt-add-support-for-intel-lunar-lake.patch +thunderbolt-add-support-for-intel-panther-lake-m-p.patch +thunderbolt-don-t-display-nvm_version-unless-upgrade.patch +x86-crash-wrap-crash-dumping-code-into-crash-related.patch +x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch +of-address-remove-duplicated-functions.patch +of-address-store-number-of-bus-flag-cells-rather-tha.patch +of-address-preserve-the-flags-portion-on-1-1-dma-ran.patch +watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch +watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch +watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch +watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch +revert-watchdog-s3c2410_wdt-use-exynos_get_pmu_regma.patch +udf_rename-only-access-the-child-content-on-cross-di.patch +udf-verify-inode-link-counts-before-performing-renam.patch +alsa-ump-use-guard-for-locking.patch +alsa-ump-don-t-open-legacy-substream-for-an-inactive.patch +alsa-ump-indicate-the-inactive-group-in-legacy-subst.patch +alsa-ump-update-legacy-substream-names-upon-fb-info-.patch +scsi-mpi3mr-use-ida-to-manage-mrioc-id.patch +scsi-mpi3mr-start-controller-indexing-from-0.patch +acpi-iort-add-pmcg-platform-information-for-hisilico.patch +acpi-iort-add-pmcg-platform-information-for-hisilico.patch-10390 +x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch +x86-ptrace-add-fred-additional-information-to-the-pt.patch +x86-fred-clear-wfe-in-missing-endbranch-cps.patch +btrfs-rename-and-export-__btrfs_cow_block.patch +btrfs-fix-use-after-free-when-cowing-tree-bock-and-t.patch +bluetooth-btusb-add-callback-function-in-btusb-suspe.patch +bluetooth-btusb-mediatek-add-callback-function-in-bt.patch +memblock-make-memblock_set_node-also-warn-about-use-.patch +crypto-ecc-prevent-ecc_digits_from_bytes-from-readin.patch +cleanup-remove-address-space-of-returned-pointer.patch +scsi-hisi_sas-fix-a-deadlock-issue-related-to-automa.patch +usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch +usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch +alsa-ump-shut-up-truncated-string-warning.patch +platform-x86-mlx-platform-call-pci_dev_put-to-balanc.patch diff --git a/queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch b/queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch new file mode 100644 index 00000000000..6155715cb2b --- /dev/null +++ b/queue-6.6/smb-client-fix-use-after-free-of-signing-key.patch @@ -0,0 +1,165 @@ +From 2237cd152a146d8945e696c0246efe5a0aaa646c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Nov 2024 10:40:55 -0300 +Subject: smb: client: fix use-after-free of signing key + +From: Paulo Alcantara + +[ Upstream commit 343d7fe6df9e247671440a932b6a73af4fa86d95 ] + +Customers have reported use-after-free in @ses->auth_key.response with +SMB2.1 + sign mounts which occurs due to following race: + +task A task B +cifs_mount() + dfs_mount_share() + get_session() + cifs_mount_get_session() cifs_send_recv() + cifs_get_smb_ses() compound_send_recv() + cifs_setup_session() smb2_setup_request() + kfree_sensitive() smb2_calc_signature() + crypto_shash_setkey() *UAF* + +Fix this by ensuring that we have a valid @ses->auth_key.response by +checking whether @ses->ses_status is SES_GOOD or SES_EXITING with +@ses->ses_lock held. After commit 24a9799aa8ef ("smb: client: fix UAF +in smb2_reconnect_server()"), we made sure to call ->logoff() only +when @ses was known to be good (e.g. valid ->auth_key.response), so +it's safe to access signing key when @ses->ses_status == SES_EXITING. + +Cc: stable@vger.kernel.org +Reported-by: Jay Shin +Signed-off-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb2proto.h | 2 -- + fs/smb/client/smb2transport.c | 56 +++++++++++++++++++++++++---------- + 2 files changed, 40 insertions(+), 18 deletions(-) + +diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h +index fd90d8e5a1d1..750e4e397b13 100644 +--- a/fs/smb/client/smb2proto.h ++++ b/fs/smb/client/smb2proto.h +@@ -37,8 +37,6 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, + struct smb_rqst *rqst); + extern struct mid_q_entry *smb2_setup_async_request( + struct TCP_Server_Info *server, struct smb_rqst *rqst); +-extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, +- __u64 ses_id); + extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, + __u64 ses_id, __u32 tid); + extern int smb2_calc_signature(struct smb_rqst *rqst, +diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c +index 73eae1b16034..4a43802375b3 100644 +--- a/fs/smb/client/smb2transport.c ++++ b/fs/smb/client/smb2transport.c +@@ -74,7 +74,7 @@ smb311_crypto_shash_allocate(struct TCP_Server_Info *server) + + + static +-int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) ++int smb3_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key) + { + struct cifs_chan *chan; + struct TCP_Server_Info *pserver; +@@ -168,16 +168,41 @@ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) + return NULL; + } + +-struct cifs_ses * +-smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) ++static int smb2_get_sign_key(struct TCP_Server_Info *server, ++ __u64 ses_id, u8 *key) + { + struct cifs_ses *ses; ++ int rc = -ENOENT; ++ ++ if (SERVER_IS_CHAN(server)) ++ server = server->primary_server; + + spin_lock(&cifs_tcp_ses_lock); +- ses = smb2_find_smb_ses_unlocked(server, ses_id); +- spin_unlock(&cifs_tcp_ses_lock); ++ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { ++ if (ses->Suid != ses_id) ++ continue; + +- return ses; ++ rc = 0; ++ spin_lock(&ses->ses_lock); ++ switch (ses->ses_status) { ++ case SES_EXITING: /* SMB2_LOGOFF */ ++ case SES_GOOD: ++ if (likely(ses->auth_key.response)) { ++ memcpy(key, ses->auth_key.response, ++ SMB2_NTLMV2_SESSKEY_SIZE); ++ } else { ++ rc = -EIO; ++ } ++ break; ++ default: ++ rc = -EAGAIN; ++ break; ++ } ++ spin_unlock(&ses->ses_lock); ++ break; ++ } ++ spin_unlock(&cifs_tcp_ses_lock); ++ return rc; + } + + static struct cifs_tcon * +@@ -236,14 +261,16 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + unsigned char *sigptr = smb2_signature; + struct kvec *iov = rqst->rq_iov; + struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base; +- struct cifs_ses *ses; + struct shash_desc *shash = NULL; + struct smb_rqst drqst; ++ __u64 sid = le64_to_cpu(shdr->SessionId); ++ u8 key[SMB2_NTLMV2_SESSKEY_SIZE]; + +- ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); +- if (unlikely(!ses)) { +- cifs_server_dbg(FYI, "%s: Could not find session\n", __func__); +- return -ENOENT; ++ rc = smb2_get_sign_key(server, sid, key); ++ if (unlikely(rc)) { ++ cifs_server_dbg(FYI, "%s: [sesid=0x%llx] couldn't find signing key: %d\n", ++ __func__, sid, rc); ++ return rc; + } + + memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); +@@ -260,8 +287,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + shash = server->secmech.hmacsha256; + } + +- rc = crypto_shash_setkey(shash->tfm, ses->auth_key.response, +- SMB2_NTLMV2_SESSKEY_SIZE); ++ rc = crypto_shash_setkey(shash->tfm, key, sizeof(key)); + if (rc) { + cifs_server_dbg(VFS, + "%s: Could not update with response\n", +@@ -303,8 +329,6 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + out: + if (allocate_crypto) + cifs_free_hash(&shash); +- if (ses) +- cifs_put_smb_ses(ses); + return rc; + } + +@@ -570,7 +594,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + struct smb_rqst drqst; + u8 key[SMB3_SIGN_KEY_SIZE]; + +- rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); ++ rc = smb3_get_sign_key(le64_to_cpu(shdr->SessionId), server, key); + if (unlikely(rc)) { + cifs_server_dbg(FYI, "%s: Could not get signing key\n", __func__); + return rc; +-- +2.39.5 + diff --git a/queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch b/queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch new file mode 100644 index 00000000000..303cc51a8ff --- /dev/null +++ b/queue-6.6/smb-client-rename-cifs_ace-to-smb_ace.patch @@ -0,0 +1,362 @@ +From 5f856fdc5d8214ca2defc219f8f4f1b80db352c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 08:20:58 +0000 +Subject: smb/client: rename cifs_ace to smb_ace + +From: ChenXiaoSong + +[ Upstream commit 09bedafc1e2c5c82aad3cbfe1359e2b0bf752f3a ] + +Preparation for moving acl definitions to new common header file. + +Use the following shell command to rename: + + find fs/smb/client -type f -exec sed -i \ + 's/struct cifs_ace/struct smb_ace/g' {} + + +Signed-off-by: ChenXiaoSong +Reviewed-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions") +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 62 +++++++++++++++++++-------------------- + fs/smb/client/cifsacl.h | 4 +-- + fs/smb/client/cifsglob.h | 2 +- + fs/smb/client/cifsproto.h | 6 ++-- + fs/smb/client/smb2pdu.c | 8 ++--- + 5 files changed, 41 insertions(+), 41 deletions(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 2e1c9b528dde..e2ec1d934335 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -666,7 +666,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, + return; + } + +-static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct smb_sid *psid) ++static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid) + { + __u16 size = 1 + 1 + 2 + 4; + +@@ -685,7 +685,7 @@ static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct sm + return size; + } + +-static __u16 fill_ace_for_sid(struct cifs_ace *pntace, ++static __u16 fill_ace_for_sid(struct smb_ace *pntace, + const struct smb_sid *psid, __u64 nmode, + umode_t bits, __u8 access_type, + bool allow_delete_child) +@@ -723,7 +723,7 @@ static __u16 fill_ace_for_sid(struct cifs_ace *pntace, + + + #ifdef CONFIG_CIFS_DEBUG2 +-static void dump_ace(struct cifs_ace *pace, char *end_of_acl) ++static void dump_ace(struct smb_ace *pace, char *end_of_acl) + { + int num_subauth; + +@@ -766,7 +766,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + int num_aces = 0; + int acl_size; + char *acl_base; +- struct cifs_ace **ppace; ++ struct smb_ace **ppace; + + /* BB need to add parm so we can store the SID BB */ + +@@ -799,15 +799,15 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + if (num_aces > 0) { + umode_t denied_mode = 0; + +- if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *)) ++ if (num_aces > ULONG_MAX / sizeof(struct smb_ace *)) + return; +- ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *), ++ ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), + GFP_KERNEL); + if (!ppace) + return; + + for (i = 0; i < num_aces; ++i) { +- ppace[i] = (struct cifs_ace *) (acl_base + acl_size); ++ ppace[i] = (struct smb_ace *) (acl_base + acl_size); + #ifdef CONFIG_CIFS_DEBUG2 + dump_ace(ppace[i], end_of_acl); + #endif +@@ -849,7 +849,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + + /* memcpy((void *)(&(cifscred->aces[i])), + (void *)ppace[i], +- sizeof(struct cifs_ace)); */ ++ sizeof(struct smb_ace)); */ + + acl_base = (char *)ppace[i]; + acl_size = le16_to_cpu(ppace[i]->size); +@@ -861,7 +861,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + return; + } + +-unsigned int setup_authusers_ACE(struct cifs_ace *pntace) ++unsigned int setup_authusers_ACE(struct smb_ace *pntace) + { + int i; + unsigned int ace_size = 20; +@@ -885,7 +885,7 @@ unsigned int setup_authusers_ACE(struct cifs_ace *pntace) + * Fill in the special SID based on the mode. See + * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx + */ +-unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) ++unsigned int setup_special_mode_ACE(struct smb_ace *pntace, __u64 nmode) + { + int i; + unsigned int ace_size = 28; +@@ -907,7 +907,7 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode) + return ace_size; + } + +-unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) ++unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace) + { + int i; + unsigned int ace_size = 28; +@@ -944,17 +944,17 @@ static void populate_new_aces(char *nacl_base, + __u64 deny_user_mode = 0; + __u64 deny_group_mode = 0; + bool sticky_set = false; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + + nmode = *pnmode; + num_aces = *pnum_aces; + nsize = *pnsize; + + if (modefromsid) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += setup_special_mode_ACE(pnntace, nmode); + num_aces++; +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += setup_authusers_ACE(pnntace); + num_aces++; + goto set_size; +@@ -992,7 +992,7 @@ static void populate_new_aces(char *nacl_base, + sticky_set = true; + + if (deny_user_mode) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode, + 0700, ACCESS_DENIED, false); + num_aces++; +@@ -1000,31 +1000,31 @@ static void populate_new_aces(char *nacl_base, + + /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/ + if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode, + 0070, ACCESS_DENIED, false); + num_aces++; + } + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pownersid, user_mode, + 0700, ACCESS_ALLOWED, true); + num_aces++; + + /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */ + if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) { +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode, + 0070, ACCESS_DENIED, false); + num_aces++; + } + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode, + 0070, ACCESS_ALLOWED, !sticky_set); + num_aces++; + +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode, + 0007, ACCESS_ALLOWED, !sticky_set); + num_aces++; +@@ -1040,11 +1040,11 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p + { + int i; + u16 size = 0; +- struct cifs_ace *pntace = NULL; ++ struct smb_ace *pntace = NULL; + char *acl_base = NULL; + u32 src_num_aces = 0; + u16 nsize = 0; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + char *nacl_base = NULL; + u16 ace_size = 0; + +@@ -1057,8 +1057,8 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p + + /* Go through all the ACEs */ + for (i = 0; i < src_num_aces; ++i) { +- pntace = (struct cifs_ace *) (acl_base + size); +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pntace = (struct smb_ace *) (acl_base + size); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + + if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0) + ace_size = cifs_copy_ace(pnntace, pntace, pnownersid); +@@ -1080,11 +1080,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + { + int i; + u16 size = 0; +- struct cifs_ace *pntace = NULL; ++ struct smb_ace *pntace = NULL; + char *acl_base = NULL; + u32 src_num_aces = 0; + u16 nsize = 0; +- struct cifs_ace *pnntace = NULL; ++ struct smb_ace *pnntace = NULL; + char *nacl_base = NULL; + u32 num_aces = 0; + bool new_aces_set = false; +@@ -1108,7 +1108,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + + /* Retain old ACEs which we can retain */ + for (i = 0; i < src_num_aces; ++i) { +- pntace = (struct cifs_ace *) (acl_base + size); ++ pntace = (struct smb_ace *) (acl_base + size); + + if (!new_aces_set && (pntace->flags & INHERITED_ACE)) { + /* Place the new ACEs in between existing explicit and inherited */ +@@ -1130,7 +1130,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + } + + /* update the pointer to the next ACE to populate*/ +- pnntace = (struct cifs_ace *) (nacl_base + nsize); ++ pnntace = (struct smb_ace *) (nacl_base + nsize); + + nsize += cifs_copy_ace(pnntace, pntace, NULL); + num_aces++; +@@ -1625,9 +1625,9 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + nsecdesclen = secdesclen; + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ + if (mode_from_sid) +- nsecdesclen += 2 * sizeof(struct cifs_ace); ++ nsecdesclen += 2 * sizeof(struct smb_ace); + else /* cifsacl */ +- nsecdesclen += 5 * sizeof(struct cifs_ace); ++ nsecdesclen += 5 * sizeof(struct smb_ace); + } else { /* chown */ + /* When ownership changes, changes new owner sid length could be different */ + nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); +@@ -1636,7 +1636,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + if (mode_from_sid) + nsecdesclen += +- le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace); ++ le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace); + else /* cifsacl */ + nsecdesclen += le16_to_cpu(dacl_ptr->size); + } +diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h +index a23d59987828..cbaed8038e36 100644 +--- a/fs/smb/client/cifsacl.h ++++ b/fs/smb/client/cifsacl.h +@@ -35,7 +35,7 @@ + */ + #define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \ + sizeof(struct smb_acl) + \ +- (sizeof(struct cifs_ace) * 4)) ++ (sizeof(struct smb_ace) * 4)) + + /* + * Maximum size of a string representation of a SID: +@@ -111,7 +111,7 @@ struct smb_acl { + #define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 + #define FAILED_ACCESS_ACE_FLAG 0x80 + +-struct cifs_ace { ++struct smb_ace { + __u8 type; /* see above and MS-DTYP 2.4.4.1 */ + __u8 flags; + __le16 size; +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 69d850b6b37f..43b42eca6780 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -205,7 +205,7 @@ struct cifs_cred { + struct smb_sid osid; + struct smb_sid gsid; + struct cifs_ntace *ntaces; +- struct cifs_ace *aces; ++ struct smb_ace *aces; + }; + + struct cifs_open_info_data { +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 059e506ccf5b..6399dbd04625 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -241,9 +241,9 @@ extern int cifs_set_acl(struct mnt_idmap *idmap, + struct dentry *dentry, struct posix_acl *acl, int type); + extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, + const char *path, int flag); +-extern unsigned int setup_authusers_ACE(struct cifs_ace *pace); +-extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode); +-extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace); ++extern unsigned int setup_authusers_ACE(struct smb_ace *pace); ++extern unsigned int setup_special_mode_ACE(struct smb_ace *pace, __u64 nmode); ++extern unsigned int setup_special_user_owner_ACE(struct smb_ace *pace); + + extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); + extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 42f950ae10fb..101c80f22d77 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -2623,7 +2623,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) + unsigned int group_offset = 0; + struct smb3_acl acl = {}; + +- *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8); ++ *len = round_up(sizeof(struct crt_sd_ctxt) + (sizeof(struct smb_ace) * 4), 8); + + if (set_owner) { + /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */ +@@ -2672,21 +2672,21 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len) + ptr += sizeof(struct smb3_acl); + + /* create one ACE to hold the mode embedded in reserved special SID */ +- acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode); ++ acelen = setup_special_mode_ACE((struct smb_ace *)ptr, (__u64)mode); + ptr += acelen; + acl_size = acelen + sizeof(struct smb3_acl); + ace_count = 1; + + if (set_owner) { + /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */ +- acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr); ++ acelen = setup_special_user_owner_ACE((struct smb_ace *)ptr); + ptr += acelen; + acl_size += acelen; + ace_count += 1; + } + + /* and one more ACE to allow access for authenticated users */ +- acelen = setup_authusers_ACE((struct cifs_ace *)ptr); ++ acelen = setup_authusers_ACE((struct smb_ace *)ptr); + ptr += acelen; + acl_size += acelen; + ace_count += 1; +-- +2.39.5 + diff --git a/queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch b/queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch new file mode 100644 index 00000000000..f2323c15808 --- /dev/null +++ b/queue-6.6/smb-client-rename-cifs_acl-to-smb_acl.patch @@ -0,0 +1,195 @@ +From ae8d47f6ff4a57650599089653687582f98ce584 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 08:20:57 +0000 +Subject: smb/client: rename cifs_acl to smb_acl + +From: ChenXiaoSong + +[ Upstream commit 251b93ae73805b216e84ed2190b525f319da4c87 ] + +Preparation for moving acl definitions to new common header file. + +Use the following shell command to rename: + + find fs/smb/client -type f -exec sed -i \ + 's/struct cifs_acl/struct smb_acl/g' {} + + +Signed-off-by: ChenXiaoSong +Reviewed-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions") +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 34 +++++++++++++++++----------------- + fs/smb/client/cifsacl.h | 4 ++-- + 2 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index dd399f9a7424..2e1c9b528dde 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -758,7 +758,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl) + } + #endif + +-static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, ++static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + struct smb_sid *pownersid, struct smb_sid *pgrpsid, + struct cifs_fattr *fattr, bool mode_from_special_sid) + { +@@ -793,7 +793,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, + fattr->cf_mode &= ~(0777); + + acl_base = (char *)pdacl; +- acl_size = sizeof(struct cifs_acl); ++ acl_size = sizeof(struct smb_acl); + + num_aces = le32_to_cpu(pdacl->num_aces); + if (num_aces > 0) { +@@ -1034,7 +1034,7 @@ static void populate_new_aces(char *nacl_base, + *pnsize = nsize; + } + +-static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl, ++static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl, + struct smb_sid *pownersid, struct smb_sid *pgrpsid, + struct smb_sid *pnownersid, struct smb_sid *pngrpsid) + { +@@ -1049,11 +1049,11 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl + u16 ace_size = 0; + + acl_base = (char *)pdacl; +- size = sizeof(struct cifs_acl); ++ size = sizeof(struct smb_acl); + src_num_aces = le32_to_cpu(pdacl->num_aces); + + nacl_base = (char *)pndacl; +- nsize = sizeof(struct cifs_acl); ++ nsize = sizeof(struct smb_acl); + + /* Go through all the ACEs */ + for (i = 0; i < src_num_aces; ++i) { +@@ -1074,7 +1074,7 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl + return nsize; + } + +-static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, ++static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl, + struct smb_sid *pownersid, struct smb_sid *pgrpsid, + __u64 *pnmode, bool mode_from_sid) + { +@@ -1091,7 +1091,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + + /* Assuming that pndacl and pnmode are never NULL */ + nacl_base = (char *)pndacl; +- nsize = sizeof(struct cifs_acl); ++ nsize = sizeof(struct smb_acl); + + /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */ + if (!pdacl) { +@@ -1103,7 +1103,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + } + + acl_base = (char *)pdacl; +- size = sizeof(struct cifs_acl); ++ size = sizeof(struct smb_acl); + src_num_aces = le32_to_cpu(pdacl->num_aces); + + /* Retain old ACEs which we can retain */ +@@ -1196,7 +1196,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + { + int rc = 0; + struct smb_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ ++ struct smb_acl *dacl_ptr; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + acl_len; + __u32 dacloffset; + +@@ -1208,7 +1208,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + dacloffset = le32_to_cpu(pntsd->dacloffset); +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n", + pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), + le32_to_cpu(pntsd->gsidoffset), +@@ -1259,14 +1259,14 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + __u32 sidsoffset; + struct smb_sid *owner_sid_ptr, *group_sid_ptr; + struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL; +- struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ +- struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ ++ struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */ ++ struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + secdesclen; + u16 size = 0; + + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) { + cifs_dbg(VFS, "Server returned illegal ACL size\n"); + return -EINVAL; +@@ -1280,7 +1280,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ + ndacloffset = sizeof(struct smb_ntsd); +- ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); ++ ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); + +@@ -1298,7 +1298,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + *aclflag |= CIFS_ACL_DACL; + } else { + ndacloffset = sizeof(struct smb_ntsd); +- ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); ++ ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); + ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0; +@@ -1580,7 +1580,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + __u32 secdesclen = 0; + __u32 nsecdesclen = 0; + __u32 dacloffset = 0; +- struct cifs_acl *dacl_ptr = NULL; ++ struct smb_acl *dacl_ptr = NULL; + struct smb_ntsd *pntsd = NULL; /* acl obtained from server */ + struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); +@@ -1633,7 +1633,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { +- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + if (mode_from_sid) + nsecdesclen += + le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct cifs_ace); +diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h +index 6a38718220fc..a23d59987828 100644 +--- a/fs/smb/client/cifsacl.h ++++ b/fs/smb/client/cifsacl.h +@@ -34,7 +34,7 @@ + * owner, group and world). + */ + #define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \ +- sizeof(struct cifs_acl) + \ ++ sizeof(struct smb_acl) + \ + (sizeof(struct cifs_ace) * 4)) + + /* +@@ -74,7 +74,7 @@ struct smb_sid { + /* size of a struct smb_sid, sans sub_auth array */ + #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS) + +-struct cifs_acl { ++struct smb_acl { + __le16 revision; /* revision level */ + __le16 size; + __le32 num_aces; +-- +2.39.5 + diff --git a/queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch b/queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch new file mode 100644 index 00000000000..c5dbd373a26 --- /dev/null +++ b/queue-6.6/smb-client-rename-cifs_ntsd-to-smb_ntsd.patch @@ -0,0 +1,402 @@ +From 1f20539d1950f49230c561f4b4a82ced00410ee8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 08:20:55 +0000 +Subject: smb/client: rename cifs_ntsd to smb_ntsd + +From: ChenXiaoSong + +[ Upstream commit 3651487607ae778df1051a0a38bb34a5bd34e3b7 ] + +Preparation for moving acl definitions to new common header file. + +Use the following shell command to rename: + + find fs/smb/client -type f -exec sed -i \ + 's/struct cifs_ntsd/struct smb_ntsd/g' {} + + +Signed-off-by: ChenXiaoSong +Reviewed-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions") +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 36 ++++++++++++++++++------------------ + fs/smb/client/cifsacl.h | 6 +++--- + fs/smb/client/cifsglob.h | 12 ++++++------ + fs/smb/client/cifsproto.h | 16 ++++++++-------- + fs/smb/client/cifssmb.c | 6 +++--- + fs/smb/client/smb2ops.c | 14 +++++++------- + fs/smb/client/smb2pdu.c | 2 +- + fs/smb/client/smb2proto.h | 2 +- + fs/smb/client/xattr.c | 4 ++-- + 9 files changed, 49 insertions(+), 49 deletions(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index f5b6df82e857..3f7657475cd9 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -515,8 +515,8 @@ exit_cifs_idmap(void) + } + + /* copy ntsd, owner sid, and group sid from a security descriptor to another */ +-static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd, +- struct cifs_ntsd *pnntsd, ++static __u32 copy_sec_desc(const struct smb_ntsd *pntsd, ++ struct smb_ntsd *pnntsd, + __u32 sidsoffset, + struct cifs_sid *pownersid, + struct cifs_sid *pgrpsid) +@@ -527,7 +527,7 @@ static __u32 copy_sec_desc(const struct cifs_ntsd *pntsd, + /* copy security descriptor control portion */ + pnntsd->revision = pntsd->revision; + pnntsd->type = pntsd->type; +- pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd)); ++ pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd)); + pnntsd->sacloffset = 0; + pnntsd->osidoffset = cpu_to_le32(sidsoffset); + pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid)); +@@ -1191,7 +1191,7 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) + + /* Convert CIFS ACL to POSIX form */ + static int parse_sec_desc(struct cifs_sb_info *cifs_sb, +- struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, ++ struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, + bool get_mode_from_special_sid) + { + int rc = 0; +@@ -1249,7 +1249,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + } + + /* Convert permission bits from mode to equivalent CIFS ACL */ +-static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ++static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid, + bool mode_from_sid, bool id_from_sid, int *aclflag) + { +@@ -1279,7 +1279,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + le32_to_cpu(pntsd->gsidoffset)); + + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ +- ndacloffset = sizeof(struct cifs_ntsd); ++ ndacloffset = sizeof(struct smb_ntsd); + ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); +@@ -1297,7 +1297,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + + *aclflag |= CIFS_ACL_DACL; + } else { +- ndacloffset = sizeof(struct cifs_ntsd); ++ ndacloffset = sizeof(struct smb_ntsd); + ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset); + ndacl_ptr->revision = + dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION); +@@ -1385,11 +1385,11 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, + } + + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY +-struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, ++struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + const struct cifs_fid *cifsfid, u32 *pacllen, + u32 __maybe_unused unused) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + unsigned int xid; + int rc; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -1410,10 +1410,10 @@ struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, + return pntsd; + } + +-static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, ++static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, + const char *path, u32 *pacllen) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + int oplock = 0; + unsigned int xid; + int rc; +@@ -1454,11 +1454,11 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, + } + + /* Retrieve an ACL from the server */ +-struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, ++struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, + struct inode *inode, const char *path, + u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + struct cifsFileInfo *open_file = NULL; + + if (inode) +@@ -1472,7 +1472,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, + } + + /* Set an ACL on the server */ +-int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, ++int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen, + struct inode *inode, const char *path, int aclflag) + { + int oplock = 0; +@@ -1528,7 +1528,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, + struct inode *inode, bool mode_from_special_sid, + const char *path, const struct cifs_fid *pfid) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + u32 acllen = 0; + int rc = 0; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -1581,8 +1581,8 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + __u32 nsecdesclen = 0; + __u32 dacloffset = 0; + struct cifs_acl *dacl_ptr = NULL; +- struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ +- struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ ++ struct smb_ntsd *pntsd = NULL; /* acl obtained from server */ ++ struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); + struct smb_version_operations *ops; +@@ -1630,7 +1630,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + nsecdesclen += 5 * sizeof(struct cifs_ace); + } else { /* chown */ + /* When ownership changes, changes new owner sid length could be different */ +- nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2); ++ nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct cifs_sid) * 2); + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { + dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); +diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h +index ccbfc754bd3c..1516545d7f67 100644 +--- a/fs/smb/client/cifsacl.h ++++ b/fs/smb/client/cifsacl.h +@@ -33,7 +33,7 @@ + * Security Descriptor length containing DACL with 3 ACEs (one each for + * owner, group and world). + */ +-#define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \ ++#define DEFAULT_SEC_DESC_LEN (sizeof(struct smb_ntsd) + \ + sizeof(struct cifs_acl) + \ + (sizeof(struct cifs_ace) * 4)) + +@@ -55,7 +55,7 @@ + #define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1) + #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ + +-struct cifs_ntsd { ++struct smb_ntsd { + __le16 revision; /* revision level */ + __le16 type; + __le32 osidoffset; +@@ -194,6 +194,6 @@ struct owner_group_sids { + * Minimum security descriptor can be one without any SACL and DACL and can + * consist of revision, type, and two sids of minimum size for owner and group + */ +-#define MIN_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + (2 * MIN_SID_LEN)) ++#define MIN_SEC_DESC_LEN (sizeof(struct smb_ntsd) + (2 * MIN_SID_LEN)) + + #endif /* _CIFSACL_H */ +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 6b57b167a49d..cf22629bf90b 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -539,12 +539,12 @@ struct smb_version_operations { + int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, + const char *, const void *, const __u16, + const struct nls_table *, struct cifs_sb_info *); +- struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, +- const char *, u32 *, u32); +- struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, +- const struct cifs_fid *, u32 *, u32); +- int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, +- int); ++ struct smb_ntsd * (*get_acl)(struct cifs_sb_info *cifssb, struct inode *ino, ++ const char *patch, u32 *plen, u32 info); ++ struct smb_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *cifssmb, ++ const struct cifs_fid *pfid, u32 *plen, u32 info); ++ int (*set_acl)(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, const char *path, ++ int flag); + /* writepages retry size */ + unsigned int (*wp_retry_size)(struct inode *); + /* get mtu credits */ +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 83692bf60007..f34c533efe49 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -231,16 +231,16 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, + const char *path, const struct cifs_fid *pfid); + extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + kuid_t uid, kgid_t gid); +-extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *, +- const char *, u32 *, u32); +-extern struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *, +- const struct cifs_fid *, u32 *, u32); ++extern struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifssmb, struct inode *ino, ++ const char *path, u32 *plen, u32 info); ++extern struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifssb, ++ const struct cifs_fid *pfid, u32 *plen, u32 info); + extern struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap, + struct dentry *dentry, int type); + extern int cifs_set_acl(struct mnt_idmap *idmap, + struct dentry *dentry, struct posix_acl *acl, int type); +-extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, +- const char *, int); ++extern int set_cifs_acl(struct smb_ntsd *pntsd, __u32 len, struct inode *ino, ++ const char *path, int flag); + extern unsigned int setup_authusers_ACE(struct cifs_ace *pace); + extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode); + extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace); +@@ -568,9 +568,9 @@ extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, + const struct nls_table *nls_codepage, + struct cifs_sb_info *cifs_sb); + extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, +- __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); ++ __u16 fid, struct smb_ntsd **acl_inf, __u32 *buflen); + extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, +- struct cifs_ntsd *, __u32, int); ++ struct smb_ntsd *pntsd, __u32 len, int aclflag); + extern int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, + const unsigned char *searchName, + struct posix_acl **acl, const int acl_type, +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index a34db419e46f..2f8745736dbb 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -3385,7 +3385,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, + /* Get Security Descriptor (by handle) from remote server for a file or dir */ + int + CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, +- struct cifs_ntsd **acl_inf, __u32 *pbuflen) ++ struct smb_ntsd **acl_inf, __u32 *pbuflen) + { + int rc = 0; + int buf_type = 0; +@@ -3455,7 +3455,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, + + /* check if buffer is big enough for the acl + header followed by the smallest SID */ +- if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) || ++ if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || + (*pbuflen >= 64 * 1024)) { + cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); + rc = -EINVAL; +@@ -3475,7 +3475,7 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, + + int + CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, +- struct cifs_ntsd *pntsd, __u32 acllen, int aclflag) ++ struct smb_ntsd *pntsd, __u32 acllen, int aclflag) + { + __u16 byte_count, param_count, data_count, param_offset, data_offset; + int rc = 0; +diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c +index 6645f147d57c..fc6d00344c50 100644 +--- a/fs/smb/client/smb2ops.c ++++ b/fs/smb/client/smb2ops.c +@@ -3001,11 +3001,11 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, + return rc; + } + +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, + const struct cifs_fid *cifsfid, u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + unsigned int xid; + int rc = -EOPNOTSUPP; + struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); +@@ -3030,11 +3030,11 @@ get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, + + } + +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + const char *path, u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; + unsigned int xid; + int rc; +@@ -3097,7 +3097,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, + } + + static int +-set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, ++set_smb2_acl(struct smb_ntsd *pnntsd, __u32 acllen, + struct inode *inode, const char *path, int aclflag) + { + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; +@@ -3155,12 +3155,12 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen, + } + + /* Retrieve an ACL from the server */ +-static struct cifs_ntsd * ++static struct smb_ntsd * + get_smb2_acl(struct cifs_sb_info *cifs_sb, + struct inode *inode, const char *path, + u32 *pacllen, u32 info) + { +- struct cifs_ntsd *pntsd = NULL; ++ struct smb_ntsd *pntsd = NULL; + struct cifsFileInfo *open_file = NULL; + + if (inode && !(info & SACL_SECINFO)) +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 38b26468eb0c..0a4985bba55f 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -5626,7 +5626,7 @@ SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, + int + SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, +- struct cifs_ntsd *pnntsd, int pacllen, int aclflag) ++ struct smb_ntsd *pnntsd, int pacllen, int aclflag) + { + return send_set_info(xid, tcon, persistent_fid, volatile_fid, + current->tgid, 0, SMB2_O_INFO_SECURITY, aclflag, +diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h +index 613667b46c58..fd90d8e5a1d1 100644 +--- a/fs/smb/client/smb2proto.h ++++ b/fs/smb/client/smb2proto.h +@@ -247,7 +247,7 @@ extern int SMB2_set_info_init(struct cifs_tcon *tcon, + extern void SMB2_set_info_free(struct smb_rqst *rqst); + extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, +- struct cifs_ntsd *pnntsd, int pacllen, int aclflag); ++ struct smb_ntsd *pnntsd, int pacllen, int aclflag); + extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + struct smb2_file_full_ea_info *buf, int len); +diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c +index c2bf829310be..e8696ad4da99 100644 +--- a/fs/smb/client/xattr.c ++++ b/fs/smb/client/xattr.c +@@ -162,7 +162,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, + case XATTR_CIFS_ACL: + case XATTR_CIFS_NTSD: + case XATTR_CIFS_NTSD_FULL: { +- struct cifs_ntsd *pacl; ++ struct smb_ntsd *pacl; + + if (!value) + goto out; +@@ -315,7 +315,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, + * fetch owner and DACL otherwise + */ + u32 acllen, extra_info; +- struct cifs_ntsd *pacl; ++ struct smb_ntsd *pacl; + + if (pTcon->ses->server->ops->get_acl == NULL) + goto out; /* rc already EOPNOTSUPP */ +-- +2.39.5 + diff --git a/queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch b/queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch new file mode 100644 index 00000000000..ece7962a98b --- /dev/null +++ b/queue-6.6/smb-client-rename-cifs_sid-to-smb_sid.patch @@ -0,0 +1,486 @@ +From 1dfdf72170666c41e22d81705cc81bfd868208f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 08:20:56 +0000 +Subject: smb/client: rename cifs_sid to smb_sid + +From: ChenXiaoSong + +[ Upstream commit 7f599d8fb3e087aff5be4e1392baaae3f8d42419 ] + +Preparation for moving acl definitions to new common header file. + +Use the following shell command to rename: + + find fs/smb/client -type f -exec sed -i \ + 's/struct cifs_sid/struct smb_sid/g' {} + + +Signed-off-by: ChenXiaoSong +Reviewed-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: d413eabff18d ("fs/smb/client: implement chmod() for SMB3 POSIX Extensions") +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifsacl.c | 96 +++++++++++++++++++-------------------- + fs/smb/client/cifsacl.h | 6 +-- + fs/smb/client/cifsglob.h | 8 ++-- + fs/smb/client/cifsproto.h | 2 +- + fs/smb/client/smb2inode.c | 4 +- + fs/smb/client/smb2pdu.c | 2 +- + fs/smb/client/smb2pdu.h | 8 ++-- + 7 files changed, 63 insertions(+), 63 deletions(-) + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 3f7657475cd9..dd399f9a7424 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -27,18 +27,18 @@ + #include "cifs_unicode.h" + + /* security id for everyone/world system group */ +-static const struct cifs_sid sid_everyone = { ++static const struct smb_sid sid_everyone = { + 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; + /* security id for Authenticated Users system group */ +-static const struct cifs_sid sid_authusers = { ++static const struct smb_sid sid_authusers = { + 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} }; + + /* S-1-22-1 Unmapped Unix users */ +-static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, ++static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, + {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-22-2 Unmapped Unix groups */ +-static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, ++static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, + {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* +@@ -48,17 +48,17 @@ static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, + /* S-1-5-88 MS NFS and Apple style UID/GID/mode */ + + /* S-1-5-88-1 Unix uid */ +-static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-5-88-2 Unix gid */ +-static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + + /* S-1-5-88-3 Unix mode */ +-static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5}, ++static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5}, + {cpu_to_le32(88), + cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; + +@@ -106,7 +106,7 @@ static struct key_type cifs_idmap_key_type = { + }; + + static char * +-sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) ++sid_to_key_str(struct smb_sid *sidptr, unsigned int type) + { + int i, len; + unsigned int saval; +@@ -158,7 +158,7 @@ sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) + * the same returns zero, if they do not match returns non-zero. + */ + static int +-compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) ++compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid) + { + int i; + int num_subauth, num_sat, num_saw; +@@ -204,11 +204,11 @@ compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) + } + + static bool +-is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group) ++is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group) + { + int i; + int num_subauth; +- const struct cifs_sid *pwell_known_sid; ++ const struct smb_sid *pwell_known_sid; + + if (!psid || (puid == NULL)) + return false; +@@ -260,7 +260,7 @@ is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group) + } + + static __u16 +-cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) ++cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src) + { + int i; + __u16 size = 1 + 1 + 6; +@@ -277,11 +277,11 @@ cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) + } + + static int +-id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) ++id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid) + { + int rc; + struct key *sidkey; +- struct cifs_sid *ksid; ++ struct smb_sid *ksid; + unsigned int ksid_size; + char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */ + const struct cred *saved_cred; +@@ -312,8 +312,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + * it could be. + */ + ksid = sidkey->datalen <= sizeof(sidkey->payload) ? +- (struct cifs_sid *)&sidkey->payload : +- (struct cifs_sid *)sidkey->payload.data[0]; ++ (struct smb_sid *)&sidkey->payload : ++ (struct smb_sid *)sidkey->payload.data[0]; + + ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32)); + if (ksid_size > sidkey->datalen) { +@@ -336,7 +336,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid) + } + + int +-sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, ++sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid, + struct cifs_fattr *fattr, uint sidtype) + { + int rc = 0; +@@ -518,11 +518,11 @@ exit_cifs_idmap(void) + static __u32 copy_sec_desc(const struct smb_ntsd *pntsd, + struct smb_ntsd *pnntsd, + __u32 sidsoffset, +- struct cifs_sid *pownersid, +- struct cifs_sid *pgrpsid) ++ struct smb_sid *pownersid, ++ struct smb_sid *pgrpsid) + { +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr; ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr; + + /* copy security descriptor control portion */ + pnntsd->revision = pntsd->revision; +@@ -530,28 +530,28 @@ static __u32 copy_sec_desc(const struct smb_ntsd *pntsd, + pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd)); + pnntsd->sacloffset = 0; + pnntsd->osidoffset = cpu_to_le32(sidsoffset); +- pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid)); ++ pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid)); + + /* copy owner sid */ + if (pownersid) + owner_sid_ptr = pownersid; + else +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset); ++ nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset); + cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr); + + /* copy group sid */ + if (pgrpsid) + group_sid_ptr = pgrpsid; + else +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); +- ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset + +- sizeof(struct cifs_sid)); ++ ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset + ++ sizeof(struct smb_sid)); + cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr); + +- return sidsoffset + (2 * sizeof(struct cifs_sid)); ++ return sidsoffset + (2 * sizeof(struct smb_sid)); + } + + +@@ -666,7 +666,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, + return; + } + +-static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct cifs_sid *psid) ++static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct smb_sid *psid) + { + __u16 size = 1 + 1 + 2 + 4; + +@@ -686,7 +686,7 @@ static __u16 cifs_copy_ace(struct cifs_ace *dst, struct cifs_ace *src, struct ci + } + + static __u16 fill_ace_for_sid(struct cifs_ace *pntace, +- const struct cifs_sid *psid, __u64 nmode, ++ const struct smb_sid *psid, __u64 nmode, + umode_t bits, __u8 access_type, + bool allow_delete_child) + { +@@ -759,7 +759,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl) + #endif + + static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, + struct cifs_fattr *fattr, bool mode_from_special_sid) + { + int i; +@@ -930,8 +930,8 @@ unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace) + } + + static void populate_new_aces(char *nacl_base, +- struct cifs_sid *pownersid, +- struct cifs_sid *pgrpsid, ++ struct smb_sid *pownersid, ++ struct smb_sid *pgrpsid, + __u64 *pnmode, u32 *pnum_aces, u16 *pnsize, + bool modefromsid) + { +@@ -967,7 +967,7 @@ static void populate_new_aces(char *nacl_base, + * updated in the inode. + */ + +- if (!memcmp(pownersid, pgrpsid, sizeof(struct cifs_sid))) { ++ if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) { + /* + * Case when owner and group SIDs are the same. + * Set the more restrictive of the two modes. +@@ -1035,8 +1035,8 @@ static void populate_new_aces(char *nacl_base, + } + + static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl *pndacl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, +- struct cifs_sid *pnownersid, struct cifs_sid *pngrpsid) ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, ++ struct smb_sid *pnownersid, struct smb_sid *pngrpsid) + { + int i; + u16 size = 0; +@@ -1075,7 +1075,7 @@ static __u16 replace_sids_and_copy_aces(struct cifs_acl *pdacl, struct cifs_acl + } + + static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, +- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, ++ struct smb_sid *pownersid, struct smb_sid *pgrpsid, + __u64 *pnmode, bool mode_from_sid) + { + int i; +@@ -1156,7 +1156,7 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl, + return 0; + } + +-static int parse_sid(struct cifs_sid *psid, char *end_of_acl) ++static int parse_sid(struct smb_sid *psid, char *end_of_acl) + { + /* BB need to add parm so we can store the SID BB */ + +@@ -1195,7 +1195,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + bool get_mode_from_special_sid) + { + int rc = 0; +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; + struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + acl_len; + __u32 dacloffset; +@@ -1203,9 +1203,9 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + if (pntsd == NULL) + return -EIO; + +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + dacloffset = le32_to_cpu(pntsd->dacloffset); + dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); +@@ -1257,8 +1257,8 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + __u32 dacloffset; + __u32 ndacloffset; + __u32 sidsoffset; +- struct cifs_sid *owner_sid_ptr, *group_sid_ptr; +- struct cifs_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL; ++ struct smb_sid *owner_sid_ptr, *group_sid_ptr; ++ struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL; + struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */ + struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */ + char *end_of_acl = ((char *)pntsd) + secdesclen; +@@ -1273,9 +1273,9 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + } + } + +- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ owner_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->osidoffset)); +- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + ++ group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + + if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ +@@ -1305,7 +1305,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + + if (uid_valid(uid)) { /* chown */ + uid_t id; +- nowner_sid_ptr = kzalloc(sizeof(struct cifs_sid), ++ nowner_sid_ptr = kzalloc(sizeof(struct smb_sid), + GFP_KERNEL); + if (!nowner_sid_ptr) { + rc = -ENOMEM; +@@ -1334,7 +1334,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + } + if (gid_valid(gid)) { /* chgrp */ + gid_t id; +- ngroup_sid_ptr = kzalloc(sizeof(struct cifs_sid), ++ ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid), + GFP_KERNEL); + if (!ngroup_sid_ptr) { + rc = -ENOMEM; +@@ -1630,7 +1630,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + nsecdesclen += 5 * sizeof(struct cifs_ace); + } else { /* chown */ + /* When ownership changes, changes new owner sid length could be different */ +- nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct cifs_sid) * 2); ++ nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { + dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); +diff --git a/fs/smb/client/cifsacl.h b/fs/smb/client/cifsacl.h +index 1516545d7f67..6a38718220fc 100644 +--- a/fs/smb/client/cifsacl.h ++++ b/fs/smb/client/cifsacl.h +@@ -64,14 +64,14 @@ struct smb_ntsd { + __le32 dacloffset; + } __attribute__((packed)); + +-struct cifs_sid { ++struct smb_sid { + __u8 revision; /* revision level */ + __u8 num_subauth; + __u8 authority[NUM_AUTHS]; + __le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */ + } __attribute__((packed)); + +-/* size of a struct cifs_sid, sans sub_auth array */ ++/* size of a struct smb_sid, sans sub_auth array */ + #define CIFS_SID_BASE_SIZE (1 + 1 + NUM_AUTHS) + + struct cifs_acl { +@@ -116,7 +116,7 @@ struct cifs_ace { + __u8 flags; + __le16 size; + __le32 access_req; +- struct cifs_sid sid; /* ie UUID of user or group who gets these perms */ ++ struct smb_sid sid; /* ie UUID of user or group who gets these perms */ + } __attribute__((packed)); + + /* +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index cf22629bf90b..69d850b6b37f 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -202,8 +202,8 @@ struct cifs_cred { + int gid; + int mode; + int cecount; +- struct cifs_sid osid; +- struct cifs_sid gsid; ++ struct smb_sid osid; ++ struct smb_sid gsid; + struct cifs_ntace *ntaces; + struct cifs_ace *aces; + }; +@@ -231,8 +231,8 @@ struct cifs_open_info_data { + unsigned int eas_len; + } wsl; + char *symlink_target; +- struct cifs_sid posix_owner; +- struct cifs_sid posix_group; ++ struct smb_sid posix_owner; ++ struct smb_sid posix_group; + union { + struct smb2_file_all_info fi; + struct smb311_posix_qinfo posix_fi; +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index f34c533efe49..059e506ccf5b 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -223,7 +223,7 @@ extern int cifs_set_file_info(struct inode *inode, struct iattr *attrs, + extern int cifs_rename_pending_delete(const char *full_path, + struct dentry *dentry, + const unsigned int xid); +-extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, ++extern int sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid, + struct cifs_fattr *fattr, uint sidtype); + extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, + struct cifs_fattr *fattr, struct inode *inode, +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index 2a292736c89a..e695df1dbb23 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -315,7 +315,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + SMB2_O_INFO_FILE, 0, + sizeof(struct smb311_posix_qinfo *) + + (PATH_MAX * 2) + +- (sizeof(struct cifs_sid) * 2), 0, NULL); ++ (sizeof(struct smb_sid) * 2), 0, NULL); + } else { + rc = SMB2_query_info_init(tcon, server, + &rqst[num_rqst], +@@ -325,7 +325,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, + SMB2_O_INFO_FILE, 0, + sizeof(struct smb311_posix_qinfo *) + + (PATH_MAX * 2) + +- (sizeof(struct cifs_sid) * 2), 0, NULL); ++ (sizeof(struct smb_sid) * 2), 0, NULL); + } + if (!rc && (!cfile || num_rqst > 1)) { + smb2_set_next_command(tcon, &rqst[num_rqst]); +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 0a4985bba55f..42f950ae10fb 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -3915,7 +3915,7 @@ SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen) + { + size_t output_len = sizeof(struct smb311_posix_qinfo *) + +- (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2); ++ (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2); + *plen = 0; + + return query_info(xid, tcon, persistent_fid, volatile_fid, +diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h +index 5c458ab3b05a..076d9e83e1a0 100644 +--- a/fs/smb/client/smb2pdu.h ++++ b/fs/smb/client/smb2pdu.h +@@ -364,8 +364,8 @@ struct create_posix_rsp { + u32 nlink; + u32 reparse_tag; + u32 mode; +- struct cifs_sid owner; /* var-sized on the wire */ +- struct cifs_sid group; /* var-sized on the wire */ ++ struct smb_sid owner; /* var-sized on the wire */ ++ struct smb_sid group; /* var-sized on the wire */ + } __packed; + + #define SMB2_QUERY_DIRECTORY_IOV_SIZE 2 +@@ -408,8 +408,8 @@ struct smb2_posix_info { + struct smb2_posix_info_parsed { + const struct smb2_posix_info *base; + size_t size; +- struct cifs_sid owner; +- struct cifs_sid group; ++ struct smb_sid owner; ++ struct smb_sid group; + int name_len; + const u8 *name; + }; +-- +2.39.5 + diff --git a/queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch b/queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch new file mode 100644 index 00000000000..d9e0fc5ea94 --- /dev/null +++ b/queue-6.6/smb-client-stop-flooding-dmesg-in-smb2_calc_signatur.patch @@ -0,0 +1,38 @@ +From 87c234693cf0285f61446a00e145084321fd5bc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Sep 2024 02:04:01 -0300 +Subject: smb: client: stop flooding dmesg in smb2_calc_signature() + +From: Paulo Alcantara + +[ Upstream commit a13ca780afab350f37f8be9eda2bf79d1aed9bdd ] + +When having several mounts that share same credential and the client +couldn't re-establish an SMB session due to an expired kerberos ticket +or rotated password, smb2_calc_signature() will end up flooding dmesg +when not finding SMB sessions to calculate signatures. + +Signed-off-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Stable-dep-of: 343d7fe6df9e ("smb: client: fix use-after-free of signing key") +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb2transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c +index 4ca04e62a993..73eae1b16034 100644 +--- a/fs/smb/client/smb2transport.c ++++ b/fs/smb/client/smb2transport.c +@@ -242,7 +242,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server, + + ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId)); + if (unlikely(!ses)) { +- cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); ++ cifs_server_dbg(FYI, "%s: Could not find session\n", __func__); + return -ENOENT; + } + +-- +2.39.5 + diff --git a/queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch b/queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch new file mode 100644 index 00000000000..577f2dbe9bb --- /dev/null +++ b/queue-6.6/softirq-allow-raising-sched_softirq-from-smp-call-fu.patch @@ -0,0 +1,91 @@ +From 1a1f81f97d609db67730370e56ba4733824136c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2024 05:44:29 +0000 +Subject: softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT + kernel + +From: K Prateek Nayak + +[ Upstream commit 6675ce20046d149e1e1ffe7e9577947dee17aad5 ] + +do_softirq_post_smp_call_flush() on PREEMPT_RT kernels carries a +WARN_ON_ONCE() for any SOFTIRQ being raised from an SMP-call-function. +Since do_softirq_post_smp_call_flush() is called with preempt disabled, +raising a SOFTIRQ during flush_smp_call_function_queue() can lead to +longer preempt disabled sections. + +Since commit b2a02fc43a1f ("smp: Optimize +send_call_function_single_ipi()") IPIs to an idle CPU in +TIF_POLLING_NRFLAG mode can be optimized out by instead setting +TIF_NEED_RESCHED bit in idle task's thread_info and relying on the +flush_smp_call_function_queue() in the idle-exit path to run the +SMP-call-function. + +To trigger an idle load balancing, the scheduler queues +nohz_csd_function() responsible for triggering an idle load balancing on +a target nohz idle CPU and sends an IPI. Only now, this IPI is optimized +out and the SMP-call-function is executed from +flush_smp_call_function_queue() in do_idle() which can raise a +SCHED_SOFTIRQ to trigger the balancing. + +So far, this went undetected since, the need_resched() check in +nohz_csd_function() would make it bail out of idle load balancing early +as the idle thread does not clear TIF_POLLING_NRFLAG before calling +flush_smp_call_function_queue(). The need_resched() check was added with +the intent to catch a new task wakeup, however, it has recently +discovered to be unnecessary and will be removed in the subsequent +commit after which nohz_csd_function() can raise a SCHED_SOFTIRQ from +flush_smp_call_function_queue() to trigger an idle load balance on an +idle target in TIF_POLLING_NRFLAG mode. + +nohz_csd_function() bails out early if "idle_cpu()" check for the +target CPU, and does not lock the target CPU's rq until the very end, +once it has found tasks to run on the CPU and will not inhibit the +wakeup of, or running of a newly woken up higher priority task. Account +for this and prevent a WARN_ON_ONCE() when SCHED_SOFTIRQ is raised from +flush_smp_call_function_queue(). + +Signed-off-by: K Prateek Nayak +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20241119054432.6405-2-kprateek.nayak@amd.com +Signed-off-by: Sasha Levin +--- + kernel/softirq.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/kernel/softirq.c b/kernel/softirq.c +index bd9716d7bb63..f24d80cf20bd 100644 +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -279,17 +279,24 @@ static inline void invoke_softirq(void) + wakeup_softirqd(); + } + ++#define SCHED_SOFTIRQ_MASK BIT(SCHED_SOFTIRQ) ++ + /* + * flush_smp_call_function_queue() can raise a soft interrupt in a function +- * call. On RT kernels this is undesired and the only known functionality +- * in the block layer which does this is disabled on RT. If soft interrupts +- * get raised which haven't been raised before the flush, warn so it can be ++ * call. On RT kernels this is undesired and the only known functionalities ++ * are in the block layer which is disabled on RT, and in the scheduler for ++ * idle load balancing. If soft interrupts get raised which haven't been ++ * raised before the flush, warn if it is not a SCHED_SOFTIRQ so it can be + * investigated. + */ + void do_softirq_post_smp_call_flush(unsigned int was_pending) + { +- if (WARN_ON_ONCE(was_pending != local_softirq_pending())) ++ unsigned int is_pending = local_softirq_pending(); ++ ++ if (unlikely(was_pending != is_pending)) { ++ WARN_ON_ONCE(was_pending != (is_pending & ~SCHED_SOFTIRQ_MASK)); + invoke_softirq(); ++ } + } + + #else /* CONFIG_PREEMPT_RT */ +-- +2.39.5 + diff --git a/queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch b/queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch new file mode 100644 index 00000000000..e01cb5d890b --- /dev/null +++ b/queue-6.6/thunderbolt-add-support-for-intel-lunar-lake.patch @@ -0,0 +1,54 @@ +From abeb580d38a04ac82eb79aaae31aeadb4299943c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 May 2022 13:47:11 +0300 +Subject: thunderbolt: Add support for Intel Lunar Lake + +From: Mika Westerberg + +[ Upstream commit 2cd3da4e37453019e21a486d9de3144f46b4fdf7 ] + +Intel Lunar Lake has similar integrated Thunderbolt/USB4 controller as +Intel Meteor Lake with some small differences in the host router (it has +3 DP IN adapters for instance). Add the Intel Lunar Lake PCI IDs to the +driver list of supported devices. + +Tested-by: Pengfei Xu +Signed-off-by: Mika Westerberg +Stable-dep-of: 8644b48714dc ("thunderbolt: Add support for Intel Panther Lake-M/P") +Signed-off-by: Sasha Levin +--- + drivers/thunderbolt/nhi.c | 4 ++++ + drivers/thunderbolt/nhi.h | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index 1ec6f9c82aef..b22023fae60d 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -1524,6 +1524,10 @@ static struct pci_device_id nhi_ids[] = { + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL_P_NHI1), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) }, + +diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h +index 0f029ce75882..7a07c7c1a9c2 100644 +--- a/drivers/thunderbolt/nhi.h ++++ b/drivers/thunderbolt/nhi.h +@@ -90,6 +90,8 @@ extern const struct tb_nhi_ops icl_nhi_ops; + #define PCI_DEVICE_ID_INTEL_TGL_H_NHI1 0x9a21 + #define PCI_DEVICE_ID_INTEL_RPL_NHI0 0xa73e + #define PCI_DEVICE_ID_INTEL_RPL_NHI1 0xa76d ++#define PCI_DEVICE_ID_INTEL_LNL_NHI0 0xa833 ++#define PCI_DEVICE_ID_INTEL_LNL_NHI1 0xa834 + + #define PCI_CLASS_SERIAL_USB_USB4 0x0c0340 + +-- +2.39.5 + diff --git a/queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch b/queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch new file mode 100644 index 00000000000..abb35039e02 --- /dev/null +++ b/queue-6.6/thunderbolt-add-support-for-intel-panther-lake-m-p.patch @@ -0,0 +1,58 @@ +From be1f09403ebe8713bef6bba0b61e50f24fd5559d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 May 2024 10:15:14 +0300 +Subject: thunderbolt: Add support for Intel Panther Lake-M/P + +From: Mika Westerberg + +[ Upstream commit 8644b48714dca8bf2f42a4ff8311de8efc9bd8c3 ] + +Intel Panther Lake-M/P has the same integrated Thunderbolt/USB4 +controller as Lunar Lake. Add these PCI IDs to the driver list of +supported devices. + +Cc: stable@vger.kernel.org +Signed-off-by: Mika Westerberg +Signed-off-by: Sasha Levin +--- + drivers/thunderbolt/nhi.c | 8 ++++++++ + drivers/thunderbolt/nhi.h | 4 ++++ + 2 files changed, 12 insertions(+) + +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index b22023fae60d..79f2bf5df19a 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -1528,6 +1528,14 @@ static struct pci_device_id nhi_ids[] = { + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_LNL_NHI1), + .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_M_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI0), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, ++ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_PTL_P_NHI1), ++ .driver_data = (kernel_ulong_t)&icl_nhi_ops }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI) }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI) }, + +diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h +index 7a07c7c1a9c2..16744f25a9a0 100644 +--- a/drivers/thunderbolt/nhi.h ++++ b/drivers/thunderbolt/nhi.h +@@ -92,6 +92,10 @@ extern const struct tb_nhi_ops icl_nhi_ops; + #define PCI_DEVICE_ID_INTEL_RPL_NHI1 0xa76d + #define PCI_DEVICE_ID_INTEL_LNL_NHI0 0xa833 + #define PCI_DEVICE_ID_INTEL_LNL_NHI1 0xa834 ++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI0 0xe333 ++#define PCI_DEVICE_ID_INTEL_PTL_M_NHI1 0xe334 ++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI0 0xe433 ++#define PCI_DEVICE_ID_INTEL_PTL_P_NHI1 0xe434 + + #define PCI_CLASS_SERIAL_USB_USB4 0x0c0340 + +-- +2.39.5 + diff --git a/queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch b/queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch new file mode 100644 index 00000000000..48bcd0d0ea9 --- /dev/null +++ b/queue-6.6/thunderbolt-don-t-display-nvm_version-unless-upgrade.patch @@ -0,0 +1,77 @@ +From 96ef200006965eee0b58f9e0184648a3f32256c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2024 10:25:51 -0600 +Subject: thunderbolt: Don't display nvm_version unless upgrade supported + +From: Mario Limonciello + +[ Upstream commit e34f1717ef0632fcec5cb827e5e0e9f223d70c9b ] + +The read will never succeed if NVM wasn't initialized due to an unknown +format. + +Add a new callback for visibility to only show when supported. + +Cc: stable@vger.kernel.org +Fixes: aef9c693e7e5 ("thunderbolt: Move vendor specific NVM handling into nvm.c") +Reported-by: Richard Hughes +Closes: https://github.com/fwupd/fwupd/issues/8200 +Signed-off-by: Mario Limonciello +Signed-off-by: Mika Westerberg +Signed-off-by: Sasha Levin +--- + drivers/thunderbolt/retimer.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c +index 47becb363ada..2ee8c5ebca7c 100644 +--- a/drivers/thunderbolt/retimer.c ++++ b/drivers/thunderbolt/retimer.c +@@ -98,6 +98,7 @@ static int tb_retimer_nvm_add(struct tb_retimer *rt) + + err_nvm: + dev_dbg(&rt->dev, "NVM upgrade disabled\n"); ++ rt->no_nvm_upgrade = true; + if (!IS_ERR(nvm)) + tb_nvm_free(nvm); + +@@ -177,8 +178,6 @@ static ssize_t nvm_authenticate_show(struct device *dev, + + if (!rt->nvm) + ret = -EAGAIN; +- else if (rt->no_nvm_upgrade) +- ret = -EOPNOTSUPP; + else + ret = sysfs_emit(buf, "%#x\n", rt->auth_status); + +@@ -331,6 +330,19 @@ static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, + } + static DEVICE_ATTR_RO(vendor); + ++static umode_t retimer_is_visible(struct kobject *kobj, struct attribute *attr, ++ int n) ++{ ++ struct device *dev = kobj_to_dev(kobj); ++ struct tb_retimer *rt = tb_to_retimer(dev); ++ ++ if (attr == &dev_attr_nvm_authenticate.attr || ++ attr == &dev_attr_nvm_version.attr) ++ return rt->no_nvm_upgrade ? 0 : attr->mode; ++ ++ return attr->mode; ++} ++ + static struct attribute *retimer_attrs[] = { + &dev_attr_device.attr, + &dev_attr_nvm_authenticate.attr, +@@ -340,6 +352,7 @@ static struct attribute *retimer_attrs[] = { + }; + + static const struct attribute_group retimer_group = { ++ .is_visible = retimer_is_visible, + .attrs = retimer_attrs, + }; + +-- +2.39.5 + diff --git a/queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch b/queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch new file mode 100644 index 00000000000..2dc3e985894 --- /dev/null +++ b/queue-6.6/udf-verify-inode-link-counts-before-performing-renam.patch @@ -0,0 +1,47 @@ +From 38e7b6d3ef558f9dcbb437d094ee2efc9fa2b784 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Nov 2024 12:55:12 +0100 +Subject: udf: Verify inode link counts before performing rename + +From: Jan Kara + +[ Upstream commit 6756af923e06aa33ad8894aaecbf9060953ba00f ] + +During rename, we are updating link counts of various inodes either when +rename deletes target or when moving directory across directories. +Verify involved link counts are sane so that we don't trip warnings in +VFS. + +Reported-by: syzbot+3ff7365dc04a6bcafa66@syzkaller.appspotmail.com +Signed-off-by: Jan Kara +Signed-off-by: Sasha Levin +--- + fs/udf/namei.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index 0461a7b1e9b4..8ac73f41d6eb 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -792,8 +792,18 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + retval = -ENOTEMPTY; + if (!empty_dir(new_inode)) + goto out_oiter; ++ retval = -EFSCORRUPTED; ++ if (new_inode->i_nlink != 2) ++ goto out_oiter; + } ++ retval = -EFSCORRUPTED; ++ if (old_dir->i_nlink < 3) ++ goto out_oiter; + is_dir = true; ++ } else if (new_inode) { ++ retval = -EFSCORRUPTED; ++ if (new_inode->i_nlink < 1) ++ goto out_oiter; + } + if (is_dir && old_dir != new_dir) { + retval = udf_fiiter_find_entry(old_inode, &dotdot_name, +-- +2.39.5 + diff --git a/queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch b/queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch new file mode 100644 index 00000000000..3386c463c70 --- /dev/null +++ b/queue-6.6/udf_rename-only-access-the-child-content-on-cross-di.patch @@ -0,0 +1,61 @@ +From 29df5c14514fcefbda1046b60119bf5d6b3119e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 14:44:23 -0400 +Subject: udf_rename(): only access the child content on cross-directory rename + +From: Al Viro + +[ Upstream commit 9d35cebb794bb7be93db76c3383979c7deacfef9 ] + +We can't really afford locking the source on same-directory rename; +currently vfs_rename() tries to do that, but it will have to be +changed. The logics in udf_rename() is lazy and goes looking for +".." in source even in same-directory case. It's not hard to get +rid of that, leaving that behaviour only for cross-directory case; +that VFS can get locks safely (and will keep doing that after the +coming changes). + +Reviewed-by: Jan Kara +Signed-off-by: Al Viro +Stable-dep-of: 6756af923e06 ("udf: Verify inode link counts before performing rename") +Signed-off-by: Sasha Levin +--- + fs/udf/namei.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/fs/udf/namei.c b/fs/udf/namei.c +index b3f57ad2b869..0461a7b1e9b4 100644 +--- a/fs/udf/namei.c ++++ b/fs/udf/namei.c +@@ -770,7 +770,7 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + struct inode *old_inode = d_inode(old_dentry); + struct inode *new_inode = d_inode(new_dentry); + struct udf_fileident_iter oiter, niter, diriter; +- bool has_diriter = false; ++ bool has_diriter = false, is_dir = false; + int retval; + struct kernel_lb_addr tloc; + +@@ -793,6 +793,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + if (!empty_dir(new_inode)) + goto out_oiter; + } ++ is_dir = true; ++ } ++ if (is_dir && old_dir != new_dir) { + retval = udf_fiiter_find_entry(old_inode, &dotdot_name, + &diriter); + if (retval == -ENOENT) { +@@ -880,7 +883,9 @@ static int udf_rename(struct mnt_idmap *idmap, struct inode *old_dir, + cpu_to_lelb(UDF_I(new_dir)->i_location); + udf_fiiter_write_fi(&diriter, NULL); + udf_fiiter_release(&diriter); ++ } + ++ if (is_dir) { + inode_dec_link_count(old_dir); + if (new_inode) + inode_dec_link_count(new_inode); +-- +2.39.5 + diff --git a/queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch b/queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch new file mode 100644 index 00000000000..62d81832ea5 --- /dev/null +++ b/queue-6.6/usb-chipidea-add-ci_hdrc_force_vbus_active_always-fl.patch @@ -0,0 +1,56 @@ +From a4b96dd91bf254d63e2084e6c31c207c261a2bdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Oct 2023 22:59:01 +0300 +Subject: usb: chipidea: add CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS flag + +From: Tomer Maimon + +[ Upstream commit 2978cc1f285390c1bd4d9bfc665747adc6e4b19c ] + +Adding CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS flag to modify the vbus_active +parameter to active in case the ChipIdea USB IP role is device-only and +there is no otgsc register. + +Signed-off-by: Tomer Maimon +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20231017195903.1665260-2-tmaimon77@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: ec841b8d73cf ("usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag") +Signed-off-by: Sasha Levin +--- + drivers/usb/chipidea/otg.c | 5 ++++- + include/linux/usb/chipidea.h | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c +index f5490f2a5b6b..647e98f4e351 100644 +--- a/drivers/usb/chipidea/otg.c ++++ b/drivers/usb/chipidea/otg.c +@@ -130,8 +130,11 @@ enum ci_role ci_otg_role(struct ci_hdrc *ci) + + void ci_handle_vbus_change(struct ci_hdrc *ci) + { +- if (!ci->is_otg) ++ if (!ci->is_otg) { ++ if (ci->platdata->flags & CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS) ++ usb_gadget_vbus_connect(&ci->gadget); + return; ++ } + + if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active) + usb_gadget_vbus_connect(&ci->gadget); +diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h +index 0b4f2d5faa08..5a7f96684ea2 100644 +--- a/include/linux/usb/chipidea.h ++++ b/include/linux/usb/chipidea.h +@@ -64,6 +64,7 @@ struct ci_hdrc_platform_data { + #define CI_HDRC_PMQOS BIT(15) + #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) + #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) ++#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18) + enum usb_dr_mode dr_mode; + #define CI_HDRC_CONTROLLER_RESET_EVENT 0 + #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 +-- +2.39.5 + diff --git a/queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch b/queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch new file mode 100644 index 00000000000..6cd33c1914e --- /dev/null +++ b/queue-6.6/usb-chipidea-add-ci_hdrc_has_short_pkt_limit-flag.patch @@ -0,0 +1,90 @@ +From 3c006c4a9edd0b45f89187cf1d716a6c20d6e5c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 16:12:01 +0800 +Subject: usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag + +From: Xu Yang + +[ Upstream commit ec841b8d73cff37f8960e209017efe1eb2fb21f2 ] + +Currently, the imx deivice controller has below limitations: + +1. can't generate short packet interrupt if IOC not set in dTD. So if one + request span more than one dTDs and only the last dTD set IOC, the usb + request will pending there if no more data comes. +2. the controller can't accurately deliver data to differtent usb requests + in some cases due to short packet. For example: one usb request span 3 + dTDs, then if the controller received a short packet the next packet + will go to 2nd dTD of current request rather than the first dTD of next + request. +3. can't build a bus packet use multiple dTDs. For example: controller + needs to send one packet of 512 bytes use dTD1 (200 bytes) + dTD2 + (312 bytes), actually the host side will see 200 bytes short packet. + +Based on these limits, add CI_HDRC_HAS_SHORT_PKT_LIMIT flag and use it on +imx platforms. + +Signed-off-by: Xu Yang +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20240923081203.2851768-1-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/chipidea/ci.h | 1 + + drivers/usb/chipidea/ci_hdrc_imx.c | 1 + + drivers/usb/chipidea/core.c | 2 ++ + include/linux/usb/chipidea.h | 1 + + 4 files changed, 5 insertions(+) + +diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h +index 2a38e1eb6546..e4b003d060c2 100644 +--- a/drivers/usb/chipidea/ci.h ++++ b/drivers/usb/chipidea/ci.h +@@ -260,6 +260,7 @@ struct ci_hdrc { + bool b_sess_valid_event; + bool imx28_write_fix; + bool has_portsc_pec_bug; ++ bool has_short_pkt_limit; + bool supports_runtime_pm; + bool in_lpm; + bool wakeup_int; +diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c +index e28bb2f2612d..477af457c1a1 100644 +--- a/drivers/usb/chipidea/ci_hdrc_imx.c ++++ b/drivers/usb/chipidea/ci_hdrc_imx.c +@@ -334,6 +334,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) + struct ci_hdrc_platform_data pdata = { + .name = dev_name(&pdev->dev), + .capoffset = DEF_CAPOFFSET, ++ .flags = CI_HDRC_HAS_SHORT_PKT_LIMIT, + .notify_event = ci_hdrc_imx_notify_event, + }; + int ret; +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index ca71df4f32e4..c161a4ee5290 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -1076,6 +1076,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) + CI_HDRC_SUPPORTS_RUNTIME_PM); + ci->has_portsc_pec_bug = !!(ci->platdata->flags & + CI_HDRC_HAS_PORTSC_PEC_MISSED); ++ ci->has_short_pkt_limit = !!(ci->platdata->flags & ++ CI_HDRC_HAS_SHORT_PKT_LIMIT); + platform_set_drvdata(pdev, ci); + + ret = hw_device_init(ci, base); +diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h +index 5a7f96684ea2..ebdfef124b2b 100644 +--- a/include/linux/usb/chipidea.h ++++ b/include/linux/usb/chipidea.h +@@ -65,6 +65,7 @@ struct ci_hdrc_platform_data { + #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) + #define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) + #define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18) ++#define CI_HDRC_HAS_SHORT_PKT_LIMIT BIT(19) + enum usb_dr_mode dr_mode; + #define CI_HDRC_CONTROLLER_RESET_EVENT 0 + #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 +-- +2.39.5 + diff --git a/queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch b/queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch new file mode 100644 index 00000000000..951fe156520 --- /dev/null +++ b/queue-6.6/usb-chipidea-udc-limit-usb-request-length-to-max-16k.patch @@ -0,0 +1,58 @@ +From 3a2effe2072215a53d333ffca74fd3caf8a1a23b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Sep 2024 16:12:02 +0800 +Subject: usb: chipidea: udc: limit usb request length to max 16KB + +From: Xu Yang + +[ Upstream commit ca8d18aa7b0f22d66a3ca9a90d8f73431b8eca89 ] + +To let the device controller work properly on short packet limitations, +one usb request should only correspond to one dTD. Then every dTD will +set IOC. In theory, each dTD support up to 20KB data transfer if the +offset is 0. Due to we cannot predetermine the offset, this will limit +the usb request length to max 16KB. This should be fine since most of +the user transfer data based on this size policy. + +Signed-off-by: Xu Yang +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20240923081203.2851768-2-xu.yang_2@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/chipidea/ci.h | 1 + + drivers/usb/chipidea/udc.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h +index e4b003d060c2..97437de52ef6 100644 +--- a/drivers/usb/chipidea/ci.h ++++ b/drivers/usb/chipidea/ci.h +@@ -25,6 +25,7 @@ + #define TD_PAGE_COUNT 5 + #define CI_HDRC_PAGE_SIZE 4096ul /* page size for TD's */ + #define ENDPT_MAX 32 ++#define CI_MAX_REQ_SIZE (4 * CI_HDRC_PAGE_SIZE) + #define CI_MAX_BUF_SIZE (TD_PAGE_COUNT * CI_HDRC_PAGE_SIZE) + + /****************************************************************************** +diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c +index 9f7d003e467b..f2ae5f4c5828 100644 +--- a/drivers/usb/chipidea/udc.c ++++ b/drivers/usb/chipidea/udc.c +@@ -959,6 +959,12 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, + return -EMSGSIZE; + } + ++ if (ci->has_short_pkt_limit && ++ hwreq->req.length > CI_MAX_REQ_SIZE) { ++ dev_err(hwep->ci->dev, "request length too big (max 16KB)\n"); ++ return -EMSGSIZE; ++ } ++ + /* first nuke then test link, e.g. previous status has not sent */ + if (!list_empty(&hwreq->queue)) { + dev_err(hwep->ci->dev, "request already in queue\n"); +-- +2.39.5 + diff --git a/queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch b/queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch new file mode 100644 index 00000000000..7a74f7bcc53 --- /dev/null +++ b/queue-6.6/usb-dwc3-gadget-add-missing-check-for-single-port-ra.patch @@ -0,0 +1,168 @@ +From b1f48b41c7dfb8ad06fdf37f2a118863125e4ab7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Nov 2024 10:18:02 +0530 +Subject: usb: dwc3: gadget: Add missing check for single port RAM in TxFIFO + resizing logic + +From: Selvarasu Ganesan + +[ Upstream commit 61eb055cd3048ee01ca43d1be924167d33e16fdc ] + +The existing implementation of the TxFIFO resizing logic only supports +scenarios where more than one port RAM is used. However, there is a need +to resize the TxFIFO in USB2.0-only mode where only a single port RAM is +available. This commit introduces the necessary changes to support +TxFIFO resizing in such scenarios by adding a missing check for single +port RAM. + +This fix addresses certain platform configurations where the existing +TxFIFO resizing logic does not work properly due to the absence of +support for single port RAM. By adding this missing check, we ensure +that the TxFIFO resizing logic works correctly in all scenarios, +including those with a single port RAM. + +Fixes: 9f607a309fbe ("usb: dwc3: Resize TX FIFOs to meet EP bursting requirements") +Cc: stable@vger.kernel.org # 6.12.x: fad16c82: usb: dwc3: gadget: Refine the logic for resizing Tx FIFOs +Signed-off-by: Selvarasu Ganesan +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20241112044807.623-1-selvarasu.g@samsung.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/core.h | 4 +++ + drivers/usb/dwc3/gadget.c | 54 +++++++++++++++++++++++++++++++++------ + 2 files changed, 50 insertions(+), 8 deletions(-) + +diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h +index b118f4aab189..d00bf714a7cc 100644 +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -899,6 +899,7 @@ struct dwc3_hwparams { + #define DWC3_MODE(n) ((n) & 0x7) + + /* HWPARAMS1 */ ++#define DWC3_SPRAM_TYPE(n) (((n) >> 23) & 1) + #define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) + + /* HWPARAMS3 */ +@@ -909,6 +910,9 @@ struct dwc3_hwparams { + #define DWC3_NUM_IN_EPS(p) (((p)->hwparams3 & \ + (DWC3_NUM_IN_EPS_MASK)) >> 18) + ++/* HWPARAMS6 */ ++#define DWC3_RAM0_DEPTH(n) (((n) & (0xffff0000)) >> 16) ++ + /* HWPARAMS7 */ + #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff) + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index b560996bd421..656460c0c1dd 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -687,6 +687,44 @@ static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult) + return fifo_size; + } + ++/** ++ * dwc3_gadget_calc_ram_depth - calculates the ram depth for txfifo ++ * @dwc: pointer to the DWC3 context ++ */ ++static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc) ++{ ++ int ram_depth; ++ int fifo_0_start; ++ bool is_single_port_ram; ++ ++ /* Check supporting RAM type by HW */ ++ is_single_port_ram = DWC3_SPRAM_TYPE(dwc->hwparams.hwparams1); ++ ++ /* ++ * If a single port RAM is utilized, then allocate TxFIFOs from ++ * RAM0. otherwise, allocate them from RAM1. ++ */ ++ ram_depth = is_single_port_ram ? DWC3_RAM0_DEPTH(dwc->hwparams.hwparams6) : ++ DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); ++ ++ /* ++ * In a single port RAM configuration, the available RAM is shared ++ * between the RX and TX FIFOs. This means that the txfifo can begin ++ * at a non-zero address. ++ */ ++ if (is_single_port_ram) { ++ u32 reg; ++ ++ /* Check if TXFIFOs start at non-zero addr */ ++ reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); ++ fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg); ++ ++ ram_depth -= (fifo_0_start >> 16); ++ } ++ ++ return ram_depth; ++} ++ + /** + * dwc3_gadget_clear_tx_fifos - Clears txfifo allocation + * @dwc: pointer to the DWC3 context +@@ -753,7 +791,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + { + struct dwc3 *dwc = dep->dwc; + int fifo_0_start; +- int ram1_depth; ++ int ram_depth; + int fifo_size; + int min_depth; + int num_in_ep; +@@ -773,7 +811,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + if (dep->flags & DWC3_EP_TXFIFO_RESIZED) + return 0; + +- ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); ++ ram_depth = dwc3_gadget_calc_ram_depth(dwc); + + if ((dep->endpoint.maxburst > 1 && + usb_endpoint_xfer_bulk(dep->endpoint.desc)) || +@@ -794,7 +832,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + + /* Reserve at least one FIFO for the number of IN EPs */ + min_depth = num_in_ep * (fifo + 1); +- remaining = ram1_depth - min_depth - dwc->last_fifo_depth; ++ remaining = ram_depth - min_depth - dwc->last_fifo_depth; + remaining = max_t(int, 0, remaining); + /* + * We've already reserved 1 FIFO per EP, so check what we can fit in +@@ -820,9 +858,9 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) + dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size); + + /* Check fifo size allocation doesn't exceed available RAM size. */ +- if (dwc->last_fifo_depth >= ram1_depth) { ++ if (dwc->last_fifo_depth >= ram_depth) { + dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n", +- dwc->last_fifo_depth, ram1_depth, ++ dwc->last_fifo_depth, ram_depth, + dep->endpoint.name, fifo_size); + if (DWC3_IP_IS(DWC3)) + fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size); +@@ -3078,7 +3116,7 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) + struct dwc3 *dwc = gadget_to_dwc(g); + struct usb_ep *ep; + int fifo_size = 0; +- int ram1_depth; ++ int ram_depth; + int ep_num = 0; + + if (!dwc->do_fifo_resize) +@@ -3101,8 +3139,8 @@ static int dwc3_gadget_check_config(struct usb_gadget *g) + fifo_size += dwc->max_cfg_eps; + + /* Check if we can fit a single fifo per endpoint */ +- ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); +- if (fifo_size > ram1_depth) ++ ram_depth = dwc3_gadget_calc_ram_depth(dwc); ++ if (fifo_size > ram_depth) + return -ENOMEM; + + return 0; +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch b/queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch new file mode 100644 index 00000000000..edfaabbe06e --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-add-callback-for-connector-status-upd.patch @@ -0,0 +1,83 @@ +From 8e5fa2737d76d60b931b656b66b9c9c4cb7abb69 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 07:49:53 +0300 +Subject: usb: typec: ucsi: add callback for connector status updates + +From: Dmitry Baryshkov + +[ Upstream commit 24bce22d09ec8e67022aab9a888acb56fb7a996a ] + +Allow UCSI glue driver to perform addtional work to update connector +status. For example, it might check the cable orientation. This call is +performed after reading new connector statatus, so the platform driver +can peek at new connection status bits. + +The callback is called both when registering the port and when the +connector change event is being handled. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-1-d4b1cb22a33f@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports") +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi.c | 6 ++++++ + drivers/usb/typec/ucsi/ucsi.h | 3 +++ + 2 files changed, 9 insertions(+) + +diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c +index f6fb5575d4f0..3f7039a711c7 100644 +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -903,6 +903,9 @@ static void ucsi_handle_connector_change(struct work_struct *work) + + trace_ucsi_connector_change(con->num, &con->status); + ++ if (ucsi->ops->connector_status) ++ ucsi->ops->connector_status(con); ++ + role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR); + + if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) { +@@ -1322,6 +1325,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) + } + ret = 0; /* ucsi_send_command() returns length on success */ + ++ if (ucsi->ops->connector_status) ++ ucsi->ops->connector_status(con); ++ + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + case UCSI_CONSTAT_PARTNER_TYPE_UFP: + case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP: +diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h +index 42c60eba5fb6..3d23b52cf5a9 100644 +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -15,6 +15,7 @@ + + struct ucsi; + struct ucsi_altmode; ++struct ucsi_connector; + struct dentry; + + /* UCSI offsets (Bytes) */ +@@ -52,6 +53,7 @@ struct dentry; + * @sync_write: Blocking write operation + * @async_write: Non-blocking write operation + * @update_altmodes: Squashes duplicate DP altmodes ++ * @connector_status: Updates connector status, called holding connector lock + * + * Read and write routines for UCSI interface. @sync_write must wait for the + * Command Completion Event from the PPM before returning, and @async_write must +@@ -66,6 +68,7 @@ struct ucsi_operations { + const void *val, size_t val_len); + bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, + struct ucsi_altmode *updated); ++ void (*connector_status)(struct ucsi_connector *con); + }; + + struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops); +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch b/queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch new file mode 100644 index 00000000000..7706e18b052 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-add-update_connector-callback.patch @@ -0,0 +1,62 @@ +From fcc56dec86949c2b7f814f2de8a1e702cefee01d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 07:49:56 +0300 +Subject: usb: typec: ucsi: add update_connector callback + +From: Dmitry Baryshkov + +[ Upstream commit 62866465196228917f233aea68de73be6cdb9fae ] + +Add a callback to allow glue drivers to update the connector before +registering corresponding power supply and Type-C port. In particular +this is useful if glue drivers want to touch the connector's Type-C +capabilities structure. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-4-d4b1cb22a33f@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports") +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi.c | 3 +++ + drivers/usb/typec/ucsi/ucsi.h | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c +index 3f7039a711c7..d6a3fd00c3a5 100644 +--- a/drivers/usb/typec/ucsi/ucsi.c ++++ b/drivers/usb/typec/ucsi/ucsi.c +@@ -1261,6 +1261,9 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) + cap->driver_data = con; + cap->ops = &ucsi_ops; + ++ if (ucsi->ops->update_connector) ++ ucsi->ops->update_connector(con); ++ + ret = ucsi_register_port_psy(con); + if (ret) + goto out; +diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h +index 3d23b52cf5a9..921ef0e115cf 100644 +--- a/drivers/usb/typec/ucsi/ucsi.h ++++ b/drivers/usb/typec/ucsi/ucsi.h +@@ -53,6 +53,7 @@ struct dentry; + * @sync_write: Blocking write operation + * @async_write: Non-blocking write operation + * @update_altmodes: Squashes duplicate DP altmodes ++ * @update_connector: Update connector capabilities before registering + * @connector_status: Updates connector status, called holding connector lock + * + * Read and write routines for UCSI interface. @sync_write must wait for the +@@ -68,6 +69,7 @@ struct ucsi_operations { + const void *val, size_t val_len); + bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, + struct ucsi_altmode *updated); ++ void (*update_connector)(struct ucsi_connector *con); + void (*connector_status)(struct ucsi_connector *con); + }; + +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch b/queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch new file mode 100644 index 00000000000..2ed79272483 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-glink-be-more-precise-on-orientation-.patch @@ -0,0 +1,52 @@ +From dd216decafb23ae9a0497b94d65914afdd7de392 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 9 Nov 2024 02:04:15 +0200 +Subject: usb: typec: ucsi: glink: be more precise on orientation-aware ports + +From: Dmitry Baryshkov + +[ Upstream commit de9df030ccb5d3e31ee0c715d74cd77c619748f8 ] + +Instead of checking if any of the USB-C ports have orientation GPIO and +thus is orientation-aware, check for the GPIO for the port being +registered. There are no boards that are affected by this change at this +moment, so the patch is not marked as a fix, but it might affect other +boards in future. + +Reviewed-by: Abel Vesa +Reviewed-by: Neil Armstrong +Reviewed-by: Johan Hovold +Tested-by: Johan Hovold +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20241109-ucsi-glue-fixes-v2-2-8b21ff4f9fbe@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index f6c3af5846e6..f0b4d0a4bb19 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -189,12 +189,12 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, + static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con) + { + struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); +- int i; + +- for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) { +- if (ucsi->port_orientation[i]) +- con->typec_cap.orientation_aware = true; +- } ++ if (con->num > PMIC_GLINK_MAX_PORTS || ++ !ucsi->port_orientation[con->num - 1]) ++ return; ++ ++ con->typec_cap.orientation_aware = true; + } + + static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch b/queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch new file mode 100644 index 00000000000..09238a19a0d --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-glink-fix-off-by-one-in-connector_sta.patch @@ -0,0 +1,44 @@ +From a133c18476098231cc3f082a93437920cc6dde7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 9 Nov 2024 02:04:14 +0200 +Subject: usb: typec: ucsi: glink: fix off-by-one in connector_status + +From: Dmitry Baryshkov + +[ Upstream commit 4a22918810980897393fa1776ea3877e4baf8cca ] + +UCSI connector's indices start from 1 up to 3, PMIC_GLINK_MAX_PORTS. +Correct the condition in the pmic_glink_ucsi_connector_status() +callback, fixing Type-C orientation reporting for the third USB-C +connector. + +Fixes: 76716fd5bf09 ("usb: typec: ucsi: glink: move GPIO reading into connector_status callback") +Cc: stable@vger.kernel.org +Reported-by: Abel Vesa +Reviewed-by: Neil Armstrong +Reviewed-by: Johan Hovold +Tested-by: Johan Hovold +Signed-off-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20241109-ucsi-glue-fixes-v2-1-8b21ff4f9fbe@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index f0b4d0a4bb19..82a1081d44f1 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -202,7 +202,7 @@ static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) + struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); + int orientation; + +- if (con->num >= PMIC_GLINK_MAX_PORTS || ++ if (con->num > PMIC_GLINK_MAX_PORTS || + !ucsi->port_orientation[con->num - 1]) + return; + +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch b/queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch new file mode 100644 index 00000000000..215068ae6ff --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-glink-move-gpio-reading-into-connecto.patch @@ -0,0 +1,109 @@ +From c05054d97d08da8259a5d3186d28823b5893db92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 07:49:54 +0300 +Subject: usb: typec: ucsi: glink: move GPIO reading into connector_status + callback + +From: Dmitry Baryshkov + +[ Upstream commit 76716fd5bf09725c2c6825264147f16c21e56853 ] + +To simplify the platform code move Type-C orientation handling into the +connector_status callback. As it is called both during connector +registration and on connector change events, duplicated code from +pmic_glink_ucsi_register() can be dropped. + +Also this moves operations that can sleep into a worker thread, +removing the only sleeping operation from pmic_glink_ucsi_notify(). + +Tested-by: Krishna Kurapati +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-2-d4b1cb22a33f@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports") +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 48 ++++++++++++----------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index 94f2df02f06e..4c9352cdd641 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -186,10 +186,28 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, + return ret; + } + ++static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) ++{ ++ struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); ++ int orientation; ++ ++ if (con->num >= PMIC_GLINK_MAX_PORTS || ++ !ucsi->port_orientation[con->num - 1]) ++ return; ++ ++ orientation = gpiod_get_value(ucsi->port_orientation[con->num - 1]); ++ if (orientation >= 0) { ++ typec_switch_set(ucsi->port_switch[con->num - 1], ++ orientation ? TYPEC_ORIENTATION_REVERSE ++ : TYPEC_ORIENTATION_NORMAL); ++ } ++} ++ + static const struct ucsi_operations pmic_glink_ucsi_ops = { + .read = pmic_glink_ucsi_read, + .sync_write = pmic_glink_ucsi_sync_write, +- .async_write = pmic_glink_ucsi_async_write ++ .async_write = pmic_glink_ucsi_async_write, ++ .connector_status = pmic_glink_ucsi_connector_status, + }; + + static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len) +@@ -228,20 +246,8 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + } + + con_num = UCSI_CCI_CONNECTOR(cci); +- if (con_num) { +- if (con_num <= PMIC_GLINK_MAX_PORTS && +- ucsi->port_orientation[con_num - 1]) { +- int orientation = gpiod_get_value(ucsi->port_orientation[con_num - 1]); +- +- if (orientation >= 0) { +- typec_switch_set(ucsi->port_switch[con_num - 1], +- orientation ? TYPEC_ORIENTATION_REVERSE +- : TYPEC_ORIENTATION_NORMAL); +- } +- } +- ++ if (con_num) + ucsi_connector_change(ucsi->ucsi, con_num); +- } + + if (ucsi->sync_pending && + (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) { +@@ -252,20 +258,6 @@ static void pmic_glink_ucsi_notify(struct work_struct *work) + static void pmic_glink_ucsi_register(struct work_struct *work) + { + struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work); +- int orientation; +- int i; +- +- for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) { +- if (!ucsi->port_orientation[i]) +- continue; +- orientation = gpiod_get_value(ucsi->port_orientation[i]); +- +- if (orientation >= 0) { +- typec_switch_set(ucsi->port_switch[i], +- orientation ? TYPEC_ORIENTATION_REVERSE +- : TYPEC_ORIENTATION_NORMAL); +- } +- } + + ucsi_register(ucsi->ucsi); + } +-- +2.39.5 + diff --git a/queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch b/queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch new file mode 100644 index 00000000000..95f3231c9b5 --- /dev/null +++ b/queue-6.6/usb-typec-ucsi-glink-set-orientation-aware-if-suppor.patch @@ -0,0 +1,56 @@ +From abc9a5d8ff267d55496034a70e7f0becbe2440f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Apr 2024 07:49:57 +0300 +Subject: usb: typec: ucsi: glink: set orientation aware if supported + +From: Dmitry Baryshkov + +[ Upstream commit 3d1b6c9d47707d6a0f80bb5db6473b1f107b5baf ] + +If the PMIC-GLINK device has orientation GPIOs declared, then it will +report connection orientation. In this case set the flag to mark +registered ports as orientation-aware. + +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240411-ucsi-orient-aware-v2-5-d4b1cb22a33f@linaro.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: de9df030ccb5 ("usb: typec: ucsi: glink: be more precise on orientation-aware ports") +Signed-off-by: Sasha Levin +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c +index 4c9352cdd641..f6c3af5846e6 100644 +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -186,6 +186,17 @@ static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset, + return ret; + } + ++static void pmic_glink_ucsi_update_connector(struct ucsi_connector *con) ++{ ++ struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); ++ int i; ++ ++ for (i = 0; i < PMIC_GLINK_MAX_PORTS; i++) { ++ if (ucsi->port_orientation[i]) ++ con->typec_cap.orientation_aware = true; ++ } ++} ++ + static void pmic_glink_ucsi_connector_status(struct ucsi_connector *con) + { + struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(con->ucsi); +@@ -207,6 +218,7 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = { + .read = pmic_glink_ucsi_read, + .sync_write = pmic_glink_ucsi_sync_write, + .async_write = pmic_glink_ucsi_async_write, ++ .update_connector = pmic_glink_ucsi_update_connector, + .connector_status = pmic_glink_ucsi_connector_status, + }; + +-- +2.39.5 + diff --git a/queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch b/queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch new file mode 100644 index 00000000000..7c025de2146 --- /dev/null +++ b/queue-6.6/usb-xhci-avoid-queuing-redundant-stop-endpoint-comma.patch @@ -0,0 +1,121 @@ +From 5491cfddbc5c9c312ad1b1002c58ca0dc8ea33be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 12:14:59 +0200 +Subject: usb: xhci: Avoid queuing redundant Stop Endpoint commands + +From: Michal Pecio + +[ Upstream commit 474538b8dd1cd9c666e56cfe8ef60fbb0fb513f4 ] + +Stop Endpoint command on an already stopped endpoint fails and may be +misinterpreted as a known hardware bug by the completion handler. This +results in an unnecessary delay with repeated retries of the command. + +Avoid queuing this command when endpoint state flags indicate that it's +stopped or halted and the command will fail. If commands are pending on +the endpoint, their completion handlers will process cancelled TDs so +it's done. In case of waiting for external operations like clearing TT +buffer, the endpoint is stopped and cancelled TDs can be processed now. + +This eliminates practically all unnecessary retries because an endpoint +with pending URBs is maintained in Running state by the driver, unless +aforementioned commands or other operations are pending on it. This is +guaranteed by xhci_ring_ep_doorbell() and by the fact that it is called +every time any of those operations completes. + +The only known exceptions are hardware bugs (the endpoint never starts +at all) and Stream Protocol errors not associated with any TRB, which +cause an endpoint reset not followed by restart. Sounds like a bug. + +Generally, these retries are only expected to happen when the endpoint +fails to start for unknown/no reason, which is a worse problem itself, +and fixing the bug eliminates the retries too. + +All cases were tested and found to work as expected. SET_DEQ_PENDING +was produced by patching uvcvideo to unlink URBs in 100us intervals, +which then runs into this case very often. EP_HALTED was produced by +restarting 'cat /dev/ttyUSB0' on a serial dongle with broken cable. +EP_CLEARING_TT by the same, with the dongle on an external hub. + +Fixes: fd9d55d190c0 ("xhci: retry Stop Endpoint on buggy NEC controllers") +CC: stable@vger.kernel.org +Signed-off-by: Michal Pecio +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20241106101459.775897-34-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-ring.c | 13 +++++++++++++ + drivers/usb/host/xhci.c | 19 +++++++++++++++---- + drivers/usb/host/xhci.h | 1 + + 3 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 729319d81753..0d628af5c3ba 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1092,6 +1092,19 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) + return 0; + } + ++/* ++ * Erase queued TDs from transfer ring(s) and give back those the xHC didn't ++ * stop on. If necessary, queue commands to move the xHC off cancelled TDs it ++ * stopped on. Those will be given back later when the commands complete. ++ * ++ * Call under xhci->lock on a stopped endpoint. ++ */ ++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep) ++{ ++ xhci_invalidate_cancelled_tds(ep); ++ xhci_giveback_invalidated_tds(ep); ++} ++ + /* + * Returns the TD the endpoint ring halted on. + * Only call for non-running rings without streams. +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 0b3688478ed3..70e6c240a540 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1738,10 +1738,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) + } + } + +- /* Queue a stop endpoint command, but only if this is +- * the first cancellation to be handled. +- */ +- if (!(ep->ep_state & EP_STOP_CMD_PENDING)) { ++ /* These completion handlers will sort out cancelled TDs for us */ ++ if (ep->ep_state & (EP_STOP_CMD_PENDING | EP_HALTED | SET_DEQ_PENDING)) { ++ xhci_dbg(xhci, "Not queuing Stop Endpoint on slot %d ep %d in state 0x%x\n", ++ urb->dev->slot_id, ep_index, ep->ep_state); ++ goto done; ++ } ++ ++ /* In this case no commands are pending but the endpoint is stopped */ ++ if (ep->ep_state & EP_CLEARING_TT) { ++ /* and cancelled TDs can be given back right away */ ++ xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n", ++ urb->dev->slot_id, ep_index, ep->ep_state); ++ xhci_process_cancelled_tds(ep); ++ } else { ++ /* Otherwise, queue a new Stop Endpoint command */ + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); + if (!command) { + ret = -ENOMEM; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index d89010ac5f8a..fddb3a90dae3 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1952,6 +1952,7 @@ void xhci_ring_doorbell_for_active_rings(struct xhci_hcd *xhci, + void xhci_cleanup_command_queue(struct xhci_hcd *xhci); + void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring); + unsigned int count_trbs(u64 addr, u64 len); ++void xhci_process_cancelled_tds(struct xhci_virt_ep *ep); + + /* xHCI roothub code */ + void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port, +-- +2.39.5 + diff --git a/queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch b/queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch new file mode 100644 index 00000000000..25d834eb0c9 --- /dev/null +++ b/queue-6.6/usb-xhci-limit-stop-endpoint-retries.patch @@ -0,0 +1,149 @@ +From 67f640fbd282d84cc56e34072d5e30b93771e62c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Nov 2024 12:14:57 +0200 +Subject: usb: xhci: Limit Stop Endpoint retries + +From: Michal Pecio + +[ Upstream commit 42b7581376015c1bbcbe5831f043cd0ac119d028 ] + +Some host controllers fail to atomically transition an endpoint to the +Running state on a doorbell ring and enter a hidden "Restarting" state, +which looks very much like Stopped, with the important difference that +it will spontaneously transition to Running anytime soon. + +A Stop Endpoint command queued in the Restarting state typically fails +with Context State Error and the completion handler sees the Endpoint +Context State as either still Stopped or already Running. Even a case +of Halted was observed, when an error occurred right after the restart. + +The Halted state is already recovered from by resetting the endpoint. +The Running state is handled by retrying Stop Endpoint. + +The Stopped state was recognized as a problem on NEC controllers and +worked around also by retrying, because the endpoint soon restarts and +then stops for good. But there is a risk: the command may fail if the +endpoint is "stopped for good" already, and retries will fail forever. + +The possibility of this was not realized at the time, but a number of +cases were discovered later and reproduced. Some proved difficult to +deal with, and it is outright impossible to predict if an endpoint may +fail to ever start at all due to a hardware bug. One such bug (albeit +on ASM3142, not on NEC) was found to be reliably triggered simply by +toggling an AX88179 NIC up/down in a tight loop for a few seconds. + +An endless retries storm is quite nasty. Besides putting needless load +on the xHC and CPU, it causes URBs never to be given back, paralyzing +the device and connection/disconnection logic for the whole bus if the +device is unplugged. User processes waiting for URBs become unkillable, +drivers and kworker threads lock up and xhci_hcd cannot be reloaded. + +For peace of mind, impose a timeout on Stop Endpoint retries in this +case. If they don't succeed in 100ms, consider the endpoint stopped +permanently for some reason and just give back the unlinked URBs. This +failure case is rare already and work is under way to make it rarer. + +Start this work today by also handling one simple case of race with +Reset Endpoint, because it costs just two lines to implement. + +Fixes: fd9d55d190c0 ("xhci: retry Stop Endpoint on buggy NEC controllers") +CC: stable@vger.kernel.org +Signed-off-by: Michal Pecio +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20241106101459.775897-32-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: e21ebe51af68 ("xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic") +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-ring.c | 28 ++++++++++++++++++++++++---- + drivers/usb/host/xhci.c | 2 ++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 27 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 7c3e39482834..d318310e3135 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -52,6 +52,7 @@ + * endpoint rings; it generates events on the event ring for these. + */ + ++#include + #include + #include + #include +@@ -1182,16 +1183,35 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + return; + case EP_STATE_STOPPED: + /* +- * NEC uPD720200 sometimes sets this state and fails with +- * Context Error while continuing to process TRBs. +- * Be conservative and trust EP_CTX_STATE on other chips. ++ * Per xHCI 4.6.9, Stop Endpoint command on a Stopped ++ * EP is a Context State Error, and EP stays Stopped. ++ * ++ * But maybe it failed on Halted, and somebody ran Reset ++ * Endpoint later. EP state is now Stopped and EP_HALTED ++ * still set because Reset EP handler will run after us. ++ */ ++ if (ep->ep_state & EP_HALTED) ++ break; ++ /* ++ * On some HCs EP state remains Stopped for some tens of ++ * us to a few ms or more after a doorbell ring, and any ++ * new Stop Endpoint fails without aborting the restart. ++ * This handler may run quickly enough to still see this ++ * Stopped state, but it will soon change to Running. ++ * ++ * Assume this bug on unexpected Stop Endpoint failures. ++ * Keep retrying until the EP starts and stops again, on ++ * chips where this is known to help. Wait for 100ms. + */ + if (!(xhci->quirks & XHCI_NEC_HOST)) + break; ++ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) ++ break; + fallthrough; + case EP_STATE_RUNNING: + /* Race, HW handled stop ep cmd before ep was running */ +- xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n"); ++ xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n", ++ GET_EP_CTX_STATE(ep_ctx)); + + command = xhci_alloc_command(xhci, false, GFP_ATOMIC); + if (!command) { +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 3bd70e6ad64b..0b3688478ed3 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -8,6 +8,7 @@ + * Some code borrowed from the Linux EHCI driver. + */ + ++#include + #include + #include + #include +@@ -1746,6 +1747,7 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) + ret = -ENOMEM; + goto done; + } ++ ep->stop_time = jiffies; + ep->ep_state |= EP_STOP_CMD_PENDING; + xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, + ep_index, 0); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 4bbd12db7239..d89010ac5f8a 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -717,6 +717,7 @@ struct xhci_virt_ep { + /* Bandwidth checking storage */ + struct xhci_bw_info bw_info; + struct list_head bw_endpoint_list; ++ unsigned long stop_time; + /* Isoch Frame ID checking storage */ + int next_frame_id; + /* Use new Isoch TRB layout needed for extended TBC support */ +-- +2.39.5 + diff --git a/queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch b/queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch new file mode 100644 index 00000000000..3d8bc5016a8 --- /dev/null +++ b/queue-6.6/watchdog-rzg2l_wdt-power-on-the-watchdog-domain-in-t.patch @@ -0,0 +1,103 @@ +From a9767f47e1c2bfcdfe37d9cfc8888f4f619e2efd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Oct 2024 19:47:32 +0300 +Subject: watchdog: rzg2l_wdt: Power on the watchdog domain in the restart + handler + +From: Claudiu Beznea + +[ Upstream commit bad201b2ac4e238c6d4b6966a220240e3861640c ] + +On RZ/G3S the watchdog can be part of a software-controlled PM domain. In +this case, the watchdog device need to be powered on in +struct watchdog_ops::restart API. This can be done though +pm_runtime_resume_and_get() API if the watchdog PM domain and watchdog +device are marked as IRQ safe. We mark the watchdog PM domain as IRQ safe +with GENPD_FLAG_IRQ_SAFE when the watchdog PM domain is registered and the +watchdog device though pm_runtime_irq_safe(). + +Before commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait +context'") pm_runtime_get_sync() was used in watchdog restart handler +(which is similar to pm_runtime_resume_and_get() except the later one +handles the runtime resume errors). + +Commit e4cf89596c1f ("watchdog: rzg2l_wdt: Fix 'BUG: Invalid wait +context'") dropped the pm_runtime_get_sync() and replaced it with +clk_prepare_enable() to avoid invalid wait context due to genpd_lock() +in genpd_runtime_resume() being called from atomic context. But +clk_prepare_enable() doesn't fit for this either (as reported by +Ulf Hansson) as clk_prepare() can also sleep (it just not throw invalid +wait context warning as it is not written for this). + +Because the watchdog device is marked now as IRQ safe (though this patch) +the irq_safe_dev_in_sleep_domain() call from genpd_runtime_resume() returns +1 for devices not registering an IRQ safe PM domain for watchdog (as the +watchdog device is IRQ safe, PM domain is not and watchdog PM domain is +always-on), this being the case for RZ/G3S with old device trees and +the rest of the SoCs that use this driver, we can now drop also the +clk_prepare_enable() calls in restart handler and rely on +pm_runtime_resume_and_get(). + +Thus, drop clk_prepare_enable() and use pm_runtime_resume_and_get() in +watchdog restart handler. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Ulf Hansson +Reviewed-by: Geert Uytterhoeven +Acked-by: Guenter Roeck +Link: https://lore.kernel.org/r/20241015164732.4085249-5-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/rzg2l_wdt.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c +index d09f938415fc..525a72d8d746 100644 +--- a/drivers/watchdog/rzg2l_wdt.c ++++ b/drivers/watchdog/rzg2l_wdt.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -166,8 +167,22 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + int ret; + +- clk_prepare_enable(priv->pclk); +- clk_prepare_enable(priv->osc_clk); ++ /* ++ * In case of RZ/G3S the watchdog device may be part of an IRQ safe power ++ * domain that is currently powered off. In this case we need to power ++ * it on before accessing registers. Along with this the clocks will be ++ * enabled. We don't undo the pm_runtime_resume_and_get() as the device ++ * need to be on for the reboot to happen. ++ * ++ * For the rest of SoCs not registering a watchdog IRQ safe power ++ * domain it is safe to call pm_runtime_resume_and_get() as the ++ * irq_safe_dev_in_sleep_domain() call in genpd_runtime_resume() ++ * returns non zero value and the genpd_lock() is avoided, thus, there ++ * will be no invalid wait context reported by lockdep. ++ */ ++ ret = pm_runtime_resume_and_get(wdev->parent); ++ if (ret) ++ return ret; + + if (priv->devtype == WDT_RZG2L) { + ret = reset_control_deassert(priv->rstc); +@@ -275,6 +290,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + + priv->devtype = (uintptr_t)of_device_get_match_data(dev); + ++ pm_runtime_irq_safe(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + priv->wdev.info = &rzg2l_wdt_ident; +-- +2.39.5 + diff --git a/queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch b/queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch new file mode 100644 index 00000000000..a73a50eaa67 --- /dev/null +++ b/queue-6.6/watchdog-rzg2l_wdt-rely-on-the-reset-driver-for-doin.patch @@ -0,0 +1,118 @@ +From 38d9e40d3b0bd69c9e889090edd9960e5930ca34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 09:57:21 +0300 +Subject: watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset + +From: Claudiu Beznea + +[ Upstream commit d8997ed79ed7c7c32b2ae571e0d99a58bbfd01fe ] + +The reset driver has been adapted in commit da235d2fac21 +("clk: renesas: rzg2l: Check reset monitor registers") to check the reset +monitor bits before declaring reset asserts/de-asserts as +successful/failure operations. With that, there is no need to keep the +reset workaround for RZ/V2M in place in the watchdog driver. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Philipp Zabel +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20240531065723.1085423-8-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Stable-dep-of: bad201b2ac4e ("watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler") +Signed-off-by: Sasha Levin +--- + drivers/watchdog/rzg2l_wdt.c | 39 ++++-------------------------------- + 1 file changed, 4 insertions(+), 35 deletions(-) + +diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c +index 7aad66da138a..d09f938415fc 100644 +--- a/drivers/watchdog/rzg2l_wdt.c ++++ b/drivers/watchdog/rzg2l_wdt.c +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -54,35 +53,11 @@ struct rzg2l_wdt_priv { + struct reset_control *rstc; + unsigned long osc_clk_rate; + unsigned long delay; +- unsigned long minimum_assertion_period; + struct clk *pclk; + struct clk *osc_clk; + enum rz_wdt_type devtype; + }; + +-static int rzg2l_wdt_reset(struct rzg2l_wdt_priv *priv) +-{ +- int err, status; +- +- if (priv->devtype == WDT_RZV2M) { +- /* WDT needs TYPE-B reset control */ +- err = reset_control_assert(priv->rstc); +- if (err) +- return err; +- ndelay(priv->minimum_assertion_period); +- err = reset_control_deassert(priv->rstc); +- if (err) +- return err; +- err = read_poll_timeout(reset_control_status, status, +- status != 1, 0, 1000, false, +- priv->rstc); +- } else { +- err = reset_control_reset(priv->rstc); +- } +- +- return err; +-} +- + static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv) + { + /* delay timer when change the setting register */ +@@ -189,13 +164,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + unsigned long action, void *data) + { + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); ++ int ret; + + clk_prepare_enable(priv->pclk); + clk_prepare_enable(priv->osc_clk); + + if (priv->devtype == WDT_RZG2L) { +- int ret; +- + ret = reset_control_deassert(priv->rstc); + if (ret) + return ret; +@@ -207,7 +181,9 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + rzg2l_wdt_write(priv, PEEN_FORCE, PEEN); + } else { + /* RZ/V2M doesn't have parity error registers */ +- rzg2l_wdt_reset(priv); ++ ret = reset_control_reset(priv->rstc); ++ if (ret) ++ return ret; + + wdev->timeout = 0; + +@@ -299,13 +275,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + + priv->devtype = (uintptr_t)of_device_get_match_data(dev); + +- if (priv->devtype == WDT_RZV2M) { +- priv->minimum_assertion_period = RZV2M_A_NSEC + +- 3 * F2CYCLE_NSEC(pclk_rate) + 5 * +- max(F2CYCLE_NSEC(priv->osc_clk_rate), +- F2CYCLE_NSEC(pclk_rate)); +- } +- + pm_runtime_enable(&pdev->dev); + + priv->wdev.info = &rzg2l_wdt_ident; +-- +2.39.5 + diff --git a/queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch b/queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch new file mode 100644 index 00000000000..4ae690979a2 --- /dev/null +++ b/queue-6.6/watchdog-rzg2l_wdt-remove-reset-de-assert-from-probe.patch @@ -0,0 +1,110 @@ +From 0f600398be367bf7b70f62c7c7792b35fa4762c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 May 2024 09:57:19 +0300 +Subject: watchdog: rzg2l_wdt: Remove reset de-assert from probe + +From: Claudiu Beznea + +[ Upstream commit 064319c3fac88e04f53f3460cd24ae90de2d9fb6 ] + +There is no need to de-assert the reset signal on probe as the watchdog +is not used prior executing start. Also, the clocks are not enabled in +probe (pm_runtime_enable() doesn't do that), thus this is another indicator +that the watchdog wasn't used previously like this. Instead, keep the +watchdog hardware in its previous state at probe (by default it is in +reset state), enable it when it is started and move it to reset state +when it is stopped. This saves some extra power when the watchdog is +unused. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20240531065723.1085423-6-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Stable-dep-of: bad201b2ac4e ("watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler") +Signed-off-by: Sasha Levin +--- + drivers/watchdog/rzg2l_wdt.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c +index 7bce093316c4..7aad66da138a 100644 +--- a/drivers/watchdog/rzg2l_wdt.c ++++ b/drivers/watchdog/rzg2l_wdt.c +@@ -129,6 +129,12 @@ static int rzg2l_wdt_start(struct watchdog_device *wdev) + if (ret) + return ret; + ++ ret = reset_control_deassert(priv->rstc); ++ if (ret) { ++ pm_runtime_put(wdev->parent); ++ return ret; ++ } ++ + /* Initialize time out */ + rzg2l_wdt_init_timeout(wdev); + +@@ -146,7 +152,9 @@ static int rzg2l_wdt_stop(struct watchdog_device *wdev) + struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + int ret; + +- rzg2l_wdt_reset(priv); ++ ret = reset_control_assert(priv->rstc); ++ if (ret) ++ return ret; + + ret = pm_runtime_put(wdev->parent); + if (ret < 0) +@@ -186,6 +194,12 @@ static int rzg2l_wdt_restart(struct watchdog_device *wdev, + clk_prepare_enable(priv->osc_clk); + + if (priv->devtype == WDT_RZG2L) { ++ int ret; ++ ++ ret = reset_control_deassert(priv->rstc); ++ if (ret) ++ return ret; ++ + /* Generate Reset (WDTRSTB) Signal on parity error */ + rzg2l_wdt_write(priv, 0, PECR); + +@@ -236,13 +250,11 @@ static const struct watchdog_ops rzg2l_wdt_ops = { + .restart = rzg2l_wdt_restart, + }; + +-static void rzg2l_wdt_reset_assert_pm_disable(void *data) ++static void rzg2l_wdt_pm_disable(void *data) + { + struct watchdog_device *wdev = data; +- struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev); + + pm_runtime_disable(wdev->parent); +- reset_control_assert(priv->rstc); + } + + static int rzg2l_wdt_probe(struct platform_device *pdev) +@@ -285,10 +297,6 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc), + "failed to get cpg reset"); + +- ret = reset_control_deassert(priv->rstc); +- if (ret) +- return dev_err_probe(dev, ret, "failed to deassert"); +- + priv->devtype = (uintptr_t)of_device_get_match_data(dev); + + if (priv->devtype == WDT_RZV2M) { +@@ -309,9 +317,7 @@ static int rzg2l_wdt_probe(struct platform_device *pdev) + priv->wdev.timeout = WDT_DEFAULT_TIMEOUT; + + watchdog_set_drvdata(&priv->wdev, priv); +- ret = devm_add_action_or_reset(&pdev->dev, +- rzg2l_wdt_reset_assert_pm_disable, +- &priv->wdev); ++ ret = devm_add_action_or_reset(&pdev->dev, rzg2l_wdt_pm_disable, &priv->wdev); + if (ret < 0) + return ret; + +-- +2.39.5 + diff --git a/queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch b/queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch new file mode 100644 index 00000000000..50f31e560f7 --- /dev/null +++ b/queue-6.6/watchdog-s3c2410_wdt-use-exynos_get_pmu_regmap_by_ph.patch @@ -0,0 +1,73 @@ +From d9b6d9fd215637faecdb7f5ef92865a6a76ca509 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Feb 2024 22:06:13 +0000 +Subject: watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU + regs + +From: Peter Griffin + +[ Upstream commit 746f0770f916e6c48e422d6a34e67eae16707f0e ] + +Obtain the PMU regmap using the new API added to exynos-pmu driver rather +than syscon_regmap_lookup_by_phandle(). As this driver no longer depends +on mfd syscon remove that header and Kconfig dependency. + +Tested-by: Alexey Klimov +Tested-by: Sam Protsenko +Acked-by: Guenter Roeck +Reviewed-by: Sam Protsenko +Signed-off-by: Peter Griffin +Link: https://lore.kernel.org/r/20240220220613.797068-3-peter.griffin@linaro.org +Signed-off-by: Krzysztof Kozlowski +Stable-dep-of: ccfb765944bb ("Revert "watchdog: s3c2410_wdt: use exynos_get_pmu_regmap_by_phandle() for PMU regs"") +Signed-off-by: Sasha Levin +--- + drivers/watchdog/Kconfig | 1 - + drivers/watchdog/s3c2410_wdt.c | 8 ++++---- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +index 751458959411..4ecf701abe5f 100644 +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -512,7 +512,6 @@ config S3C2410_WATCHDOG + tristate "S3C6410/S5Pv210/Exynos Watchdog" + depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST + select WATCHDOG_CORE +- select MFD_SYSCON if ARCH_EXYNOS + help + Watchdog timer block in the Samsung S3C64xx, S5Pv210 and Exynos + SoCs. This will reboot the system when the timer expires with +diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c +index 0b4bd883ff28..0c9c649583d4 100644 +--- a/drivers/watchdog/s3c2410_wdt.c ++++ b/drivers/watchdog/s3c2410_wdt.c +@@ -23,9 +23,9 @@ + #include + #include + #include +-#include + #include + #include ++#include + + #define S3C2410_WTCON 0x00 + #define S3C2410_WTDAT 0x04 +@@ -640,11 +640,11 @@ static int s3c2410wdt_probe(struct platform_device *pdev) + return ret; + + if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { +- wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, +- "samsung,syscon-phandle"); ++ wdt->pmureg = exynos_get_pmu_regmap_by_phandle(dev->of_node, ++ "samsung,syscon-phandle"); + if (IS_ERR(wdt->pmureg)) + return dev_err_probe(dev, PTR_ERR(wdt->pmureg), +- "syscon regmap lookup failed.\n"); ++ "PMU regmap lookup failed.\n"); + } + + wdt_irq = platform_get_irq(pdev, 0); +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch b/queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch new file mode 100644 index 00000000000..deb58be8f14 --- /dev/null +++ b/queue-6.6/wifi-ath10k-avoid-null-pointer-error-during-sdio-rem.patch @@ -0,0 +1,105 @@ +From 8b0ef76c817997bbc0ba67255cb520002b8f3490 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 10:22:46 +0800 +Subject: wifi: ath10k: avoid NULL pointer error during sdio remove +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kang Yang + +[ Upstream commit 95c38953cb1ecf40399a676a1f85dfe2b5780a9a ] + +When running 'rmmod ath10k', ath10k_sdio_remove() will free sdio +workqueue by destroy_workqueue(). But if CONFIG_INIT_ON_FREE_DEFAULT_ON +is set to yes, kernel panic will happen: +Call trace: + destroy_workqueue+0x1c/0x258 + ath10k_sdio_remove+0x84/0x94 + sdio_bus_remove+0x50/0x16c + device_release_driver_internal+0x188/0x25c + device_driver_detach+0x20/0x2c + +This is because during 'rmmod ath10k', ath10k_sdio_remove() will call +ath10k_core_destroy() before destroy_workqueue(). wiphy_dev_release() +will finally be called in ath10k_core_destroy(). This function will free +struct cfg80211_registered_device *rdev and all its members, including +wiphy, dev and the pointer of sdio workqueue. Then the pointer of sdio +workqueue will be set to NULL due to CONFIG_INIT_ON_FREE_DEFAULT_ON. + +After device release, destroy_workqueue() will use NULL pointer then the +kernel panic happen. + +Call trace: +ath10k_sdio_remove + ->ath10k_core_unregister + …… + ->ath10k_core_stop + ->ath10k_hif_stop + ->ath10k_sdio_irq_disable + ->ath10k_hif_power_down + ->del_timer_sync(&ar_sdio->sleep_timer) + ->ath10k_core_destroy + ->ath10k_mac_destroy + ->ieee80211_free_hw + ->wiphy_free + …… + ->wiphy_dev_release + ->destroy_workqueue + +Need to call destroy_workqueue() before ath10k_core_destroy(), free +the work queue buffer first and then free pointer of work queue by +ath10k_core_destroy(). This order matches the error path order in +ath10k_sdio_probe(). + +No work will be queued on sdio workqueue between it is destroyed and +ath10k_core_destroy() is called. Based on the call_stack above, the +reason is: +Only ath10k_sdio_sleep_timer_handler(), ath10k_sdio_hif_tx_sg() and +ath10k_sdio_irq_disable() will queue work on sdio workqueue. +Sleep timer will be deleted before ath10k_core_destroy() in +ath10k_hif_power_down(). +ath10k_sdio_irq_disable() only be called in ath10k_hif_stop(). +ath10k_core_unregister() will call ath10k_hif_power_down() to stop hif +bus, so ath10k_sdio_hif_tx_sg() won't be called anymore. + +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189 + +Signed-off-by: Kang Yang +Tested-by: David Ruth +Reviewed-by: David Ruth +Link: https://patch.msgid.link/20241008022246.1010-1-quic_kangyang@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/sdio.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c +index 0ab5433f6cf6..850d999615a2 100644 +--- a/drivers/net/wireless/ath/ath10k/sdio.c ++++ b/drivers/net/wireless/ath/ath10k/sdio.c +@@ -3,7 +3,7 @@ + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl +- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +@@ -2648,9 +2648,9 @@ static void ath10k_sdio_remove(struct sdio_func *func) + + netif_napi_del(&ar->napi); + +- ath10k_core_destroy(ar); +- + destroy_workqueue(ar_sdio->workqueue); ++ ++ ath10k_core_destroy(ar); + } + + static const struct sdio_device_id ath10k_sdio_devices[] = { +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch b/queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch new file mode 100644 index 00000000000..b383d8dcfcc --- /dev/null +++ b/queue-6.6/wifi-ath10k-update-qualcomm-innovation-center-inc.-c.patch @@ -0,0 +1,387 @@ +From 40147aa9c89b1046acb61a78cf1c07a022669b75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 13:39:28 +0200 +Subject: wifi: ath10k: Update Qualcomm Innovation Center, Inc. copyrights + +From: Jeff Johnson + +[ Upstream commit b1dc0ba41431147e55407140962c76f3e7a06753 ] + +Update the copyright for all ath10k files modified on behalf of +Qualcomm Innovation Center, Inc. in 2021 through 2023. + +Signed-off-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231128-ath12kcopyrights-v1-3-be0b7408cbac@quicinc.com +Stable-dep-of: 95c38953cb1e ("wifi: ath10k: avoid NULL pointer error during sdio remove") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/bmi.c | 1 + + drivers/net/wireless/ath/ath10k/ce.c | 1 + + drivers/net/wireless/ath/ath10k/core.c | 1 + + drivers/net/wireless/ath/ath10k/core.h | 1 + + drivers/net/wireless/ath/ath10k/coredump.c | 1 + + drivers/net/wireless/ath/ath10k/coredump.h | 1 + + drivers/net/wireless/ath/ath10k/debug.c | 1 + + drivers/net/wireless/ath/ath10k/debugfs_sta.c | 1 + + drivers/net/wireless/ath/ath10k/htc.c | 1 + + drivers/net/wireless/ath/ath10k/htt.h | 1 + + drivers/net/wireless/ath/ath10k/htt_rx.c | 1 + + drivers/net/wireless/ath/ath10k/htt_tx.c | 1 + + drivers/net/wireless/ath/ath10k/hw.c | 1 + + drivers/net/wireless/ath/ath10k/hw.h | 1 + + drivers/net/wireless/ath/ath10k/mac.c | 1 + + drivers/net/wireless/ath/ath10k/pci.c | 1 + + drivers/net/wireless/ath/ath10k/pci.h | 1 + + drivers/net/wireless/ath/ath10k/qmi.c | 1 + + drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c | 1 + + drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h | 1 + + drivers/net/wireless/ath/ath10k/rx_desc.h | 1 + + drivers/net/wireless/ath/ath10k/sdio.c | 1 + + drivers/net/wireless/ath/ath10k/thermal.c | 1 + + drivers/net/wireless/ath/ath10k/usb.h | 1 + + drivers/net/wireless/ath/ath10k/wmi-tlv.h | 1 + + drivers/net/wireless/ath/ath10k/wmi.c | 1 + + drivers/net/wireless/ath/ath10k/wmi.h | 1 + + drivers/net/wireless/ath/ath10k/wow.c | 1 + + 28 files changed, 28 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c +index af6546572df2..9a4f8e815412 100644 +--- a/drivers/net/wireless/ath/ath10k/bmi.c ++++ b/drivers/net/wireless/ath/ath10k/bmi.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "bmi.h" +diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c +index c27b8204718a..afae4a8027f8 100644 +--- a/drivers/net/wireless/ath/ath10k/ce.c ++++ b/drivers/net/wireless/ath/ath10k/ce.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "hif.h" +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 81058be3598f..c3a8b3496be2 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 4b5239de4018..cb2359d2ee0b 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _CORE_H_ +diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c +index 2d1634a890dd..bb3a276b7ed5 100644 +--- a/drivers/net/wireless/ath/ath10k/coredump.c ++++ b/drivers/net/wireless/ath/ath10k/coredump.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "coredump.h" +diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h +index 437b9759f05d..e5ef0352e319 100644 +--- a/drivers/net/wireless/ath/ath10k/coredump.h ++++ b/drivers/net/wireless/ath/ath10k/coredump.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: ISC */ + /* + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _COREDUMP_H_ +diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c +index fe89bc61e531..92ad0a04bcc7 100644 +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c +index 5598cf706daa..0f6de862c3a9 100644 +--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c +index 5bfeecb95fca..a6e21ce90bad 100644 +--- a/drivers/net/wireless/ath/ath10k/htc.c ++++ b/drivers/net/wireless/ath/ath10k/htc.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h +index 7b24297146e7..52f6dc6b81c5 100644 +--- a/drivers/net/wireless/ath/ath10k/htt.h ++++ b/drivers/net/wireless/ath/ath10k/htt.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _HTT_H_ +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 438b0caaceb7..51855f23ea26 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "core.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c +index bd603feb7953..60425d22d707 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_tx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c +index 6d32b43a4da6..8fafe096adff 100644 +--- a/drivers/net/wireless/ath/ath10k/hw.c ++++ b/drivers/net/wireless/ath/ath10k/hw.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h +index 7ecdd0011cfa..afd336282615 100644 +--- a/drivers/net/wireless/ath/ath10k/hw.h ++++ b/drivers/net/wireless/ath/ath10k/hw.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _HW_H_ +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index d5e6e11f630b..655fb5cdf01f 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "mac.h" +diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c +index 23f366221939..aaa240f3c08a 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h +index 480cd97ab739..27bb4cf2dfea 100644 +--- a/drivers/net/wireless/ath/ath10k/pci.h ++++ b/drivers/net/wireless/ath/ath10k/pci.h +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _PCI_H_ +diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c +index 52c1a3de8da6..38e939f572a9 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi.c ++++ b/drivers/net/wireless/ath/ath10k/qmi.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c +index 1c81e454f943..0e85c75d2278 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c ++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h +index f0db991408dc..9f311f3bc9e7 100644 +--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h ++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: ISC */ + /* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef WCN3990_QMI_SVC_V01_H +diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h +index 777e53aa69dc..564293df1e9a 100644 +--- a/drivers/net/wireless/ath/ath10k/rx_desc.h ++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _RX_DESC_H_ +diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c +index 56fbcfb80bf8..0ab5433f6cf6 100644 +--- a/drivers/net/wireless/ath/ath10k/sdio.c ++++ b/drivers/net/wireless/ath/ath10k/sdio.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl ++ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c +index cefd97323dfe..31c8d7fbb095 100644 +--- a/drivers/net/wireless/ath/ath10k/thermal.c ++++ b/drivers/net/wireless/ath/ath10k/thermal.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2014-2015 Qualcomm Atheros, Inc. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/usb.h b/drivers/net/wireless/ath/ath10k/usb.h +index 48e066ba8162..7e4cfbb673c9 100644 +--- a/drivers/net/wireless/ath/ath10k/usb.h ++++ b/drivers/net/wireless/ath/ath10k/usb.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _USB_H_ +diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h +index dbb48d70f2e9..83a8f07a687f 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + #ifndef _WMI_TLV_H + #define _WMI_TLV_H +diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c +index 1c21dbde77b8..818aea99f85e 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include +diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h +index b112e8826093..9146df98fcee 100644 +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -3,6 +3,7 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #ifndef _WMI_H_ +diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c +index 20b9aa8ddf7d..aa7b2e703f3d 100644 +--- a/drivers/net/wireless/ath/ath10k/wow.c ++++ b/drivers/net/wireless/ath/ath10k/wow.c +@@ -2,6 +2,7 @@ + /* + * Copyright (c) 2015-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + + #include "mac.h" +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch b/queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch new file mode 100644 index 00000000000..791fb097d3d --- /dev/null +++ b/queue-6.6/wifi-ath12k-fix-atomic-calls-in-ath12k_mac_op_set_bi.patch @@ -0,0 +1,171 @@ +From fe1b88e14cac1f0244b4f33cbd20708a157bab7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2024 19:59:27 +0300 +Subject: wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask() + +From: Kalle Valo + +[ Upstream commit 8fac3266c68a8e647240b8ac8d0b82f1821edf85 ] + +When I try to manually set bitrates: + +iw wlan0 set bitrates legacy-2.4 1 + +I get sleeping from invalid context error, see below. Fix that by switching to +use recently introduced ieee80211_iterate_stations_mtx(). + +Do note that WCN6855 firmware is still crashing, I'm not sure if that firmware +even supports bitrate WMI commands and should we consider disabling +ath12k_mac_op_set_bitrate_mask() for WCN6855? But that's for another patch. + +BUG: sleeping function called from invalid context at drivers/net/wireless/ath/ath12k/wmi.c:420 +in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 2236, name: iw +preempt_count: 0, expected: 0 +RCU nest depth: 1, expected: 0 +3 locks held by iw/2236: + #0: ffffffffabc6f1d8 (cb_lock){++++}-{3:3}, at: genl_rcv+0x14/0x40 + #1: ffff888138410810 (&rdev->wiphy.mtx){+.+.}-{3:3}, at: nl80211_pre_doit+0x54d/0x800 [cfg80211] + #2: ffffffffab2cfaa0 (rcu_read_lock){....}-{1:2}, at: ieee80211_iterate_stations_atomic+0x2f/0x200 [mac80211] +CPU: 3 UID: 0 PID: 2236 Comm: iw Not tainted 6.11.0-rc7-wt-ath+ #1772 +Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021 +Call Trace: + + dump_stack_lvl+0xa4/0xe0 + dump_stack+0x10/0x20 + __might_resched+0x363/0x5a0 + ? __alloc_skb+0x165/0x340 + __might_sleep+0xad/0x160 + ath12k_wmi_cmd_send+0xb1/0x3d0 [ath12k] + ? ath12k_wmi_init_wcn7850+0xa40/0xa40 [ath12k] + ? __netdev_alloc_skb+0x45/0x7b0 + ? __asan_memset+0x39/0x40 + ? ath12k_wmi_alloc_skb+0xf0/0x150 [ath12k] + ? reacquire_held_locks+0x4d0/0x4d0 + ath12k_wmi_set_peer_param+0x340/0x5b0 [ath12k] + ath12k_mac_disable_peer_fixed_rate+0xa3/0x110 [ath12k] + ? ath12k_mac_vdev_stop+0x4f0/0x4f0 [ath12k] + ieee80211_iterate_stations_atomic+0xd4/0x200 [mac80211] + ath12k_mac_op_set_bitrate_mask+0x5d2/0x1080 [ath12k] + ? ath12k_mac_vif_chan+0x320/0x320 [ath12k] + drv_set_bitrate_mask+0x267/0x470 [mac80211] + ieee80211_set_bitrate_mask+0x4cc/0x8a0 [mac80211] + ? __this_cpu_preempt_check+0x13/0x20 + nl80211_set_tx_bitrate_mask+0x2bc/0x530 [cfg80211] + ? nl80211_parse_tx_bitrate_mask+0x2320/0x2320 [cfg80211] + ? trace_contention_end+0xef/0x140 + ? rtnl_unlock+0x9/0x10 + ? nl80211_pre_doit+0x557/0x800 [cfg80211] + genl_family_rcv_msg_doit+0x1f0/0x2e0 + ? genl_family_rcv_msg_attrs_parse.isra.0+0x250/0x250 + ? ns_capable+0x57/0xd0 + genl_family_rcv_msg+0x34c/0x600 + ? genl_family_rcv_msg_dumpit+0x310/0x310 + ? __lock_acquire+0xc62/0x1de0 + ? he_set_mcs_mask.isra.0+0x8d0/0x8d0 [cfg80211] + ? nl80211_parse_tx_bitrate_mask+0x2320/0x2320 [cfg80211] + ? cfg80211_external_auth_request+0x690/0x690 [cfg80211] + genl_rcv_msg+0xa0/0x130 + netlink_rcv_skb+0x14c/0x400 + ? genl_family_rcv_msg+0x600/0x600 + ? netlink_ack+0xd70/0xd70 + ? rwsem_optimistic_spin+0x4f0/0x4f0 + ? genl_rcv+0x14/0x40 + ? down_read_killable+0x580/0x580 + ? netlink_deliver_tap+0x13e/0x350 + ? __this_cpu_preempt_check+0x13/0x20 + genl_rcv+0x23/0x40 + netlink_unicast+0x45e/0x790 + ? netlink_attachskb+0x7f0/0x7f0 + netlink_sendmsg+0x7eb/0xdb0 + ? netlink_unicast+0x790/0x790 + ? __this_cpu_preempt_check+0x13/0x20 + ? selinux_socket_sendmsg+0x31/0x40 + ? netlink_unicast+0x790/0x790 + __sock_sendmsg+0xc9/0x160 + ____sys_sendmsg+0x620/0x990 + ? kernel_sendmsg+0x30/0x30 + ? __copy_msghdr+0x410/0x410 + ? __kasan_check_read+0x11/0x20 + ? mark_lock+0xe6/0x1470 + ___sys_sendmsg+0xe9/0x170 + ? copy_msghdr_from_user+0x120/0x120 + ? __lock_acquire+0xc62/0x1de0 + ? do_fault_around+0x2c6/0x4e0 + ? do_user_addr_fault+0x8c1/0xde0 + ? reacquire_held_locks+0x220/0x4d0 + ? do_user_addr_fault+0x8c1/0xde0 + ? __kasan_check_read+0x11/0x20 + ? __fdget+0x4e/0x1d0 + ? sockfd_lookup_light+0x1a/0x170 + __sys_sendmsg+0xd2/0x180 + ? __sys_sendmsg_sock+0x20/0x20 + ? reacquire_held_locks+0x4d0/0x4d0 + ? debug_smp_processor_id+0x17/0x20 + __x64_sys_sendmsg+0x72/0xb0 + ? lockdep_hardirqs_on+0x7d/0x100 + x64_sys_call+0x894/0x9f0 + do_syscall_64+0x64/0x130 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 +RIP: 0033:0x7f230fe04807 +Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 89 54 24 1c 48 89 74 24 10 +RSP: 002b:00007ffe996a7ea8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000556f9f9c3390 RCX: 00007f230fe04807 +RDX: 0000000000000000 RSI: 00007ffe996a7ee0 RDI: 0000000000000003 +RBP: 0000556f9f9c88c0 R08: 0000000000000002 R09: 0000000000000000 +R10: 0000556f965ca190 R11: 0000000000000246 R12: 0000556f9f9c8780 +R13: 00007ffe996a7ee0 R14: 0000556f9f9c87d0 R15: 0000556f9f9c88c0 + + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/20241007165932.78081-2-kvalo@kernel.org +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index e4b8c45898d2..713899735ccc 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -6676,9 +6676,9 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + arvif->vdev_id, ret); + return ret; + } +- ieee80211_iterate_stations_atomic(hw, +- ath12k_mac_disable_peer_fixed_rate, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_disable_peer_fixed_rate, ++ arvif); + } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask, + &single_nss)) { + rate = WMI_FIXED_RATE_NONE; +@@ -6722,16 +6722,16 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + return -EINVAL; + } + +- ieee80211_iterate_stations_atomic(hw, +- ath12k_mac_disable_peer_fixed_rate, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_disable_peer_fixed_rate, ++ arvif); + + mutex_lock(&ar->conf_mutex); + + arvif->bitrate_mask = *mask; +- ieee80211_iterate_stations_atomic(hw, +- ath12k_mac_set_bitrate_mask_iter, +- arvif); ++ ieee80211_iterate_stations_mtx(hw, ++ ath12k_mac_set_bitrate_mask_iter, ++ arvif); + + mutex_unlock(&ar->conf_mutex); + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch b/queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch new file mode 100644 index 00000000000..164c667c713 --- /dev/null +++ b/queue-6.6/wifi-ath12k-optimize-the-mac80211-hw-data-access.patch @@ -0,0 +1,123 @@ +From a28acaad2f30e25e035925efd0472f3cb62d7c9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Nov 2023 05:28:11 +0530 +Subject: wifi: ath12k: Optimize the mac80211 hw data access + +From: Karthikeyan Periyasamy + +[ Upstream commit 842addae02089fce4731be1c8d7d539449d4d009 ] + +Currently mac80211 hw data is accessed by convert the hw to radio (ar) +structure and then radio to hw structure which is not necessary in some +places where mac80211 hw data is already present. So in that kind of +places avoid the conversion and directly access the mac80211 hw data. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Karthikeyan Periyasamy +Acked-by: Jeff Johnson +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20231120235812.2602198-2-quic_periyasa@quicinc.com +Stable-dep-of: 8fac3266c68a ("wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 14 +++++++------- + drivers/net/wireless/ath/ath12k/reg.c | 6 +++--- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index f90191a290c2..e4b8c45898d2 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -4945,7 +4945,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, + if (ret) { + ath12k_warn(ar->ab, "failed to queue management frame %d\n", + ret); +- ieee80211_free_txskb(ar->hw, skb); ++ ieee80211_free_txskb(hw, skb); + } + return; + } +@@ -4953,7 +4953,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw, + ret = ath12k_dp_tx(ar, arvif, skb); + if (ret) { + ath12k_warn(ar->ab, "failed to transmit frame %d\n", ret); +- ieee80211_free_txskb(ar->hw, skb); ++ ieee80211_free_txskb(hw, skb); + } + } + +@@ -5496,7 +5496,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, + goto err_peer_del; + + param_id = WMI_VDEV_PARAM_RTS_THRESHOLD; +- param_value = ar->hw->wiphy->rts_threshold; ++ param_value = hw->wiphy->rts_threshold; + ret = ath12k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, + param_id, param_value); + if (ret) { +@@ -6676,7 +6676,7 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + arvif->vdev_id, ret); + return ret; + } +- ieee80211_iterate_stations_atomic(ar->hw, ++ ieee80211_iterate_stations_atomic(hw, + ath12k_mac_disable_peer_fixed_rate, + arvif); + } else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask, +@@ -6722,14 +6722,14 @@ ath12k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, + return -EINVAL; + } + +- ieee80211_iterate_stations_atomic(ar->hw, ++ ieee80211_iterate_stations_atomic(hw, + ath12k_mac_disable_peer_fixed_rate, + arvif); + + mutex_lock(&ar->conf_mutex); + + arvif->bitrate_mask = *mask; +- ieee80211_iterate_stations_atomic(ar->hw, ++ ieee80211_iterate_stations_atomic(hw, + ath12k_mac_set_bitrate_mask_iter, + arvif); + +@@ -6767,7 +6767,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, + ath12k_warn(ar->ab, "pdev %d successfully recovered\n", + ar->pdev->pdev_id); + ar->state = ATH12K_STATE_ON; +- ieee80211_wake_queues(ar->hw); ++ ieee80211_wake_queues(hw); + + if (ab->is_reset) { + recovery_count = atomic_inc_return(&ab->recovery_count); +diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c +index 32bdefeccc24..837a3e1ec3a4 100644 +--- a/drivers/net/wireless/ath/ath12k/reg.c ++++ b/drivers/net/wireless/ath/ath12k/reg.c +@@ -28,11 +28,11 @@ static const struct ieee80211_regdomain ath12k_world_regd = { + } + }; + +-static bool ath12k_regdom_changes(struct ath12k *ar, char *alpha2) ++static bool ath12k_regdom_changes(struct ieee80211_hw *hw, char *alpha2) + { + const struct ieee80211_regdomain *regd; + +- regd = rcu_dereference_rtnl(ar->hw->wiphy->regd); ++ regd = rcu_dereference_rtnl(hw->wiphy->regd); + /* This can happen during wiphy registration where the previous + * user request is received before we update the regd received + * from firmware. +@@ -71,7 +71,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) + return; + } + +- if (!ath12k_regdom_changes(ar, request->alpha2)) { ++ if (!ath12k_regdom_changes(hw, request->alpha2)) { + ath12k_dbg(ar->ab, ATH12K_DBG_REG, "Country is already set\n"); + return; + } +-- +2.39.5 + diff --git a/queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch b/queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch new file mode 100644 index 00000000000..6883f1e9ca6 --- /dev/null +++ b/queue-6.6/wifi-mac80211-add-non-atomic-station-iterator.patch @@ -0,0 +1,93 @@ +From 62c4d12f503c092263b527512217b4d11cdf357f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Aug 2024 17:40:23 -0700 +Subject: wifi: mac80211: Add non-atomic station iterator + +From: Rory Little + +[ Upstream commit 7c3b69eadea9e57c28bf914b0fd70f268f3682e1 ] + +Drivers may at times want to iterate their stations with a function +which requires some non-atomic operations. + +ieee80211_iterate_stations_mtx() introduces an API to iterate stations +while holding that wiphy's mutex. This allows the iterating function to +do non-atomic operations safely. + +Signed-off-by: Rory Little +Link: https://patch.msgid.link/20240806004024.2014080-2-rory@candelatech.com +[unify internal list iteration functions] +Signed-off-by: Johannes Berg +Stable-dep-of: 8fac3266c68a ("wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()") +Signed-off-by: Sasha Levin +--- + include/net/mac80211.h | 18 ++++++++++++++++++ + net/mac80211/util.c | 16 +++++++++++++++- + 2 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/include/net/mac80211.h b/include/net/mac80211.h +index 901fe3ac139e..835a58ce9ca5 100644 +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6080,6 +6080,24 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + void (*iterator)(void *data, + struct ieee80211_sta *sta), + void *data); ++ ++/** ++ * ieee80211_iterate_stations_mtx - iterate stations ++ * ++ * This function iterates over all stations associated with a given ++ * hardware that are currently uploaded to the driver and calls the callback ++ * function for them. This version can only be used while holding the wiphy ++ * mutex. ++ * ++ * @hw: the hardware struct of which the interfaces should be iterated over ++ * @iterator: the iterator function to call ++ * @data: first argument of the iterator function ++ */ ++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data); ++ + /** + * ieee80211_queue_work - add work onto the mac80211 workqueue + * +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index d682c32821a1..cc3c46a82077 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -827,7 +827,8 @@ static void __iterate_stations(struct ieee80211_local *local, + { + struct sta_info *sta; + +- list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ list_for_each_entry_rcu(sta, &local->sta_list, list, ++ lockdep_is_held(&local->hw.wiphy->mtx)) { + if (!sta->uploaded) + continue; + +@@ -848,6 +849,19 @@ void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, + } + EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); + ++void ieee80211_iterate_stations_mtx(struct ieee80211_hw *hw, ++ void (*iterator)(void *data, ++ struct ieee80211_sta *sta), ++ void *data) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ lockdep_assert_wiphy(local->hw.wiphy); ++ ++ __iterate_stations(local, iterator, data); ++} ++EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_mtx); ++ + struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); +-- +2.39.5 + diff --git a/queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch b/queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch new file mode 100644 index 00000000000..fec80445625 --- /dev/null +++ b/queue-6.6/wifi-mac80211-export-ieee80211_purge_tx_queue-for-dr.patch @@ -0,0 +1,74 @@ +From c54d8898c482819efdeb76d19dd4b804a41a01e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 09:42:54 +0800 +Subject: wifi: mac80211: export ieee80211_purge_tx_queue() for drivers + +From: Ping-Ke Shih + +[ Upstream commit 53bc1b73b67836ac9867f93dee7a443986b4a94f ] + +Drivers need to purge TX SKB when stopping. Using skb_queue_purge() can't +report TX status to mac80211, causing ieee80211_free_ack_frame() warns +"Have pending ack frames!". Export ieee80211_purge_tx_queue() for drivers +to not have to reimplement it. + +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240822014255.10211-1-pkshih@realtek.com +Signed-off-by: Johannes Berg +Stable-dep-of: 3e5e4a801aaf ("wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb") +Signed-off-by: Sasha Levin +--- + include/net/mac80211.h | 13 +++++++++++++ + net/mac80211/ieee80211_i.h | 2 -- + net/mac80211/status.c | 1 + + 3 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/include/net/mac80211.h b/include/net/mac80211.h +index 47ade676565d..901fe3ac139e 100644 +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3039,6 +3039,19 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, + */ + void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); + ++/** ++ * ieee80211_purge_tx_queue - purge TX skb queue ++ * @hw: the hardware ++ * @skbs: the skbs ++ * ++ * Free a set of transmit skbs. Use this function when device is going to stop ++ * but some transmit skbs without TX status are still queued. ++ * This function does not take the list lock and the caller must hold the ++ * relevant locks to use it. ++ */ ++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, ++ struct sk_buff_head *skbs); ++ + /** + * DOC: Hardware crypto acceleration + * +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index daea061d0fc1..04c876d78d3b 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2057,8 +2057,6 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, + u32 info_flags, + u32 ctrl_flags, + u64 *cookie); +-void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, +- struct sk_buff_head *skbs); + struct sk_buff * + ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u32 info_flags); +diff --git a/net/mac80211/status.c b/net/mac80211/status.c +index 44d83da60aee..9676ed15efec 100644 +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -1270,3 +1270,4 @@ void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + while ((skb = __skb_dequeue(skbs))) + ieee80211_free_txskb(hw, skb); + } ++EXPORT_SYMBOL(ieee80211_purge_tx_queue); +-- +2.39.5 + diff --git a/queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch b/queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch new file mode 100644 index 00000000000..4941f77b316 --- /dev/null +++ b/queue-6.6/wifi-rtw88-use-ieee80211_purge_tx_queue-to-purge-tx-.patch @@ -0,0 +1,128 @@ +From ccccfeb30c5f9c20a97d082b03113c367f4ca07d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 09:42:55 +0800 +Subject: wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb + +From: Ping-Ke Shih + +[ Upstream commit 3e5e4a801aaf4283390cc34959c6c48f910ca5ea ] + +When removing kernel modules by: + rmmod rtw88_8723cs rtw88_8703b rtw88_8723x rtw88_sdio rtw88_core + +Driver uses skb_queue_purge() to purge TX skb, but not report tx status +causing "Have pending ack frames!" warning. Use ieee80211_purge_tx_queue() +to correct this. + +Since ieee80211_purge_tx_queue() doesn't take locks, to prevent racing +between TX work and purge TX queue, flush and destroy TX work in advance. + + wlan0: deauthenticating from aa:f5:fd:60:4c:a8 by local + choice (Reason: 3=DEAUTH_LEAVING) + ------------[ cut here ]------------ + Have pending ack frames! + WARNING: CPU: 3 PID: 9232 at net/mac80211/main.c:1691 + ieee80211_free_ack_frame+0x5c/0x90 [mac80211] + CPU: 3 PID: 9232 Comm: rmmod Tainted: G C + 6.10.1-200.fc40.aarch64 #1 + Hardware name: pine64 Pine64 PinePhone Braveheart + (1.1)/Pine64 PinePhone Braveheart (1.1), BIOS 2024.01 01/01/2024 + pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] + lr : ieee80211_free_ack_frame+0x5c/0x90 [mac80211] + sp : ffff80008c1b37b0 + x29: ffff80008c1b37b0 x28: ffff000003be8000 x27: 0000000000000000 + x26: 0000000000000000 x25: ffff000003dc14b8 x24: ffff80008c1b37d0 + x23: ffff000000ff9f80 x22: 0000000000000000 x21: 000000007fffffff + x20: ffff80007c7e93d8 x19: ffff00006e66f400 x18: 0000000000000000 + x17: ffff7ffffd2b3000 x16: ffff800083fc0000 x15: 0000000000000000 + x14: 0000000000000000 x13: 2173656d61726620 x12: 6b636120676e6964 + x11: 0000000000000000 x10: 000000000000005d x9 : ffff8000802af2b0 + x8 : ffff80008c1b3430 x7 : 0000000000000001 x6 : 0000000000000001 + x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 + x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000003be8000 + Call trace: + ieee80211_free_ack_frame+0x5c/0x90 [mac80211] + idr_for_each+0x74/0x110 + ieee80211_free_hw+0x44/0xe8 [mac80211] + rtw_sdio_remove+0x9c/0xc0 [rtw88_sdio] + sdio_bus_remove+0x44/0x180 + device_remove+0x54/0x90 + device_release_driver_internal+0x1d4/0x238 + driver_detach+0x54/0xc0 + bus_remove_driver+0x78/0x108 + driver_unregister+0x38/0x78 + sdio_unregister_driver+0x2c/0x40 + rtw_8723cs_driver_exit+0x18/0x1000 [rtw88_8723cs] + __do_sys_delete_module.isra.0+0x190/0x338 + __arm64_sys_delete_module+0x1c/0x30 + invoke_syscall+0x74/0x100 + el0_svc_common.constprop.0+0x48/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x3c/0x158 + el0t_64_sync_handler+0x120/0x138 + el0t_64_sync+0x194/0x198 + ---[ end trace 0000000000000000 ]--- + +Reported-by: Peter Robinson +Closes: https://lore.kernel.org/linux-wireless/CALeDE9OAa56KMzgknaCD3quOgYuEHFx9_hcT=OFgmMAb+8MPyA@mail.gmail.com/ +Tested-by: Ping-Ke Shih # 8723DU +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240822014255.10211-2-pkshih@realtek.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw88/sdio.c | 6 +++--- + drivers/net/wireless/realtek/rtw88/usb.c | 5 +++-- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c +index 0cae5746f540..5bd1ee81210d 100644 +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -1295,12 +1295,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev) + struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + int i; + +- for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) +- skb_queue_purge(&rtwsdio->tx_queue[i]); +- + flush_workqueue(rtwsdio->txwq); + destroy_workqueue(rtwsdio->txwq); + kfree(rtwsdio->tx_handler_data); ++ ++ for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) ++ ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]); + } + + int rtw_sdio_probe(struct sdio_func *sdio_func, +diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c +index 04a64afcbf8a..8f1d653282b7 100644 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -416,10 +416,11 @@ static void rtw_usb_tx_handler(struct work_struct *work) + + static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb) + { ++ struct rtw_dev *rtwdev = rtwusb->rtwdev; + int i; + + for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++) +- skb_queue_purge(&rtwusb->tx_queue[i]); ++ ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]); + } + + static void rtw_usb_write_port_complete(struct urb *urb) +@@ -801,9 +802,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev) + { + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); + +- rtw_usb_tx_queue_purge(rtwusb); + flush_workqueue(rtwusb->txwq); + destroy_workqueue(rtwusb->txwq); ++ rtw_usb_tx_queue_purge(rtwusb); + } + + static int rtw_usb_intf_init(struct rtw_dev *rtwdev, +-- +2.39.5 + diff --git a/queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch b/queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch new file mode 100644 index 00000000000..501e941319d --- /dev/null +++ b/queue-6.6/x86-crash-wrap-crash-dumping-code-into-crash-related.patch @@ -0,0 +1,264 @@ +From f42388f495a402ab0b4d8c4f8f5a3e49fcbe373b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Jan 2024 13:12:46 +0800 +Subject: x86, crash: wrap crash dumping code into crash related ifdefs + +From: Baoquan He + +[ Upstream commit a4eeb2176d89fdf2785851521577b94b31690a60 ] + +Now crash codes under kernel/ folder has been split out from kexec +code, crash dumping can be separated from kexec reboot in config +items on x86 with some adjustments. + +Here, also change some ifdefs or IS_ENABLED() check to more appropriate +ones, e,g + - #ifdef CONFIG_KEXEC_CORE -> #ifdef CONFIG_CRASH_DUMP + - (!IS_ENABLED(CONFIG_KEXEC_CORE)) - > (!IS_ENABLED(CONFIG_CRASH_RESERVE)) + +[bhe@redhat.com: don't nest CONFIG_CRASH_DUMP ifdef inside CONFIG_KEXEC_CODE ifdef scope] + Link: https://lore.kernel.org/all/SN6PR02MB4157931105FA68D72E3D3DB8D47B2@SN6PR02MB4157.namprd02.prod.outlook.com/T/#u +Link: https://lkml.kernel.org/r/20240124051254.67105-7-bhe@redhat.com +Signed-off-by: Baoquan He +Cc: Al Viro +Cc: Eric W. Biederman +Cc: Hari Bathini +Cc: Pingfan Liu +Cc: Klara Modin +Cc: Michael Kelley +Cc: Nathan Chancellor +Cc: Stephen Rothwell +Cc: Yang Li +Signed-off-by: Andrew Morton +Stable-dep-of: bcc80dec91ee ("x86/hyperv: Fix hv tsc page based sched_clock for hibernation") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/Makefile | 4 ++-- + arch/x86/kernel/cpu/mshyperv.c | 10 ++++++++-- + arch/x86/kernel/kexec-bzimage64.c | 4 ++++ + arch/x86/kernel/kvm.c | 4 ++-- + arch/x86/kernel/machine_kexec_64.c | 3 +++ + arch/x86/kernel/reboot.c | 4 ++-- + arch/x86/kernel/setup.c | 2 +- + arch/x86/kernel/smp.c | 2 +- + arch/x86/xen/enlighten_hvm.c | 4 ++++ + arch/x86/xen/mmu_pv.c | 2 +- + 10 files changed, 28 insertions(+), 11 deletions(-) + +diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile +index 3269a0e23d3a..15fc9fc3dcf0 100644 +--- a/arch/x86/kernel/Makefile ++++ b/arch/x86/kernel/Makefile +@@ -99,9 +99,9 @@ obj-$(CONFIG_TRACING) += trace.o + obj-$(CONFIG_RETHOOK) += rethook.o + obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o + obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o +-obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o ++obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o + obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o +-obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o ++obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o crash.o + obj-y += kprobes/ + obj-$(CONFIG_MODULES) += module.o + obj-$(CONFIG_X86_32) += doublefault_32.o +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index bcb2d640a0cd..93e1cb4f7ff1 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -209,7 +209,9 @@ static void hv_machine_shutdown(void) + if (kexec_in_progress) + hyperv_cleanup(); + } ++#endif /* CONFIG_KEXEC_CORE */ + ++#ifdef CONFIG_CRASH_DUMP + static void hv_machine_crash_shutdown(struct pt_regs *regs) + { + if (hv_crash_handler) +@@ -221,7 +223,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs) + /* Disable the hypercall page when there is only 1 active CPU. */ + hyperv_cleanup(); + } +-#endif /* CONFIG_KEXEC_CORE */ ++#endif /* CONFIG_CRASH_DUMP */ + #endif /* CONFIG_HYPERV */ + + static uint32_t __init ms_hyperv_platform(void) +@@ -493,9 +495,13 @@ static void __init ms_hyperv_init_platform(void) + no_timer_check = 1; + #endif + +-#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE) ++#if IS_ENABLED(CONFIG_HYPERV) ++#if defined(CONFIG_KEXEC_CORE) + machine_ops.shutdown = hv_machine_shutdown; ++#endif ++#if defined(CONFIG_CRASH_DUMP) + machine_ops.crash_shutdown = hv_machine_crash_shutdown; ++#endif + #endif + if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { + /* +diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c +index a61c12c01270..0de509c02d18 100644 +--- a/arch/x86/kernel/kexec-bzimage64.c ++++ b/arch/x86/kernel/kexec-bzimage64.c +@@ -263,11 +263,13 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, + memset(¶ms->hd0_info, 0, sizeof(params->hd0_info)); + memset(¶ms->hd1_info, 0, sizeof(params->hd1_info)); + ++#ifdef CONFIG_CRASH_DUMP + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_setup_memmap_entries(image, params); + if (ret) + return ret; + } else ++#endif + setup_e820_entries(params); + + nr_e820_entries = params->e820_entries; +@@ -428,12 +430,14 @@ static void *bzImage64_load(struct kimage *image, char *kernel, + return ERR_PTR(-EINVAL); + } + ++#ifdef CONFIG_CRASH_DUMP + /* Allocate and load backup region */ + if (image->type == KEXEC_TYPE_CRASH) { + ret = crash_load_segments(image); + if (ret) + return ERR_PTR(ret); + } ++#endif + + /* + * Load purgatory. For 64bit entry point, purgatory code can be +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index b8ab9ee5896c..38d88c8b56ec 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -769,7 +769,7 @@ static struct notifier_block kvm_pv_reboot_nb = { + * won't be valid. In cases like kexec, in which you install a new kernel, this + * means a random memory location will be kept being written. + */ +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + static void kvm_crash_shutdown(struct pt_regs *regs) + { + kvm_guest_cpu_offline(true); +@@ -852,7 +852,7 @@ static void __init kvm_guest_init(void) + kvm_guest_cpu_init(); + #endif + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + machine_ops.crash_shutdown = kvm_crash_shutdown; + #endif + +diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c +index 2fa12d1dc676..aaeac2deb85d 100644 +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -545,6 +545,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) + } + #endif /* CONFIG_KEXEC_FILE */ + ++#ifdef CONFIG_CRASH_DUMP ++ + static int + kexec_mark_range(unsigned long start, unsigned long end, bool protect) + { +@@ -589,6 +591,7 @@ void arch_kexec_unprotect_crashkres(void) + { + kexec_mark_crashkres(false); + } ++#endif + + /* + * During a traditional boot under SME, SME will encrypt the kernel, +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 830425e6d38e..f3130f762784 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = { + .emergency_restart = native_machine_emergency_restart, + .restart = native_machine_restart, + .halt = native_machine_halt, +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + .crash_shutdown = native_machine_crash_shutdown, + #endif + }; +@@ -826,7 +826,7 @@ void machine_halt(void) + machine_ops.halt(); + } + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_CRASH_DUMP + void machine_crash_shutdown(struct pt_regs *regs) + { + machine_ops.crash_shutdown(regs); +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index eb129277dcdd..8bcecabd475b 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -547,7 +547,7 @@ static void __init reserve_crashkernel(void) + bool high = false; + int ret; + +- if (!IS_ENABLED(CONFIG_KEXEC_CORE)) ++ if (!IS_ENABLED(CONFIG_CRASH_RESERVE)) + return; + + total_mem = memblock_phys_mem_size(); +diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c +index 96a771f9f930..52c3823b7211 100644 +--- a/arch/x86/kernel/smp.c ++++ b/arch/x86/kernel/smp.c +@@ -282,7 +282,7 @@ struct smp_ops smp_ops = { + .smp_cpus_done = native_smp_cpus_done, + + .stop_other_cpus = native_stop_other_cpus, +-#if defined(CONFIG_KEXEC_CORE) ++#if defined(CONFIG_CRASH_DUMP) + .crash_stop_other_cpus = kdump_nmi_shootdown_cpus, + #endif + .smp_send_reschedule = native_smp_send_reschedule, +diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c +index 70be57e8f51c..ade22feee7ae 100644 +--- a/arch/x86/xen/enlighten_hvm.c ++++ b/arch/x86/xen/enlighten_hvm.c +@@ -141,7 +141,9 @@ static void xen_hvm_shutdown(void) + if (kexec_in_progress) + xen_reboot(SHUTDOWN_soft_reset); + } ++#endif + ++#ifdef CONFIG_CRASH_DUMP + static void xen_hvm_crash_shutdown(struct pt_regs *regs) + { + native_machine_crash_shutdown(regs); +@@ -229,6 +231,8 @@ static void __init xen_hvm_guest_init(void) + + #ifdef CONFIG_KEXEC_CORE + machine_ops.shutdown = xen_hvm_shutdown; ++#endif ++#ifdef CONFIG_CRASH_DUMP + machine_ops.crash_shutdown = xen_hvm_crash_shutdown; + #endif + } +diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c +index 6b201e64d8ab..bfd57d07f4b5 100644 +--- a/arch/x86/xen/mmu_pv.c ++++ b/arch/x86/xen/mmu_pv.c +@@ -2517,7 +2517,7 @@ int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr, + } + EXPORT_SYMBOL_GPL(xen_remap_pfn); + +-#ifdef CONFIG_KEXEC_CORE ++#ifdef CONFIG_VMCORE_INFO + phys_addr_t paddr_vmcoreinfo_note(void) + { + if (xen_pv_domain()) +-- +2.39.5 + diff --git a/queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch b/queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch new file mode 100644 index 00000000000..5fc64167555 --- /dev/null +++ b/queue-6.6/x86-fred-clear-wfe-in-missing-endbranch-cps.patch @@ -0,0 +1,103 @@ +From b1d1dadd691a4a9a0fb66ca9b12b28ba376b54c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Nov 2024 09:59:34 -0800 +Subject: x86/fred: Clear WFE in missing-ENDBRANCH #CPs + +From: Xin Li (Intel) + +[ Upstream commit dc81e556f2a017d681251ace21bf06c126d5a192 ] + +An indirect branch instruction sets the CPU indirect branch tracker +(IBT) into WAIT_FOR_ENDBRANCH (WFE) state and WFE stays asserted +across the instruction boundary. When the decoder finds an +inappropriate instruction while WFE is set ENDBR, the CPU raises a #CP +fault. + +For the "kernel IBT no ENDBR" selftest where #CPs are deliberately +triggered, the WFE state of the interrupted context needs to be +cleared to let execution continue. Otherwise when the CPU resumes +from the instruction that just caused the previous #CP, another +missing-ENDBRANCH #CP is raised and the CPU enters a dead loop. + +This is not a problem with IDT because it doesn't preserve WFE and +IRET doesn't set WFE. But FRED provides space on the entry stack +(in an expanded CS area) to save and restore the WFE state, thus the +WFE state is no longer clobbered, so software must clear it. + +Clear WFE to avoid dead looping in ibt_clear_fred_wfe() and the +!ibt_fatal code path when execution is allowed to continue. + +Clobbering WFE in any other circumstance is a security-relevant bug. + +[ dhansen: changelog rewording ] + +Fixes: a5f6c2ace997 ("x86/shstk: Add user control-protection fault handler") +Signed-off-by: Xin Li (Intel) +Signed-off-by: Dave Hansen +Signed-off-by: Ingo Molnar +Acked-by: Dave Hansen +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/all/20241113175934.3897541-1-xin%40zytor.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cet.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/arch/x86/kernel/cet.c b/arch/x86/kernel/cet.c +index d2c732a34e5d..303bf74d175b 100644 +--- a/arch/x86/kernel/cet.c ++++ b/arch/x86/kernel/cet.c +@@ -81,6 +81,34 @@ static void do_user_cp_fault(struct pt_regs *regs, unsigned long error_code) + + static __ro_after_init bool ibt_fatal = true; + ++/* ++ * By definition, all missing-ENDBRANCH #CPs are a result of WFE && !ENDBR. ++ * ++ * For the kernel IBT no ENDBR selftest where #CPs are deliberately triggered, ++ * the WFE state of the interrupted context needs to be cleared to let execution ++ * continue. Otherwise when the CPU resumes from the instruction that just ++ * caused the previous #CP, another missing-ENDBRANCH #CP is raised and the CPU ++ * enters a dead loop. ++ * ++ * This is not a problem with IDT because it doesn't preserve WFE and IRET doesn't ++ * set WFE. But FRED provides space on the entry stack (in an expanded CS area) ++ * to save and restore the WFE state, thus the WFE state is no longer clobbered, ++ * so software must clear it. ++ */ ++static void ibt_clear_fred_wfe(struct pt_regs *regs) ++{ ++ /* ++ * No need to do any FRED checks. ++ * ++ * For IDT event delivery, the high-order 48 bits of CS are pushed ++ * as 0s into the stack, and later IRET ignores these bits. ++ * ++ * For FRED, a test to check if fred_cs.wfe is set would be dropped ++ * by compilers. ++ */ ++ regs->fred_cs.wfe = 0; ++} ++ + static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + { + if ((error_code & CP_EC) != CP_ENDBR) { +@@ -90,6 +118,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + + if (unlikely(regs->ip == (unsigned long)&ibt_selftest_noendbr)) { + regs->ax = 0; ++ ibt_clear_fred_wfe(regs); + return; + } + +@@ -97,6 +126,7 @@ static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code) + if (!ibt_fatal) { + printk(KERN_DEFAULT CUT_HERE); + __warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL); ++ ibt_clear_fred_wfe(regs); + return; + } + BUG(); +-- +2.39.5 + diff --git a/queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch b/queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch new file mode 100644 index 00000000000..086294daebc --- /dev/null +++ b/queue-6.6/x86-hyperv-fix-hv-tsc-page-based-sched_clock-for-hib.patch @@ -0,0 +1,177 @@ +From 4c8d45af23c2af5ce425e6ded5fed31e0ffcff2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Sep 2024 11:09:17 +0530 +Subject: x86/hyperv: Fix hv tsc page based sched_clock for hibernation + +From: Naman Jain + +[ Upstream commit bcc80dec91ee745b3d66f3e48f0ec2efdea97149 ] + +read_hv_sched_clock_tsc() assumes that the Hyper-V clock counter is +bigger than the variable hv_sched_clock_offset, which is cached during +early boot, but depending on the timing this assumption may be false +when a hibernated VM starts again (the clock counter starts from 0 +again) and is resuming back (Note: hv_init_tsc_clocksource() is not +called during hibernation/resume); consequently, +read_hv_sched_clock_tsc() may return a negative integer (which is +interpreted as a huge positive integer since the return type is u64) +and new kernel messages are prefixed with huge timestamps before +read_hv_sched_clock_tsc() grows big enough (which typically takes +several seconds). + +Fix the issue by saving the Hyper-V clock counter just before the +suspend, and using it to correct the hv_sched_clock_offset in +resume. This makes hv tsc page based sched_clock continuous and ensures +that post resume, it starts from where it left off during suspend. +Override x86_platform.save_sched_clock_state and +x86_platform.restore_sched_clock_state routines to correct this as soon +as possible. + +Note: if Invariant TSC is available, the issue doesn't happen because +1) we don't register read_hv_sched_clock_tsc() for sched clock: +See commit e5313f1c5404 ("clocksource/drivers/hyper-v: Rework +clocksource and sched clock setup"); +2) the common x86 code adjusts TSC similarly: see +__restore_processor_state() -> tsc_verify_tsc_adjust(true) and +x86_platform.restore_sched_clock_state(). + +Cc: stable@vger.kernel.org +Fixes: 1349401ff1aa ("clocksource/drivers/hyper-v: Suspend/resume Hyper-V clocksource for hibernation") +Co-developed-by: Dexuan Cui +Signed-off-by: Dexuan Cui +Signed-off-by: Naman Jain +Reviewed-by: Michael Kelley +Link: https://lore.kernel.org/r/20240917053917.76787-1-namjain@linux.microsoft.com +Signed-off-by: Wei Liu +Message-ID: <20240917053917.76787-1-namjain@linux.microsoft.com> +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/cpu/mshyperv.c | 58 ++++++++++++++++++++++++++++++ + drivers/clocksource/hyperv_timer.c | 14 +++++++- + include/clocksource/hyperv_timer.h | 2 ++ + 3 files changed, 73 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index 93e1cb4f7ff1..6328cf56e59b 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -224,6 +224,63 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs) + hyperv_cleanup(); + } + #endif /* CONFIG_CRASH_DUMP */ ++ ++static u64 hv_ref_counter_at_suspend; ++static void (*old_save_sched_clock_state)(void); ++static void (*old_restore_sched_clock_state)(void); ++ ++/* ++ * Hyper-V clock counter resets during hibernation. Save and restore clock ++ * offset during suspend/resume, while also considering the time passed ++ * before suspend. This is to make sure that sched_clock using hv tsc page ++ * based clocksource, proceeds from where it left off during suspend and ++ * it shows correct time for the timestamps of kernel messages after resume. ++ */ ++static void save_hv_clock_tsc_state(void) ++{ ++ hv_ref_counter_at_suspend = hv_read_reference_counter(); ++} ++ ++static void restore_hv_clock_tsc_state(void) ++{ ++ /* ++ * Adjust the offsets used by hv tsc clocksource to ++ * account for the time spent before hibernation. ++ * adjusted value = reference counter (time) at suspend ++ * - reference counter (time) now. ++ */ ++ hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter()); ++} ++ ++/* ++ * Functions to override save_sched_clock_state and restore_sched_clock_state ++ * functions of x86_platform. The Hyper-V clock counter is reset during ++ * suspend-resume and the offset used to measure time needs to be ++ * corrected, post resume. ++ */ ++static void hv_save_sched_clock_state(void) ++{ ++ old_save_sched_clock_state(); ++ save_hv_clock_tsc_state(); ++} ++ ++static void hv_restore_sched_clock_state(void) ++{ ++ restore_hv_clock_tsc_state(); ++ old_restore_sched_clock_state(); ++} ++ ++static void __init x86_setup_ops_for_tsc_pg_clock(void) ++{ ++ if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE)) ++ return; ++ ++ old_save_sched_clock_state = x86_platform.save_sched_clock_state; ++ x86_platform.save_sched_clock_state = hv_save_sched_clock_state; ++ ++ old_restore_sched_clock_state = x86_platform.restore_sched_clock_state; ++ x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state; ++} + #endif /* CONFIG_HYPERV */ + + static uint32_t __init ms_hyperv_platform(void) +@@ -578,6 +635,7 @@ static void __init ms_hyperv_init_platform(void) + + /* Register Hyper-V specific clocksource */ + hv_init_clocksource(); ++ x86_setup_ops_for_tsc_pg_clock(); + hv_vtl_init_platform(); + #endif + /* +diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c +index 8ff7cd4e20bb..5eec1457e139 100644 +--- a/drivers/clocksource/hyperv_timer.c ++++ b/drivers/clocksource/hyperv_timer.c +@@ -27,7 +27,8 @@ + #include + + static struct clock_event_device __percpu *hv_clock_event; +-static u64 hv_sched_clock_offset __ro_after_init; ++/* Note: offset can hold negative values after hibernation. */ ++static u64 hv_sched_clock_offset __read_mostly; + + /* + * If false, we're using the old mechanism for stimer0 interrupts +@@ -456,6 +457,17 @@ static void resume_hv_clock_tsc(struct clocksource *arg) + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); + } + ++/* ++ * Called during resume from hibernation, from overridden ++ * x86_platform.restore_sched_clock_state routine. This is to adjust offsets ++ * used to calculate time for hv tsc page based sched_clock, to account for ++ * time spent before hibernation. ++ */ ++void hv_adj_sched_clock_offset(u64 offset) ++{ ++ hv_sched_clock_offset -= offset; ++} ++ + #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK + static int hv_cs_enable(struct clocksource *cs) + { +diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h +index 6cdc873ac907..aa5233b1eba9 100644 +--- a/include/clocksource/hyperv_timer.h ++++ b/include/clocksource/hyperv_timer.h +@@ -38,6 +38,8 @@ extern void hv_remap_tsc_clocksource(void); + extern unsigned long hv_get_tsc_pfn(void); + extern struct ms_hyperv_tsc_page *hv_get_tsc_page(void); + ++extern void hv_adj_sched_clock_offset(u64 offset); ++ + static __always_inline bool + hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, + u64 *cur_tsc, u64 *time) +-- +2.39.5 + diff --git a/queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch b/queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch new file mode 100644 index 00000000000..2939bee0932 --- /dev/null +++ b/queue-6.6/x86-mm-carve-out-invlpg-inline-asm-for-use-by-others.patch @@ -0,0 +1,56 @@ +From e4f1455e41ec556226af9bad8598d04b714dab6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Nov 2024 12:21:32 +0100 +Subject: x86/mm: Carve out INVLPG inline asm for use by others + +From: Borislav Petkov (AMD) + +[ Upstream commit f1d84b59cbb9547c243d93991acf187fdbe9fbe9 ] + +No functional changes. + +Signed-off-by: Borislav Petkov (AMD) +Link: https://lore.kernel.org/r/ZyulbYuvrkshfsd2@antipodes +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/tlb.h | 4 ++++ + arch/x86/mm/tlb.c | 3 ++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h +index 580636cdc257..4d3c9d00d6b6 100644 +--- a/arch/x86/include/asm/tlb.h ++++ b/arch/x86/include/asm/tlb.h +@@ -34,4 +34,8 @@ static inline void __tlb_remove_table(void *table) + free_page_and_swap_cache(table); + } + ++static inline void invlpg(unsigned long addr) ++{ ++ asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); ++} + #endif /* _ASM_X86_TLB_H */ +diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c +index 2fbae48f0b47..64f594826a28 100644 +--- a/arch/x86/mm/tlb.c ++++ b/arch/x86/mm/tlb.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + #include "mm_internal.h" + +@@ -1145,7 +1146,7 @@ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr) + bool cpu_pcide; + + /* Flush 'addr' from the kernel PCID: */ +- asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); ++ invlpg(addr); + + /* If PTI is off there is no user PCID and nothing to flush. */ + if (!static_cpu_has(X86_FEATURE_PTI)) +-- +2.39.5 + diff --git a/queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch b/queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch new file mode 100644 index 00000000000..a37f28ae593 --- /dev/null +++ b/queue-6.6/x86-ptrace-add-fred-additional-information-to-the-pt.patch @@ -0,0 +1,137 @@ +From f91e62282bab1b2f055166147b0b2323c710f23b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Dec 2023 02:50:03 -0800 +Subject: x86/ptrace: Add FRED additional information to the pt_regs structure + +From: Xin Li + +[ Upstream commit 3c77bf02d0c03beb3efdf7a5b427fb2e1a76c265 ] + +FRED defines additional information in the upper 48 bits of cs/ss +fields. Therefore add the information definitions into the pt_regs +structure. + +Specifically introduce a new structure fred_ss to denote the FRED flags +above SS selector, which avoids FRED_SSX_ macros and makes the code +simpler and easier to read. + +Suggested-by: Thomas Gleixner +Originally-by: H. Peter Anvin (Intel) +Signed-off-by: Xin Li +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov (AMD) +Tested-by: Shan Kang +Link: https://lore.kernel.org/r/20231205105030.8698-15-xin3.li@intel.com +Stable-dep-of: dc81e556f2a0 ("x86/fred: Clear WFE in missing-ENDBRANCH #CPs") +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/ptrace.h | 66 ++++++++++++++++++++++++++++++++--- + 1 file changed, 61 insertions(+), 5 deletions(-) + +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index b268cd2a2d01..5a83fbd9bc0b 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -56,6 +56,50 @@ struct pt_regs { + + #else /* __i386__ */ + ++struct fred_cs { ++ /* CS selector */ ++ u64 cs : 16, ++ /* Stack level at event time */ ++ sl : 2, ++ /* IBT in WAIT_FOR_ENDBRANCH state */ ++ wfe : 1, ++ : 45; ++}; ++ ++struct fred_ss { ++ /* SS selector */ ++ u64 ss : 16, ++ /* STI state */ ++ sti : 1, ++ /* Set if syscall, sysenter or INT n */ ++ swevent : 1, ++ /* Event is NMI type */ ++ nmi : 1, ++ : 13, ++ /* Event vector */ ++ vector : 8, ++ : 8, ++ /* Event type */ ++ type : 4, ++ : 4, ++ /* Event was incident to enclave execution */ ++ enclave : 1, ++ /* CPU was in long mode */ ++ lm : 1, ++ /* ++ * Nested exception during FRED delivery, not set ++ * for #DF. ++ */ ++ nested : 1, ++ : 1, ++ /* ++ * The length of the instruction causing the event. ++ * Only set for INTO, INT1, INT3, INT n, SYSCALL ++ * and SYSENTER. 0 otherwise. ++ */ ++ insnlen : 4; ++}; ++ + struct pt_regs { + /* + * C ABI says these regs are callee-preserved. They aren't saved on +@@ -85,6 +129,12 @@ struct pt_regs { + * - the syscall number (syscall, sysenter, int80) + * - error_code stored by the CPU on traps and exceptions + * - the interrupt number for device interrupts ++ * ++ * A FRED stack frame starts here: ++ * 1) It _always_ includes an error code; ++ * ++ * 2) The return frame for ERET[US] starts here, but ++ * the content of orig_ax is ignored. + */ + unsigned long orig_ax; + +@@ -92,24 +142,30 @@ struct pt_regs { + unsigned long ip; + + union { +- /* The full 64-bit data slot containing CS */ +- u64 csx; + /* CS selector */ + u16 cs; ++ /* The extended 64-bit data slot containing CS */ ++ u64 csx; ++ /* The FRED CS extension */ ++ struct fred_cs fred_cs; + }; + + unsigned long flags; + unsigned long sp; + + union { +- /* The full 64-bit data slot containing SS */ +- u64 ssx; + /* SS selector */ + u16 ss; ++ /* The extended 64-bit data slot containing SS */ ++ u64 ssx; ++ /* The FRED SS extension */ ++ struct fred_ss fred_ss; + }; + + /* +- * Top of stack on IDT systems. ++ * Top of stack on IDT systems, while FRED systems have extra fields ++ * defined above for storing exception related information, e.g. CR2 or ++ * DR6. + */ + }; + +-- +2.39.5 + diff --git a/queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch b/queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch new file mode 100644 index 00000000000..157eed08d3e --- /dev/null +++ b/queue-6.6/x86-ptrace-cleanup-the-definition-of-the-pt_regs-str.patch @@ -0,0 +1,144 @@ +From 07f03d87296dadf00cd3d6479a64060f042a13e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Dec 2023 02:50:02 -0800 +Subject: x86/ptrace: Cleanup the definition of the pt_regs structure + +From: Xin Li + +[ Upstream commit ee63291aa8287cb7ded767d340155fe8681fc075 ] + +struct pt_regs is hard to read because the member or section related +comments are not aligned with the members. + +The 'cs' and 'ss' members of pt_regs are type of 'unsigned long' while +in reality they are only 16-bit wide. This works so far as the +remaining space is unused, but FRED will use the remaining bits for +other purposes. + +To prepare for FRED: + + - Cleanup the formatting + - Convert 'cs' and 'ss' to u16 and embed them into an union + with a u64 + - Fixup the related printk() format strings + +Suggested-by: Thomas Gleixner +Originally-by: H. Peter Anvin (Intel) +Signed-off-by: Xin Li +Signed-off-by: Thomas Gleixner +Signed-off-by: Borislav Petkov (AMD) +Tested-by: Shan Kang +Link: https://lore.kernel.org/r/20231205105030.8698-14-xin3.li@intel.com +Stable-dep-of: dc81e556f2a0 ("x86/fred: Clear WFE in missing-ENDBRANCH #CPs") +Signed-off-by: Sasha Levin +--- + arch/x86/entry/vsyscall/vsyscall_64.c | 2 +- + arch/x86/include/asm/ptrace.h | 48 +++++++++++++++++++-------- + arch/x86/kernel/process_64.c | 2 +- + 3 files changed, 37 insertions(+), 15 deletions(-) + +diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c +index 1245000a8792..2fb7d53cf333 100644 +--- a/arch/x86/entry/vsyscall/vsyscall_64.c ++++ b/arch/x86/entry/vsyscall/vsyscall_64.c +@@ -76,7 +76,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, + if (!show_unhandled_signals) + return; + +- printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", ++ printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n", + level, current->comm, task_pid_nr(current), + message, regs->ip, regs->cs, + regs->sp, regs->ax, regs->si, regs->di); +diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h +index f4db78b09c8f..b268cd2a2d01 100644 +--- a/arch/x86/include/asm/ptrace.h ++++ b/arch/x86/include/asm/ptrace.h +@@ -57,17 +57,19 @@ struct pt_regs { + #else /* __i386__ */ + + struct pt_regs { +-/* +- * C ABI says these regs are callee-preserved. They aren't saved on kernel entry +- * unless syscall needs a complete, fully filled "struct pt_regs". +- */ ++ /* ++ * C ABI says these regs are callee-preserved. They aren't saved on ++ * kernel entry unless syscall needs a complete, fully filled ++ * "struct pt_regs". ++ */ + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long bp; + unsigned long bx; +-/* These regs are callee-clobbered. Always saved on kernel entry. */ ++ ++ /* These regs are callee-clobbered. Always saved on kernel entry. */ + unsigned long r11; + unsigned long r10; + unsigned long r9; +@@ -77,18 +79,38 @@ struct pt_regs { + unsigned long dx; + unsigned long si; + unsigned long di; +-/* +- * On syscall entry, this is syscall#. On CPU exception, this is error code. +- * On hw interrupt, it's IRQ number: +- */ ++ ++ /* ++ * orig_ax is used on entry for: ++ * - the syscall number (syscall, sysenter, int80) ++ * - error_code stored by the CPU on traps and exceptions ++ * - the interrupt number for device interrupts ++ */ + unsigned long orig_ax; +-/* Return frame for iretq */ ++ ++ /* The IRETQ return frame starts here */ + unsigned long ip; +- unsigned long cs; ++ ++ union { ++ /* The full 64-bit data slot containing CS */ ++ u64 csx; ++ /* CS selector */ ++ u16 cs; ++ }; ++ + unsigned long flags; + unsigned long sp; +- unsigned long ss; +-/* top of stack page */ ++ ++ union { ++ /* The full 64-bit data slot containing SS */ ++ u64 ssx; ++ /* SS selector */ ++ u16 ss; ++ }; ++ ++ /* ++ * Top of stack on IDT systems. ++ */ + }; + + #endif /* !__i386__ */ +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index d595ef7c1de0..dd19a4db741a 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -117,7 +117,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode, + + printk("%sFS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", + log_lvl, fs, fsindex, gs, gsindex, shadowgs); +- printk("%sCS: %04lx DS: %04x ES: %04x CR0: %016lx\n", ++ printk("%sCS: %04x DS: %04x ES: %04x CR0: %016lx\n", + log_lvl, regs->cs, ds, es, cr0); + printk("%sCR2: %016lx CR3: %016lx CR4: %016lx\n", + log_lvl, cr2, cr3, cr4); +-- +2.39.5 + diff --git a/queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch b/queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch new file mode 100644 index 00000000000..545372979a0 --- /dev/null +++ b/queue-6.6/xhci-retry-stop-endpoint-on-buggy-nec-controllers.patch @@ -0,0 +1,57 @@ +From e508d0ec7a43a542274c68c15a620ce08cfdbc18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Feb 2024 16:14:36 +0200 +Subject: xhci: retry Stop Endpoint on buggy NEC controllers + +From: Michal Pecio + +[ Upstream commit fd9d55d190c0e5fefd3a9165ea361809427885a1 ] + +Two NEC uPD720200 adapters have been observed to randomly misbehave: +a Stop Endpoint command fails with Context Error, the Output Context +indicates Stopped state, and the endpoint keeps running. Very often, +Set TR Dequeue Pointer is seen to fail next with Context Error too, +in addition to problems from unexpectedly completed cancelled work. + +The pathology is common on fast running isoc endpoints like uvcvideo, +but has also been reproduced on a full-speed bulk endpoint of pl2303. +It seems all EPs are affected, with risk proportional to their load. + +Reproduction involves receiving any kind of stream and closing it to +make the device driver cancel URBs already queued in advance. + +Deal with it by retrying the command like in the Running state. + +Signed-off-by: Michal Pecio +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240229141438.619372-8-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: e21ebe51af68 ("xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic") +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-ring.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 50f588011400..7c3e39482834 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1180,6 +1180,15 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + break; + ep->ep_state &= ~EP_STOP_CMD_PENDING; + return; ++ case EP_STATE_STOPPED: ++ /* ++ * NEC uPD720200 sometimes sets this state and fails with ++ * Context Error while continuing to process TRBs. ++ * Be conservative and trust EP_CTX_STATE on other chips. ++ */ ++ if (!(xhci->quirks & XHCI_NEC_HOST)) ++ break; ++ fallthrough; + case EP_STATE_RUNNING: + /* Race, HW handled stop ep cmd before ep was running */ + xhci_dbg(xhci, "Stop ep completion ctx error, ep is running\n"); +-- +2.39.5 + diff --git a/queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch b/queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch new file mode 100644 index 00000000000..2ced24bd184 --- /dev/null +++ b/queue-6.6/xhci-turn-nec-specific-quirk-for-handling-stop-endpo.patch @@ -0,0 +1,45 @@ +From f33d1477db7f55664b457f32fb7c0f4e6dc8209c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Dec 2024 12:21:21 +0200 +Subject: xhci: Turn NEC specific quirk for handling Stop Endpoint errors + generic + +From: Mathias Nyman + +[ Upstream commit e21ebe51af688eb98fd6269240212a3c7300deea ] + +xHC hosts from several vendors have the same issue where endpoints start +so slowly that a later queued 'Stop Endpoint' command may complete before +endpoint is up and running. + +The 'Stop Endpoint' command fails with context state error as the endpoint +still appears as stopped. + +See commit 42b758137601 ("usb: xhci: Limit Stop Endpoint retries") for +details + +CC: stable@vger.kernel.org +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20241217102122.2316814-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-ring.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index d318310e3135..729319d81753 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1203,8 +1203,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, + * Keep retrying until the EP starts and stops again, on + * chips where this is known to help. Wait for 100ms. + */ +- if (!(xhci->quirks & XHCI_NEC_HOST)) +- break; + if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) + break; + fallthrough; +-- +2.39.5 +