]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Mon, 9 Dec 2024 11:18:31 +0000 (06:18 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 9 Dec 2024 11:18:31 +0000 (06:18 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
35 files changed:
queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch [new file with mode: 0644]
queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch [new file with mode: 0644]
queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch [new file with mode: 0644]
queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch [new file with mode: 0644]
queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch [new file with mode: 0644]
queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch [new file with mode: 0644]
queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch [new file with mode: 0644]
queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch [new file with mode: 0644]
queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch [new file with mode: 0644]
queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch [new file with mode: 0644]
queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch [new file with mode: 0644]
queue-5.15/dt_bindings-rs485-correct-delay-values.patch [new file with mode: 0644]
queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch [new file with mode: 0644]
queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch [new file with mode: 0644]
queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch [new file with mode: 0644]
queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch [new file with mode: 0644]
queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch [new file with mode: 0644]
queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch [new file with mode: 0644]
queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch [new file with mode: 0644]
queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch [new file with mode: 0644]
queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch [new file with mode: 0644]
queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch [new file with mode: 0644]
queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch [new file with mode: 0644]
queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch [new file with mode: 0644]
queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch [new file with mode: 0644]
queue-5.15/net-smc-limit-backlog-connections.patch [new file with mode: 0644]
queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch [new file with mode: 0644]
queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch [new file with mode: 0644]
queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch [new file with mode: 0644]
queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch [new file with mode: 0644]
queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch [new file with mode: 0644]
queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch [new file with mode: 0644]

diff --git a/queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch b/queue-5.15/can-c_can-c_can_handle_bus_err-update-statistics-if-.patch
new file mode 100644 (file)
index 0000000..af4cca8
--- /dev/null
@@ -0,0 +1,96 @@
+From b326aa76d1d11c1df4365de1f1174262c5f655c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:42 +0100
+Subject: can: c_can: c_can_handle_bus_err(): update statistics if skb
+ allocation fails
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 9e66242504f49e17481d8e197730faba7d99c934 ]
+
+Ensure that the statistics are always updated, even if the skb
+allocation fails.
+
+Fixes: 4d6d26537940 ("can: c_can: fix {rx,tx}_errors statistics")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-2-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/c_can/c_can_main.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index d9595eb3e125f..875ac76bc5fdd 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -1022,49 +1022,57 @@ static int c_can_handle_bus_err(struct net_device *dev,
+       /* propagate the error condition to the CAN stack */
+       skb = alloc_can_err_skb(dev, &cf);
+-      if (unlikely(!skb))
+-              return 0;
+       /* check for 'last error code' which tells us the
+        * type of the last error to occur on the CAN bus
+        */
+-      cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++      if (likely(skb))
++              cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+       switch (lec_type) {
+       case LEC_STUFF_ERROR:
+               netdev_dbg(dev, "stuff error\n");
+-              cf->data[2] |= CAN_ERR_PROT_STUFF;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_STUFF;
+               stats->rx_errors++;
+               break;
+       case LEC_FORM_ERROR:
+               netdev_dbg(dev, "form error\n");
+-              cf->data[2] |= CAN_ERR_PROT_FORM;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_FORM;
+               stats->rx_errors++;
+               break;
+       case LEC_ACK_ERROR:
+               netdev_dbg(dev, "ack error\n");
+-              cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+               stats->tx_errors++;
+               break;
+       case LEC_BIT1_ERROR:
+               netdev_dbg(dev, "bit1 error\n");
+-              cf->data[2] |= CAN_ERR_PROT_BIT1;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT1;
+               stats->tx_errors++;
+               break;
+       case LEC_BIT0_ERROR:
+               netdev_dbg(dev, "bit0 error\n");
+-              cf->data[2] |= CAN_ERR_PROT_BIT0;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT0;
+               stats->tx_errors++;
+               break;
+       case LEC_CRC_ERROR:
+               netdev_dbg(dev, "CRC error\n");
+-              cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+               stats->rx_errors++;
+               break;
+       default:
+               break;
+       }
++      if (unlikely(!skb))
++              return 0;
++
+       netif_receive_skb(skb);
+       return 1;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch b/queue-5.15/can-do-not-increase-rx-statistics-when-generating-a-.patch
new file mode 100644 (file)
index 0000000..24b0de7
--- /dev/null
@@ -0,0 +1,640 @@
+From d70d4ed68726d5f383bb35554b3c3e1fe919c7e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Dec 2021 21:15:27 +0900
+Subject: can: do not increase rx statistics when generating a CAN rx error
+ message frame
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit 676068db69b847f06fe054fca15bf6b107bd24da ]
+
+The CAN error message frames (i.e. error skb) are an interface
+specific to socket CAN. The payload of the CAN error message frames
+does not correspond to any actual data sent on the wire. Only an error
+flag and a delimiter are transmitted when an error occurs (c.f. ISO
+11898-1 section 10.4.4.2 "Error flag").
+
+For this reason, it makes no sense to increment the rx_packets and
+rx_bytes fields of struct net_device_stats because no actual payload
+were transmitted on the wire.
+
+This patch fixes all the CAN drivers.
+
+Link: https://lore.kernel.org/all/20211207121531.42941-2-mailhol.vincent@wanadoo.fr
+CC: Marc Kleine-Budde <mkl@pengutronix.de>
+CC: Nicolas Ferre <nicolas.ferre@microchip.com>
+CC: Alexandre Belloni <alexandre.belloni@bootlin.com>
+CC: Ludovic Desroches <ludovic.desroches@microchip.com>
+CC: Chandrasekar Ramakrishnan <rcsekar@samsung.com>
+CC: Maxime Ripard <mripard@kernel.org>
+CC: Chen-Yu Tsai <wens@csie.org>
+CC: Jernej Skrabec <jernej.skrabec@gmail.com>
+CC: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
+CC: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
+CC: Michal Simek <michal.simek@xilinx.com>
+CC: Stephane Grosjean <s.grosjean@peak-system.com>
+Tested-by: Jimmy Assarsson <extja@kvaser.com> # kvaser
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Acked-by: Stefan Mätje <stefan.maetje@esd.eu> # esd_usb2
+Tested-by: Stefan Mätje <stefan.maetje@esd.eu> # esd_usb2
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/at91_can.c                        | 6 ------
+ drivers/net/can/c_can/c_can_main.c                | 5 -----
+ drivers/net/can/cc770/cc770.c                     | 3 ---
+ drivers/net/can/dev/dev.c                         | 4 ----
+ drivers/net/can/dev/rx-offload.c                  | 6 ++++--
+ drivers/net/can/ifi_canfd/ifi_canfd.c             | 5 -----
+ drivers/net/can/kvaser_pciefd.c                   | 5 -----
+ drivers/net/can/m_can/m_can.c                     | 7 -------
+ drivers/net/can/mscan/mscan.c                     | 9 +++++----
+ drivers/net/can/pch_can.c                         | 3 ---
+ drivers/net/can/peak_canfd/peak_canfd.c           | 4 ----
+ drivers/net/can/rcar/rcar_can.c                   | 6 +-----
+ drivers/net/can/rcar/rcar_canfd.c                 | 4 ----
+ drivers/net/can/sja1000/sja1000.c                 | 2 --
+ drivers/net/can/sun4i_can.c                       | 7 ++-----
+ drivers/net/can/usb/ems_usb.c                     | 2 --
+ drivers/net/can/usb/esd_usb2.c                    | 2 --
+ drivers/net/can/usb/etas_es58x/es58x_core.c       | 7 -------
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c  | 2 --
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 8 --------
+ drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 4 ----
+ drivers/net/can/usb/peak_usb/pcan_usb.c           | 2 --
+ drivers/net/can/usb/peak_usb/pcan_usb_fd.c        | 3 ---
+ drivers/net/can/usb/peak_usb/pcan_usb_pro.c       | 2 --
+ drivers/net/can/usb/ucan.c                        | 6 ++++--
+ drivers/net/can/usb/usb_8dev.c                    | 2 --
+ drivers/net/can/xilinx_can.c                      | 9 +--------
+ 27 files changed, 17 insertions(+), 108 deletions(-)
+
+diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
+index b06af90a99640..26cb3d8869789 100644
+--- a/drivers/net/can/at91_can.c
++++ b/drivers/net/can/at91_can.c
+@@ -553,8 +553,6 @@ static void at91_rx_overflow_err(struct net_device *dev)
+       cf->can_id |= CAN_ERR_CRTL;
+       cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_receive_skb(skb);
+ }
+@@ -779,8 +777,6 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+       at91_poll_err_frame(dev, cf, reg_sr);
+-      dev->stats.rx_packets++;
+-      dev->stats.rx_bytes += cf->len;
+       netif_receive_skb(skb);
+       return 1;
+@@ -1037,8 +1033,6 @@ static void at91_irq_err(struct net_device *dev)
+       at91_irq_err_state(dev, cf, new_state);
+-      dev->stats.rx_packets++;
+-      dev->stats.rx_bytes += cf->len;
+       netif_rx(skb);
+       priv->can.state = new_state;
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index 8ab43f1272bd9..d9595eb3e125f 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -919,7 +919,6 @@ static int c_can_handle_state_change(struct net_device *dev,
+       unsigned int reg_err_counter;
+       unsigned int rx_err_passive;
+       struct c_can_priv *priv = netdev_priv(dev);
+-      struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       struct can_berr_counter bec;
+@@ -995,8 +994,6 @@ static int c_can_handle_state_change(struct net_device *dev,
+               break;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_receive_skb(skb);
+       return 1;
+@@ -1068,8 +1065,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
+               break;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_receive_skb(skb);
+       return 1;
+ }
+diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
+index f8a130f594e2e..a5fd8ccedec21 100644
+--- a/drivers/net/can/cc770/cc770.c
++++ b/drivers/net/can/cc770/cc770.c
+@@ -499,7 +499,6 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
+ static int cc770_err(struct net_device *dev, u8 status)
+ {
+       struct cc770_priv *priv = netdev_priv(dev);
+-      struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       u8 lec;
+@@ -571,8 +570,6 @@ static int cc770_err(struct net_device *dev, u8 status)
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
+index 94916f2d24d41..62d3e4d1fe99e 100644
+--- a/drivers/net/can/dev/dev.c
++++ b/drivers/net/can/dev/dev.c
+@@ -136,7 +136,6 @@ EXPORT_SYMBOL_GPL(can_change_state);
+ static void can_restart(struct net_device *dev)
+ {
+       struct can_priv *priv = netdev_priv(dev);
+-      struct net_device_stats *stats = &dev->stats;
+       struct sk_buff *skb;
+       struct can_frame *cf;
+       int err;
+@@ -156,9 +155,6 @@ static void can_restart(struct net_device *dev)
+       cf->can_id |= CAN_ERR_RESTARTED;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+-
+       netif_rx_ni(skb);
+ restart:
+diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c
+index 37b0cc65237b7..7dbf46b9ca5dd 100644
+--- a/drivers/net/can/dev/rx-offload.c
++++ b/drivers/net/can/dev/rx-offload.c
+@@ -54,8 +54,10 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
+               struct can_frame *cf = (struct can_frame *)skb->data;
+               work_done++;
+-              stats->rx_packets++;
+-              stats->rx_bytes += cf->len;
++              if (!(cf->can_id & CAN_ERR_FLAG)) {
++                      stats->rx_packets++;
++                      stats->rx_bytes += cf->len;
++              }
+               netif_receive_skb(skb);
+       }
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index 5bb957a26bc69..e8318e984bf2f 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -430,8 +430,6 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+              priv->base + IFI_CANFD_INTERRUPT);
+       writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_receive_skb(skb);
+       return 1;
+@@ -456,7 +454,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
+                                        enum can_state new_state)
+ {
+       struct ifi_canfd_priv *priv = netdev_priv(ndev);
+-      struct net_device_stats *stats = &ndev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       struct can_berr_counter bec;
+@@ -522,8 +519,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
+               break;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_receive_skb(skb);
+       return 1;
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index 477bc56b12060..26bc8c7ad75b9 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -1327,9 +1327,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
+       cf->data[6] = bec.txerr;
+       cf->data[7] = bec.rxerr;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+-
+       netif_rx(skb);
+       return 0;
+ }
+@@ -1524,8 +1521,6 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
+       if (skb) {
+               cf->can_id |= CAN_ERR_BUSERROR;
+-              stats->rx_bytes += cf->len;
+-              stats->rx_packets++;
+               netif_rx(skb);
+       } else {
+               stats->rx_dropped++;
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index a87f6ce86cea3..abc3907feb739 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -653,9 +653,6 @@ static int m_can_handle_lec_err(struct net_device *dev,
+               break;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+-
+       if (cdev->is_peripheral)
+               timestamp = m_can_get_timestamp(cdev);
+@@ -712,7 +709,6 @@ static int m_can_handle_state_change(struct net_device *dev,
+                                    enum can_state new_state)
+ {
+       struct m_can_classdev *cdev = netdev_priv(dev);
+-      struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       struct can_berr_counter bec;
+@@ -777,9 +773,6 @@ static int m_can_handle_state_change(struct net_device *dev,
+               break;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+-
+       if (cdev->is_peripheral)
+               timestamp = m_can_get_timestamp(cdev);
+diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
+index fa32e418eb296..9e1cce0260da6 100644
+--- a/drivers/net/can/mscan/mscan.c
++++ b/drivers/net/can/mscan/mscan.c
+@@ -401,13 +401,14 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
+                       continue;
+               }
+-              if (canrflg & MSCAN_RXF)
++              if (canrflg & MSCAN_RXF) {
+                       mscan_get_rx_frame(dev, frame);
+-              else if (canrflg & MSCAN_ERR_IF)
++                      stats->rx_packets++;
++                      stats->rx_bytes += frame->len;
++              } else if (canrflg & MSCAN_ERR_IF) {
+                       mscan_get_err_frame(dev, frame, canrflg);
++              }
+-              stats->rx_packets++;
+-              stats->rx_bytes += frame->len;
+               work_done++;
+               netif_receive_skb(skb);
+       }
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index cd8d536c6fb20..da01ce36ed592 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -561,9 +561,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
+       priv->can.state = state;
+       netif_receive_skb(skb);
+-
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+ }
+ static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
+diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
+index d08718e98e110..d5b8bc6d29804 100644
+--- a/drivers/net/can/peak_canfd/peak_canfd.c
++++ b/drivers/net/can/peak_canfd/peak_canfd.c
+@@ -409,8 +409,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
+               return -ENOMEM;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       pucan_netif_rx(skb, msg->ts_low, msg->ts_high);
+       return 0;
+@@ -438,8 +436,6 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
+       cf->data[6] = priv->bec.txerr;
+       cf->data[7] = priv->bec.rxerr;
+-      stats->rx_bytes += cf->len;
+-      stats->rx_packets++;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 945b319de841c..68ad7da5c07e0 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -223,7 +223,6 @@ static void tx_failure_cleanup(struct net_device *ndev)
+ static void rcar_can_error(struct net_device *ndev)
+ {
+       struct rcar_can_priv *priv = netdev_priv(ndev);
+-      struct net_device_stats *stats = &ndev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       u8 eifr, txerr = 0, rxerr = 0;
+@@ -362,11 +361,8 @@ static void rcar_can_error(struct net_device *ndev)
+               }
+       }
+-      if (skb) {
+-              stats->rx_packets++;
+-              stats->rx_bytes += cf->len;
++      if (skb)
+               netif_rx(skb);
+-      }
+ }
+ static void rcar_can_tx_done(struct net_device *ndev)
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 4e230e1456647..9d5b8cda8fc54 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1033,8 +1033,6 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
+       /* Clear channel error interrupts that are handled */
+       rcar_canfd_write(priv->base, RCANFD_CERFL(ch),
+                        RCANFD_CERFL_ERR(~cerfl));
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+@@ -1176,8 +1174,6 @@ static void rcar_canfd_state_change(struct net_device *ndev,
+               rx_state = txerr <= rxerr ? state : 0;
+               can_change_state(ndev, cf, tx_state, rx_state);
+-              stats->rx_packets++;
+-              stats->rx_bytes += cf->len;
+               netif_rx(skb);
+       }
+ }
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index aae2677e24f99..1e4c797679674 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -488,8 +488,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+                       can_bus_off(dev);
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index ad8f50807aca5..ab9adfe92a94b 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -621,13 +621,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+                       can_bus_off(dev);
+       }
+-      if (likely(skb)) {
+-              stats->rx_packets++;
+-              stats->rx_bytes += cf->len;
++      if (likely(skb))
+               netif_rx(skb);
+-      } else {
++      else
+               return -ENOMEM;
+-      }
+       return 0;
+ }
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index a1b7c1a451c0c..0581e70ab903e 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -397,8 +397,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+               stats->rx_errors++;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
+index 1abdf88597de0..14104cb02fb1a 100644
+--- a/drivers/net/can/usb/esd_usb2.c
++++ b/drivers/net/can/usb/esd_usb2.c
+@@ -301,8 +301,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+               priv->bec.txerr = txerr;
+               priv->bec.rxerr = rxerr;
+-              stats->rx_packets++;
+-              stats->rx_bytes += cf->len;
+               netif_rx(skb);
+       }
+ }
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 0e6faf962ebbc..34d374d301e50 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -849,13 +849,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
+               break;
+       }
+-      /* driver/net/can/dev.c:can_restart() takes in account error
+-       * messages in the RX stats. Doing the same here for
+-       * consistency.
+-       */
+-      netdev->stats.rx_packets++;
+-      netdev->stats.rx_bytes += CAN_ERR_DLC;
+-
+       if (cf) {
+               if (cf->data[1])
+                       cf->can_id |= CAN_ERR_CRTL;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 95ed200553929..f6cb5ba61ac93 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -315,8 +315,6 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
+       cf->can_id |= CAN_ERR_CRTL;
+       cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 562105b8a6327..684c9685ba613 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -922,7 +922,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+       struct net_device *netdev = priv->netdev;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+-      struct net_device_stats *stats;
+       enum can_state new_state, old_state;
+       old_state = priv->can.state;
+@@ -974,9 +973,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
+               cf->data[7] = bec->rxerr;
+       }
+-      stats = &netdev->stats;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+@@ -1131,8 +1127,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
+               cf->data[7] = bec.rxerr;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+       priv->bec.txerr = bec.txerr;
+@@ -1166,8 +1160,6 @@ static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv,
+       }
+       stats->tx_errors++;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index ad3103391c793..43ec056646661 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -907,8 +907,6 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+               if (skb) {
+                       cf->can_id |= CAN_ERR_RESTARTED;
+-                      stats->rx_packets++;
+-                      stats->rx_bytes += cf->len;
+                       netif_rx(skb);
+               } else {
+                       netdev_err(priv->netdev,
+@@ -1131,8 +1129,6 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+               cf->data[7] = es->rxerr;
+       }
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
+index af8d3dadbbb8b..d7adc313a6eda 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
+@@ -520,8 +520,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
+                                    &hwts->hwtstamp);
+       }
+-      mc->netdev->stats.rx_packets++;
+-      mc->netdev->stats.rx_bytes += cf->len;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+index 6bd12549f1014..185f5a98d2177 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+@@ -577,9 +577,6 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
+       if (!skb)
+               return -ENOMEM;
+-      netdev->stats.rx_packets++;
+-      netdev->stats.rx_bytes += cf->len;
+-
+       peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
+                            le32_to_cpu(sm->ts_high));
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+index 858ab22708fcd..f6d19879bf404 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+@@ -660,8 +660,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
+       hwts = skb_hwtstamps(skb);
+       peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(er->ts32), &hwts->hwtstamp);
+-      netdev->stats.rx_packets++;
+-      netdev->stats.rx_bytes += can_frame->len;
+       netif_rx(skb);
+       return 0;
+diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
+index 1679cbe45ded2..d582c39fc8d0e 100644
+--- a/drivers/net/can/usb/ucan.c
++++ b/drivers/net/can/usb/ucan.c
+@@ -621,8 +621,10 @@ static void ucan_rx_can_msg(struct ucan_priv *up, struct ucan_message_in *m)
+               memcpy(cf->data, m->msg.can_msg.data, cf->len);
+       /* don't count error frames as real packets */
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
++      if (!(cf->can_id & CAN_ERR_FLAG)) {
++              stats->rx_packets++;
++              stats->rx_bytes += cf->len;
++      }
+       /* pass it to Linux */
+       netif_rx(skb);
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index a5dee2ee24656..3dbb689535d1e 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -450,8 +450,6 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
+       priv->bec.txerr = txerr;
+       priv->bec.rxerr = rxerr;
+-      stats->rx_packets++;
+-      stats->rx_bytes += cf->len;
+       netif_rx(skb);
+ }
+diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
+index a2e751f0ae0b1..cb48598e32ad8 100644
+--- a/drivers/net/can/xilinx_can.c
++++ b/drivers/net/can/xilinx_can.c
+@@ -966,13 +966,8 @@ static void xcan_update_error_state_after_rxtx(struct net_device *ndev)
+               xcan_set_error_state(ndev, new_state, skb ? cf : NULL);
+-              if (skb) {
+-                      struct net_device_stats *stats = &ndev->stats;
+-
+-                      stats->rx_packets++;
+-                      stats->rx_bytes += cf->len;
++              if (skb)
+                       netif_rx(skb);
+-              }
+       }
+ }
+@@ -1096,8 +1091,6 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
+               if (skb) {
+                       skb_cf->can_id |= cf.can_id;
+                       memcpy(skb_cf->data, cf.data, CAN_ERR_DLC);
+-                      stats->rx_packets++;
+-                      stats->rx_bytes += CAN_ERR_DLC;
+                       netif_rx(skb);
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch b/queue-5.15/can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch
new file mode 100644 (file)
index 0000000..1cfa2ba
--- /dev/null
@@ -0,0 +1,126 @@
+From 072fc358c93d4fdc6b9f4a57ac0b33f3fd10d1de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:52 +0100
+Subject: can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 72a7e2e74b3075959f05e622bae09b115957dffe ]
+
+The ems_usb_rx_err() function only incremented the receive error counter
+and never the transmit error counter, even if the ECC_DIR flag reported
+that an error had occurred during transmission.
+
+Increment the receive/transmit error counter based on the value of the
+ECC_DIR flag.
+
+Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-12-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/ems_usb.c | 58 ++++++++++++++++++++---------------
+ 1 file changed, 33 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index 0581e70ab903e..af81ccc9572bc 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -334,15 +334,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+       struct net_device_stats *stats = &dev->netdev->stats;
+       skb = alloc_can_err_skb(dev->netdev, &cf);
+-      if (skb == NULL)
+-              return;
+       if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
+               u8 state = msg->msg.can_state;
+               if (state & SJA1000_SR_BS) {
+                       dev->can.state = CAN_STATE_BUS_OFF;
+-                      cf->can_id |= CAN_ERR_BUSOFF;
++                      if (skb)
++                              cf->can_id |= CAN_ERR_BUSOFF;
+                       dev->can.can_stats.bus_off++;
+                       can_bus_off(dev->netdev);
+@@ -360,44 +359,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+               /* bus error interrupt */
+               dev->can.can_stats.bus_error++;
+-              stats->rx_errors++;
+-              cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++              if (skb) {
++                      cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+-              switch (ecc & SJA1000_ECC_MASK) {
+-              case SJA1000_ECC_BIT:
+-                      cf->data[2] |= CAN_ERR_PROT_BIT;
+-                      break;
+-              case SJA1000_ECC_FORM:
+-                      cf->data[2] |= CAN_ERR_PROT_FORM;
+-                      break;
+-              case SJA1000_ECC_STUFF:
+-                      cf->data[2] |= CAN_ERR_PROT_STUFF;
+-                      break;
+-              default:
+-                      cf->data[3] = ecc & SJA1000_ECC_SEG;
+-                      break;
++                      switch (ecc & SJA1000_ECC_MASK) {
++                      case SJA1000_ECC_BIT:
++                              cf->data[2] |= CAN_ERR_PROT_BIT;
++                              break;
++                      case SJA1000_ECC_FORM:
++                              cf->data[2] |= CAN_ERR_PROT_FORM;
++                              break;
++                      case SJA1000_ECC_STUFF:
++                              cf->data[2] |= CAN_ERR_PROT_STUFF;
++                              break;
++                      default:
++                              cf->data[3] = ecc & SJA1000_ECC_SEG;
++                              break;
++                      }
+               }
+               /* Error occurred during transmission? */
+-              if ((ecc & SJA1000_ECC_DIR) == 0)
+-                      cf->data[2] |= CAN_ERR_PROT_TX;
++              if ((ecc & SJA1000_ECC_DIR) == 0) {
++                      stats->tx_errors++;
++                      if (skb)
++                              cf->data[2] |= CAN_ERR_PROT_TX;
++              } else {
++                      stats->rx_errors++;
++              }
+-              if (dev->can.state == CAN_STATE_ERROR_WARNING ||
+-                  dev->can.state == CAN_STATE_ERROR_PASSIVE) {
++              if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING ||
++                          dev->can.state == CAN_STATE_ERROR_PASSIVE)) {
+                       cf->can_id |= CAN_ERR_CRTL;
+                       cf->data[1] = (txerr > rxerr) ?
+                           CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
+               }
+       } else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
+-              cf->can_id |= CAN_ERR_CRTL;
+-              cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
++              if (skb) {
++                      cf->can_id |= CAN_ERR_CRTL;
++                      cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
++              }
+               stats->rx_over_errors++;
+               stats->rx_errors++;
+       }
+-      netif_rx(skb);
++      if (skb)
++              netif_rx(skb);
+ }
+ /*
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch b/queue-5.15/can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch
new file mode 100644 (file)
index 0000000..61cf940
--- /dev/null
@@ -0,0 +1,118 @@
+From 50313bd214585aedf4dc1482aecbbb82568bc03c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:48 +0100
+Subject: can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors
+ statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit bb03d568bb21b4afe7935d1943bcf68ddea3ea45 ]
+
+The ifi_canfd_handle_lec_err() function was incorrectly incrementing only
+the receive error counter, even in cases of bit or acknowledgment errors
+that occur during transmission.
+
+Fix the issue by incrementing the appropriate counter based on the
+type of error.
+
+Fixes: 5bbd655a8bd0 ("can: ifi: Add more detailed error reporting")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/20241122221650.633981-8-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++++---------
+ 1 file changed, 40 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index e8318e984bf2f..6a66d63f25c1d 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -393,36 +393,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+               return 0;
+       priv->can.can_stats.bus_error++;
+-      stats->rx_errors++;
+       /* Propagate the error condition to the CAN stack. */
+       skb = alloc_can_err_skb(ndev, &cf);
+-      if (unlikely(!skb))
+-              return 0;
+       /* Read the error counter register and check for new errors. */
+-      cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++      if (likely(skb))
++              cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+-      if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
+-              cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
++      if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) {
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
+-              cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++      if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) {
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
+-              cf->data[2] |= CAN_ERR_PROT_BIT0;
++      if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) {
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT0;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
+-              cf->data[2] |= CAN_ERR_PROT_BIT1;
++      if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) {
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT1;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
+-              cf->data[2] |= CAN_ERR_PROT_STUFF;
++      if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) {
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_STUFF;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
+-              cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++      if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) {
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++      }
+-      if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
+-              cf->data[2] |= CAN_ERR_PROT_FORM;
++      if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) {
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_FORM;
++      }
+       /* Reset the error counter, ack the IRQ and re-enable the counter. */
+       writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
+@@ -430,6 +449,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
+              priv->base + IFI_CANFD_INTERRUPT);
+       writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
++      if (unlikely(!skb))
++              return 0;
++
+       netif_receive_skb(skb);
+       return 1;
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch b/queue-5.15/can-j1939-j1939_session_new-fix-skb-reference-counti.patch
new file mode 100644 (file)
index 0000000..a169ba3
--- /dev/null
@@ -0,0 +1,43 @@
+From 1fb91334f60f0c64f03e2d42e37071b9bd36cee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Nov 2024 12:48:23 +0300
+Subject: can: j1939: j1939_session_new(): fix skb reference counting
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ]
+
+Since j1939_session_skb_queue() does an extra skb_get() for each new
+skb, do the same for the initial one in j1939_session_new() to avoid
+refcount underflow.
+
+Reported-by: syzbot+d4e8dc385d9258220c31@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d4e8dc385d9258220c31
+Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Tested-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://patch.msgid.link/20241105094823.2403806-1-dmantipov@yandex.ru
+[mkl: clean up commit message]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index 5d2097e5ca3a8..a58f6f5dfcf8e 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1505,7 +1505,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv,
+       session->state = J1939_SESSION_NEW;
+       skb_queue_head_init(&session->skb_queue);
+-      skb_queue_tail(&session->skb_queue, skb);
++      skb_queue_tail(&session->skb_queue, skb_get(skb));
+       skcb = j1939_skb_to_cb(skb);
+       memcpy(&session->skcb, skcb, sizeof(session->skcb));
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch b/queue-5.15/can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch
new file mode 100644 (file)
index 0000000..187b460
--- /dev/null
@@ -0,0 +1,103 @@
+From af29adb7b8dadbbacd901513c03de843bf0df353 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:47 +0100
+Subject: can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 988d4222bf9039a875a3d48f2fe35c317831ff68 ]
+
+The m_can_handle_lec_err() function was incorrectly incrementing only the
+receive error counter, even in cases of bit or acknowledgment errors that
+occur during transmission.
+
+Fix the issue by incrementing the appropriate counter based on the
+type of error.
+
+Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-7-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index abc3907feb739..a4edd7ab37eb2 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -612,47 +612,60 @@ static int m_can_handle_lec_err(struct net_device *dev,
+       u32 timestamp = 0;
+       cdev->can.can_stats.bus_error++;
+-      stats->rx_errors++;
+       /* propagate the error condition to the CAN stack */
+       skb = alloc_can_err_skb(dev, &cf);
+-      if (unlikely(!skb))
+-              return 0;
+       /* check for 'last error code' which tells us the
+        * type of the last error to occur on the CAN bus
+        */
+-      cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
++      if (likely(skb))
++              cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+       switch (lec_type) {
+       case LEC_STUFF_ERROR:
+               netdev_dbg(dev, "stuff error\n");
+-              cf->data[2] |= CAN_ERR_PROT_STUFF;
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_STUFF;
+               break;
+       case LEC_FORM_ERROR:
+               netdev_dbg(dev, "form error\n");
+-              cf->data[2] |= CAN_ERR_PROT_FORM;
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_FORM;
+               break;
+       case LEC_ACK_ERROR:
+               netdev_dbg(dev, "ack error\n");
+-              cf->data[3] = CAN_ERR_PROT_LOC_ACK;
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+               break;
+       case LEC_BIT1_ERROR:
+               netdev_dbg(dev, "bit1 error\n");
+-              cf->data[2] |= CAN_ERR_PROT_BIT1;
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT1;
+               break;
+       case LEC_BIT0_ERROR:
+               netdev_dbg(dev, "bit0 error\n");
+-              cf->data[2] |= CAN_ERR_PROT_BIT0;
++              stats->tx_errors++;
++              if (likely(skb))
++                      cf->data[2] |= CAN_ERR_PROT_BIT0;
+               break;
+       case LEC_CRC_ERROR:
+               netdev_dbg(dev, "CRC error\n");
+-              cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
++              stats->rx_errors++;
++              if (likely(skb))
++                      cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+               break;
+       default:
+               break;
+       }
++      if (unlikely(!skb))
++              return 0;
++
+       if (cdev->is_peripheral)
+               timestamp = m_can_get_timestamp(cdev);
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch b/queue-5.15/can-peak_usb-canfd-store-64-bits-hw-timestamps.patch
new file mode 100644 (file)
index 0000000..eea777b
--- /dev/null
@@ -0,0 +1,101 @@
+From 5319ee693281fe06e32d551a282cced263cb7b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Sep 2021 11:46:03 +0200
+Subject: can: peak_usb: CANFD: store 64-bits hw timestamps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Stephane Grosjean <s.grosjean@peak-system.com>
+
+[ Upstream commit 28e0a70cede3fa6835e36302207776831cc41b8b ]
+
+This patch allows to use the whole 64-bit timestamps received from the
+CAN-FD device (expressed in µs) rather than only its low part, in the
+hwtstamp structure of the skb transferred to the network layer, when a
+CAN/CANFD frame has been received.
+
+Link: https://lore.kernel.org/all/20210930094603.23134-1-s.grosjean@peak-system.com
+Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Stable-dep-of: 9e66242504f4 ("can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/peak_usb/pcan_usb_core.c | 13 +++++++++++++
+ drivers/net/can/usb/peak_usb/pcan_usb_core.h |  1 +
+ drivers/net/can/usb/peak_usb/pcan_usb_fd.c   |  9 ++++++---
+ 3 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index e8f43ed90b722..6107fef9f4a03 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -205,6 +205,19 @@ int peak_usb_netif_rx(struct sk_buff *skb,
+       return netif_rx(skb);
+ }
++/* post received skb with native 64-bit hw timestamp */
++int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high)
++{
++      struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
++      u64 ns_ts;
++
++      ns_ts = (u64)ts_high << 32 | ts_low;
++      ns_ts *= NSEC_PER_USEC;
++      hwts->hwtstamp = ns_to_ktime(ns_ts);
++
++      return netif_rx(skb);
++}
++
+ /*
+  * callback for bulk Rx urb
+  */
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+index b00a4811bf61f..daa19f57e7422 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+@@ -143,6 +143,7 @@ void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
+ void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *tv);
+ int peak_usb_netif_rx(struct sk_buff *skb,
+                     struct peak_time_ref *time_ref, u32 ts_low);
++int peak_usb_netif_rx_64(struct sk_buff *skb, u32 ts_low, u32 ts_high);
+ void peak_usb_async_complete(struct urb *urb);
+ void peak_usb_restart_complete(struct peak_usb_device *dev);
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+index 09029a3bad1ac..6bd12549f1014 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+@@ -515,7 +515,8 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
+       netdev->stats.rx_packets++;
+       netdev->stats.rx_bytes += cfd->len;
+-      peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
++      peak_usb_netif_rx_64(skb, le32_to_cpu(rm->ts_low),
++                           le32_to_cpu(rm->ts_high));
+       return 0;
+ }
+@@ -579,7 +580,8 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
+       netdev->stats.rx_packets++;
+       netdev->stats.rx_bytes += cf->len;
+-      peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
++      peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
++                           le32_to_cpu(sm->ts_high));
+       return 0;
+ }
+@@ -629,7 +631,8 @@ static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if,
+       cf->can_id |= CAN_ERR_CRTL;
+       cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+-      peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(ov->ts_low));
++      peak_usb_netif_rx_64(skb, le32_to_cpu(ov->ts_low),
++                           le32_to_cpu(ov->ts_high));
+       netdev->stats.rx_over_errors++;
+       netdev->stats.rx_errors++;
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch b/queue-5.15/can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch
new file mode 100644 (file)
index 0000000..46960a5
--- /dev/null
@@ -0,0 +1,47 @@
+From ae52d5247de6204c18d6001dfb1fa2cfa768a2b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:43 +0100
+Subject: can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf
+ is NULL
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ]
+
+Call the function can_change_state() if the allocation of the skb
+fails, as it handles the cf parameter when it is null.
+
+Additionally, this ensures that the statistics related to state error
+counters (i. e. warning, passive, and bus-off) are updated.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-3-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index ab9adfe92a94b..aad1882a9be11 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -613,10 +613,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+               tx_state = txerr >= rxerr ? state : 0;
+               rx_state = txerr <= rxerr ? state : 0;
+-              if (likely(skb))
+-                      can_change_state(dev, cf, tx_state, rx_state);
+-              else
+-                      priv->can.state = state;
++              /* The skb allocation might fail, but can_change_state()
++               * handles cf == NULL.
++               */
++              can_change_state(dev, cf, tx_state, rx_state);
+               if (state == CAN_STATE_BUS_OFF)
+                       can_bus_off(dev);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch b/queue-5.15/can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch
new file mode 100644 (file)
index 0000000..86b8e04
--- /dev/null
@@ -0,0 +1,63 @@
+From 7251cb2179542e863d4fc4cc2b3d252a52693a33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Nov 2024 23:15:51 +0100
+Subject: can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+
+From: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+
+[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ]
+
+The sun4i_can_err() function only incremented the receive error counter
+and never the transmit error counter, even if the STA_ERR_DIR flag
+reported that an error had occurred during transmission.
+
+Increment the receive/transmit error counter based on the value of the
+STA_ERR_DIR flag.
+
+Fixes: 0738eff14d81 ("can: Allwinner A10/A20 CAN Controller support - Kernel module")
+Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
+Link: https://patch.msgid.link/20241122221650.633981-11-dario.binacchi@amarulasolutions.com
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/sun4i_can.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index aad1882a9be11..3e5aa2e0ea66e 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -563,11 +563,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+               /* bus error interrupt */
+               netdev_dbg(dev, "bus error interrupt\n");
+               priv->can.can_stats.bus_error++;
+-              stats->rx_errors++;
++              ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+               if (likely(skb)) {
+-                      ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
+-
+                       cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+                       switch (ecc & SUN4I_STA_MASK_ERR) {
+@@ -585,9 +583,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
+                                              >> 16;
+                               break;
+                       }
+-                      /* error occurred during transmission? */
+-                      if ((ecc & SUN4I_STA_ERR_DIR) == 0)
++              }
++
++              /* error occurred during transmission? */
++              if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
++                      if (likely(skb))
+                               cf->data[2] |= CAN_ERR_PROT_TX;
++                      stats->tx_errors++;
++              } else {
++                      stats->rx_errors++;
+               }
+       }
+       if (isrc & SUN4I_INT_ERR_PASSIVE) {
+-- 
+2.43.0
+
diff --git a/queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch b/queue-5.15/dccp-fix-memory-leak-in-dccp_feat_change_recv.patch
new file mode 100644 (file)
index 0000000..b700c11
--- /dev/null
@@ -0,0 +1,78 @@
+From 8e11e1f62bd5d75fd66fc3544f42f04e104e2d48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 17:39:02 +0300
+Subject: dccp: Fix memory leak in dccp_feat_change_recv
+
+From: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+
+[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ]
+
+If dccp_feat_push_confirm() fails after new value for SP feature was accepted
+without reconciliation ('entry == NULL' branch), memory allocated for that value
+with dccp_feat_clone_sp_val() is never freed.
+
+Here is the kmemleak stack for this:
+
+unreferenced object 0xffff88801d4ab488 (size 8):
+  comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s)
+  hex dump (first 8 bytes):
+    01 b4 4a 1d 80 88 ff ff                          ..J.....
+  backtrace:
+    [<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128
+    [<0000000019b38405>] kmemdup include/linux/string.h:465 [inline]
+    [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline]
+    [<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline]
+    [<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline]
+    [<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416
+    [<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125
+    [<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650
+    [<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688
+    [<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline]
+    [<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570
+    [<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111
+    [<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline]
+    [<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696
+    [<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735
+    [<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865
+    [<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882
+    [<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline]
+    [<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline]
+    [<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889
+    [<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
+    [<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1
+
+Clean up the allocated memory in case of dccp_feat_push_confirm() failure
+and bail out with an error reset code.
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: e77b8363b2ea ("dccp: Process incoming Change feature-negotiation options")
+Signed-off-by: Ivan Solodovnikov <solodovnikov.ia@phystech.edu>
+Link: https://patch.msgid.link/20241126143902.190853-1-solodovnikov.ia@phystech.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dccp/feat.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/dccp/feat.c b/net/dccp/feat.c
+index 54086bb05c42c..f7554dcdaaba9 100644
+--- a/net/dccp/feat.c
++++ b/net/dccp/feat.c
+@@ -1166,8 +1166,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt,
+                       goto not_valid_or_not_known;
+               }
+-              return dccp_feat_push_confirm(fn, feat, local, &fval);
++              if (dccp_feat_push_confirm(fn, feat, local, &fval)) {
++                      kfree(fval.sp.vec);
++                      return DCCP_RESET_CODE_TOO_BUSY;
++              }
++              return 0;
+       } else if (entry->state == FEAT_UNSTABLE) {     /* 6.6.2 */
+               return 0;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch b/queue-5.15/dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch
new file mode 100644 (file)
index 0000000..46a9cc5
--- /dev/null
@@ -0,0 +1,57 @@
+From ed4c0422993073e9c8e26b1fd0039a69316dcc8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Sep 2024 11:53:06 +0200
+Subject: dt-bindings: serial: rs485: Fix rs485-rts-delay property
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit 12b3642b6c242061d3ba84e6e3050c3141ded14c ]
+
+Code expects array only with 2 items which should be checked.
+But also item checking is not working as it should likely because of
+incorrect items description.
+
+Fixes: d50f974c4f7f ("dt-bindings: serial: Convert rs485 bindings to json-schema")
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
+Link: https://lore.kernel.org/r/820c639b9e22fe037730ed44d1b044cdb6d28b75.1726480384.git.michal.simek@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/serial/rs485.yaml     | 19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 518949737c86e..bc43670c69fa9 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -18,16 +18,15 @@ properties:
+     description: prop-encoded-array <a b>
+     $ref: /schemas/types.yaml#/definitions/uint32-array
+     items:
+-      items:
+-        - description: Delay between rts signal and beginning of data sent in
+-            milliseconds. It corresponds to the delay before sending data.
+-          default: 0
+-          maximum: 100
+-        - description: Delay between end of data sent and rts signal in milliseconds.
+-            It corresponds to the delay after sending data and actual release
+-            of the line.
+-          default: 0
+-          maximum: 100
++      - description: Delay between rts signal and beginning of data sent in
++          milliseconds. It corresponds to the delay before sending data.
++        default: 0
++        maximum: 100
++      - description: Delay between end of data sent and rts signal in milliseconds.
++          It corresponds to the delay after sending data and actual release
++          of the line.
++        default: 0
++        maximum: 100
+   rs485-rts-active-low:
+     description: drive RTS low when sending (default is high).
+-- 
+2.43.0
+
diff --git a/queue-5.15/dt_bindings-rs485-correct-delay-values.patch b/queue-5.15/dt_bindings-rs485-correct-delay-values.patch
new file mode 100644 (file)
index 0000000..e4e1f2c
--- /dev/null
@@ -0,0 +1,54 @@
+From 4c0be6994b06ee57b549e60666bdd01949cccc3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Jul 2022 18:44:40 +0200
+Subject: dt_bindings: rs485: Correct delay values
+
+From: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+
+[ Upstream commit 885dcb08c93d75b784468e65fd4f1f82d5313061 ]
+
+Currently the documentation claims that a maximum of 1000 msecs is allowed
+for RTS delays. However nothing actually checks the values read from device
+tree/ACPI and so it is possible to set much higher values.
+
+There is already a maximum of 100 ms enforced for RTS delays that are set
+via the UART TIOCSRS485 ioctl. To be consistent with that use the same
+limit for DT/ACPI values.
+
+Although this change is visible to userspace the risk of breaking anything
+when reducing the max delays from 1000 to 100 ms should be very low, since
+100 ms is already a very high maximum for delays that are usually rather in
+the usecs range.
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Lino Sanfilippo <l.sanfilippo@kunbus.com>
+Link: https://lore.kernel.org/r/20220710164442.2958979-7-LinoSanfilippo@gmx.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 12b3642b6c24 ("dt-bindings: serial: rs485: Fix rs485-rts-delay property")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/serial/rs485.yaml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 0c9fa694f85c8..518949737c86e 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -22,12 +22,12 @@ properties:
+         - description: Delay between rts signal and beginning of data sent in
+             milliseconds. It corresponds to the delay before sending data.
+           default: 0
+-          maximum: 1000
++          maximum: 100
+         - description: Delay between end of data sent and rts signal in milliseconds.
+             It corresponds to the delay after sending data and actual release
+             of the line.
+           default: 0
+-          maximum: 1000
++          maximum: 100
+   rs485-rts-active-low:
+     description: drive RTS low when sending (default is high).
+-- 
+2.43.0
+
diff --git a/queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch b/queue-5.15/ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch
new file mode 100644 (file)
index 0000000..a955b04
--- /dev/null
@@ -0,0 +1,127 @@
+From 5eb8c9aca16fc84f93478568f9531bb2c3438cf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 16:33:57 +0100
+Subject: ethtool: Fix wrong mod state in case of verbose and no_mask bitset
+
+From: Kory Maincent <kory.maincent@bootlin.com>
+
+[ Upstream commit 910c4788d6155b2202ec88273376cd7ecdc24f0a ]
+
+A bitset without mask in a _SET request means we want exactly the bits in
+the bitset to be set. This works correctly for compact format but when
+verbose format is parsed, ethnl_update_bitset32_verbose() only sets the
+bits present in the request bitset but does not clear the rest. The commit
+6699170376ab ("ethtool: fix application of verbose no_mask bitset") fixes
+this issue by clearing the whole target bitmap before we start iterating.
+The solution proposed brought an issue with the behavior of the mod
+variable. As the bitset is always cleared the old value will always
+differ to the new value.
+
+Fix it by adding a new function to compare bitmaps and a temporary variable
+which save the state of the old bitmap.
+
+Fixes: 6699170376ab ("ethtool: fix application of verbose no_mask bitset")
+Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
+Link: https://patch.msgid.link/20241202153358.1142095-1-kory.maincent@bootlin.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/bitset.c | 48 ++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 44 insertions(+), 4 deletions(-)
+
+diff --git a/net/ethtool/bitset.c b/net/ethtool/bitset.c
+index 0515d6604b3b9..f0883357d12e5 100644
+--- a/net/ethtool/bitset.c
++++ b/net/ethtool/bitset.c
+@@ -425,12 +425,32 @@ static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits,
+       return 0;
+ }
++/**
++ * ethnl_bitmap32_equal() - Compare two bitmaps
++ * @map1:  first bitmap
++ * @map2:  second bitmap
++ * @nbits: bit size to compare
++ *
++ * Return: true if first @nbits are equal, false if not
++ */
++static bool ethnl_bitmap32_equal(const u32 *map1, const u32 *map2,
++                               unsigned int nbits)
++{
++      if (memcmp(map1, map2, nbits / 32 * sizeof(u32)))
++              return false;
++      if (nbits % 32 == 0)
++              return true;
++      return !((map1[nbits / 32] ^ map2[nbits / 32]) &
++               ethnl_lower_bits(nbits % 32));
++}
++
+ static int
+ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+                             const struct nlattr *attr, struct nlattr **tb,
+                             ethnl_string_array_t names,
+                             struct netlink_ext_ack *extack, bool *mod)
+ {
++      u32 *saved_bitmap = NULL;
+       struct nlattr *bit_attr;
+       bool no_mask;
+       int rem;
+@@ -448,8 +468,20 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+       }
+       no_mask = tb[ETHTOOL_A_BITSET_NOMASK];
+-      if (no_mask)
+-              ethnl_bitmap32_clear(bitmap, 0, nbits, mod);
++      if (no_mask) {
++              unsigned int nwords = DIV_ROUND_UP(nbits, 32);
++              unsigned int nbytes = nwords * sizeof(u32);
++              bool dummy;
++
++              /* The bitmap size is only the size of the map part without
++               * its mask part.
++               */
++              saved_bitmap = kcalloc(nwords, sizeof(u32), GFP_KERNEL);
++              if (!saved_bitmap)
++                      return -ENOMEM;
++              memcpy(saved_bitmap, bitmap, nbytes);
++              ethnl_bitmap32_clear(bitmap, 0, nbits, &dummy);
++      }
+       nla_for_each_nested(bit_attr, tb[ETHTOOL_A_BITSET_BITS], rem) {
+               bool old_val, new_val;
+@@ -458,22 +490,30 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,
+               if (nla_type(bit_attr) != ETHTOOL_A_BITSET_BITS_BIT) {
+                       NL_SET_ERR_MSG_ATTR(extack, bit_attr,
+                                           "only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS");
++                      kfree(saved_bitmap);
+                       return -EINVAL;
+               }
+               ret = ethnl_parse_bit(&idx, &new_val, nbits, bit_attr, no_mask,
+                                     names, extack);
+-              if (ret < 0)
++              if (ret < 0) {
++                      kfree(saved_bitmap);
+                       return ret;
++              }
+               old_val = bitmap[idx / 32] & ((u32)1 << (idx % 32));
+               if (new_val != old_val) {
+                       if (new_val)
+                               bitmap[idx / 32] |= ((u32)1 << (idx % 32));
+                       else
+                               bitmap[idx / 32] &= ~((u32)1 << (idx % 32));
+-                      *mod = true;
++                      if (!no_mask)
++                              *mod = true;
+               }
+       }
++      if (no_mask && !ethnl_bitmap32_equal(saved_bitmap, bitmap, nbits))
++              *mod = true;
++
++      kfree(saved_bitmap);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch b/queue-5.15/geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch
new file mode 100644 (file)
index 0000000..465d08a
--- /dev/null
@@ -0,0 +1,85 @@
+From ce3650d63463ee160dd469cde19387969fe8fb4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Dec 2024 18:21:21 +0000
+Subject: geneve: do not assume mac header is set in geneve_xmit_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 8588c99c7d47448fcae39e3227d6e2bb97aad86d ]
+
+We should not assume mac header is set in output path.
+
+Use skb_eth_hdr() instead of eth_hdr() to fix the issue.
+
+sysbot reported the following :
+
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 skb_mac_header include/linux/skbuff.h:3052 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 eth_hdr include/linux/if_ether.h:24 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit_skb drivers/net/geneve.c:898 [inline]
+ WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039
+Modules linked in:
+CPU: 0 UID: 0 PID: 11635 Comm: syz.4.1423 Not tainted 6.12.0-syzkaller-10296-gaaf20f870da0 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+ RIP: 0010:skb_mac_header include/linux/skbuff.h:3052 [inline]
+ RIP: 0010:eth_hdr include/linux/if_ether.h:24 [inline]
+ RIP: 0010:geneve_xmit_skb drivers/net/geneve.c:898 [inline]
+ RIP: 0010:geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039
+Code: 21 c6 02 e9 35 d4 ff ff e8 a5 48 4c fb 90 0f 0b 90 e9 fd f5 ff ff e8 97 48 4c fb 90 0f 0b 90 e9 d8 f5 ff ff e8 89 48 4c fb 90 <0f> 0b 90 e9 41 e4 ff ff e8 7b 48 4c fb 90 0f 0b 90 e9 cd e7 ff ff
+RSP: 0018:ffffc90003b2f870 EFLAGS: 00010283
+RAX: 000000000000037a RBX: 000000000000ffff RCX: ffffc9000dc3d000
+RDX: 0000000000080000 RSI: ffffffff86428417 RDI: 0000000000000003
+RBP: ffffc90003b2f9f0 R08: 0000000000000003 R09: 000000000000ffff
+R10: 000000000000ffff R11: 0000000000000002 R12: ffff88806603c000
+R13: 0000000000000000 R14: ffff8880685b2780 R15: 0000000000000e23
+FS:  00007fdc2deed6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000001b30a1dff8 CR3: 0000000056b8c000 CR4: 00000000003526f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+  __netdev_start_xmit include/linux/netdevice.h:5002 [inline]
+  netdev_start_xmit include/linux/netdevice.h:5011 [inline]
+  __dev_direct_xmit+0x58a/0x720 net/core/dev.c:4490
+  dev_direct_xmit include/linux/netdevice.h:3181 [inline]
+  packet_xmit+0x1e4/0x360 net/packet/af_packet.c:285
+  packet_snd net/packet/af_packet.c:3146 [inline]
+  packet_sendmsg+0x2700/0x5660 net/packet/af_packet.c:3178
+  sock_sendmsg_nosec net/socket.c:711 [inline]
+  __sock_sendmsg net/socket.c:726 [inline]
+  __sys_sendto+0x488/0x4f0 net/socket.c:2197
+  __do_sys_sendto net/socket.c:2204 [inline]
+  __se_sys_sendto net/socket.c:2200 [inline]
+  __x64_sys_sendto+0xe0/0x1c0 net/socket.c:2200
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0xcd/0x250 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: a025fb5f49ad ("geneve: Allow configuration of DF behaviour")
+Reported-by: syzbot+3ec5271486d7cb2d242a@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/674f4b72.050a0220.17bd51.004a.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Link: https://patch.msgid.link/20241203182122.2725517-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/geneve.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index d7440cc4be80b..10e3d69205a4f 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -985,7 +985,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+               if (geneve->cfg.df == GENEVE_DF_SET) {
+                       df = htons(IP_DF);
+               } else if (geneve->cfg.df == GENEVE_DF_INHERIT) {
+-                      struct ethhdr *eth = eth_hdr(skb);
++                      struct ethhdr *eth = skb_eth_hdr(skb);
+                       if (ntohs(eth->h_proto) == ETH_P_IPV6) {
+                               df = htons(IP_DF);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch b/queue-5.15/gpio-grgpio-add-null-check-in-grgpio_probe.patch
new file mode 100644 (file)
index 0000000..badc946
--- /dev/null
@@ -0,0 +1,41 @@
+From 1d125a4130e74e280caf63f46d2992bd60308925 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2024 17:18:22 +0800
+Subject: gpio: grgpio: Add NULL check in grgpio_probe
+
+From: Charles Han <hanchunchao@inspur.com>
+
+[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ]
+
+devm_kasprintf() can return a NULL pointer on failure,but this
+returned value in grgpio_probe is not checked.
+Add NULL check in grgpio_probe, to handle kernel NULL
+pointer dereference error.
+
+Cc: stable@vger.kernel.org
+Fixes: 7eb6ce2f2723 ("gpio: Convert to using %pOF instead of full_name")
+Signed-off-by: Charles Han <hanchunchao@inspur.com>
+Link: https://lore.kernel.org/r/20241114091822.78199-1-hanchunchao@inspur.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index bf5ecf23cbceb..0d2441b7c6d02 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -363,6 +363,9 @@ static int grgpio_probe(struct platform_device *ofdev)
+       gc->owner = THIS_MODULE;
+       gc->to_irq = grgpio_to_irq;
+       gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
++      if (!gc->label)
++              return -ENOMEM;
++
+       gc->base = -1;
+       err = of_property_read_u32(np, "nbits", &prop);
+-- 
+2.43.0
+
diff --git a/queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch b/queue-5.15/gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
new file mode 100644 (file)
index 0000000..04d0707
--- /dev/null
@@ -0,0 +1,115 @@
+From cf43ad3f0f2d4c07e76d9a946eb572ba29cfe0fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Oct 2024 15:18:31 +0200
+Subject: gpio: grgpio: use a helper variable to store the address of
+ ofdev->dev
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ]
+
+Instead of dereferencing the platform device pointer repeatedly, just
+store its address in a helper variable.
+
+Link: https://lore.kernel.org/r/20241015131832.44678-3-brgl@bgdev.pl
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-grgpio.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
+index 21204a5dca3d4..bf5ecf23cbceb 100644
+--- a/drivers/gpio/gpio-grgpio.c
++++ b/drivers/gpio/gpio-grgpio.c
+@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = {
+ static int grgpio_probe(struct platform_device *ofdev)
+ {
+       struct device_node *np = ofdev->dev.of_node;
++      struct device *dev = &ofdev->dev;
+       void  __iomem *regs;
+       struct gpio_chip *gc;
+       struct grgpio_priv *priv;
+@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+       int size;
+       int i;
+-      priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+@@ -346,29 +347,29 @@ static int grgpio_probe(struct platform_device *ofdev)
+               return PTR_ERR(regs);
+       gc = &priv->gc;
+-      err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA,
++      err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA,
+                        regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL,
+                        BGPIOF_BIG_ENDIAN_BYTE_ORDER);
+       if (err) {
+-              dev_err(&ofdev->dev, "bgpio_init() failed\n");
++              dev_err(dev, "bgpio_init() failed\n");
+               return err;
+       }
+       priv->regs = regs;
+       priv->imask = gc->read_reg(regs + GRGPIO_IMASK);
+-      priv->dev = &ofdev->dev;
++      priv->dev = dev;
+       gc->of_node = np;
+       gc->owner = THIS_MODULE;
+       gc->to_irq = grgpio_to_irq;
+-      gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np);
++      gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
+       gc->base = -1;
+       err = of_property_read_u32(np, "nbits", &prop);
+       if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) {
+               gc->ngpio = GRGPIO_MAX_NGPIO;
+-              dev_dbg(&ofdev->dev,
+-                      "No or invalid nbits property: assume %d\n", gc->ngpio);
++              dev_dbg(dev, "No or invalid nbits property: assume %d\n",
++                      gc->ngpio);
+       } else {
+               gc->ngpio = prop;
+       }
+@@ -380,7 +381,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+       irqmap = (s32 *)of_get_property(np, "irqmap", &size);
+       if (irqmap) {
+               if (size < gc->ngpio) {
+-                      dev_err(&ofdev->dev,
++                      dev_err(dev,
+                               "irqmap shorter than ngpio (%d < %d)\n",
+                               size, gc->ngpio);
+                       return -EINVAL;
+@@ -390,7 +391,7 @@ static int grgpio_probe(struct platform_device *ofdev)
+                                                    &grgpio_irq_domain_ops,
+                                                    priv);
+               if (!priv->domain) {
+-                      dev_err(&ofdev->dev, "Could not add irq domain\n");
++                      dev_err(dev, "Could not add irq domain\n");
+                       return -EINVAL;
+               }
+@@ -420,13 +421,13 @@ static int grgpio_probe(struct platform_device *ofdev)
+       err = gpiochip_add_data(gc, priv);
+       if (err) {
+-              dev_err(&ofdev->dev, "Could not add gpiochip\n");
++              dev_err(dev, "Could not add gpiochip\n");
+               if (priv->domain)
+                       irq_domain_remove(priv->domain);
+               return err;
+       }
+-      dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
++      dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
+                priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off");
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch b/queue-5.15/igb-fix-potential-invalid-memory-access-in-igb_init_.patch
new file mode 100644 (file)
index 0000000..adeb1c3
--- /dev/null
@@ -0,0 +1,40 @@
+From fdf81ea3fd1f68ce8dedaccfbb018e05f3fa64f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Oct 2024 20:10:48 +0800
+Subject: igb: Fix potential invalid memory access in igb_init_module()
+
+From: Yuan Can <yuancan@huawei.com>
+
+[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ]
+
+The pci_register_driver() can fail and when this happened, the dca_notifier
+needs to be unregistered, otherwise the dca_notifier can be called when
+igb fails to install, resulting to invalid memory access.
+
+Fixes: bbd98fe48a43 ("igb: Fix DCA errors and do not use context index for 82576")
+Signed-off-by: Yuan Can <yuancan@huawei.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/igb/igb_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index f3a433b4c7cdb..7712df5b93147 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -667,6 +667,10 @@ static int __init igb_init_module(void)
+       dca_register_notify(&dca_notifier);
+ #endif
+       ret = pci_register_driver(&igb_driver);
++#ifdef CONFIG_IGB_DCA
++      if (ret)
++              dca_unregister_notify(&dca_notifier);
++#endif
+       return ret;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch b/queue-5.15/ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch
new file mode 100644 (file)
index 0000000..85a2aae
--- /dev/null
@@ -0,0 +1,117 @@
+From dd4d91b9fbaae7a9fc29c0e400beaed538653f47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Nov 2024 03:42:56 -0600
+Subject: ipvs: fix UB due to uninitialized stack access in
+ ip_vs_protocol_init()
+
+From: Jinghao Jia <jinghao7@illinois.edu>
+
+[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ]
+
+Under certain kernel configurations when building with Clang/LLVM, the
+compiler does not generate a return or jump as the terminator
+instruction for ip_vs_protocol_init(), triggering the following objtool
+warning during build time:
+
+  vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()
+
+At runtime, this either causes an oops when trying to load the ipvs
+module or a boot-time panic if ipvs is built-in. This same issue has
+been reported by the Intel kernel test robot previously.
+
+Digging deeper into both LLVM and the kernel code reveals this to be a
+undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer
+of 64 chars to store the registered protocol names and leaves it
+uninitialized after definition. The function calls strnlen() when
+concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE
+strnlen() performs an extra step to check whether the last byte of the
+input char buffer is a null character (commit 3009f891bb9f ("fortify:
+Allow strlen() and strnlen() to pass compile-time known lengths")).
+This, together with possibly other configurations, cause the following
+IR to be generated:
+
+  define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {
+    %1 = alloca [64 x i8], align 16
+    ...
+
+  14:                                               ; preds = %11
+    %15 = getelementptr inbounds i8, ptr %1, i64 63
+    %16 = load i8, ptr %15, align 1
+    %17 = tail call i1 @llvm.is.constant.i8(i8 %16)
+    %18 = icmp eq i8 %16, 0
+    %19 = select i1 %17, i1 %18, i1 false
+    br i1 %19, label %20, label %23
+
+  20:                                               ; preds = %14
+    %21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23
+    ...
+
+  23:                                               ; preds = %14, %11, %20
+    %24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24
+    ...
+  }
+
+The above code calculates the address of the last char in the buffer
+(value %15) and then loads from it (value %16). Because the buffer is
+never initialized, the LLVM GVN pass marks value %16 as undefined:
+
+  %13 = getelementptr inbounds i8, ptr %1, i64 63
+  br i1 undef, label %14, label %17
+
+This gives later passes (SCCP, in particular) more DCE opportunities by
+propagating the undef value further, and eventually removes everything
+after the load on the uninitialized stack location:
+
+  define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {
+    %1 = alloca [64 x i8], align 16
+    ...
+
+  12:                                               ; preds = %11
+    %13 = getelementptr inbounds i8, ptr %1, i64 63
+    unreachable
+  }
+
+In this way, the generated native code will just fall through to the
+next function, as LLVM does not generate any code for the unreachable IR
+instruction and leaves the function without a terminator.
+
+Zero the on-stack buffer to avoid this possible UB.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202402100205.PWXIz1ZK-lkp@intel.com/
+Co-developed-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Ruowen Qin <ruqin@redhat.com>
+Signed-off-by: Jinghao Jia <jinghao7@illinois.edu>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_proto.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
+index f100da4ba3bc3..a9fd1d3fc2cbf 100644
+--- a/net/netfilter/ipvs/ip_vs_proto.c
++++ b/net/netfilter/ipvs/ip_vs_proto.c
+@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs)
+ int __init ip_vs_protocol_init(void)
+ {
+-      char protocols[64];
++      char protocols[64] = { 0 };
+ #define REGISTER_PROTOCOL(p)                  \
+       do {                                    \
+               register_ip_vs_protocol(p);     \
+@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void)
+               strcat(protocols, (p)->name);   \
+       } while (0)
+-      protocols[0] = '\0';
+-      protocols[2] = '\0';
+ #ifdef CONFIG_IP_VS_PROTO_TCP
+       REGISTER_PROTOCOL(&ip_vs_protocol_tcp);
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch b/queue-5.15/itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch
new file mode 100644 (file)
index 0000000..f6cdaa7
--- /dev/null
@@ -0,0 +1,85 @@
+From 635b605b4d7740b1e7d322b7959f9acbbae3ab0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Sep 2024 12:14:03 -0700
+Subject: iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+
+From: Oleksandr Ocheretnyi <oocheret@cisco.com>
+
+[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ]
+
+Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake
+PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's
+value comparison for update_no_reboot_bit() call causing following
+failure:
+
+   ...
+   iTCO_vendor_support: vendor-support=0
+   iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device
+                                    disabled by hardware/BIOS
+   ...
+
+and this can lead to unexpected NMIs later during regular
+crashkernel's workflow because of watchdog probe call failures.
+
+This change masks NMI_NOW bit for TCO1_CNT register values to
+avoid unexpected NMI_NOW bit inversions.
+
+Fixes: da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO")
+Signed-off-by: Oleksandr Ocheretnyi <oocheret@cisco.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Link: https://lore.kernel.org/r/20240913191403.2560805-1-oocheret@cisco.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index a8052a3faaabb..3cebb83b3e679 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -82,6 +82,13 @@
+ #define TCO2_CNT(p)   (TCOBASE(p) + 0x0a) /* TCO2 Control Register    */
+ #define TCOv2_TMR(p)  (TCOBASE(p) + 0x12) /* TCOv2 Timer Initial Value*/
++/*
++ * NMI_NOW is bit 8 of TCO1_CNT register
++ * Read/Write
++ * This bit is implemented as RW but has no effect on HW.
++ */
++#define NMI_NOW               BIT(8)
++
+ /* internal variables */
+ struct iTCO_wdt_private {
+       struct watchdog_device wddev;
+@@ -220,13 +227,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)
+       struct iTCO_wdt_private *p = priv;
+       u16 val, newval;
+-      val = inw(TCO1_CNT(p));
++      /*
++       * writing back 1b1 to NMI_NOW of TCO1_CNT register
++       * causes NMI_NOW bit inversion what consequently does
++       * not allow to perform the register's value comparison
++       * properly.
++       *
++       * NMI_NOW bit masking for TCO1_CNT register values
++       * helps to avoid possible NMI_NOW bit inversions on
++       * following write operation.
++       */
++      val = inw(TCO1_CNT(p)) & ~NMI_NOW;
+       if (set)
+               val |= BIT(0);
+       else
+               val &= ~BIT(0);
+       outw(val, TCO1_CNT(p));
+-      newval = inw(TCO1_CNT(p));
++      newval = inw(TCO1_CNT(p)) & ~NMI_NOW;
+       /* make sure the update is successful */
+       return val != newval ? -EIO : 0;
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch b/queue-5.15/net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch
new file mode 100644 (file)
index 0000000..5b45329
--- /dev/null
@@ -0,0 +1,95 @@
+From 016f2084acb741b7d5cbb424641da63d80b16f0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Nov 2024 14:43:44 +0000
+Subject: net: hsr: avoid potential out-of-bound access in fill_frame_info()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b9653d19e556c6afd035602927a93d100a0d7644 ]
+
+syzbot is able to feed a packet with 14 bytes, pretending
+it is a vlan one.
+
+Since fill_frame_info() is relying on skb->mac_len already,
+extend the check to cover this case.
+
+BUG: KMSAN: uninit-value in fill_frame_info net/hsr/hsr_forward.c:709 [inline]
+ BUG: KMSAN: uninit-value in hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724
+  fill_frame_info net/hsr/hsr_forward.c:709 [inline]
+  hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724
+  hsr_dev_xmit+0x2f0/0x350 net/hsr/hsr_device.c:235
+  __netdev_start_xmit include/linux/netdevice.h:5002 [inline]
+  netdev_start_xmit include/linux/netdevice.h:5011 [inline]
+  xmit_one net/core/dev.c:3590 [inline]
+  dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3606
+  __dev_queue_xmit+0x366a/0x57d0 net/core/dev.c:4434
+  dev_queue_xmit include/linux/netdevice.h:3168 [inline]
+  packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276
+  packet_snd net/packet/af_packet.c:3146 [inline]
+  packet_sendmsg+0x91ae/0xa6f0 net/packet/af_packet.c:3178
+  sock_sendmsg_nosec net/socket.c:711 [inline]
+  __sock_sendmsg+0x30f/0x380 net/socket.c:726
+  __sys_sendto+0x594/0x750 net/socket.c:2197
+  __do_sys_sendto net/socket.c:2204 [inline]
+  __se_sys_sendto net/socket.c:2200 [inline]
+  __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200
+  x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Uninit was created at:
+  slab_post_alloc_hook mm/slub.c:4091 [inline]
+  slab_alloc_node mm/slub.c:4134 [inline]
+  kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4186
+  kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:587
+  __alloc_skb+0x363/0x7b0 net/core/skbuff.c:678
+  alloc_skb include/linux/skbuff.h:1323 [inline]
+  alloc_skb_with_frags+0xc8/0xd00 net/core/skbuff.c:6612
+  sock_alloc_send_pskb+0xa81/0xbf0 net/core/sock.c:2881
+  packet_alloc_skb net/packet/af_packet.c:2995 [inline]
+  packet_snd net/packet/af_packet.c:3089 [inline]
+  packet_sendmsg+0x74c6/0xa6f0 net/packet/af_packet.c:3178
+  sock_sendmsg_nosec net/socket.c:711 [inline]
+  __sock_sendmsg+0x30f/0x380 net/socket.c:726
+  __sys_sendto+0x594/0x750 net/socket.c:2197
+  __do_sys_sendto net/socket.c:2204 [inline]
+  __se_sys_sendto net/socket.c:2200 [inline]
+  __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200
+  x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: 48b491a5cc74 ("net: hsr: fix mac_len checks")
+Reported-by: syzbot+671e2853f9851d039551@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/6745dc7f.050a0220.21d33d.0018.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: WingMan Kwok <w-kwok2@ti.com>
+Cc: Murali Karicheri <m-karicheri2@ti.com>
+Cc: MD Danish Anwar <danishanwar@ti.com>
+Cc: Jiri Pirko <jiri@nvidia.com>
+Cc: George McCollister <george.mccollister@gmail.com>
+Link: https://patch.msgid.link/20241126144344.4177332-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/hsr/hsr_forward.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index e31747d328e70..20d4c3f8d8750 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -546,6 +546,8 @@ static int fill_frame_info(struct hsr_frame_info *frame,
+               frame->is_vlan = true;
+       if (frame->is_vlan) {
++              if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr))
++                      return -EINVAL;
+               vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr;
+               proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;
+               /* FIXME: */
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch b/queue-5.15/net-ipv6-release-expired-exception-dst-cached-in-soc.patch
new file mode 100644 (file)
index 0000000..1cb9278
--- /dev/null
@@ -0,0 +1,85 @@
+From 4cb9e76a35556cb99d4956f365ada92126e78ef4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:59:50 +0100
+Subject: net/ipv6: release expired exception dst cached in socket
+
+From: Jiri Wiesner <jwiesner@suse.de>
+
+[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ]
+
+Dst objects get leaked in ip6_negative_advice() when this function is
+executed for an expired IPv6 route located in the exception table. There
+are several conditions that must be fulfilled for the leak to occur:
+* an ICMPv6 packet indicating a change of the MTU for the path is received,
+  resulting in an exception dst being created
+* a TCP connection that uses the exception dst for routing packets must
+  start timing out so that TCP begins retransmissions
+* after the exception dst expires, the FIB6 garbage collector must not run
+  before TCP executes ip6_negative_advice() for the expired exception dst
+
+When TCP executes ip6_negative_advice() for an exception dst that has
+expired and if no other socket holds a reference to the exception dst, the
+refcount of the exception dst is 2, which corresponds to the increment
+made by dst_init() and the increment made by the TCP socket for which the
+connection is timing out. The refcount made by the socket is never
+released. The refcount of the dst is decremented in sk_dst_reset() but
+that decrement is counteracted by a dst_hold() intentionally placed just
+before the sk_dst_reset() in ip6_negative_advice(). After
+ip6_negative_advice() has finished, there is no other object tied to the
+dst. The socket lost its reference stored in sk_dst_cache and the dst is
+no longer in the exception table. The exception dst becomes a leaked
+object.
+
+As a result of this dst leak, an unbalanced refcount is reported for the
+loopback device of a net namespace being destroyed under kernels that do
+not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):
+unregister_netdevice: waiting for lo to become free. Usage count = 2
+
+Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The
+patch that introduced the dst_hold() in ip6_negative_advice() was
+92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22
+merely refactored the code with regards to the dst refcount so the issue
+was present even before 92f1655aa2b22. The bug was introduced in
+54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually
+expired.") where the expired cached route is deleted and the sk_dst_cache
+member of the socket is set to NULL by calling dst_negative_advice() but
+the refcount belonging to the socket is left unbalanced.
+
+The IPv4 version - ipv4_negative_advice() - is not affected by this bug.
+When the TCP connection times out ipv4_negative_advice() merely resets the
+sk_dst_cache of the socket while decrementing the refcount of the
+exception dst.
+
+Fixes: 92f1655aa2b22 ("net: fix __dst_negative_advice() race")
+Fixes: 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.")
+Link: https://lore.kernel.org/netdev/20241113105611.GA6723@incl/T/#u
+Signed-off-by: Jiri Wiesner <jwiesner@suse.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241128085950.GA4505@incl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 35d3f02ddf163..407dba4327f53 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2769,10 +2769,10 @@ static void ip6_negative_advice(struct sock *sk,
+       if (rt->rt6i_flags & RTF_CACHE) {
+               rcu_read_lock();
+               if (rt6_check_expired(rt)) {
+-                      /* counteract the dst_release() in sk_dst_reset() */
+-                      dst_hold(dst);
++                      /* rt/dst can not be destroyed yet,
++                       * because of rcu_read_lock()
++                       */
+                       sk_dst_reset(sk);
+-
+                       rt6_remove_exception_rt(rt);
+               }
+               rcu_read_unlock();
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch b/queue-5.15/net-qed-allow-old-cards-not-supporting-num_images-to.patch
new file mode 100644 (file)
index 0000000..9ee0fe8
--- /dev/null
@@ -0,0 +1,48 @@
+From 3426d4f2de2d47fdd8264b8b539339e1419fe429 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Nov 2024 09:33:58 +0100
+Subject: net/qed: allow old cards not supporting "num_images" to work
+
+From: Louis Leseur <louis.leseur@gmail.com>
+
+[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ]
+
+Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+added support for populating flash image attributes, notably
+"num_images". However, some cards were not able to return this
+information. In such cases, the driver would return EINVAL, causing the
+driver to exit.
+
+Add check to return EOPNOTSUPP instead of EINVAL when the card is not
+able to return these information. The caller function already handles
+EOPNOTSUPP without error.
+
+Fixes: 43645ce03e00 ("qed: Populate nvm image attribute shadow.")
+Co-developed-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Florian Forestier <florian@forestier.re>
+Signed-off-by: Louis Leseur <louis.leseur@gmail.com>
+Link: https://patch.msgid.link/20241128083633.26431-1-louis.leseur@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+index b734c120d508f..1f3834c6c5878 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+@@ -3253,7 +3253,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,
+       if (rc)
+               return rc;
+-      if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
++      if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED))
++              rc = -EOPNOTSUPP;
++      else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
+               rc = -EINVAL;
+       return rc;
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch b/queue-5.15/net-sched-fix-erspan_opt-settings-in-cls_flower.patch
new file mode 100644 (file)
index 0000000..992f356
--- /dev/null
@@ -0,0 +1,68 @@
+From a63291b5c03d302a554289bcbb74712f71de85fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 10:21:38 -0500
+Subject: net: sched: fix erspan_opt settings in cls_flower
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ Upstream commit 292207809486d99c78068d3f459cbbbffde88415 ]
+
+When matching erspan_opt in cls_flower, only the (version, dir, hwid)
+fields are relevant. However, in fl_set_erspan_opt() it initializes
+all bits of erspan_opt and its mask to 1. This inadvertently requires
+packets to match not only the (version, dir, hwid) fields but also the
+other fields that are unexpectedly set to 1.
+
+This patch resolves the issue by ensuring that only the (version, dir,
+hwid) fields are configured in fl_set_erspan_opt(), leaving the other
+fields to 0 in erspan_opt.
+
+Fixes: 79b1011cb33d ("net: sched: allow flower to match erspan options")
+Reported-by: Shuang Li <shuali@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Reviewed-by: Cong Wang <cong.wang@bytedance.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_flower.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index bff0a5f24aca8..057612c97a372 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -1224,7 +1224,6 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+       int err;
+       md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len];
+-      memset(md, 0xff, sizeof(*md));
+       md->version = 1;
+       if (!depth)
+@@ -1253,9 +1252,9 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+                       NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
+                       return -EINVAL;
+               }
++              memset(&md->u.index, 0xff, sizeof(md->u.index));
+               if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX]) {
+                       nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX];
+-                      memset(&md->u, 0x00, sizeof(md->u));
+                       md->u.index = nla_get_be32(nla);
+               }
+       } else if (md->version == 2) {
+@@ -1264,10 +1263,12 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,
+                       NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
+                       return -EINVAL;
+               }
++              md->u.md2.dir = 1;
+               if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR]) {
+                       nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR];
+                       md->u.md2.dir = nla_get_u8(nla);
+               }
++              set_hwid(&md->u.md2, 0xff);
+               if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID]) {
+                       nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID];
+                       set_hwid(&md->u.md2, nla_get_u8(nla));
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch b/queue-5.15/net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch
new file mode 100644 (file)
index 0000000..5d0986b
--- /dev/null
@@ -0,0 +1,90 @@
+From c017e9f8507e77817e179b082ec7f66cfecaaf9f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 18:46:07 +0100
+Subject: net/sched: tbf: correct backlog statistic for GSO packets
+
+From: Martin Ottens <martin.ottens@fau.de>
+
+[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ]
+
+When the length of a GSO packet in the tbf qdisc is larger than the burst
+size configured the packet will be segmented by the tbf_segment function.
+Whenever this function is used to enqueue SKBs, the backlog statistic of
+the tbf is not increased correctly. This can lead to underflows of the
+'backlog' byte-statistic value when these packets are dequeued from tbf.
+
+Reproduce the bug:
+Ensure that the sender machine has GSO enabled. Configured the tbf on
+the outgoing interface of the machine as follows (burstsize = 1 MTU):
+$ tc qdisc add dev <oif> root handle 1: tbf rate 50Mbit burst 1514 latency 50ms
+
+Send bulk TCP traffic out via this interface, e.g., by running an iPerf3
+client on this machine. Check the qdisc statistics:
+$ tc -s qdisc show dev <oif>
+
+The 'backlog' byte-statistic has incorrect values while traffic is
+transferred, e.g., high values due to u32 underflows. When the transfer
+is stopped, the value is != 0, which should never happen.
+
+This patch fixes this bug by updating the statistics correctly, even if
+single SKBs of a GSO SKB cannot be enqueued.
+
+Fixes: e43ac79a4bc6 ("sch_tbf: segment too big GSO packets")
+Signed-off-by: Martin Ottens <martin.ottens@fau.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20241125174608.1484356-1-martin.ottens@fau.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_tbf.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index 7461e5c67d50a..5f50fdeaafa8d 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -193,7 +193,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+       struct tbf_sched_data *q = qdisc_priv(sch);
+       struct sk_buff *segs, *nskb;
+       netdev_features_t features = netif_skb_features(skb);
+-      unsigned int len = 0, prev_len = qdisc_pkt_len(skb);
++      unsigned int len = 0, prev_len = qdisc_pkt_len(skb), seg_len;
+       int ret, nb;
+       segs = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK);
+@@ -204,21 +204,27 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,
+       nb = 0;
+       skb_list_walk_safe(segs, segs, nskb) {
+               skb_mark_not_on_list(segs);
+-              qdisc_skb_cb(segs)->pkt_len = segs->len;
+-              len += segs->len;
++              seg_len = segs->len;
++              qdisc_skb_cb(segs)->pkt_len = seg_len;
+               ret = qdisc_enqueue(segs, q->qdisc, to_free);
+               if (ret != NET_XMIT_SUCCESS) {
+                       if (net_xmit_drop_count(ret))
+                               qdisc_qstats_drop(sch);
+               } else {
+                       nb++;
++                      len += seg_len;
+               }
+       }
+       sch->q.qlen += nb;
+-      if (nb > 1)
++      sch->qstats.backlog += len;
++      if (nb > 0) {
+               qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len);
+-      consume_skb(skb);
+-      return nb > 0 ? NET_XMIT_SUCCESS : NET_XMIT_DROP;
++              consume_skb(skb);
++              return NET_XMIT_SUCCESS;
++      }
++
++      kfree_skb(skb);
++      return NET_XMIT_DROP;
+ }
+ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch b/queue-5.15/net-smc-fix-lgr-and-link-use-after-free-issue.patch
new file mode 100644 (file)
index 0000000..0fecbf8
--- /dev/null
@@ -0,0 +1,92 @@
+From c2f5d6d5fa9488a1bc15c7715ca87d0751f693ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 21:30:14 +0800
+Subject: net/smc: fix LGR and link use-after-free issue
+
+From: Wen Gu <guwen@linux.alibaba.com>
+
+[ Upstream commit 2c7f14ed9c19ec0f149479d1c2842ec1f9bf76d7 ]
+
+We encountered a LGR/link use-after-free issue, which manifested as
+the LGR/link refcnt reaching 0 early and entering the clear process,
+making resource access unsafe.
+
+ refcount_t: addition on 0; use-after-free.
+ WARNING: CPU: 14 PID: 107447 at lib/refcount.c:25 refcount_warn_saturate+0x9c/0x140
+ Workqueue: events smc_lgr_terminate_work [smc]
+ Call trace:
+  refcount_warn_saturate+0x9c/0x140
+  __smc_lgr_terminate.part.45+0x2a8/0x370 [smc]
+  smc_lgr_terminate_work+0x28/0x30 [smc]
+  process_one_work+0x1b8/0x420
+  worker_thread+0x158/0x510
+  kthread+0x114/0x118
+
+or
+
+ refcount_t: underflow; use-after-free.
+ WARNING: CPU: 6 PID: 93140 at lib/refcount.c:28 refcount_warn_saturate+0xf0/0x140
+ Workqueue: smc_hs_wq smc_listen_work [smc]
+ Call trace:
+  refcount_warn_saturate+0xf0/0x140
+  smcr_link_put+0x1cc/0x1d8 [smc]
+  smc_conn_free+0x110/0x1b0 [smc]
+  smc_conn_abort+0x50/0x60 [smc]
+  smc_listen_find_device+0x75c/0x790 [smc]
+  smc_listen_work+0x368/0x8a0 [smc]
+  process_one_work+0x1b8/0x420
+  worker_thread+0x158/0x510
+  kthread+0x114/0x118
+
+It is caused by repeated release of LGR/link refcnt. One suspect is that
+smc_conn_free() is called repeatedly because some smc_conn_free() from
+server listening path are not protected by sock lock.
+
+e.g.
+
+Calls under socklock        | smc_listen_work
+-------------------------------------------------------
+lock_sock(sk)               | smc_conn_abort
+smc_conn_free               | \- smc_conn_free
+\- smcr_link_put            |    \- smcr_link_put (duplicated)
+release_sock(sk)
+
+So here add sock lock protection in smc_listen_work() path, making it
+exclusive with other connection operations.
+
+Fixes: 3b2dec2603d5 ("net/smc: restructure client and server code in af_smc")
+Co-developed-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
+Signed-off-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
+Co-developed-by: Kai <KaiShen@linux.alibaba.com>
+Signed-off-by: Kai <KaiShen@linux.alibaba.com>
+Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
+Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index d433b88e6a277..1072b32a1d75d 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -1509,6 +1509,7 @@ static void smc_listen_out(struct smc_sock *new_smc)
+       if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
+               atomic_dec(&lsmc->queued_smc_hs);
++      release_sock(newsmcsk); /* lock in smc_listen_work() */
+       if (lsmc->sk.sk_state == SMC_LISTEN) {
+               lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
+               smc_accept_enqueue(&lsmc->sk, newsmcsk);
+@@ -1921,6 +1922,7 @@ static void smc_listen_work(struct work_struct *work)
+       struct smc_init_info *ini = NULL;
+       int rc = 0;
++      lock_sock(&new_smc->sk); /* release in smc_listen_out() */
+       if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN)
+               return smc_listen_out_err(new_smc);
+-- 
+2.43.0
+
diff --git a/queue-5.15/net-smc-limit-backlog-connections.patch b/queue-5.15/net-smc-limit-backlog-connections.patch
new file mode 100644 (file)
index 0000000..85b8629
--- /dev/null
@@ -0,0 +1,162 @@
+From baed6108d25c33ddbc43ad7b36b7a743d5bb61fb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 17:11:35 +0800
+Subject: net/smc: Limit backlog connections
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+[ Upstream commit 8270d9c21041470f58348248b9d9dcf3bf79592e ]
+
+Current implementation does not handling backlog semantics, one
+potential risk is that server will be flooded by infinite amount
+connections, even if client was SMC-incapable.
+
+This patch works to put a limit on backlog connections, referring to the
+TCP implementation, we divides SMC connections into two categories:
+
+1. Half SMC connection, which includes all TCP established while SMC not
+connections.
+
+2. Full SMC connection, which includes all SMC established connections.
+
+For half SMC connection, since all half SMC connections starts with TCP
+established, we can achieve our goal by put a limit before TCP
+established. Refer to the implementation of TCP, this limits will based
+on not only the half SMC connections but also the full connections,
+which is also a constraint on full SMC connections.
+
+For full SMC connections, although we know exactly where it starts, it's
+quite hard to put a limit before it. The easiest way is to block wait
+before receive SMC confirm CLC message, while it's under protection by
+smc_server_lgr_pending, a global lock, which leads this limit to the
+entire host instead of a single listen socket. Another way is to drop
+the full connections, but considering the cast of SMC connections, we
+prefer to keep full SMC connections.
+
+Even so, the limits of full SMC connections still exists, see commits
+about half SMC connection below.
+
+After this patch, the limits of backend connection shows like:
+
+For SMC:
+
+1. Client with SMC-capability can makes 2 * backlog full SMC connections
+   or 1 * backlog half SMC connections and 1 * backlog full SMC
+   connections at most.
+
+2. Client without SMC-capability can only makes 1 * backlog half TCP
+   connections and 1 * backlog full TCP connections.
+
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 2c7f14ed9c19 ("net/smc: fix LGR and link use-after-free issue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/smc/af_smc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ net/smc/smc.h    |  6 +++++-
+ 2 files changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index bd0b3a8b95d50..d433b88e6a277 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -71,6 +71,36 @@ static void smc_set_keepalive(struct sock *sk, int val)
+       smc->clcsock->sk->sk_prot->keepalive(smc->clcsock->sk, val);
+ }
++static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk,
++                                        struct sk_buff *skb,
++                                        struct request_sock *req,
++                                        struct dst_entry *dst,
++                                        struct request_sock *req_unhash,
++                                        bool *own_req)
++{
++      struct smc_sock *smc;
++
++      smc = smc_clcsock_user_data(sk);
++
++      if (READ_ONCE(sk->sk_ack_backlog) + atomic_read(&smc->queued_smc_hs) >
++                              sk->sk_max_ack_backlog)
++              goto drop;
++
++      if (sk_acceptq_is_full(&smc->sk)) {
++              NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
++              goto drop;
++      }
++
++      /* passthrough to original syn recv sock fct */
++      return smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash,
++                                            own_req);
++
++drop:
++      dst_release(dst);
++      tcp_listendrop(sk);
++      return NULL;
++}
++
+ static struct smc_hashinfo smc_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(smc_v4_hashinfo.lock),
+ };
+@@ -1476,6 +1506,9 @@ static void smc_listen_out(struct smc_sock *new_smc)
+       struct smc_sock *lsmc = new_smc->listen_smc;
+       struct sock *newsmcsk = &new_smc->sk;
++      if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
++              atomic_dec(&lsmc->queued_smc_hs);
++
+       if (lsmc->sk.sk_state == SMC_LISTEN) {
+               lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
+               smc_accept_enqueue(&lsmc->sk, newsmcsk);
+@@ -2008,6 +2041,9 @@ static void smc_tcp_listen_work(struct work_struct *work)
+               if (!new_smc)
+                       continue;
++              if (tcp_sk(new_smc->clcsock->sk)->syn_smc)
++                      atomic_inc(&lsmc->queued_smc_hs);
++
+               new_smc->listen_smc = lsmc;
+               new_smc->use_fallback = lsmc->use_fallback;
+               new_smc->fallback_rsn = lsmc->fallback_rsn;
+@@ -2074,6 +2110,15 @@ static int smc_listen(struct socket *sock, int backlog)
+       smc->clcsock->sk->sk_data_ready = smc_clcsock_data_ready;
+       smc->clcsock->sk->sk_user_data =
+               (void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
++
++      /* save original ops */
++      smc->ori_af_ops = inet_csk(smc->clcsock->sk)->icsk_af_ops;
++
++      smc->af_ops = *smc->ori_af_ops;
++      smc->af_ops.syn_recv_sock = smc_tcp_syn_recv_sock;
++
++      inet_csk(smc->clcsock->sk)->icsk_af_ops = &smc->af_ops;
++
+       rc = kernel_listen(smc->clcsock, backlog);
+       if (rc) {
+               smc->clcsock->sk->sk_data_ready = smc->clcsk_data_ready;
+diff --git a/net/smc/smc.h b/net/smc/smc.h
+index 57e376756b913..1c00f1bba2cdb 100644
+--- a/net/smc/smc.h
++++ b/net/smc/smc.h
+@@ -241,6 +241,10 @@ struct smc_sock {                         /* smc sock container */
+       bool                    use_fallback;   /* fallback to tcp */
+       int                     fallback_rsn;   /* reason for fallback */
+       u32                     peer_diagnosis; /* decline reason from peer */
++      atomic_t                queued_smc_hs;  /* queued smc handshakes */
++      struct inet_connection_sock_af_ops              af_ops;
++      const struct inet_connection_sock_af_ops        *ori_af_ops;
++                                              /* original af ops */
+       int                     sockopt_defer_accept;
+                                               /* sockopt TCP_DEFER_ACCEPT
+                                                * value
+@@ -265,7 +269,7 @@ static inline struct smc_sock *smc_sk(const struct sock *sk)
+       return (struct smc_sock *)sk;
+ }
+-static inline struct smc_sock *smc_clcsock_user_data(struct sock *clcsk)
++static inline struct smc_sock *smc_clcsock_user_data(const struct sock *clcsk)
+ {
+       return (struct smc_sock *)
+              ((uintptr_t)clcsk->sk_user_data & ~SK_USER_DATA_NOCOPY);
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch b/queue-5.15/netfilter-ipset-hold-module-reference-while-requesti.patch
new file mode 100644 (file)
index 0000000..88361c5
--- /dev/null
@@ -0,0 +1,49 @@
+From f38cbbc568896cd7ba7fd3e438e0b678b91e46f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Nov 2024 16:30:38 +0100
+Subject: netfilter: ipset: Hold module reference while requesting a module
+
+From: Phil Sutter <phil@nwl.cc>
+
+[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ]
+
+User space may unload ip_set.ko while it is itself requesting a set type
+backend module, leading to a kernel crash. The race condition may be
+provoked by inserting an mdelay() right after the nfnl_unlock() call.
+
+Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support")
+Signed-off-by: Phil Sutter <phil@nwl.cc>
+Acked-by: Jozsef Kadlecsik <kadlec@netfilter.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipset/ip_set_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index f2f6b7325c706..72e5638206c0e 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -104,14 +104,19 @@ find_set_type(const char *name, u8 family, u8 revision)
+ static bool
+ load_settype(const char *name)
+ {
++      if (!try_module_get(THIS_MODULE))
++              return false;
++
+       nfnl_unlock(NFNL_SUBSYS_IPSET);
+       pr_debug("try to load ip_set_%s\n", name);
+       if (request_module("ip_set_%s", name) < 0) {
+               pr_warn("Can't find ip_set type %s\n", name);
+               nfnl_lock(NFNL_SUBSYS_IPSET);
++              module_put(THIS_MODULE);
+               return false;
+       }
+       nfnl_lock(NFNL_SUBSYS_IPSET);
++      module_put(THIS_MODULE);
+       return true;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch b/queue-5.15/netfilter-nft_set_hash-skip-duplicated-elements-pend.patch
new file mode 100644 (file)
index 0000000..80ddffc
--- /dev/null
@@ -0,0 +1,97 @@
+From bc68880146f0e721d84010bb438233d55b5aaad1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Dec 2024 00:04:49 +0100
+Subject: netfilter: nft_set_hash: skip duplicated elements pending gc run
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ]
+
+rhashtable does not provide stable walk, duplicated elements are
+possible in case of resizing. I considered that checking for errors when
+calling rhashtable_walk_next() was sufficient to detect the resizing.
+However, rhashtable_walk_next() returns -EAGAIN only at the end of the
+iteration, which is too late, because a gc work containing duplicated
+elements could have been already scheduled for removal to the worker.
+
+Add a u32 gc worker sequence number per set, bump it on every workqueue
+run. Annotate gc worker sequence number on the expired element. Use it
+to skip those already seen in this gc workqueue run.
+
+Note that this new field is never reset in case gc transaction fails, so
+next gc worker run on the expired element overrides it. Wraparound of gc
+worker sequence number should not be an issue with stale gc worker
+sequence number in the element, that would just postpone the element
+removal in one gc run.
+
+Note that it is not possible to use flags to annotate that element is
+pending gc run to detect duplicates, given that gc transaction can be
+invalidated in case of update from the control plane, therefore, not
+allowing to clear such flag.
+
+On x86_64, pahole reports no changes in the size of nft_rhash_elem.
+
+Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API")
+Reported-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Tested-by: Laurent Fasnacht <laurent.fasnacht@proton.ch>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_hash.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
+index 1fd3b413350dc..5c4209b49bda7 100644
+--- a/net/netfilter/nft_set_hash.c
++++ b/net/netfilter/nft_set_hash.c
+@@ -24,10 +24,12 @@
+ struct nft_rhash {
+       struct rhashtable               ht;
+       struct delayed_work             gc_work;
++      u32                             wq_gc_seq;
+ };
+ struct nft_rhash_elem {
+       struct rhash_head               node;
++      u32                             wq_gc_seq;
+       struct nft_set_ext              ext;
+ };
+@@ -339,6 +341,10 @@ static void nft_rhash_gc(struct work_struct *work)
+       if (!gc)
+               goto done;
++      /* Elements never collected use a zero gc worker sequence number. */
++      if (unlikely(++priv->wq_gc_seq == 0))
++              priv->wq_gc_seq++;
++
+       rhashtable_walk_enter(&priv->ht, &hti);
+       rhashtable_walk_start(&hti);
+@@ -356,6 +362,14 @@ static void nft_rhash_gc(struct work_struct *work)
+                       goto try_later;
+               }
++              /* rhashtable walk is unstable, already seen in this gc run?
++               * Then, skip this element. In case of (unlikely) sequence
++               * wraparound and stale element wq_gc_seq, next gc run will
++               * just find this expired element.
++               */
++              if (he->wq_gc_seq == priv->wq_gc_seq)
++                      continue;
++
+               if (nft_set_elem_is_dead(&he->ext))
+                       goto dead_elem;
+@@ -372,6 +386,8 @@ static void nft_rhash_gc(struct work_struct *work)
+               if (!gc)
+                       goto try_later;
++              /* annotate gc sequence for this attempt. */
++              he->wq_gc_seq = priv->wq_gc_seq;
+               nft_trans_gc_elem_add(gc, he);
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch b/queue-5.15/netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch
new file mode 100644 (file)
index 0000000..15a1b9b
--- /dev/null
@@ -0,0 +1,109 @@
+From 3584065cf9b9c5aa9e7bc8f0109d5bbfbbf2f667 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Nov 2024 09:55:42 +0300
+Subject: netfilter: x_tables: fix LED ID check in led_tg_check()
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ]
+
+Syzbot has reported the following BUG detected by KASAN:
+
+BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70
+Read of size 1 at addr ffff8881022da0c8 by task repro/5879
+...
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x241/0x360
+ ? __pfx_dump_stack_lvl+0x10/0x10
+ ? __pfx__printk+0x10/0x10
+ ? _printk+0xd5/0x120
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ print_report+0x169/0x550
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x183/0x530
+ ? __virt_addr_valid+0x45f/0x530
+ ? __phys_addr+0xba/0x170
+ ? strlen+0x58/0x70
+ kasan_report+0x143/0x180
+ ? strlen+0x58/0x70
+ strlen+0x58/0x70
+ kstrdup+0x20/0x80
+ led_tg_check+0x18b/0x3c0
+ xt_check_target+0x3bb/0xa40
+ ? __pfx_xt_check_target+0x10/0x10
+ ? stack_depot_save_flags+0x6e4/0x830
+ ? nft_target_init+0x174/0xc30
+ nft_target_init+0x82d/0xc30
+ ? __pfx_nft_target_init+0x10/0x10
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? rcu_is_watching+0x15/0xb0
+ ? nf_tables_newrule+0x1609/0x2980
+ ? nf_tables_newrule+0x1609/0x2980
+ ? __kmalloc_noprof+0x21a/0x400
+ nf_tables_newrule+0x1860/0x2980
+ ? __pfx_nf_tables_newrule+0x10/0x10
+ ? __nla_parse+0x40/0x60
+ nfnetlink_rcv+0x14e5/0x2ab0
+ ? __pfx_validate_chain+0x10/0x10
+ ? __pfx_nfnetlink_rcv+0x10/0x10
+ ? __lock_acquire+0x1384/0x2050
+ ? netlink_deliver_tap+0x2e/0x1b0
+ ? __pfx_lock_release+0x10/0x10
+ ? netlink_deliver_tap+0x2e/0x1b0
+ netlink_unicast+0x7f8/0x990
+ ? __pfx_netlink_unicast+0x10/0x10
+ ? __virt_addr_valid+0x183/0x530
+ ? __check_object_size+0x48e/0x900
+ netlink_sendmsg+0x8e4/0xcb0
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ ? aa_sock_msg_perm+0x91/0x160
+ ? __pfx_netlink_sendmsg+0x10/0x10
+ __sock_sendmsg+0x223/0x270
+ ____sys_sendmsg+0x52a/0x7e0
+ ? __pfx_____sys_sendmsg+0x10/0x10
+ __sys_sendmsg+0x292/0x380
+ ? __pfx___sys_sendmsg+0x10/0x10
+ ? lockdep_hardirqs_on_prepare+0x43d/0x780
+ ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10
+ ? exc_page_fault+0x590/0x8c0
+ ? do_syscall_64+0xb6/0x230
+ do_syscall_64+0xf3/0x230
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+...
+ </TASK>
+
+Since an invalid (without '\0' byte at all) byte sequence may be passed
+from userspace, add an extra check to ensure that such a sequence is
+rejected as possible ID and so never passed to 'kstrdup()' and further.
+
+Reported-by: syzbot+6c8215822f35fdb35667@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=6c8215822f35fdb35667
+Fixes: 268cb38e1802 ("netfilter: x_tables: add LED trigger target")
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/xt_LED.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
+index 211bfa2a2ac04..c2c10a536cc68 100644
+--- a/net/netfilter/xt_LED.c
++++ b/net/netfilter/xt_LED.c
+@@ -97,7 +97,9 @@ static int led_tg_check(const struct xt_tgchk_param *par)
+       struct xt_led_info_internal *ledinternal;
+       int err;
+-      if (ledinfo->id[0] == '\0')
++      /* Bail out if empty string or not a string at all. */
++      if (ledinfo->id[0] == '\0' ||
++          !memchr(ledinfo->id, '\0', sizeof(ledinfo->id)))
+               return -EINVAL;
+       mutex_lock(&xt_led_mutex);
+-- 
+2.43.0
+
diff --git a/queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch b/queue-5.15/ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch
new file mode 100644 (file)
index 0000000..220174b
--- /dev/null
@@ -0,0 +1,42 @@
+From 980a99dd285b52ce1faabc17596a850fe829e011 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Nov 2024 10:59:54 +0000
+Subject: ptp: Add error handling for adjfine callback in ptp_clock_adjtime
+
+From: Ajay Kaher <ajay.kaher@broadcom.com>
+
+[ Upstream commit 98337d7c87577ded71114f6976edb70a163e27bc ]
+
+ptp_clock_adjtime sets ptp->dialed_frequency even when adjfine
+callback returns an error. This causes subsequent reads to return
+an incorrect value.
+
+Fix this by adding error check before ptp->dialed_frequency is set.
+
+Fixes: 39a8cbd9ca05 ("ptp: remember the adjusted frequency")
+Signed-off-by: Ajay Kaher <ajay.kaher@broadcom.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241125105954.1509971-1-ajay.kaher@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_clock.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
+index e70c6dec3a3a3..92dd1c6f54f4a 100644
+--- a/drivers/ptp/ptp_clock.c
++++ b/drivers/ptp/ptp_clock.c
+@@ -136,7 +136,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
+                       err = ops->adjfine(ops, tx->freq);
+               else
+                       err = ops->adjfreq(ops, ppb);
+-              ptp->dialed_frequency = tx->freq;
++              if (!err)
++                      ptp->dialed_frequency = tx->freq;
+       } else if (tx->modes & ADJ_OFFSET) {
+               if (ops->adjphase) {
+                       s32 offset = tx->offset;
+-- 
+2.43.0
+
diff --git a/queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch b/queue-5.15/serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch
new file mode 100644 (file)
index 0000000..59cd782
--- /dev/null
@@ -0,0 +1,49 @@
+From c080688daab7ea65b1f7914ee83648305a130cd9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Nov 2024 14:56:29 +0530
+Subject: serial: amba-pl011: Fix RX stall when DMA is used
+
+From: Kartik Rajput <kkartik@nvidia.com>
+
+[ Upstream commit 2bcacc1c87acf9a8ebc17de18cb2b3cfeca547cf ]
+
+Function pl011_throttle_rx() calls pl011_stop_rx() to disable RX, which
+also disables the RX DMA by clearing the RXDMAE bit of the DMACR
+register. However, to properly unthrottle RX when DMA is used, the
+function pl011_unthrottle_rx() is expected to set the RXDMAE bit of
+the DMACR register, which it currently lacks. This causes RX to stall
+after the throttle API is called.
+
+Set RXDMAE bit in the DMACR register while unthrottling RX if RX DMA is
+used.
+
+Fixes: 211565b10099 ("serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle")
+Cc: stable@vger.kernel.org
+Signed-off-by: Kartik Rajput <kkartik@nvidia.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20241113092629.60226-1-kkartik@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 16fc159bdf3b9..8ae8fb8132d5b 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1842,6 +1842,11 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+       pl011_write(uap->im, uap, REG_IMSC);
++      if (uap->using_rx_dma) {
++              uap->dmacr |= UART011_RXDMAE;
++              pl011_write(uap->dmacr, uap, REG_DMACR);
++      }
++
+       uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch b/queue-5.15/serial-amba-pl011-use-port-lock-wrappers.patch
new file mode 100644 (file)
index 0000000..304ebb2
--- /dev/null
@@ -0,0 +1,338 @@
+From de8b11d5e089eca946f187e136df1b4a6019c8ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Sep 2023 20:43:34 +0206
+Subject: serial: amba-pl011: Use port lock wrappers
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 68ca3e72d7463d79d29b6e4961d6028df2a88e25 ]
+
+When a serial port is used for kernel console output, then all
+modifications to the UART registers which are done from other contexts,
+e.g. getty, termios, are interference points for the kernel console.
+
+So far this has been ignored and the printk output is based on the
+principle of hope. The rework of the console infrastructure which aims to
+support threaded and atomic consoles, requires to mark sections which
+modify the UART registers as unsafe. This allows the atomic write function
+to make informed decisions and eventually to restore operational state. It
+also allows to prevent the regular UART code from modifying UART registers
+while printk output is in progress.
+
+All modifications of UART registers are guarded by the UART port lock,
+which provides an obvious synchronization point with the console
+infrastructure.
+
+To avoid adding this functionality to all UART drivers, wrap the
+spin_[un]lock*() invocations for uart_port::lock into helper functions
+which just contain the spin_[un]lock*() invocations for now. In a
+subsequent step these helpers will gain the console synchronization
+mechanisms.
+
+Converted with coccinelle. No functional change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20230914183831.587273-18-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 2bcacc1c87ac ("serial: amba-pl011: Fix RX stall when DMA is used")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/amba-pl011.c | 72 ++++++++++++++++-----------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index a5eb5dc275ccd..16fc159bdf3b9 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -351,9 +351,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
+                               flag = TTY_FRAME;
+               }
+-              spin_unlock(&uap->port.lock);
++              uart_port_unlock(&uap->port);
+               sysrq = uart_handle_sysrq_char(&uap->port, ch & 255);
+-              spin_lock(&uap->port.lock);
++              uart_port_lock(&uap->port);
+               if (!sysrq)
+                       uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
+@@ -548,7 +548,7 @@ static void pl011_dma_tx_callback(void *data)
+       unsigned long flags;
+       u16 dmacr;
+-      spin_lock_irqsave(&uap->port.lock, flags);
++      uart_port_lock_irqsave(&uap->port, &flags);
+       if (uap->dmatx.queued)
+               dma_unmap_single(dmatx->chan->device->dev, dmatx->dma,
+                               dmatx->len, DMA_TO_DEVICE);
+@@ -569,7 +569,7 @@ static void pl011_dma_tx_callback(void *data)
+       if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
+           uart_circ_empty(&uap->port.state->xmit)) {
+               uap->dmatx.queued = false;
+-              spin_unlock_irqrestore(&uap->port.lock, flags);
++              uart_port_unlock_irqrestore(&uap->port, flags);
+               return;
+       }
+@@ -580,7 +580,7 @@ static void pl011_dma_tx_callback(void *data)
+                */
+               pl011_start_tx_pio(uap);
+-      spin_unlock_irqrestore(&uap->port.lock, flags);
++      uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+ /*
+@@ -1009,7 +1009,7 @@ static void pl011_dma_rx_callback(void *data)
+        * routine to flush out the secondary DMA buffer while
+        * we immediately trigger the next DMA job.
+        */
+-      spin_lock_irq(&uap->port.lock);
++      uart_port_lock_irq(&uap->port);
+       /*
+        * Rx data can be taken by the UART interrupts during
+        * the DMA irq handler. So we check the residue here.
+@@ -1025,7 +1025,7 @@ static void pl011_dma_rx_callback(void *data)
+       ret = pl011_dma_rx_trigger_dma(uap);
+       pl011_dma_rx_chars(uap, pending, lastbuf, false);
+-      spin_unlock_irq(&uap->port.lock);
++      uart_port_unlock_irq(&uap->port);
+       /*
+        * Do this check after we picked the DMA chars so we don't
+        * get some IRQ immediately from RX.
+@@ -1091,11 +1091,11 @@ static void pl011_dma_rx_poll(struct timer_list *t)
+       if (jiffies_to_msecs(jiffies - dmarx->last_jiffies)
+                       > uap->dmarx.poll_timeout) {
+-              spin_lock_irqsave(&uap->port.lock, flags);
++              uart_port_lock_irqsave(&uap->port, &flags);
+               pl011_dma_rx_stop(uap);
+               uap->im |= UART011_RXIM;
+               pl011_write(uap->im, uap, REG_IMSC);
+-              spin_unlock_irqrestore(&uap->port.lock, flags);
++              uart_port_unlock_irqrestore(&uap->port, flags);
+               uap->dmarx.running = false;
+               dmaengine_terminate_all(rxchan);
+@@ -1191,10 +1191,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
+       while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
+               cpu_relax();
+-      spin_lock_irq(&uap->port.lock);
++      uart_port_lock_irq(&uap->port);
+       uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
+       pl011_write(uap->dmacr, uap, REG_DMACR);
+-      spin_unlock_irq(&uap->port.lock);
++      uart_port_unlock_irq(&uap->port);
+       if (uap->using_tx_dma) {
+               /* In theory, this should already be done by pl011_dma_flush_buffer */
+@@ -1405,9 +1405,9 @@ static void pl011_throttle_rx(struct uart_port *port)
+ {
+       unsigned long flags;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       pl011_stop_rx(port);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void pl011_enable_ms(struct uart_port *port)
+@@ -1425,7 +1425,7 @@ __acquires(&uap->port.lock)
+ {
+       pl011_fifo_to_tty(uap);
+-      spin_unlock(&uap->port.lock);
++      uart_port_unlock(&uap->port);
+       tty_flip_buffer_push(&uap->port.state->port);
+       /*
+        * If we were temporarily out of DMA mode for a while,
+@@ -1450,7 +1450,7 @@ __acquires(&uap->port.lock)
+ #endif
+               }
+       }
+-      spin_lock(&uap->port.lock);
++      uart_port_lock(&uap->port);
+ }
+ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
+@@ -1556,7 +1556,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
+       unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+       int handled = 0;
+-      spin_lock_irqsave(&uap->port.lock, flags);
++      uart_port_lock_irqsave(&uap->port, &flags);
+       status = pl011_read(uap, REG_RIS) & uap->im;
+       if (status) {
+               do {
+@@ -1586,7 +1586,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
+               handled = 1;
+       }
+-      spin_unlock_irqrestore(&uap->port.lock, flags);
++      uart_port_unlock_irqrestore(&uap->port, flags);
+       return IRQ_RETVAL(handled);
+ }
+@@ -1658,14 +1658,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
+       unsigned long flags;
+       unsigned int lcr_h;
+-      spin_lock_irqsave(&uap->port.lock, flags);
++      uart_port_lock_irqsave(&uap->port, &flags);
+       lcr_h = pl011_read(uap, REG_LCRH_TX);
+       if (break_state == -1)
+               lcr_h |= UART01x_LCRH_BRK;
+       else
+               lcr_h &= ~UART01x_LCRH_BRK;
+       pl011_write(lcr_h, uap, REG_LCRH_TX);
+-      spin_unlock_irqrestore(&uap->port.lock, flags);
++      uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+ #ifdef CONFIG_CONSOLE_POLL
+@@ -1804,7 +1804,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+       unsigned long flags;
+       unsigned int i;
+-      spin_lock_irqsave(&uap->port.lock, flags);
++      uart_port_lock_irqsave(&uap->port, &flags);
+       /* Clear out any spuriously appearing RX interrupts */
+       pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
+@@ -1826,7 +1826,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+       if (!pl011_dma_rx_running(uap))
+               uap->im |= UART011_RXIM;
+       pl011_write(uap->im, uap, REG_IMSC);
+-      spin_unlock_irqrestore(&uap->port.lock, flags);
++      uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+ static void pl011_unthrottle_rx(struct uart_port *port)
+@@ -1834,7 +1834,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+       struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
+       unsigned long flags;
+-      spin_lock_irqsave(&uap->port.lock, flags);
++      uart_port_lock_irqsave(&uap->port, &flags);
+       uap->im = UART011_RTIM;
+       if (!pl011_dma_rx_running(uap))
+@@ -1842,7 +1842,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
+       pl011_write(uap->im, uap, REG_IMSC);
+-      spin_unlock_irqrestore(&uap->port.lock, flags);
++      uart_port_unlock_irqrestore(&uap->port, flags);
+ }
+ static int pl011_startup(struct uart_port *port)
+@@ -1862,7 +1862,7 @@ static int pl011_startup(struct uart_port *port)
+       pl011_write(uap->vendor->ifls, uap, REG_IFLS);
+-      spin_lock_irq(&uap->port.lock);
++      uart_port_lock_irq(&uap->port);
+       /* restore RTS and DTR */
+       cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
+@@ -1873,7 +1873,7 @@ static int pl011_startup(struct uart_port *port)
+       pl011_write(cr, uap, REG_CR);
+-      spin_unlock_irq(&uap->port.lock);
++      uart_port_unlock_irq(&uap->port);
+       /*
+        * initialise the old status of the modem signals
+@@ -1934,13 +1934,13 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
+       unsigned int cr;
+       uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
+-      spin_lock_irq(&uap->port.lock);
++      uart_port_lock_irq(&uap->port);
+       cr = pl011_read(uap, REG_CR);
+       uap->old_cr = cr;
+       cr &= UART011_CR_RTS | UART011_CR_DTR;
+       cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
+       pl011_write(cr, uap, REG_CR);
+-      spin_unlock_irq(&uap->port.lock);
++      uart_port_unlock_irq(&uap->port);
+       /*
+        * disable break condition and fifos
+@@ -1952,14 +1952,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
+ static void pl011_disable_interrupts(struct uart_amba_port *uap)
+ {
+-      spin_lock_irq(&uap->port.lock);
++      uart_port_lock_irq(&uap->port);
+       /* mask all interrupts and clear all pending ones */
+       uap->im = 0;
+       pl011_write(uap->im, uap, REG_IMSC);
+       pl011_write(0xffff, uap, REG_ICR);
+-      spin_unlock_irq(&uap->port.lock);
++      uart_port_unlock_irq(&uap->port);
+ }
+ static void pl011_shutdown(struct uart_port *port)
+@@ -2104,7 +2104,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
+       bits = tty_get_frame_size(termios->c_cflag);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       /*
+        * Update the per-port timeout.
+@@ -2171,7 +2171,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
+       pl011_write_lcr_h(uap, lcr_h);
+       pl011_write(old_cr, uap, REG_CR);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void
+@@ -2189,10 +2189,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios,
+       termios->c_cflag &= ~(CMSPAR | CRTSCTS);
+       termios->c_cflag |= CS8 | CLOCAL;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       uart_update_timeout(port, CS8, uap->fixed_baud);
+       pl011_setup_status_masks(port, termios);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static const char *pl011_type(struct uart_port *port)
+@@ -2345,9 +2345,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+       if (uap->port.sysrq)
+               locked = 0;
+       else if (oops_in_progress)
+-              locked = spin_trylock(&uap->port.lock);
++              locked = uart_port_trylock(&uap->port);
+       else
+-              spin_lock(&uap->port.lock);
++              uart_port_lock(&uap->port);
+       /*
+        *      First save the CR then disable the interrupts
+@@ -2373,7 +2373,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+               pl011_write(old_cr, uap, REG_CR);
+       if (locked)
+-              spin_unlock(&uap->port.lock);
++              uart_port_unlock(&uap->port);
+       local_irq_restore(flags);
+       clk_disable(uap->clk);
+-- 
+2.43.0
+
index 82aa7623b25f955f5506681f1aeeaea2b6dbc735..b28d5ddec0b3f08c68687144737ad41ce0aff4b2 100644 (file)
@@ -397,3 +397,37 @@ drm-sti-avoid-potential-dereference-of-error-pointers-in-sti_hqvdp_atomic_check.
 drm-sti-avoid-potential-dereference-of-error-pointers-in-sti_gdp_atomic_check.patch
 drm-sti-avoid-potential-dereference-of-error-pointers.patch
 drm-etnaviv-flush-shader-l1-cache-after-user-commandstream.patch
+itco_wdt-mask-nmi_now-bit-for-update_no_reboot_bit-c.patch
+watchdog-mediatek-make-sure-system-reset-gets-assert.patch
+can-peak_usb-canfd-store-64-bits-hw-timestamps.patch
+can-do-not-increase-rx-statistics-when-generating-a-.patch
+can-c_can-c_can_handle_bus_err-update-statistics-if-.patch
+can-sun4i_can-sun4i_can_err-call-can_change_state-ev.patch
+can-m_can-m_can_handle_lec_err-fix-rx-tx-_errors-sta.patch
+can-ifi_canfd-ifi_canfd_handle_lec_err-fix-rx-tx-_er.patch
+can-sun4i_can-sun4i_can_err-fix-rx-tx-_errors-statis.patch
+can-ems_usb-ems_usb_rx_err-fix-rx-tx-_errors-statist.patch
+ipvs-fix-ub-due-to-uninitialized-stack-access-in-ip_.patch
+netfilter-x_tables-fix-led-id-check-in-led_tg_check.patch
+ptp-add-error-handling-for-adjfine-callback-in-ptp_c.patch
+net-sched-tbf-correct-backlog-statistic-for-gso-pack.patch
+net-hsr-avoid-potential-out-of-bound-access-in-fill_.patch
+can-j1939-j1939_session_new-fix-skb-reference-counti.patch
+net-ipv6-release-expired-exception-dst-cached-in-soc.patch
+dccp-fix-memory-leak-in-dccp_feat_change_recv.patch
+tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch
+net-smc-limit-backlog-connections.patch
+net-smc-fix-lgr-and-link-use-after-free-issue.patch
+net-qed-allow-old-cards-not-supporting-num_images-to.patch
+igb-fix-potential-invalid-memory-access-in-igb_init_.patch
+net-sched-fix-erspan_opt-settings-in-cls_flower.patch
+netfilter-ipset-hold-module-reference-while-requesti.patch
+netfilter-nft_set_hash-skip-duplicated-elements-pend.patch
+ethtool-fix-wrong-mod-state-in-case-of-verbose-and-n.patch
+geneve-do-not-assume-mac-header-is-set-in-geneve_xmi.patch
+gpio-grgpio-use-a-helper-variable-to-store-the-addre.patch
+gpio-grgpio-add-null-check-in-grgpio_probe.patch
+dt_bindings-rs485-correct-delay-values.patch
+dt-bindings-serial-rs485-fix-rs485-rts-delay-propert.patch
+serial-amba-pl011-use-port-lock-wrappers.patch
+serial-amba-pl011-fix-rx-stall-when-dma-is-used.patch
diff --git a/queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch b/queue-5.15/tipc-fix-use-after-free-of-kernel-socket-in-cleanup_.patch
new file mode 100644 (file)
index 0000000..d44de7f
--- /dev/null
@@ -0,0 +1,107 @@
+From 0efd40a3082aea84de4e529fb63ccfacc65c3b86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Nov 2024 14:05:12 +0900
+Subject: tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ]
+
+syzkaller reported a use-after-free of UDP kernel socket
+in cleanup_bearer() without repro. [0][1]
+
+When bearer_disable() calls tipc_udp_disable(), cleanup
+of the UDP kernel socket is deferred by work calling
+cleanup_bearer().
+
+tipc_net_stop() waits for such works to finish by checking
+tipc_net(net)->wq_count.  However, the work decrements the
+count too early before releasing the kernel socket,
+unblocking cleanup_net() and resulting in use-after-free.
+
+Let's move the decrement after releasing the socket in
+cleanup_bearer().
+
+[0]:
+ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at
+     sk_alloc+0x438/0x608
+     inet_create+0x4c8/0xcb0
+     __sock_create+0x350/0x6b8
+     sock_create_kern+0x58/0x78
+     udp_sock_create4+0x68/0x398
+     udp_sock_create+0x88/0xc8
+     tipc_udp_enable+0x5e8/0x848
+     __tipc_nl_bearer_enable+0x84c/0xed8
+     tipc_nl_bearer_enable+0x38/0x60
+     genl_family_rcv_msg_doit+0x170/0x248
+     genl_rcv_msg+0x400/0x5b0
+     netlink_rcv_skb+0x1dc/0x398
+     genl_rcv+0x44/0x68
+     netlink_unicast+0x678/0x8b0
+     netlink_sendmsg+0x5e4/0x898
+     ____sys_sendmsg+0x500/0x830
+
+[1]:
+BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline]
+BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ udp_hashslot include/net/udp.h:85 [inline]
+ udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979
+ sk_common_release+0xaf/0x3f0 net/core/sock.c:3820
+ inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437
+ inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489
+ __sock_release net/socket.c:658 [inline]
+ sock_release+0xa0/0x210 net/socket.c:686
+ cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+Uninit was created at:
+ slab_free_hook mm/slub.c:2269 [inline]
+ slab_free mm/slub.c:4580 [inline]
+ kmem_cache_free+0x207/0xc40 mm/slub.c:4682
+ net_free net/core/net_namespace.c:454 [inline]
+ cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647
+ process_one_work kernel/workqueue.c:3229 [inline]
+ process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310
+ worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391
+ kthread+0x531/0x6b0 kernel/kthread.c:389
+ ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
+
+CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
+Workqueue: events cleanup_bearer
+
+Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20241127050512.28438-1-kuniyu@amazon.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/udp_media.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
+index 73e461dc12d7b..3f5a12b85b2d3 100644
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -818,10 +818,10 @@ static void cleanup_bearer(struct work_struct *work)
+               kfree_rcu(rcast, rcu);
+       }
+-      atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+       dst_cache_destroy(&ub->rcast.dst_cache);
+       udp_tunnel_sock_release(ub->ubsock);
+       synchronize_net();
++      atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count);
+       kfree(ub);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch b/queue-5.15/watchdog-mediatek-make-sure-system-reset-gets-assert.patch
new file mode 100644 (file)
index 0000000..d63c995
--- /dev/null
@@ -0,0 +1,48 @@
+From 15b6923bcd2e79fc5049059d699807d172ac03f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Nov 2024 10:47:51 +0000
+Subject: watchdog: mediatek: Make sure system reset gets asserted in
+ mtk_wdt_restart()
+
+From: Yassine Oudjana <y.oudjana@protonmail.com>
+
+[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ]
+
+Clear the IRQ enable bit of WDT_MODE before asserting software reset
+in order to make TOPRGU issue a system reset signal instead of an IRQ.
+
+Fixes: a44a45536f7b ("watchdog: Add driver for Mediatek watchdog")
+Signed-off-by: Yassine Oudjana <y.oudjana@protonmail.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Link: https://lore.kernel.org/r/20241106104738.195968-2-y.oudjana@protonmail.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/watchdog/mtk_wdt.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
+index 796fbb048cbea..a9d67ead94838 100644
+--- a/drivers/watchdog/mtk_wdt.c
++++ b/drivers/watchdog/mtk_wdt.c
+@@ -164,9 +164,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
+ {
+       struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+       void __iomem *wdt_base;
++      u32 reg;
+       wdt_base = mtk_wdt->wdt_base;
++      /* Enable reset in order to issue a system reset instead of an IRQ */
++      reg = readl(wdt_base + WDT_MODE);
++      reg &= ~WDT_MODE_IRQ_EN;
++      writel(reg | WDT_MODE_KEY, wdt_base + WDT_MODE);
++
+       while (1) {
+               writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);
+               mdelay(5);
+-- 
+2.43.0
+