From: Sasha Levin Date: Mon, 6 May 2024 19:23:43 +0000 (-0400) Subject: Fixes for 6.6 X-Git-Tag: v4.19.314~126 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8042a9144add436e4efe8a9e3060df2ddb63cc89;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/alsa-emu10k1-factor-out-snd_emu1010_load_dock_firmwa.patch b/queue-6.6/alsa-emu10k1-factor-out-snd_emu1010_load_dock_firmwa.patch new file mode 100644 index 00000000000..0efa6f623d9 --- /dev/null +++ b/queue-6.6/alsa-emu10k1-factor-out-snd_emu1010_load_dock_firmwa.patch @@ -0,0 +1,127 @@ +From b1fd76c727d183edab47e24a097ac8e854c4b0c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 11:37:12 +0200 +Subject: ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware() + +From: Oswald Buddenhagen + +[ Upstream commit 28deafd0fbdc45cc9c63bd7dd4efc35137958862 ] + +Pulled out of the next patch to improve its legibility. + +As the function is now available, call it directly from +snd_emu10k1_emu1010_init(), thus making the MicroDock firmware loading +synchronous - there isn't really a reason not to. Note that this does +not affect the AudioDocks of rev1 cards, as these have no independent +power supplies, and thus come up only a while after the main card is +initialized. + +As a drive-by, adjust the priorities of two messages to better reflect +their impact. + +Signed-off-by: Oswald Buddenhagen +Signed-off-by: Takashi Iwai +Message-ID: <20240428093716.3198666-3-oswald.buddenhagen@gmx.de> +Stable-dep-of: f848337cd801 ("ALSA: emu10k1: move the whole GPIO event handling to the workqueue") +Signed-off-by: Sasha Levin +--- + sound/pci/emu10k1/emu10k1_main.c | 66 +++++++++++++++++--------------- + 1 file changed, 36 insertions(+), 30 deletions(-) + +diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c +index 85f70368a27db..6265fc9ae2606 100644 +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -732,11 +732,43 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, int dock, + return snd_emu1010_load_firmware_entry(emu, *fw); + } + ++static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu) ++{ ++ u32 tmp, tmp2; ++ int err; ++ ++ dev_info(emu->card->dev, "emu1010: Loading Audio Dock Firmware\n"); ++ /* Return to Audio Dock programming mode */ ++ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, ++ EMU_HANA_FPGA_CONFIG_AUDIODOCK); ++ err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw); ++ if (err < 0) ++ return; ++ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); ++ ++ snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp); ++ dev_dbg(emu->card->dev, "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp); ++ if ((tmp & 0x1f) != 0x15) { ++ /* FPGA failed to be programmed */ ++ dev_err(emu->card->dev, ++ "emu1010: Loading Audio Dock Firmware failed, reg = 0x%x\n", ++ tmp); ++ return; ++ } ++ dev_info(emu->card->dev, "emu1010: Audio Dock Firmware loaded\n"); ++ ++ snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp); ++ snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2); ++ dev_info(emu->card->dev, "Audio Dock ver: %u.%u\n", tmp, tmp2); ++ ++ /* Allow DLL to settle, to sync clocking between 1010 and Dock */ ++ msleep(10); ++} ++ + static void emu1010_firmware_work(struct work_struct *work) + { + struct snd_emu10k1 *emu; +- u32 tmp, tmp2, reg; +- int err; ++ u32 reg; + + emu = container_of(work, struct snd_emu10k1, + emu1010.firmware_work); +@@ -749,33 +781,7 @@ static void emu1010_firmware_work(struct work_struct *work) + snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); /* OPTIONS: Which cards are attached to the EMU */ + if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { + /* Audio Dock attached */ +- /* Return to Audio Dock programming mode */ +- dev_info(emu->card->dev, +- "emu1010: Loading Audio Dock Firmware\n"); +- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, +- EMU_HANA_FPGA_CONFIG_AUDIODOCK); +- err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw); +- if (err < 0) +- return; +- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0); +- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp); +- dev_info(emu->card->dev, +- "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp); +- if ((tmp & 0x1f) != 0x15) { +- /* FPGA failed to be programmed */ +- dev_info(emu->card->dev, +- "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", +- tmp); +- return; +- } +- dev_info(emu->card->dev, +- "emu1010: Audio Dock Firmware loaded\n"); +- snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp); +- snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2); +- dev_info(emu->card->dev, "Audio Dock ver: %u.%u\n", tmp, tmp2); +- /* Sync clocking between 1010 and Dock */ +- /* Allow DLL to settle */ +- msleep(10); ++ snd_emu1010_load_dock_firmware(emu); + /* Unmute all. Default is muted after a firmware load */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); + } else if (!(reg & EMU_HANA_OPTION_DOCK_ONLINE)) { +@@ -892,7 +898,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) + snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); + dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg); + if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) +- schedule_work(&emu->emu1010.firmware_work); ++ snd_emu1010_load_dock_firmware(emu); + if (emu->card_capabilities->no_adat) { + emu->emu1010.optical_in = 0; /* IN_SPDIF */ + emu->emu1010.optical_out = 0; /* OUT_SPDIF */ +-- +2.43.0 + diff --git a/queue-6.6/alsa-emu10k1-fix-e-mu-card-dock-presence-monitoring.patch b/queue-6.6/alsa-emu10k1-fix-e-mu-card-dock-presence-monitoring.patch new file mode 100644 index 00000000000..8258037fb30 --- /dev/null +++ b/queue-6.6/alsa-emu10k1-fix-e-mu-card-dock-presence-monitoring.patch @@ -0,0 +1,67 @@ +From 90e742ebf6e8761e7634639f514ad20d0b824c66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 11:37:11 +0200 +Subject: ALSA: emu10k1: fix E-MU card dock presence monitoring + +From: Oswald Buddenhagen + +[ Upstream commit 398321d7531963b95841865eb371fe65c44c6921 ] + +While there are two separate IRQ status bits for dock attach and detach, +the hardware appears to mix them up more or less randomly, making them +useless for tracking what actually happened. It is much safer to check +the dock status separately and proceed based on that, as the old polling +code did. + +Note that the code assumes that only the dock can be hot-plugged - if +other option card bits changed, the logic would break. + +Fixes: fbb64eedf5a3 ("ALSA: emu10k1: make E-MU dock monitoring interrupt-driven") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218584 +Signed-off-by: Oswald Buddenhagen +Signed-off-by: Takashi Iwai +Message-ID: <20240428093716.3198666-2-oswald.buddenhagen@gmx.de> +Signed-off-by: Sasha Levin +--- + sound/pci/emu10k1/emu10k1_main.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c +index de5c41e578e1f..85f70368a27db 100644 +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -778,6 +778,11 @@ static void emu1010_firmware_work(struct work_struct *work) + msleep(10); + /* Unmute all. Default is muted after a firmware load */ + snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); ++ } else if (!(reg & EMU_HANA_OPTION_DOCK_ONLINE)) { ++ /* Audio Dock removed */ ++ dev_info(emu->card->dev, "emu1010: Audio Dock detached\n"); ++ /* The hardware auto-mutes all, so we unmute again */ ++ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); + } + } + +@@ -810,14 +815,12 @@ static void emu1010_interrupt(struct snd_emu10k1 *emu) + u32 sts; + + snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts); +- if (sts & EMU_HANA_IRQ_DOCK_LOST) { +- /* Audio Dock removed */ +- dev_info(emu->card->dev, "emu1010: Audio Dock detached\n"); +- /* The hardware auto-mutes all, so we unmute again */ +- snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE); +- } else if (sts & EMU_HANA_IRQ_DOCK) { ++ ++ // The distinction of the IRQ status bits is unreliable, ++ // so we dispatch later based on option card status. ++ if (sts & (EMU_HANA_IRQ_DOCK | EMU_HANA_IRQ_DOCK_LOST)) + schedule_work(&emu->emu1010.firmware_work); +- } ++ + if (sts & EMU_HANA_IRQ_WCLK_CHANGED) + schedule_work(&emu->emu1010.clock_work); + } +-- +2.43.0 + diff --git a/queue-6.6/alsa-emu10k1-fix-e-mu-dock-initialization.patch b/queue-6.6/alsa-emu10k1-fix-e-mu-dock-initialization.patch new file mode 100644 index 00000000000..dd3bf1c0cbd --- /dev/null +++ b/queue-6.6/alsa-emu10k1-fix-e-mu-dock-initialization.patch @@ -0,0 +1,51 @@ +From 5012413c0eed0379b9a82b34c43f51cfc79b5ab1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 11:37:15 +0200 +Subject: ALSA: emu10k1: fix E-MU dock initialization + +From: Oswald Buddenhagen + +[ Upstream commit e8289fd3fa65d60cf04dab6f7845eda352c04ea6 ] + +A side effect of making the dock monitoring interrupt-driven was that +we'd be very quick to program a freshly connected dock. However, for +unclear reasons, the dock does not work when we do that - despite the +FPGA netlist upload going just fine. We work around this by adding a +delay before programming the dock; for safety, the value is several +times as much as was determined empirically. + +Note that a badly timed dock hot-plug would have triggered the problem +even before the referenced commit - but now it would happen 100% instead +of about 3% of the time, thus making it impossible to work around by +re-plugging. + +Fixes: fbb64eedf5a3 ("ALSA: emu10k1: make E-MU dock monitoring interrupt-driven") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218584 +Signed-off-by: Oswald Buddenhagen +Signed-off-by: Takashi Iwai +Message-ID: <20240428093716.3198666-6-oswald.buddenhagen@gmx.de> +Signed-off-by: Sasha Levin +--- + sound/pci/emu10k1/emu10k1_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c +index 86eaf5963502c..ade90c7ecd922 100644 +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -737,6 +737,12 @@ static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu) + u32 tmp, tmp2; + int err; + ++ // The docking events clearly arrive prematurely - while the ++ // Dock's FPGA seems to be successfully programmed, the Dock ++ // fails to initialize subsequently if we don't give it some ++ // time to "warm up" here. ++ msleep(200); ++ + dev_info(emu->card->dev, "emu1010: Loading Audio Dock Firmware\n"); + /* Return to Audio Dock programming mode */ + snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, +-- +2.43.0 + diff --git a/queue-6.6/alsa-emu10k1-move-the-whole-gpio-event-handling-to-t.patch b/queue-6.6/alsa-emu10k1-move-the-whole-gpio-event-handling-to-t.patch new file mode 100644 index 00000000000..4ff0b5fe57e --- /dev/null +++ b/queue-6.6/alsa-emu10k1-move-the-whole-gpio-event-handling-to-t.patch @@ -0,0 +1,179 @@ +From 1e1ddc5fcab6cc323cf0dc4d8fab1ee310d2de43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Apr 2024 11:37:13 +0200 +Subject: ALSA: emu10k1: move the whole GPIO event handling to the workqueue + +From: Oswald Buddenhagen + +[ Upstream commit f848337cd801c7106a4ec0d61765771dab2a5909 ] + +The actual event processing was already done by workqueue items. We can +move the event dispatching there as well, rather than doing it already +in the interrupt handler callback. + +This change has a rather profound "side effect" on the reliability of +the FPGA programming: once we enter programming mode, we must not issue +any snd_emu1010_fpga_{read,write}() calls until we're done, as these +would badly mess up the programming protocol. But exactly that would +happen when trying to program the dock, as that triggers GPIO interrupts +as a side effect. This is mitigated by deferring the actual interrupt +handling, as workqueue items are not re-entrant. + +To avoid scheduling the dispatcher on non-events, we now explicitly +ignore GPIO IRQs triggered by "uninteresting" pins, which happens a lot +as a side effect of calling snd_emu1010_fpga_{read,write}(). + +Fixes: fbb64eedf5a3 ("ALSA: emu10k1: make E-MU dock monitoring interrupt-driven") +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218584 +Signed-off-by: Oswald Buddenhagen +Signed-off-by: Takashi Iwai +Message-ID: <20240428093716.3198666-4-oswald.buddenhagen@gmx.de> +Signed-off-by: Sasha Levin +--- + include/sound/emu10k1.h | 3 +- + sound/pci/emu10k1/emu10k1.c | 3 +- + sound/pci/emu10k1/emu10k1_main.c | 56 ++++++++++++++++---------------- + 3 files changed, 30 insertions(+), 32 deletions(-) + +diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h +index 1af9e68193920..9cc10fab01a8c 100644 +--- a/include/sound/emu10k1.h ++++ b/include/sound/emu10k1.h +@@ -1684,8 +1684,7 @@ struct snd_emu1010 { + unsigned int clock_fallback; + unsigned int optical_in; /* 0:SPDIF, 1:ADAT */ + unsigned int optical_out; /* 0:SPDIF, 1:ADAT */ +- struct work_struct firmware_work; +- struct work_struct clock_work; ++ struct work_struct work; + }; + + struct snd_emu10k1 { +diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c +index fe72e7d772412..dadeda7758cee 100644 +--- a/sound/pci/emu10k1/emu10k1.c ++++ b/sound/pci/emu10k1/emu10k1.c +@@ -189,8 +189,7 @@ static int snd_emu10k1_suspend(struct device *dev) + + emu->suspend = 1; + +- cancel_work_sync(&emu->emu1010.firmware_work); +- cancel_work_sync(&emu->emu1010.clock_work); ++ cancel_work_sync(&emu->emu1010.work); + + snd_ac97_suspend(emu->ac97); + +diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c +index 6265fc9ae2606..86eaf5963502c 100644 +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -765,19 +765,10 @@ static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu) + msleep(10); + } + +-static void emu1010_firmware_work(struct work_struct *work) ++static void emu1010_dock_event(struct snd_emu10k1 *emu) + { +- struct snd_emu10k1 *emu; + u32 reg; + +- emu = container_of(work, struct snd_emu10k1, +- emu1010.firmware_work); +- if (emu->card->shutdown) +- return; +-#ifdef CONFIG_PM_SLEEP +- if (emu->suspend) +- return; +-#endif + snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ®); /* OPTIONS: Which cards are attached to the EMU */ + if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { + /* Audio Dock attached */ +@@ -792,20 +783,10 @@ static void emu1010_firmware_work(struct work_struct *work) + } + } + +-static void emu1010_clock_work(struct work_struct *work) ++static void emu1010_clock_event(struct snd_emu10k1 *emu) + { +- struct snd_emu10k1 *emu; + struct snd_ctl_elem_id id; + +- emu = container_of(work, struct snd_emu10k1, +- emu1010.clock_work); +- if (emu->card->shutdown) +- return; +-#ifdef CONFIG_PM_SLEEP +- if (emu->suspend) +- return; +-#endif +- + spin_lock_irq(&emu->reg_lock); + // This is the only thing that can actually happen. + emu->emu1010.clock_source = emu->emu1010.clock_fallback; +@@ -816,19 +797,40 @@ static void emu1010_clock_work(struct work_struct *work) + snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE, &id); + } + +-static void emu1010_interrupt(struct snd_emu10k1 *emu) ++static void emu1010_work(struct work_struct *work) + { ++ struct snd_emu10k1 *emu; + u32 sts; + ++ emu = container_of(work, struct snd_emu10k1, emu1010.work); ++ if (emu->card->shutdown) ++ return; ++#ifdef CONFIG_PM_SLEEP ++ if (emu->suspend) ++ return; ++#endif ++ + snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts); + + // The distinction of the IRQ status bits is unreliable, + // so we dispatch later based on option card status. + if (sts & (EMU_HANA_IRQ_DOCK | EMU_HANA_IRQ_DOCK_LOST)) +- schedule_work(&emu->emu1010.firmware_work); ++ emu1010_dock_event(emu); + + if (sts & EMU_HANA_IRQ_WCLK_CHANGED) +- schedule_work(&emu->emu1010.clock_work); ++ emu1010_clock_event(emu); ++} ++ ++static void emu1010_interrupt(struct snd_emu10k1 *emu) ++{ ++ // We get an interrupt on each GPIO input pin change, but we ++ // care only about the ones triggered by the dedicated pin. ++ u16 sts = inw(emu->port + A_GPIO); ++ u16 bit = emu->card_capabilities->ca0108_chip ? 0x2000 : 0x8000; ++ if (!(sts & bit)) ++ return; ++ ++ schedule_work(&emu->emu1010.work); + } + + /* +@@ -969,8 +971,7 @@ static void snd_emu10k1_free(struct snd_card *card) + /* Disable 48Volt power to Audio Dock */ + snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0); + } +- cancel_work_sync(&emu->emu1010.firmware_work); +- cancel_work_sync(&emu->emu1010.clock_work); ++ cancel_work_sync(&emu->emu1010.work); + release_firmware(emu->firmware); + release_firmware(emu->dock_fw); + snd_util_memhdr_free(emu->memhdr); +@@ -1549,8 +1550,7 @@ int snd_emu10k1_create(struct snd_card *card, + emu->irq = -1; + emu->synth = NULL; + emu->get_synth_voice = NULL; +- INIT_WORK(&emu->emu1010.firmware_work, emu1010_firmware_work); +- INIT_WORK(&emu->emu1010.clock_work, emu1010_clock_work); ++ INIT_WORK(&emu->emu1010.work, emu1010_work); + /* read revision & serial */ + emu->revision = pci->revision; + pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); +-- +2.43.0 + diff --git a/queue-6.6/alsa-hda-intel-sdw-acpi-fix-usage-of-device_get_name.patch b/queue-6.6/alsa-hda-intel-sdw-acpi-fix-usage-of-device_get_name.patch new file mode 100644 index 00000000000..d34b616819c --- /dev/null +++ b/queue-6.6/alsa-hda-intel-sdw-acpi-fix-usage-of-device_get_name.patch @@ -0,0 +1,44 @@ +From 9e15bcfcb73e1c53ba052bcbbe29f6908a7eed7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 10:27:31 -0500 +Subject: ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node() + +From: Pierre-Louis Bossart + +[ Upstream commit c158cf914713efc3bcdc25680c7156c48c12ef6a ] + +The documentation for device_get_named_child_node() mentions this +important point: + +" +The caller is responsible for calling fwnode_handle_put() on the +returned fwnode pointer. +" + +Add fwnode_handle_put() to avoid a leaked reference. + +Signed-off-by: Pierre-Louis Bossart +Fixes: 08c2a4bc9f2a ("ALSA: hda: move Intel SoundWire ACPI scan to dedicated module") +Message-ID: <20240426152731.38420-1-pierre-louis.bossart@linux.intel.com> +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/intel-sdw-acpi.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/hda/intel-sdw-acpi.c b/sound/hda/intel-sdw-acpi.c +index b57d72ea4503f..4e376994bf78b 100644 +--- a/sound/hda/intel-sdw-acpi.c ++++ b/sound/hda/intel-sdw-acpi.c +@@ -41,6 +41,8 @@ static bool is_link_enabled(struct fwnode_handle *fw_node, u8 idx) + "intel-quirk-mask", + &quirk_mask); + ++ fwnode_handle_put(link); ++ + if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE) + return false; + +-- +2.43.0 + diff --git a/queue-6.6/asoc-codecs-wsa881x-set-clk_stop_mode1-flag.patch b/queue-6.6/asoc-codecs-wsa881x-set-clk_stop_mode1-flag.patch new file mode 100644 index 00000000000..b7aada981b4 --- /dev/null +++ b/queue-6.6/asoc-codecs-wsa881x-set-clk_stop_mode1-flag.patch @@ -0,0 +1,36 @@ +From 32284cee55dbd66109603e0d491c644df7e2bb6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Apr 2024 15:00:12 +0100 +Subject: ASoC: codecs: wsa881x: set clk_stop_mode1 flag + +From: Srinivas Kandagatla + +[ Upstream commit 32ac501957e5f68fe0e4bf88fb4db75cfb8f6566 ] + +WSA881x codecs do not retain the state while clock is stopped, so mark +this with clk_stop_mode1 flag. + +Fixes: a0aab9e1404a ("ASoC: codecs: add wsa881x amplifier support") +Signed-off-by: Srinivas Kandagatla +Link: https://lore.kernel.org/r/20240419140012.91384-1-srinivas.kandagatla@linaro.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/wsa881x.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c +index 3c025dabaf7a4..1253695bebd86 100644 +--- a/sound/soc/codecs/wsa881x.c ++++ b/sound/soc/codecs/wsa881x.c +@@ -1155,6 +1155,7 @@ static int wsa881x_probe(struct sdw_slave *pdev, + pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; ++ pdev->prop.clk_stop_mode1 = true; + gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val); + + wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config); +-- +2.43.0 + diff --git a/queue-6.6/asoc-intel-avs-set-name-of-control-as-in-topology.patch b/queue-6.6/asoc-intel-avs-set-name-of-control-as-in-topology.patch new file mode 100644 index 00000000000..ac4ba896273 --- /dev/null +++ b/queue-6.6/asoc-intel-avs-set-name-of-control-as-in-topology.patch @@ -0,0 +1,45 @@ +From 7c20b0ea6c1c5c2251865bb4bd1e31a8a734b250 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 16:26:21 +0200 +Subject: ASoC: Intel: avs: Set name of control as in topology +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Amadeusz Sławiński + +[ Upstream commit 4cbb5050bffc49c716381ea2ecb07306dd46f83a ] + +When creating controls attached to widgets, there are a lot of rules if +they get their name prefixed with widget name or not. Due to that +controls ended up with weirdly looking names like "ssp0_fe DSP Volume", +while topology set it to "DSP Volume". + +Fix this by setting no_wname_in_kcontrol_name to true in avs topology +widgets which disables unwanted behaviour. + +Fixes: be2b81b519d7 ("ASoC: Intel: avs: Parse control tuples") +Signed-off-by: Amadeusz Sławiński +Link: https://lore.kernel.org/r/20240418142621.2487478-1-amadeuszx.slawinski@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/avs/topology.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c +index 45d0eb2a8e710..141255420c12b 100644 +--- a/sound/soc/intel/avs/topology.c ++++ b/sound/soc/intel/avs/topology.c +@@ -1412,6 +1412,8 @@ static int avs_widget_load(struct snd_soc_component *comp, int index, + if (!le32_to_cpu(dw->priv.size)) + return 0; + ++ w->no_wname_in_kcontrol_name = true; ++ + if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) { + dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n"); + w->ignore_suspend = false; +-- +2.43.0 + diff --git a/queue-6.6/asoc-meson-axg-card-make-links-nonatomic.patch b/queue-6.6/asoc-meson-axg-card-make-links-nonatomic.patch new file mode 100644 index 00000000000..80b8442e5e6 --- /dev/null +++ b/queue-6.6/asoc-meson-axg-card-make-links-nonatomic.patch @@ -0,0 +1,38 @@ +From d02b5c44e2ff3189d99bb7cc7264f94bdd4caf49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 17:29:39 +0200 +Subject: ASoC: meson: axg-card: make links nonatomic + +From: Jerome Brunet + +[ Upstream commit dcba52ace7d4c12e2c8c273eff55ea03a84c8baf ] + +Non atomic operations need to be performed in the trigger callback +of the TDM interfaces. Those are BEs but what matters is the nonatomic +flag of the FE in the DPCM context. Just set nonatomic for everything so, +at least, what is done is clear. + +Fixes: 7864a79f37b5 ("ASoC: meson: add axg sound card support") +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20240426152946.3078805-3-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/meson/axg-card.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/meson/axg-card.c b/sound/soc/meson/axg-card.c +index f10c0c17863eb..b6f5b4572012d 100644 +--- a/sound/soc/meson/axg-card.c ++++ b/sound/soc/meson/axg-card.c +@@ -318,6 +318,7 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np, + + dai_link->cpus = cpu; + dai_link->num_cpus = 1; ++ dai_link->nonatomic = true; + + ret = meson_card_parse_dai(card, np, dai_link->cpus); + if (ret) +-- +2.43.0 + diff --git a/queue-6.6/asoc-meson-axg-fifo-use-field-helpers.patch b/queue-6.6/asoc-meson-axg-fifo-use-field-helpers.patch new file mode 100644 index 00000000000..146aa90979a --- /dev/null +++ b/queue-6.6/asoc-meson-axg-fifo-use-field-helpers.patch @@ -0,0 +1,208 @@ +From 499eb85031918f8974923c82b9aa9c63dd75c24b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Feb 2024 16:08:25 +0100 +Subject: ASoC: meson: axg-fifo: use FIELD helpers + +From: Jerome Brunet + +[ Upstream commit 9e6f39535c794adea6ba802a52c722d193c28124 ] + +Use FIELD_GET() and FIELD_PREP() helpers instead of doing it manually. + +Signed-off-by: Jerome Brunet +Link: https://msgid.link/r/20240227150826.573581-1-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Stable-dep-of: b11d26660dff ("ASoC: meson: axg-fifo: use threaded irq to check periods") +Signed-off-by: Sasha Levin +--- + sound/soc/meson/axg-fifo.c | 25 +++++++++++++------------ + sound/soc/meson/axg-fifo.h | 12 +++++------- + sound/soc/meson/axg-frddr.c | 5 +++-- + sound/soc/meson/axg-toddr.c | 22 ++++++++++------------ + 4 files changed, 31 insertions(+), 33 deletions(-) + +diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c +index bccfb770b3391..bde7598750064 100644 +--- a/sound/soc/meson/axg-fifo.c ++++ b/sound/soc/meson/axg-fifo.c +@@ -3,6 +3,7 @@ + // Copyright (c) 2018 BayLibre, SAS. + // Author: Jerome Brunet + ++#include + #include + #include + #include +@@ -145,8 +146,8 @@ int axg_fifo_pcm_hw_params(struct snd_soc_component *component, + /* Enable irq if necessary */ + irq_en = runtime->no_period_wakeup ? 0 : FIFO_INT_COUNT_REPEAT; + regmap_update_bits(fifo->map, FIFO_CTRL0, +- CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), +- CTRL0_INT_EN(irq_en)); ++ CTRL0_INT_EN, ++ FIELD_PREP(CTRL0_INT_EN, irq_en)); + + return 0; + } +@@ -176,9 +177,9 @@ int axg_fifo_pcm_hw_free(struct snd_soc_component *component, + { + struct axg_fifo *fifo = axg_fifo_data(ss); + +- /* Disable the block count irq */ ++ /* Disable irqs */ + regmap_update_bits(fifo->map, FIFO_CTRL0, +- CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), 0); ++ CTRL0_INT_EN, 0); + + return 0; + } +@@ -187,13 +188,13 @@ EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free); + static void axg_fifo_ack_irq(struct axg_fifo *fifo, u8 mask) + { + regmap_update_bits(fifo->map, FIFO_CTRL1, +- CTRL1_INT_CLR(FIFO_INT_MASK), +- CTRL1_INT_CLR(mask)); ++ CTRL1_INT_CLR, ++ FIELD_PREP(CTRL1_INT_CLR, mask)); + + /* Clear must also be cleared */ + regmap_update_bits(fifo->map, FIFO_CTRL1, +- CTRL1_INT_CLR(FIFO_INT_MASK), +- 0); ++ CTRL1_INT_CLR, ++ FIELD_PREP(CTRL1_INT_CLR, 0)); + } + + static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) +@@ -204,7 +205,7 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) + + regmap_read(fifo->map, FIFO_STATUS1, &status); + +- status = STATUS1_INT_STS(status) & FIFO_INT_MASK; ++ status = FIELD_GET(STATUS1_INT_STS, status); + if (status & FIFO_INT_COUNT_REPEAT) + snd_pcm_period_elapsed(ss); + else +@@ -254,15 +255,15 @@ int axg_fifo_pcm_open(struct snd_soc_component *component, + + /* Setup status2 so it reports the memory pointer */ + regmap_update_bits(fifo->map, FIFO_CTRL1, +- CTRL1_STATUS2_SEL_MASK, +- CTRL1_STATUS2_SEL(STATUS2_SEL_DDR_READ)); ++ CTRL1_STATUS2_SEL, ++ FIELD_PREP(CTRL1_STATUS2_SEL, STATUS2_SEL_DDR_READ)); + + /* Make sure the dma is initially disabled */ + __dma_enable(fifo, false); + + /* Disable irqs until params are ready */ + regmap_update_bits(fifo->map, FIFO_CTRL0, +- CTRL0_INT_EN(FIFO_INT_MASK), 0); ++ CTRL0_INT_EN, 0); + + /* Clear any pending interrupt */ + axg_fifo_ack_irq(fifo, FIFO_INT_MASK); +diff --git a/sound/soc/meson/axg-fifo.h b/sound/soc/meson/axg-fifo.h +index b63acd723c870..5b7d32c37991b 100644 +--- a/sound/soc/meson/axg-fifo.h ++++ b/sound/soc/meson/axg-fifo.h +@@ -42,21 +42,19 @@ struct snd_soc_pcm_runtime; + + #define FIFO_CTRL0 0x00 + #define CTRL0_DMA_EN BIT(31) +-#define CTRL0_INT_EN(x) ((x) << 16) ++#define CTRL0_INT_EN GENMASK(23, 16) + #define CTRL0_SEL_MASK GENMASK(2, 0) + #define CTRL0_SEL_SHIFT 0 + #define FIFO_CTRL1 0x04 +-#define CTRL1_INT_CLR(x) ((x) << 0) +-#define CTRL1_STATUS2_SEL_MASK GENMASK(11, 8) +-#define CTRL1_STATUS2_SEL(x) ((x) << 8) ++#define CTRL1_INT_CLR GENMASK(7, 0) ++#define CTRL1_STATUS2_SEL GENMASK(11, 8) + #define STATUS2_SEL_DDR_READ 0 +-#define CTRL1_FRDDR_DEPTH_MASK GENMASK(31, 24) +-#define CTRL1_FRDDR_DEPTH(x) ((x) << 24) ++#define CTRL1_FRDDR_DEPTH GENMASK(31, 24) + #define FIFO_START_ADDR 0x08 + #define FIFO_FINISH_ADDR 0x0c + #define FIFO_INT_ADDR 0x10 + #define FIFO_STATUS1 0x14 +-#define STATUS1_INT_STS(x) ((x) << 0) ++#define STATUS1_INT_STS GENMASK(7, 0) + #define FIFO_STATUS2 0x18 + #define FIFO_INIT_ADDR 0x24 + #define FIFO_CTRL2 0x28 +diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c +index 8c166a5f338ce..747a900c0bb22 100644 +--- a/sound/soc/meson/axg-frddr.c ++++ b/sound/soc/meson/axg-frddr.c +@@ -7,6 +7,7 @@ + * This driver implements the frontend playback DAI of AXG and G12A based SoCs + */ + ++#include + #include + #include + #include +@@ -59,8 +60,8 @@ static int axg_frddr_dai_hw_params(struct snd_pcm_substream *substream, + /* Trim the FIFO depth if the period is small to improve latency */ + depth = min(period, fifo->depth); + val = (depth / AXG_FIFO_BURST) - 1; +- regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH_MASK, +- CTRL1_FRDDR_DEPTH(val)); ++ regmap_update_bits(fifo->map, FIFO_CTRL1, CTRL1_FRDDR_DEPTH, ++ FIELD_PREP(CTRL1_FRDDR_DEPTH, val)); + + return 0; + } +diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c +index 1a0be177b8fe7..972ad99f31be2 100644 +--- a/sound/soc/meson/axg-toddr.c ++++ b/sound/soc/meson/axg-toddr.c +@@ -5,6 +5,7 @@ + + /* This driver implements the frontend capture DAI of AXG based SoCs */ + ++#include + #include + #include + #include +@@ -19,12 +20,9 @@ + #define CTRL0_TODDR_EXT_SIGNED BIT(29) + #define CTRL0_TODDR_PP_MODE BIT(28) + #define CTRL0_TODDR_SYNC_CH BIT(27) +-#define CTRL0_TODDR_TYPE_MASK GENMASK(15, 13) +-#define CTRL0_TODDR_TYPE(x) ((x) << 13) +-#define CTRL0_TODDR_MSB_POS_MASK GENMASK(12, 8) +-#define CTRL0_TODDR_MSB_POS(x) ((x) << 8) +-#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) +-#define CTRL0_TODDR_LSB_POS(x) ((x) << 3) ++#define CTRL0_TODDR_TYPE GENMASK(15, 13) ++#define CTRL0_TODDR_MSB_POS GENMASK(12, 8) ++#define CTRL0_TODDR_LSB_POS GENMASK(7, 3) + #define CTRL1_TODDR_FORCE_FINISH BIT(25) + #define CTRL1_SEL_SHIFT 28 + +@@ -76,12 +74,12 @@ static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream, + width = params_width(params); + + regmap_update_bits(fifo->map, FIFO_CTRL0, +- CTRL0_TODDR_TYPE_MASK | +- CTRL0_TODDR_MSB_POS_MASK | +- CTRL0_TODDR_LSB_POS_MASK, +- CTRL0_TODDR_TYPE(type) | +- CTRL0_TODDR_MSB_POS(TODDR_MSB_POS) | +- CTRL0_TODDR_LSB_POS(TODDR_MSB_POS - (width - 1))); ++ CTRL0_TODDR_TYPE | ++ CTRL0_TODDR_MSB_POS | ++ CTRL0_TODDR_LSB_POS, ++ FIELD_PREP(CTRL0_TODDR_TYPE, type) | ++ FIELD_PREP(CTRL0_TODDR_MSB_POS, TODDR_MSB_POS) | ++ FIELD_PREP(CTRL0_TODDR_LSB_POS, TODDR_MSB_POS - (width - 1))); + + return 0; + } +-- +2.43.0 + diff --git a/queue-6.6/asoc-meson-axg-fifo-use-threaded-irq-to-check-period.patch b/queue-6.6/asoc-meson-axg-fifo-use-threaded-irq-to-check-period.patch new file mode 100644 index 00000000000..5b9e36531c0 --- /dev/null +++ b/queue-6.6/asoc-meson-axg-fifo-use-threaded-irq-to-check-period.patch @@ -0,0 +1,89 @@ +From fe52528aa4911a0b6ede3514dc91bad7726e1883 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 17:29:38 +0200 +Subject: ASoC: meson: axg-fifo: use threaded irq to check periods + +From: Jerome Brunet + +[ Upstream commit b11d26660dff8d7430892008616452dc8e5fb0f3 ] + +With the AXG audio subsystem, there is a possible random channel shift on +TDM capture, when the slot number per lane is more than 2, and there is +more than one lane used. + +The problem has been there since the introduction of the axg audio support +but such scenario is pretty uncommon. This is why there is no loud +complains about the problem. + +Solving the problem require to make the links non-atomic and use the +trigger() callback to start FEs and BEs in the appropriate order. + +This was tried in the past and reverted because it caused the block irq to +sleep while atomic. However, instead of reverting, the solution is to call +snd_pcm_period_elapsed() in a non atomic context. + +Use the bottom half of a threaded IRQ to do so. + +Fixes: 6dc4fa179fb8 ("ASoC: meson: add axg fifo base driver") +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20240426152946.3078805-2-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/meson/axg-fifo.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c +index bde7598750064..94b169a5493b5 100644 +--- a/sound/soc/meson/axg-fifo.c ++++ b/sound/soc/meson/axg-fifo.c +@@ -204,18 +204,26 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) + unsigned int status; + + regmap_read(fifo->map, FIFO_STATUS1, &status); +- + status = FIELD_GET(STATUS1_INT_STS, status); ++ axg_fifo_ack_irq(fifo, status); ++ ++ /* Use the thread to call period elapsed on nonatomic links */ + if (status & FIFO_INT_COUNT_REPEAT) +- snd_pcm_period_elapsed(ss); +- else +- dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", +- status); ++ return IRQ_WAKE_THREAD; + +- /* Ack irqs */ +- axg_fifo_ack_irq(fifo, status); ++ dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", ++ status); ++ ++ return IRQ_NONE; ++} ++ ++static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id) ++{ ++ struct snd_pcm_substream *ss = dev_id; ++ ++ snd_pcm_period_elapsed(ss); + +- return IRQ_RETVAL(status); ++ return IRQ_HANDLED; + } + + int axg_fifo_pcm_open(struct snd_soc_component *component, +@@ -243,8 +251,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component, + if (ret) + return ret; + +- ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0, +- dev_name(dev), ss); ++ ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block, ++ axg_fifo_pcm_irq_block_thread, ++ IRQF_ONESHOT, dev_name(dev), ss); + if (ret) + return ret; + +-- +2.43.0 + diff --git a/queue-6.6/asoc-meson-axg-tdm-interface-manage-formatters-in-tr.patch b/queue-6.6/asoc-meson-axg-tdm-interface-manage-formatters-in-tr.patch new file mode 100644 index 00000000000..16a031435d5 --- /dev/null +++ b/queue-6.6/asoc-meson-axg-tdm-interface-manage-formatters-in-tr.patch @@ -0,0 +1,91 @@ +From cc178a55fc90ac49cf224feba401f5eb2fd7f116 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 17:29:40 +0200 +Subject: ASoC: meson: axg-tdm-interface: manage formatters in trigger + +From: Jerome Brunet + +[ Upstream commit f949ed458ad15a00d41b37c745ebadaef171aaae ] + +So far, the formatters have been reset/enabled using the .prepare() +callback. This was done in this callback because walking the formatters use +a mutex. A mutex is used because formatter handling require dealing +possibly slow clock operation. + +With the support of non-atomic, .trigger() callback may be used which also +allows to properly enable and disable formatters on start but also +pause/resume. + +This solve a random shift on TDMIN as well repeated samples on for TDMOUT. + +Fixes: d60e4f1e4be5 ("ASoC: meson: add tdm interface driver") +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20240426152946.3078805-4-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/meson/axg-tdm-interface.c | 34 ++++++++++++++++------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c +index 2cedbce738373..a71790908e178 100644 +--- a/sound/soc/meson/axg-tdm-interface.c ++++ b/sound/soc/meson/axg-tdm-interface.c +@@ -349,26 +349,31 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream, + return 0; + } + +-static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream, ++static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream, ++ int cmd, + struct snd_soc_dai *dai) + { +- struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); ++ struct axg_tdm_stream *ts = ++ snd_soc_dai_get_dma_data(dai, substream); + +- /* Stop all attached formatters */ +- axg_tdm_stream_stop(ts); ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ axg_tdm_stream_start(ts); ++ break; ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ case SNDRV_PCM_TRIGGER_STOP: ++ axg_tdm_stream_stop(ts); ++ break; ++ default: ++ return -EINVAL; ++ } + + return 0; + } + +-static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream); +- +- /* Force all attached formatters to update */ +- return axg_tdm_stream_reset(ts); +-} +- + static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai) + { + int stream; +@@ -412,8 +417,7 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = { + .set_fmt = axg_tdm_iface_set_fmt, + .startup = axg_tdm_iface_startup, + .hw_params = axg_tdm_iface_hw_params, +- .prepare = axg_tdm_iface_prepare, +- .hw_free = axg_tdm_iface_hw_free, ++ .trigger = axg_tdm_iface_trigger, + }; + + /* TDM Backend DAIs */ +-- +2.43.0 + diff --git a/queue-6.6/asoc-meson-cards-select-snd_dynamic_minors.patch b/queue-6.6/asoc-meson-cards-select-snd_dynamic_minors.patch new file mode 100644 index 00000000000..61fd3c24ee2 --- /dev/null +++ b/queue-6.6/asoc-meson-cards-select-snd_dynamic_minors.patch @@ -0,0 +1,43 @@ +From 979ecb5d4966ac867b42a61056a795db10e4e29d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 15:41:47 +0200 +Subject: ASoC: meson: cards: select SND_DYNAMIC_MINORS + +From: Jerome Brunet + +[ Upstream commit 6db26f9ea4edd8a17d39ab3c20111e3ccd704aef ] + +Amlogic sound cards do create a lot of pcm interfaces, possibly more than +8. Some pcm interfaces are internal (like DPCM backends and c2c) and not +exposed to userspace. + +Those interfaces still increase the number passed to snd_find_free_minor(), +which eventually exceeds 8 causing -EBUSY error on card registration if +CONFIG_SND_DYNAMIC_MINORS=n and the interface is exposed to userspace. + +select CONFIG_SND_DYNAMIC_MINORS for Amlogic cards to avoid the problem. + +Fixes: 7864a79f37b5 ("ASoC: meson: add axg sound card support") +Signed-off-by: Jerome Brunet +Link: https://lore.kernel.org/r/20240426134150.3053741-1-jbrunet@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/meson/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig +index b93ea33739f29..6458d5dc4902f 100644 +--- a/sound/soc/meson/Kconfig ++++ b/sound/soc/meson/Kconfig +@@ -99,6 +99,7 @@ config SND_MESON_AXG_PDM + + config SND_MESON_CARD_UTILS + tristate ++ select SND_DYNAMIC_MINORS + + config SND_MESON_CODEC_GLUE + tristate +-- +2.43.0 + diff --git a/queue-6.6/asoc-sof-intel-add-default-firmware-library-path-for.patch b/queue-6.6/asoc-sof-intel-add-default-firmware-library-path-for.patch new file mode 100644 index 00000000000..e32b85c575b --- /dev/null +++ b/queue-6.6/asoc-sof-intel-add-default-firmware-library-path-for.patch @@ -0,0 +1,44 @@ +From 9922a5fe9780eff6e4ccfd1d58dfb044c54542f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 14:41:45 -0500 +Subject: ASoC: SOF: Intel: add default firmware library path for LNL +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pierre-Louis Bossart + +[ Upstream commit 305539a25a1c9929b058381aac6104bd939c0fee ] + +The commit cd6f2a2e6346 ("ASoC: SOF: Intel: Set the default firmware +library path for IPC4") added the default_lib_path field for all +platforms, but this was missed when LunarLake was later introduced. + +Fixes: 64a63d9914a5 ("ASoC: SOF: Intel: LNL: Add support for Lunarlake platform") +Signed-off-by: Pierre-Louis Bossart +Reviewed-by: Péter Ujfalusi +Reviewed-by: Bard Liao +Link: https://msgid.link/r/20240408194147.28919-2-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/intel/pci-lnl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/sof/intel/pci-lnl.c b/sound/soc/sof/intel/pci-lnl.c +index 1b12c280edb46..7ad7aa3c3461b 100644 +--- a/sound/soc/sof/intel/pci-lnl.c ++++ b/sound/soc/sof/intel/pci-lnl.c +@@ -35,6 +35,9 @@ static const struct sof_dev_desc lnl_desc = { + .default_fw_path = { + [SOF_INTEL_IPC4] = "intel/sof-ipc4/lnl", + }, ++ .default_lib_path = { ++ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/lnl", ++ }, + .default_tplg_path = { + [SOF_INTEL_IPC4] = "intel/sof-ace-tplg", + }, +-- +2.43.0 + diff --git a/queue-6.6/asoc-sof-introduce-generic-names-for-ipc-types.patch b/queue-6.6/asoc-sof-introduce-generic-names-for-ipc-types.patch new file mode 100644 index 00000000000..d796a7852c8 --- /dev/null +++ b/queue-6.6/asoc-sof-introduce-generic-names-for-ipc-types.patch @@ -0,0 +1,52 @@ +From dc4f6577d2683a4baac5b0776c55735a651cbf39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 13:42:18 +0300 +Subject: ASoC: SOF: Introduce generic names for IPC types + +From: Peter Ujfalusi + +[ Upstream commit 6974f2cd2fa94fef663133af23722cf607853e22 ] + +Change the enum names for the IPC types to be more descriptive and drop +tying the IPC4 to Intel SoCs. + +Add defines to avoid build breakage while the related code is +modified to use the new enum names. + +Signed-off-by: Peter Ujfalusi +Reviewed-by: Daniel Baluta +Reviewed-by: Rander Wang +Reviewed-by: Ranjani Sridharan +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230919104226.32239-2-peter.ujfalusi@linux.intel.com +Signed-off-by: Mark Brown +Stable-dep-of: 305539a25a1c ("ASoC: SOF: Intel: add default firmware library path for LNL") +Signed-off-by: Sasha Levin +--- + include/sound/sof.h | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/include/sound/sof.h b/include/sound/sof.h +index 51294f2ba302c..31121c6df0272 100644 +--- a/include/sound/sof.h ++++ b/include/sound/sof.h +@@ -52,11 +52,14 @@ enum sof_dsp_power_states { + + /* Definitions for multiple IPCs */ + enum sof_ipc_type { +- SOF_IPC, +- SOF_INTEL_IPC4, ++ SOF_IPC_TYPE_3, ++ SOF_IPC_TYPE_4, + SOF_IPC_TYPE_COUNT + }; + ++#define SOF_IPC SOF_IPC_TYPE_3 ++#define SOF_INTEL_IPC4 SOF_IPC_TYPE_4 ++ + /* + * SOF Platform data. + */ +-- +2.43.0 + diff --git a/queue-6.6/bna-ensure-the-copied-buf-is-nul-terminated.patch b/queue-6.6/bna-ensure-the-copied-buf-is-nul-terminated.patch new file mode 100644 index 00000000000..08bebe04c03 --- /dev/null +++ b/queue-6.6/bna-ensure-the-copied-buf-is-nul-terminated.patch @@ -0,0 +1,49 @@ +From ba5d3bb06c0a5e14e62cc3cc7fd556d7f8156cca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 21:44:19 +0700 +Subject: bna: ensure the copied buf is NUL terminated + +From: Bui Quang Minh + +[ Upstream commit 8c34096c7fdf272fd4c0c37fe411cd2e3ed0ee9f ] + +Currently, we allocate a nbytes-sized kernel buffer and copy nbytes from +userspace to that buffer. Later, we use sscanf on this buffer but we don't +ensure that the string is terminated inside the buffer, this can lead to +OOB read when using sscanf. Fix this issue by using memdup_user_nul +instead of memdup_user. + +Fixes: 7afc5dbde091 ("bna: Add debugfs interface.") +Signed-off-by: Bui Quang Minh +Link: https://lore.kernel.org/r/20240424-fix-oob-read-v2-2-f1f1b53a10f4@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +index 7246e13dd559f..97291bfbeea58 100644 +--- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c ++++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +@@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, + void *kern_buf; + + /* Copy the user space buf */ +- kern_buf = memdup_user(buf, nbytes); ++ kern_buf = memdup_user_nul(buf, nbytes); + if (IS_ERR(kern_buf)) + return PTR_ERR(kern_buf); + +@@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf, + void *kern_buf; + + /* Copy the user space buf */ +- kern_buf = memdup_user(buf, nbytes); ++ kern_buf = memdup_user_nul(buf, nbytes); + if (IS_ERR(kern_buf)) + return PTR_ERR(kern_buf); + +-- +2.43.0 + diff --git a/queue-6.6/bpf-arm64-fix-incorrect-runtime-stats.patch b/queue-6.6/bpf-arm64-fix-incorrect-runtime-stats.patch new file mode 100644 index 00000000000..2ecaf1e375a --- /dev/null +++ b/queue-6.6/bpf-arm64-fix-incorrect-runtime-stats.patch @@ -0,0 +1,53 @@ +From 42da47f6ecb90530f61b1bbcabae865b91c393f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 14:42:07 +0800 +Subject: bpf, arm64: Fix incorrect runtime stats + +From: Xu Kuohai + +[ Upstream commit dc7d7447b56bcc9cf79a9c22e4edad200a298e4c ] + +When __bpf_prog_enter() returns zero, the arm64 register x20 that stores +prog start time is not assigned to zero, causing incorrect runtime stats. + +To fix it, assign the return value of bpf_prog_enter() to x20 register +immediately upon its return. + +Fixes: efc9909fdce0 ("bpf, arm64: Add bpf trampoline for arm64") +Reported-by: Ivan Babrou +Signed-off-by: Xu Kuohai +Signed-off-by: Daniel Borkmann +Tested-by: Ivan Babrou +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240416064208.2919073-2-xukuohai@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/arm64/net/bpf_jit_comp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c +index 29196dce9b91d..166619348b98e 100644 +--- a/arch/arm64/net/bpf_jit_comp.c ++++ b/arch/arm64/net/bpf_jit_comp.c +@@ -1738,15 +1738,15 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l, + + emit_call(enter_prog, ctx); + ++ /* save return value to callee saved register x20 */ ++ emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx); ++ + /* if (__bpf_prog_enter(prog) == 0) + * goto skip_exec_of_prog; + */ + branch = ctx->image + ctx->idx; + emit(A64_NOP, ctx); + +- /* save return value to callee saved register x20 */ +- emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx); +- + emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx); + if (!p->jited) + emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx); +-- +2.43.0 + diff --git a/queue-6.6/bpf-fix-a-verifier-verbose-message.patch b/queue-6.6/bpf-fix-a-verifier-verbose-message.patch new file mode 100644 index 00000000000..f60ab35e6ad --- /dev/null +++ b/queue-6.6/bpf-fix-a-verifier-verbose-message.patch @@ -0,0 +1,46 @@ +From 8db0a8e8e11ac48b3c6a12e4eb4c9875ffdeddc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Apr 2024 16:11:00 +0200 +Subject: bpf: Fix a verifier verbose message + +From: Anton Protopopov + +[ Upstream commit 37eacb9f6e89fb399a79e952bc9c78eb3e16290e ] + +Long ago a map file descriptor in a pseudo ldimm64 instruction could +only be present as an immediate value insn[0].imm, and thus this value +was used in a verbose verifier message printed when the file descriptor +wasn't valid. Since addition of BPF_PSEUDO_MAP_IDX_VALUE/BPF_PSEUDO_MAP_IDX +the insn[0].imm field can also contain an index pointing to the file +descriptor in the attr.fd_array array. However, if the file descriptor +is invalid, the verifier still prints the verbose message containing +value of insn[0].imm. Patch the verifier message to always print the +actual file descriptor value. + +Fixes: 387544bfa291 ("bpf: Introduce fd_idx") +Signed-off-by: Anton Protopopov +Signed-off-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240412141100.3562942-1-aspsk@isovalent.com +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index c9fc734989c68..818bac019d0d3 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -17655,8 +17655,7 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env) + f = fdget(fd); + map = __bpf_map_get(f); + if (IS_ERR(map)) { +- verbose(env, "fd %d is not pointing to valid bpf_map\n", +- insn[0].imm); ++ verbose(env, "fd %d is not pointing to valid bpf_map\n", fd); + return PTR_ERR(map); + } + +-- +2.43.0 + diff --git a/queue-6.6/bpf-kconfig-fix-debug_info_btf_modules-kconfig-defin.patch b/queue-6.6/bpf-kconfig-fix-debug_info_btf_modules-kconfig-defin.patch new file mode 100644 index 00000000000..32ed28069e3 --- /dev/null +++ b/queue-6.6/bpf-kconfig-fix-debug_info_btf_modules-kconfig-defin.patch @@ -0,0 +1,57 @@ +From ae969d98f50f010aacbcb1ecfc71a3a74939a068 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 15:03:44 -0700 +Subject: bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition + +From: Andrii Nakryiko + +[ Upstream commit 229087f6f1dc2d0c38feba805770f28529980ec0 ] + +Turns out that due to CONFIG_DEBUG_INFO_BTF_MODULES not having an +explicitly specified "menu item name" in Kconfig, it's basically +impossible to turn it off (see [0]). + +This patch fixes the issue by defining menu name for +CONFIG_DEBUG_INFO_BTF_MODULES, which makes it actually adjustable +and independent of CONFIG_DEBUG_INFO_BTF, in the sense that one can +have DEBUG_INFO_BTF=y and DEBUG_INFO_BTF_MODULES=n. + +We still keep it as defaulting to Y, of course. + +Fixes: 5f9ae91f7c0d ("kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it") +Reported-by: Vincent Li +Signed-off-by: Andrii Nakryiko +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/CAK3+h2xiFfzQ9UXf56nrRRP=p1+iUxGoEP5B+aq9MDT5jLXDSg@mail.gmail.com [0] +Link: https://lore.kernel.org/bpf/20240404220344.3879270-1-andrii@kernel.org +Signed-off-by: Sasha Levin +--- + lib/Kconfig.debug | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index d2f73bb4121b0..da5513cfc1258 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -373,7 +373,7 @@ config DEBUG_INFO_SPLIT + Incompatible with older versions of ccache. + + config DEBUG_INFO_BTF +- bool "Generate BTF typeinfo" ++ bool "Generate BTF type information" + depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED + depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST + depends on BPF_SYSCALL +@@ -404,7 +404,8 @@ config PAHOLE_HAS_LANG_EXCLUDE + using DEBUG_INFO_BTF_MODULES. + + config DEBUG_INFO_BTF_MODULES +- def_bool y ++ bool "Generate BTF type information for kernel modules" ++ default y + depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF + help + Generate compact split BTF type information for kernel modules. +-- +2.43.0 + diff --git a/queue-6.6/bpf-skmsg-fix-null-pointer-dereference-in-sk_psock_s.patch b/queue-6.6/bpf-skmsg-fix-null-pointer-dereference-in-sk_psock_s.patch new file mode 100644 index 00000000000..575f1da9d56 --- /dev/null +++ b/queue-6.6/bpf-skmsg-fix-null-pointer-dereference-in-sk_psock_s.patch @@ -0,0 +1,120 @@ +From 4fc05eabcf6459fcb8e02d8c72612d5cc387e865 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 10:10:01 +0800 +Subject: bpf, skmsg: Fix NULL pointer dereference in + sk_psock_skb_ingress_enqueue + +From: Jason Xing + +[ Upstream commit 6648e613226e18897231ab5e42ffc29e63fa3365 ] + +Fix NULL pointer data-races in sk_psock_skb_ingress_enqueue() which +syzbot reported [1]. + +[1] +BUG: KCSAN: data-race in sk_psock_drop / sk_psock_skb_ingress_enqueue + +write to 0xffff88814b3278b8 of 8 bytes by task 10724 on cpu 1: + sk_psock_stop_verdict net/core/skmsg.c:1257 [inline] + sk_psock_drop+0x13e/0x1f0 net/core/skmsg.c:843 + sk_psock_put include/linux/skmsg.h:459 [inline] + sock_map_close+0x1a7/0x260 net/core/sock_map.c:1648 + unix_release+0x4b/0x80 net/unix/af_unix.c:1048 + __sock_release net/socket.c:659 [inline] + sock_close+0x68/0x150 net/socket.c:1421 + __fput+0x2c1/0x660 fs/file_table.c:422 + __fput_sync+0x44/0x60 fs/file_table.c:507 + __do_sys_close fs/open.c:1556 [inline] + __se_sys_close+0x101/0x1b0 fs/open.c:1541 + __x64_sys_close+0x1f/0x30 fs/open.c:1541 + do_syscall_64+0xd3/0x1d0 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +read to 0xffff88814b3278b8 of 8 bytes by task 10713 on cpu 0: + sk_psock_data_ready include/linux/skmsg.h:464 [inline] + sk_psock_skb_ingress_enqueue+0x32d/0x390 net/core/skmsg.c:555 + sk_psock_skb_ingress_self+0x185/0x1e0 net/core/skmsg.c:606 + sk_psock_verdict_apply net/core/skmsg.c:1008 [inline] + sk_psock_verdict_recv+0x3e4/0x4a0 net/core/skmsg.c:1202 + unix_read_skb net/unix/af_unix.c:2546 [inline] + unix_stream_read_skb+0x9e/0xf0 net/unix/af_unix.c:2682 + sk_psock_verdict_data_ready+0x77/0x220 net/core/skmsg.c:1223 + unix_stream_sendmsg+0x527/0x860 net/unix/af_unix.c:2339 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x140/0x180 net/socket.c:745 + ____sys_sendmsg+0x312/0x410 net/socket.c:2584 + ___sys_sendmsg net/socket.c:2638 [inline] + __sys_sendmsg+0x1e9/0x280 net/socket.c:2667 + __do_sys_sendmsg net/socket.c:2676 [inline] + __se_sys_sendmsg net/socket.c:2674 [inline] + __x64_sys_sendmsg+0x46/0x50 net/socket.c:2674 + do_syscall_64+0xd3/0x1d0 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +value changed: 0xffffffff83d7feb0 -> 0x0000000000000000 + +Reported by Kernel Concurrency Sanitizer on: +CPU: 0 PID: 10713 Comm: syz-executor.4 Tainted: G W 6.8.0-syzkaller-08951-gfe46a7dd189e #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/29/2024 + +Prior to this, commit 4cd12c6065df ("bpf, sockmap: Fix NULL pointer +dereference in sk_psock_verdict_data_ready()") fixed one NULL pointer +similarly due to no protection of saved_data_ready. Here is another +different caller causing the same issue because of the same reason. So +we should protect it with sk_callback_lock read lock because the writer +side in the sk_psock_drop() uses "write_lock_bh(&sk->sk_callback_lock);". + +To avoid errors that could happen in future, I move those two pairs of +lock into the sk_psock_data_ready(), which is suggested by John Fastabend. + +Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface") +Reported-by: syzbot+aa8c8ec2538929f18f2d@syzkaller.appspotmail.com +Signed-off-by: Jason Xing +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Closes: https://syzkaller.appspot.com/bug?extid=aa8c8ec2538929f18f2d +Link: https://lore.kernel.org/all/20240329134037.92124-1-kerneljasonxing@gmail.com +Link: https://lore.kernel.org/bpf/20240404021001.94815-1-kerneljasonxing@gmail.com +Signed-off-by: Sasha Levin +--- + include/linux/skmsg.h | 2 ++ + net/core/skmsg.c | 5 +---- + 2 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index bd4418377bacf..062fe440f5d09 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -456,10 +456,12 @@ static inline void sk_psock_put(struct sock *sk, struct sk_psock *psock) + + static inline void sk_psock_data_ready(struct sock *sk, struct sk_psock *psock) + { ++ read_lock_bh(&sk->sk_callback_lock); + if (psock->saved_data_ready) + psock->saved_data_ready(sk); + else + sk->sk_data_ready(sk); ++ read_unlock_bh(&sk->sk_callback_lock); + } + + static inline void psock_set_prog(struct bpf_prog **pprog, +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index 4d75ef9d24bfa..fd20aae30be23 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -1226,11 +1226,8 @@ static void sk_psock_verdict_data_ready(struct sock *sk) + + rcu_read_lock(); + psock = sk_psock(sk); +- if (psock) { +- read_lock_bh(&sk->sk_callback_lock); ++ if (psock) + sk_psock_data_ready(sk, psock); +- read_unlock_bh(&sk->sk_callback_lock); +- } + rcu_read_unlock(); + } + } +-- +2.43.0 + diff --git a/queue-6.6/cxgb4-properly-lock-tx-queue-for-the-selftest.patch b/queue-6.6/cxgb4-properly-lock-tx-queue-for-the-selftest.patch new file mode 100644 index 00000000000..183070779ae --- /dev/null +++ b/queue-6.6/cxgb4-properly-lock-tx-queue-for-the-selftest.patch @@ -0,0 +1,62 @@ +From 33414aa81ccdab06512054d5d1e0c0b94bf98a29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 11:11:47 +0200 +Subject: cxgb4: Properly lock TX queue for the selftest. + +From: Sebastian Andrzej Siewior + +[ Upstream commit 9067eccdd7849dd120d5495dbd5a686fa6ed2c1a ] + +The selftest for the driver sends a dummy packet and checks if the +packet will be received properly as it should be. The regular TX path +and the selftest can use the same network queue so locking is required +and was missing in the selftest path. This was addressed in the commit +cited below. +Unfortunately locking the TX queue requires BH to be disabled which is +not the case in selftest path which is invoked in process context. +Lockdep should be complaining about this. + +Use __netif_tx_lock_bh() for TX queue locking. + +Fixes: c650e04898072 ("cxgb4: Fix race between loopback and normal Tx path") +Reported-by: "John B. Wyatt IV" +Closes: https://lore.kernel.org/all/Zic0ot5aGgR-V4Ks@thinkpad2021/ +Signed-off-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20240429091147.YWAaal4v@linutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/chelsio/cxgb4/sge.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index 98dd78551d89a..fff1ce835bc0d 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -2684,12 +2684,12 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev) + lb->loopback = 1; + + q = &adap->sge.ethtxq[pi->first_qset]; +- __netif_tx_lock(q->txq, smp_processor_id()); ++ __netif_tx_lock_bh(q->txq); + + reclaim_completed_tx(adap, &q->q, -1, true); + credits = txq_avail(&q->q) - ndesc; + if (unlikely(credits < 0)) { +- __netif_tx_unlock(q->txq); ++ __netif_tx_unlock_bh(q->txq); + return -ENOMEM; + } + +@@ -2724,7 +2724,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev) + init_completion(&lb->completion); + txq_advance(&q->q, ndesc); + cxgb4_ring_tx_db(adap, &q->q, ndesc); +- __netif_tx_unlock(q->txq); ++ __netif_tx_unlock_bh(q->txq); + + /* wait for the pkt to return */ + ret = wait_for_completion_timeout(&lb->completion, 10 * HZ); +-- +2.43.0 + diff --git a/queue-6.6/drm-amdgpu-fix-doorbell-regression.patch b/queue-6.6/drm-amdgpu-fix-doorbell-regression.patch new file mode 100644 index 00000000000..4b67a8cd97f --- /dev/null +++ b/queue-6.6/drm-amdgpu-fix-doorbell-regression.patch @@ -0,0 +1,40 @@ +From c24af57f3a3befc79bc64aa489e160691c50f44d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 14:29:47 +0200 +Subject: drm/amdgpu: fix doorbell regression + +From: Shashank Sharma + +[ Upstream commit 705d0480e6ae5a73ca3a9c04316d0678e19a46ed ] + +This patch adds a missed handling of PL domain doorbell while +handling VRAM faults. + +Cc: Christian Koenig +Cc: Alex Deucher +Fixes: a6ff969fe9cb ("drm/amdgpu: fix visible VRAM handling during faults") +Reviewed-by: Christian Koenig +Signed-off-by: Shashank Sharma +Signed-off-by: Arvind Yadav +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index d1687b5725693..b95018b1d2ae6 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -424,7 +424,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, + return false; + + if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT || +- res->mem_type == AMDGPU_PL_PREEMPT) ++ res->mem_type == AMDGPU_PL_PREEMPT || res->mem_type == AMDGPU_PL_DOORBELL) + return true; + + if (res->mem_type != TTM_PL_VRAM) +-- +2.43.0 + diff --git a/queue-6.6/drm-panel-ili9341-correct-use-of-device-property-api.patch b/queue-6.6/drm-panel-ili9341-correct-use-of-device-property-api.patch new file mode 100644 index 00000000000..02d4e4532f9 --- /dev/null +++ b/queue-6.6/drm-panel-ili9341-correct-use-of-device-property-api.patch @@ -0,0 +1,65 @@ +From 49125fc75bd74580c97e5012547866229a078a50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Apr 2024 17:26:17 +0300 +Subject: drm/panel: ili9341: Correct use of device property APIs + +From: Andy Shevchenko + +[ Upstream commit d43cd48ef1791801c61a54fade4a88d294dedf77 ] + +It seems driver missed the point of proper use of device property APIs. +Correct this by updating headers and calls respectively. + +Fixes: 5a04227326b0 ("drm/panel: Add ilitek ili9341 panel driver") +Signed-off-by: Andy Shevchenko +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20240425142706.2440113-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20240425142706.2440113-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/Kconfig | 2 +- + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig +index 869e535faefa3..3a2f4a9f1d466 100644 +--- a/drivers/gpu/drm/panel/Kconfig ++++ b/drivers/gpu/drm/panel/Kconfig +@@ -184,7 +184,7 @@ config DRM_PANEL_ILITEK_IL9322 + + config DRM_PANEL_ILITEK_ILI9341 + tristate "Ilitek ILI9341 240x320 QVGA panels" +- depends on OF && SPI ++ depends on SPI + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER + depends on BACKLIGHT_CLASS_DEVICE +diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +index 3574681891e81..7584ddb0e4416 100644 +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +@@ -22,8 +22,9 @@ + #include + #include + #include ++#include + #include +-#include ++#include + #include + #include + +@@ -691,7 +692,7 @@ static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc, + * Every new incarnation of this display must have a unique + * data entry for the system in this driver. + */ +- ili->conf = of_device_get_match_data(dev); ++ ili->conf = device_get_match_data(dev); + if (!ili->conf) { + dev_err(dev, "missing device configuration\n"); + return -ENODEV; +-- +2.43.0 + diff --git a/queue-6.6/drm-panel-ili9341-respect-deferred-probe.patch b/queue-6.6/drm-panel-ili9341-respect-deferred-probe.patch new file mode 100644 index 00000000000..296363a2165 --- /dev/null +++ b/queue-6.6/drm-panel-ili9341-respect-deferred-probe.patch @@ -0,0 +1,50 @@ +From b6133af81e22702cdec186dbbc49c9757c0b0354 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Apr 2024 17:26:18 +0300 +Subject: drm/panel: ili9341: Respect deferred probe + +From: Andy Shevchenko + +[ Upstream commit 740fc1e0509be3f7e2207e89125b06119ed62943 ] + +GPIO controller might not be available when driver is being probed. +There are plenty of reasons why, one of which is deferred probe. + +Since GPIOs are optional, return any error code we got to the upper +layer, including deferred probe. With that in mind, use dev_err_probe() +in order to avoid spamming the logs. + +Fixes: 5a04227326b0 ("drm/panel: Add ilitek ili9341 panel driver") +Signed-off-by: Andy Shevchenko +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Neil Armstrong +Reviewed-by: Sui Jingfeng +Link: https://lore.kernel.org/r/20240425142706.2440113-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20240425142706.2440113-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +index 7584ddb0e4416..24c74c56e5648 100644 +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +@@ -715,11 +715,11 @@ static int ili9341_probe(struct spi_device *spi) + + reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(reset)) +- dev_err(dev, "Failed to get gpio 'reset'\n"); ++ return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n"); + + dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); + if (IS_ERR(dc)) +- dev_err(dev, "Failed to get gpio 'dc'\n"); ++ return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n"); + + if (!strcmp(id->name, "sf-tc240t-9370-t")) + return ili9341_dpi_probe(spi, dc, reset); +-- +2.43.0 + diff --git a/queue-6.6/drm-panel-ili9341-use-predefined-error-codes.patch b/queue-6.6/drm-panel-ili9341-use-predefined-error-codes.patch new file mode 100644 index 00000000000..dde44af904f --- /dev/null +++ b/queue-6.6/drm-panel-ili9341-use-predefined-error-codes.patch @@ -0,0 +1,53 @@ +From f03054b57181215c8d535b6361b86a3e393436d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Apr 2024 17:26:19 +0300 +Subject: drm/panel: ili9341: Use predefined error codes + +From: Andy Shevchenko + +[ Upstream commit da85f0aaa9f21999753b01d45c0343f885a8f905 ] + +In one case the -1 is returned which is quite confusing code for +the wrong device ID, in another the ret is returning instead of +plain 0 that also confusing as readed may ask the possible meaning +of positive codes, which are never the case there. Convert both +to use explicit predefined error codes to make it clear what's going +on there. + +Fixes: 5a04227326b0 ("drm/panel: Add ilitek ili9341 panel driver") +Signed-off-by: Andy Shevchenko +Reviewed-by: Neil Armstrong +Reviewed-by: Sui Jingfeng +Link: https://lore.kernel.org/r/20240425142706.2440113-4-andriy.shevchenko@linux.intel.com +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20240425142706.2440113-4-andriy.shevchenko@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +index 24c74c56e5648..b933380b7eb78 100644 +--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c ++++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +@@ -422,7 +422,7 @@ static int ili9341_dpi_prepare(struct drm_panel *panel) + + ili9341_dpi_init(ili); + +- return ret; ++ return 0; + } + + static int ili9341_dpi_enable(struct drm_panel *panel) +@@ -726,7 +726,7 @@ static int ili9341_probe(struct spi_device *spi) + else if (!strcmp(id->name, "yx240qv29")) + return ili9341_dbi_probe(spi, dc, reset); + +- return -1; ++ return -ENODEV; + } + + static void ili9341_remove(struct spi_device *spi) +-- +2.43.0 + diff --git a/queue-6.6/fix-a-potential-infinite-loop-in-extract_user_to_sg.patch b/queue-6.6/fix-a-potential-infinite-loop-in-extract_user_to_sg.patch new file mode 100644 index 00000000000..f0f1202989d --- /dev/null +++ b/queue-6.6/fix-a-potential-infinite-loop-in-extract_user_to_sg.patch @@ -0,0 +1,45 @@ +From 9c43b5a006eda6364b06e921f2855b451acd06d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Apr 2024 09:39:32 +0100 +Subject: Fix a potential infinite loop in extract_user_to_sg() + +From: David Howells + +[ Upstream commit 6a30653b604aaad1bf0f2e74b068ceb8b6fc7aea ] + +Fix extract_user_to_sg() so that it will break out of the loop if +iov_iter_extract_pages() returns 0 rather than looping around forever. + +[Note that I've included two fixes lines as the function got moved to a +different file and renamed] + +Fixes: 85dd2c8ff368 ("netfs: Add a function to extract a UBUF or IOVEC into a BVEC iterator") +Fixes: f5f82cd18732 ("Move netfs_extract_iter_to_sg() to lib/scatterlist.c") +Signed-off-by: David Howells +cc: Jeff Layton +cc: Steve French +cc: Herbert Xu +cc: netfs@lists.linux.dev +Link: https://lore.kernel.org/r/1967121.1714034372@warthog.procyon.org.uk +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + lib/scatterlist.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/scatterlist.c b/lib/scatterlist.c +index 68b45c82c37a6..7bc2220fea805 100644 +--- a/lib/scatterlist.c ++++ b/lib/scatterlist.c +@@ -1124,7 +1124,7 @@ static ssize_t extract_user_to_sg(struct iov_iter *iter, + do { + res = iov_iter_extract_pages(iter, &pages, maxsize, sg_max, + extraction_flags, &off); +- if (res < 0) ++ if (res <= 0) + goto failed; + + len = res; +-- +2.43.0 + diff --git a/queue-6.6/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch b/queue-6.6/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch new file mode 100644 index 00000000000..0de91bb5189 --- /dev/null +++ b/queue-6.6/ipv4-fix-uninit-value-access-in-__ip_make_skb.patch @@ -0,0 +1,104 @@ +From b007c70343496e2e02d6108c9d905da606e21f48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 21:39:45 +0900 +Subject: ipv4: Fix uninit-value access in __ip_make_skb() + +From: Shigeru Yoshida + +[ Upstream commit fc1092f51567277509563800a3c56732070b6aa4 ] + +KMSAN reported uninit-value access in __ip_make_skb() [1]. __ip_make_skb() +tests HDRINCL to know if the skb has icmphdr. However, HDRINCL can cause a +race condition. If calling setsockopt(2) with IP_HDRINCL changes HDRINCL +while __ip_make_skb() is running, the function will access icmphdr in the +skb even if it is not included. This causes the issue reported by KMSAN. + +Check FLOWI_FLAG_KNOWN_NH on fl4->flowi4_flags instead of testing HDRINCL +on the socket. + +Also, fl4->fl4_icmp_type and fl4->fl4_icmp_code are not initialized. These +are union in struct flowi4 and are implicitly initialized by +flowi4_init_output(), but we should not rely on specific union layout. + +Initialize these explicitly in raw_sendmsg(). + +[1] +BUG: KMSAN: uninit-value in __ip_make_skb+0x2b74/0x2d20 net/ipv4/ip_output.c:1481 + __ip_make_skb+0x2b74/0x2d20 net/ipv4/ip_output.c:1481 + ip_finish_skb include/net/ip.h:243 [inline] + ip_push_pending_frames+0x4c/0x5c0 net/ipv4/ip_output.c:1508 + raw_sendmsg+0x2381/0x2690 net/ipv4/raw.c:654 + inet_sendmsg+0x27b/0x2a0 net/ipv4/af_inet.c:851 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x274/0x3c0 net/socket.c:745 + __sys_sendto+0x62c/0x7b0 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x130/0x200 net/socket.c:2199 + do_syscall_64+0xd8/0x1f0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +Uninit was created at: + slab_post_alloc_hook mm/slub.c:3804 [inline] + slab_alloc_node mm/slub.c:3845 [inline] + kmem_cache_alloc_node+0x5f6/0xc50 mm/slub.c:3888 + kmalloc_reserve+0x13c/0x4a0 net/core/skbuff.c:577 + __alloc_skb+0x35a/0x7c0 net/core/skbuff.c:668 + alloc_skb include/linux/skbuff.h:1318 [inline] + __ip_append_data+0x49ab/0x68c0 net/ipv4/ip_output.c:1128 + ip_append_data+0x1e7/0x260 net/ipv4/ip_output.c:1365 + raw_sendmsg+0x22b1/0x2690 net/ipv4/raw.c:648 + inet_sendmsg+0x27b/0x2a0 net/ipv4/af_inet.c:851 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg+0x274/0x3c0 net/socket.c:745 + __sys_sendto+0x62c/0x7b0 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x130/0x200 net/socket.c:2199 + do_syscall_64+0xd8/0x1f0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +CPU: 1 PID: 15709 Comm: syz-executor.7 Not tainted 6.8.0-11567-gb3603fcb79b1 #25 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-1.fc39 04/01/2014 + +Fixes: 99e5acae193e ("ipv4: Fix potential uninit variable access bug in __ip_make_skb()") +Reported-by: syzkaller +Signed-off-by: Shigeru Yoshida +Link: https://lore.kernel.org/r/20240430123945.2057348-1-syoshida@redhat.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/ip_output.c | 2 +- + net/ipv4/raw.c | 3 +++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 196495ff3977b..2458461e24874 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1469,7 +1469,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk, + * by icmp_hdr(skb)->type. + */ + if (sk->sk_type == SOCK_RAW && +- !inet_test_bit(HDRINCL, sk)) ++ !(fl4->flowi4_flags & FLOWI_FLAG_KNOWN_NH)) + icmp_type = fl4->fl4_icmp_type; + else + icmp_type = icmp_hdr(skb)->type; +diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c +index ee55d0cbe4e63..39834b95ee59a 100644 +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -604,6 +604,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) + (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), + daddr, saddr, 0, 0, sk->sk_uid); + ++ fl4.fl4_icmp_type = 0; ++ fl4.fl4_icmp_code = 0; ++ + if (!hdrincl) { + rfv.msg = msg; + rfv.hlen = 0; +-- +2.43.0 + diff --git a/queue-6.6/net-bridge-fix-multicast-to-unicast-with-fraglist-gs.patch b/queue-6.6/net-bridge-fix-multicast-to-unicast-with-fraglist-gs.patch new file mode 100644 index 00000000000..3ee71da2753 --- /dev/null +++ b/queue-6.6/net-bridge-fix-multicast-to-unicast-with-fraglist-gs.patch @@ -0,0 +1,39 @@ +From e6e7872eda70c3624e3a994d069f95fc580b1feb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Apr 2024 20:24:18 +0200 +Subject: net: bridge: fix multicast-to-unicast with fraglist GSO + +From: Felix Fietkau + +[ Upstream commit 59c878cbcdd80ed39315573b3511d0acfd3501b5 ] + +Calling skb_copy on a SKB_GSO_FRAGLIST skb is not valid, since it returns +an invalid linearized skb. This code only needs to change the ethernet +header, so pskb_copy is the right function to call here. + +Fixes: 6db6f0eae605 ("bridge: multicast to unicast") +Signed-off-by: Felix Fietkau +Acked-by: Paolo Abeni +Acked-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/bridge/br_forward.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c +index 7431f89e897b9..d7c35f55bd69f 100644 +--- a/net/bridge/br_forward.c ++++ b/net/bridge/br_forward.c +@@ -266,7 +266,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb, + if (skb->dev == p->dev && ether_addr_equal(src, addr)) + return; + +- skb = skb_copy(skb, GFP_ATOMIC); ++ skb = pskb_copy(skb, GFP_ATOMIC); + if (!skb) { + DEV_STATS_INC(dev, tx_dropped); + return; +-- +2.43.0 + diff --git a/queue-6.6/net-core-reject-skb_copy-_expand-for-fraglist-gso-sk.patch b/queue-6.6/net-core-reject-skb_copy-_expand-for-fraglist-gso-sk.patch new file mode 100644 index 00000000000..64c977ed203 --- /dev/null +++ b/queue-6.6/net-core-reject-skb_copy-_expand-for-fraglist-gso-sk.patch @@ -0,0 +1,73 @@ +From c20135e549c203e364748c32ad857ec80808c659 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Apr 2024 20:24:19 +0200 +Subject: net: core: reject skb_copy(_expand) for fraglist GSO skbs + +From: Felix Fietkau + +[ Upstream commit d091e579b864fa790dd6a0cd537a22c383126681 ] + +SKB_GSO_FRAGLIST skbs must not be linearized, otherwise they become +invalid. Return NULL if such an skb is passed to skb_copy or +skb_copy_expand, in order to prevent a crash on a potential later +call to skb_gso_segment. + +Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") +Signed-off-by: Felix Fietkau +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/skbuff.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 60876262b3fb3..f0a9ef1aeaa29 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1971,11 +1971,17 @@ static inline int skb_alloc_rx_flag(const struct sk_buff *skb) + + struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) + { +- int headerlen = skb_headroom(skb); +- unsigned int size = skb_end_offset(skb) + skb->data_len; +- struct sk_buff *n = __alloc_skb(size, gfp_mask, +- skb_alloc_rx_flag(skb), NUMA_NO_NODE); ++ struct sk_buff *n; ++ unsigned int size; ++ int headerlen; ++ ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; + ++ headerlen = skb_headroom(skb); ++ size = skb_end_offset(skb) + skb->data_len; ++ n = __alloc_skb(size, gfp_mask, ++ skb_alloc_rx_flag(skb), NUMA_NO_NODE); + if (!n) + return NULL; + +@@ -2303,12 +2309,17 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, + /* + * Allocate the copy buffer + */ +- struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom, +- gfp_mask, skb_alloc_rx_flag(skb), +- NUMA_NO_NODE); +- int oldheadroom = skb_headroom(skb); + int head_copy_len, head_copy_off; ++ struct sk_buff *n; ++ int oldheadroom; ++ ++ if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST)) ++ return NULL; + ++ oldheadroom = skb_headroom(skb); ++ n = __alloc_skb(newheadroom + skb->len + newtailroom, ++ gfp_mask, skb_alloc_rx_flag(skb), ++ NUMA_NO_NODE); + if (!n) + return NULL; + +-- +2.43.0 + diff --git a/queue-6.6/net-dsa-mv88e6xxx-fix-number-of-databases-for-88e614.patch b/queue-6.6/net-dsa-mv88e6xxx-fix-number-of-databases-for-88e614.patch new file mode 100644 index 00000000000..14ff1ee8408 --- /dev/null +++ b/queue-6.6/net-dsa-mv88e6xxx-fix-number-of-databases-for-88e614.patch @@ -0,0 +1,52 @@ +From 78f0f2f6b40ff25ebc0f4079d1739b5b416f3d5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Apr 2024 15:38:32 +0200 +Subject: net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Behún + +[ Upstream commit b9a61c20179fda7bdfe2c1210aa72451991ab81a ] + +The Topaz family (88E6141 and 88E6341) only support 256 Forwarding +Information Tables. + +Fixes: a75961d0ebfd ("net: dsa: mv88e6xxx: Add support for ethernet switch 88E6341") +Fixes: 1558727a1c1b ("net: dsa: mv88e6xxx: Add support for ethernet switch 88E6141") +Signed-off-by: Marek Behún +Reviewed-by: Andrew Lunn +Reviewed-by: Florian Fainelli +Link: https://lore.kernel.org/r/20240429133832.9547-1-kabel@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/mv88e6xxx/chip.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 8556502f06721..db1d9df7d47fe 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -5588,7 +5588,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { + .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, + .family = MV88E6XXX_FAMILY_6341, + .name = "Marvell 88E6141", +- .num_databases = 4096, ++ .num_databases = 256, + .num_macs = 2048, + .num_ports = 6, + .num_internal_phys = 5, +@@ -6047,7 +6047,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { + .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, + .family = MV88E6XXX_FAMILY_6341, + .name = "Marvell 88E6341", +- .num_databases = 4096, ++ .num_databases = 256, + .num_macs = 2048, + .num_internal_phys = 5, + .num_ports = 6, +-- +2.43.0 + diff --git a/queue-6.6/net-gro-add-flush-check-in-udp_gro_receive_segment.patch b/queue-6.6/net-gro-add-flush-check-in-udp_gro_receive_segment.patch new file mode 100644 index 00000000000..323b3ea16a2 --- /dev/null +++ b/queue-6.6/net-gro-add-flush-check-in-udp_gro_receive_segment.patch @@ -0,0 +1,61 @@ +From ba1fcd59b1bc712a623c6ee2684f50fc81ca0d74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 16:35:55 +0200 +Subject: net: gro: add flush check in udp_gro_receive_segment + +From: Richard Gobert + +[ Upstream commit 5babae777c61aa8a8679d59d3cdc54165ad96d42 ] + +GRO-GSO path is supposed to be transparent and as such L3 flush checks are +relevant to all UDP flows merging in GRO. This patch uses the same logic +and code from tcp_gro_receive, terminating merge if flush is non zero. + +Fixes: e20cf8d3f1f7 ("udp: implement GRO for plain UDP sockets.") +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/ipv4/udp_offload.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index 889d4926fc0c1..e5971890d637d 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -471,6 +471,7 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head, + struct sk_buff *p; + unsigned int ulen; + int ret = 0; ++ int flush; + + /* requires non zero csum, for symmetry with GSO */ + if (!uh->check) { +@@ -504,13 +505,22 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head, + return p; + } + ++ flush = NAPI_GRO_CB(p)->flush; ++ ++ if (NAPI_GRO_CB(p)->flush_id != 1 || ++ NAPI_GRO_CB(p)->count != 1 || ++ !NAPI_GRO_CB(p)->is_atomic) ++ flush |= NAPI_GRO_CB(p)->flush_id; ++ else ++ NAPI_GRO_CB(p)->is_atomic = false; ++ + /* Terminate the flow on len mismatch or if it grow "too much". + * Under small packet flood GRO count could elsewhere grow a lot + * leading to excessive truesize values. + * On len mismatch merge the first packet shorter than gso_size, + * otherwise complete the GRO packet. + */ +- if (ulen > ntohs(uh2->len)) { ++ if (ulen > ntohs(uh2->len) || flush) { + pp = p; + } else { + if (NAPI_GRO_CB(skb)->is_flist) { +-- +2.43.0 + diff --git a/queue-6.6/net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch b/queue-6.6/net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch new file mode 100644 index 00000000000..9a6133e676d --- /dev/null +++ b/queue-6.6/net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch @@ -0,0 +1,215 @@ +From cf53b12810d9a5c5d3094b618588f9be73ce5954 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 16:35:54 +0200 +Subject: net: gro: fix udp bad offset in socket lookup by adding + {inner_}network_offset to napi_gro_cb + +From: Richard Gobert + +[ Upstream commit 5ef31ea5d053a8f493a772ebad3f3ce82c35d845 ] + +Commits a602456 ("udp: Add GRO functions to UDP socket") and 57c67ff ("udp: +additional GRO support") introduce incorrect usage of {ip,ipv6}_hdr in the +complete phase of gro. The functions always return skb->network_header, +which in the case of encapsulated packets at the gro complete phase, is +always set to the innermost L3 of the packet. That means that calling +{ip,ipv6}_hdr for skbs which completed the GRO receive phase (both in +gro_list and *_gro_complete) when parsing an encapsulated packet's _outer_ +L3/L4 may return an unexpected value. + +This incorrect usage leads to a bug in GRO's UDP socket lookup. +udp{4,6}_lib_lookup_skb functions use ip_hdr/ipv6_hdr respectively. These +*_hdr functions return network_header which will point to the innermost L3, +resulting in the wrong offset being used in __udp{4,6}_lib_lookup with +encapsulated packets. + +This patch adds network_offset and inner_network_offset to napi_gro_cb, and +makes sure both are set correctly. + +To fix the issue, network_offsets union is used inside napi_gro_cb, in +which both the outer and the inner network offsets are saved. + +Reproduction example: + +Endpoint configuration example (fou + local address bind) + + # ip fou add port 6666 ipproto 4 + # ip link add name tun1 type ipip remote 2.2.2.1 local 2.2.2.2 encap fou encap-dport 5555 encap-sport 6666 mode ipip + # ip link set tun1 up + # ip a add 1.1.1.2/24 dev tun1 + +Netperf TCP_STREAM result on net-next before patch is applied: + +net-next main, GRO enabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.28 2.37 + +net-next main, GRO disabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.01 2745.06 + +patch applied, GRO enabled: + $ netperf -H 1.1.1.2 -t TCP_STREAM -l 5 + Recv Send Send + Socket Socket Message Elapsed + Size Size Size Time Throughput + bytes bytes bytes secs. 10^6bits/sec + + 131072 16384 16384 5.01 2877.38 + +Fixes: a6024562ffd7 ("udp: Add GRO functions to UDP socket") +Signed-off-by: Richard Gobert +Reviewed-by: Eric Dumazet +Reviewed-by: Willem de Bruijn +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/net/gro.h | 9 +++++++++ + net/8021q/vlan_core.c | 2 ++ + net/core/gro.c | 1 + + net/ipv4/af_inet.c | 1 + + net/ipv4/udp.c | 3 ++- + net/ipv4/udp_offload.c | 3 ++- + net/ipv6/ip6_offload.c | 1 + + net/ipv6/udp.c | 3 ++- + net/ipv6/udp_offload.c | 3 ++- + 9 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/include/net/gro.h b/include/net/gro.h +index 88644b3ca6600..018343254c90a 100644 +--- a/include/net/gro.h ++++ b/include/net/gro.h +@@ -86,6 +86,15 @@ struct napi_gro_cb { + + /* used to support CHECKSUM_COMPLETE for tunneling protocols */ + __wsum csum; ++ ++ /* L3 offsets */ ++ union { ++ struct { ++ u16 network_offset; ++ u16 inner_network_offset; ++ }; ++ u16 network_offsets[2]; ++ }; + }; + + #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) +diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c +index f001582345052..9404dd551dfd2 100644 +--- a/net/8021q/vlan_core.c ++++ b/net/8021q/vlan_core.c +@@ -478,6 +478,8 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head, + if (unlikely(!vhdr)) + goto out; + ++ NAPI_GRO_CB(skb)->network_offsets[NAPI_GRO_CB(skb)->encap_mark] = hlen; ++ + type = vhdr->h_vlan_encapsulated_proto; + + ptype = gro_find_receive_by_type(type); +diff --git a/net/core/gro.c b/net/core/gro.c +index cefddf65f7db0..31e40f25fdf10 100644 +--- a/net/core/gro.c ++++ b/net/core/gro.c +@@ -373,6 +373,7 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb, u32 nhoff) + const struct skb_shared_info *pinfo = skb_shinfo(skb); + const skb_frag_t *frag0 = &pinfo->frags[0]; + ++ NAPI_GRO_CB(skb)->network_offset = 0; + NAPI_GRO_CB(skb)->data_offset = 0; + NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index e59962f34caa6..b50308105551f 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1571,6 +1571,7 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) + /* The above will be needed by the transport layer if there is one + * immediately following this IP hdr. + */ ++ NAPI_GRO_CB(skb)->inner_network_offset = off; + + /* Note : No need to call skb_gro_postpull_rcsum() here, + * as we already checked checksum over ipv4 header was 0 +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 5e9219623c0a6..ca576587f6d21 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -534,7 +534,8 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, + struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb, + __be16 sport, __be16 dport) + { +- const struct iphdr *iph = ip_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset); + struct net *net = dev_net(skb->dev); + int iif, sdif; + +diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c +index c3d67423ae189..889d4926fc0c1 100644 +--- a/net/ipv4/udp_offload.c ++++ b/net/ipv4/udp_offload.c +@@ -718,7 +718,8 @@ EXPORT_SYMBOL(udp_gro_complete); + + INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff) + { +- const struct iphdr *iph = ip_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct iphdr *iph = (struct iphdr *)(skb->data + offset); + struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); + + /* do fraglist only if there is no outer UDP encap (or we already processed it) */ +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index f6e5fcdf041d1..7f014a8969fb2 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -240,6 +240,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, + goto out; + + skb_set_network_header(skb, off); ++ NAPI_GRO_CB(skb)->inner_network_offset = off; + + flush += ntohs(iph->payload_len) != skb->len - hlen; + +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index a05c83cfdde97..124cf2bb2a6d7 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -275,7 +275,8 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, + struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, + __be16 sport, __be16 dport) + { +- const struct ipv6hdr *iph = ipv6_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + offset); + struct net *net = dev_net(skb->dev); + int iif, sdif; + +diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c +index 626d7b362dc7b..639a4b506f9b5 100644 +--- a/net/ipv6/udp_offload.c ++++ b/net/ipv6/udp_offload.c +@@ -164,7 +164,8 @@ struct sk_buff *udp6_gro_receive(struct list_head *head, struct sk_buff *skb) + + INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff) + { +- const struct ipv6hdr *ipv6h = ipv6_hdr(skb); ++ const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation]; ++ const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + offset); + struct udphdr *uh = (struct udphdr *)(skb->data + nhoff); + + /* do fraglist only if there is no outer UDP encap (or we already processed it) */ +-- +2.43.0 + diff --git a/queue-6.6/net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch b/queue-6.6/net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch new file mode 100644 index 00000000000..ec2dcccab46 --- /dev/null +++ b/queue-6.6/net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch @@ -0,0 +1,121 @@ +From 93bf9a54def74d302b370cd11150cf2a02eb6a7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jan 2024 15:44:21 +0100 +Subject: net: gro: parse ipv6 ext headers without frag0 invalidation + +From: Richard Gobert + +[ Upstream commit dff0b0161ad571f888d37f5e7163a07dcafdef60 ] + +The existing code always pulls the IPv6 header and sets the transport +offset initially. Then optionally again pulls any extension headers in +ipv6_gso_pull_exthdrs and sets the transport offset again on return from +that call. skb->data is set at the start of the first extension header +before calling ipv6_gso_pull_exthdrs, and must disable the frag0 +optimization because that function uses pskb_may_pull/pskb_pull instead of +skb_gro_ helpers. It sets the GRO offset to the TCP header with +skb_gro_pull and sets the transport header. Then returns skb->data to its +position before this block. + +This commit introduces a new helper function - ipv6_gro_pull_exthdrs - +which is used in ipv6_gro_receive to pull ipv6 ext headers instead of +ipv6_gso_pull_exthdrs. Thus, there is no modification of skb->data, all +operations use skb_gro_* helpers, and the frag0 fast path can be taken for +IPv6 packets with ext headers. + +Signed-off-by: Richard Gobert +Reviewed-by: Willem de Bruijn +Reviewed-by: David Ahern +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/504130f6-b56c-4dcc-882c-97942c59f5b7@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 5ef31ea5d053 ("net: gro: fix udp bad offset in socket lookup by adding {inner_}network_offset to napi_gro_cb") +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_offload.c | 51 +++++++++++++++++++++++++++++++++--------- + 1 file changed, 41 insertions(+), 10 deletions(-) + +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index d6314287338da..f6e5fcdf041d1 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -37,6 +37,40 @@ + INDIRECT_CALL_L4(cb, f2, f1, head, skb); \ + }) + ++static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto) ++{ ++ const struct net_offload *ops = NULL; ++ struct ipv6_opt_hdr *opth; ++ ++ for (;;) { ++ int len; ++ ++ ops = rcu_dereference(inet6_offloads[proto]); ++ ++ if (unlikely(!ops)) ++ break; ++ ++ if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) ++ break; ++ ++ opth = skb_gro_header(skb, off + sizeof(*opth), off); ++ if (unlikely(!opth)) ++ break; ++ ++ len = ipv6_optlen(opth); ++ ++ opth = skb_gro_header(skb, off + len, off); ++ if (unlikely(!opth)) ++ break; ++ proto = opth->nexthdr; ++ ++ off += len; ++ } ++ ++ skb_gro_pull(skb, off - skb_network_offset(skb)); ++ return proto; ++} ++ + static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) + { + const struct net_offload *ops = NULL; +@@ -206,28 +240,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, + goto out; + + skb_set_network_header(skb, off); +- skb_gro_pull(skb, sizeof(*iph)); +- skb_set_transport_header(skb, skb_gro_offset(skb)); + +- flush += ntohs(iph->payload_len) != skb_gro_len(skb); ++ flush += ntohs(iph->payload_len) != skb->len - hlen; + + proto = iph->nexthdr; + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) { +- pskb_pull(skb, skb_gro_offset(skb)); +- skb_gro_frag0_invalidate(skb); +- proto = ipv6_gso_pull_exthdrs(skb, proto); +- skb_gro_pull(skb, -skb_transport_offset(skb)); +- skb_reset_transport_header(skb); +- __skb_push(skb, skb_gro_offset(skb)); ++ proto = ipv6_gro_pull_exthdrs(skb, hlen, proto); + + ops = rcu_dereference(inet6_offloads[proto]); + if (!ops || !ops->callbacks.gro_receive) + goto out; + +- iph = ipv6_hdr(skb); ++ iph = skb_gro_network_header(skb); ++ } else { ++ skb_gro_pull(skb, sizeof(*iph)); + } + ++ skb_set_transport_header(skb, skb_gro_offset(skb)); ++ + NAPI_GRO_CB(skb)->proto = proto; + + flush--; +-- +2.43.0 + diff --git a/queue-6.6/net-l2tp-drop-flow-hash-on-forward.patch b/queue-6.6/net-l2tp-drop-flow-hash-on-forward.patch new file mode 100644 index 00000000000..31d7ff6441d --- /dev/null +++ b/queue-6.6/net-l2tp-drop-flow-hash-on-forward.patch @@ -0,0 +1,49 @@ +From 5c78370d4da879436d331b6b62a776492f516096 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 19:11:10 +0200 +Subject: net l2tp: drop flow hash on forward + +From: David Bauer + +[ Upstream commit 42f853b42899d9b445763b55c3c8adc72be0f0e1 ] + +Drop the flow-hash of the skb when forwarding to the L2TP netdev. + +This avoids the L2TP qdisc from using the flow-hash from the outer +packet, which is identical for every flow within the tunnel. + +This does not affect every platform but is specific for the ethernet +driver. It depends on the platform including L4 information in the +flow-hash. + +One such example is the Mediatek Filogic MT798x family of networking +processors. + +Fixes: d9e31d17ceba ("l2tp: Add L2TP ethernet pseudowire support") +Acked-by: James Chapman +Signed-off-by: David Bauer +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240424171110.13701-1-mail@david-bauer.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/l2tp/l2tp_eth.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c +index f2ae03c404736..1f41d2f3b8c4e 100644 +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -136,6 +136,9 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, + /* checksums verified by L2TP */ + skb->ip_summed = CHECKSUM_NONE; + ++ /* drop outer flow-hash */ ++ skb_clear_hash(skb); ++ + skb_dst_drop(skb); + nf_reset_ct(skb); + +-- +2.43.0 + diff --git a/queue-6.6/net-qede-sanitize-rc-in-qede_add_tc_flower_fltr.patch b/queue-6.6/net-qede-sanitize-rc-in-qede_add_tc_flower_fltr.patch new file mode 100644 index 00000000000..da8df9ffa11 --- /dev/null +++ b/queue-6.6/net-qede-sanitize-rc-in-qede_add_tc_flower_fltr.patch @@ -0,0 +1,76 @@ +From 30fa33c80a2d10bc037ac3419165009d73ef85c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 09:12:23 +0000 +Subject: net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Asbjørn Sloth Tønnesen + +[ Upstream commit e25714466abd9d96901b15efddf82c60a38abd86 ] + +Explicitly set 'rc' (return code), before jumping to the +unlock and return path. + +By not having any code depend on that 'rc' remains at +it's initial value of -EINVAL, then we can re-use 'rc' for +the return code of function calls in subsequent patches. + +Only compile tested. + +Signed-off-by: Asbjørn Sloth Tønnesen +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Stable-dep-of: fcee2065a178 ("net: qede: use return from qede_parse_flow_attr() for flower") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qede/qede_filter.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c +index a5ac21a0ee33f..8ecdfa36a6854 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c +@@ -1868,8 +1868,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, + struct flow_cls_offload *f) + { + struct qede_arfs_fltr_node *n; +- int min_hlen, rc = -EINVAL; + struct qede_arfs_tuple t; ++ int min_hlen, rc; + + __qede_lock(edev); + +@@ -1879,8 +1879,10 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, + } + + /* parse flower attribute and prepare filter */ +- if (qede_parse_flow_attr(edev, proto, f->rule, &t)) ++ if (qede_parse_flow_attr(edev, proto, f->rule, &t)) { ++ rc = -EINVAL; + goto unlock; ++ } + + /* Validate profile mode and number of filters */ + if ((edev->arfs->filter_count && edev->arfs->mode != t.mode) || +@@ -1888,12 +1890,15 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, + DP_NOTICE(edev, + "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n", + t.mode, edev->arfs->mode, edev->arfs->filter_count); ++ rc = -EINVAL; + goto unlock; + } + + /* parse tc actions and get the vf_id */ +- if (qede_parse_actions(edev, &f->rule->action, f->common.extack)) ++ if (qede_parse_actions(edev, &f->rule->action, f->common.extack)) { ++ rc = -EINVAL; + goto unlock; ++ } + + if (qede_flow_find_fltr(edev, &t)) { + rc = -EEXIST; +-- +2.43.0 + diff --git a/queue-6.6/net-qede-use-return-from-qede_parse_actions.patch b/queue-6.6/net-qede-use-return-from-qede_parse_actions.patch new file mode 100644 index 00000000000..137ffa1d7bc --- /dev/null +++ b/queue-6.6/net-qede-use-return-from-qede_parse_actions.patch @@ -0,0 +1,57 @@ +From b1d2dc3825fe8732ed4f5cdcec024270bb9eb12d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 09:12:26 +0000 +Subject: net: qede: use return from qede_parse_actions() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Asbjørn Sloth Tønnesen + +[ Upstream commit f26f719a36e56381a1f4230e5364e7ad4d485888 ] + +When calling qede_parse_actions() then the +return code was only used for a non-zero check, +and then -EINVAL was returned. + +qede_parse_actions() can currently fail with: +* -EINVAL +* -EOPNOTSUPP + +This patch changes the code to use the actual +return code, not just return -EINVAL. + +The blaimed commit broke the implicit assumption +that only -EINVAL would ever be returned. + +Only compile tested. + +Fixes: 319a1d19471e ("flow_offload: check for basic action hw stats type") +Signed-off-by: Asbjørn Sloth Tønnesen +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c +index 377d661f70f78..cb6b33a228ea2 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c +@@ -1894,10 +1894,9 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, + } + + /* parse tc actions and get the vf_id */ +- if (qede_parse_actions(edev, &f->rule->action, f->common.extack)) { +- rc = -EINVAL; ++ rc = qede_parse_actions(edev, &f->rule->action, f->common.extack); ++ if (rc) + goto unlock; +- } + + if (qede_flow_find_fltr(edev, &t)) { + rc = -EEXIST; +-- +2.43.0 + diff --git a/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch b/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch new file mode 100644 index 00000000000..7e2ebad2538 --- /dev/null +++ b/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch @@ -0,0 +1,58 @@ +From 21d596086ffd7f8ba7a0a804a0913ba2416ce498 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 09:12:24 +0000 +Subject: net: qede: use return from qede_parse_flow_attr() for flower +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Asbjørn Sloth Tønnesen + +[ Upstream commit fcee2065a178f78be6fd516302830378b17dba3d ] + +In qede_add_tc_flower_fltr(), when calling +qede_parse_flow_attr() then the return code +was only used for a non-zero check, and then +-EINVAL was returned. + +qede_parse_flow_attr() can currently fail with: +* -EINVAL +* -EOPNOTSUPP +* -EPROTONOSUPPORT + +This patch changes the code to use the actual +return code, not just return -EINVAL. + +The blaimed commit introduced these functions. + +Only compile tested. + +Fixes: 2ce9c93eaca6 ("qede: Ingress tc flower offload (drop action) support.") +Signed-off-by: Asbjørn Sloth Tønnesen +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c +index 8ecdfa36a6854..25ef0f4258cb1 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c +@@ -1879,10 +1879,9 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, + } + + /* parse flower attribute and prepare filter */ +- if (qede_parse_flow_attr(edev, proto, f->rule, &t)) { +- rc = -EINVAL; ++ rc = qede_parse_flow_attr(edev, proto, f->rule, &t); ++ if (rc) + goto unlock; +- } + + /* Validate profile mode and number of filters */ + if ((edev->arfs->filter_count && edev->arfs->mode != t.mode) || +-- +2.43.0 + diff --git a/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch-1718 b/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch-1718 new file mode 100644 index 00000000000..e592727251e --- /dev/null +++ b/queue-6.6/net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch-1718 @@ -0,0 +1,60 @@ +From b7b73283d5e8ce1a8ce77d2fefeee5cfdfe65431 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 09:12:25 +0000 +Subject: net: qede: use return from qede_parse_flow_attr() for flow_spec +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Asbjørn Sloth Tønnesen + +[ Upstream commit 27b44414a34b108c5a37cd5b4894f606061d86e7 ] + +In qede_flow_spec_to_rule(), when calling +qede_parse_flow_attr() then the return code +was only used for a non-zero check, and then +-EINVAL was returned. + +qede_parse_flow_attr() can currently fail with: +* -EINVAL +* -EOPNOTSUPP +* -EPROTONOSUPPORT + +This patch changes the code to use the actual +return code, not just return -EINVAL. + +The blaimed commit introduced qede_flow_spec_to_rule(), +and this call to qede_parse_flow_attr(), it looks +like it just duplicated how it was already used. + +Only compile tested. + +Fixes: 37c5d3efd7f8 ("qede: use ethtool_rx_flow_rule() to remove duplicated parser code") +Signed-off-by: Asbjørn Sloth Tønnesen +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/qlogic/qede/qede_filter.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c +index 25ef0f4258cb1..377d661f70f78 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_filter.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c +@@ -2002,10 +2002,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev, + if (IS_ERR(flow)) + return PTR_ERR(flow); + +- if (qede_parse_flow_attr(edev, proto, flow->rule, t)) { +- err = -EINVAL; ++ err = qede_parse_flow_attr(edev, proto, flow->rule, t); ++ if (err) + goto err_out; +- } + + /* Make sure location is valid and filter isn't already set */ + err = qede_flow_spec_validate(edev, &flow->rule->action, t, +-- +2.43.0 + diff --git a/queue-6.6/nsh-restore-skb-protocol-data-mac_header-for-outer-h.patch b/queue-6.6/nsh-restore-skb-protocol-data-mac_header-for-outer-h.patch new file mode 100644 index 00000000000..4ebba231479 --- /dev/null +++ b/queue-6.6/nsh-restore-skb-protocol-data-mac_header-for-outer-h.patch @@ -0,0 +1,181 @@ +From 3386749c459fc62ef9cb4cf2e839ce751d724182 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 19:35:49 -0700 +Subject: nsh: Restore skb->{protocol,data,mac_header} for outer header in + nsh_gso_segment(). + +From: Kuniyuki Iwashima + +[ Upstream commit 4b911a9690d72641879ea6d13cce1de31d346d79 ] + +syzbot triggered various splats (see [0] and links) by a crafted GSO +packet of VIRTIO_NET_HDR_GSO_UDP layering the following protocols: + + ETH_P_8021AD + ETH_P_NSH + ETH_P_IPV6 + IPPROTO_UDP + +NSH can encapsulate IPv4, IPv6, Ethernet, NSH, and MPLS. As the inner +protocol can be Ethernet, NSH GSO handler, nsh_gso_segment(), calls +skb_mac_gso_segment() to invoke inner protocol GSO handlers. + +nsh_gso_segment() does the following for the original skb before +calling skb_mac_gso_segment() + + 1. reset skb->network_header + 2. save the original skb->{mac_heaeder,mac_len} in a local variable + 3. pull the NSH header + 4. resets skb->mac_header + 5. set up skb->mac_len and skb->protocol for the inner protocol. + +and does the following for the segmented skb + + 6. set ntohs(ETH_P_NSH) to skb->protocol + 7. push the NSH header + 8. restore skb->mac_header + 9. set skb->mac_header + mac_len to skb->network_header + 10. restore skb->mac_len + +There are two problems in 6-7 and 8-9. + + (a) + After 6 & 7, skb->data points to the NSH header, so the outer header + (ETH_P_8021AD in this case) is stripped when skb is sent out of netdev. + + Also, if NSH is encapsulated by NSH + Ethernet (so NSH-Ethernet-NSH), + skb_pull() in the first nsh_gso_segment() will make skb->data point + to the middle of the outer NSH or Ethernet header because the Ethernet + header is not pulled by the second nsh_gso_segment(). + + (b) + While restoring skb->{mac_header,network_header} in 8 & 9, + nsh_gso_segment() does not assume that the data in the linear + buffer is shifted. + + However, udp6_ufo_fragment() could shift the data and change + skb->mac_header accordingly as demonstrated by syzbot. + + If this happens, even the restored skb->mac_header points to + the middle of the outer header. + +It seems nsh_gso_segment() has never worked with outer headers so far. + +At the end of nsh_gso_segment(), the outer header must be restored for +the segmented skb, instead of the NSH header. + +To do that, let's calculate the outer header position relatively from +the inner header and set skb->{data,mac_header,protocol} properly. + +[0]: +BUG: KMSAN: uninit-value in ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:524 [inline] +BUG: KMSAN: uninit-value in ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] +BUG: KMSAN: uninit-value in ipvlan_queue_xmit+0xf44/0x16b0 drivers/net/ipvlan/ipvlan_core.c:668 + ipvlan_process_outbound drivers/net/ipvlan/ipvlan_core.c:524 [inline] + ipvlan_xmit_mode_l3 drivers/net/ipvlan/ipvlan_core.c:602 [inline] + ipvlan_queue_xmit+0xf44/0x16b0 drivers/net/ipvlan/ipvlan_core.c:668 + ipvlan_start_xmit+0x5c/0x1a0 drivers/net/ipvlan/ipvlan_main.c:222 + __netdev_start_xmit include/linux/netdevice.h:4989 [inline] + netdev_start_xmit include/linux/netdevice.h:5003 [inline] + xmit_one net/core/dev.c:3547 [inline] + dev_hard_start_xmit+0x244/0xa10 net/core/dev.c:3563 + __dev_queue_xmit+0x33ed/0x51c0 net/core/dev.c:4351 + dev_queue_xmit include/linux/netdevice.h:3171 [inline] + packet_xmit+0x9c/0x6b0 net/packet/af_packet.c:276 + packet_snd net/packet/af_packet.c:3081 [inline] + packet_sendmsg+0x8aef/0x9f10 net/packet/af_packet.c:3113 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + __sys_sendto+0x735/0xa10 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x125/0x1c0 net/socket.c:2199 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +Uninit was created at: + slab_post_alloc_hook mm/slub.c:3819 [inline] + slab_alloc_node mm/slub.c:3860 [inline] + __do_kmalloc_node mm/slub.c:3980 [inline] + __kmalloc_node_track_caller+0x705/0x1000 mm/slub.c:4001 + kmalloc_reserve+0x249/0x4a0 net/core/skbuff.c:582 + __alloc_skb+0x352/0x790 net/core/skbuff.c:651 + skb_segment+0x20aa/0x7080 net/core/skbuff.c:4647 + udp6_ufo_fragment+0xcab/0x1150 net/ipv6/udp_offload.c:109 + ipv6_gso_segment+0x14be/0x2ca0 net/ipv6/ip6_offload.c:152 + skb_mac_gso_segment+0x3e8/0x760 net/core/gso.c:53 + nsh_gso_segment+0x6f4/0xf70 net/nsh/nsh.c:108 + skb_mac_gso_segment+0x3e8/0x760 net/core/gso.c:53 + __skb_gso_segment+0x4b0/0x730 net/core/gso.c:124 + skb_gso_segment include/net/gso.h:83 [inline] + validate_xmit_skb+0x107f/0x1930 net/core/dev.c:3628 + __dev_queue_xmit+0x1f28/0x51c0 net/core/dev.c:4343 + dev_queue_xmit include/linux/netdevice.h:3171 [inline] + packet_xmit+0x9c/0x6b0 net/packet/af_packet.c:276 + packet_snd net/packet/af_packet.c:3081 [inline] + packet_sendmsg+0x8aef/0x9f10 net/packet/af_packet.c:3113 + sock_sendmsg_nosec net/socket.c:730 [inline] + __sock_sendmsg net/socket.c:745 [inline] + __sys_sendto+0x735/0xa10 net/socket.c:2191 + __do_sys_sendto net/socket.c:2203 [inline] + __se_sys_sendto net/socket.c:2199 [inline] + __x64_sys_sendto+0x125/0x1c0 net/socket.c:2199 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcf/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +CPU: 1 PID: 5101 Comm: syz-executor421 Not tainted 6.8.0-rc5-syzkaller-00297-gf2e367d6ad3b #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024 + +Fixes: c411ed854584 ("nsh: add GSO support") +Reported-and-tested-by: syzbot+42a0dc856239de4de60e@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=42a0dc856239de4de60e +Reported-and-tested-by: syzbot+c298c9f0e46a3c86332b@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=c298c9f0e46a3c86332b +Link: https://lore.kernel.org/netdev/20240415222041.18537-1-kuniyu@amazon.com/ +Signed-off-by: Kuniyuki Iwashima +Link: https://lore.kernel.org/r/20240424023549.21862-1-kuniyu@amazon.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/nsh/nsh.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c +index f4a38bd6a7e04..bfb7758063f31 100644 +--- a/net/nsh/nsh.c ++++ b/net/nsh/nsh.c +@@ -77,13 +77,15 @@ EXPORT_SYMBOL_GPL(nsh_pop); + static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { ++ unsigned int outer_hlen, mac_len, nsh_len; + struct sk_buff *segs = ERR_PTR(-EINVAL); + u16 mac_offset = skb->mac_header; +- unsigned int nsh_len, mac_len; +- __be16 proto; ++ __be16 outer_proto, proto; + + skb_reset_network_header(skb); + ++ outer_proto = skb->protocol; ++ outer_hlen = skb_mac_header_len(skb); + mac_len = skb->mac_len; + + if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) +@@ -113,10 +115,10 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, + } + + for (skb = segs; skb; skb = skb->next) { +- skb->protocol = htons(ETH_P_NSH); +- __skb_push(skb, nsh_len); +- skb->mac_header = mac_offset; +- skb->network_header = skb->mac_header + mac_len; ++ skb->protocol = outer_proto; ++ __skb_push(skb, nsh_len + outer_hlen); ++ skb_reset_mac_header(skb); ++ skb_set_network_header(skb, outer_hlen); + skb->mac_len = mac_len; + } + +-- +2.43.0 + diff --git a/queue-6.6/nvme-fix-warn-output-about-shared-namespaces-without.patch b/queue-6.6/nvme-fix-warn-output-about-shared-namespaces-without.patch new file mode 100644 index 00000000000..014e3db8b87 --- /dev/null +++ b/queue-6.6/nvme-fix-warn-output-about-shared-namespaces-without.patch @@ -0,0 +1,38 @@ +From 790a9a5705008e5c7e56afca2fb684bd9b5b9595 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Apr 2024 08:57:14 +0800 +Subject: nvme: fix warn output about shared namespaces without + CONFIG_NVME_MULTIPATH + +From: Yi Zhang + +[ Upstream commit 0bc2e80b9be51712b19e919db5abc97a418f8292 ] + +Move the stray '.' that is currently at the end of the line after +newline '\n' to before newline character which is the right position. + +Fixes: ce8d78616a6b ("nvme: warn about shared namespaces without CONFIG_NVME_MULTIPATH") +Signed-off-by: Yi Zhang +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 012c8b3f5f9c9..2db71e222fa7d 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3540,7 +3540,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info) + "Found shared namespace %d, but multipathing not supported.\n", + info->nsid); + dev_warn_once(ctrl->device, +- "Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0\n."); ++ "Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0.\n"); + } + } + +-- +2.43.0 + diff --git a/queue-6.6/octeontx2-af-avoid-off-by-one-read-from-userspace.patch b/queue-6.6/octeontx2-af-avoid-off-by-one-read-from-userspace.patch new file mode 100644 index 00000000000..4f791501bc9 --- /dev/null +++ b/queue-6.6/octeontx2-af-avoid-off-by-one-read-from-userspace.patch @@ -0,0 +1,44 @@ +From d2cec37a85bc8f245ca6329a35513be58ed264cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 21:44:23 +0700 +Subject: octeontx2-af: avoid off-by-one read from userspace + +From: Bui Quang Minh + +[ Upstream commit f299ee709fb45036454ca11e90cb2810fe771878 ] + +We try to access count + 1 byte from userspace with memdup_user(buffer, +count + 1). However, the userspace only provides buffer of count bytes and +only these count bytes are verified to be okay to access. To ensure the +copied buffer is NUL terminated, we use memdup_user_nul instead. + +Fixes: 3a2eb515d136 ("octeontx2-af: Fix an off by one in rvu_dbg_qsize_write()") +Signed-off-by: Bui Quang Minh +Link: https://lore.kernel.org/r/20240424-fix-oob-read-v2-6-f1f1b53a10f4@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +index d30e84803481d..feca86e429df2 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c +@@ -999,12 +999,10 @@ static ssize_t rvu_dbg_qsize_write(struct file *filp, + u16 pcifunc; + int ret, lf; + +- cmd_buf = memdup_user(buffer, count + 1); ++ cmd_buf = memdup_user_nul(buffer, count); + if (IS_ERR(cmd_buf)) + return -ENOMEM; + +- cmd_buf[count] = '\0'; +- + cmd_buf_tmp = strchr(cmd_buf, '\n'); + if (cmd_buf_tmp) { + *cmd_buf_tmp = '\0'; +-- +2.43.0 + diff --git a/queue-6.6/regmap-add-regmap_read_bypassed.patch b/queue-6.6/regmap-add-regmap_read_bypassed.patch new file mode 100644 index 00000000000..81a6d2eef31 --- /dev/null +++ b/queue-6.6/regmap-add-regmap_read_bypassed.patch @@ -0,0 +1,110 @@ +From d7b88e18b0566742867b94ea5c572d24ada3d148 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 11:18:00 +0100 +Subject: regmap: Add regmap_read_bypassed() + +From: Richard Fitzgerald + +[ Upstream commit 70ee853eec5693fefd8348a2b049d9cb83362e58 ] + +Add a regmap_read_bypassed() to allow reads from the hardware registers +while the regmap is in cache-only mode. + +A typical use for this is to keep the cache in cache-only mode until +the hardware has reached a valid state, but one or more status registers +must be polled to determine when this state is reached. + +For example, firmware download on the cs35l56 can take several seconds if +there are multiple amps sharing limited bus bandwidth. This is too long +to block in probe() so it is done as a background task. The device must +be soft-reset to reboot the firmware and during this time the registers are +not accessible, so the cache should be in cache-only. But the driver must +poll a register to detect when reboot has completed. + +Signed-off-by: Richard Fitzgerald +Fixes: 8a731fd37f8b ("ASoC: cs35l56: Move utility functions to shared file") +Link: https://msgid.link/r/20240408101803.43183-2-rf@opensource.cirrus.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/base/regmap/regmap.c | 37 ++++++++++++++++++++++++++++++++++++ + include/linux/regmap.h | 8 ++++++++ + 2 files changed, 45 insertions(+) + +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index ea61577471994..c5b5241891a5a 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -2836,6 +2836,43 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) + } + EXPORT_SYMBOL_GPL(regmap_read); + ++/** ++ * regmap_read_bypassed() - Read a value from a single register direct ++ * from the device, bypassing the cache ++ * ++ * @map: Register map to read from ++ * @reg: Register to be read from ++ * @val: Pointer to store read value ++ * ++ * A value of zero will be returned on success, a negative errno will ++ * be returned in error cases. ++ */ ++int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val) ++{ ++ int ret; ++ bool bypass, cache_only; ++ ++ if (!IS_ALIGNED(reg, map->reg_stride)) ++ return -EINVAL; ++ ++ map->lock(map->lock_arg); ++ ++ bypass = map->cache_bypass; ++ cache_only = map->cache_only; ++ map->cache_bypass = true; ++ map->cache_only = false; ++ ++ ret = _regmap_read(map, reg, val); ++ ++ map->cache_bypass = bypass; ++ map->cache_only = cache_only; ++ ++ map->unlock(map->lock_arg); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(regmap_read_bypassed); ++ + /** + * regmap_raw_read() - Read raw data from the device + * +diff --git a/include/linux/regmap.h b/include/linux/regmap.h +index c9182a47736ef..113261287af28 100644 +--- a/include/linux/regmap.h ++++ b/include/linux/regmap.h +@@ -1225,6 +1225,7 @@ int regmap_multi_reg_write_bypassed(struct regmap *map, + int regmap_raw_write_async(struct regmap *map, unsigned int reg, + const void *val, size_t val_len); + int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val); ++int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val); + int regmap_raw_read(struct regmap *map, unsigned int reg, + void *val, size_t val_len); + int regmap_noinc_read(struct regmap *map, unsigned int reg, +@@ -1734,6 +1735,13 @@ static inline int regmap_read(struct regmap *map, unsigned int reg, + return -EINVAL; + } + ++static inline int regmap_read_bypassed(struct regmap *map, unsigned int reg, ++ unsigned int *val) ++{ ++ WARN_ONCE(1, "regmap API is disabled"); ++ return -EINVAL; ++} ++ + static inline int regmap_raw_read(struct regmap *map, unsigned int reg, + void *val, size_t val_len) + { +-- +2.43.0 + diff --git a/queue-6.6/riscv-bpf-fix-incorrect-runtime-stats.patch b/queue-6.6/riscv-bpf-fix-incorrect-runtime-stats.patch new file mode 100644 index 00000000000..f724761d19e --- /dev/null +++ b/queue-6.6/riscv-bpf-fix-incorrect-runtime-stats.patch @@ -0,0 +1,54 @@ +From 3d95997810ca505e44b2d5d122e4312cf0e7416e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 14:42:08 +0800 +Subject: riscv, bpf: Fix incorrect runtime stats +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xu Kuohai + +[ Upstream commit 10541b374aa05c8118cc6a529a615882e53f261b ] + +When __bpf_prog_enter() returns zero, the s1 register is not set to zero, +resulting in incorrect runtime stats. Fix it by setting s1 immediately upon +the return of __bpf_prog_enter(). + +Fixes: 49b5e77ae3e2 ("riscv, bpf: Add bpf trampoline support for RV64") +Signed-off-by: Xu Kuohai +Signed-off-by: Daniel Borkmann +Reviewed-by: Pu Lehui +Acked-by: Björn Töpel +Link: https://lore.kernel.org/bpf/20240416064208.2919073-3-xukuohai@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/riscv/net/bpf_jit_comp64.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c +index 8581693e62d39..b3990874e4818 100644 +--- a/arch/riscv/net/bpf_jit_comp64.c ++++ b/arch/riscv/net/bpf_jit_comp64.c +@@ -740,6 +740,9 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of + if (ret) + return ret; + ++ /* store prog start time */ ++ emit_mv(RV_REG_S1, RV_REG_A0, ctx); ++ + /* if (__bpf_prog_enter(prog) == 0) + * goto skip_exec_of_prog; + */ +@@ -747,9 +750,6 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of + /* nop reserved for conditional jump */ + emit(rv_nop(), ctx); + +- /* store prog start time */ +- emit_mv(RV_REG_S1, RV_REG_A0, ctx); +- + /* arg1: &args_off */ + emit_addi(RV_REG_A0, RV_REG_FP, -args_off, ctx); + if (!p->jited) +-- +2.43.0 + diff --git a/queue-6.6/rxrpc-clients-must-accept-conn-from-any-address.patch b/queue-6.6/rxrpc-clients-must-accept-conn-from-any-address.patch new file mode 100644 index 00000000000..e7b071fcdd4 --- /dev/null +++ b/queue-6.6/rxrpc-clients-must-accept-conn-from-any-address.patch @@ -0,0 +1,59 @@ +From 2d3ed9bc0deebe91c447184222a142d56ab9ab57 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Apr 2024 13:30:57 -0300 +Subject: rxrpc: Clients must accept conn from any address + +From: Jeffrey Altman + +[ Upstream commit 8953285d7bd63c12b007432a9b4587fa2fad49fb ] + +The find connection logic of Transarc's Rx was modified in the mid-1990s +to support multi-homed servers which might send a response packet from +an address other than the destination address in the received packet. +The rules for accepting a packet by an Rx initiator (RX_CLIENT_CONNECTION) +were altered to permit acceptance of a packet from any address provided +that the port number was unchanged and all of the connection identifiers +matched (Epoch, CID, SecurityClass, ...). + +This change applies the same rules to the Linux implementation which makes +it consistent with IBM AFS 3.6, Arla, OpenAFS and AuriStorFS. + +Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both") +Signed-off-by: Jeffrey Altman +Acked-by: David Howells +Signed-off-by: Marc Dionne +Link: https://lore.kernel.org/r/20240419163057.4141728-1-marc.dionne@auristor.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/rxrpc/conn_object.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c +index df8a271948a1c..7aa58129ae455 100644 +--- a/net/rxrpc/conn_object.c ++++ b/net/rxrpc/conn_object.c +@@ -118,18 +118,13 @@ struct rxrpc_connection *rxrpc_find_client_connection_rcu(struct rxrpc_local *lo + switch (srx->transport.family) { + case AF_INET: + if (peer->srx.transport.sin.sin_port != +- srx->transport.sin.sin_port || +- peer->srx.transport.sin.sin_addr.s_addr != +- srx->transport.sin.sin_addr.s_addr) ++ srx->transport.sin.sin_port) + goto not_found; + break; + #ifdef CONFIG_AF_RXRPC_IPV6 + case AF_INET6: + if (peer->srx.transport.sin6.sin6_port != +- srx->transport.sin6.sin6_port || +- memcmp(&peer->srx.transport.sin6.sin6_addr, +- &srx->transport.sin6.sin6_addr, +- sizeof(struct in6_addr)) != 0) ++ srx->transport.sin6.sin6_port) + goto not_found; + break; + #endif +-- +2.43.0 + diff --git a/queue-6.6/s390-cio-ensure-the-copied-buf-is-nul-terminated.patch b/queue-6.6/s390-cio-ensure-the-copied-buf-is-nul-terminated.patch new file mode 100644 index 00000000000..366649942fc --- /dev/null +++ b/queue-6.6/s390-cio-ensure-the-copied-buf-is-nul-terminated.patch @@ -0,0 +1,40 @@ +From 42a18988e7574afffc677edf167e7f5e32f45552 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Apr 2024 21:44:22 +0700 +Subject: s390/cio: Ensure the copied buf is NUL terminated + +From: Bui Quang Minh + +[ Upstream commit da7c622cddd4fe36be69ca61e8c42e43cde94784 ] + +Currently, we allocate a lbuf-sized kernel buffer and copy lbuf from +userspace to that buffer. Later, we use scanf on this buffer but we don't +ensure that the string is terminated inside the buffer, this can lead to +OOB read when using scanf. Fix this issue by using memdup_user_nul instead. + +Fixes: a4f17cc72671 ("s390/cio: add CRW inject functionality") +Signed-off-by: Bui Quang Minh +Reviewed-by: Heiko Carstens +Link: https://lore.kernel.org/r/20240424-fix-oob-read-v2-5-f1f1b53a10f4@gmail.com +Signed-off-by: Alexander Gordeev +Signed-off-by: Sasha Levin +--- + drivers/s390/cio/cio_inject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/s390/cio/cio_inject.c b/drivers/s390/cio/cio_inject.c +index 8613fa937237b..a2e771ebae8eb 100644 +--- a/drivers/s390/cio/cio_inject.c ++++ b/drivers/s390/cio/cio_inject.c +@@ -95,7 +95,7 @@ static ssize_t crw_inject_write(struct file *file, const char __user *buf, + return -EINVAL; + } + +- buffer = vmemdup_user(buf, lbuf); ++ buffer = memdup_user_nul(buf, lbuf); + if (IS_ERR(buffer)) + return -ENOMEM; + +-- +2.43.0 + diff --git a/queue-6.6/s390-mm-fix-clearing-storage-keys-for-huge-pages.patch b/queue-6.6/s390-mm-fix-clearing-storage-keys-for-huge-pages.patch new file mode 100644 index 00000000000..bd655cea3a3 --- /dev/null +++ b/queue-6.6/s390-mm-fix-clearing-storage-keys-for-huge-pages.patch @@ -0,0 +1,42 @@ +From 4975b840333b44bed31892c79a855e6045ce766c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 13:42:20 +0200 +Subject: s390/mm: Fix clearing storage keys for huge pages + +From: Claudio Imbrenda + +[ Upstream commit 412050af2ea39407fe43324b0be4ab641530ce88 ] + +The function __storage_key_init_range() expects the end address to be +the first byte outside the range to be initialized. I.e. end - start +should be the size of the area to be initialized. + +The current code works because __storage_key_init_range() will still loop +over every page in the range, but it is slower than using sske_frame(). + +Fixes: 3afdfca69870 ("s390/mm: Clear skeys for newly mapped huge guest pmds") +Reviewed-by: Heiko Carstens +Signed-off-by: Claudio Imbrenda +Link: https://lore.kernel.org/r/20240416114220.28489-3-imbrenda@linux.ibm.com +Signed-off-by: Alexander Gordeev +Signed-off-by: Sasha Levin +--- + arch/s390/mm/hugetlbpage.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c +index 5f64f3d0fafbb..763469e518eec 100644 +--- a/arch/s390/mm/hugetlbpage.c ++++ b/arch/s390/mm/hugetlbpage.c +@@ -139,7 +139,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste) + } + + if (!test_and_set_bit(PG_arch_1, &page->flags)) +- __storage_key_init_range(paddr, paddr + size - 1); ++ __storage_key_init_range(paddr, paddr + size); + } + + void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, +-- +2.43.0 + diff --git a/queue-6.6/s390-mm-fix-storage-key-clearing-for-guest-huge-page.patch b/queue-6.6/s390-mm-fix-storage-key-clearing-for-guest-huge-page.patch new file mode 100644 index 00000000000..7d4e523b11f --- /dev/null +++ b/queue-6.6/s390-mm-fix-storage-key-clearing-for-guest-huge-page.patch @@ -0,0 +1,42 @@ +From 3aa5f347277f29cfe968672a5e49bde56a88170a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 13:42:19 +0200 +Subject: s390/mm: Fix storage key clearing for guest huge pages + +From: Claudio Imbrenda + +[ Upstream commit 843c3280686fc1a83d89ee1e0b5599c9f6b09d0c ] + +The function __storage_key_init_range() expects the end address to be +the first byte outside the range to be initialized. I.e. end - start +should be the size of the area to be initialized. + +The current code works because __storage_key_init_range() will still loop +over every page in the range, but it is slower than using sske_frame(). + +Fixes: 964c2c05c9f3 ("s390/mm: Clear huge page storage keys on enable_skey") +Reviewed-by: Heiko Carstens +Signed-off-by: Claudio Imbrenda +Link: https://lore.kernel.org/r/20240416114220.28489-2-imbrenda@linux.ibm.com +Signed-off-by: Alexander Gordeev +Signed-off-by: Sasha Levin +--- + arch/s390/mm/gmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c +index d17bb1ef63f41..0da54dc9430a9 100644 +--- a/arch/s390/mm/gmap.c ++++ b/arch/s390/mm/gmap.c +@@ -2659,7 +2659,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr, + return 0; + + start = pmd_val(*pmd) & HPAGE_MASK; +- end = start + HPAGE_SIZE - 1; ++ end = start + HPAGE_SIZE; + __storage_key_init_range(start, end); + set_bit(PG_arch_1, &page->flags); + cond_resched(); +-- +2.43.0 + diff --git a/queue-6.6/s390-qeth-fix-kernel-panic-after-setting-hsuid.patch b/queue-6.6/s390-qeth-fix-kernel-panic-after-setting-hsuid.patch new file mode 100644 index 00000000000..423025fe002 --- /dev/null +++ b/queue-6.6/s390-qeth-fix-kernel-panic-after-setting-hsuid.patch @@ -0,0 +1,230 @@ +From 66ed8cd7918c2ef2191772480e29862cb45191ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 11:10:04 +0200 +Subject: s390/qeth: Fix kernel panic after setting hsuid + +From: Alexandra Winter + +[ Upstream commit 8a2e4d37afb8500b276e5ee903dee06f50ab0494 ] + +Symptom: +When the hsuid attribute is set for the first time on an IQD Layer3 +device while the corresponding network interface is already UP, +the kernel will try to execute a napi function pointer that is NULL. + +Example: +--------------------------------------------------------------------------- +[ 2057.572696] illegal operation: 0001 ilc:1 [#1] SMP +[ 2057.572702] Modules linked in: af_iucv qeth_l3 zfcp scsi_transport_fc sunrpc nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 +nft_reject nft_ct nf_tables_set nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables libcrc32c nfnetlink ghash_s390 prng xts aes_s390 des_s390 de +s_generic sha3_512_s390 sha3_256_s390 sha512_s390 vfio_ccw vfio_mdev mdev vfio_iommu_type1 eadm_sch vfio ext4 mbcache jbd2 qeth_l2 bridge stp llc dasd_eckd_mod qeth dasd_mod + qdio ccwgroup pkey zcrypt +[ 2057.572739] CPU: 6 PID: 60182 Comm: stress_client Kdump: loaded Not tainted 4.18.0-541.el8.s390x #1 +[ 2057.572742] Hardware name: IBM 3931 A01 704 (LPAR) +[ 2057.572744] Krnl PSW : 0704f00180000000 0000000000000002 (0x2) +[ 2057.572748] R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:3 PM:0 RI:0 EA:3 +[ 2057.572751] Krnl GPRS: 0000000000000004 0000000000000000 00000000a3b008d8 0000000000000000 +[ 2057.572754] 00000000a3b008d8 cb923a29c779abc5 0000000000000000 00000000814cfd80 +[ 2057.572756] 000000000000012c 0000000000000000 00000000a3b008d8 00000000a3b008d8 +[ 2057.572758] 00000000bab6d500 00000000814cfd80 0000000091317e46 00000000814cfc68 +[ 2057.572762] Krnl Code:#0000000000000000: 0000 illegal + >0000000000000002: 0000 illegal + 0000000000000004: 0000 illegal + 0000000000000006: 0000 illegal + 0000000000000008: 0000 illegal + 000000000000000a: 0000 illegal + 000000000000000c: 0000 illegal + 000000000000000e: 0000 illegal +[ 2057.572800] Call Trace: +[ 2057.572801] ([<00000000ec639700>] 0xec639700) +[ 2057.572803] [<00000000913183e2>] net_rx_action+0x2ba/0x398 +[ 2057.572809] [<0000000091515f76>] __do_softirq+0x11e/0x3a0 +[ 2057.572813] [<0000000090ce160c>] do_softirq_own_stack+0x3c/0x58 +[ 2057.572817] ([<0000000090d2cbd6>] do_softirq.part.1+0x56/0x60) +[ 2057.572822] [<0000000090d2cc60>] __local_bh_enable_ip+0x80/0x98 +[ 2057.572825] [<0000000091314706>] __dev_queue_xmit+0x2be/0xd70 +[ 2057.572827] [<000003ff803dd6d6>] afiucv_hs_send+0x24e/0x300 [af_iucv] +[ 2057.572830] [<000003ff803dd88a>] iucv_send_ctrl+0x102/0x138 [af_iucv] +[ 2057.572833] [<000003ff803de72a>] iucv_sock_connect+0x37a/0x468 [af_iucv] +[ 2057.572835] [<00000000912e7e90>] __sys_connect+0xa0/0xd8 +[ 2057.572839] [<00000000912e9580>] sys_socketcall+0x228/0x348 +[ 2057.572841] [<0000000091514e1a>] system_call+0x2a6/0x2c8 +[ 2057.572843] Last Breaking-Event-Address: +[ 2057.572844] [<0000000091317e44>] __napi_poll+0x4c/0x1d8 +[ 2057.572846] +[ 2057.572847] Kernel panic - not syncing: Fatal exception in interrupt +------------------------------------------------------------------------------------------- + +Analysis: +There is one napi structure per out_q: card->qdio.out_qs[i].napi +The napi.poll functions are set during qeth_open(). + +Since +commit 1cfef80d4c2b ("s390/qeth: Don't call dev_close/dev_open (DOWN/UP)") +qeth_set_offline()/qeth_set_online() no longer call dev_close()/ +dev_open(). So if qeth_free_qdio_queues() cleared +card->qdio.out_qs[i].napi.poll while the network interface was UP and the +card was offline, they are not set again. + +Reproduction: +chzdev -e $devno layer2=0 +ip link set dev $network_interface up +echo 0 > /sys/bus/ccwgroup/devices/0.0.$devno/online +echo foo > /sys/bus/ccwgroup/devices/0.0.$devno/hsuid +echo 1 > /sys/bus/ccwgroup/devices/0.0.$devno/online +-> Crash (can be enforced e.g. by af_iucv connect(), ip link down/up, ...) + +Note that a Completion Queue (CQ) is only enabled or disabled, when hsuid +is set for the first time or when it is removed. + +Workarounds: +- Set hsuid before setting the device online for the first time +or +- Use chzdev -d $devno; chzdev $devno hsuid=xxx; chzdev -e $devno; +to set hsuid on an existing device. (this will remove and recreate the +network interface) + +Fix: +There is no need to free the output queues when a completion queue is +added or removed. +card->qdio.state now indicates whether the inbound buffer pool and the +outbound queues are allocated. +card->qdio.c_q indicates whether a CQ is allocated. + +Fixes: 1cfef80d4c2b ("s390/qeth: Don't call dev_close/dev_open (DOWN/UP)") +Signed-off-by: Alexandra Winter +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240430091004.2265683-1-wintera@linux.ibm.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/s390/net/qeth_core_main.c | 61 ++++++++++++++----------------- + 1 file changed, 27 insertions(+), 34 deletions(-) + +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 1148b4ecabdde..f0f3b6272d5b8 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -364,30 +364,33 @@ static int qeth_cq_init(struct qeth_card *card) + return rc; + } + ++static void qeth_free_cq(struct qeth_card *card) ++{ ++ if (card->qdio.c_q) { ++ qeth_free_qdio_queue(card->qdio.c_q); ++ card->qdio.c_q = NULL; ++ } ++} ++ + static int qeth_alloc_cq(struct qeth_card *card) + { + if (card->options.cq == QETH_CQ_ENABLED) { + QETH_CARD_TEXT(card, 2, "cqon"); +- card->qdio.c_q = qeth_alloc_qdio_queue(); + if (!card->qdio.c_q) { +- dev_err(&card->gdev->dev, "Failed to create completion queue\n"); +- return -ENOMEM; ++ card->qdio.c_q = qeth_alloc_qdio_queue(); ++ if (!card->qdio.c_q) { ++ dev_err(&card->gdev->dev, ++ "Failed to create completion queue\n"); ++ return -ENOMEM; ++ } + } + } else { + QETH_CARD_TEXT(card, 2, "nocq"); +- card->qdio.c_q = NULL; ++ qeth_free_cq(card); + } + return 0; + } + +-static void qeth_free_cq(struct qeth_card *card) +-{ +- if (card->qdio.c_q) { +- qeth_free_qdio_queue(card->qdio.c_q); +- card->qdio.c_q = NULL; +- } +-} +- + static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15, + int delayed) + { +@@ -2628,6 +2631,10 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) + + QETH_CARD_TEXT(card, 2, "allcqdbf"); + ++ /* completion */ ++ if (qeth_alloc_cq(card)) ++ goto out_err; ++ + if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED, + QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) + return 0; +@@ -2663,10 +2670,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) + queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT; + } + +- /* completion */ +- if (qeth_alloc_cq(card)) +- goto out_freeoutq; +- + return 0; + + out_freeoutq: +@@ -2677,6 +2680,8 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) + qeth_free_buffer_pool(card); + out_buffer_pool: + atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); ++ qeth_free_cq(card); ++out_err: + return -ENOMEM; + } + +@@ -2684,11 +2689,12 @@ static void qeth_free_qdio_queues(struct qeth_card *card) + { + int i, j; + ++ qeth_free_cq(card); ++ + if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == + QETH_QDIO_UNINITIALIZED) + return; + +- qeth_free_cq(card); + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { + if (card->qdio.in_q->bufs[j].rx_skb) { + consume_skb(card->qdio.in_q->bufs[j].rx_skb); +@@ -3742,24 +3748,11 @@ static void qeth_qdio_poll(struct ccw_device *cdev, unsigned long card_ptr) + + int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq) + { +- int rc; +- +- if (card->options.cq == QETH_CQ_NOTAVAILABLE) { +- rc = -1; +- goto out; +- } else { +- if (card->options.cq == cq) { +- rc = 0; +- goto out; +- } +- +- qeth_free_qdio_queues(card); +- card->options.cq = cq; +- rc = 0; +- } +-out: +- return rc; ++ if (card->options.cq == QETH_CQ_NOTAVAILABLE) ++ return -1; + ++ card->options.cq = cq; ++ return 0; + } + EXPORT_SYMBOL_GPL(qeth_configure_cq); + +-- +2.43.0 + diff --git a/queue-6.6/s390-vdso-add-cfi-for-ra-register-to-asm-macro-vdso_.patch b/queue-6.6/s390-vdso-add-cfi-for-ra-register-to-asm-macro-vdso_.patch new file mode 100644 index 00000000000..cff2ea0d7da --- /dev/null +++ b/queue-6.6/s390-vdso-add-cfi-for-ra-register-to-asm-macro-vdso_.patch @@ -0,0 +1,56 @@ +From b545ef5ab137ffa4274b16fc4486642d74416f0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 17:35:52 +0200 +Subject: s390/vdso: Add CFI for RA register to asm macro vdso_func + +From: Jens Remus + +[ Upstream commit b961ec10b9f9719987470236feb50c967db5a652 ] + +The return-address (RA) register r14 is specified as volatile in the +s390x ELF ABI [1]. Nevertheless proper CFI directives must be provided +for an unwinder to restore the return address, if the RA register +value is changed from its value at function entry, as it is the case. + +[1]: s390x ELF ABI, https://github.com/IBM/s390x-abi/releases + +Fixes: 4bff8cb54502 ("s390: convert to GENERIC_VDSO") +Signed-off-by: Jens Remus +Acked-by: Heiko Carstens +Signed-off-by: Alexander Gordeev +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/dwarf.h | 1 + + arch/s390/kernel/vdso64/vdso_user_wrapper.S | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/arch/s390/include/asm/dwarf.h b/arch/s390/include/asm/dwarf.h +index 4f21ae561e4dd..390906b8e386e 100644 +--- a/arch/s390/include/asm/dwarf.h ++++ b/arch/s390/include/asm/dwarf.h +@@ -9,6 +9,7 @@ + #define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset + #define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset + #define CFI_RESTORE .cfi_restore ++#define CFI_REL_OFFSET .cfi_rel_offset + + #ifdef CONFIG_AS_CFI_VAL_OFFSET + #define CFI_VAL_OFFSET .cfi_val_offset +diff --git a/arch/s390/kernel/vdso64/vdso_user_wrapper.S b/arch/s390/kernel/vdso64/vdso_user_wrapper.S +index 57f62596e53b9..85247ef5a41b8 100644 +--- a/arch/s390/kernel/vdso64/vdso_user_wrapper.S ++++ b/arch/s390/kernel/vdso64/vdso_user_wrapper.S +@@ -24,8 +24,10 @@ __kernel_\func: + CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE) + CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD + stg %r14,STACK_FRAME_OVERHEAD(%r15) ++ CFI_REL_OFFSET 14, STACK_FRAME_OVERHEAD + brasl %r14,__s390_vdso_\func + lg %r14,STACK_FRAME_OVERHEAD(%r15) ++ CFI_RESTORE 14 + aghi %r15,WRAPPER_FRAME_SIZE + CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD + CFI_RESTORE 15 +-- +2.43.0 + diff --git a/queue-6.6/series b/queue-6.6/series index dd8f226d6b9..7b45557f018 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -26,3 +26,64 @@ pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch regulator-mt6360-de-capitalize-devicetree-regulator-.patch regulator-change-stubbed-devm_regulator_get_enable-t.patch regulator-change-devm_regulator_get_enable_optional-.patch +bpf-kconfig-fix-debug_info_btf_modules-kconfig-defin.patch +bpf-skmsg-fix-null-pointer-dereference-in-sk_psock_s.patch +regmap-add-regmap_read_bypassed.patch +asoc-sof-introduce-generic-names-for-ipc-types.patch +asoc-sof-intel-add-default-firmware-library-path-for.patch +nvme-fix-warn-output-about-shared-namespaces-without.patch +bpf-fix-a-verifier-verbose-message.patch +spi-spi-axi-spi-engine-use-helper-function-devm_clk_.patch +spi-axi-spi-engine-simplify-driver-data-allocation.patch +spi-axi-spi-engine-use-devm_spi_alloc_host.patch +spi-axi-spi-engine-move-msg-state-to-new-struct.patch +spi-axi-spi-engine-use-common-axi-macros.patch +spi-axi-spi-engine-fix-version-format-string.patch +spi-hisi-kunpeng-delete-the-dump-interface-of-data-r.patch +bpf-arm64-fix-incorrect-runtime-stats.patch +riscv-bpf-fix-incorrect-runtime-stats.patch +asoc-intel-avs-set-name-of-control-as-in-topology.patch +asoc-codecs-wsa881x-set-clk_stop_mode1-flag.patch +s390-mm-fix-storage-key-clearing-for-guest-huge-page.patch +s390-mm-fix-clearing-storage-keys-for-huge-pages.patch +xdp-use-flags-field-to-disambiguate-broadcast-redire.patch +bna-ensure-the-copied-buf-is-nul-terminated.patch +octeontx2-af-avoid-off-by-one-read-from-userspace.patch +nsh-restore-skb-protocol-data-mac_header-for-outer-h.patch +net-l2tp-drop-flow-hash-on-forward.patch +s390-vdso-add-cfi-for-ra-register-to-asm-macro-vdso_.patch +fix-a-potential-infinite-loop-in-extract_user_to_sg.patch +alsa-emu10k1-fix-e-mu-card-dock-presence-monitoring.patch +alsa-emu10k1-factor-out-snd_emu1010_load_dock_firmwa.patch +alsa-emu10k1-move-the-whole-gpio-event-handling-to-t.patch +alsa-emu10k1-fix-e-mu-dock-initialization.patch +net-qede-sanitize-rc-in-qede_add_tc_flower_fltr.patch +net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch +net-qede-use-return-from-qede_parse_flow_attr-for-fl.patch-1718 +net-qede-use-return-from-qede_parse_actions.patch +vxlan-fix-racy-device-stats-updates.patch +vxlan-add-missing-vni-filter-counter-update-in-arp_r.patch +asoc-meson-axg-fifo-use-field-helpers.patch +asoc-meson-axg-fifo-use-threaded-irq-to-check-period.patch +asoc-meson-axg-card-make-links-nonatomic.patch +asoc-meson-axg-tdm-interface-manage-formatters-in-tr.patch +asoc-meson-cards-select-snd_dynamic_minors.patch +alsa-hda-intel-sdw-acpi-fix-usage-of-device_get_name.patch +s390-cio-ensure-the-copied-buf-is-nul-terminated.patch +cxgb4-properly-lock-tx-queue-for-the-selftest.patch +net-dsa-mv88e6xxx-fix-number-of-databases-for-88e614.patch +drm-amdgpu-fix-doorbell-regression.patch +spi-fix-null-pointer-dereference-within-spi_sync.patch +net-bridge-fix-multicast-to-unicast-with-fraglist-gs.patch +net-core-reject-skb_copy-_expand-for-fraglist-gso-sk.patch +rxrpc-clients-must-accept-conn-from-any-address.patch +tipc-fix-a-possible-memleak-in-tipc_buf_append.patch +vxlan-pull-inner-ip-header-in-vxlan_rcv.patch +s390-qeth-fix-kernel-panic-after-setting-hsuid.patch +drm-panel-ili9341-correct-use-of-device-property-api.patch +drm-panel-ili9341-respect-deferred-probe.patch +drm-panel-ili9341-use-predefined-error-codes.patch +ipv4-fix-uninit-value-access-in-__ip_make_skb.patch +net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch +net-gro-fix-udp-bad-offset-in-socket-lookup-by-addin.patch +net-gro-add-flush-check-in-udp_gro_receive_segment.patch diff --git a/queue-6.6/spi-axi-spi-engine-fix-version-format-string.patch b/queue-6.6/spi-axi-spi-engine-fix-version-format-string.patch new file mode 100644 index 00000000000..df16d98df55 --- /dev/null +++ b/queue-6.6/spi-axi-spi-engine-fix-version-format-string.patch @@ -0,0 +1,41 @@ +From 77dd6c7c7db20bf5a6035518691edf87c8964eca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Apr 2024 17:52:48 -0500 +Subject: spi: axi-spi-engine: fix version format string + +From: David Lechner + +[ Upstream commit 0064db9ce4aa7cc794e6f4aed60dee0f94fc9bcf ] + +The version format string in the AXI SPI Engine driver was probably +intended to print the version number in the same format as the DT +compatible string (e.g. 1.00.a). However, the version just uses +semantic versioning so formatting the patch number as a character +is not correct and would result in printing control characters for +patch numbers less than 32. + +Fixes: b1353d1c1d45 ("spi: Add Analog Devices AXI SPI Engine controller support") +Signed-off-by: David Lechner +Link: https://lore.kernel.org/r/20240412-axi-spi-engine-version-printf-v1-1-95e1e842c1a6@baylibre.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index 9c7b6a92417ce..9faee4fcc049a 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -532,7 +532,7 @@ static int spi_engine_probe(struct platform_device *pdev) + + version = readl(spi_engine->base + ADI_AXI_REG_VERSION); + if (ADI_AXI_PCORE_VER_MAJOR(version) != 1) { +- dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n", ++ dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%u\n", + ADI_AXI_PCORE_VER_MAJOR(version), + ADI_AXI_PCORE_VER_MINOR(version), + ADI_AXI_PCORE_VER_PATCH(version)); +-- +2.43.0 + diff --git a/queue-6.6/spi-axi-spi-engine-move-msg-state-to-new-struct.patch b/queue-6.6/spi-axi-spi-engine-move-msg-state-to-new-struct.patch new file mode 100644 index 00000000000..c4f107072ed --- /dev/null +++ b/queue-6.6/spi-axi-spi-engine-move-msg-state-to-new-struct.patch @@ -0,0 +1,353 @@ +From 45053a4c68ad406faa8ed4bba7bdbe4a7b4f75c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Nov 2023 14:13:00 -0600 +Subject: spi: axi-spi-engine: move msg state to new struct + +From: David Lechner + +[ Upstream commit 7f970ecb77b6759d37ee743fc36fc0daba960e75 ] + +This moves the message state in the AXI SPI Engine driver to a new +struct spi_engine_msg_state. + +Previously, the driver state contained various pointers that pointed +to memory owned by a struct spi_message. However, it did not set any of +these pointers to NULL when a message was completed. This could lead to +use after free bugs. + +Example of how this could happen: +1. SPI core calls into spi_engine_transfer_one_message() with msg1. +2. Assume something was misconfigured and spi_engine_tx_next() is not + called enough times in interrupt callbacks for msg1 such that + spi_engine->tx_xfer is never set to NULL before the msg1 completes. +3. SYNC interrupt is received and spi_finalize_current_message() is + called for msg1. spi_engine->msg is set to NULL but no other + message-specific state is reset. +4. Caller that sent msg1 is notified of the completion and frees msg1 + and the associated xfers and tx/rx buffers. +4. SPI core calls into spi_engine_transfer_one_message() with msg2. +5. When spi_engine_tx_next() is called for msg2, spi_engine->tx_xfer is + still be pointing to an xfer from msg1, which was already freed. + spi_engine_xfer_next() tries to access xfer->transfer_list of one + of the freed xfers and we get a segfault or undefined behavior. + +To avoid issues like this, instead of putting per-message state in the +driver state struct, we can make use of the struct spi_message::state +field to store a pointer to a new struct spi_engine_msg_state. This way, +all of the state that belongs to specific message stays with that +message and we don't have to remember to manually reset all aspects of +the message state when a message is completed. Rather, a new state is +allocated for each message. + +Most of the changes are just renames where the state is accessed. One +place where this wasn't straightforward was the sync_id member. This +has been changed to use ida_alloc_range() since we needed to separate +the per-message sync_id from the per-controller next available sync_id. + +Signed-off-by: David Lechner +Link: https://lore.kernel.org/r/20231117-axi-spi-engine-series-1-v1-9-cc59db999b87@baylibre.com +Signed-off-by: Mark Brown +Stable-dep-of: 0064db9ce4aa ("spi: axi-spi-engine: fix version format string") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 150 ++++++++++++++++++++----------- + 1 file changed, 96 insertions(+), 54 deletions(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index 77c1c115448d6..9ca5b45c4b4cc 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -78,28 +79,42 @@ struct spi_engine_program { + uint16_t instructions[]; + }; + +-struct spi_engine { +- struct clk *clk; +- struct clk *ref_clk; +- +- spinlock_t lock; +- +- void __iomem *base; +- +- struct spi_message *msg; ++/** ++ * struct spi_engine_message_state - SPI engine per-message state ++ */ ++struct spi_engine_message_state { ++ /** Instructions for executing this message. */ + struct spi_engine_program *p; ++ /** Number of elements in cmd_buf array. */ + unsigned cmd_length; ++ /** Array of commands not yet written to CMD FIFO. */ + const uint16_t *cmd_buf; +- ++ /** Next xfer with tx_buf not yet fully written to TX FIFO. */ + struct spi_transfer *tx_xfer; ++ /** Size of tx_buf in bytes. */ + unsigned int tx_length; ++ /** Bytes not yet written to TX FIFO. */ + const uint8_t *tx_buf; +- ++ /** Next xfer with rx_buf not yet fully written to RX FIFO. */ + struct spi_transfer *rx_xfer; ++ /** Size of tx_buf in bytes. */ + unsigned int rx_length; ++ /** Bytes not yet written to the RX FIFO. */ + uint8_t *rx_buf; ++ /** ID to correlate SYNC interrupts with this message. */ ++ u8 sync_id; ++}; ++ ++struct spi_engine { ++ struct clk *clk; ++ struct clk *ref_clk; + +- unsigned int sync_id; ++ spinlock_t lock; ++ ++ void __iomem *base; ++ ++ struct spi_message *msg; ++ struct ida sync_ida; + unsigned int completed_id; + + unsigned int int_enable; +@@ -258,100 +273,105 @@ static void spi_engine_xfer_next(struct spi_engine *spi_engine, + + static void spi_engine_tx_next(struct spi_engine *spi_engine) + { +- struct spi_transfer *xfer = spi_engine->tx_xfer; ++ struct spi_engine_message_state *st = spi_engine->msg->state; ++ struct spi_transfer *xfer = st->tx_xfer; + + do { + spi_engine_xfer_next(spi_engine, &xfer); + } while (xfer && !xfer->tx_buf); + +- spi_engine->tx_xfer = xfer; ++ st->tx_xfer = xfer; + if (xfer) { +- spi_engine->tx_length = xfer->len; +- spi_engine->tx_buf = xfer->tx_buf; ++ st->tx_length = xfer->len; ++ st->tx_buf = xfer->tx_buf; + } else { +- spi_engine->tx_buf = NULL; ++ st->tx_buf = NULL; + } + } + + static void spi_engine_rx_next(struct spi_engine *spi_engine) + { +- struct spi_transfer *xfer = spi_engine->rx_xfer; ++ struct spi_engine_message_state *st = spi_engine->msg->state; ++ struct spi_transfer *xfer = st->rx_xfer; + + do { + spi_engine_xfer_next(spi_engine, &xfer); + } while (xfer && !xfer->rx_buf); + +- spi_engine->rx_xfer = xfer; ++ st->rx_xfer = xfer; + if (xfer) { +- spi_engine->rx_length = xfer->len; +- spi_engine->rx_buf = xfer->rx_buf; ++ st->rx_length = xfer->len; ++ st->rx_buf = xfer->rx_buf; + } else { +- spi_engine->rx_buf = NULL; ++ st->rx_buf = NULL; + } + } + + static bool spi_engine_write_cmd_fifo(struct spi_engine *spi_engine) + { + void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_CMD_FIFO; ++ struct spi_engine_message_state *st = spi_engine->msg->state; + unsigned int n, m, i; + const uint16_t *buf; + + n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_CMD_FIFO_ROOM); +- while (n && spi_engine->cmd_length) { +- m = min(n, spi_engine->cmd_length); +- buf = spi_engine->cmd_buf; ++ while (n && st->cmd_length) { ++ m = min(n, st->cmd_length); ++ buf = st->cmd_buf; + for (i = 0; i < m; i++) + writel_relaxed(buf[i], addr); +- spi_engine->cmd_buf += m; +- spi_engine->cmd_length -= m; ++ st->cmd_buf += m; ++ st->cmd_length -= m; + n -= m; + } + +- return spi_engine->cmd_length != 0; ++ return st->cmd_length != 0; + } + + static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine) + { + void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDO_DATA_FIFO; ++ struct spi_engine_message_state *st = spi_engine->msg->state; + unsigned int n, m, i; + const uint8_t *buf; + + n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDO_FIFO_ROOM); +- while (n && spi_engine->tx_length) { +- m = min(n, spi_engine->tx_length); +- buf = spi_engine->tx_buf; ++ while (n && st->tx_length) { ++ m = min(n, st->tx_length); ++ buf = st->tx_buf; + for (i = 0; i < m; i++) + writel_relaxed(buf[i], addr); +- spi_engine->tx_buf += m; +- spi_engine->tx_length -= m; ++ st->tx_buf += m; ++ st->tx_length -= m; + n -= m; +- if (spi_engine->tx_length == 0) ++ if (st->tx_length == 0) + spi_engine_tx_next(spi_engine); + } + +- return spi_engine->tx_length != 0; ++ return st->tx_length != 0; + } + + static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine) + { + void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDI_DATA_FIFO; ++ struct spi_engine_message_state *st = spi_engine->msg->state; + unsigned int n, m, i; + uint8_t *buf; + + n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDI_FIFO_LEVEL); +- while (n && spi_engine->rx_length) { +- m = min(n, spi_engine->rx_length); +- buf = spi_engine->rx_buf; ++ while (n && st->rx_length) { ++ m = min(n, st->rx_length); ++ buf = st->rx_buf; + for (i = 0; i < m; i++) + buf[i] = readl_relaxed(addr); +- spi_engine->rx_buf += m; +- spi_engine->rx_length -= m; ++ st->rx_buf += m; ++ st->rx_length -= m; + n -= m; +- if (spi_engine->rx_length == 0) ++ if (st->rx_length == 0) + spi_engine_rx_next(spi_engine); + } + +- return spi_engine->rx_length != 0; ++ return st->rx_length != 0; + } + + static irqreturn_t spi_engine_irq(int irq, void *devid) +@@ -387,12 +407,16 @@ static irqreturn_t spi_engine_irq(int irq, void *devid) + disable_int |= SPI_ENGINE_INT_SDI_ALMOST_FULL; + } + +- if (pending & SPI_ENGINE_INT_SYNC) { +- if (spi_engine->msg && +- spi_engine->completed_id == spi_engine->sync_id) { ++ if (pending & SPI_ENGINE_INT_SYNC && spi_engine->msg) { ++ struct spi_engine_message_state *st = spi_engine->msg->state; ++ ++ if (spi_engine->completed_id == st->sync_id) { + struct spi_message *msg = spi_engine->msg; ++ struct spi_engine_message_state *st = msg->state; + +- kfree(spi_engine->p); ++ ida_free(&spi_engine->sync_ida, st->sync_id); ++ kfree(st->p); ++ kfree(st); + msg->status = 0; + msg->actual_length = msg->frame_length; + spi_engine->msg = NULL; +@@ -417,29 +441,46 @@ static int spi_engine_transfer_one_message(struct spi_controller *host, + { + struct spi_engine_program p_dry, *p; + struct spi_engine *spi_engine = spi_controller_get_devdata(host); ++ struct spi_engine_message_state *st; + unsigned int int_enable = 0; + unsigned long flags; + size_t size; ++ int ret; ++ ++ st = kzalloc(sizeof(*st), GFP_KERNEL); ++ if (!st) ++ return -ENOMEM; + + p_dry.length = 0; + spi_engine_compile_message(spi_engine, msg, true, &p_dry); + + size = sizeof(*p->instructions) * (p_dry.length + 1); + p = kzalloc(sizeof(*p) + size, GFP_KERNEL); +- if (!p) ++ if (!p) { ++ kfree(st); + return -ENOMEM; ++ } ++ ++ ret = ida_alloc_range(&spi_engine->sync_ida, 0, U8_MAX, GFP_KERNEL); ++ if (ret < 0) { ++ kfree(p); ++ kfree(st); ++ return ret; ++ } ++ ++ st->sync_id = ret; ++ + spi_engine_compile_message(spi_engine, msg, false, p); + + spin_lock_irqsave(&spi_engine->lock, flags); +- spi_engine->sync_id = (spi_engine->sync_id + 1) & 0xff; +- spi_engine_program_add_cmd(p, false, +- SPI_ENGINE_CMD_SYNC(spi_engine->sync_id)); ++ spi_engine_program_add_cmd(p, false, SPI_ENGINE_CMD_SYNC(st->sync_id)); + ++ msg->state = st; + spi_engine->msg = msg; +- spi_engine->p = p; ++ st->p = p; + +- spi_engine->cmd_buf = p->instructions; +- spi_engine->cmd_length = p->length; ++ st->cmd_buf = p->instructions; ++ st->cmd_length = p->length; + if (spi_engine_write_cmd_fifo(spi_engine)) + int_enable |= SPI_ENGINE_INT_CMD_ALMOST_EMPTY; + +@@ -448,7 +489,7 @@ static int spi_engine_transfer_one_message(struct spi_controller *host, + int_enable |= SPI_ENGINE_INT_SDO_ALMOST_EMPTY; + + spi_engine_rx_next(spi_engine); +- if (spi_engine->rx_length != 0) ++ if (st->rx_length != 0) + int_enable |= SPI_ENGINE_INT_SDI_ALMOST_FULL; + + int_enable |= SPI_ENGINE_INT_SYNC; +@@ -480,6 +521,7 @@ static int spi_engine_probe(struct platform_device *pdev) + spi_engine = spi_controller_get_devdata(host); + + spin_lock_init(&spi_engine->lock); ++ ida_init(&spi_engine->sync_ida); + + spi_engine->clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(spi_engine->clk)) +-- +2.43.0 + diff --git a/queue-6.6/spi-axi-spi-engine-simplify-driver-data-allocation.patch b/queue-6.6/spi-axi-spi-engine-simplify-driver-data-allocation.patch new file mode 100644 index 00000000000..25c4b6c575b --- /dev/null +++ b/queue-6.6/spi-axi-spi-engine-simplify-driver-data-allocation.patch @@ -0,0 +1,47 @@ +From 05aac5a4292fa2fd8b16eecebdbec90087a81a7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Nov 2023 14:12:54 -0600 +Subject: spi: axi-spi-engine: simplify driver data allocation + +From: David Lechner + +[ Upstream commit 9e4ce5220eedea2cc440f3961dec1b5122e815b2 ] + +This simplifies the private data allocation in the AXI SPI Engine driver +by making use of the feature built into the spi_alloc_host() function +instead of doing it manually. + +Signed-off-by: David Lechner +Link: https://lore.kernel.org/r/20231117-axi-spi-engine-series-1-v1-3-cc59db999b87@baylibre.com +Signed-off-by: Mark Brown +Stable-dep-of: 0064db9ce4aa ("spi: axi-spi-engine: fix version format string") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index b96e55f59d1a9..bdf0aa4ceb1df 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -473,15 +473,11 @@ static int spi_engine_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL); +- if (!spi_engine) +- return -ENOMEM; +- +- host = spi_alloc_host(&pdev->dev, 0); ++ host = spi_alloc_host(&pdev->dev, sizeof(*spi_engine)); + if (!host) + return -ENOMEM; + +- spi_controller_set_devdata(host, spi_engine); ++ spi_engine = spi_controller_get_devdata(host); + + spin_lock_init(&spi_engine->lock); + +-- +2.43.0 + diff --git a/queue-6.6/spi-axi-spi-engine-use-common-axi-macros.patch b/queue-6.6/spi-axi-spi-engine-use-common-axi-macros.patch new file mode 100644 index 00000000000..b06cb3765c1 --- /dev/null +++ b/queue-6.6/spi-axi-spi-engine-use-common-axi-macros.patch @@ -0,0 +1,68 @@ +From 27c757a631b40e5186a80834d33f989b5fc9ff06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 15:31:32 -0600 +Subject: spi: axi-spi-engine: use common AXI macros + +From: David Lechner + +[ Upstream commit 88c2b56c2690061121cad03f0f551db465287575 ] + +This avoid duplicating the same macros in multiple drivers by reusing +the common AXI macros for the version register. + +Signed-off-by: David Lechner +Reviewed-by: Nuno Sa +Link: https://lore.kernel.org/r/20240202213132.3863124-2-dlechner@baylibre.com +Signed-off-by: Mark Brown +Stable-dep-of: 0064db9ce4aa ("spi: axi-spi-engine: fix version format string") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index 9ca5b45c4b4cc..9c7b6a92417ce 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -6,6 +6,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -14,12 +15,6 @@ + #include + #include + +-#define SPI_ENGINE_VERSION_MAJOR(x) ((x >> 16) & 0xff) +-#define SPI_ENGINE_VERSION_MINOR(x) ((x >> 8) & 0xff) +-#define SPI_ENGINE_VERSION_PATCH(x) (x & 0xff) +- +-#define SPI_ENGINE_REG_VERSION 0x00 +- + #define SPI_ENGINE_REG_RESET 0x40 + + #define SPI_ENGINE_REG_INT_ENABLE 0x80 +@@ -535,12 +530,12 @@ static int spi_engine_probe(struct platform_device *pdev) + if (IS_ERR(spi_engine->base)) + return PTR_ERR(spi_engine->base); + +- version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); +- if (SPI_ENGINE_VERSION_MAJOR(version) != 1) { ++ version = readl(spi_engine->base + ADI_AXI_REG_VERSION); ++ if (ADI_AXI_PCORE_VER_MAJOR(version) != 1) { + dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n", +- SPI_ENGINE_VERSION_MAJOR(version), +- SPI_ENGINE_VERSION_MINOR(version), +- SPI_ENGINE_VERSION_PATCH(version)); ++ ADI_AXI_PCORE_VER_MAJOR(version), ++ ADI_AXI_PCORE_VER_MINOR(version), ++ ADI_AXI_PCORE_VER_PATCH(version)); + return -ENODEV; + } + +-- +2.43.0 + diff --git a/queue-6.6/spi-axi-spi-engine-use-devm_spi_alloc_host.patch b/queue-6.6/spi-axi-spi-engine-use-devm_spi_alloc_host.patch new file mode 100644 index 00000000000..5c39879ac6c --- /dev/null +++ b/queue-6.6/spi-axi-spi-engine-use-devm_spi_alloc_host.patch @@ -0,0 +1,115 @@ +From ddca355f0e558deac360a7beb6c3db1cda07fd94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Nov 2023 14:12:55 -0600 +Subject: spi: axi-spi-engine: use devm_spi_alloc_host() + +From: David Lechner + +[ Upstream commit e12cd96e8e93044646fdf4b2c9a1de62cfa01e7c ] + +This modifies the AXI SPI Engine driver to use devm_spi_alloc_host() +instead of spi_alloc_host() to simplify the code a bit. + +In addition to simplifying the error paths in the probe function, we +can also remove spi_controller_get/put() calls in the remove function +since devm_spi_alloc_host() sets a flag to no longer decrement the +controller reference count in the spi_unregister_controller() function. + +Signed-off-by: David Lechner +Link: https://lore.kernel.org/r/20231117-axi-spi-engine-series-1-v1-4-cc59db999b87@baylibre.com +Signed-off-by: Mark Brown +Stable-dep-of: 0064db9ce4aa ("spi: axi-spi-engine: fix version format string") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 31 ++++++++++--------------------- + 1 file changed, 10 insertions(+), 21 deletions(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index bdf0aa4ceb1df..77c1c115448d6 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -473,7 +473,7 @@ static int spi_engine_probe(struct platform_device *pdev) + if (irq < 0) + return irq; + +- host = spi_alloc_host(&pdev->dev, sizeof(*spi_engine)); ++ host = devm_spi_alloc_host(&pdev->dev, sizeof(*spi_engine)); + if (!host) + return -ENOMEM; + +@@ -482,22 +482,16 @@ static int spi_engine_probe(struct platform_device *pdev) + spin_lock_init(&spi_engine->lock); + + spi_engine->clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); +- if (IS_ERR(spi_engine->clk)) { +- ret = PTR_ERR(spi_engine->clk); +- goto err_put_host; +- } ++ if (IS_ERR(spi_engine->clk)) ++ return PTR_ERR(spi_engine->clk); + + spi_engine->ref_clk = devm_clk_get_enabled(&pdev->dev, "spi_clk"); +- if (IS_ERR(spi_engine->ref_clk)) { +- ret = PTR_ERR(spi_engine->ref_clk); +- goto err_put_host; +- } ++ if (IS_ERR(spi_engine->ref_clk)) ++ return PTR_ERR(spi_engine->ref_clk); + + spi_engine->base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(spi_engine->base)) { +- ret = PTR_ERR(spi_engine->base); +- goto err_put_host; +- } ++ if (IS_ERR(spi_engine->base)) ++ return PTR_ERR(spi_engine->base); + + version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); + if (SPI_ENGINE_VERSION_MAJOR(version) != 1) { +@@ -505,8 +499,7 @@ static int spi_engine_probe(struct platform_device *pdev) + SPI_ENGINE_VERSION_MAJOR(version), + SPI_ENGINE_VERSION_MINOR(version), + SPI_ENGINE_VERSION_PATCH(version)); +- ret = -ENODEV; +- goto err_put_host; ++ return -ENODEV; + } + + writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); +@@ -515,7 +508,7 @@ static int spi_engine_probe(struct platform_device *pdev) + + ret = request_irq(irq, spi_engine_irq, 0, pdev->name, host); + if (ret) +- goto err_put_host; ++ return ret; + + host->dev.of_node = pdev->dev.of_node; + host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE; +@@ -533,14 +526,12 @@ static int spi_engine_probe(struct platform_device *pdev) + return 0; + err_free_irq: + free_irq(irq, host); +-err_put_host: +- spi_controller_put(host); + return ret; + } + + static void spi_engine_remove(struct platform_device *pdev) + { +- struct spi_controller *host = spi_controller_get(platform_get_drvdata(pdev)); ++ struct spi_controller *host = platform_get_drvdata(pdev); + struct spi_engine *spi_engine = spi_controller_get_devdata(host); + int irq = platform_get_irq(pdev, 0); + +@@ -548,8 +539,6 @@ static void spi_engine_remove(struct platform_device *pdev) + + free_irq(irq, host); + +- spi_controller_put(host); +- + writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); + writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET); +-- +2.43.0 + diff --git a/queue-6.6/spi-fix-null-pointer-dereference-within-spi_sync.patch b/queue-6.6/spi-fix-null-pointer-dereference-within-spi_sync.patch new file mode 100644 index 00000000000..f8e1e70e23c --- /dev/null +++ b/queue-6.6/spi-fix-null-pointer-dereference-within-spi_sync.patch @@ -0,0 +1,64 @@ +From 3fc8d30a1e01d41763a093e72fbc7702bd7e57bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 19:27:05 +0100 +Subject: spi: fix null pointer dereference within spi_sync + +From: Mans Rullgard + +[ Upstream commit 4756fa529b2f12b7cb8f21fe229b0f6f47190829 ] + +If spi_sync() is called with the non-empty queue and the same spi_message +is then reused, the complete callback for the message remains set while +the context is cleared, leading to a null pointer dereference when the +callback is invoked from spi_finalize_current_message(). + +With function inlining disabled, the call stack might look like this: + + _raw_spin_lock_irqsave from complete_with_flags+0x18/0x58 + complete_with_flags from spi_complete+0x8/0xc + spi_complete from spi_finalize_current_message+0xec/0x184 + spi_finalize_current_message from spi_transfer_one_message+0x2a8/0x474 + spi_transfer_one_message from __spi_pump_transfer_message+0x104/0x230 + __spi_pump_transfer_message from __spi_transfer_message_noqueue+0x30/0xc4 + __spi_transfer_message_noqueue from __spi_sync+0x204/0x248 + __spi_sync from spi_sync+0x24/0x3c + spi_sync from mcp251xfd_regmap_crc_read+0x124/0x28c [mcp251xfd] + mcp251xfd_regmap_crc_read [mcp251xfd] from _regmap_raw_read+0xf8/0x154 + _regmap_raw_read from _regmap_bus_read+0x44/0x70 + _regmap_bus_read from _regmap_read+0x60/0xd8 + _regmap_read from regmap_read+0x3c/0x5c + regmap_read from mcp251xfd_alloc_can_err_skb+0x1c/0x54 [mcp251xfd] + mcp251xfd_alloc_can_err_skb [mcp251xfd] from mcp251xfd_irq+0x194/0xe70 [mcp251xfd] + mcp251xfd_irq [mcp251xfd] from irq_thread_fn+0x1c/0x78 + irq_thread_fn from irq_thread+0x118/0x1f4 + irq_thread from kthread+0xd8/0xf4 + kthread from ret_from_fork+0x14/0x28 + +Fix this by also setting message->complete to NULL when the transfer is +complete. + +Fixes: ae7d2346dc89 ("spi: Don't use the message queue if possible in spi_sync") + +Signed-off-by: Mans Rullgard +Link: https://lore.kernel.org/r/20240430182705.13019-1-mans@mansr.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 1e08cd571d21a..76383ddbd6a6f 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -4261,6 +4261,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) + wait_for_completion(&done); + status = message->status; + } ++ message->complete = NULL; + message->context = NULL; + + return status; +-- +2.43.0 + diff --git a/queue-6.6/spi-hisi-kunpeng-delete-the-dump-interface-of-data-r.patch b/queue-6.6/spi-hisi-kunpeng-delete-the-dump-interface-of-data-r.patch new file mode 100644 index 00000000000..0c772d59303 --- /dev/null +++ b/queue-6.6/spi-hisi-kunpeng-delete-the-dump-interface-of-data-r.patch @@ -0,0 +1,41 @@ +From 71e9ffe7c553325616cf22611f108424ea9fe6bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Apr 2024 09:58:39 +0800 +Subject: spi: hisi-kunpeng: Delete the dump interface of data registers in + debugfs + +From: Devyn Liu + +[ Upstream commit 7430764f5a85d30314aeef2d5438dff1fb0b1d68 ] + +Due to the reading of FIFO during the dump of data registers in +debugfs, if SPI transmission is in progress, it will be affected +and may result in transmission failure. Therefore, the dump +interface of data registers in debugfs is removed. + +Fixes: 2b2142f247eb ("spi: hisi-kunpeng: Add debugfs support") +Signed-off-by: Devyn Liu +Reviewed-by: Jay Fang +Link: https://lore.kernel.org/r/20240416015839.3323398-1-liudingyuan@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-hisi-kunpeng.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c +index 35ef5e8e2ffd2..77e9738e42f60 100644 +--- a/drivers/spi/spi-hisi-kunpeng.c ++++ b/drivers/spi/spi-hisi-kunpeng.c +@@ -151,8 +151,6 @@ static const struct debugfs_reg32 hisi_spi_regs[] = { + HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR), + HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC), + HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR), +- HISI_SPI_DBGFS_REG("DIN", HISI_SPI_DIN), +- HISI_SPI_DBGFS_REG("DOUT", HISI_SPI_DOUT), + HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR), + HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR), + HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR), +-- +2.43.0 + diff --git a/queue-6.6/spi-spi-axi-spi-engine-use-helper-function-devm_clk_.patch b/queue-6.6/spi-spi-axi-spi-engine-use-helper-function-devm_clk_.patch new file mode 100644 index 00000000000..3f09a3e77f7 --- /dev/null +++ b/queue-6.6/spi-spi-axi-spi-engine-use-helper-function-devm_clk_.patch @@ -0,0 +1,105 @@ +From 62c21e4b0f545a15dd35be81bd09a1e5db97a7ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Aug 2023 21:39:18 +0800 +Subject: spi: spi-axi-spi-engine: Use helper function devm_clk_get_enabled() + +From: Li Zetao + +[ Upstream commit a08199b309f833fd4221ab5ee2391c791fe26385 ] + +Since commit 7ef9651e9792 ("clk: Provide new devm_clk helpers for prepared +and enabled clocks"), devm_clk_get() and clk_prepare_enable() can now be +replaced by devm_clk_get_enabled() when driver enables (and possibly +prepares) the clocks for the whole lifetime of the device. Moreover, it is +no longer necessary to unprepare and disable the clocks explicitly. + +Reviewed-by: Jonathan Cameron +Signed-off-by: Li Zetao +Link: https://lore.kernel.org/r/20230823133938.1359106-6-lizetao1@huawei.com +Signed-off-by: Mark Brown +Stable-dep-of: 0064db9ce4aa ("spi: axi-spi-engine: fix version format string") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-axi-spi-engine.c | 25 +++++-------------------- + 1 file changed, 5 insertions(+), 20 deletions(-) + +diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c +index 0258c9a72fdcc..b96e55f59d1a9 100644 +--- a/drivers/spi/spi-axi-spi-engine.c ++++ b/drivers/spi/spi-axi-spi-engine.c +@@ -485,30 +485,22 @@ static int spi_engine_probe(struct platform_device *pdev) + + spin_lock_init(&spi_engine->lock); + +- spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); ++ spi_engine->clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(spi_engine->clk)) { + ret = PTR_ERR(spi_engine->clk); + goto err_put_host; + } + +- spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk"); ++ spi_engine->ref_clk = devm_clk_get_enabled(&pdev->dev, "spi_clk"); + if (IS_ERR(spi_engine->ref_clk)) { + ret = PTR_ERR(spi_engine->ref_clk); + goto err_put_host; + } + +- ret = clk_prepare_enable(spi_engine->clk); +- if (ret) +- goto err_put_host; +- +- ret = clk_prepare_enable(spi_engine->ref_clk); +- if (ret) +- goto err_clk_disable; +- + spi_engine->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(spi_engine->base)) { + ret = PTR_ERR(spi_engine->base); +- goto err_ref_clk_disable; ++ goto err_put_host; + } + + version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); +@@ -518,7 +510,7 @@ static int spi_engine_probe(struct platform_device *pdev) + SPI_ENGINE_VERSION_MINOR(version), + SPI_ENGINE_VERSION_PATCH(version)); + ret = -ENODEV; +- goto err_ref_clk_disable; ++ goto err_put_host; + } + + writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); +@@ -527,7 +519,7 @@ static int spi_engine_probe(struct platform_device *pdev) + + ret = request_irq(irq, spi_engine_irq, 0, pdev->name, host); + if (ret) +- goto err_ref_clk_disable; ++ goto err_put_host; + + host->dev.of_node = pdev->dev.of_node; + host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE; +@@ -545,10 +537,6 @@ static int spi_engine_probe(struct platform_device *pdev) + return 0; + err_free_irq: + free_irq(irq, host); +-err_ref_clk_disable: +- clk_disable_unprepare(spi_engine->ref_clk); +-err_clk_disable: +- clk_disable_unprepare(spi_engine->clk); + err_put_host: + spi_controller_put(host); + return ret; +@@ -569,9 +557,6 @@ static void spi_engine_remove(struct platform_device *pdev) + writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); + writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET); +- +- clk_disable_unprepare(spi_engine->ref_clk); +- clk_disable_unprepare(spi_engine->clk); + } + + static const struct of_device_id spi_engine_match_table[] = { +-- +2.43.0 + diff --git a/queue-6.6/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch b/queue-6.6/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch new file mode 100644 index 00000000000..66b641da5e7 --- /dev/null +++ b/queue-6.6/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch @@ -0,0 +1,43 @@ +From 4f962c2f54caba19f1ed2149a55258e2fe03a471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 10:03:38 -0400 +Subject: tipc: fix a possible memleak in tipc_buf_append + +From: Xin Long + +[ Upstream commit 97bf6f81b29a8efaf5d0983251a7450e5794370d ] + +__skb_linearize() doesn't free the skb when it fails, so move +'*buf = NULL' after __skb_linearize(), so that the skb can be +freed on the err path. + +Fixes: b7df21cf1b79 ("tipc: skb_linearize the head skb when reassembling msgs") +Reported-by: Paolo Abeni +Signed-off-by: Xin Long +Reviewed-by: Simon Horman +Reviewed-by: Tung Nguyen +Link: https://lore.kernel.org/r/90710748c29a1521efac4f75ea01b3b7e61414cf.1714485818.git.lucien.xin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/tipc/msg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index 5c9fd4791c4ba..c52ab423082cd 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -142,9 +142,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + if (fragid == FIRST_FRAGMENT) { + if (unlikely(head)) + goto err; +- *buf = NULL; + if (skb_has_frag_list(frag) && __skb_linearize(frag)) + goto err; ++ *buf = NULL; + frag = skb_unshare(frag, GFP_ATOMIC); + if (unlikely(!frag)) + goto err; +-- +2.43.0 + diff --git a/queue-6.6/vxlan-add-missing-vni-filter-counter-update-in-arp_r.patch b/queue-6.6/vxlan-add-missing-vni-filter-counter-update-in-arp_r.patch new file mode 100644 index 00000000000..d1b785dc1e9 --- /dev/null +++ b/queue-6.6/vxlan-add-missing-vni-filter-counter-update-in-arp_r.patch @@ -0,0 +1,40 @@ +From fe8564d5f2c32689ba949aef8f8743ca0fe9a624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 17:27:19 +0200 +Subject: vxlan: Add missing VNI filter counter update in arp_reduce(). + +From: Guillaume Nault + +[ Upstream commit b22ea4ef4c3438817fcb604255b55b0058ed8c64 ] + +VXLAN stores per-VNI statistics using vxlan_vnifilter_count(). +These statistics were not updated when arp_reduce() failed its +pskb_may_pull() call. + +Use vxlan_vnifilter_count() to update the VNI counter when that +happens. + +Fixes: 4095e0e1328a ("drivers: vxlan: vnifilter: per vni stats") +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index 3d3c11e61f9de..7e5e60318045a 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -1838,6 +1838,8 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + + if (!pskb_may_pull(skb, arp_hdr_len(dev))) { + dev_core_stats_tx_dropped_inc(dev); ++ vxlan_vnifilter_count(vxlan, vni, NULL, ++ VXLAN_VNI_STATS_TX_DROPS, 0); + goto out; + } + parp = arp_hdr(skb); +-- +2.43.0 + diff --git a/queue-6.6/vxlan-fix-racy-device-stats-updates.patch b/queue-6.6/vxlan-fix-racy-device-stats-updates.patch new file mode 100644 index 00000000000..ee28274e8ed --- /dev/null +++ b/queue-6.6/vxlan-fix-racy-device-stats-updates.patch @@ -0,0 +1,140 @@ +From 84963967b168ca46896481eaf66f2d940be97c4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Apr 2024 17:27:17 +0200 +Subject: vxlan: Fix racy device stats updates. + +From: Guillaume Nault + +[ Upstream commit 6dee402daba4eb8677a9438ebdcd8fe90ddd4326 ] + +VXLAN devices update their stats locklessly. Therefore these counters +should either be stored in per-cpu data structures or the updates +should be done using atomic increments. + +Since the net_device_core_stats infrastructure is already used in +vxlan_rcv(), use it for the other rx_dropped and tx_dropped counter +updates. Update the other counters atomically using DEV_STATS_INC(). + +Fixes: d342894c5d2f ("vxlan: virtual extensible lan") +Signed-off-by: Guillaume Nault +Reviewed-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index ecdf0276004f9..3d3c11e61f9de 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -1766,8 +1766,8 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) + skb_reset_network_header(skb); + + if (!vxlan_ecn_decapsulate(vs, oiph, skb)) { +- ++vxlan->dev->stats.rx_frame_errors; +- ++vxlan->dev->stats.rx_errors; ++ DEV_STATS_INC(vxlan->dev, rx_frame_errors); ++ DEV_STATS_INC(vxlan->dev, rx_errors); + vxlan_vnifilter_count(vxlan, vni, vninode, + VXLAN_VNI_STATS_RX_ERRORS, 0); + goto drop; +@@ -1837,7 +1837,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + goto out; + + if (!pskb_may_pull(skb, arp_hdr_len(dev))) { +- dev->stats.tx_dropped++; ++ dev_core_stats_tx_dropped_inc(dev); + goto out; + } + parp = arp_hdr(skb); +@@ -1893,7 +1893,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + reply->pkt_type = PACKET_HOST; + + if (netif_rx(reply) == NET_RX_DROP) { +- dev->stats.rx_dropped++; ++ dev_core_stats_rx_dropped_inc(dev); + vxlan_vnifilter_count(vxlan, vni, NULL, + VXLAN_VNI_STATS_RX_DROPS, 0); + } +@@ -2052,7 +2052,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) + goto out; + + if (netif_rx(reply) == NET_RX_DROP) { +- dev->stats.rx_dropped++; ++ dev_core_stats_rx_dropped_inc(dev); + vxlan_vnifilter_count(vxlan, vni, NULL, + VXLAN_VNI_STATS_RX_DROPS, 0); + } +@@ -2371,7 +2371,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, + len); + } else { + drop: +- dev->stats.rx_dropped++; ++ dev_core_stats_rx_dropped_inc(dev); + vxlan_vnifilter_count(dst_vxlan, vni, NULL, + VXLAN_VNI_STATS_RX_DROPS, 0); + } +@@ -2403,7 +2403,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev, + daddr->sa.sa_family, dst_port, + vxlan->cfg.flags); + if (!dst_vxlan) { +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + vxlan_vnifilter_count(vxlan, vni, NULL, + VXLAN_VNI_STATS_TX_ERRORS, 0); + kfree_skb(skb); +@@ -2664,7 +2664,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + return; + + drop: +- dev->stats.tx_dropped++; ++ dev_core_stats_tx_dropped_inc(dev); + vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_DROPS, 0); + dev_kfree_skb(skb); + return; +@@ -2672,11 +2672,11 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + tx_error: + rcu_read_unlock(); + if (err == -ELOOP) +- dev->stats.collisions++; ++ DEV_STATS_INC(dev, collisions); + else if (err == -ENETUNREACH) +- dev->stats.tx_carrier_errors++; ++ DEV_STATS_INC(dev, tx_carrier_errors); + dst_release(ndst); +- dev->stats.tx_errors++; ++ DEV_STATS_INC(dev, tx_errors); + vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_ERRORS, 0); + kfree_skb(skb); + } +@@ -2709,7 +2709,7 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev, + return; + + drop: +- dev->stats.tx_dropped++; ++ dev_core_stats_tx_dropped_inc(dev); + vxlan_vnifilter_count(netdev_priv(dev), vni, NULL, + VXLAN_VNI_STATS_TX_DROPS, 0); + dev_kfree_skb(skb); +@@ -2747,7 +2747,7 @@ static netdev_tx_t vxlan_xmit_nhid(struct sk_buff *skb, struct net_device *dev, + return NETDEV_TX_OK; + + drop: +- dev->stats.tx_dropped++; ++ dev_core_stats_tx_dropped_inc(dev); + vxlan_vnifilter_count(netdev_priv(dev), vni, NULL, + VXLAN_VNI_STATS_TX_DROPS, 0); + dev_kfree_skb(skb); +@@ -2844,7 +2844,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) + !is_multicast_ether_addr(eth->h_dest)) + vxlan_fdb_miss(vxlan, eth->h_dest); + +- dev->stats.tx_dropped++; ++ dev_core_stats_tx_dropped_inc(dev); + vxlan_vnifilter_count(vxlan, vni, NULL, + VXLAN_VNI_STATS_TX_DROPS, 0); + kfree_skb(skb); +-- +2.43.0 + diff --git a/queue-6.6/vxlan-pull-inner-ip-header-in-vxlan_rcv.patch b/queue-6.6/vxlan-pull-inner-ip-header-in-vxlan_rcv.patch new file mode 100644 index 00000000000..121759abf74 --- /dev/null +++ b/queue-6.6/vxlan-pull-inner-ip-header-in-vxlan_rcv.patch @@ -0,0 +1,74 @@ +From def4285d833616ac7ccebc15a7b6621c659668d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Apr 2024 18:50:13 +0200 +Subject: vxlan: Pull inner IP header in vxlan_rcv(). + +From: Guillaume Nault + +[ Upstream commit f7789419137b18e3847d0cc41afd788c3c00663d ] + +Ensure the inner IP header is part of skb's linear data before reading +its ECN bits. Otherwise we might read garbage. +One symptom is the system erroneously logging errors like +"vxlan: non-ECT from xxx.xxx.xxx.xxx with TOS=xxxx". + +Similar bugs have been fixed in geneve, ip_tunnel and ip6_tunnel (see +commit 1ca1ba465e55 ("geneve: make sure to pull inner header in +geneve_rx()") for example). So let's reuse the same code structure for +consistency. Maybe we'll can add a common helper in the future. + +Fixes: d342894c5d2f ("vxlan: virtual extensible lan") +Signed-off-by: Guillaume Nault +Reviewed-by: Ido Schimmel +Reviewed-by: Eric Dumazet +Reviewed-by: Nikolay Aleksandrov +Reviewed-by: Sabrina Dubroca +Link: https://lore.kernel.org/r/1239c8db54efec341dd6455c77e0380f58923a3c.1714495737.git.gnault@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index 7e5e60318045a..f98069920e27f 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -1674,6 +1674,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) + bool raw_proto = false; + void *oiph; + __be32 vni = 0; ++ int nh; + + /* Need UDP and VXLAN header to be present */ + if (!pskb_may_pull(skb, VXLAN_HLEN)) +@@ -1762,9 +1763,25 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) + skb->pkt_type = PACKET_HOST; + } + +- oiph = skb_network_header(skb); ++ /* Save offset of outer header relative to skb->head, ++ * because we are going to reset the network header to the inner header ++ * and might change skb->head. ++ */ ++ nh = skb_network_header(skb) - skb->head; ++ + skb_reset_network_header(skb); + ++ if (!pskb_inet_may_pull(skb)) { ++ DEV_STATS_INC(vxlan->dev, rx_length_errors); ++ DEV_STATS_INC(vxlan->dev, rx_errors); ++ vxlan_vnifilter_count(vxlan, vni, vninode, ++ VXLAN_VNI_STATS_RX_ERRORS, 0); ++ goto drop; ++ } ++ ++ /* Get the outer header. */ ++ oiph = skb->head + nh; ++ + if (!vxlan_ecn_decapsulate(vs, oiph, skb)) { + DEV_STATS_INC(vxlan->dev, rx_frame_errors); + DEV_STATS_INC(vxlan->dev, rx_errors); +-- +2.43.0 + diff --git a/queue-6.6/xdp-use-flags-field-to-disambiguate-broadcast-redire.patch b/queue-6.6/xdp-use-flags-field-to-disambiguate-broadcast-redire.patch new file mode 100644 index 00000000000..bb212cedc99 --- /dev/null +++ b/queue-6.6/xdp-use-flags-field-to-disambiguate-broadcast-redire.patch @@ -0,0 +1,153 @@ +From 15347a65295bb39f94618f9df3ac11b610989050 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 09:18:39 +0200 +Subject: xdp: use flags field to disambiguate broadcast redirect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit 5bcf0dcbf9066348058b88a510c57f70f384c92c ] + +When redirecting a packet using XDP, the bpf_redirect_map() helper will set +up the redirect destination information in struct bpf_redirect_info (using +the __bpf_xdp_redirect_map() helper function), and the xdp_do_redirect() +function will read this information after the XDP program returns and pass +the frame on to the right redirect destination. + +When using the BPF_F_BROADCAST flag to do multicast redirect to a whole +map, __bpf_xdp_redirect_map() sets the 'map' pointer in struct +bpf_redirect_info to point to the destination map to be broadcast. And +xdp_do_redirect() reacts to the value of this map pointer to decide whether +it's dealing with a broadcast or a single-value redirect. However, if the +destination map is being destroyed before xdp_do_redirect() is called, the +map pointer will be cleared out (by bpf_clear_redirect_map()) without +waiting for any XDP programs to stop running. This causes xdp_do_redirect() +to think that the redirect was to a single target, but the target pointer +is also NULL (since broadcast redirects don't have a single target), so +this causes a crash when a NULL pointer is passed to dev_map_enqueue(). + +To fix this, change xdp_do_redirect() to react directly to the presence of +the BPF_F_BROADCAST flag in the 'flags' value in struct bpf_redirect_info +to disambiguate between a single-target and a broadcast redirect. And only +read the 'map' pointer if the broadcast flag is set, aborting if that has +been cleared out in the meantime. This prevents the crash, while keeping +the atomic (cmpxchg-based) clearing of the map pointer itself, and without +adding any more checks in the non-broadcast fast path. + +Fixes: e624d4ed4aa8 ("xdp: Extend xdp_redirect_map with broadcast support") +Reported-and-tested-by: syzbot+af9492708df9797198d6@syzkaller.appspotmail.com +Signed-off-by: Toke Høiland-Jørgensen +Acked-by: Stanislav Fomichev +Reviewed-by: Hangbin Liu +Acked-by: Jesper Dangaard Brouer +Link: https://lore.kernel.org/r/20240418071840.156411-1-toke@redhat.com +Signed-off-by: Martin KaFai Lau +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 42 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 32 insertions(+), 10 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 24f23a30c945e..df4578219e82c 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -4334,10 +4334,12 @@ static __always_inline int __xdp_do_redirect_frame(struct bpf_redirect_info *ri, + enum bpf_map_type map_type = ri->map_type; + void *fwd = ri->tgt_value; + u32 map_id = ri->map_id; ++ u32 flags = ri->flags; + struct bpf_map *map; + int err; + + ri->map_id = 0; /* Valid map id idr range: [1,INT_MAX[ */ ++ ri->flags = 0; + ri->map_type = BPF_MAP_TYPE_UNSPEC; + + if (unlikely(!xdpf)) { +@@ -4349,11 +4351,20 @@ static __always_inline int __xdp_do_redirect_frame(struct bpf_redirect_info *ri, + case BPF_MAP_TYPE_DEVMAP: + fallthrough; + case BPF_MAP_TYPE_DEVMAP_HASH: +- map = READ_ONCE(ri->map); +- if (unlikely(map)) { ++ if (unlikely(flags & BPF_F_BROADCAST)) { ++ map = READ_ONCE(ri->map); ++ ++ /* The map pointer is cleared when the map is being torn ++ * down by bpf_clear_redirect_map() ++ */ ++ if (unlikely(!map)) { ++ err = -ENOENT; ++ break; ++ } ++ + WRITE_ONCE(ri->map, NULL); + err = dev_map_enqueue_multi(xdpf, dev, map, +- ri->flags & BPF_F_EXCLUDE_INGRESS); ++ flags & BPF_F_EXCLUDE_INGRESS); + } else { + err = dev_map_enqueue(fwd, xdpf, dev); + } +@@ -4416,9 +4427,9 @@ EXPORT_SYMBOL_GPL(xdp_do_redirect_frame); + static int xdp_do_generic_redirect_map(struct net_device *dev, + struct sk_buff *skb, + struct xdp_buff *xdp, +- struct bpf_prog *xdp_prog, +- void *fwd, +- enum bpf_map_type map_type, u32 map_id) ++ struct bpf_prog *xdp_prog, void *fwd, ++ enum bpf_map_type map_type, u32 map_id, ++ u32 flags) + { + struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info); + struct bpf_map *map; +@@ -4428,11 +4439,20 @@ static int xdp_do_generic_redirect_map(struct net_device *dev, + case BPF_MAP_TYPE_DEVMAP: + fallthrough; + case BPF_MAP_TYPE_DEVMAP_HASH: +- map = READ_ONCE(ri->map); +- if (unlikely(map)) { ++ if (unlikely(flags & BPF_F_BROADCAST)) { ++ map = READ_ONCE(ri->map); ++ ++ /* The map pointer is cleared when the map is being torn ++ * down by bpf_clear_redirect_map() ++ */ ++ if (unlikely(!map)) { ++ err = -ENOENT; ++ break; ++ } ++ + WRITE_ONCE(ri->map, NULL); + err = dev_map_redirect_multi(dev, skb, xdp_prog, map, +- ri->flags & BPF_F_EXCLUDE_INGRESS); ++ flags & BPF_F_EXCLUDE_INGRESS); + } else { + err = dev_map_generic_redirect(fwd, skb, xdp_prog); + } +@@ -4469,9 +4489,11 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb, + enum bpf_map_type map_type = ri->map_type; + void *fwd = ri->tgt_value; + u32 map_id = ri->map_id; ++ u32 flags = ri->flags; + int err; + + ri->map_id = 0; /* Valid map id idr range: [1,INT_MAX[ */ ++ ri->flags = 0; + ri->map_type = BPF_MAP_TYPE_UNSPEC; + + if (map_type == BPF_MAP_TYPE_UNSPEC && map_id == INT_MAX) { +@@ -4491,7 +4513,7 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb, + return 0; + } + +- return xdp_do_generic_redirect_map(dev, skb, xdp, xdp_prog, fwd, map_type, map_id); ++ return xdp_do_generic_redirect_map(dev, skb, xdp, xdp_prog, fwd, map_type, map_id, flags); + err: + _trace_xdp_redirect_err(dev, xdp_prog, ri->tgt_index, err); + return err; +-- +2.43.0 +