From: Greg Kroah-Hartman Date: Wed, 5 Aug 2026 12:07:33 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.10.263~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30632f6ef825acaaa34d21fb620961d6adc3796f;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch can-peak_usb-add-bounds-check-for-usb-channel-index.patch can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch can-peak_usb-validate-ucan-receive-record-lengths.patch can-softing-fw_parse-validate-firmware-record-spans.patch drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch --- diff --git a/queue-5.10/can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch b/queue-5.10/can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch new file mode 100644 index 0000000000..ad45991f8a --- /dev/null +++ b/queue-5.10/can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch @@ -0,0 +1,40 @@ +From eb96c58907922546e415e545fe9a14ea63b02719 Mon Sep 17 00:00:00 2001 +From: Oleksij Rempel +Date: Tue, 28 Jul 2026 07:58:35 +0200 +Subject: can: j1939: transport: j1939_session_fresh_new(): initialize receive buffer + +From: Oleksij Rempel + +commit eb96c58907922546e415e545fe9a14ea63b02719 upstream. + +Zero the allocated buffer in j1939_session_fresh_new() to ensure it +contains no residual data. + +While there is a potential performance impact if users allocate maximum +sized ETP buffers, most real-world use cases are not noticeably affected +since the maximum known buffer size is typically around 65K. + +Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") +Reported-by: Ji'an Zhou +Message-ID: +Signed-off-by: Oleksij Rempel +Link: https://patch.msgid.link/20260728055835.1151785-3-o.rempel@pengutronix.de +Cc: stable@kernel.org +[mkl: add Message-ID] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + net/can/j1939/transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1546,7 +1546,7 @@ j1939_session *j1939_session_fresh_new(s + } + + /* alloc data area */ +- skb_put(skb, size); ++ skb_put_zero(skb, size); + /* skb is recounted in j1939_session_new() */ + return session; + } diff --git a/queue-5.10/can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch b/queue-5.10/can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch new file mode 100644 index 0000000000..2993fd9780 --- /dev/null +++ b/queue-5.10/can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch @@ -0,0 +1,33 @@ +From 941eaf9a6d3b33dea49f2c0a1da7546a03b6ff71 Mon Sep 17 00:00:00 2001 +From: Abdun Nihaal +Date: Wed, 22 Jul 2026 16:09:03 +0530 +Subject: can: kvaser_usb: kvaser_usb_hydra_get_busparams(): fix memory leak in kvaser_usb_hydra_get_busparams() + +From: Abdun Nihaal + +commit 941eaf9a6d3b33dea49f2c0a1da7546a03b6ff71 upstream. + +The memory allocated for cmd is not freed after the call to +kvaser_usb_send_cmd() in both the normal and error paths. +Fix that by adding a kfree() immediately after the call. + +Fixes: 39d3df6b0ea8 ("can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming") +Cc: stable@vger.kernel.org +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20260722103906.108571-1-nihaal@cse.iitm.ac.in +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +@@ -1582,6 +1582,7 @@ static int kvaser_usb_hydra_get_busparam + reinit_completion(&priv->get_busparams_comp); + + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); ++ kfree(cmd); + if (err) + return err; + diff --git a/queue-5.10/can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch b/queue-5.10/can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch new file mode 100644 index 0000000000..6514a67c37 --- /dev/null +++ b/queue-5.10/can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch @@ -0,0 +1,63 @@ +From 0293dd153f9dbc1ddf5dacdccc76b363bce4a8ee Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Wed, 22 Jul 2026 12:22:21 +0800 +Subject: can: kvaser_usb_leaf: kvaser_usb_leaf_wait_cmd(): validate received command extents + +From: Pengpeng Hou + +commit 0293dd153f9dbc1ddf5dacdccc76b363bce4a8ee upstream. + +The wait and bulk receive paths walk variable-length commands from a +USB buffer. A nonzero command shorter than CMD_HEADER_LEN can still be +dispatched, and the wait path copies a matching command into a fixed +caller-owned struct kvaser_cmd using the device-provided length. + +Reject nonzero commands that do not contain the fixed header or that +extend beyond the current USB buffer item. In the wait path, also reject +a matching command that exceeds the destination before copying it. + +Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") +Signed-off-by: Pengpeng Hou +Link: https://patch.msgid.link/20260722042221.44066-1-pengpeng@iscas.ac.cn +Cc: stable@kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c ++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +@@ -615,13 +615,22 @@ static int kvaser_usb_leaf_wait_cmd(cons + continue; + } + +- if (pos + tmp->len > actual_len) { ++ if (tmp->len < CMD_HEADER_LEN || ++ tmp->len > actual_len - pos) { + dev_err_ratelimited(&dev->intf->dev, + "Format error\n"); + break; + } + + if (tmp->id == id) { ++ if (tmp->len > sizeof(*cmd)) { ++ dev_err_ratelimited(&dev->intf->dev, ++ "Received command %u too large (%u)\n", ++ tmp->id, tmp->len); ++ err = -EIO; ++ goto end; ++ } ++ + memcpy(cmd, tmp, tmp->len); + goto end; + } +@@ -1576,7 +1585,7 @@ static void kvaser_usb_leaf_read_bulk_ca + continue; + } + +- if (pos + cmd->len > len) { ++ if (cmd->len < CMD_HEADER_LEN || cmd->len > len - pos) { + dev_err_ratelimited(&dev->intf->dev, "Format error\n"); + break; + } diff --git a/queue-5.10/can-peak_usb-add-bounds-check-for-usb-channel-index.patch b/queue-5.10/can-peak_usb-add-bounds-check-for-usb-channel-index.patch new file mode 100644 index 0000000000..c8af474dac --- /dev/null +++ b/queue-5.10/can-peak_usb-add-bounds-check-for-usb-channel-index.patch @@ -0,0 +1,74 @@ +From 39132f166ca8ce00ae60d8a9068e06a60943cc4b Mon Sep 17 00:00:00 2001 +From: James Gao +Date: Wed, 20 May 2026 13:40:03 +0800 +Subject: can: peak_usb: add bounds check for USB channel index + +From: James Gao + +commit 39132f166ca8ce00ae60d8a9068e06a60943cc4b upstream. + +The channel control index ctrl_idx is derived from rx->len which comes +directly from a device USB payload. The mask 0x0f allows values 0-15, but +the array size of usb_if->dev[] is only 2. Values 2-15 cause heap +out-of-bounds read, eventually causing kernel panic in the IRQ context. + +Add bounds checking for ctrl_idx before the array access in both +pcan_usb_pro_handle_canmsg() and pcan_usb_pro_handle_error(). + +Fixes: d8a199355f8f ("can: usb: PEAK-System Technik PCAN-USB Pro specific part") +Signed-off-by: James Gao +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/TYWPR01MB8559DBAAAA6A7F410400329CF0012@TYWPR01MB8559.jpnprd01.prod.outlook.com +Cc: stable@kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +@@ -521,12 +521,18 @@ static int pcan_usb_pro_handle_canmsg(st + struct pcan_usb_pro_rxmsg *rx) + { + const unsigned int ctrl_idx = (rx->len >> 4) & 0x0f; +- struct peak_usb_device *dev = usb_if->dev[ctrl_idx]; +- struct net_device *netdev = dev->netdev; ++ struct peak_usb_device *dev; ++ struct net_device *netdev; + struct can_frame *can_frame; + struct sk_buff *skb; + struct skb_shared_hwtstamps *hwts; + ++ if (ctrl_idx >= ARRAY_SIZE(usb_if->dev)) ++ return -EINVAL; ++ ++ dev = usb_if->dev[ctrl_idx]; ++ netdev = dev->netdev; ++ + skb = alloc_can_skb(netdev, &can_frame); + if (!skb) + return -ENOMEM; +@@ -558,14 +564,20 @@ static int pcan_usb_pro_handle_error(str + { + const u16 raw_status = le16_to_cpu(er->status); + const unsigned int ctrl_idx = (er->channel >> 4) & 0x0f; +- struct peak_usb_device *dev = usb_if->dev[ctrl_idx]; +- struct net_device *netdev = dev->netdev; ++ struct peak_usb_device *dev; ++ struct net_device *netdev; + struct can_frame *can_frame; + enum can_state new_state = CAN_STATE_ERROR_ACTIVE; + u8 err_mask = 0; + struct sk_buff *skb; + struct skb_shared_hwtstamps *hwts; + ++ if (ctrl_idx >= ARRAY_SIZE(usb_if->dev)) ++ return -EINVAL; ++ ++ dev = usb_if->dev[ctrl_idx]; ++ netdev = dev->netdev; ++ + /* nothing should be sent while in BUS_OFF state */ + if (dev->can.state == CAN_STATE_BUS_OFF) + return 0; diff --git a/queue-5.10/can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch b/queue-5.10/can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch new file mode 100644 index 0000000000..08c85eb292 --- /dev/null +++ b/queue-5.10/can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch @@ -0,0 +1,51 @@ +From 9b3d5a6d952c38bbcf07f903cbeadefdb56b9bc9 Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Wed, 17 Jun 2026 02:15:31 +0800 +Subject: can: peak_usb: peak_usb_start(): fix double free of transfer buffer on URB submit error + +From: Maoyi Xie + +commit 9b3d5a6d952c38bbcf07f903cbeadefdb56b9bc9 upstream. + +In peak_usb_start(), each RX URB transfer buffer is allocated with kmalloc() +and the URB is flagged URB_FREE_BUFFER so that the final usb_free_urb() also +frees the transfer buffer. + +If usb_submit_urb() fails, the error path frees the buffer explicitly with +kfree(buf) and then calls usb_free_urb(urb). Because URB_FREE_BUFFER is set, +usb_free_urb() -> urb_destroy() frees the same buffer a second time, a double +free of the transfer buffer. + + BUG: KASAN: double-free in usb_free_urb.part.0+0x91/0xb0 + Free of addr ffff8881069ccb80 by task trigger.sh/285 + + Call Trace: + kfree+0x113/0x3c0 + usb_free_urb.part.0+0x91/0xb0 + +Drop the redundant kfree(buf); usb_free_urb() already releases the transfer +buffer. This mirrors commit 03819abbeb11 ("net: usb: lan78xx: Fix double free +issue with interrupt buffer allocation"). + +Fixes: bb4785551f64 ("can: usb: PEAK-System Technik USB adapters driver core") +Closes: https://lore.kernel.org/linux-can/178159320216.2154888.16953451793788581739@maoyixie.com/T/#u +Cc: stable@vger.kernel.org +Signed-off-by: Maoyi Xie +Reviewed-by: Vincent Mailhol +Link: https://patch.msgid.link/178163373110.2507866.216458825145756798@maoyixie.com +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/peak_usb/pcan_usb_core.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c +@@ -444,7 +444,6 @@ static int peak_usb_start(struct peak_us + netif_device_detach(dev->netdev); + + usb_unanchor_urb(urb); +- kfree(buf); + usb_free_urb(urb); + break; + } diff --git a/queue-5.10/can-peak_usb-validate-ucan-receive-record-lengths.patch b/queue-5.10/can-peak_usb-validate-ucan-receive-record-lengths.patch new file mode 100644 index 0000000000..03781e9d45 --- /dev/null +++ b/queue-5.10/can-peak_usb-validate-ucan-receive-record-lengths.patch @@ -0,0 +1,100 @@ +From 93fcab2c6968446316bbb49548848df604d6346f Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Mon, 6 Jul 2026 17:28:36 +0800 +Subject: can: peak_usb: validate uCAN receive record lengths + +From: Pengpeng Hou + +commit 93fcab2c6968446316bbb49548848df604d6346f upstream. + +pcan_usb_fd_decode_buf() walks uCAN records packed in one USB +receive buffer. + +Require each record to contain the fixed header for its type, and verify +CAN payload bytes before copying them into the skb. + +Signed-off-by: Pengpeng Hou +Link: https://patch.msgid.link/20260706092836.79754-1-pengpeng@iscas.ac.cn +Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters") +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 40 ++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c ++++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +@@ -502,6 +502,13 @@ static int pcan_usb_fd_decode_canmsg(str + cfd->len = get_can_dlc(pucan_msg_get_dlc(rm)); + } + ++ if (!(rx_msg_flags & PUCAN_MSG_RTR) && ++ le16_to_cpu(rx_msg->size) - offsetof(struct pucan_rx_msg, d) < ++ cfd->len) { ++ kfree_skb(skb); ++ return -EBADMSG; ++ } ++ + cfd->can_id = le32_to_cpu(rm->can_id); + + if (rx_msg_flags & PUCAN_MSG_EXT_ID) +@@ -651,6 +658,24 @@ static void pcan_usb_fd_decode_ts(struct + peak_usb_set_ts_now(&usb_if->time_ref, le32_to_cpu(ts->ts_low)); + } + ++static size_t pcan_usb_fd_rx_msg_min_size(u16 rx_msg_type) ++{ ++ switch (rx_msg_type) { ++ case PUCAN_MSG_CAN_RX: ++ return offsetof(struct pucan_rx_msg, d); ++ case PCAN_UFD_MSG_CALIBRATION: ++ return sizeof(struct pcan_ufd_ts_msg); ++ case PUCAN_MSG_ERROR: ++ return sizeof(struct pucan_error_msg); ++ case PUCAN_MSG_STATUS: ++ return sizeof(struct pucan_status_msg); ++ case PCAN_UFD_MSG_OVERRUN: ++ return sizeof(struct pcan_ufd_ovr_msg); ++ default: ++ return sizeof(struct pucan_msg); ++ } ++} ++ + /* callback for bulk IN urb */ + static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb) + { +@@ -665,6 +690,12 @@ static int pcan_usb_fd_decode_buf(struct + msg_end = urb->transfer_buffer + urb->actual_length; + for (; msg_ptr < msg_end;) { + u16 rx_msg_type, rx_msg_size; ++ size_t rx_msg_min_size; ++ ++ if (msg_end - msg_ptr < sizeof(*rx_msg)) { ++ err = -EBADMSG; ++ break; ++ } + + rx_msg = (struct pucan_msg *)msg_ptr; + if (!rx_msg->size) { +@@ -676,12 +707,19 @@ static int pcan_usb_fd_decode_buf(struct + rx_msg_type = le16_to_cpu(rx_msg->type); + + /* check if the record goes out of current packet */ +- if (msg_ptr + rx_msg_size > msg_end) { ++ if (rx_msg_size > msg_end - msg_ptr) { + netdev_err(netdev, + "got frag rec: should inc usb rx buf sze\n"); + err = -EBADMSG; + break; + } ++ ++ rx_msg_min_size = pcan_usb_fd_rx_msg_min_size(rx_msg_type); ++ if (rx_msg_size < rx_msg_min_size) { ++ netdev_err(netdev, "got short rec\n"); ++ err = -EBADMSG; ++ break; ++ } + + switch (rx_msg_type) { + case PUCAN_MSG_CAN_RX: diff --git a/queue-5.10/can-softing-fw_parse-validate-firmware-record-spans.patch b/queue-5.10/can-softing-fw_parse-validate-firmware-record-spans.patch new file mode 100644 index 0000000000..d71f570d8b --- /dev/null +++ b/queue-5.10/can-softing-fw_parse-validate-firmware-record-spans.patch @@ -0,0 +1,158 @@ +From 856d6cb04e5407523566b075841dcd6423757d1c Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Wed, 22 Jul 2026 12:43:47 +0800 +Subject: can: softing: fw_parse(): validate firmware record spans + +From: Pengpeng Hou + +commit 856d6cb04e5407523566b075841dcd6423757d1c upstream. + +fw_parse() reads a fixed record header, a firmware-provided payload, +and a trailing checksum without knowing the end of the firmware blob. A +truncated record can therefore make those reads exceed the blob. + +The same record also supplies addresses and lengths for writes into +DPRAM. The generic loader uses wrap-prone mixed signed arithmetic for its +bounds check, while the application loader does not bound the staging +copy at all. + +Pass the firmware end to the parser and validate the full source record. +Use a signed wide offset for generic DPRAM records and validate the +application staging span against the mapped DPRAM before copying. + +Fixes: 03fd3cf5a179 ("can: add driver for Softing card") +Signed-off-by: Pengpeng Hou +Link: https://patch.msgid.link/20260722044347.2708-1-pengpeng@iscas.ac.cn +Cc: stable@kernel.org +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/softing/softing_fw.c | 46 ++++++++++++++++++++++++----------- + 1 file changed, 32 insertions(+), 14 deletions(-) + +--- a/drivers/net/can/softing/softing_fw.c ++++ b/drivers/net/can/softing/softing_fw.c +@@ -91,12 +91,12 @@ int softing_bootloader_command(struct so + return ret; + } + +-static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr, +- uint16_t *plen, const uint8_t **pdat) ++static int fw_parse(const u8 **pmem, const u8 *limit, u16 *ptype, ++ u32 *paddr, u16 *plen, const u8 **pdat) + { + uint16_t checksum[2]; +- const uint8_t *mem; +- const uint8_t *end; ++ const u8 *mem; ++ const u8 *record_end; + + /* + * firmware records are a binary, unaligned stream composed of: +@@ -114,14 +114,21 @@ static int fw_parse(const uint8_t **pmem + * endianness & alignment. + */ + mem = *pmem; ++ /* A record needs an 8-byte prefix and a 2-byte checksum. */ ++ if (mem > limit || limit - mem < 10) ++ return -EINVAL; ++ + *ptype = le16_to_cpup((void *)&mem[0]); + *paddr = le32_to_cpup((void *)&mem[2]); + *plen = le16_to_cpup((void *)&mem[6]); ++ if (*plen > limit - mem - 10) ++ return -EINVAL; ++ + *pdat = &mem[8]; + /* verify checksum */ +- end = &mem[8 + *plen]; +- checksum[0] = le16_to_cpup((void *)end); +- for (checksum[1] = 0; mem < end; ++mem) ++ record_end = &mem[8 + *plen]; ++ checksum[0] = le16_to_cpup((void *)record_end); ++ for (checksum[1] = 0; mem < record_end; ++mem) + checksum[1] += *mem; + if (checksum[0] != checksum[1]) + return -EINVAL; +@@ -139,6 +146,7 @@ int softing_load_fw(const char *file, st + uint16_t type, len; + uint32_t addr; + uint8_t *buf = NULL, *new_buf; ++ s64 dpram_offset; + int buflen = 0; + int8_t type_end = 0; + +@@ -153,7 +161,7 @@ int softing_load_fw(const char *file, st + mem = fw->data; + end = &mem[fw->size]; + /* look for header record */ +- ret = fw_parse(&mem, &type, &addr, &len, &dat); ++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat); + if (ret < 0) + goto failed; + if (type != 0xffff) +@@ -164,7 +172,7 @@ int softing_load_fw(const char *file, st + } + /* ok, we had a header */ + while (mem < end) { +- ret = fw_parse(&mem, &type, &addr, &len, &dat); ++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat); + if (ret < 0) + goto failed; + if (type == 3) { +@@ -179,9 +187,13 @@ int softing_load_fw(const char *file, st + goto failed; + } + +- if ((addr + len + offset) > size) ++ dpram_offset = (s64)addr + offset; ++ if (dpram_offset < 0 || dpram_offset > size || ++ len > size - dpram_offset) { ++ ret = -EINVAL; + goto failed; +- memcpy_toio(&dpram[addr + offset], dat, len); ++ } ++ memcpy_toio(&dpram[dpram_offset], dat, len); + /* be sure to flush caches from IO space */ + mb(); + if (len > buflen) { +@@ -195,7 +207,7 @@ int softing_load_fw(const char *file, st + buf = new_buf; + } + /* verify record data */ +- memcpy_fromio(buf, &dpram[addr + offset], len); ++ memcpy_fromio(buf, &dpram[dpram_offset], len); + if (memcmp(buf, dat, len)) { + /* is not ok */ + dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); +@@ -237,7 +249,7 @@ int softing_load_app_fw(const char *file + mem = fw->data; + end = &mem[fw->size]; + /* look for header record */ +- ret = fw_parse(&mem, &type, &addr, &len, &dat); ++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat); + if (ret) + goto failed; + ret = -EINVAL; +@@ -253,7 +265,7 @@ int softing_load_app_fw(const char *file + } + /* ok, we had a header */ + while (mem < end) { +- ret = fw_parse(&mem, &type, &addr, &len, &dat); ++ ret = fw_parse(&mem, end, &type, &addr, &len, &dat); + if (ret) + goto failed; + +@@ -279,6 +291,12 @@ int softing_load_app_fw(const char *file + /* work in 16bit (target) */ + sum &= 0xffff; + ++ if (card->pdat->app.offs > card->dpram_size || ++ len > card->dpram_size - card->pdat->app.offs) { ++ ret = -EINVAL; ++ goto failed; ++ } ++ + memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); + iowrite32(card->pdat->app.offs + card->pdat->app.addr, + &card->dpram[DPRAM_COMMAND + 2]); diff --git a/queue-5.10/drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch b/queue-5.10/drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch new file mode 100644 index 0000000000..b3c9fcbfef --- /dev/null +++ b/queue-5.10/drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch @@ -0,0 +1,60 @@ +From 5e70f6804b4d6256058c360b10e044ee04ea4a4e Mon Sep 17 00:00:00 2001 +From: Harkirat Gill +Date: Mon, 27 Jul 2026 14:37:56 -0400 +Subject: drm/amdgpu: cap GTT size to physical RAM on APUs + +From: Harkirat Gill + +commit 5e70f6804b4d6256058c360b10e044ee04ea4a4e upstream. + +On APUs, the GTT pool is backed by system RAM, but its size is not bound +to the non-carveout memory that actually backs it. A user can end up +with GTT + VRAM exceeding total physical memory through the following +sequence: + + - Have a large non-carveout memory space (~128GB) and accordingly set a + large GTT (~100GB) via the ttm module parameter. + - Lower the non-carveout memory space in BIOS by increasing the UMA + Frame Buffer Size (VRAM) to 64GB. + - The previously set GTT value (~100GB) persists, even though the new + non-carveout space (64GB) can no longer back it. + +This leads to a case where kernel reports GTT (100GB) + VRAM (64GB) +despite the sum being greater than total physical memory (128GB). + +Cap the GTT size to totalram_pages() on APUs. totalram_pages() already +excludes the VRAM carveout, so the resulting GTT can never exceed the +system RAM that actually backs it. + +Signed-off-by: Harkirat Gill +Reviewed-by: David Francis +Assisted-by: Claude:claude-opus-4 +Signed-off-by: Alex Deucher +(cherry picked from commit 5dafdd649280c7dc6c22c8f877da3f54fcc441e1) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -1979,6 +1979,18 @@ int amdgpu_ttm_init(struct amdgpu_device + else + gtt_size = (uint64_t)amdgpu_gtt_size << 20; + ++ /* Cap GTT so that it does not exceed total physical RAM. */ ++ if (adev->flags & AMD_IS_APU) { ++ u64 phys_ram = (u64)totalram_pages() << PAGE_SHIFT; ++ ++ if (gtt_size > phys_ram) { ++ gtt_size = phys_ram; ++ dev_info(adev->dev, ++ "Capping GTT to %uM to not exceed available system memory\n", ++ (unsigned int)(gtt_size / (1024 * 1024))); ++ } ++ } ++ + /* Initialize GTT memory pool */ + r = amdgpu_gtt_mgr_init(adev, gtt_size); + if (r) { diff --git a/queue-5.10/drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch b/queue-5.10/drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch new file mode 100644 index 0000000000..eeae3bb027 --- /dev/null +++ b/queue-5.10/drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch @@ -0,0 +1,95 @@ +From 48a570c964d8e37d353381e4195106277e17f5cb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ma=C3=ADra=20Canal?= +Date: Mon, 27 Jul 2026 11:32:29 -0300 +Subject: drm/vc4: Zero the tile state data array before each BIN job +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maíra Canal + +commit 48a570c964d8e37d353381e4195106277e17f5cb upstream. + +The binner BO is a single 16MB buffer split into 512KB slots that are +handed out to jobs at submission time and recycled as jobs complete, +without ever being cleared. Each slot holds the job's Tile State Data +Array (TSDA) at its start, followed by the tile allocation pool. + +While the tile allocation pool is only walked by the render thread +through branches the binner generated during the current job, the +TSDA is the PTB's own per-tile bookkeeping and is consumed by the +hardware itself. Although the kernel sets the "Auto-initialise Tile +State Data Array" flag in the tile binning mode configuration, the +PTB demonstrably still acts on stale tile state left by the slot's +previous user: the binner ends up creating invalid command streams +with invalid primitive streams and branches, which can cause GPU hangs +as observed in [1][2]. + +Zero the TSDA when the job's binning slot is configured. This clears +48 bytes per tile (~24KB for a 1080p frame) in the submission path, and +guarantees the PTB never sees another job's tile state. + +The tile count is only checked for being non-zero today, so the 8-bit +fields it comes from can describe a tile state array almost six times +larger than the slot it has to live in. Bound it before the slot is +handed out, since such size decides how much of the slot is left for +the tile alloc pool. + +Link: https://github.com/raspberrypi/linux/issues/3221 [1] +Link: https://github.com/raspberrypi/linux/issues/5780 [2] +Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.") +Cc: stable@vger.kernel.org +Reviewed-by: Iago Toral Quiroga +Link: https://patch.msgid.link/20260727-vc4-bin-oom-fixes-v2-2-0d8a5eddc7c9@igalia.com +Signed-off-by: Maíra Canal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/vc4/vc4_validate.c | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_validate.c ++++ b/drivers/gpu/drm/vc4/vc4_validate.c +@@ -379,6 +379,23 @@ validate_tile_binning_config(VALIDATE_AR + return -EINVAL; + } + ++ /* The tile state data array is 48 bytes per tile, and we put it at ++ * the start of a BO containing both it and the tile alloc. ++ */ ++ tile_state_size = 48 * tile_count; ++ ++ /* Since the tile alloc array will follow us, align. */ ++ tile_state_size = roundup(tile_state_size, 4096); ++ ++ /* Reject configurations whose tile state would leave no room for ++ * the tile alloc pool that follows it in the slot. ++ */ ++ if (tile_state_size >= vc4->bin_alloc_size) { ++ DRM_DEBUG("Tile binning config of %dx%d too large\n", ++ exec->bin_tiles_x, exec->bin_tiles_y); ++ return -EINVAL; ++ } ++ + bin_slot = vc4_v3d_get_bin_slot(vc4); + if (bin_slot < 0) { + if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) { +@@ -394,13 +411,13 @@ validate_tile_binning_config(VALIDATE_AR + exec->bin_slots |= BIT(bin_slot); + bin_addr = vc4->bin_bo->base.paddr + bin_slot * vc4->bin_alloc_size; + +- /* The tile state data array is 48 bytes per tile, and we put it at +- * the start of a BO containing both it and the tile alloc. +- */ +- tile_state_size = 48 * tile_count; ++ exec->tile_alloc_offset = bin_addr + tile_state_size; + +- /* Since the tile alloc array will follow us, align. */ +- exec->tile_alloc_offset = bin_addr + roundup(tile_state_size, 4096); ++ /* The TSDA area must be zeroed out before use, otherwise the PTB might ++ * consume a stale tile state. ++ */ ++ memset(vc4->bin_bo->base.vaddr + bin_slot * vc4->bin_alloc_size, 0, ++ tile_state_size); + + *(uint8_t *)(validated + 14) = + ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK | diff --git a/queue-5.10/series b/queue-5.10/series index 89a1b2c462..f22a7dd428 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -288,3 +288,12 @@ phy-zynqmp-keep-serdes-scrambler-and-8b-10b-enabled-for-usb.patch net-openvswitch-fix-potential-uaf-on-meter-attach-failure.patch net-openvswitch-fix-skb-leak-on-flow-key-update-failure-during-ct.patch i2c-jz4780-cache-host-clock-rate-at-probe-to-prevent-ccf-prepare_lock-deadlock.patch +can-j1939-transport-j1939_session_fresh_new-initialize-receive-buffer.patch +can-kvaser_usb-kvaser_usb_hydra_get_busparams-fix-memory-leak-in-kvaser_usb_hydra_get_busparams.patch +can-kvaser_usb_leaf-kvaser_usb_leaf_wait_cmd-validate-received-command-extents.patch +can-softing-fw_parse-validate-firmware-record-spans.patch +can-peak_usb-add-bounds-check-for-usb-channel-index.patch +can-peak_usb-peak_usb_start-fix-double-free-of-transfer-buffer-on-urb-submit-error.patch +can-peak_usb-validate-ucan-receive-record-lengths.patch +drm-vc4-zero-the-tile-state-data-array-before-each-bin-job.patch +drm-amdgpu-cap-gtt-size-to-physical-ram-on-apus.patch