-LINUX_VERSION-6.6 = .45
-LINUX_KERNEL_HASH-6.6.45 = 121bed240767e4a0959c1609e78eeaaf3e0620d9d1a5ed1f6e36bdf609c4f179
+LINUX_VERSION-6.6 = .46
+LINUX_KERNEL_HASH-6.6.46 = 052f932396d9c7d84ceeda91226a8ef797c12188bde41e6c419602d990dd45f2
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_ACPI_PARKING_PROTOCOL is not set
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
return segs;
-@@ -255,7 +255,7 @@ struct sk_buff *tcp_gro_lookup(struct li
+@@ -258,7 +258,7 @@ struct sk_buff *tcp_gro_lookup(struct li
continue;
th2 = tcp_hdr(p);
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
-@@ -321,8 +321,8 @@ struct sk_buff *tcp_gro_receive(struct l
+@@ -324,8 +324,8 @@ struct sk_buff *tcp_gro_receive(struct l
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
for (i = sizeof(*th); i < thlen; i += 4)
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
-@@ -719,7 +719,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
+@@ -720,7 +720,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
*/
static int spidev_of_check(struct device *dev)
{
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
-@@ -57,6 +57,8 @@
+@@ -58,6 +58,8 @@
#define extra_checks 0
#endif
/* Device and char device-related information */
static DEFINE_IDA(gpio_ida);
static dev_t gpio_devt;
-@@ -2591,8 +2593,8 @@ int gpiod_direction_output(struct gpio_d
+@@ -2592,8 +2594,8 @@ int gpiod_direction_output(struct gpio_d
value = !!value;
/* GPIOs used for enabled IRQs shall not be set as output */
gpiod_err(desc,
"%s: tried to set a GPIO tied to an IRQ as output\n",
__func__);
-@@ -3470,8 +3472,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
+@@ -3471,8 +3473,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
}
/* To be valid for IRQ the line needs to be input or open drain */
static const struct spi_device_id spidev_spi_ids[] = {
+ { .name = "spidev" },
+ { .name = "bh2228fv" },
{ .name = "dh2228fv" },
{ .name = "ltc2488" },
- { .name = "sx1301" },
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
-@@ -4693,6 +4693,7 @@ static const struct {
+@@ -4707,6 +4707,7 @@ static const struct {
*/
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
int ret = 0;
bool invalid_bdaddr;
size_t i;
-@@ -4721,7 +4722,8 @@ static int hci_dev_setup_sync(struct hci
+@@ -4735,7 +4736,8 @@ static int hci_dev_setup_sync(struct hci
test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
if (!ret) {
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
-@@ -110,6 +110,7 @@ static int gpiochip_irqchip_init_valid_m
+@@ -111,6 +111,7 @@ static int gpiochip_irqchip_init_valid_m
static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc);
static bool gpiolib_initialized;
static inline void desc_set_label(struct gpio_desc *d, const char *label)
{
-@@ -745,6 +746,7 @@ int gpiochip_add_data_with_key(struct gp
+@@ -746,6 +747,7 @@ int gpiochip_add_data_with_key(struct gp
unsigned int i;
int base = 0;
int ret = 0;
/*
* First: allocate and populate the internal stat container, and
-@@ -769,7 +771,16 @@ int gpiochip_add_data_with_key(struct gp
+@@ -770,7 +772,16 @@ int gpiochip_add_data_with_key(struct gp
else if (gc->parent)
device_set_node(&gdev->dev, dev_fwnode(gc->parent));
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1522,10 +1522,14 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1524,10 +1524,14 @@ static int bcm_sf2_sw_probe(struct platf
rev = reg_readl(priv, REG_PHY_REVISION);
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1536,6 +1536,12 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1538,6 +1538,12 @@ static int bcm_sf2_sw_probe(struct platf
priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
priv->irq0, priv->irq1);
}
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -357,6 +357,14 @@ struct sk_buff *__udp_gso_segment(struct
+@@ -361,6 +361,14 @@ struct sk_buff *__udp_gso_segment(struct
else
uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -278,6 +278,12 @@ struct sk_buff *__udp_gso_segment(struct
- if (gso_skb->len <= sizeof(*uh) + mss)
+@@ -282,6 +282,12 @@ struct sk_buff *__udp_gso_segment(struct
+ skb_transport_header(gso_skb)))
return ERR_PTR(-EINVAL);
+ /* We don't know if egress device can segment and checksum the packet
# CONFIG_ARM64_ERRATUM_2658417 is not set
# CONFIG_ARM64_ERRATUM_2966298 is not set
# CONFIG_ARM64_ERRATUM_3117295 is not set
+# CONFIG_ARM64_ERRATUM_3194386 is not set
# CONFIG_ARM64_ERRATUM_819472 is not set
# CONFIG_ARM64_ERRATUM_824069 is not set
# CONFIG_ARM64_ERRATUM_826319 is not set
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1083,12 +1083,18 @@ static const struct usb_device_id produc
+@@ -1084,12 +1084,18 @@ static const struct usb_device_id produc
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
.driver_info = (unsigned long)&qmi_wwan_info,
},
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -1657,7 +1657,7 @@ static void device_links_purge(struct de
+@@ -1658,7 +1658,7 @@ static void device_links_purge(struct de
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
DL_FLAG_PM_RUNTIME)
--- /dev/null
+From 32412565c27d63e15f25e76d86ee04c29b201b96 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 19 Aug 2024 15:20:42 +0200
+Subject: [PATCH] udp: fix receiving fraglist GSO packets
+
+When assembling fraglist GSO packets, udp4_gro_complete does not set
+skb->csum_start, which makes the extra validation in __udp_gso_segment fail.
+
+Fixes: 89add40066f9 ("net: drop bad gso csum_start and offset in virtio_net_hdr")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+ net/ipv4/udp_offload.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -279,7 +279,8 @@ struct sk_buff *__udp_gso_segment(struct
+ return ERR_PTR(-EINVAL);
+
+ if (unlikely(skb_checksum_start(gso_skb) !=
+- skb_transport_header(gso_skb)))
++ skb_transport_header(gso_skb) &&
++ !(skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)))
+ return ERR_PTR(-EINVAL);
+
+ /* We don't know if egress device can segment and checksum the packet
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
-@@ -178,61 +245,76 @@ out:
+@@ -181,61 +248,76 @@ out:
return segs;
}
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -269,6 +351,19 @@ found:
+@@ -272,6 +354,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -290,7 +385,6 @@ out_check_final:
+@@ -293,7 +388,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -314,18 +408,58 @@ void tcp_gro_complete(struct sk_buff *sk
+@@ -317,18 +411,58 @@ void tcp_gro_complete(struct sk_buff *sk
}
EXPORT_SYMBOL(tcp_gro_complete);
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -333,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -336,6 +470,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -447,33 +447,6 @@ out:
+@@ -451,33 +451,6 @@ out:
return segs;
}
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -8267,7 +8267,7 @@ static int nft_register_flowtable_net_ho
+@@ -8279,7 +8279,7 @@ static int nft_register_flowtable_net_ho
err = flowtable->data.type->setup(&flowtable->data,
hook->ops.dev,
FLOW_BLOCK_BIND);
* CONFIG_CMDLINE is meant to be a default in case nothing else
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
-@@ -2269,6 +2269,14 @@ config CMDLINE_FORCE
+@@ -2307,6 +2307,14 @@ config CMDLINE_FORCE
endchoice
#include <media/v4l2-common.h>
-@@ -1246,9 +1251,149 @@ static void uvc_video_decode_data(struct
+@@ -1275,9 +1280,149 @@ static void uvc_video_decode_data(struct
uvc_urb->async_operations++;
}
/* Mark the buffer as done if the EOF marker is set. */
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
uvc_dbg(stream->dev, FRAME, "Frame complete (EOF found)\n");
-@@ -1830,6 +1975,8 @@ static int uvc_init_video_isoc(struct uv
+@@ -1859,6 +2004,8 @@ static int uvc_init_video_isoc(struct uv
if (npackets == 0)
return -ENOMEM;