]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sun, 7 Jan 2024 01:58:54 +0000 (20:58 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 7 Jan 2024 01:58:54 +0000 (20:58 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
22 files changed:
queue-5.4/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch [new file with mode: 0644]
queue-5.4/asix-add-check-for-usbnet_get_endpoints.patch [new file with mode: 0644]
queue-5.4/asoc-meson-g12a-extract-codec-to-codec-utils.patch [new file with mode: 0644]
queue-5.4/asoc-meson-g12a-tohdmitx-fix-event-generation-for-s-.patch [new file with mode: 0644]
queue-5.4/asoc-meson-g12a-tohdmitx-validate-written-enum-value.patch [new file with mode: 0644]
queue-5.4/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch [new file with mode: 0644]
queue-5.4/can-raw-add-support-for-so_mark.patch [new file with mode: 0644]
queue-5.4/can-raw-add-support-for-so_txtime-scm_txtime.patch [new file with mode: 0644]
queue-5.4/i40e-fix-filter-input-checks-to-prevent-config-with-.patch [new file with mode: 0644]
queue-5.4/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch [new file with mode: 0644]
queue-5.4/i40e-restore-vf-msi-x-state-during-pci-reset.patch [new file with mode: 0644]
queue-5.4/mm-memory-failure-check-the-mapcount-of-the-precise-.patch [new file with mode: 0644]
queue-5.4/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch [new file with mode: 0644]
queue-5.4/net-implement-missing-getsockopt-so_timestamping_new.patch [new file with mode: 0644]
queue-5.4/net-implement-missing-so_timestamping_new-cmsg-suppo.patch [new file with mode: 0644]
queue-5.4/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch [new file with mode: 0644]
queue-5.4/net-qla3xxx-switch-from-pci_-to-dma_-api.patch [new file with mode: 0644]
queue-5.4/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch [new file with mode: 0644]
queue-5.4/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch [new file with mode: 0644]
queue-5.4/net-timestamp-extend-sof_timestamping_opt_id-to-hw-t.patch [new file with mode: 0644]
queue-5.4/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch b/queue-5.4/arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch
new file mode 100644 (file)
index 0000000..55bc9f8
--- /dev/null
@@ -0,0 +1,64 @@
+From 0ee4cf301c543492c01c39c5b44433dfe78c5468 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 20:39:02 +0100
+Subject: ARM: sun9i: smp: Fix array-index-out-of-bounds read in
+ sunxi_mc_smp_init
+
+From: Stefan Wahren <wahrenst@gmx.net>
+
+[ Upstream commit 72ad3b772b6d393701df58ba1359b0bb346a19ed ]
+
+Running a multi-arch kernel (multi_v7_defconfig) on a Raspberry Pi 3B+
+with enabled CONFIG_UBSAN triggers the following warning:
+
+ UBSAN: array-index-out-of-bounds in arch/arm/mach-sunxi/mc_smp.c:810:29
+ index 2 is out of range for type 'sunxi_mc_smp_data [2]'
+ CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc6-00248-g5254c0cbc92d
+ Hardware name: BCM2835
+  unwind_backtrace from show_stack+0x10/0x14
+  show_stack from dump_stack_lvl+0x40/0x4c
+  dump_stack_lvl from ubsan_epilogue+0x8/0x34
+  ubsan_epilogue from __ubsan_handle_out_of_bounds+0x78/0x80
+  __ubsan_handle_out_of_bounds from sunxi_mc_smp_init+0xe4/0x4cc
+  sunxi_mc_smp_init from do_one_initcall+0xa0/0x2fc
+  do_one_initcall from kernel_init_freeable+0xf4/0x2f4
+  kernel_init_freeable from kernel_init+0x18/0x158
+  kernel_init from ret_from_fork+0x14/0x28
+
+Since the enabled method couldn't match with any entry from
+sunxi_mc_smp_data, the value of the index shouldn't be used right after
+the loop. So move it after the check of ret in order to have a valid
+index.
+
+Fixes: 1631090e34f5 ("ARM: sun9i: smp: Add is_a83t field")
+Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
+Link: https://lore.kernel.org/r/20231228193903.9078-1-wahrenst@gmx.net
+Reviewed-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-sunxi/mc_smp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c
+index 26cbce1353387..b2f5f4f28705f 100644
+--- a/arch/arm/mach-sunxi/mc_smp.c
++++ b/arch/arm/mach-sunxi/mc_smp.c
+@@ -808,12 +808,12 @@ static int __init sunxi_mc_smp_init(void)
+                       break;
+       }
+-      is_a83t = sunxi_mc_smp_data[i].is_a83t;
+-
+       of_node_put(node);
+       if (ret)
+               return -ENODEV;
++      is_a83t = sunxi_mc_smp_data[i].is_a83t;
++
+       if (!sunxi_mc_smp_cpu_table_init())
+               return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-5.4/asix-add-check-for-usbnet_get_endpoints.patch b/queue-5.4/asix-add-check-for-usbnet_get_endpoints.patch
new file mode 100644 (file)
index 0000000..3ffaabd
--- /dev/null
@@ -0,0 +1,38 @@
+From fb6265e8f9403d8822dd36a8912e3f23e465957b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 03:35:34 +0000
+Subject: asix: Add check for usbnet_get_endpoints
+
+From: Chen Ni <nichen@iscas.ac.cn>
+
+[ Upstream commit eaac6a2d26b65511e164772bec6918fcbc61938e ]
+
+Add check for usbnet_get_endpoints() and return the error if it fails
+in order to transfer the error.
+
+Fixes: 16626b0cc3d5 ("asix: Add a new driver for the AX88172A")
+Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/ax88172a.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
+index 6101d82102e79..bf65262e2256d 100644
+--- a/drivers/net/usb/ax88172a.c
++++ b/drivers/net/usb/ax88172a.c
+@@ -186,7 +186,9 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
+       u8 buf[ETH_ALEN];
+       struct ax88172a_private *priv;
+-      usbnet_get_endpoints(dev, intf);
++      ret = usbnet_get_endpoints(dev, intf);
++      if (ret)
++              return ret;
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+-- 
+2.43.0
+
diff --git a/queue-5.4/asoc-meson-g12a-extract-codec-to-codec-utils.patch b/queue-5.4/asoc-meson-g12a-extract-codec-to-codec-utils.patch
new file mode 100644 (file)
index 0000000..b3ad8fd
--- /dev/null
@@ -0,0 +1,573 @@
+From 51aa6d37a344fca4c0bc043f6e7002bd1ef99833 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Feb 2020 16:51:52 +0100
+Subject: ASoC: meson: g12a: extract codec-to-codec utils
+
+From: Jerome Brunet <jbrunet@baylibre.com>
+
+[ Upstream commit 9c29fd9bdf92900dc0cc5c2d8f58951a7bdc0f41 ]
+
+The hdmi routing mechanism used on g12a hdmi is also used:
+* other Amlogic SoC types
+* for the internal DAC path
+
+Each of these codec glues are slightly different but the idea
+behind it remains the same. This change extract some helper functions
+from the g12a-tohdmitx driver to make them available for other Amlogic
+codecs.
+
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Link: https://lore.kernel.org/r/20200213155159.3235792-3-jbrunet@baylibre.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 1e001206804b ("ASoC: meson: g12a-tohdmitx: Validate written enum values")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/Kconfig            |   4 +
+ sound/soc/meson/Makefile           |   2 +
+ sound/soc/meson/g12a-tohdmitx.c    | 219 ++++++-----------------------
+ sound/soc/meson/meson-codec-glue.c | 149 ++++++++++++++++++++
+ sound/soc/meson/meson-codec-glue.h |  32 +++++
+ 5 files changed, 230 insertions(+), 176 deletions(-)
+ create mode 100644 sound/soc/meson/meson-codec-glue.c
+ create mode 100644 sound/soc/meson/meson-codec-glue.h
+
+diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
+index e0d24592ebd70..f9188274f6b0f 100644
+--- a/sound/soc/meson/Kconfig
++++ b/sound/soc/meson/Kconfig
+@@ -85,9 +85,13 @@ config SND_MESON_AXG_PDM
+         Select Y or M to add support for PDM input embedded
+         in the Amlogic AXG SoC family
++config SND_MESON_CODEC_GLUE
++      tristate
++
+ config SND_MESON_G12A_TOHDMITX
+       tristate "Amlogic G12A To HDMI TX Control Support"
+       select REGMAP_MMIO
++      select SND_MESON_CODEC_GLUE
+       imply SND_SOC_HDMI_CODEC
+       help
+         Select Y or M to add support for HDMI audio on the g12a SoC
+diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
+index 1a8b1470ed843..529a807b3f376 100644
+--- a/sound/soc/meson/Makefile
++++ b/sound/soc/meson/Makefile
+@@ -11,6 +11,7 @@ snd-soc-meson-axg-sound-card-objs := axg-card.o
+ snd-soc-meson-axg-spdifin-objs := axg-spdifin.o
+ snd-soc-meson-axg-spdifout-objs := axg-spdifout.o
+ snd-soc-meson-axg-pdm-objs := axg-pdm.o
++snd-soc-meson-codec-glue-objs := meson-codec-glue.o
+ snd-soc-meson-g12a-tohdmitx-objs := g12a-tohdmitx.o
+ obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o
+@@ -24,4 +25,5 @@ obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o
+ obj-$(CONFIG_SND_MESON_AXG_SPDIFIN) += snd-soc-meson-axg-spdifin.o
+ obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
+ obj-$(CONFIG_SND_MESON_AXG_PDM) += snd-soc-meson-axg-pdm.o
++obj-$(CONFIG_SND_MESON_CODEC_GLUE) += snd-soc-meson-codec-glue.o
+ obj-$(CONFIG_SND_MESON_G12A_TOHDMITX) += snd-soc-meson-g12a-tohdmitx.o
+diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
+index cbe47e0cae426..d02825669484a 100644
+--- a/sound/soc/meson/g12a-tohdmitx.c
++++ b/sound/soc/meson/g12a-tohdmitx.c
+@@ -12,112 +12,51 @@
+ #include <sound/soc-dai.h>
+ #include <dt-bindings/sound/meson-g12a-tohdmitx.h>
++#include "meson-codec-glue.h"
+ #define G12A_TOHDMITX_DRV_NAME "g12a-tohdmitx"
+ #define TOHDMITX_CTRL0                        0x0
+ #define  CTRL0_ENABLE_SHIFT           31
+-#define  CTRL0_I2S_DAT_SEL            GENMASK(13, 12)
++#define  CTRL0_I2S_DAT_SEL_SHIFT      12
++#define  CTRL0_I2S_DAT_SEL            (0x3 << CTRL0_I2S_DAT_SEL_SHIFT)
+ #define  CTRL0_I2S_LRCLK_SEL          GENMASK(9, 8)
+ #define  CTRL0_I2S_BLK_CAP_INV                BIT(7)
+ #define  CTRL0_I2S_BCLK_O_INV         BIT(6)
+ #define  CTRL0_I2S_BCLK_SEL           GENMASK(5, 4)
+ #define  CTRL0_SPDIF_CLK_CAP_INV      BIT(3)
+ #define  CTRL0_SPDIF_CLK_O_INV                BIT(2)
+-#define  CTRL0_SPDIF_SEL              BIT(1)
++#define  CTRL0_SPDIF_SEL_SHIFT                1
++#define  CTRL0_SPDIF_SEL              (0x1 << CTRL0_SPDIF_SEL_SHIFT)
+ #define  CTRL0_SPDIF_CLK_SEL          BIT(0)
+-struct g12a_tohdmitx_input {
+-      struct snd_soc_pcm_stream params;
+-      unsigned int fmt;
+-};
+-
+-static struct snd_soc_dapm_widget *
+-g12a_tohdmitx_get_input(struct snd_soc_dapm_widget *w)
+-{
+-      struct snd_soc_dapm_path *p = NULL;
+-      struct snd_soc_dapm_widget *in;
+-
+-      snd_soc_dapm_widget_for_each_source_path(w, p) {
+-              if (!p->connect)
+-                      continue;
+-
+-              /* Check that we still are in the same component */
+-              if (snd_soc_dapm_to_component(w->dapm) !=
+-                  snd_soc_dapm_to_component(p->source->dapm))
+-                      continue;
+-
+-              if (p->source->id == snd_soc_dapm_dai_in)
+-                      return p->source;
+-
+-              in = g12a_tohdmitx_get_input(p->source);
+-              if (in)
+-                      return in;
+-      }
+-
+-      return NULL;
+-}
+-
+-static struct g12a_tohdmitx_input *
+-g12a_tohdmitx_get_input_data(struct snd_soc_dapm_widget *w)
+-{
+-      struct snd_soc_dapm_widget *in =
+-              g12a_tohdmitx_get_input(w);
+-      struct snd_soc_dai *dai;
+-
+-      if (WARN_ON(!in))
+-              return NULL;
+-
+-      dai = in->priv;
+-
+-      return dai->playback_dma_data;
+-}
+-
+ static const char * const g12a_tohdmitx_i2s_mux_texts[] = {
+       "I2S A", "I2S B", "I2S C",
+ };
+-static SOC_ENUM_SINGLE_EXT_DECL(g12a_tohdmitx_i2s_mux_enum,
+-                              g12a_tohdmitx_i2s_mux_texts);
+-
+-static int g12a_tohdmitx_get_input_val(struct snd_soc_component *component,
+-                                     unsigned int mask)
+-{
+-      unsigned int val;
+-
+-      snd_soc_component_read(component, TOHDMITX_CTRL0, &val);
+-      return (val & mask) >> __ffs(mask);
+-}
+-
+-static int g12a_tohdmitx_i2s_mux_get_enum(struct snd_kcontrol *kcontrol,
+-                                        struct snd_ctl_elem_value *ucontrol)
+-{
+-      struct snd_soc_component *component =
+-              snd_soc_dapm_kcontrol_component(kcontrol);
+-
+-      ucontrol->value.enumerated.item[0] =
+-              g12a_tohdmitx_get_input_val(component, CTRL0_I2S_DAT_SEL);
+-
+-      return 0;
+-}
+-
+ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol,
+-                                        struct snd_ctl_elem_value *ucontrol)
++                                 struct snd_ctl_elem_value *ucontrol)
+ {
+       struct snd_soc_component *component =
+               snd_soc_dapm_kcontrol_component(kcontrol);
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-      unsigned int mux = ucontrol->value.enumerated.item[0];
+-      unsigned int val = g12a_tohdmitx_get_input_val(component,
+-                                                     CTRL0_I2S_DAT_SEL);
++      unsigned int mux, changed;
++
++      mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]);
++      changed = snd_soc_component_test_bits(component, e->reg,
++                                            CTRL0_I2S_DAT_SEL,
++                                            FIELD_PREP(CTRL0_I2S_DAT_SEL,
++                                                       mux));
++
++      if (!changed)
++              return 0;
+       /* Force disconnect of the mux while updating */
+-      if (val != mux)
+-              snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL);
++      snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL);
+-      snd_soc_component_update_bits(component, TOHDMITX_CTRL0,
++      snd_soc_component_update_bits(component, e->reg,
+                                     CTRL0_I2S_DAT_SEL |
+                                     CTRL0_I2S_LRCLK_SEL |
+                                     CTRL0_I2S_BCLK_SEL,
+@@ -130,30 +69,19 @@ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol,
+       return 1;
+ }
++static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_i2s_mux_enum, TOHDMITX_CTRL0,
++                          CTRL0_I2S_DAT_SEL_SHIFT,
++                          g12a_tohdmitx_i2s_mux_texts);
++
+ static const struct snd_kcontrol_new g12a_tohdmitx_i2s_mux =
+       SOC_DAPM_ENUM_EXT("I2S Source", g12a_tohdmitx_i2s_mux_enum,
+-                        g12a_tohdmitx_i2s_mux_get_enum,
++                        snd_soc_dapm_get_enum_double,
+                         g12a_tohdmitx_i2s_mux_put_enum);
+ static const char * const g12a_tohdmitx_spdif_mux_texts[] = {
+       "SPDIF A", "SPDIF B",
+ };
+-static SOC_ENUM_SINGLE_EXT_DECL(g12a_tohdmitx_spdif_mux_enum,
+-                              g12a_tohdmitx_spdif_mux_texts);
+-
+-static int g12a_tohdmitx_spdif_mux_get_enum(struct snd_kcontrol *kcontrol,
+-                                          struct snd_ctl_elem_value *ucontrol)
+-{
+-      struct snd_soc_component *component =
+-              snd_soc_dapm_kcontrol_component(kcontrol);
+-
+-      ucontrol->value.enumerated.item[0] =
+-              g12a_tohdmitx_get_input_val(component, CTRL0_SPDIF_SEL);
+-
+-      return 0;
+-}
+-
+ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol,
+                                           struct snd_ctl_elem_value *ucontrol)
+ {
+@@ -162,13 +90,18 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol,
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+-      unsigned int mux = ucontrol->value.enumerated.item[0];
+-      unsigned int val = g12a_tohdmitx_get_input_val(component,
+-                                                     CTRL0_SPDIF_SEL);
++      unsigned int mux, changed;
++
++      mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]);
++      changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0,
++                                            CTRL0_SPDIF_SEL,
++                                            FIELD_PREP(CTRL0_SPDIF_SEL, mux));
++
++      if (!changed)
++              return 0;
+       /* Force disconnect of the mux while updating */
+-      if (val != mux)
+-              snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL);
++      snd_soc_dapm_mux_update_power(dapm, kcontrol, 0, NULL, NULL);
+       snd_soc_component_update_bits(component, TOHDMITX_CTRL0,
+                                     CTRL0_SPDIF_SEL |
+@@ -181,9 +114,13 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol,
+       return 0;
+ }
++static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0,
++                          CTRL0_SPDIF_SEL_SHIFT,
++                          g12a_tohdmitx_spdif_mux_texts);
++
+ static const struct snd_kcontrol_new g12a_tohdmitx_spdif_mux =
+       SOC_DAPM_ENUM_EXT("SPDIF Source", g12a_tohdmitx_spdif_mux_enum,
+-                        g12a_tohdmitx_spdif_mux_get_enum,
++                        snd_soc_dapm_get_enum_double,
+                         g12a_tohdmitx_spdif_mux_put_enum);
+ static const struct snd_kcontrol_new g12a_tohdmitx_out_enable =
+@@ -201,83 +138,13 @@ static const struct snd_soc_dapm_widget g12a_tohdmitx_widgets[] = {
+                           &g12a_tohdmitx_out_enable),
+ };
+-static int g12a_tohdmitx_input_probe(struct snd_soc_dai *dai)
+-{
+-      struct g12a_tohdmitx_input *data;
+-
+-      data = kzalloc(sizeof(*data), GFP_KERNEL);
+-      if (!data)
+-              return -ENOMEM;
+-
+-      dai->playback_dma_data = data;
+-      return 0;
+-}
+-
+-static int g12a_tohdmitx_input_remove(struct snd_soc_dai *dai)
+-{
+-      kfree(dai->playback_dma_data);
+-      return 0;
+-}
+-
+-static int g12a_tohdmitx_input_hw_params(struct snd_pcm_substream *substream,
+-                                       struct snd_pcm_hw_params *params,
+-                                       struct snd_soc_dai *dai)
+-{
+-      struct g12a_tohdmitx_input *data = dai->playback_dma_data;
+-
+-      data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params));
+-      data->params.rate_min = params_rate(params);
+-      data->params.rate_max = params_rate(params);
+-      data->params.formats = 1 << params_format(params);
+-      data->params.channels_min = params_channels(params);
+-      data->params.channels_max = params_channels(params);
+-      data->params.sig_bits = dai->driver->playback.sig_bits;
+-
+-      return 0;
+-}
+-
+-
+-static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai,
+-                                     unsigned int fmt)
+-{
+-      struct g12a_tohdmitx_input *data = dai->playback_dma_data;
+-
+-      /* Save the source stream format for the downstream link */
+-      data->fmt = fmt;
+-      return 0;
+-}
+-
+-static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream,
+-                                      struct snd_soc_dai *dai)
+-{
+-      struct snd_soc_pcm_runtime *rtd = substream->private_data;
+-      struct g12a_tohdmitx_input *in_data =
+-              g12a_tohdmitx_get_input_data(dai->capture_widget);
+-
+-      if (!in_data)
+-              return -ENODEV;
+-
+-      if (WARN_ON(!rtd->dai_link->params)) {
+-              dev_warn(dai->dev, "codec2codec link expected\n");
+-              return -EINVAL;
+-      }
+-
+-      /* Replace link params with the input params */
+-      rtd->dai_link->params = &in_data->params;
+-
+-      if (!in_data->fmt)
+-              return 0;
+-
+-      return snd_soc_runtime_set_dai_fmt(rtd, in_data->fmt);
+-}
+-
+ static const struct snd_soc_dai_ops g12a_tohdmitx_input_ops = {
+-      .hw_params      = g12a_tohdmitx_input_hw_params,
+-      .set_fmt        = g12a_tohdmitx_input_set_fmt,
++      .hw_params      = meson_codec_glue_input_hw_params,
++      .set_fmt        = meson_codec_glue_input_set_fmt,
+ };
+ static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = {
+-      .startup        = g12a_tohdmitx_output_startup,
++      .startup        = meson_codec_glue_output_startup,
+ };
+ #define TOHDMITX_SPDIF_FORMATS                                        \
+@@ -304,8 +171,8 @@ static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = {
+       .id = (xid),                                                    \
+       .playback = TOHDMITX_STREAM(xname, "Playback", xfmt, xchmax),   \
+       .ops = &g12a_tohdmitx_input_ops,                                \
+-      .probe = g12a_tohdmitx_input_probe,                             \
+-      .remove = g12a_tohdmitx_input_remove,                           \
++      .probe = meson_codec_glue_input_dai_probe,                      \
++      .remove = meson_codec_glue_input_dai_remove,                    \
+ }
+ #define TOHDMITX_OUT(xname, xid, xfmt, xchmax) {                      \
+diff --git a/sound/soc/meson/meson-codec-glue.c b/sound/soc/meson/meson-codec-glue.c
+new file mode 100644
+index 0000000000000..97bbc967e1769
+--- /dev/null
++++ b/sound/soc/meson/meson-codec-glue.c
+@@ -0,0 +1,149 @@
++// SPDX-License-Identifier: GPL-2.0
++//
++// Copyright (c) 2019 BayLibre, SAS.
++// Author: Jerome Brunet <jbrunet@baylibre.com>
++
++#include <linux/module.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dai.h>
++
++#include "meson-codec-glue.h"
++
++static struct snd_soc_dapm_widget *
++meson_codec_glue_get_input(struct snd_soc_dapm_widget *w)
++{
++      struct snd_soc_dapm_path *p = NULL;
++      struct snd_soc_dapm_widget *in;
++
++      snd_soc_dapm_widget_for_each_source_path(w, p) {
++              if (!p->connect)
++                      continue;
++
++              /* Check that we still are in the same component */
++              if (snd_soc_dapm_to_component(w->dapm) !=
++                  snd_soc_dapm_to_component(p->source->dapm))
++                      continue;
++
++              if (p->source->id == snd_soc_dapm_dai_in)
++                      return p->source;
++
++              in = meson_codec_glue_get_input(p->source);
++              if (in)
++                      return in;
++      }
++
++      return NULL;
++}
++
++static void meson_codec_glue_input_set_data(struct snd_soc_dai *dai,
++                                          struct meson_codec_glue_input *data)
++{
++      dai->playback_dma_data = data;
++}
++
++struct meson_codec_glue_input *
++meson_codec_glue_input_get_data(struct snd_soc_dai *dai)
++{
++      return dai->playback_dma_data;
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_input_get_data);
++
++static struct meson_codec_glue_input *
++meson_codec_glue_output_get_input_data(struct snd_soc_dapm_widget *w)
++{
++      struct snd_soc_dapm_widget *in =
++              meson_codec_glue_get_input(w);
++      struct snd_soc_dai *dai;
++
++      if (WARN_ON(!in))
++              return NULL;
++
++      dai = in->priv;
++
++      return meson_codec_glue_input_get_data(dai);
++}
++
++int meson_codec_glue_input_hw_params(struct snd_pcm_substream *substream,
++                                   struct snd_pcm_hw_params *params,
++                                   struct snd_soc_dai *dai)
++{
++      struct meson_codec_glue_input *data =
++              meson_codec_glue_input_get_data(dai);
++
++      data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params));
++      data->params.rate_min = params_rate(params);
++      data->params.rate_max = params_rate(params);
++      data->params.formats = 1 << params_format(params);
++      data->params.channels_min = params_channels(params);
++      data->params.channels_max = params_channels(params);
++      data->params.sig_bits = dai->driver->playback.sig_bits;
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_input_hw_params);
++
++int meson_codec_glue_input_set_fmt(struct snd_soc_dai *dai,
++                                 unsigned int fmt)
++{
++      struct meson_codec_glue_input *data =
++              meson_codec_glue_input_get_data(dai);
++
++      /* Save the source stream format for the downstream link */
++      data->fmt = fmt;
++      return 0;
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_input_set_fmt);
++
++int meson_codec_glue_output_startup(struct snd_pcm_substream *substream,
++                                  struct snd_soc_dai *dai)
++{
++      struct snd_soc_pcm_runtime *rtd = substream->private_data;
++      struct meson_codec_glue_input *in_data =
++              meson_codec_glue_output_get_input_data(dai->capture_widget);
++
++      if (!in_data)
++              return -ENODEV;
++
++      if (WARN_ON(!rtd->dai_link->params)) {
++              dev_warn(dai->dev, "codec2codec link expected\n");
++              return -EINVAL;
++      }
++
++      /* Replace link params with the input params */
++      rtd->dai_link->params = &in_data->params;
++
++      if (!in_data->fmt)
++              return 0;
++
++      return snd_soc_runtime_set_dai_fmt(rtd, in_data->fmt);
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_output_startup);
++
++int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai)
++{
++      struct meson_codec_glue_input *data;
++
++      data = kzalloc(sizeof(*data), GFP_KERNEL);
++      if (!data)
++              return -ENOMEM;
++
++      meson_codec_glue_input_set_data(dai, data);
++      return 0;
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_probe);
++
++int meson_codec_glue_input_dai_remove(struct snd_soc_dai *dai)
++{
++      struct meson_codec_glue_input *data =
++              meson_codec_glue_input_get_data(dai);
++
++      kfree(data);
++      return 0;
++}
++EXPORT_SYMBOL_GPL(meson_codec_glue_input_dai_remove);
++
++MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
++MODULE_DESCRIPTION("Amlogic Codec Glue Helpers");
++MODULE_LICENSE("GPL v2");
++
+diff --git a/sound/soc/meson/meson-codec-glue.h b/sound/soc/meson/meson-codec-glue.h
+new file mode 100644
+index 0000000000000..07f99446c0c6b
+--- /dev/null
++++ b/sound/soc/meson/meson-codec-glue.h
+@@ -0,0 +1,32 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (c) 2018 Baylibre SAS.
++ * Author: Jerome Brunet <jbrunet@baylibre.com>
++ */
++
++#ifndef _MESON_CODEC_GLUE_H
++#define _MESON_CODEC_GLUE_H
++
++#include <sound/soc.h>
++
++struct meson_codec_glue_input {
++      struct snd_soc_pcm_stream params;
++      unsigned int fmt;
++};
++
++/* Input helpers */
++struct meson_codec_glue_input *
++meson_codec_glue_input_get_data(struct snd_soc_dai *dai);
++int meson_codec_glue_input_hw_params(struct snd_pcm_substream *substream,
++                                   struct snd_pcm_hw_params *params,
++                                   struct snd_soc_dai *dai);
++int meson_codec_glue_input_set_fmt(struct snd_soc_dai *dai,
++                                 unsigned int fmt);
++int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai);
++int meson_codec_glue_input_dai_remove(struct snd_soc_dai *dai);
++
++/* Output helpers */
++int meson_codec_glue_output_startup(struct snd_pcm_substream *substream,
++                                  struct snd_soc_dai *dai);
++
++#endif /* _MESON_CODEC_GLUE_H */
+-- 
+2.43.0
+
diff --git a/queue-5.4/asoc-meson-g12a-tohdmitx-fix-event-generation-for-s-.patch b/queue-5.4/asoc-meson-g12a-tohdmitx-fix-event-generation-for-s-.patch
new file mode 100644 (file)
index 0000000..07055c1
--- /dev/null
@@ -0,0 +1,39 @@
+From e9203e3757f19216c844168885d6c09acf92153d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 18:34:04 +0000
+Subject: ASoC: meson: g12a-tohdmitx: Fix event generation for S/PDIF mux
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit b036d8ef3120b996751495ce25994eea58032a98 ]
+
+When a control changes value the return value from _put() should be 1 so
+we get events generated to userspace notifying applications of the change.
+While the I2S mux gets this right the S/PDIF mux does not, fix the return
+value.
+
+Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-4-424af7a8fb91@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/g12a-tohdmitx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
+index 2f44c138e1dee..c875c350be070 100644
+--- a/sound/soc/meson/g12a-tohdmitx.c
++++ b/sound/soc/meson/g12a-tohdmitx.c
+@@ -117,7 +117,7 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol,
+       snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL);
+-      return 0;
++      return 1;
+ }
+ static SOC_ENUM_SINGLE_DECL(g12a_tohdmitx_spdif_mux_enum, TOHDMITX_CTRL0,
+-- 
+2.43.0
+
diff --git a/queue-5.4/asoc-meson-g12a-tohdmitx-validate-written-enum-value.patch b/queue-5.4/asoc-meson-g12a-tohdmitx-validate-written-enum-value.patch
new file mode 100644 (file)
index 0000000..7ef20aa
--- /dev/null
@@ -0,0 +1,50 @@
+From 76e63129f04341bd4637686b28f19775a460e601 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 18:34:02 +0000
+Subject: ASoC: meson: g12a-tohdmitx: Validate written enum values
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit 1e001206804be3f3d21f4a1cf16e5d059d75643f ]
+
+When writing to an enum we need to verify that the value written is valid
+for the enumeration, the helper function snd_soc_item_enum_to_val() doesn't
+do it since it needs to return an unsigned (and in any case we'd need to
+check the return value).
+
+Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240103-meson-enum-val-v1-2-424af7a8fb91@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/meson/g12a-tohdmitx.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
+index d02825669484a..2f44c138e1dee 100644
+--- a/sound/soc/meson/g12a-tohdmitx.c
++++ b/sound/soc/meson/g12a-tohdmitx.c
+@@ -44,6 +44,9 @@ static int g12a_tohdmitx_i2s_mux_put_enum(struct snd_kcontrol *kcontrol,
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int mux, changed;
++      if (ucontrol->value.enumerated.item[0] >= e->items)
++              return -EINVAL;
++
+       mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]);
+       changed = snd_soc_component_test_bits(component, e->reg,
+                                             CTRL0_I2S_DAT_SEL,
+@@ -92,6 +95,9 @@ static int g12a_tohdmitx_spdif_mux_put_enum(struct snd_kcontrol *kcontrol,
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       unsigned int mux, changed;
++      if (ucontrol->value.enumerated.item[0] >= e->items)
++              return -EINVAL;
++
+       mux = snd_soc_enum_item_to_val(e, ucontrol->value.enumerated.item[0]);
+       changed = snd_soc_component_test_bits(component, TOHDMITX_CTRL0,
+                                             CTRL0_SPDIF_SEL,
+-- 
+2.43.0
+
diff --git a/queue-5.4/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch b/queue-5.4/bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch
new file mode 100644 (file)
index 0000000..eee69f8
--- /dev/null
@@ -0,0 +1,47 @@
+From 261b36212f4dcc4227a3960fe3f8b0caa7a582d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 16:59:24 -0800
+Subject: bnxt_en: Remove mis-applied code from bnxt_cfg_ntp_filters()
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit e009b2efb7a8850498796b360043ac25c8d3d28f ]
+
+The 2 lines to check for the BNXT_HWRM_PF_UNLOAD_SP_EVENT bit was
+mis-applied to bnxt_cfg_ntp_filters() and should have been applied to
+bnxt_sp_task().
+
+Fixes: 19241368443f ("bnxt_en: Send PF driver unload notification to all VFs.")
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 7f85315744009..2a12a41442611 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -10340,6 +10340,8 @@ static void bnxt_sp_task(struct work_struct *work)
+               bnxt_cfg_ntp_filters(bp);
+       if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event))
+               bnxt_hwrm_exec_fwd_req(bp);
++      if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event))
++              netdev_info(bp->dev, "Receive PF driver unload event!\n");
+       if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) {
+               bnxt_hwrm_tunnel_dst_port_alloc(
+                       bp, bp->vxlan_port,
+@@ -11266,8 +11268,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
+                       }
+               }
+       }
+-      if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event))
+-              netdev_info(bp->dev, "Receive PF driver unload event!");
+ }
+ #else
+-- 
+2.43.0
+
diff --git a/queue-5.4/can-raw-add-support-for-so_mark.patch b/queue-5.4/can-raw-add-support-for-so_mark.patch
new file mode 100644 (file)
index 0000000..6aa516d
--- /dev/null
@@ -0,0 +1,36 @@
+From f5a70e0c671d9daf9c8a5dfc7a1ffb2e59cb5cbe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Dec 2022 10:10:08 +0100
+Subject: can: raw: add support for SO_MARK
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 0826e82b8a32e646b7b32ba8b68ba30812028e47 ]
+
+Add support for SO_MARK to the CAN_RAW protocol. This makes it
+possible to add traffic control filters based on the fwmark.
+
+Link: https://lore.kernel.org/all/20221210113653.170346-1-mkl@pengutronix.de
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 7f6ca95d16b9 ("net: Implement missing getsockopt(SO_TIMESTAMPING_NEW)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 2700153262771..2f500d8a0af24 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -826,6 +826,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+       skb->dev = dev;
+       skb->sk  = sk;
+       skb->priority = sk->sk_priority;
++      skb->mark = sk->sk_mark;
+       skb->tstamp = sockc.transmit_time;
+       skb_setup_tx_timestamp(skb, sockc.tsflags);
+-- 
+2.43.0
+
diff --git a/queue-5.4/can-raw-add-support-for-so_txtime-scm_txtime.patch b/queue-5.4/can-raw-add-support-for-so_txtime-scm_txtime.patch
new file mode 100644 (file)
index 0000000..d8e023e
--- /dev/null
@@ -0,0 +1,63 @@
+From 441f593b2aca37ef5de4096f16b22b2e27761fa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Apr 2022 12:31:52 +0200
+Subject: can: raw: add support for SO_TXTIME/SCM_TXTIME
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 51a0d5e51178fcd147c1b8fdab2ed16b561326db ]
+
+This patch calls into sock_cmsg_send() to parse the user supplied
+control information into a struct sockcm_cookie. Then assign the
+requested transmit time to the skb.
+
+This makes it possible to use the Earliest TXTIME First (ETF) packet
+scheduler with the CAN_RAW protocol. The user can send a CAN_RAW frame
+with a TXTIME and the kernel (with the ETF scheduler) will take care
+of sending it to the network interface.
+
+Link: https://lore.kernel.org/all/20220502091946.1916211-3-mkl@pengutronix.de
+Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 7f6ca95d16b9 ("net: Implement missing getsockopt(SO_TIMESTAMPING_NEW)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/raw.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/net/can/raw.c b/net/can/raw.c
+index bb837019d1724..2700153262771 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -770,6 +770,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ {
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
++      struct sockcm_cookie sockc;
+       struct sk_buff *skb;
+       struct net_device *dev;
+       int ifindex;
+@@ -815,11 +816,19 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+       if (err < 0)
+               goto free_skb;
+-      skb_setup_tx_timestamp(skb, sk->sk_tsflags);
++      sockcm_init(&sockc, sk);
++      if (msg->msg_controllen) {
++              err = sock_cmsg_send(sk, msg, &sockc);
++              if (unlikely(err))
++                      goto free_skb;
++      }
+       skb->dev = dev;
+       skb->sk  = sk;
+       skb->priority = sk->sk_priority;
++      skb->tstamp = sockc.transmit_time;
++
++      skb_setup_tx_timestamp(skb, sockc.tsflags);
+       err = can_send(skb, ro->loopback);
+-- 
+2.43.0
+
diff --git a/queue-5.4/i40e-fix-filter-input-checks-to-prevent-config-with-.patch b/queue-5.4/i40e-fix-filter-input-checks-to-prevent-config-with-.patch
new file mode 100644 (file)
index 0000000..ce5c79f
--- /dev/null
@@ -0,0 +1,53 @@
+From faa4d14fabcef705e8648878e038617a0ceff4c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 11:23:11 +0100
+Subject: i40e: Fix filter input checks to prevent config with invalid values
+
+From: Sudheer Mogilappagari <sudheer.mogilappagari@intel.com>
+
+[ Upstream commit 3e48041d9820c17e0a51599d12e66c6e12a8d08d ]
+
+Prevent VF from configuring filters with unsupported actions or use
+REDIRECT action with invalid tc number. Current checks could cause
+out of bounds access on PF side.
+
+Fixes: e284fc280473 ("i40e: Add and delete cloud filter")
+Reviewed-by: Andrii Staikov <andrii.staikov@intel.com>
+Signed-off-by: Sudheer Mogilappagari <sudheer.mogilappagari@intel.com>
+Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Bharathi Sreenivas <bharathi.sreenivas@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 37ce764ed3730..d53e535a447d6 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -3332,16 +3332,16 @@ static int i40e_validate_cloud_filter(struct i40e_vf *vf,
+       bool found = false;
+       int bkt;
+-      if (!tc_filter->action) {
++      if (tc_filter->action != VIRTCHNL_ACTION_TC_REDIRECT) {
+               dev_info(&pf->pdev->dev,
+-                       "VF %d: Currently ADq doesn't support Drop Action\n",
+-                       vf->vf_id);
++                       "VF %d: ADQ doesn't support this action (%d)\n",
++                       vf->vf_id, tc_filter->action);
+               goto err;
+       }
+       /* action_meta is TC number here to which the filter is applied */
+       if (!tc_filter->action_meta ||
+-          tc_filter->action_meta > I40E_MAX_VF_VSI) {
++          tc_filter->action_meta > vf->num_tc) {
+               dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n",
+                        vf->vf_id, tc_filter->action_meta);
+               goto err;
+-- 
+2.43.0
+
diff --git a/queue-5.4/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch b/queue-5.4/i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch
new file mode 100644 (file)
index 0000000..c083346
--- /dev/null
@@ -0,0 +1,120 @@
+From 2c9bb1cbe44e9d6c27f97c554cf8214d40f1f345 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 15:08:50 +0800
+Subject: i40e: fix use-after-free in i40e_aqc_add_filters()
+
+From: Ke Xiao <xiaoke@sangfor.com.cn>
+
+[ Upstream commit 6a15584e99db8918b60e507539c7446375dcf366 ]
+
+Commit 3116f59c12bd ("i40e: fix use-after-free in
+i40e_sync_filters_subtask()") avoided use-after-free issues,
+by increasing refcount during update the VSI filter list to
+the HW. However, it missed the unicast situation.
+
+When deleting an unicast FDB entry, the i40e driver will release
+the mac_filter, and i40e_service_task will concurrently request
+firmware to add the mac_filter, which will lead to the following
+use-after-free issue.
+
+Fix again for both netdev->uc and netdev->mc.
+
+BUG: KASAN: use-after-free in i40e_aqc_add_filters+0x55c/0x5b0 [i40e]
+Read of size 2 at addr ffff888eb3452d60 by task kworker/8:7/6379
+
+CPU: 8 PID: 6379 Comm: kworker/8:7 Kdump: loaded Tainted: G
+Workqueue: i40e i40e_service_task [i40e]
+Call Trace:
+ dump_stack+0x71/0xab
+ print_address_description+0x6b/0x290
+ kasan_report+0x14a/0x2b0
+ i40e_aqc_add_filters+0x55c/0x5b0 [i40e]
+ i40e_sync_vsi_filters+0x1676/0x39c0 [i40e]
+ i40e_service_task+0x1397/0x2bb0 [i40e]
+ process_one_work+0x56a/0x11f0
+ worker_thread+0x8f/0xf40
+ kthread+0x2a0/0x390
+ ret_from_fork+0x1f/0x40
+
+Allocated by task 21948:
+ kasan_kmalloc+0xa6/0xd0
+ kmem_cache_alloc_trace+0xdb/0x1c0
+ i40e_add_filter+0x11e/0x520 [i40e]
+ i40e_addr_sync+0x37/0x60 [i40e]
+ __hw_addr_sync_dev+0x1f5/0x2f0
+ i40e_set_rx_mode+0x61/0x1e0 [i40e]
+ dev_uc_add_excl+0x137/0x190
+ i40e_ndo_fdb_add+0x161/0x260 [i40e]
+ rtnl_fdb_add+0x567/0x950
+ rtnetlink_rcv_msg+0x5db/0x880
+ netlink_rcv_skb+0x254/0x380
+ netlink_unicast+0x454/0x610
+ netlink_sendmsg+0x747/0xb00
+ sock_sendmsg+0xe2/0x120
+ __sys_sendto+0x1ae/0x290
+ __x64_sys_sendto+0xdd/0x1b0
+ do_syscall_64+0xa0/0x370
+ entry_SYSCALL_64_after_hwframe+0x65/0xca
+
+Freed by task 21948:
+ __kasan_slab_free+0x137/0x190
+ kfree+0x8b/0x1b0
+ __i40e_del_filter+0x116/0x1e0 [i40e]
+ i40e_del_mac_filter+0x16c/0x300 [i40e]
+ i40e_addr_unsync+0x134/0x1b0 [i40e]
+ __hw_addr_sync_dev+0xff/0x2f0
+ i40e_set_rx_mode+0x61/0x1e0 [i40e]
+ dev_uc_del+0x77/0x90
+ rtnl_fdb_del+0x6a5/0x860
+ rtnetlink_rcv_msg+0x5db/0x880
+ netlink_rcv_skb+0x254/0x380
+ netlink_unicast+0x454/0x610
+ netlink_sendmsg+0x747/0xb00
+ sock_sendmsg+0xe2/0x120
+ __sys_sendto+0x1ae/0x290
+ __x64_sys_sendto+0xdd/0x1b0
+ do_syscall_64+0xa0/0x370
+ entry_SYSCALL_64_after_hwframe+0x65/0xca
+
+Fixes: 3116f59c12bd ("i40e: fix use-after-free in i40e_sync_filters_subtask()")
+Fixes: 41c445ff0f48 ("i40e: main driver core")
+Signed-off-by: Ke Xiao <xiaoke@sangfor.com.cn>
+Signed-off-by: Ding Hui <dinghui@sangfor.com.cn>
+Cc: Di Zhu <zhudi2@huawei.com>
+Reviewed-by: Jan Sokolowski <jan.sokolowski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 3ccc248b1a8a7..b44ba73414831 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -110,12 +110,18 @@ static struct workqueue_struct *i40e_wq;
+ static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f,
+                                 struct net_device *netdev, int delta)
+ {
++      struct netdev_hw_addr_list *ha_list;
+       struct netdev_hw_addr *ha;
+       if (!f || !netdev)
+               return;
+-      netdev_for_each_mc_addr(ha, netdev) {
++      if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr))
++              ha_list = &netdev->uc;
++      else
++              ha_list = &netdev->mc;
++
++      netdev_hw_addr_list_for_each(ha, ha_list) {
+               if (ether_addr_equal(ha->addr, f->macaddr)) {
+                       ha->refcount += delta;
+                       if (ha->refcount <= 0)
+-- 
+2.43.0
+
diff --git a/queue-5.4/i40e-restore-vf-msi-x-state-during-pci-reset.patch b/queue-5.4/i40e-restore-vf-msi-x-state-during-pci-reset.patch
new file mode 100644 (file)
index 0000000..461c981
--- /dev/null
@@ -0,0 +1,103 @@
+From 41f8897d0779f4bb7243d35fed836de51600902e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 14:27:35 +0100
+Subject: i40e: Restore VF MSI-X state during PCI reset
+
+From: Andrii Staikov <andrii.staikov@intel.com>
+
+[ Upstream commit 371e576ff3e8580d91d49026e5d5faebf5565558 ]
+
+During a PCI FLR the MSI-X Enable flag in the VF PCI MSI-X capability
+register will be cleared. This can lead to issues when a VF is
+assigned to a VM because in these cases the VF driver receives no
+indication of the PF PCI error/reset and additionally it is incapable
+of restoring the cleared flag in the hypervisor configuration space
+without fully reinitializing the driver interrupt functionality.
+
+Since the VF driver is unable to easily resolve this condition on its own,
+restore the VF MSI-X flag during the PF PCI reset handling.
+
+Fixes: 19b7960b2da1 ("i40e: implement split PCI error reset handler")
+Co-developed-by: Karen Ostrowska <karen.ostrowska@intel.com>
+Signed-off-by: Karen Ostrowska <karen.ostrowska@intel.com>
+Co-developed-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Andrii Staikov <andrii.staikov@intel.com>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_main.c   |  3 +++
+ .../ethernet/intel/i40e/i40e_virtchnl_pf.c    | 26 +++++++++++++++++++
+ .../ethernet/intel/i40e/i40e_virtchnl_pf.h    |  3 +++
+ 3 files changed, 32 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index b44ba73414831..fa938281281a4 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -15716,6 +15716,9 @@ static void i40e_pci_error_reset_done(struct pci_dev *pdev)
+       struct i40e_pf *pf = pci_get_drvdata(pdev);
+       i40e_reset_and_rebuild(pf, false, false);
++#ifdef CONFIG_PCI_IOV
++      i40e_restore_all_vfs_msi_state(pdev);
++#endif /* CONFIG_PCI_IOV */
+ }
+ /**
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index d53e535a447d6..e79b8dc5c2a5e 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -99,6 +99,32 @@ void i40e_vc_notify_reset(struct i40e_pf *pf)
+                            (u8 *)&pfe, sizeof(struct virtchnl_pf_event));
+ }
++#ifdef CONFIG_PCI_IOV
++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev)
++{
++      u16 vf_id;
++      u16 pos;
++
++      /* Continue only if this is a PF */
++      if (!pdev->is_physfn)
++              return;
++
++      if (!pci_num_vf(pdev))
++              return;
++
++      pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
++      if (pos) {
++              struct pci_dev *vf_dev = NULL;
++
++              pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
++              while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) {
++                      if (vf_dev->is_virtfn && vf_dev->physfn == pdev)
++                              pci_restore_msi_state(vf_dev);
++              }
++      }
++}
++#endif /* CONFIG_PCI_IOV */
++
+ /**
+  * i40e_vc_notify_vf_reset
+  * @vf: pointer to the VF structure
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+index 23182731a73d0..75d916714ad8a 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+@@ -141,5 +141,8 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable);
+ void i40e_vc_notify_link_state(struct i40e_pf *pf);
+ void i40e_vc_notify_reset(struct i40e_pf *pf);
++#ifdef CONFIG_PCI_IOV
++void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev);
++#endif /* CONFIG_PCI_IOV */
+ #endif /* _I40E_VIRTCHNL_PF_H_ */
+-- 
+2.43.0
+
diff --git a/queue-5.4/mm-memory-failure-check-the-mapcount-of-the-precise-.patch b/queue-5.4/mm-memory-failure-check-the-mapcount-of-the-precise-.patch
new file mode 100644 (file)
index 0000000..5ff1ed6
--- /dev/null
@@ -0,0 +1,54 @@
+From d913c79b96102a56cc4f7a330309eb8f0166791d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 13:58:36 +0000
+Subject: mm/memory-failure: check the mapcount of the precise page
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit c79c5a0a00a9457718056b588f312baadf44e471 ]
+
+A process may map only some of the pages in a folio, and might be missed
+if it maps the poisoned page but not the head page.  Or it might be
+unnecessarily hit if it maps the head page, but not the poisoned page.
+
+Link: https://lkml.kernel.org/r/20231218135837.3310403-3-willy@infradead.org
+Fixes: 7af446a841a2 ("HWPOISON, hugetlb: enable error handling path for hugepage")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memory-failure.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index 9030ab0d9d975..c6453f9ffd4d9 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -986,7 +986,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
+        * This check implies we don't kill processes if their pages
+        * are in the swap cache early. Those are always late kills.
+        */
+-      if (!page_mapped(hpage))
++      if (!page_mapped(p))
+               return true;
+       if (PageKsm(p)) {
+@@ -1030,10 +1030,10 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
+       if (kill)
+               collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED);
+-      unmap_success = try_to_unmap(hpage, ttu);
++      unmap_success = try_to_unmap(p, ttu);
+       if (!unmap_success)
+               pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n",
+-                     pfn, page_mapcount(hpage));
++                     pfn, page_mapcount(p));
+       /*
+        * try_to_unmap() might put mlocked page in lru cache, so call
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch b/queue-5.4/net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch
new file mode 100644 (file)
index 0000000..6831a42
--- /dev/null
@@ -0,0 +1,46 @@
+From 71959784908d9b9b24f945b2df35b25bc6fac9ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 14:56:38 +0100
+Subject: net: bcmgenet: Fix FCS generation for fragmented skbuffs
+
+From: Adrian Cinal <adriancinal@gmail.com>
+
+[ Upstream commit e584f2ff1e6cc9b1d99e8a6b0f3415940d1b3eb3 ]
+
+The flag DMA_TX_APPEND_CRC was only written to the first DMA descriptor
+in the TX path, where each descriptor corresponds to a single skbuff
+fragment (or the skbuff head). This led to packets with no FCS appearing
+on the wire if the kernel allocated the packet in fragments, which would
+always happen when using PACKET_MMAP/TPACKET (cf. tpacket_fill_skb() in
+net/af_packet.c).
+
+Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
+Signed-off-by: Adrian Cinal <adriancinal1@gmail.com>
+Acked-by: Doug Berger <opendmb@gmail.com>
+Acked-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/20231228135638.1339245-1-adriancinal1@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index 750acbf294640..eeadeeec17bab 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -1648,8 +1648,10 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
+               /* Note: if we ever change from DMA_TX_APPEND_CRC below we
+                * will need to restore software padding of "runt" packets
+                */
++              len_stat |= DMA_TX_APPEND_CRC;
++
+               if (!i) {
+-                      len_stat |= DMA_TX_APPEND_CRC | DMA_SOP;
++                      len_stat |= DMA_SOP;
+                       if (skb->ip_summed == CHECKSUM_PARTIAL)
+                               len_stat |= DMA_TX_DO_CSUM;
+               }
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-implement-missing-getsockopt-so_timestamping_new.patch b/queue-5.4/net-implement-missing-getsockopt-so_timestamping_new.patch
new file mode 100644 (file)
index 0000000..8caf0f8
--- /dev/null
@@ -0,0 +1,60 @@
+From 55f187e0dfd93dc016c60cef248642274ab0d255 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 00:19:01 +0100
+Subject: net: Implement missing getsockopt(SO_TIMESTAMPING_NEW)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jörn-Thorben Hinz <jthinz@mailbox.tu-berlin.de>
+
+[ Upstream commit 7f6ca95d16b96567ce4cf458a2790ff17fa620c3 ]
+
+Commit 9718475e6908 ("socket: Add SO_TIMESTAMPING_NEW") added the new
+socket option SO_TIMESTAMPING_NEW. Setting the option is handled in
+sk_setsockopt(), querying it was not handled in sk_getsockopt(), though.
+
+Following remarks on an earlier submission of this patch, keep the old
+behavior of getsockopt(SO_TIMESTAMPING_OLD) which returns the active
+flags even if they actually have been set through SO_TIMESTAMPING_NEW.
+
+The new getsockopt(SO_TIMESTAMPING_NEW) is stricter, returning flags
+only if they have been set through the same option.
+
+Fixes: 9718475e6908 ("socket: Add SO_TIMESTAMPING_NEW")
+Link: https://lore.kernel.org/lkml/20230703175048.151683-1-jthinz@mailbox.tu-berlin.de/
+Link: https://lore.kernel.org/netdev/0d7cddc9-03fa-43db-a579-14f3e822615b@app.fastmail.com/
+Signed-off-by: Jörn-Thorben Hinz <jthinz@mailbox.tu-berlin.de>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 2c3c5df139345..a3ca522434a6e 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1309,9 +1309,16 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+               break;
+       case SO_LINGER:
++      case SO_TIMESTAMPING_NEW:
+               lv              = sizeof(v.ling);
+-              v.ling.l_onoff  = sock_flag(sk, SOCK_LINGER);
+-              v.ling.l_linger = sk->sk_lingertime / HZ;
++              /* For the later-added case SO_TIMESTAMPING_NEW: Be strict about only
++               * returning the flags when they were set through the same option.
++               * Don't change the beviour for the old case SO_TIMESTAMPING_OLD.
++               */
++              if (optname == SO_TIMESTAMPING_OLD || sock_flag(sk, SOCK_TSTAMP_NEW)) {
++                      v.ling.l_onoff  = sock_flag(sk, SOCK_LINGER);
++                      v.ling.l_linger = sk->sk_lingertime / HZ;
++              }
+               break;
+       case SO_BSDCOMPAT:
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-implement-missing-so_timestamping_new-cmsg-suppo.patch b/queue-5.4/net-implement-missing-so_timestamping_new-cmsg-suppo.patch
new file mode 100644 (file)
index 0000000..d3949d3
--- /dev/null
@@ -0,0 +1,40 @@
+From 0af316372dd6fb4069a2aed54f46e4fcfed359f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 09:57:44 +0100
+Subject: net: Implement missing SO_TIMESTAMPING_NEW cmsg support
+
+From: Thomas Lange <thomas@corelatus.se>
+
+[ Upstream commit 382a32018b74f407008615e0e831d05ed28e81cd ]
+
+Commit 9718475e6908 ("socket: Add SO_TIMESTAMPING_NEW") added the new
+socket option SO_TIMESTAMPING_NEW. However, it was never implemented in
+__sock_cmsg_send thus breaking SO_TIMESTAMPING cmsg for platforms using
+SO_TIMESTAMPING_NEW.
+
+Fixes: 9718475e6908 ("socket: Add SO_TIMESTAMPING_NEW")
+Link: https://lore.kernel.org/netdev/6a7281bf-bc4a-4f75-bb88-7011908ae471@app.fastmail.com/
+Signed-off-by: Thomas Lange <thomas@corelatus.se>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://lore.kernel.org/r/20240104085744.49164-1-thomas@corelatus.se
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/sock.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/core/sock.c b/net/core/sock.c
+index a3ca522434a6e..42076a3e12c3c 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2310,6 +2310,7 @@ int __sock_cmsg_send(struct sock *sk, struct msghdr *msg, struct cmsghdr *cmsg,
+               sockc->mark = *(u32 *)CMSG_DATA(cmsg);
+               break;
+       case SO_TIMESTAMPING_OLD:
++      case SO_TIMESTAMPING_NEW:
+               if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32)))
+                       return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch b/queue-5.4/net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch
new file mode 100644 (file)
index 0000000..0b7b218
--- /dev/null
@@ -0,0 +1,44 @@
+From d0e8b2dc79f2badceaf9f4307b2c8e634a7ef3c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Dec 2023 15:02:27 +0800
+Subject: net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues
+
+From: Dinghao Liu <dinghao.liu@zju.edu.cn>
+
+[ Upstream commit 89f45c30172c80e55c887f32f1af8e184124577b ]
+
+When dma_alloc_coherent() fails, we should free qdev->lrg_buf
+to prevent potential memleak.
+
+Fixes: 1357bfcf7106 ("qla3xxx: Dynamically size the rx buffer queue based on the MTU.")
+Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
+Link: https://lore.kernel.org/r/20231227070227.10527-1-dinghao.liu@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qla3xxx.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 65cdf1bfbddb8..5d0e65a3b6a83 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -2590,6 +2590,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev)
+       if (qdev->lrg_buf_q_alloc_virt_addr == NULL) {
+               netdev_err(qdev->ndev, "lBufQ failed\n");
++              kfree(qdev->lrg_buf);
+               return -ENOMEM;
+       }
+       qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr;
+@@ -2614,6 +2615,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev)
+                                 qdev->lrg_buf_q_alloc_size,
+                                 qdev->lrg_buf_q_alloc_virt_addr,
+                                 qdev->lrg_buf_q_alloc_phy_addr);
++              kfree(qdev->lrg_buf);
+               return -ENOMEM;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-qla3xxx-switch-from-pci_-to-dma_-api.patch b/queue-5.4/net-qla3xxx-switch-from-pci_-to-dma_-api.patch
new file mode 100644 (file)
index 0000000..f7a1209
--- /dev/null
@@ -0,0 +1,564 @@
+From ea2fbddcfdf85d30cfb860c12f04955dcc3c02a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Jan 2021 09:15:42 +0100
+Subject: net/qla3xxx: switch from 'pci_' to 'dma_' API
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 41fb4c1ba7478fe34c7e094e124e4ee4513b9763 ]
+
+The wrappers in include/linux/pci-dma-compat.h should go away.
+
+The patch has been generated with the coccinelle script below and has been
+hand modified to replace GFP_ with a correct flag.
+It has been compile tested.
+
+When memory is allocated in 'ql_alloc_net_req_rsp_queues()' GFP_KERNEL can
+be used because it is only called from 'ql_alloc_mem_resources()' which
+already calls 'ql_alloc_buffer_queues()' which uses GFP_KERNEL. (see below)
+
+When memory is allocated in 'ql_alloc_buffer_queues()' GFP_KERNEL can be
+used because this flag is already used just a few line above.
+
+When memory is allocated in 'ql_alloc_small_buffers()' GFP_KERNEL can
+be used because it is only called from 'ql_alloc_mem_resources()' which
+already calls 'ql_alloc_buffer_queues()' which uses GFP_KERNEL. (see above)
+
+When memory is allocated in 'ql_alloc_mem_resources()' GFP_KERNEL can be
+used because this function already calls 'ql_alloc_buffer_queues()' which
+uses GFP_KERNEL. (see above)
+
+While at it, use 'dma_set_mask_and_coherent()' instead of 'dma_set_mask()/
+dma_set_coherent_mask()' in order to slightly simplify code.
+
+@@
+@@
+-    PCI_DMA_BIDIRECTIONAL
++    DMA_BIDIRECTIONAL
+
+@@
+@@
+-    PCI_DMA_TODEVICE
++    DMA_TO_DEVICE
+
+@@
+@@
+-    PCI_DMA_FROMDEVICE
++    DMA_FROM_DEVICE
+
+@@
+@@
+-    PCI_DMA_NONE
++    DMA_NONE
+
+@@
+expression e1, e2, e3;
+@@
+-    pci_alloc_consistent(e1, e2, e3)
++    dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
+
+@@
+expression e1, e2, e3;
+@@
+-    pci_zalloc_consistent(e1, e2, e3)
++    dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_free_consistent(e1, e2, e3, e4)
++    dma_free_coherent(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_map_single(e1, e2, e3, e4)
++    dma_map_single(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_unmap_single(e1, e2, e3, e4)
++    dma_unmap_single(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4, e5;
+@@
+-    pci_map_page(e1, e2, e3, e4, e5)
++    dma_map_page(&e1->dev, e2, e3, e4, e5)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_unmap_page(e1, e2, e3, e4)
++    dma_unmap_page(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_map_sg(e1, e2, e3, e4)
++    dma_map_sg(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_unmap_sg(e1, e2, e3, e4)
++    dma_unmap_sg(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
++    dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_dma_sync_single_for_device(e1, e2, e3, e4)
++    dma_sync_single_for_device(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
++    dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2, e3, e4;
+@@
+-    pci_dma_sync_sg_for_device(e1, e2, e3, e4)
++    dma_sync_sg_for_device(&e1->dev, e2, e3, e4)
+
+@@
+expression e1, e2;
+@@
+-    pci_dma_mapping_error(e1, e2)
++    dma_mapping_error(&e1->dev, e2)
+
+@@
+expression e1, e2;
+@@
+-    pci_set_dma_mask(e1, e2)
++    dma_set_mask(&e1->dev, e2)
+
+@@
+expression e1, e2;
+@@
+-    pci_set_consistent_dma_mask(e1, e2)
++    dma_set_coherent_mask(&e1->dev, e2)
+
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/20210117081542.560021-1-christophe.jaillet@wanadoo.fr
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 89f45c30172c ("net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qla3xxx.c | 196 ++++++++++++--------------
+ 1 file changed, 87 insertions(+), 109 deletions(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 2fa68592210d7..65cdf1bfbddb8 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -316,12 +316,11 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev,
+                        * buffer
+                        */
+                       skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE);
+-                      map = pci_map_single(qdev->pdev,
++                      map = dma_map_single(&qdev->pdev->dev,
+                                            lrg_buf_cb->skb->data,
+-                                           qdev->lrg_buffer_len -
+-                                           QL_HEADER_SPACE,
+-                                           PCI_DMA_FROMDEVICE);
+-                      err = pci_dma_mapping_error(qdev->pdev, map);
++                                           qdev->lrg_buffer_len - QL_HEADER_SPACE,
++                                           DMA_FROM_DEVICE);
++                      err = dma_mapping_error(&qdev->pdev->dev, map);
+                       if (err) {
+                               netdev_err(qdev->ndev,
+                                          "PCI mapping failed with error: %d\n",
+@@ -1803,13 +1802,12 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
+                                * first buffer
+                                */
+                               skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE);
+-                              map = pci_map_single(qdev->pdev,
++                              map = dma_map_single(&qdev->pdev->dev,
+                                                    lrg_buf_cb->skb->data,
+-                                                   qdev->lrg_buffer_len -
+-                                                   QL_HEADER_SPACE,
+-                                                   PCI_DMA_FROMDEVICE);
++                                                   qdev->lrg_buffer_len - QL_HEADER_SPACE,
++                                                   DMA_FROM_DEVICE);
+-                              err = pci_dma_mapping_error(qdev->pdev, map);
++                              err = dma_mapping_error(&qdev->pdev->dev, map);
+                               if (err) {
+                                       netdev_err(qdev->ndev,
+                                                  "PCI mapping failed with error: %d\n",
+@@ -1944,18 +1942,16 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
+               goto invalid_seg_count;
+       }
+-      pci_unmap_single(qdev->pdev,
++      dma_unmap_single(&qdev->pdev->dev,
+                        dma_unmap_addr(&tx_cb->map[0], mapaddr),
+-                       dma_unmap_len(&tx_cb->map[0], maplen),
+-                       PCI_DMA_TODEVICE);
++                       dma_unmap_len(&tx_cb->map[0], maplen), DMA_TO_DEVICE);
+       tx_cb->seg_count--;
+       if (tx_cb->seg_count) {
+               for (i = 1; i < tx_cb->seg_count; i++) {
+-                      pci_unmap_page(qdev->pdev,
+-                                     dma_unmap_addr(&tx_cb->map[i],
+-                                                    mapaddr),
++                      dma_unmap_page(&qdev->pdev->dev,
++                                     dma_unmap_addr(&tx_cb->map[i], mapaddr),
+                                      dma_unmap_len(&tx_cb->map[i], maplen),
+-                                     PCI_DMA_TODEVICE);
++                                     DMA_TO_DEVICE);
+               }
+       }
+       qdev->ndev->stats.tx_packets++;
+@@ -2022,10 +2018,9 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev,
+       qdev->ndev->stats.rx_bytes += length;
+       skb_put(skb, length);
+-      pci_unmap_single(qdev->pdev,
++      dma_unmap_single(&qdev->pdev->dev,
+                        dma_unmap_addr(lrg_buf_cb2, mapaddr),
+-                       dma_unmap_len(lrg_buf_cb2, maplen),
+-                       PCI_DMA_FROMDEVICE);
++                       dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE);
+       prefetch(skb->data);
+       skb_checksum_none_assert(skb);
+       skb->protocol = eth_type_trans(skb, qdev->ndev);
+@@ -2068,10 +2063,9 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
+       skb2 = lrg_buf_cb2->skb;
+       skb_put(skb2, length);  /* Just the second buffer length here. */
+-      pci_unmap_single(qdev->pdev,
++      dma_unmap_single(&qdev->pdev->dev,
+                        dma_unmap_addr(lrg_buf_cb2, mapaddr),
+-                       dma_unmap_len(lrg_buf_cb2, maplen),
+-                       PCI_DMA_FROMDEVICE);
++                       dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE);
+       prefetch(skb2->data);
+       skb_checksum_none_assert(skb2);
+@@ -2320,9 +2314,9 @@ static int ql_send_map(struct ql3_adapter *qdev,
+       /*
+        * Map the skb buffer first.
+        */
+-      map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE);
++      map = dma_map_single(&qdev->pdev->dev, skb->data, len, DMA_TO_DEVICE);
+-      err = pci_dma_mapping_error(qdev->pdev, map);
++      err = dma_mapping_error(&qdev->pdev->dev, map);
+       if (err) {
+               netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n",
+                          err);
+@@ -2358,11 +2352,11 @@ static int ql_send_map(struct ql3_adapter *qdev,
+                   (seg == 7 && seg_cnt > 8) ||
+                   (seg == 12 && seg_cnt > 13) ||
+                   (seg == 17 && seg_cnt > 18)) {
+-                      map = pci_map_single(qdev->pdev, oal,
++                      map = dma_map_single(&qdev->pdev->dev, oal,
+                                            sizeof(struct oal),
+-                                           PCI_DMA_TODEVICE);
++                                           DMA_TO_DEVICE);
+-                      err = pci_dma_mapping_error(qdev->pdev, map);
++                      err = dma_mapping_error(&qdev->pdev->dev, map);
+                       if (err) {
+                               netdev_err(qdev->ndev,
+                                          "PCI mapping outbound address list with error: %d\n",
+@@ -2424,24 +2418,24 @@ static int ql_send_map(struct ql3_adapter *qdev,
+                   (seg == 7 && seg_cnt > 8) ||
+                   (seg == 12 && seg_cnt > 13) ||
+                   (seg == 17 && seg_cnt > 18)) {
+-                      pci_unmap_single(qdev->pdev,
+-                              dma_unmap_addr(&tx_cb->map[seg], mapaddr),
+-                              dma_unmap_len(&tx_cb->map[seg], maplen),
+-                               PCI_DMA_TODEVICE);
++                      dma_unmap_single(&qdev->pdev->dev,
++                                       dma_unmap_addr(&tx_cb->map[seg], mapaddr),
++                                       dma_unmap_len(&tx_cb->map[seg], maplen),
++                                       DMA_TO_DEVICE);
+                       oal++;
+                       seg++;
+               }
+-              pci_unmap_page(qdev->pdev,
++              dma_unmap_page(&qdev->pdev->dev,
+                              dma_unmap_addr(&tx_cb->map[seg], mapaddr),
+                              dma_unmap_len(&tx_cb->map[seg], maplen),
+-                             PCI_DMA_TODEVICE);
++                             DMA_TO_DEVICE);
+       }
+-      pci_unmap_single(qdev->pdev,
++      dma_unmap_single(&qdev->pdev->dev,
+                        dma_unmap_addr(&tx_cb->map[0], mapaddr),
+                        dma_unmap_addr(&tx_cb->map[0], maplen),
+-                       PCI_DMA_TODEVICE);
++                       DMA_TO_DEVICE);
+       return NETDEV_TX_BUSY;
+@@ -2527,9 +2521,8 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev)
+       wmb();
+       qdev->req_q_virt_addr =
+-          pci_alloc_consistent(qdev->pdev,
+-                               (size_t) qdev->req_q_size,
+-                               &qdev->req_q_phy_addr);
++          dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size,
++                             &qdev->req_q_phy_addr, GFP_KERNEL);
+       if ((qdev->req_q_virt_addr == NULL) ||
+           LS_64BITS(qdev->req_q_phy_addr) & (qdev->req_q_size - 1)) {
+@@ -2538,16 +2531,14 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev)
+       }
+       qdev->rsp_q_virt_addr =
+-          pci_alloc_consistent(qdev->pdev,
+-                               (size_t) qdev->rsp_q_size,
+-                               &qdev->rsp_q_phy_addr);
++          dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->rsp_q_size,
++                             &qdev->rsp_q_phy_addr, GFP_KERNEL);
+       if ((qdev->rsp_q_virt_addr == NULL) ||
+           LS_64BITS(qdev->rsp_q_phy_addr) & (qdev->rsp_q_size - 1)) {
+               netdev_err(qdev->ndev, "rspQ allocation failed\n");
+-              pci_free_consistent(qdev->pdev, (size_t) qdev->req_q_size,
+-                                  qdev->req_q_virt_addr,
+-                                  qdev->req_q_phy_addr);
++              dma_free_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size,
++                                qdev->req_q_virt_addr, qdev->req_q_phy_addr);
+               return -ENOMEM;
+       }
+@@ -2563,15 +2554,13 @@ static void ql_free_net_req_rsp_queues(struct ql3_adapter *qdev)
+               return;
+       }
+-      pci_free_consistent(qdev->pdev,
+-                          qdev->req_q_size,
+-                          qdev->req_q_virt_addr, qdev->req_q_phy_addr);
++      dma_free_coherent(&qdev->pdev->dev, qdev->req_q_size,
++                        qdev->req_q_virt_addr, qdev->req_q_phy_addr);
+       qdev->req_q_virt_addr = NULL;
+-      pci_free_consistent(qdev->pdev,
+-                          qdev->rsp_q_size,
+-                          qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr);
++      dma_free_coherent(&qdev->pdev->dev, qdev->rsp_q_size,
++                        qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr);
+       qdev->rsp_q_virt_addr = NULL;
+@@ -2595,9 +2584,9 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev)
+               return -ENOMEM;
+       qdev->lrg_buf_q_alloc_virt_addr =
+-              pci_alloc_consistent(qdev->pdev,
+-                                   qdev->lrg_buf_q_alloc_size,
+-                                   &qdev->lrg_buf_q_alloc_phy_addr);
++              dma_alloc_coherent(&qdev->pdev->dev,
++                                 qdev->lrg_buf_q_alloc_size,
++                                 &qdev->lrg_buf_q_alloc_phy_addr, GFP_KERNEL);
+       if (qdev->lrg_buf_q_alloc_virt_addr == NULL) {
+               netdev_err(qdev->ndev, "lBufQ failed\n");
+@@ -2615,15 +2604,16 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev)
+               qdev->small_buf_q_alloc_size = qdev->small_buf_q_size * 2;
+       qdev->small_buf_q_alloc_virt_addr =
+-              pci_alloc_consistent(qdev->pdev,
+-                                   qdev->small_buf_q_alloc_size,
+-                                   &qdev->small_buf_q_alloc_phy_addr);
++              dma_alloc_coherent(&qdev->pdev->dev,
++                                 qdev->small_buf_q_alloc_size,
++                                 &qdev->small_buf_q_alloc_phy_addr, GFP_KERNEL);
+       if (qdev->small_buf_q_alloc_virt_addr == NULL) {
+               netdev_err(qdev->ndev, "Small Buffer Queue allocation failed\n");
+-              pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size,
+-                                  qdev->lrg_buf_q_alloc_virt_addr,
+-                                  qdev->lrg_buf_q_alloc_phy_addr);
++              dma_free_coherent(&qdev->pdev->dev,
++                                qdev->lrg_buf_q_alloc_size,
++                                qdev->lrg_buf_q_alloc_virt_addr,
++                                qdev->lrg_buf_q_alloc_phy_addr);
+               return -ENOMEM;
+       }
+@@ -2640,17 +2630,15 @@ static void ql_free_buffer_queues(struct ql3_adapter *qdev)
+               return;
+       }
+       kfree(qdev->lrg_buf);
+-      pci_free_consistent(qdev->pdev,
+-                          qdev->lrg_buf_q_alloc_size,
+-                          qdev->lrg_buf_q_alloc_virt_addr,
+-                          qdev->lrg_buf_q_alloc_phy_addr);
++      dma_free_coherent(&qdev->pdev->dev, qdev->lrg_buf_q_alloc_size,
++                        qdev->lrg_buf_q_alloc_virt_addr,
++                        qdev->lrg_buf_q_alloc_phy_addr);
+       qdev->lrg_buf_q_virt_addr = NULL;
+-      pci_free_consistent(qdev->pdev,
+-                          qdev->small_buf_q_alloc_size,
+-                          qdev->small_buf_q_alloc_virt_addr,
+-                          qdev->small_buf_q_alloc_phy_addr);
++      dma_free_coherent(&qdev->pdev->dev, qdev->small_buf_q_alloc_size,
++                        qdev->small_buf_q_alloc_virt_addr,
++                        qdev->small_buf_q_alloc_phy_addr);
+       qdev->small_buf_q_virt_addr = NULL;
+@@ -2668,9 +2656,9 @@ static int ql_alloc_small_buffers(struct ql3_adapter *qdev)
+                QL_SMALL_BUFFER_SIZE);
+       qdev->small_buf_virt_addr =
+-              pci_alloc_consistent(qdev->pdev,
+-                                   qdev->small_buf_total_size,
+-                                   &qdev->small_buf_phy_addr);
++              dma_alloc_coherent(&qdev->pdev->dev,
++                                 qdev->small_buf_total_size,
++                                 &qdev->small_buf_phy_addr, GFP_KERNEL);
+       if (qdev->small_buf_virt_addr == NULL) {
+               netdev_err(qdev->ndev, "Failed to get small buffer memory\n");
+@@ -2703,10 +2691,10 @@ static void ql_free_small_buffers(struct ql3_adapter *qdev)
+               return;
+       }
+       if (qdev->small_buf_virt_addr != NULL) {
+-              pci_free_consistent(qdev->pdev,
+-                                  qdev->small_buf_total_size,
+-                                  qdev->small_buf_virt_addr,
+-                                  qdev->small_buf_phy_addr);
++              dma_free_coherent(&qdev->pdev->dev,
++                                qdev->small_buf_total_size,
++                                qdev->small_buf_virt_addr,
++                                qdev->small_buf_phy_addr);
+               qdev->small_buf_virt_addr = NULL;
+       }
+@@ -2721,10 +2709,10 @@ static void ql_free_large_buffers(struct ql3_adapter *qdev)
+               lrg_buf_cb = &qdev->lrg_buf[i];
+               if (lrg_buf_cb->skb) {
+                       dev_kfree_skb(lrg_buf_cb->skb);
+-                      pci_unmap_single(qdev->pdev,
++                      dma_unmap_single(&qdev->pdev->dev,
+                                        dma_unmap_addr(lrg_buf_cb, mapaddr),
+                                        dma_unmap_len(lrg_buf_cb, maplen),
+-                                       PCI_DMA_FROMDEVICE);
++                                       DMA_FROM_DEVICE);
+                       memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb));
+               } else {
+                       break;
+@@ -2776,13 +2764,11 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev)
+                        * buffer
+                        */
+                       skb_reserve(skb, QL_HEADER_SPACE);
+-                      map = pci_map_single(qdev->pdev,
+-                                           skb->data,
+-                                           qdev->lrg_buffer_len -
+-                                           QL_HEADER_SPACE,
+-                                           PCI_DMA_FROMDEVICE);
++                      map = dma_map_single(&qdev->pdev->dev, skb->data,
++                                           qdev->lrg_buffer_len - QL_HEADER_SPACE,
++                                           DMA_FROM_DEVICE);
+-                      err = pci_dma_mapping_error(qdev->pdev, map);
++                      err = dma_mapping_error(&qdev->pdev->dev, map);
+                       if (err) {
+                               netdev_err(qdev->ndev,
+                                          "PCI mapping failed with error: %d\n",
+@@ -2867,8 +2853,8 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev)
+        * Network Completion Queue Producer Index Register
+        */
+       qdev->shadow_reg_virt_addr =
+-              pci_alloc_consistent(qdev->pdev,
+-                                   PAGE_SIZE, &qdev->shadow_reg_phy_addr);
++              dma_alloc_coherent(&qdev->pdev->dev, PAGE_SIZE,
++                                 &qdev->shadow_reg_phy_addr, GFP_KERNEL);
+       if (qdev->shadow_reg_virt_addr != NULL) {
+               qdev->preq_consumer_index = qdev->shadow_reg_virt_addr;
+@@ -2923,10 +2909,9 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev)
+ err_buffer_queues:
+       ql_free_net_req_rsp_queues(qdev);
+ err_req_rsp:
+-      pci_free_consistent(qdev->pdev,
+-                          PAGE_SIZE,
+-                          qdev->shadow_reg_virt_addr,
+-                          qdev->shadow_reg_phy_addr);
++      dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE,
++                        qdev->shadow_reg_virt_addr,
++                        qdev->shadow_reg_phy_addr);
+       return -ENOMEM;
+ }
+@@ -2939,10 +2924,9 @@ static void ql_free_mem_resources(struct ql3_adapter *qdev)
+       ql_free_buffer_queues(qdev);
+       ql_free_net_req_rsp_queues(qdev);
+       if (qdev->shadow_reg_virt_addr != NULL) {
+-              pci_free_consistent(qdev->pdev,
+-                                  PAGE_SIZE,
+-                                  qdev->shadow_reg_virt_addr,
+-                                  qdev->shadow_reg_phy_addr);
++              dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE,
++                                qdev->shadow_reg_virt_addr,
++                                qdev->shadow_reg_phy_addr);
+               qdev->shadow_reg_virt_addr = NULL;
+       }
+ }
+@@ -3643,18 +3627,15 @@ static void ql_reset_work(struct work_struct *work)
+                       if (tx_cb->skb) {
+                               netdev_printk(KERN_DEBUG, ndev,
+                                             "Freeing lost SKB\n");
+-                              pci_unmap_single(qdev->pdev,
+-                                       dma_unmap_addr(&tx_cb->map[0],
+-                                                      mapaddr),
+-                                       dma_unmap_len(&tx_cb->map[0], maplen),
+-                                       PCI_DMA_TODEVICE);
++                              dma_unmap_single(&qdev->pdev->dev,
++                                               dma_unmap_addr(&tx_cb->map[0], mapaddr),
++                                               dma_unmap_len(&tx_cb->map[0], maplen),
++                                               DMA_TO_DEVICE);
+                               for (j = 1; j < tx_cb->seg_count; j++) {
+-                                      pci_unmap_page(qdev->pdev,
+-                                             dma_unmap_addr(&tx_cb->map[j],
+-                                                            mapaddr),
+-                                             dma_unmap_len(&tx_cb->map[j],
+-                                                           maplen),
+-                                             PCI_DMA_TODEVICE);
++                                      dma_unmap_page(&qdev->pdev->dev,
++                                                     dma_unmap_addr(&tx_cb->map[j], mapaddr),
++                                                     dma_unmap_len(&tx_cb->map[j], maplen),
++                                                     DMA_TO_DEVICE);
+                               }
+                               dev_kfree_skb(tx_cb->skb);
+                               tx_cb->skb = NULL;
+@@ -3786,13 +3767,10 @@ static int ql3xxx_probe(struct pci_dev *pdev,
+       pci_set_master(pdev);
+-      if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
++      if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
+               pci_using_dac = 1;
+-              err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+-      } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
++      else if (!(err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))))
+               pci_using_dac = 0;
+-              err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+-      }
+       if (err) {
+               pr_err("%s no usable DMA configuration\n", pci_name(pdev));
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch b/queue-5.4/net-save-and-restore-msg_namelen-in-sock_sendmsg.patch
new file mode 100644 (file)
index 0000000..8341ab4
--- /dev/null
@@ -0,0 +1,55 @@
+From d1cbbf3db417201a8d257cb065aa556ebe802fcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 09:12:30 -0400
+Subject: net: Save and restore msg_namelen in sock_sendmsg
+
+From: Marc Dionne <marc.dionne@auristor.com>
+
+[ Upstream commit 01b2885d9415152bcb12ff1f7788f500a74ea0ed ]
+
+Commit 86a7e0b69bd5 ("net: prevent rewrite of msg_name in
+sock_sendmsg()") made sock_sendmsg save the incoming msg_name pointer
+and restore it before returning, to insulate the caller against
+msg_name being changed by the called code.  If the address length
+was also changed however, we may return with an inconsistent structure
+where the length doesn't match the address, and attempts to reuse it may
+lead to lost packets.
+
+For example, a kernel that doesn't have commit 1c5950fc6fe9 ("udp6: fix
+potential access to stale information") will replace a v4 mapped address
+with its ipv4 equivalent, and shorten namelen accordingly from 28 to 16.
+If the caller attempts to reuse the resulting msg structure, it will have
+the original ipv6 (v4 mapped) address but an incorrect v4 length.
+
+Fixes: 86a7e0b69bd5 ("net: prevent rewrite of msg_name in sock_sendmsg()")
+Signed-off-by: Marc Dionne <marc.dionne@auristor.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/socket.c b/net/socket.c
+index 38c26e20511d7..e3a50f107d64d 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -661,6 +661,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg)
+ {
+       struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name;
+       struct sockaddr_storage address;
++      int save_len = msg->msg_namelen;
+       int ret;
+       if (msg->msg_name) {
+@@ -670,6 +671,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg)
+       ret = __sock_sendmsg(sock, msg);
+       msg->msg_name = save_addr;
++      msg->msg_namelen = save_len;
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch b/queue-5.4/net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch
new file mode 100644 (file)
index 0000000..28ac646
--- /dev/null
@@ -0,0 +1,40 @@
+From b41009cf4f2057c500dedc997efbbb0c27d29d8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 10:25:31 +0800
+Subject: net: sched: em_text: fix possible memory leak in em_text_destroy()
+
+From: Hangyu Hua <hbh25y@gmail.com>
+
+[ Upstream commit 8fcb0382af6f1ef50936f1be05b8149eb2f88496 ]
+
+m->data needs to be freed when em_text_destroy is called.
+
+Fixes: d675c989ed2d ("[PKT_SCHED]: Packet classification based on textsearch (ematch)")
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/em_text.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/em_text.c b/net/sched/em_text.c
+index 6f3c1fb2fb44c..f176afb70559e 100644
+--- a/net/sched/em_text.c
++++ b/net/sched/em_text.c
+@@ -97,8 +97,10 @@ static int em_text_change(struct net *net, void *data, int len,
+ static void em_text_destroy(struct tcf_ematch *m)
+ {
+-      if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config)
++      if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) {
+               textsearch_destroy(EM_TEXT_PRIV(m)->config);
++              kfree(EM_TEXT_PRIV(m));
++      }
+ }
+ static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m)
+-- 
+2.43.0
+
diff --git a/queue-5.4/net-timestamp-extend-sof_timestamping_opt_id-to-hw-t.patch b/queue-5.4/net-timestamp-extend-sof_timestamping_opt_id-to-hw-t.patch
new file mode 100644 (file)
index 0000000..d53740e
--- /dev/null
@@ -0,0 +1,52 @@
+From f5752280b642e9f3dc6c4d30a318371cba6f4c0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 6 Mar 2023 08:07:38 -0800
+Subject: net-timestamp: extend SOF_TIMESTAMPING_OPT_ID to HW timestamps
+
+From: Vadim Fedorenko <vadfed@meta.com>
+
+[ Upstream commit 8ca5a5790b9a1ce147484d2a2c4e66d2553f3d6c ]
+
+When the feature was added it was enabled for SW timestamps only but
+with current hardware the same out-of-order timestamps can be seen.
+Let's expand the area for the feature to all types of timestamps.
+
+Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 7f6ca95d16b9 ("net: Implement missing getsockopt(SO_TIMESTAMPING_NEW)")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ip_output.c  | 2 +-
+ net/ipv6/ip6_output.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index bf7c2333bc236..0f70c2dbbe5bb 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -993,7 +993,7 @@ static int __ip_append_data(struct sock *sk,
+       mtu = cork->gso_size ? IP_MAX_MTU : cork->fragsize;
+       paged = !!cork->gso_size;
+-      if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
++      if (cork->tx_flags & SKBTX_ANY_TSTAMP &&
+           sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
+               tskey = sk->sk_tskey++;
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index d3455585e6a8c..c67d634dccd47 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1425,7 +1425,7 @@ static int __ip6_append_data(struct sock *sk,
+       mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize;
+       orig_mtu = mtu;
+-      if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP &&
++      if (cork->tx_flags & SKBTX_ANY_TSTAMP &&
+           sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)
+               tskey = sk->sk_tskey++;
+-- 
+2.43.0
+
diff --git a/queue-5.4/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch b/queue-5.4/nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch
new file mode 100644 (file)
index 0000000..e14d3d1
--- /dev/null
@@ -0,0 +1,128 @@
+From ca4a3af8c76a69f4405024d141d9857b16090aa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 23:19:43 +0530
+Subject: nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to
+ llcp_local
+
+From: Siddh Raman Pant <code@siddh.me>
+
+[ Upstream commit c95f919567d6f1914f13350af61a1b044ac85014 ]
+
+llcp_sock_sendmsg() calls nfc_llcp_send_ui_frame() which in turn calls
+nfc_alloc_send_skb(), which accesses the nfc_dev from the llcp_sock for
+getting the headroom and tailroom needed for skb allocation.
+
+Parallelly the nfc_dev can be freed, as the refcount is decreased via
+nfc_free_device(), leading to a UAF reported by Syzkaller, which can
+be summarized as follows:
+
+(1) llcp_sock_sendmsg() -> nfc_llcp_send_ui_frame()
+       -> nfc_alloc_send_skb() -> Dereference *nfc_dev
+(2) virtual_ncidev_close() -> nci_free_device() -> nfc_free_device()
+       -> put_device() -> nfc_release() -> Free *nfc_dev
+
+When a reference to llcp_local is acquired, we do not acquire the same
+for the nfc_dev. This leads to freeing even when the llcp_local is in
+use, and this is the case with the UAF described above too.
+
+Thus, when we acquire a reference to llcp_local, we should acquire a
+reference to nfc_dev, and release the references appropriately later.
+
+References for llcp_local is initialized in nfc_llcp_register_device()
+(which is called by nfc_register_device()). Thus, we should acquire a
+reference to nfc_dev there.
+
+nfc_unregister_device() calls nfc_llcp_unregister_device() which in
+turn calls nfc_llcp_local_put(). Thus, the reference to nfc_dev is
+appropriately released later.
+
+Reported-and-tested-by: syzbot+bbe84a4010eeea00982d@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bbe84a4010eeea00982d
+Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket")
+Reviewed-by: Suman Ghosh <sumang@marvell.com>
+Signed-off-by: Siddh Raman Pant <code@siddh.me>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_core.c | 39 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
+index 92f70686bee0a..da3cb0d29b972 100644
+--- a/net/nfc/llcp_core.c
++++ b/net/nfc/llcp_core.c
+@@ -147,6 +147,13 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
+ static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
+ {
++      /* Since using nfc_llcp_local may result in usage of nfc_dev, whenever
++       * we hold a reference to local, we also need to hold a reference to
++       * the device to avoid UAF.
++       */
++      if (!nfc_get_device(local->dev->idx))
++              return NULL;
++
+       kref_get(&local->ref);
+       return local;
+@@ -179,10 +186,18 @@ static void local_release(struct kref *ref)
+ int nfc_llcp_local_put(struct nfc_llcp_local *local)
+ {
++      struct nfc_dev *dev;
++      int ret;
++
+       if (local == NULL)
+               return 0;
+-      return kref_put(&local->ref, local_release);
++      dev = local->dev;
++
++      ret = kref_put(&local->ref, local_release);
++      nfc_put_device(dev);
++
++      return ret;
+ }
+ static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
+@@ -968,8 +983,17 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
+       }
+       new_sock = nfc_llcp_sock(new_sk);
+-      new_sock->dev = local->dev;
++
+       new_sock->local = nfc_llcp_local_get(local);
++      if (!new_sock->local) {
++              reason = LLCP_DM_REJ;
++              sock_put(&new_sock->sk);
++              release_sock(&sock->sk);
++              sock_put(&sock->sk);
++              goto fail;
++      }
++
++      new_sock->dev = local->dev;
+       new_sock->rw = sock->rw;
+       new_sock->miux = sock->miux;
+       new_sock->nfc_protocol = sock->nfc_protocol;
+@@ -1607,7 +1631,16 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
+       if (local == NULL)
+               return -ENOMEM;
+-      local->dev = ndev;
++      /* As we are going to initialize local's refcount, we need to get the
++       * nfc_dev to avoid UAF, otherwise there is no point in continuing.
++       * See nfc_llcp_local_get().
++       */
++      local->dev = nfc_get_device(ndev->idx);
++      if (!local->dev) {
++              kfree(local);
++              return -ENODEV;
++      }
++
+       INIT_LIST_HEAD(&local->list);
+       kref_init(&local->ref);
+       mutex_init(&local->sdp_lock);
+-- 
+2.43.0
+
index f97ece4d239595902c40ac39424915fda97c409a..3e0fdd3095340efa75ae247d72930819f0e34e65 100644 (file)
@@ -43,3 +43,24 @@ usb-fotg210-hcd-delete-an-incorrect-bounds-test.patch
 smb-client-fix-oob-in-smbcalcsize.patch
 ring-buffer-fix-wake-ups-when-buffer_percent-is-set-to-100.patch
 block-don-t-invalidate-pagecache-for-invalid-falloc-modes.patch
+nfc-llcp_core-hold-a-ref-to-llcp_local-dev-when-hold.patch
+i40e-fix-filter-input-checks-to-prevent-config-with-.patch
+net-sched-em_text-fix-possible-memory-leak-in-em_tex.patch
+net-implement-missing-getsockopt-so_timestamping_new.patch
+can-raw-add-support-for-so_txtime-scm_txtime.patch
+can-raw-add-support-for-so_mark.patch
+net-timestamp-extend-sof_timestamping_opt_id-to-hw-t.patch
+arm-sun9i-smp-fix-array-index-out-of-bounds-read-in-.patch
+net-bcmgenet-fix-fcs-generation-for-fragmented-skbuf.patch
+net-save-and-restore-msg_namelen-in-sock_sendmsg.patch
+i40e-fix-use-after-free-in-i40e_aqc_add_filters.patch
+asoc-meson-g12a-extract-codec-to-codec-utils.patch
+asoc-meson-g12a-tohdmitx-validate-written-enum-value.patch
+asoc-meson-g12a-tohdmitx-fix-event-generation-for-s-.patch
+i40e-restore-vf-msi-x-state-during-pci-reset.patch
+net-qla3xxx-switch-from-pci_-to-dma_-api.patch
+net-qla3xxx-fix-potential-memleak-in-ql_alloc_buffer.patch
+asix-add-check-for-usbnet_get_endpoints.patch
+bnxt_en-remove-mis-applied-code-from-bnxt_cfg_ntp_fi.patch
+net-implement-missing-so_timestamping_new-cmsg-suppo.patch
+mm-memory-failure-check-the-mapcount-of-the-precise-.patch