--- /dev/null
+From a7511dcd9dd4bc55d123f9b800c8a4ed2662e5c6 Mon Sep 17 00:00:00 2001
+From: Stepan Ionichev <sozdayvek@gmail.com>
+Date: Thu, 14 May 2026 22:43:42 +0500
+Subject: auxdisplay: line-display: fix OOB read on zero-length message_store()
+
+From: Stepan Ionichev <sozdayvek@gmail.com>
+
+commit a7511dcd9dd4bc55d123f9b800c8a4ed2662e5c6 upstream.
+
+linedisp_display() unconditionally reads msg[count - 1] before
+checking whether count is zero, so a write of zero bytes to the
+message sysfs attribute hits msg[-1]:
+
+ write(fd, "", 0);
+
+ -> message_store(..., buf, count=0)
+ -> linedisp_display(linedisp, buf, count=0)
+ -> msg[count - 1] == '\n' ; OOB read
+
+The kernfs write buffer for that store is a 1-byte allocation
+(kernfs_fop_write_iter() does kmalloc(len + 1) with len == 0),
+so msg[-1] is a 1-byte read before the slab object. On a
+KASAN-enabled kernel this trips an out-of-bounds report and
+panics; on stock kernels it silently reads adjacent slab data
+and, if that byte happens to be '\n', the following count--
+wraps ssize_t 0 to -1 and is then passed to kmemdup_nul().
+
+linedisp_display() is reached from the message_store() sysfs
+callback (drivers/auxdisplay/line-display.c message attribute,
+mode 0644) and from the in-tree initial-message setup with
+count == -1, so the OOB path is only userspace-triggerable via
+zero-byte writes; vfs_write() does not short-circuit on
+count == 0 and kernfs_fop_write_iter() dispatches the store
+callback regardless.
+
+Guard the trailing-newline trim with a count check. The
+existing if (!count) block then takes the clear-display path
+unchanged.
+
+Affects every auxdisplay driver that registers via
+linedisp_register() / linedisp_attach(): ht16k33, max6959,
+img-ascii-lcd, seg-led-gpio.
+
+Fixes: 7e76aece6f03 ("auxdisplay: Extract character line display core support")
+Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/auxdisplay/line-display.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/auxdisplay/line-display.c
++++ b/drivers/auxdisplay/line-display.c
+@@ -173,7 +173,7 @@ static int linedisp_display(struct lined
+ count = strlen(msg);
+
+ /* if the string ends with a newline, trim it */
+- if (msg[count - 1] == '\n')
++ if (count && msg[count - 1] == '\n')
+ count--;
+
+ if (!count) {
--- /dev/null
+From bfa9d28960ed677d556bdf097073bc3129686229 Mon Sep 17 00:00:00 2001
+From: Pavitra Jha <jhapavitra98@gmail.com>
+Date: Thu, 21 May 2026 04:04:14 -0400
+Subject: Bluetooth: hci_conn: Fix memory leak in hci_le_big_terminate()
+
+From: Pavitra Jha <jhapavitra98@gmail.com>
+
+commit bfa9d28960ed677d556bdf097073bc3129686229 upstream.
+
+hci_le_big_terminate() allocates iso_list_data via kzalloc_obj but
+returns 0 without freeing it when neither pa_sync_term nor big_sync_term
+flags are set after evaluating the PA and BIG sync connection state.
+
+This early-return path was introduced when hci_le_big_terminate() was
+refactored to take struct hci_conn instead of raw u8 parameters, adding
+PA/BIG flag evaluation logic. The existing kfree() on hci_cmd_sync_queue
+failure does not cover this path.
+
+Fixes: a7bcffc673de ("Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavitra Jha <jhapavitra98@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_conn.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -803,8 +803,10 @@ static int hci_le_big_terminate(struct h
+ d->big_sync_term = true;
+ }
+
+- if (!d->pa_sync_term && !d->big_sync_term)
++ if (!d->pa_sync_term && !d->big_sync_term) {
++ kfree(d);
+ return 0;
++ }
+
+ ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
+ terminate_big_destroy);
--- /dev/null
+From fa21e86caba2347e89eb65af926205a36a097c53 Mon Sep 17 00:00:00 2001
+From: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+Date: Mon, 25 May 2026 14:51:56 +0800
+Subject: Bluetooth: hci_qca: Use 100 ms SSR delay for rampatch and NVM loading
+
+From: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+
+commit fa21e86caba2347e89eb65af926205a36a097c53 upstream.
+
+When bt_en is pulled high by hardware, the host does not re-download
+the firmware after SSR. The controller loads the rampatch and NVM
+internally.
+
+On HMT chip, the rampatch is ~264 KB and the NVM is ~9.4 KB. The
+loading process takes approximately 70 ms. The previous 50 ms delay is
+too short, causing the controller to not respond to the reset command
+sent by the host, which leads to BT initialization failure:
+
+ Bluetooth: hci0: QCA memdump Done, received 458752, total 458752
+ Bluetooth: hci0: mem_dump_status: 2
+ Bluetooth: hci0: Opcode 0x0c03 failed: -110
+
+Increase the delay to 100 ms, which was confirmed as a safe value by
+the controller, to ensure the controller has finished loading the
+firmware before the host sends commands.
+
+Steps to reproduce:
+1. Trigger SSR and wait for SSR to complete:
+ hcitool cmd 0x3f 0c 26
+2. Run "bluetoothctl power on" and observe that BT fails to start.
+
+Fixes: fce1a9244a0f ("Bluetooth: hci_qca: Fix SSR (SubSystem Restart) fail when BT_EN is pulled up by hw")
+Cc: stable@vger.kernel.org
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -1677,8 +1677,8 @@ static void qca_hw_error(struct hci_dev
+ mod_timer(&qca->tx_idle_timer, jiffies +
+ msecs_to_jiffies(qca->tx_idle_delay));
+
+- /* Controller reset completion time is 50ms */
+- msleep(50);
++ /* Wait for the controller to load the rampatch and NVM. */
++ msleep(100);
+
+ clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
+ clear_bit(QCA_IBS_DISABLED, &qca->flags);
--- /dev/null
+From bfea6091e0fffb270c20e74384b660910277eb6c Mon Sep 17 00:00:00 2001
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+Date: Mon, 25 May 2026 18:24:38 +0200
+Subject: Bluetooth: hci_sync: fix UAF in hci_le_create_cis_sync
+
+From: Doruk Tan Ozturk <doruk@0sec.ai>
+
+commit bfea6091e0fffb270c20e74384b660910277eb6c upstream.
+
+hci_le_create_cis_sync() dereferences conn->conn_timeout after releasing
+both rcu_read_lock() and hci_dev_lock(hdev). The conn pointer was
+obtained from an RCU-protected iteration over hdev->conn_hash.list and
+is not valid once these locks are dropped. A concurrent disconnect can
+free the hci_conn between the unlock and the dereference, causing a
+use-after-free read.
+
+The cancellation mechanism in hci_conn_del() cannot prevent this because
+hci_le_create_cis_pending() queues hci_create_cis_sync with data=NULL:
+
+ hci_cmd_sync_queue(hdev, hci_create_cis_sync, NULL, NULL);
+
+While hci_conn_del() dequeues with data=conn:
+
+ hci_cmd_sync_dequeue(hdev, NULL, conn, NULL);
+
+Since NULL != conn, the lookup in _hci_cmd_sync_lookup_entry() never
+matches, and the pending work item is not cancelled.
+
+Fix this by saving conn->conn_timeout into a local variable while the
+locks are still held, so the stale conn pointer is never dereferenced
+after unlock.
+
+This is the same class of bug as the one fixed by commit 035c25007c9e
+("Bluetooth: hci_sync: Fix UAF on le_read_features_complete") which
+addressed the identical pattern in a different function.
+
+This vulnerability was identified using 0sec.ai, an open-source
+automated security auditing platform (https://github.com/0sec-labs).
+
+Fixes: c09b80be6ffc ("Bluetooth: hci_conn: Fix not waiting for HCI_EVT_LE_CIS_ESTABLISHED")
+Cc: stable@vger.kernel.org
+Reported-by: Doruk Tan Ozturk <doruk@0sec.ai>
+Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_sync.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -6711,6 +6711,7 @@ int hci_le_create_cis_sync(struct hci_de
+ DEFINE_FLEX(struct hci_cp_le_create_cis, cmd, cis, num_cis, 0x1f);
+ size_t aux_num_cis = 0;
+ struct hci_conn *conn;
++ u16 timeout = 0;
+ u8 cig = BT_ISO_QOS_CIG_UNSET;
+
+ /* The spec allows only one pending LE Create CIS command at a time. If
+@@ -6781,6 +6782,7 @@ int hci_le_create_cis_sync(struct hci_de
+ set_bit(HCI_CONN_CREATE_CIS, &conn->flags);
+ cis->acl_handle = cpu_to_le16(conn->parent->handle);
+ cis->cis_handle = cpu_to_le16(conn->handle);
++ timeout = conn->conn_timeout;
+ aux_num_cis++;
+
+ if (aux_num_cis >= cmd->num_cis)
+@@ -6800,7 +6802,7 @@ done:
+ return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CIS,
+ struct_size(cmd, cis, cmd->num_cis),
+ cmd, HCI_EVT_LE_CIS_ESTABLISHED,
+- conn->conn_timeout, NULL);
++ timeout, NULL);
+ }
+
+ int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle)
--- /dev/null
+From 2a3ac9ee11dbb9845f3947cef4a79dba658cf6f6 Mon Sep 17 00:00:00 2001
+From: Muhammad Bilal <meatuni001@gmail.com>
+Date: Wed, 20 May 2026 18:56:43 -0400
+Subject: Bluetooth: HIDP: fix missing length checks in hidp_input_report()
+
+From: Muhammad Bilal <meatuni001@gmail.com>
+
+commit 2a3ac9ee11dbb9845f3947cef4a79dba658cf6f6 upstream.
+
+hidp_input_report() reads keyboard and mouse payload data from an skb
+without first verifying that skb->len contains enough data.
+
+hidp_recv_intr_frame() pulls the 1-byte HIDP header before dispatching
+to hidp_input_report(). If a paired device sends a truncated packet,
+the handler reads beyond the valid skb data, resulting in an
+out-of-bounds read of skb data. The OOB bytes may be interpreted as
+phantom key presses or spurious mouse movement.
+
+Replace the open-coded length tracking and pointer arithmetic with
+skb_pull_data() calls. skb_pull_data() returns NULL if the requested
+bytes are not present, eliminating the need for a manual size variable
+and the separate skb->len guard.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hidp/core.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/net/bluetooth/hidp/core.c
++++ b/net/bluetooth/hidp/core.c
+@@ -179,12 +179,21 @@ static void hidp_input_report(struct hid
+ {
+ struct input_dev *dev = session->input;
+ unsigned char *keys = session->keys;
+- unsigned char *udata = skb->data + 1;
+- signed char *sdata = skb->data + 1;
+- int i, size = skb->len - 1;
++ unsigned char *udata;
++ signed char *sdata;
++ u8 *hdr;
++ int i;
++
++ hdr = skb_pull_data(skb, 1);
++ if (!hdr)
++ return;
+
+- switch (skb->data[0]) {
++ switch (*hdr) {
+ case 0x01: /* Keyboard report */
++ udata = skb_pull_data(skb, 8);
++ if (!udata)
++ break;
++
+ for (i = 0; i < 8; i++)
+ input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
+
+@@ -213,6 +222,10 @@ static void hidp_input_report(struct hid
+ break;
+
+ case 0x02: /* Mouse report */
++ sdata = skb_pull_data(skb, 3);
++ if (!sdata)
++ break;
++
+ input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
+ input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
+ input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
+@@ -222,7 +235,7 @@ static void hidp_input_report(struct hid
+ input_report_rel(dev, REL_X, sdata[1]);
+ input_report_rel(dev, REL_Y, sdata[2]);
+
+- if (size > 3)
++ if (skb->len > 0)
+ input_report_rel(dev, REL_WHEEL, sdata[3]);
+ break;
+ }
--- /dev/null
+From 47f23a259517abbdb8032c057a1e8a6bf3734878 Mon Sep 17 00:00:00 2001
+From: Muhammad Bilal <meatuni001@gmail.com>
+Date: Wed, 27 May 2026 04:59:17 +0000
+Subject: Bluetooth: ISO: fix UAF in iso_recv_frame
+
+From: Muhammad Bilal <meatuni001@gmail.com>
+
+commit 47f23a259517abbdb8032c057a1e8a6bf3734878 upstream.
+
+iso_recv_frame reads conn->sk under iso_conn_lock but releases the lock
+before using sk, with no reference held. A concurrent iso_sock_kill()
+can free sk in that window, causing use-after-free on sk->sk_state and
+sock_queue_rcv_skb().
+
+Fix by replacing the bare pointer read with iso_sock_hold(conn), which
+calls sock_hold() while the spinlock is held, atomically elevating the
+refcount before the lock drops. Add a drop_put label so sock_put() is
+called on all exit paths where the hold succeeded.
+
+Fixes: ccf74f2390d60a2f9a75ef496d2564abb478f46a ("Bluetooth: Add BTPROTO_ISO socket type")
+Cc: stable@vger.kernel.org
+Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/iso.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -572,7 +572,7 @@ static void iso_recv_frame(struct iso_co
+ struct sock *sk;
+
+ iso_conn_lock(conn);
+- sk = conn->sk;
++ sk = iso_sock_hold(conn);
+ iso_conn_unlock(conn);
+
+ if (!sk)
+@@ -581,11 +581,15 @@ static void iso_recv_frame(struct iso_co
+ BT_DBG("sk %p len %d", sk, skb->len);
+
+ if (sk->sk_state != BT_CONNECTED)
+- goto drop;
++ goto drop_put;
+
+- if (!sock_queue_rcv_skb(sk, skb))
++ if (!sock_queue_rcv_skb(sk, skb)) {
++ sock_put(sk);
+ return;
++ }
+
++drop_put:
++ sock_put(sk);
+ drop:
+ kfree_skb(skb);
+ }
--- /dev/null
+From 4b5f8e608749b7e8fa386c6e4301cf9272595859 Mon Sep 17 00:00:00 2001
+From: Muhammad Bilal <meatuni001@gmail.com>
+Date: Wed, 27 May 2026 04:59:18 +0000
+Subject: Bluetooth: ISO: serialize iso_sock_clear_timer with socket lock
+
+From: Muhammad Bilal <meatuni001@gmail.com>
+
+commit 4b5f8e608749b7e8fa386c6e4301cf9272595859 upstream.
+
+iso_sock_close() calls iso_sock_clear_timer() before acquiring
+lock_sock(sk).
+
+iso_sock_clear_timer() reads iso_pi(sk)->conn twice without the
+socket lock held:
+
+ if (!iso_pi(sk)->conn)
+ return;
+ cancel_delayed_work(&iso_pi(sk)->conn->timeout_work);
+
+Concurrently, iso_conn_del() executes under lock_sock(sk) and calls
+iso_chan_del(), which sets iso_pi(sk)->conn to NULL and may result in
+the final reference to the connection being dropped:
+
+ CPU0 CPU1
+ ---- ----
+ iso_sock_clear_timer()
+ if (conn != NULL) ... lock_sock(sk)
+ iso_chan_del()
+ iso_pi(sk)->conn = NULL
+ cancel_delayed_work(conn) /* NULL deref or UAF */
+
+iso_pi(sk)->conn is not stable across the unlock window, causing a
+NULL pointer dereference or use-after-free.
+
+Serialize iso_sock_clear_timer() with the socket lock by moving it
+inside lock_sock()/release_sock(), matching the pattern used in
+iso_conn_del() and all other call sites.
+
+Fixes: ccf74f2390d60a2f9a75ef496d2564abb478f46a ("Bluetooth: Add BTPROTO_ISO socket type")
+Cc: stable@vger.kernel.org
+Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/iso.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -872,8 +872,8 @@ static void __iso_sock_close(struct sock
+ /* Must be called on unlocked socket. */
+ static void iso_sock_close(struct sock *sk)
+ {
+- iso_sock_clear_timer(sk);
+ lock_sock(sk);
++ iso_sock_clear_timer(sk);
+ __iso_sock_close(sk);
+ release_sock(sk);
+ iso_sock_kill(sk);
--- /dev/null
+From 9dbd84990394c51f5cee1e8871bb5ff8af5ed939 Mon Sep 17 00:00:00 2001
+From: Siwei Zhang <oss@fourdim.xyz>
+Date: Wed, 20 May 2026 22:30:36 -0400
+Subject: Bluetooth: L2CAP: fix chan ref leak in l2cap_chan_timeout() on !conn
+
+From: Siwei Zhang <oss@fourdim.xyz>
+
+commit 9dbd84990394c51f5cee1e8871bb5ff8af5ed939 upstream.
+
+__set_chan_timer() takes a l2cap_chan reference via l2cap_chan_hold()
+before scheduling the delayed work. The normal path in
+l2cap_chan_timeout() drops this reference with l2cap_chan_put() at the
+end, but the early return when chan->conn is NULL skips the put,
+leaking the reference.
+
+Add the missing l2cap_chan_put() before the early return.
+
+Fixes: adf0398cee86 ("Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout")
+Cc: stable@vger.kernel.org
+Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -411,8 +411,10 @@ static void l2cap_chan_timeout(struct wo
+
+ BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
+
+- if (!conn)
++ if (!conn) {
++ l2cap_chan_put(chan);
+ return;
++ }
+
+ mutex_lock(&conn->lock);
+ /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
--- /dev/null
+From 8c8e620467a7b51562dbcefbd1f09f288d7d710d Mon Sep 17 00:00:00 2001
+From: Siwei Zhang <oss@fourdim.xyz>
+Date: Wed, 20 May 2026 22:12:20 -0400
+Subject: Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()
+
+From: Siwei Zhang <oss@fourdim.xyz>
+
+commit 8c8e620467a7b51562dbcefbd1f09f288d7d710d upstream.
+
+l2cap_chan_close() removes the channel from conn->chan_l, which
+must be done under conn->lock. cleanup_listen() runs under the
+parent sk_lock, so acquiring conn->lock would invert the
+established conn->lock -> chan->lock -> sk_lock order.
+
+Instead of calling l2cap_chan_close() directly, schedule
+l2cap_chan_timeout with delay 0 to close the channel
+asynchronously. The timeout handler already acquires conn->lock
+and chan->lock in the correct order.
+
+The timer is only armed when chan->conn is still set: if it is
+already NULL, l2cap_conn_del() has already processed this channel
+(l2cap_chan_del + l2cap_sock_teardown_cb + l2cap_sock_close_cb),
+so there is nothing left to do. If l2cap_conn_del() races in
+after the timer is armed, __clear_chan_timer() inside
+l2cap_chan_del() cancels it; if the timer has already fired, the
+handler returns harmlessly because chan->conn was cleared.
+
+Fixes: 3df91ea20e74 ("Bluetooth: Revert to mutexes from RCU list")
+Cc: <stable@vger.kernel.org> # 0b58004: Bluetooth: fix UAF in l2cap_sock_cleanup_listen() vs l2cap_conn_del()
+Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_sock.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1499,6 +1499,10 @@ static void l2cap_sock_cleanup_listen(st
+ * pin it (hold_unless_zero() additionally skips a chan already past
+ * its last reference). We then drop the sk lock before taking
+ * chan->lock, so sk and chan locks are never held together.
++ *
++ * Since we cannot call l2cap_chan_close() without conn->lock,
++ * schedule l2cap_chan_timeout to close the channel; it already
++ * acquires conn->lock -> chan->lock in the correct order.
+ */
+ while ((sk = bt_accept_dequeue(parent, NULL))) {
+ struct l2cap_chan *chan;
+@@ -1516,14 +1520,12 @@ static void l2cap_sock_cleanup_listen(st
+ state_to_string(chan->state));
+
+ l2cap_chan_lock(chan);
+- __clear_chan_timer(chan);
+- l2cap_chan_close(chan, ECONNRESET);
+- /* l2cap_conn_del() may already have killed this socket
+- * (it sets SOCK_DEAD); skip the duplicate to avoid a
+- * double sock_put()/l2cap_chan_put().
++ /* Since we cannot call l2cap_chan_close() without
++ * conn->lock, schedule its timer to trigger the close
++ * and cleanup of this channel.
+ */
+- if (!sock_flag(sk, SOCK_DEAD))
+- l2cap_sock_kill(sk);
++ if (chan->conn)
++ __set_chan_timer(chan, 0);
+ l2cap_chan_unlock(chan);
+
+ l2cap_chan_put(chan);
--- /dev/null
+From 175db11786bde9061db526bf1ac5107d915f5163 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Sat, 16 May 2026 04:34:14 +0900
+Subject: Disable -Wattribute-alias for clang-23 and newer
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 175db11786bde9061db526bf1ac5107d915f5163 upstream.
+
+Clang recently added support for -Wattribute-alias [1], which results in
+the same warnings that necessitated commit bee20031772a ("disable
+-Wattribute-alias warning for SYSCALL_DEFINEx()") for GCC.
+
+ kernel/time/itimer.c:325:1: error: alias and aliasee have different types 'long (unsigned int)' and 'long (typeof (__builtin_choose_expr((__builtin_types_compatible_p(typeof ((unsigned int)0), typeof (0LL)) || __builtin_types_compatible_p(typeof ((unsigned int)0), typeof (0ULL))), 0LL, 0L)))' (aka 'long (long)') [-Werror,-Wattribute-alias]
+ 325 | SYSCALL_DEFINE1(alarm, unsigned int, seconds)
+ | ^
+ include/linux/syscalls.h:225:36: note: expanded from macro 'SYSCALL_DEFINE1'
+ 225 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
+ | ^
+ include/linux/syscalls.h:236:2: note: expanded from macro 'SYSCALL_DEFINEx'
+ 236 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+ | ^
+ include/linux/syscalls.h:251:18: note: expanded from macro '__SYSCALL_DEFINEx'
+ 251 | __attribute__((alias(__stringify(__se_sys##name)))); \
+ | ^
+ kernel/time/itimer.c:325:1: note: aliasee is declared here
+ include/linux/syscalls.h:225:36: note: expanded from macro 'SYSCALL_DEFINE1'
+ 225 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
+ | ^
+ include/linux/syscalls.h:236:2: note: expanded from macro 'SYSCALL_DEFINEx'
+ 236 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+ | ^
+ include/linux/syscalls.h:255:18: note: expanded from macro '__SYSCALL_DEFINEx'
+ 255 | asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ | ^
+ <scratch space>:16:1: note: expanded from here
+ 16 | __se_sys_alarm
+ | ^
+
+Disable the warnings in the same way for clang-23 and newer. Disable the
+warning about unknown warning options to avoid breaking the build for
+versions of clang-23 that do not have -Wattribute-alias, such as ones
+deployed by vendors like Android or CI systems or when bisecting LLVM
+between llvmorg-23-init and release/23.x.
+
+Cc: stable@vger.kernel.org
+Closes: https://github.com/ClangBuiltLinux/linux/issues/2163
+Link: https://github.com/llvm/llvm-project/commit/40da6920a0d71d49dfa2392b09153600b0759f5e [1]
+Link: https://patch.msgid.link/20260515-syscall-disable-attribute-alias-for-clang-v1-1-9a9d95d41df6@kernel.org
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/include/asm/syscall_wrapper.h | 4 ++++
+ include/linux/compat.h | 4 ++++
+ include/linux/compiler-clang.h | 6 ++++++
+ include/linux/compiler_types.h | 4 ++++
+ include/linux/syscalls.h | 4 ++++
+ 5 files changed, 22 insertions(+)
+
+--- a/arch/riscv/include/asm/syscall_wrapper.h
++++ b/arch/riscv/include/asm/syscall_wrapper.h
+@@ -32,6 +32,10 @@ asmlinkage long __riscv_sys_ni_syscall(c
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments"); \
++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \
++ "Avoid breaking versions without -Wattribute-alias"); \
++ __diag_ignore(clang, 23, "-Wattribute-alias", \
++ "Type aliasing is used to sanitize syscall arguments"); \
+ static long __se_##prefix##name(ulong, ulong, ulong, ulong, ulong, ulong, \
+ ulong) \
+ __attribute__((alias(__stringify(___se_##prefix##name)))); \
+--- a/include/linux/compat.h
++++ b/include/linux/compat.h
+@@ -72,6 +72,10 @@
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments");\
++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \
++ "Avoid breaking versions without -Wattribute-alias"); \
++ __diag_ignore(clang, 23, "-Wattribute-alias", \
++ "Type aliasing is used to sanitize syscall arguments"); \
+ asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
+ __attribute__((alias(__stringify(__se_compat_sys##name)))); \
+ ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \
+--- a/include/linux/compiler-clang.h
++++ b/include/linux/compiler-clang.h
+@@ -131,6 +131,12 @@
+ #define __diag_str(s) __diag_str1(s)
+ #define __diag(s) _Pragma(__diag_str(clang diagnostic s))
+
++#if CONFIG_CLANG_VERSION >= 230000
++#define __diag_clang_23(s) __diag(s)
++#else
++#define __diag_clang_23(s)
++#endif
++
+ #define __diag_clang_13(s) __diag(s)
+
+ #define __diag_ignore_all(option, comment) \
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -718,6 +718,10 @@ struct ftrace_likely_data {
+ #define __diag_GCC(version, severity, string)
+ #endif
+
++#ifndef __diag_clang
++#define __diag_clang(version, severity, string)
++#endif
++
+ #define __diag_push() __diag(push)
+ #define __diag_pop() __diag(pop)
+
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -247,6 +247,10 @@ static inline int is_syscall_trace_event
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments");\
++ __diag_ignore(clang, 23, "-Wunknown-warning-option", \
++ "Avoid breaking versions without -Wattribute-alias");\
++ __diag_ignore(clang, 23, "-Wattribute-alias", \
++ "Type aliasing is used to sanitize syscall arguments");\
+ asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
+ __attribute__((alias(__stringify(__se_sys##name)))); \
+ ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
--- /dev/null
+From a1b836607304f71051f9f9dcccf8b5097b86a1fb Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Date: Fri, 22 May 2026 11:12:36 +0200
+Subject: gpio: shared: fix deadlock on shared proxy's parent removal
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+commit a1b836607304f71051f9f9dcccf8b5097b86a1fb upstream.
+
+Commit 710abda58055 ("gpio: shared: call gpio_chip::of_xlate() if set")
+used the mutex embedded in struct gpio_shared_entry to protect the
+offset field which now can be modified after assignment. The critical
+section however is too wide and introduced a potential deadlock on the
+removal of the shared GPIO proxy's parent.
+
+Make the critical section shorter - only protect the offset when it's
+being read.
+
+While at it: mention the fact that the entry lock is now also used to
+protect against concurrent access to the offset field in the structure's
+documentation.
+
+Cc: stable@vger.kernel.org
+Fixes: 710abda58055 ("gpio: shared: call gpio_chip::of_xlate() if set")
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://patch.msgid.link/20260522-gpio-shared-deadlock-v1-1-76bca088f8c0@oss.qualcomm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpiolib-shared.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
+index e02d6b93a4ab..087b64c06c9f 100644
+--- a/drivers/gpio/gpiolib-shared.c
++++ b/drivers/gpio/gpiolib-shared.c
+@@ -53,7 +53,7 @@ struct gpio_shared_entry {
+ unsigned int offset;
+ /* Index in the property value array. */
+ size_t index;
+- /* Synchronizes the modification of shared_desc. */
++ /* Synchronizes the modification of shared_desc and offset. */
+ struct mutex lock;
+ struct gpio_shared_desc *shared_desc;
+ struct kref ref;
+@@ -598,12 +598,11 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
+ struct gpio_shared_ref *ref;
+
+ list_for_each_entry(entry, &gpio_shared_list, list) {
+- guard(mutex)(&entry->lock);
+-
+ if (!device_match_fwnode(&gdev->dev, entry->fwnode))
+ continue;
+
+- gpiod_free_commit(&gdev->descs[entry->offset]);
++ scoped_guard(mutex, &entry->lock)
++ gpiod_free_commit(&gdev->descs[entry->offset]);
+
+ list_for_each_entry(ref, &entry->refs, list) {
+ guard(mutex)(&ref->lock);
+--
+2.54.0
+
--- /dev/null
+From 9d7697fabbc72428f981c01ddbe0a6be0ce8b6fa Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Date: Fri, 22 May 2026 11:12:37 +0200
+Subject: gpio: shared: fix lockdep false positive by removing unneeded lock
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+commit 9d7697fabbc72428f981c01ddbe0a6be0ce8b6fa upstream.
+
+By the time gpio_device_teardown_shared() is called, the parent device
+is gone from the global list of GPIO devices and all outstanding SRCU
+read-side critical sections have completed. That means that no
+concurrent gpio_find_and_request() can call
+gpio_shared_add_proxy_lookup() for this device at this time. There's
+also no risk of the parent device being re-bound to the driver before
+the unbinding completes (including the child devices).
+
+Lockdep produces a false-positive report about a possible circular
+dependency as it doesn't know the ordering guarantee. Not taking the
+ref->lock in gpio_device_teardown_shared() silences it and is safe to do.
+
+Cc: stable@vger.kernel.org
+Fixes: ea513dd3c066 ("gpio: shared: make locking more fine-grained")
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://patch.msgid.link/20260522-gpio-shared-deadlock-v1-2-76bca088f8c0@oss.qualcomm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpiolib-shared.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/gpio/gpiolib-shared.c
++++ b/drivers/gpio/gpiolib-shared.c
+@@ -605,8 +605,6 @@ void gpio_device_teardown_shared(struct
+ gpiod_free_commit(&gdev->descs[entry->offset]);
+
+ list_for_each_entry(ref, &entry->refs, list) {
+- guard(mutex)(&ref->lock);
+-
+ if (ref->lookup) {
+ gpiod_remove_lookup_table(ref->lookup);
+ kfree(ref->lookup->table[0].key);
--- /dev/null
+From bbec30f7e19d9a1c604da7164b8057ccee590e72 Mon Sep 17 00:00:00 2001
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Date: Fri, 22 May 2026 09:49:35 +0200
+Subject: gpio: shared: undo the vote of the proxy on GPIO free
+
+From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+
+commit bbec30f7e19d9a1c604da7164b8057ccee590e72 upstream.
+
+When the user of a shared GPIO managed by gpio-shared-proxy calls
+gpiod_put() to release it, we never undo the potential "vote" for
+driving the shared line "high". In the free() callback, check if this
+proxy voted for "high" and - if so - decrease the number of votes and
+potentially revert the value to low if this is the last user.
+
+Cc: stable@vger.kernel.org
+Fixes: e992d54c6f97 ("gpio: shared-proxy: implement the shared GPIO proxy driver")
+Closes: https://sashiko.dev/#/patchset/20260513-gpio-shared-dynamic-voting-v1-1-8e1c49961b7d%40oss.qualcomm.com
+Reviewed-by: Linus Walleij <linusw@kernel.org>
+Link: https://patch.msgid.link/20260522-gpio-shared-free-vote-v3-1-8a4fddc6bedb@oss.qualcomm.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpio/gpio-shared-proxy.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/gpio/gpio-shared-proxy.c
++++ b/drivers/gpio/gpio-shared-proxy.c
+@@ -103,9 +103,18 @@ static void gpio_shared_proxy_free(struc
+ {
+ struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+ struct gpio_shared_desc *shared_desc = proxy->shared_desc;
++ int ret;
+
+ guard(gpio_shared_desc_lock)(shared_desc);
+
++ if (proxy->voted_high) {
++ ret = gpio_shared_proxy_set_unlocked(proxy,
++ shared_desc->can_sleep ? gpiod_set_value_cansleep : gpiod_set_value, 0);
++ if (ret)
++ dev_err(proxy->dev,
++ "Failed to unset the shared GPIO value on release: %d\n", ret);
++ }
++
+ proxy->shared_desc->usecnt--;
+
+ dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n",
--- /dev/null
+From 974820a59efde7c1a7e1260bcfe9bb81f833cc9f Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Mon, 25 May 2026 14:48:58 +0200
+Subject: hpfs: fix a crash if hpfs_map_dnode_bitmap fails
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 974820a59efde7c1a7e1260bcfe9bb81f833cc9f upstream.
+
+If hpfs_map_dnode_bitmap fails, the code would call hpfs_brelse4 on
+uninitialized quad buffer head, causing a crash.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hpfs/alloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/hpfs/alloc.c
++++ b/fs/hpfs/alloc.c
+@@ -372,8 +372,8 @@ int hpfs_check_free_dnodes(struct super_
+ return 0;
+ }
+ }
++ hpfs_brelse4(&qbh);
+ }
+- hpfs_brelse4(&qbh);
+ i = 0;
+ if (hpfs_sb(s)->sb_c_bitmap != -1) {
+ bmp = hpfs_map_bitmap(s, b, &qbh, "chkdn1");
--- /dev/null
+From 030675aa54cf757769b3db65642433d626b3ed7c Mon Sep 17 00:00:00 2001
+From: Chaitanya Sabnis <chaitanya.msabnis@gmail.com>
+Date: Tue, 26 May 2026 15:52:40 +0530
+Subject: i2c: davinci: fix division by zero on missing clock-frequency
+
+From: Chaitanya Sabnis <chaitanya.msabnis@gmail.com>
+
+commit 030675aa54cf757769b3db65642433d626b3ed7c upstream.
+
+When the 'clock-frequency' property is missing from the device tree,
+the driver falls back to DAVINCI_I2C_DEFAULT_BUS_FREQ. However, this
+macro was defined in kHz (100), whereas the device tree property is
+expected in Hz.
+
+The probe function divided the fallback value by 1000, causing
+integer truncation that resulted in dev->bus_freq = 0. This triggered
+a deterministic division-by-zero kernel panic when calculating clock
+dividers later in the probe sequence.
+
+Fix this by redefining DAVINCI_I2C_DEFAULT_BUS_FREQ in Hz (100000)
+to match the expected device tree property unit, allowing the existing
+division logic to work correctly for both cases.
+
+Fixes: b04ce6385979 ("i2c: davinci: kill platform data")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/all/20260514044726.57297C2BCB7@smtp.kernel.org/
+Signed-off-by: Chaitanya Sabnis <chaitanya.msabnis@gmail.com>
+Cc: <stable@vger.kernel.org> # v6.14+
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260526102240.4949-1-chaitanya.msabnis@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-davinci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-davinci.c
++++ b/drivers/i2c/busses/i2c-davinci.c
+@@ -117,7 +117,7 @@
+ /* timeout for pm runtime autosuspend */
+ #define DAVINCI_I2C_PM_TIMEOUT 1000 /* ms */
+
+-#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100
++#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100000
+
+ struct davinci_i2c_dev {
+ struct device *dev;
--- /dev/null
+From 1a772719318c11e146f6fbe621fffd230a6f456a Mon Sep 17 00:00:00 2001
+From: Radu Sabau <radu.sabau@analog.com>
+Date: Wed, 8 Apr 2026 13:32:13 +0300
+Subject: iio: adc: ad4695: Fix call ordering in offload buffer postenable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Radu Sabau <radu.sabau@analog.com>
+
+commit 1a772719318c11e146f6fbe621fffd230a6f456a upstream.
+
+ad4695_enter_advanced_sequencer_mode() was called after
+spi_offload_trigger_enable(). That is wrong because
+ad4695_enter_advanced_sequencer_mode() issues regular SPI transfers to
+put the ADC into advanced sequencer mode, and not all SPI offload capable
+controllers support regular SPI transfers while offloading is enabled.
+
+Fix this by calling ad4695_enter_advanced_sequencer_mode() before
+spi_offload_trigger_enable(), so the ADC is fully configured before the
+first CNV pulse can occur. This is consistent with the same constraint
+that already applies to the BUSY_GP_EN write above it.
+
+Update the error unwind labels accordingly: add err_exit_conversion_mode
+so that a failure of spi_offload_trigger_enable() correctly exits
+conversion mode before clearing BUSY_GP_EN.
+
+Fixes: f09f140e3ea8 ("iio: adc: ad4695: Add support for SPI offload")
+Reviewed-by: Nuno SĂ¡ <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Radu Sabau <radu.sabau@analog.com>
+Cc: Stable@vger.kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad4695.c | 23 ++++++++---------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+--- a/drivers/iio/adc/ad4695.c
++++ b/drivers/iio/adc/ad4695.c
+@@ -876,14 +876,14 @@ static int ad4695_offload_buffer_postena
+ if (ret)
+ goto err_unoptimize_message;
+
+- ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
+- &config);
++ ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
+ if (ret)
+ goto err_disable_busy_output;
+
+- ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
++ ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
++ &config);
+ if (ret)
+- goto err_offload_trigger_disable;
++ goto err_exit_conversion_mode;
+
+ mutex_lock(&st->cnv_pwm_lock);
+ pwm_get_state(st->cnv_pwm, &state);
+@@ -895,23 +895,16 @@ static int ad4695_offload_buffer_postena
+ ret = pwm_apply_might_sleep(st->cnv_pwm, &state);
+ mutex_unlock(&st->cnv_pwm_lock);
+ if (ret)
+- goto err_offload_exit_conversion_mode;
++ goto err_offload_trigger_disable;
+
+ return 0;
+
+-err_offload_exit_conversion_mode:
+- /*
+- * We have to unwind in a different order to avoid triggering offload.
+- * ad4695_exit_conversion_mode() triggers a conversion, so it has to be
+- * done after spi_offload_trigger_disable().
+- */
+- spi_offload_trigger_disable(st->offload, st->offload_trigger);
+- ad4695_exit_conversion_mode(st);
+- goto err_disable_busy_output;
+-
+ err_offload_trigger_disable:
+ spi_offload_trigger_disable(st->offload, st->offload_trigger);
+
++err_exit_conversion_mode:
++ ad4695_exit_conversion_mode(st);
++
+ err_disable_busy_output:
+ regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE,
+ AD4695_REG_GP_MODE_BUSY_GP_EN);
--- /dev/null
+From f9bbd943c34a9ad60e593a4b99ce2394e4e2381b Mon Sep 17 00:00:00 2001
+From: Salah Triki <salah.triki@gmail.com>
+Date: Mon, 27 Apr 2026 21:12:38 +0100
+Subject: iio: adc: mt6359: fix unchecked return value in mt6358_read_imp
+
+From: Salah Triki <salah.triki@gmail.com>
+
+commit f9bbd943c34a9ad60e593a4b99ce2394e4e2381b upstream.
+
+In mt6358_read_imp(), the variable val_v is passed to regmap_read()
+but the return value is not checked. If the read fails, val_v remains
+uninitialized and its random stack content is subsequently reported
+as a measurement result.
+
+Initialize val_v to zero to ensure a predictable value is reported
+in case of bus failure and to prevent potential stack data leakage.
+This also satisfies static analyzers that might otherwise flag the
+variable as used uninitialized.
+
+Fixes: 3587914bf61d ("iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC")
+Signed-off-by: Salah Triki <salah.triki@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/mt6359-auxadc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/adc/mt6359-auxadc.c
++++ b/drivers/iio/adc/mt6359-auxadc.c
+@@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359
+ return ret;
+
+ /* Read the params before stopping */
++ val_v = 0;
+ regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
+
+ mt6358_stop_imp_conv(adc_dev);
--- /dev/null
+From 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c Mon Sep 17 00:00:00 2001
+From: David Carlier <devnexen@gmail.com>
+Date: Tue, 14 Apr 2026 13:30:06 +0100
+Subject: iio: adc: npcm: fix unbalanced clk_disable_unprepare()
+
+From: David Carlier <devnexen@gmail.com>
+
+commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c upstream.
+
+The driver acquired the ADC clock with devm_clk_get() and read its
+rate, but never called clk_prepare_enable(). The probe error path and
+npcm_adc_remove() both called clk_disable_unprepare() unconditionally,
+causing the clk framework's enable/prepare counts to underflow on
+probe failure or module unbind.
+
+The issue went unnoticed because NPCM BMC firmware leaves the ADC
+clock enabled at boot, so the driver happened to work in practice.
+
+Switch to devm_clk_get_enabled() so the clock is properly enabled
+during probe and automatically released by the device-managed
+cleanup, and drop the now-redundant clk_disable_unprepare() from
+both the probe error path and remove().
+
+While at it, drop the duplicate error message on devm_request_irq()
+failure since the IRQ core already logs it.
+
+Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver")
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/npcm_adc.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platfor
+ if (IS_ERR(info->reset))
+ return PTR_ERR(info->reset);
+
+- info->adc_clk = devm_clk_get(&pdev->dev, NULL);
++ info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(info->adc_clk)) {
+ dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n");
+ return PTR_ERR(info->adc_clk);
+@@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platfor
+ info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
+
+ irq = platform_get_irq(pdev, 0);
+- if (irq < 0) {
+- ret = irq;
+- goto err_disable_clk;
+- }
++ if (irq < 0)
++ return irq;
+
+ ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0,
+ "NPCM_ADC", indio_dev);
+- if (ret < 0) {
+- dev_err(dev, "failed requesting interrupt\n");
+- goto err_disable_clk;
+- }
++ if (ret < 0)
++ return ret;
+
+ reg_con = ioread32(info->regs + NPCM_ADCCON);
+ info->vref = devm_regulator_get_optional(&pdev->dev, "vref");
+@@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platfor
+ ret = regulator_enable(info->vref);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't enable ADC reference voltage\n");
+- goto err_disable_clk;
++ return ret;
+ }
+
+ iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
+@@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platfor
+ * Any error which is not ENODEV indicates the regulator
+ * has been specified and so is a failure case.
+ */
+- if (PTR_ERR(info->vref) != -ENODEV) {
+- ret = PTR_ERR(info->vref);
+- goto err_disable_clk;
+- }
++ if (PTR_ERR(info->vref) != -ENODEV)
++ return PTR_ERR(info->vref);
+
+ /* Use internal reference */
+ iowrite32(reg_con | NPCM_ADCCON_REFSEL,
+@@ -314,8 +308,6 @@ err_iio_register:
+ iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+ if (!IS_ERR(info->vref))
+ regulator_disable(info->vref);
+-err_disable_clk:
+- clk_disable_unprepare(info->adc_clk);
+
+ return ret;
+ }
+@@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platf
+ iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+ if (!IS_ERR(info->vref))
+ regulator_disable(info->vref);
+- clk_disable_unprepare(info->adc_clk);
+ }
+
+ static struct platform_driver npcm_adc_driver = {
--- /dev/null
+From 7e5c0f97c66ad538b87c04a640573371fb434b4f Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Thu, 16 Apr 2026 11:01:22 +0200
+Subject: iio: adc: nxp-sar-adc: Avoid division by zero
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+commit 7e5c0f97c66ad538b87c04a640573371fb434b4f upstream.
+
+When Common Clock Framework is disabled, clk_get_rate() returns 0.
+This is used as part of the divisor to perform nanosecond delays
+with help of ndelay(). When the above condition occurs the compiler,
+due to unspecified behaviour, is free to do what it wants to. Here
+it saturates the value, which is logical from mathematics point of
+view. However, the ndelay() implementation has set a reasonable
+upper threshold and refuses to provide anything for such a long
+delay. That's why code may not be linked under these circumstances.
+
+To solve the issue, provide a wrapper that calls ndelay() when
+the value is known not to be zero.
+
+Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202603311958.ly6uROit-lkp@intel.com/
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Daniel Lezcano <daniel.lezcano@oss.qualcomm.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/nxp-sar-adc.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/adc/nxp-sar-adc.c
++++ b/drivers/iio/adc/nxp-sar-adc.c
+@@ -198,6 +198,15 @@ static void nxp_sar_adc_irq_cfg(struct n
+ writel(0, NXP_SAR_ADC_IMR(info->regs));
+ }
+
++static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles)
++{
++ u64 rate;
++
++ rate = clk_get_rate(info->clk);
++ if (rate)
++ ndelay(div64_u64(NSEC_PER_SEC, rate * cycles));
++}
++
+ static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
+ {
+ u32 mcr;
+@@ -221,7 +230,7 @@ static bool nxp_sar_adc_set_enabled(stru
+ * configuration of NCMR and the setting of NSTART.
+ */
+ if (enable)
+- ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3));
++ nxp_sar_adc_wait_for(info, 3);
+
+ return pwdn;
+ }
+@@ -468,7 +477,7 @@ static void nxp_sar_adc_stop_conversion(
+ * only when the capture finishes. The delay will be very
+ * short, usec-ish, which is acceptable in the atomic context.
+ */
+- ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80);
++ nxp_sar_adc_wait_for(info, 80);
+ }
+
+ static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw)
--- /dev/null
+From a9aba21a539c668a66b58eeb08ad3909e5a54c2a Mon Sep 17 00:00:00 2001
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Date: Wed, 1 Apr 2026 18:29:24 +0300
+Subject: iio: adc: nxp-sar-adc: fix division by zero in write_raw
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+commit a9aba21a539c668a66b58eeb08ad3909e5a54c2a upstream.
+
+Add a validation check for the sampling frequency value before using it
+as a divisor. A user writing zero or a negative value to the
+sampling_frequency sysfs attribute triggers a division by zero in the
+kernel.
+
+Also prevent unsigned integer underflow when the computed cycle count is
+smaller than NXP_SAR_ADC_CONV_TIME, which would wrap the u32 inpsamp to
+a huge value.
+
+Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/nxp-sar-adc.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/nxp-sar-adc.c
++++ b/drivers/iio/adc/nxp-sar-adc.c
+@@ -559,6 +559,9 @@ static int nxp_sar_adc_write_raw(struct
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
++ if (val <= 0)
++ return -EINVAL;
++
+ /*
+ * Configures the sample period duration in terms of the SAR
+ * controller clock. The minimum acceptable value is 8.
+@@ -567,7 +570,11 @@ static int nxp_sar_adc_write_raw(struct
+ * sampling timing which gives us the number of cycles expected.
+ * The value is 8-bit wide, consequently the max value is 0xFF.
+ */
+- inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME;
++ inpsamp = clk_get_rate(info->clk) / val;
++ if (inpsamp < NXP_SAR_ADC_CONV_TIME)
++ return -EINVAL;
++
++ inpsamp -= NXP_SAR_ADC_CONV_TIME;
+ nxp_sar_adc_conversion_timing_set(info, inpsamp);
+ return 0;
+
--- /dev/null
+From 8ce176501f836634f9c0419c0820140f968e9dc5 Mon Sep 17 00:00:00 2001
+From: Shuvam Pandey <shuvampandey1@gmail.com>
+Date: Mon, 6 Apr 2026 15:38:24 +0545
+Subject: iio: adc: nxp-sar-adc: zero-initialize dma_slave_config
+
+From: Shuvam Pandey <shuvampandey1@gmail.com>
+
+commit 8ce176501f836634f9c0419c0820140f968e9dc5 upstream.
+
+nxp_sar_adc_start_cyclic_dma() only fills the RX-side members of
+dma_slave_config before passing it to dmaengine_slave_config().
+
+Zero-initialize the structure so unused members do not contain stack
+garbage. Some DMA engines consult optional dma_slave_config fields, so
+leaving them uninitialized can cause DMA setup failures.
+
+Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms")
+Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/nxp-sar-adc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/nxp-sar-adc.c
++++ b/drivers/iio/adc/nxp-sar-adc.c
+@@ -675,7 +675,7 @@ static void nxp_sar_adc_dma_cb(void *dat
+ static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev)
+ {
+ struct nxp_sar_adc *info = iio_priv(indio_dev);
+- struct dma_slave_config config;
++ struct dma_slave_config config = { };
+ struct dma_async_tx_descriptor *desc;
+ int ret;
+
--- /dev/null
+From 422b5bbf333f75fb486855ad0eedc23cf21f3277 Mon Sep 17 00:00:00 2001
+From: Salah Triki <salah.triki@gmail.com>
+Date: Thu, 7 May 2026 20:07:51 +0100
+Subject: iio: adc: viperboard: Fix error handling in vprbrd_iio_read_raw
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Salah Triki <salah.triki@gmail.com>
+
+commit 422b5bbf333f75fb486855ad0eedc23cf21f3277 upstream.
+
+The driver proceeds to the reception phase even if the preceding
+transmission fails.
+
+This uses a goto error label for an early bail out and ensures the mutex is
+properly unlocked in case of failure.
+
+Fixes: ffd8a6e7a778 ("iio: adc: Add viperboard adc driver")
+Signed-off-by: Salah Triki <salah.triki@gmail.com>
+Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
+Reviewed-by: Maxwell Doose <m32285159@gmail.com>
+Reviewed-by: Nuno SĂ¡ <nuno.sa@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/viperboard_adc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/viperboard_adc.c
++++ b/drivers/iio/adc/viperboard_adc.c
+@@ -70,8 +70,10 @@ static int vprbrd_iio_read_raw(struct ii
+ VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg,
+ sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS);
+ if (ret != sizeof(struct vprbrd_adc_msg)) {
+- dev_err(&iio_dev->dev, "usb send error on adc read\n");
++ mutex_unlock(&vb->lock);
+ error = -EREMOTEIO;
++ dev_err(&iio_dev->dev, "usb send error on adc read\n");
++ goto error;
+ }
+
+ ret = usb_control_msg(vb->usb_dev,
--- /dev/null
+From 852534744c2d35626a604f128ff0b8ec12805591 Mon Sep 17 00:00:00 2001
+From: Christofer Jonason <christofer.jonason@guidelinegeo.com>
+Date: Wed, 4 Mar 2026 10:07:27 +0100
+Subject: iio: adc: xilinx-xadc: Fix sequencer mode in postdisable for dual mux
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christofer Jonason <christofer.jonason@guidelinegeo.com>
+
+commit 852534744c2d35626a604f128ff0b8ec12805591 upstream.
+
+xadc_postdisable() unconditionally sets the sequencer to continuous
+mode. For dual external multiplexer configurations this is incorrect:
+simultaneous sampling mode is required so that ADC-A samples through
+the mux on VAUX[0-7] while ADC-B simultaneously samples through the
+mux on VAUX[8-15]. In continuous mode only ADC-A is active, so
+VAUX[8-15] channels return incorrect data.
+
+Since postdisable is also called from xadc_probe() to set the initial
+idle state, the wrong sequencer mode is active from the moment the
+driver loads.
+
+The preenable path already uses xadc_get_seq_mode() which returns
+SIMULTANEOUS for dual mux. Fix postdisable to do the same.
+
+Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christofer Jonason <christofer.jonason@guidelinegeo.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Reviewed-by: Nuno SĂ¡ <nuno.sa@analog.com>
+Reviewed-by: Salih Erim <salih.erim@amd.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/xilinx-xadc-core.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/adc/xilinx-xadc-core.c
++++ b/drivers/iio/adc/xilinx-xadc-core.c
+@@ -817,6 +817,7 @@ static int xadc_postdisable(struct iio_d
+ {
+ struct xadc *xadc = iio_priv(indio_dev);
+ unsigned long scan_mask;
++ int seq_mode;
+ int ret;
+ int i;
+
+@@ -824,6 +825,12 @@ static int xadc_postdisable(struct iio_d
+ for (i = 0; i < indio_dev->num_channels; i++)
+ scan_mask |= BIT(indio_dev->channels[i].scan_index);
+
++ /*
++ * Use the correct sequencer mode for the idle state: simultaneous
++ * mode for dual external mux configurations, continuous otherwise.
++ */
++ seq_mode = xadc_get_seq_mode(xadc, scan_mask);
++
+ /* Enable all channels and calibration */
+ ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff);
+ if (ret)
+@@ -834,11 +841,11 @@ static int xadc_postdisable(struct iio_d
+ return ret;
+
+ ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
+- XADC_CONF1_SEQ_CONTINUOUS);
++ seq_mode);
+ if (ret)
+ return ret;
+
+- return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS);
++ return xadc_power_adc_b(xadc, seq_mode);
+ }
+
+ static int xadc_preenable(struct iio_dev *indio_dev)
--- /dev/null
+From a093999355084bdbfe6e97f1dd232e58a1525f0b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Beno=C3=AEt=20Monin?= <benoit.monin@bootlin.com>
+Date: Wed, 1 Apr 2026 17:24:58 +0200
+Subject: iio: buffer: Fix DMA fence leak in iio_buffer_enqueue_dmabuf()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Benoît Monin <benoit.monin@bootlin.com>
+
+commit a093999355084bdbfe6e97f1dd232e58a1525f0b upstream.
+
+iio_buffer_enqueue_dmabuf() allocates a struct iio_dma_fence (104 bytes,
+kmalloc-128) via kmalloc_obj()+dma_fence_init(), which sets the initial
+kref to 1. It then calls dma_resv_add_fence() which takes a second
+reference (kref=2), and stores a raw pointer in block->fence.
+
+On the success path the function returns without calling dma_fence_put()
+to release the initial reference, so every buffer enqueue permanently
+leaks one kmalloc-128 allocation.
+
+The iio_buffer_cleanup() work item only releases the temporary reference
+taken during completion signalling by iio_buffer_signal_dmabuf_done();
+the initial reference from dma_fence_init() is never released.
+
+With four iio_rwdev instances at 240kHz and 512 samples per buffer,
+this produces ~1875 kmalloc-128 allocations per second matching the
+observed slab growth exactly. A test with ftrace confirmed that the
+dma_fence_destroy event was never triggered.
+
+Fix by calling dma_fence_put() after dma_resv_add_fence(), transferring
+ownership of the fence to the DMA reservation object. The DMA fence then
+gets properly discarded after being signalled.
+
+Fixes: 3e26d9f08fbe0 ("iio: core: Add new DMABUF interface infrastructure")
+Originally-by: James Nuss <jamesnuss@nanometrics.ca>
+Signed-off-by: Benoît Monin <benoit.monin@bootlin.com>
+Reviewed-by: Paul Cercueil <paul@crapouillou.net>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/industrialio-buffer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/industrialio-buffer.c
++++ b/drivers/iio/industrialio-buffer.c
+@@ -1909,6 +1909,7 @@ static int iio_buffer_enqueue_dmabuf(str
+
+ dma_resv_add_fence(dmabuf->resv, &fence->base,
+ dma_to_ram ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ);
++ dma_fence_put(&fence->base);
+ dma_resv_unlock(dmabuf->resv);
+
+ cookie = dma_fence_begin_signalling();
--- /dev/null
+From 6f5ed4f2c7c83f33344e0ba179f72a12e5dad4a4 Mon Sep 17 00:00:00 2001
+From: Felix Gu <ustc.gu@gmail.com>
+Date: Thu, 30 Apr 2026 21:29:06 +0800
+Subject: iio: buffer: hw-consumer: fix use-after-free in error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+commit 6f5ed4f2c7c83f33344e0ba179f72a12e5dad4a4 upstream.
+
+In the err_put_buffers cleanup path of iio_hw_consumer_alloc(), the code
+was using list_for_each_entry() to iterate through buffers while calling
+iio_buffer_put() which can free the current buffer if refcount drops to 0.
+The list_for_each_entry() loop macro then evaluates buf->head.next to
+continue iteration, accessing the freed buffer.
+
+Fix this by using list_for_each_entry_safe().
+
+Fixes: 48b66f8f936f ("iio: Add hardware consumer buffer support")
+Reported-by: sashiko <sashiko-bot@kernel.org>
+Closes: https://sashiko.dev/#/patchset/20260427-iio_buf-v1-1-2bbdac844647%40gmail.com
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Reviewed-by: Nuno SĂ¡ <nuno.sa@analog.com>
+Reviewed-by: Maxwell Doose <m32285159@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/buffer/industrialio-hw-consumer.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/buffer/industrialio-hw-consumer.c
++++ b/drivers/iio/buffer/industrialio-hw-consumer.c
+@@ -82,7 +82,7 @@ static struct hw_consumer_buffer *iio_hw
+ */
+ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
+ {
+- struct hw_consumer_buffer *buf;
++ struct hw_consumer_buffer *buf, *tmp;
+ struct iio_hw_consumer *hwc;
+ struct iio_channel *chan;
+ int ret;
+@@ -113,7 +113,7 @@ struct iio_hw_consumer *iio_hw_consumer_
+ return hwc;
+
+ err_put_buffers:
+- list_for_each_entry(buf, &hwc->buffers, head)
++ list_for_each_entry_safe(buf, tmp, &hwc->buffers, head)
+ iio_buffer_put(&buf->buffer);
+ iio_channel_release_all(hwc->channels);
+ err_free_hwc:
--- /dev/null
+From 673478bc29cf72010faaf293c1c8c667393335a0 Mon Sep 17 00:00:00 2001
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Date: Thu, 2 Apr 2026 13:40:15 +0800
+Subject: iio: chemical: mhz19b: reject oversized serial replies
+
+From: Pengpeng Hou <pengpeng@iscas.ac.cn>
+
+commit 673478bc29cf72010faaf293c1c8c667393335a0 upstream.
+
+mhz19b_receive_buf() appends each serdev chunk into the fixed
+MHZ19B_CMD_SIZE receive buffer and advances buf_idx by len without
+checking that the chunk fits in the remaining space. A large callback
+can therefore overflow st->buf before the command path validates the
+reply.
+
+Reset the reply state before each command and reject oversized serial
+replies before copying them into the fixed buffer. When an oversized
+reply is detected, wake the waiter and report -EMSGSIZE instead of
+overwriting st->buf.
+
+Fixes: 4572a70b3681 ("iio: chemical: Add support for Winsen MHZ19B CO2 sensor")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
+Acked-by: Gyeyoung Baek <gye976@gmail.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/mhz19b.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/iio/chemical/mhz19b.c
++++ b/drivers/iio/chemical/mhz19b.c
+@@ -52,6 +52,8 @@ struct mhz19b_state {
+ struct completion buf_ready;
+
+ u8 buf_idx;
++ bool buf_overflow;
++
+ /*
+ * Serdev receive buffer.
+ * When data is received from the MH-Z19B,
+@@ -106,6 +108,10 @@ static int mhz19b_serdev_cmd(struct iio_
+ cmd_buf[8] = mhz19b_get_checksum(cmd_buf);
+
+ /* Write buf to uart ctrl synchronously */
++ st->buf_idx = 0;
++ st->buf_overflow = false;
++ reinit_completion(&st->buf_ready);
++
+ ret = serdev_device_write(serdev, cmd_buf, MHZ19B_CMD_SIZE, 0);
+ if (ret < 0)
+ return ret;
+@@ -121,6 +127,9 @@ static int mhz19b_serdev_cmd(struct iio_
+ if (!ret)
+ return -ETIMEDOUT;
+
++ if (st->buf_overflow)
++ return -EMSGSIZE;
++
+ if (st->buf[8] != mhz19b_get_checksum(st->buf)) {
+ dev_err(dev, "checksum err");
+ return -EINVAL;
+@@ -240,6 +249,14 @@ static size_t mhz19b_receive_buf(struct
+ {
+ struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev);
+ struct mhz19b_state *st = iio_priv(indio_dev);
++ size_t remaining = MHZ19B_CMD_SIZE - st->buf_idx;
++
++ if (len > remaining) {
++ st->buf_idx = 0;
++ st->buf_overflow = true;
++ complete(&st->buf_ready);
++ return len;
++ }
+
+ memcpy(st->buf + st->buf_idx, data, len);
+ st->buf_idx += len;
--- /dev/null
+From 5aba4f94b225617a55fed442a70329b2ee19c0a5 Mon Sep 17 00:00:00 2001
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Date: Wed, 1 Apr 2026 14:08:29 +0300
+Subject: iio: chemical: scd30: fix division by zero in write_raw
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 upstream.
+
+Add a zero check for val2 before using it as a divisor when setting the
+sampling frequency. A user writing a zero fractional part to the
+sampling_frequency sysfs attribute triggers a division by zero in the
+kernel.
+
+Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -256,7 +256,7 @@ static int scd30_write_raw(struct iio_de
+ guard(mutex)(&state->lock);
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+- if (val)
++ if (val || !val2)
+ return -EINVAL;
+
+ val = 1000000000 / val2;
--- /dev/null
+From ebd250c2581ec46c64c73fdfa918c9a7f757505e Mon Sep 17 00:00:00 2001
+From: Kim Seer Paller <kimseer.paller@analog.com>
+Date: Tue, 5 May 2026 12:34:32 +0800
+Subject: iio: dac: ad3530r: Fix AD3531/AD3531R powerdown mode strings
+
+From: Kim Seer Paller <kimseer.paller@analog.com>
+
+commit ebd250c2581ec46c64c73fdfa918c9a7f757505e upstream.
+
+The AD3531/AD3531R has different output operating modes from the
+AD3530/AD3530R. According to the AD3531/AD3531R datasheet, the
+powerdown modes are:
+ 01: 500 Ohm output impedance
+ 10: 3.85 kOhm output impedance
+ 11: 16 kOhm output impedance
+
+The driver currently uses the AD3530R modes (1k, 7.7k, 32k) for all
+variants, which is incorrect for AD3531/AD3531R.
+
+Add AD3531R-specific powerdown mode strings and assign them to the
+AD3531/AD3531R chip variants.
+
+Fixes: 93583174a3df ("iio: dac: ad3530r: Add driver for AD3530R and AD3531R")
+Signed-off-by: Kim Seer Paller <kimseer.paller@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad3530r.c | 54 ++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 14 deletions(-)
+
+--- a/drivers/iio/dac/ad3530r.c
++++ b/drivers/iio/dac/ad3530r.c
+@@ -105,6 +105,12 @@ static const char * const ad3530r_powerd
+ "32kohm_to_gnd",
+ };
+
++static const char * const ad3531r_powerdown_modes[] = {
++ "500ohm_to_gnd",
++ "3.85kohm_to_gnd",
++ "16kohm_to_gnd",
++};
++
+ static int ad3530r_get_powerdown_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+ {
+@@ -133,6 +139,13 @@ static const struct iio_enum ad3530r_pow
+ .set = ad3530r_set_powerdown_mode,
+ };
+
++static const struct iio_enum ad3531r_powerdown_mode_enum = {
++ .items = ad3531r_powerdown_modes,
++ .num_items = ARRAY_SIZE(ad3531r_powerdown_modes),
++ .get = ad3530r_get_powerdown_mode,
++ .set = ad3530r_set_powerdown_mode,
++};
++
+ static ssize_t ad3530r_get_dac_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private,
+ const struct iio_chan_spec *chan,
+@@ -276,7 +289,20 @@ static const struct iio_chan_spec_ext_in
+ { }
+ };
+
+-#define AD3530R_CHAN(_chan) \
++static const struct iio_chan_spec_ext_info ad3531r_ext_info[] = {
++ {
++ .name = "powerdown",
++ .shared = IIO_SEPARATE,
++ .read = ad3530r_get_dac_powerdown,
++ .write = ad3530r_set_dac_powerdown,
++ },
++ IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad3531r_powerdown_mode_enum),
++ IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE,
++ &ad3531r_powerdown_mode_enum),
++ { }
++};
++
++#define AD3530R_CHAN(_chan, _ext_info) \
+ { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+@@ -284,25 +310,25 @@ static const struct iio_chan_spec_ext_in
+ .output = 1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+- .ext_info = ad3530r_ext_info, \
++ .ext_info = _ext_info, \
+ }
+
+ static const struct iio_chan_spec ad3530r_channels[] = {
+- AD3530R_CHAN(0),
+- AD3530R_CHAN(1),
+- AD3530R_CHAN(2),
+- AD3530R_CHAN(3),
+- AD3530R_CHAN(4),
+- AD3530R_CHAN(5),
+- AD3530R_CHAN(6),
+- AD3530R_CHAN(7),
++ AD3530R_CHAN(0, ad3530r_ext_info),
++ AD3530R_CHAN(1, ad3530r_ext_info),
++ AD3530R_CHAN(2, ad3530r_ext_info),
++ AD3530R_CHAN(3, ad3530r_ext_info),
++ AD3530R_CHAN(4, ad3530r_ext_info),
++ AD3530R_CHAN(5, ad3530r_ext_info),
++ AD3530R_CHAN(6, ad3530r_ext_info),
++ AD3530R_CHAN(7, ad3530r_ext_info),
+ };
+
+ static const struct iio_chan_spec ad3531r_channels[] = {
+- AD3530R_CHAN(0),
+- AD3530R_CHAN(1),
+- AD3530R_CHAN(2),
+- AD3530R_CHAN(3),
++ AD3530R_CHAN(0, ad3531r_ext_info),
++ AD3530R_CHAN(1, ad3531r_ext_info),
++ AD3530R_CHAN(2, ad3531r_ext_info),
++ AD3530R_CHAN(3, ad3531r_ext_info),
+ };
+
+ static const struct ad3530r_chip_info ad3530_chip = {
--- /dev/null
+From 5237c3175cae5ab05f18878cec3301a04403859e Mon Sep 17 00:00:00 2001
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Date: Tue, 5 May 2026 13:35:04 +0100
+Subject: iio: dac: ad5686: acquire lock when doing powerdown control
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+commit 5237c3175cae5ab05f18878cec3301a04403859e upstream.
+
+Protect access of pwr_down_mode and pwr_down_mask fields with existing
+mutex lock. Each channel exposes their own attributes for controlling
+powerdown modes and powerdown state. This fixes potential race conditions
+as those the write functions perform non-atomic read-modify-write
+operations to those pwr_down_* fields. This issue exists since the ad5686
+driver was first introduced.
+
+Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters")
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -30,6 +30,8 @@ static int ad5686_get_powerdown_mode(str
+ {
+ struct ad5686_state *st = iio_priv(indio_dev);
+
++ guard(mutex)(&st->lock);
++
+ return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
+ }
+
+@@ -39,6 +41,8 @@ static int ad5686_set_powerdown_mode(str
+ {
+ struct ad5686_state *st = iio_priv(indio_dev);
+
++ guard(mutex)(&st->lock);
++
+ st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
+ st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
+
+@@ -57,6 +61,8 @@ static ssize_t ad5686_read_dac_powerdown
+ {
+ struct ad5686_state *st = iio_priv(indio_dev);
+
++ guard(mutex)(&st->lock);
++
+ return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
+ (0x3 << (chan->channel * 2))));
+ }
+@@ -77,6 +83,8 @@ static ssize_t ad5686_write_dac_powerdow
+ if (ret)
+ return ret;
+
++ guard(mutex)(&st->lock);
++
+ if (readin)
+ st->pwr_down_mask |= (0x3 << (chan->channel * 2));
+ else
--- /dev/null
+From d01220ee5e43c65a206df827b39bf5cf5f7b9dce Mon Sep 17 00:00:00 2001
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Date: Fri, 1 May 2026 10:14:55 +0100
+Subject: iio: dac: ad5686: fix input raw value check
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+commit d01220ee5e43c65a206df827b39bf5cf5f7b9dce upstream.
+
+Fix range check for input raw value, which is off by one, i.e., for a
+10-bit DAC the max valid value is 1023, but 1 << 10 equals 1024, which
+passes the previous check, allowing an out-of-range write. The issue
+exists since the ad5686 driver was first introduced.
+
+Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -154,7 +154,7 @@ static int ad5686_write_raw(struct iio_d
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+- if (val > (1 << chan->scan_type.realbits) || val < 0)
++ if (val >= (1 << chan->scan_type.realbits) || val < 0)
+ return -EINVAL;
+
+ mutex_lock(&st->lock);
--- /dev/null
+From 8aeaf25a85263a7a43357e16ad78ab969f6f8aeb Mon Sep 17 00:00:00 2001
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Date: Tue, 5 May 2026 13:35:05 +0100
+Subject: iio: dac: ad5686: fix powerdown control on dual-channel devices
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+commit 8aeaf25a85263a7a43357e16ad78ab969f6f8aeb upstream.
+
+Fix powerdown control by using a proper bit shift for the powerdown mask
+values. During initialization, powerdown bits are initialized so that
+unused bits are set to 1 and the correct bit shift is used. Dual-channel
+devices use one-hot encoding in the address and that reflects on the
+position of the powerdown bits, which are not channel-index based
+for that case. Quad-channel devices also use one-hot encoding for the
+channel address but the result of log2(address) coincides with the channel
+index value. Mask as 0x3U is used rather than 0x3, because shift can reach
+value of 30 (last channel of a 16-channel device), which would mess with
+the sign bit. The issue was introduced when first adding support for
+dual-channel devices, which overlooked powerdown control differences.
+
+Fixes: 7dc8faeab3e3 ("iio: dac: ad5686: add support for AD5338R")
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c | 40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -25,26 +25,37 @@ static const char * const ad5686_powerdo
+ "three_state"
+ };
+
++static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan)
++{
++ if (chan->channel == chan->address)
++ return chan->channel * 2;
++
++ /* one-hot encoding is used in dual/quad channel devices */
++ return __ffs(chan->address) * 2;
++}
++
+ static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+ {
++ unsigned int shift = ad5686_pd_mask_shift(chan);
+ struct ad5686_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+
+- return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
++ return ((st->pwr_down_mode >> shift) & 0x3U) - 1;
+ }
+
+ static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ unsigned int mode)
+ {
++ unsigned int shift = ad5686_pd_mask_shift(chan);
+ struct ad5686_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+
+- st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
+- st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
++ st->pwr_down_mode &= ~(0x3U << shift);
++ st->pwr_down_mode |= (mode + 1) << shift;
+
+ return 0;
+ }
+@@ -59,12 +70,12 @@ static const struct iio_enum ad5686_powe
+ static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+ {
++ unsigned int shift = ad5686_pd_mask_shift(chan);
+ struct ad5686_state *st = iio_priv(indio_dev);
+
+ guard(mutex)(&st->lock);
+
+- return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
+- (0x3 << (chan->channel * 2))));
++ return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift)));
+ }
+
+ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
+@@ -86,9 +97,9 @@ static ssize_t ad5686_write_dac_powerdow
+ guard(mutex)(&st->lock);
+
+ if (readin)
+- st->pwr_down_mask |= (0x3 << (chan->channel * 2));
++ st->pwr_down_mask |= 0x3U << ad5686_pd_mask_shift(chan);
+ else
+- st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
++ st->pwr_down_mask &= ~(0x3U << ad5686_pd_mask_shift(chan));
+
+ switch (st->chip_info->regmap_type) {
+ case AD5310_REGMAP:
+@@ -468,7 +479,7 @@ int ad5686_probe(struct device *dev,
+ {
+ struct ad5686_state *st;
+ struct iio_dev *indio_dev;
+- unsigned int val, ref_bit_msk;
++ unsigned int val, ref_bit_msk, shift;
+ bool has_external_vref;
+ u8 cmd;
+ int ret, i;
+@@ -492,9 +503,18 @@ int ad5686_probe(struct device *dev,
+ has_external_vref = ret != -ENODEV;
+ st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv;
+
++ /* Initialize masks to all ones provided the max shift (last channel) */
++ shift = ad5686_pd_mask_shift(&st->chip_info->channels[st->chip_info->num_channels - 1]);
++ st->pwr_down_mask = GENMASK(shift + 1, 0);
++ st->pwr_down_mode = GENMASK(shift + 1, 0);
++
+ /* Set all the power down mode for all channels to 1K pulldown */
+- for (i = 0; i < st->chip_info->num_channels; i++)
+- st->pwr_down_mode |= (0x01 << (i * 2));
++ for (i = 0; i < st->chip_info->num_channels; i++) {
++ shift = ad5686_pd_mask_shift(&st->chip_info->channels[i]);
++ st->pwr_down_mask &= ~(0x3U << shift); /* powered up state */
++ st->pwr_down_mode &= ~(0x3U << shift);
++ st->pwr_down_mode |= 0x01U << shift;
++ }
+
+ indio_dev->name = name;
+ indio_dev->info = &ad5686_info;
--- /dev/null
+From ecae2ae606d493cf11457946436335bd0e726663 Mon Sep 17 00:00:00 2001
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Date: Fri, 1 May 2026 10:14:54 +0100
+Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+commit ecae2ae606d493cf11457946436335bd0e726663 upstream.
+
+The reference bit position was ignored when writing the register at the
+probe() function (!!val was used). When such bit is 1, internal voltage
+reference is disabled so that an external one can be used. For
+multi-channel devices, bit 0 of the Internal Reference Setup command
+behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists
+since support for single-channel devices were first introduced.
+
+Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c | 6 +++---
+ drivers/iio/dac/ad5686.h | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -509,7 +509,7 @@ int ad5686_probe(struct device *dev,
+ break;
+ case AD5686_REGMAP:
+ cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
+- ref_bit_msk = 0;
++ ref_bit_msk = AD5686_REF_BIT_MSK;
+ break;
+ case AD5693_REGMAP:
+ cmd = AD5686_CMD_CONTROL_REG;
+@@ -520,9 +520,9 @@ int ad5686_probe(struct device *dev,
+ return -EINVAL;
+ }
+
+- val = (has_external_vref | ref_bit_msk);
++ val = has_external_vref ? ref_bit_msk : 0;
+
+- ret = st->write(st, cmd, 0, !!val);
++ ret = st->write(st, cmd, 0, val);
+ if (ret)
+ return ret;
+
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -46,6 +46,7 @@
+
+ #define AD5310_REF_BIT_MSK BIT(8)
+ #define AD5683_REF_BIT_MSK BIT(12)
++#define AD5686_REF_BIT_MSK BIT(0)
+ #define AD5693_REF_BIT_MSK BIT(12)
+
+ /**
--- /dev/null
+From d0a228d903425e653f18a4341e60c0538afb6d41 Mon Sep 17 00:00:00 2001
+From: Salah Triki <salah.triki@gmail.com>
+Date: Mon, 27 Apr 2026 22:33:19 +0100
+Subject: iio: dac: max5821: fix return value check in powerdown sync
+
+From: Salah Triki <salah.triki@gmail.com>
+
+commit d0a228d903425e653f18a4341e60c0538afb6d41 upstream.
+
+The function max5821_sync_powerdown_mode() returned the result of
+i2c_master_send() directly. If a partial transfer occurred, it would
+be incorrectly treated as a success by the caller.
+
+While the caller currently handles the positive return value of 2 as
+success, this patch refactors the function to return 0 on full success
+and -EIO on short writes. This ensures robust error handling for
+incomplete transfers and improves code maintainability by using
+sizeof(outbuf).
+
+Fixes: 472988972737 ("iio: add support of the max5821")
+Signed-off-by: Salah Triki <salah.triki@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/max5821.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/dac/max5821.c
++++ b/drivers/iio/dac/max5821.c
+@@ -90,6 +90,7 @@ static int max5821_sync_powerdown_mode(s
+ const struct iio_chan_spec *chan)
+ {
+ u8 outbuf[2];
++ int ret;
+
+ outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE;
+
+@@ -103,7 +104,13 @@ static int max5821_sync_powerdown_mode(s
+ else
+ outbuf[1] |= MAX5821_EXTENDED_POWER_UP;
+
+- return i2c_master_send(data->client, outbuf, 2);
++ ret = i2c_master_send(data->client, outbuf, sizeof(outbuf));
++ if (ret < 0)
++ return ret;
++ if (ret != sizeof(outbuf))
++ return -EIO;
++
++ return 0;
+ }
+
+ static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev,
--- /dev/null
+From bb21ee31f5753a7972148798fd7dfb841dd33bdb Mon Sep 17 00:00:00 2001
+From: Svyatoslav Ryhel <clamor95@gmail.com>
+Date: Thu, 16 Apr 2026 14:14:42 +0300
+Subject: iio: Fix iio_multiply_value use in iio_read_channel_processed_scale
+
+From: Svyatoslav Ryhel <clamor95@gmail.com>
+
+commit bb21ee31f5753a7972148798fd7dfb841dd33bdb upstream.
+
+The function iio_multiply_value returns IIO_VAL_INT (1) on success or a
+negative error number on failure, while iio_read_channel_processed_scale
+should return an error code or 0. This creates a situation where the
+expected result is treated as an error. Fix this by checking the
+iio_multiply_value result separately, instead of passing it as a return
+value.
+
+Fixes: 05f958d003c9 ("iio: Improve iio_read_channel_processed_scale() precision")
+Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/inkern.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/inkern.c
++++ b/drivers/iio/inkern.c
+@@ -738,7 +738,11 @@ int iio_read_channel_processed_scale(str
+ if (ret < 0)
+ return ret;
+
+- return iio_multiply_value(val, scale, ret, pval, pval2);
++ ret = iio_multiply_value(val, scale, ret, pval, pval2);
++ if (ret < 0)
++ return ret;
++
++ return 0;
+ } else {
+ ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
+ if (ret < 0)
--- /dev/null
+From 761e8b489e6cf166c574034b70637f8a7eadd0ee Mon Sep 17 00:00:00 2001
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Date: Tue, 31 Mar 2026 13:13:00 +0300
+Subject: iio: gyro: adis16260: fix division by zero in write_raw
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+commit 761e8b489e6cf166c574034b70637f8a7eadd0ee upstream.
+
+Add a validation check for the sampling frequency value before using it
+as a divisor. A user writing zero to the sampling_frequency sysfs
+attribute triggers a division by zero in the kernel.
+
+Fixes: 089a41985c6c ("staging: iio: adis16260 digital gyro driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Reviewed-by: Nuno SĂ¡ <nuno.sa@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/gyro/adis16260.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/iio/gyro/adis16260.c
++++ b/drivers/iio/gyro/adis16260.c
+@@ -287,6 +287,9 @@ static int adis16260_write_raw(struct ii
+ addr = adis16260_addresses[chan->scan_index][1];
+ return adis_write_reg_16(adis, addr, val);
+ case IIO_CHAN_INFO_SAMP_FREQ:
++ if (val <= 0)
++ return -EINVAL;
++
+ if (spi_get_device_id(adis->spi)->driver_data)
+ t = 256 / val;
+ else
--- /dev/null
+From 6bdc3023d62ed5c7d591f0eb27a5adb37fb892ae Mon Sep 17 00:00:00 2001
+From: David Carlier <devnexen@gmail.com>
+Date: Tue, 5 May 2026 14:37:48 +0100
+Subject: iio: gyro: itg3200: fix i2c read into the wrong stack location
+
+From: David Carlier <devnexen@gmail.com>
+
+commit 6bdc3023d62ed5c7d591f0eb27a5adb37fb892ae upstream.
+
+itg3200_read_all_channels() takes `__be16 *buf' as a parameter and
+fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the
+parameter (a pointer), `&buf' is the address of the local pointer
+slot on the stack of itg3200_read_all_channels(), not the address
+of the caller's scan buffer. The (char *) cast hides the type
+mismatch.
+
+i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16)
+= 8 bytes into the parameter's stack slot, which is discarded when
+the function returns. The caller's scan buffer in
+itg3200_trigger_handler() is never written to, so
+iio_push_to_buffers_with_timestamp() pushes uninitialised stack
+contents to userspace via /dev/iio:deviceX every scan -- both a
+functional bug (no actual gyroscope or temperature data is
+delivered through the triggered buffer) and an information leak.
+
+The non-buffered read_raw() path is unaffected: it goes through
+itg3200_read_reg_s16() which uses `&out' on a local s16 value,
+where that is correct.
+
+Drop the spurious `&' so the i2c read writes into the caller's
+buffer.
+
+Fixes: 9dbf091da080 ("iio: gyro: Add itg3200")
+Cc: stable@vger.kernel.org
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/gyro/itg3200_buffer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/gyro/itg3200_buffer.c
++++ b/drivers/iio/gyro/itg3200_buffer.c
+@@ -34,7 +34,7 @@ static int itg3200_read_all_channels(str
+ .addr = i2c->addr,
+ .flags = i2c->flags | I2C_M_RD,
+ .len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
+- .buf = (char *)&buf,
++ .buf = (char *)buf,
+ },
+ };
+
--- /dev/null
+From 1f4f0bcc5255dec5c4c3a1551bf49d8c33b69b20 Mon Sep 17 00:00:00 2001
+From: Aldo Conte <aldocontelk@gmail.com>
+Date: Tue, 7 Apr 2026 17:17:01 +0200
+Subject: iio: light: cm3323: fix reg_conf not being initialized correctly
+
+From: Aldo Conte <aldocontelk@gmail.com>
+
+commit 1f4f0bcc5255dec5c4c3a1551bf49d8c33b69b20 upstream.
+
+The code stores the return value of i2c_smbus_write_word_data()
+in data->reg_conf; however, this value represents the result
+of the write operation and not the value actually written to
+the configuration register. This meant that the contents of
+data->reg_conf did not truly reflect the contents
+of the hardware register.
+
+Instead, save the value of the register before the write
+and use this value in the I2C write.
+
+The bug was found by code inspection: i2c_smbus_write_word_data()
+returns 0 on success, not the value written to the register.
+
+Tested using i2c-stub on a Raspberry Pi 3B running a custom 6.19.10
+kernel. Before loading the driver, the configuration register 0x00
+CM3323_CMD_CONF was populated with 0x0030 using
+`i2cset -y 11 0x10 0x00 0x0030 w`, encoding an integration time of 320ms
+in bits[6:4].
+
+Due to incorrect initialization of data->reg_conf in
+cm3323_init(), the print of integration_time returns 0.040000
+instead of the expected 0.320000. This happens because the read of the
+integration_time depends on cm3323_get_it_bits() that is based on the
+value of data->reg_conf, which is erroneously set to 0.
+
+With this fix applied, data->reg_conf correctly saves 0x0030 after init
+and the successive integration_time reports 0.320000 as expected.
+
+Fixes: 8b0544263761 ("iio: light: Add support for Capella CM3323 color sensor")
+Cc: stable@vger.kernel.org
+Signed-off-by: Aldo Conte <aldocontelk@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/light/cm3323.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/light/cm3323.c
++++ b/drivers/iio/light/cm3323.c
+@@ -89,15 +89,14 @@ static int cm3323_init(struct iio_dev *i
+
+ /* enable sensor and set auto force mode */
+ ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);
++ data->reg_conf = ret;
+
+- ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
++ ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, data->reg_conf);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "Error writing reg_conf\n");
+ return ret;
+ }
+
+- data->reg_conf = ret;
+-
+ return 0;
+ }
+
--- /dev/null
+From b66f922f6a4fa92840f662fbcfeb4f8a0f774bcc Mon Sep 17 00:00:00 2001
+From: Felix Gu <ustc.gu@gmail.com>
+Date: Fri, 27 Mar 2026 20:27:54 +0800
+Subject: iio: light: veml6070: Fix resource leak in probe error path
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+commit b66f922f6a4fa92840f662fbcfeb4f8a0f774bcc upstream.
+
+The driver calls i2c_new_dummy_device() to create a dummy device,
+then calls i2c_smbus_write_byte(). If i2c_smbus_write_byte() fails and
+returns, the cleanup via devm_add_action_or_reset() was never registered,
+so the dummy device leaks.
+
+Switch to devm_i2c_new_dummy_device() which registers cleanup atomically
+with device creation, eliminating the error-path window.
+
+Fixes: 7501bff87c3e ("iio: light: veml6070: add action for i2c_unregister_device")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/light/veml6070.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+--- a/drivers/iio/light/veml6070.c
++++ b/drivers/iio/light/veml6070.c
+@@ -245,13 +245,6 @@ static const struct iio_info veml6070_in
+ .write_raw = veml6070_write_raw,
+ };
+
+-static void veml6070_i2c_unreg(void *p)
+-{
+- struct veml6070_data *data = p;
+-
+- i2c_unregister_device(data->client2);
+-}
+-
+ static int veml6070_probe(struct i2c_client *client)
+ {
+ struct veml6070_data *data;
+@@ -281,7 +274,8 @@ static int veml6070_probe(struct i2c_cli
+ if (ret < 0)
+ return ret;
+
+- data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB);
++ data->client2 = devm_i2c_new_dummy_device(&client->dev, client->adapter,
++ VEML6070_ADDR_DATA_LSB);
+ if (IS_ERR(data->client2))
+ return dev_err_probe(&client->dev, PTR_ERR(data->client2),
+ "i2c device for second chip address failed\n");
+@@ -292,10 +286,6 @@ static int veml6070_probe(struct i2c_cli
+ if (ret < 0)
+ return ret;
+
+- ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data);
+- if (ret < 0)
+- return ret;
+-
+ return devm_iio_device_register(&client->dev, indio_dev);
+ }
+
--- /dev/null
+From 49f79cd28f1e3333cbe0d616ce59ead0b24bf34e Mon Sep 17 00:00:00 2001
+From: Advait Dhamorikar <advaitd@mechasystems.com>
+Date: Tue, 7 Apr 2026 12:50:59 +0530
+Subject: iio: magnetometer: st_magn: fix default DRDY pin selection for LIS2MDL
+
+From: Advait Dhamorikar <advaitd@mechasystems.com>
+
+commit 49f79cd28f1e3333cbe0d616ce59ead0b24bf34e upstream.
+
+The device tree binding for st,lis2mdl does not support
+st,drdy-int-pin property. However, when no platform data is provided
+and the property is absent, the driver falls back to default_magn_pdata
+which hardcodes drdy_int_pin = 2. This causes
+`st_sensors_set_drdy_int_pin` to fail with -EINVAL because the LIS2MDL
+sensor settings have no INT2 DRDY mask defined.
+
+Fix this by checking the sensor's INT2 DRDY mask availability at
+probe time and selecting the appropriate default pin. Sensors that
+do not support INT2 DRDY will default to INT1, while all others
+retain the existing default of INT2.
+
+Fixes: 38934daf7b5c ("iio: magnetometer: st_magn: Provide default platform data")
+Signed-off-by: Advait Dhamorikar <advaitd@mechasystems.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/magnetometer/st_magn_core.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/magnetometer/st_magn_core.c
++++ b/drivers/iio/magnetometer/st_magn_core.c
+@@ -506,6 +506,11 @@ static const struct st_sensors_platform_
+ .drdy_int_pin = 2,
+ };
+
++/* LIS2MDL only supports DRDY on INT1 */
++static const struct st_sensors_platform_data alt_magn_pdata = {
++ .drdy_int_pin = 1,
++};
++
+ static int st_magn_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *ch, int *val,
+ int *val2, long mask)
+@@ -628,8 +633,12 @@ int st_magn_common_probe(struct iio_dev
+ mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
+ mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
+
+- if (!pdata)
+- pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
++ if (!pdata) {
++ if (mdata->sensor_settings->drdy_irq.int2.mask)
++ pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
++ else
++ pdata = (struct st_sensors_platform_data *)&alt_magn_pdata;
++ }
+
+ err = st_sensors_init_sensor(indio_dev, pdata);
+ if (err < 0)
--- /dev/null
+From eedf7602fbd929e97e0c480da501dc7a34beb2a8 Mon Sep 17 00:00:00 2001
+From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
+Date: Sun, 26 Apr 2026 14:47:04 +0530
+Subject: iio: ssp_sensors: cancel delayed work_refresh on remove
+
+From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
+
+commit eedf7602fbd929e97e0c480da501dc7a34beb2a8 upstream.
+
+The work_refresh may still be pending or running when the device is
+removed, cancel the delayed work_refresh in remove path.
+
+Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver")
+Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/common/ssp_sensors/ssp_dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/common/ssp_sensors/ssp_dev.c
++++ b/drivers/iio/common/ssp_sensors/ssp_dev.c
+@@ -590,6 +590,7 @@ static void ssp_remove(struct spi_device
+ ssp_clean_pending_list(data);
+
+ free_irq(data->spi->irq, data);
++ cancel_delayed_work_sync(&data->work_refresh);
+
+ timer_delete_sync(&data->wdt_timer);
+ cancel_work_sync(&data->work_wdt);
--- /dev/null
+From 4701e471c16866e7aa8f5e6a3a6b0d31e097e2c9 Mon Sep 17 00:00:00 2001
+From: Salah Triki <salah.triki@gmail.com>
+Date: Tue, 5 May 2026 08:10:24 +0100
+Subject: iio: temperature: tsys01: fix broken PROM checksum validation
+
+From: Salah Triki <salah.triki@gmail.com>
+
+commit 4701e471c16866e7aa8f5e6a3a6b0d31e097e2c9 upstream.
+
+The current implementation of tsys01_crc_valid() incorrectly sums the
+first word (n_prom[0]) repeatedly instead of iterating over the 8 words
+retrieved from the PROM. This leads to a checksum mismatch and probe
+failure on hardware.
+
+According to the TSYS01 datasheet, the PROM consists of 8 words. A valid
+check must iterate through all 8 words to verify the integrity of the
+calibration data. The current driver only checks the first word 8 times.
+
+Note: This fix was identified during a code audit and is based on
+datasheet specifications. It has not been tested on real hardware.
+
+Fixes: 43e53407f680 ("Add tsys01 meas-spec driver support")
+Signed-off-by: Salah Triki <salah.triki@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/temperature/tsys01.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/temperature/tsys01.c
++++ b/drivers/iio/temperature/tsys01.c
+@@ -119,7 +119,7 @@ static bool tsys01_crc_valid(u16 *n_prom
+ u8 sum = 0;
+
+ for (cnt = 0; cnt < TSYS01_PROM_WORDS_NB; cnt++)
+- sum += ((n_prom[0] >> 8) + (n_prom[0] & 0xFF));
++ sum += ((n_prom[cnt] >> 8) + (n_prom[cnt] & 0xFF));
+
+ return (sum == 0);
+ }
--- /dev/null
+From 76b0d0baa9ae9c60e726bbe1b6ff0bec2c993634 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Sat, 25 Apr 2026 22:07:06 -0700
+Subject: Input: elan_i2c - validate firmware size before use
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 76b0d0baa9ae9c60e726bbe1b6ff0bec2c993634 upstream.
+
+Ensure that the firmware file is large enough to contain the expected
+number of pages and the signature (which resides at the end of the
+firmware blob) before accessing them to prevent potential out-of-bounds
+reads.
+
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/ae2dOgiFvXRm4BHo@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/mouse/elan_i2c_core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/input/mouse/elan_i2c_core.c
++++ b/drivers/input/mouse/elan_i2c_core.c
+@@ -645,6 +645,11 @@ static ssize_t elan_sysfs_update_fw(stru
+ return error;
+ }
+
++ if (fw->size < data->fw_signature_address + sizeof(signature)) {
++ dev_err(dev, "firmware file too small\n");
++ return -EBADF;
++ }
++
+ /* Firmware file must match signature data */
+ fw_signature = &fw->data[data->fw_signature_address];
+ if (memcmp(fw_signature, signature, sizeof(signature)) != 0) {
--- /dev/null
+From 6cdc46b38cf146ce81d4831b6472dbf7731849a2 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Sun, 26 Apr 2026 21:09:33 -0700
+Subject: Input: xpad - fix out-of-bounds access for Share button
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 6cdc46b38cf146ce81d4831b6472dbf7731849a2 upstream.
+
+xpadone_process_packet() receives len directly from urb->actual_length
+and uses it to index the share-button byte at data[len - 18] or
+data[len - 26]. Since both len and data[0] are under the device's
+control, a broken controller can send a GIP_CMD_INPUT packet with
+actual_length < 18 (e.g. 5 bytes) and reach this code path, causing
+accesses beyond the actual array.
+
+Fix this by calculating the offset and checking bounds against the
+packet length.
+
+Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Fixes: 4ef46367073b ("Input: xpad - fix Share button on Xbox One controllers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/joystick/xpad.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -1110,10 +1110,10 @@ static void xpadone_process_packet(struc
+ input_report_key(dev, BTN_START, data[4] & BIT(2));
+ input_report_key(dev, BTN_SELECT, data[4] & BIT(3));
+ if (xpad->mapping & MAP_SHARE_BUTTON) {
+- if (xpad->mapping & MAP_SHARE_OFFSET)
+- input_report_key(dev, KEY_RECORD, data[len - 26] & BIT(0));
+- else
+- input_report_key(dev, KEY_RECORD, data[len - 18] & BIT(0));
++ u32 offset = (xpad->mapping & MAP_SHARE_OFFSET) ? 26 : 18;
++
++ if (len >= offset)
++ input_report_key(dev, KEY_RECORD, data[len - offset] & BIT(0));
+ }
+
+ /* buttons A,B,X,Y */
--- /dev/null
+From fa0b9b2b7ae3539908d69c2b9ac0d144d9bc5139 Mon Sep 17 00:00:00 2001
+From: Linpu Yu <linpu5433@gmail.com>
+Date: Sun, 10 May 2026 13:43:30 +0800
+Subject: ipc: limit next_id allocation to the valid ID range
+
+From: Linpu Yu <linpu5433@gmail.com>
+
+commit fa0b9b2b7ae3539908d69c2b9ac0d144d9bc5139 upstream.
+
+The checkpoint/restore sysctl path can request the next SysV IPC id
+through ids->next_id. ipc_idr_alloc() currently forwards that request to
+idr_alloc() with an open-ended upper bound.
+
+If the valid tail of the SysV IPC id space is full, the allocation can
+spill beyond ipc_mni. The returned SysV IPC id still uses the normal
+index encoding, so later lookup and removal can target the wrong slot.
+This leaves the real IDR entry behind and breaks the IDR state for the
+object.
+
+The bug is in ipc_idr_alloc() in the checkpoint/restore path.
+
+1. ids->next_id is passed to:
+
+ idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id), 0, ...)
+
+2. The zero upper bound makes the allocation effectively open-ended.
+ Once the valid SysV IPC tail is occupied, idr_alloc() can spill past
+ ipc_mni and allocate an entry beyond the valid IPC id range.
+
+3. The new object id is still encoded with the narrower SysV IPC index
+ width:
+
+ new->id = (new->seq << ipcmni_seq_shift()) + idx
+
+4. Later removal goes through ipc_rmid(), which uses:
+
+ ipcid_to_idx(ipcp->id)
+
+ That truncates the real IDR index. An object actually stored at a
+ high index can then be removed as if it lived at a low in-range
+ index.
+
+5. For shared memory, shm_destroy() frees the current object anyway, but
+ the real high IDR slot is left behind as a dangling pointer.
+
+6. A subsequent walk of /proc/sysvipc/shm reaches the stale IDR entry
+ and dereferences freed memory.
+
+Prevent this by bounding the requested allocation to ipc_mni so the
+checkpoint/restore path fails once the valid range is exhausted.
+
+Link: https://lore.kernel.org/cover.1778336914.git.linpu5433@gmail.com
+Link: https://lore.kernel.org/2eebe949bfa7d1f6e13b5be6a92c64c850ce9d45.1778336914.git.linpu5433@gmail.com
+Fixes: 03f595668017 ("ipc: add sysctl to specify desired next object id")
+Signed-off-by: Linpu Yu <linpu5433@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Cc: Kees Cook <kees@kernel.org>
+Cc: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Cc: Davidlohr Bueso <dave@stgolabs.net>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ ipc/util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/ipc/util.c
++++ b/ipc/util.c
+@@ -253,7 +253,7 @@ static inline int ipc_idr_alloc(struct i
+ } else {
+ new->seq = ipcid_to_seqx(next_id);
+ idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id),
+- 0, GFP_NOWAIT);
++ ipc_mni, GFP_NOWAIT);
+ }
+ if (idx >= 0)
+ new->id = (new->seq << ipcmni_seq_shift()) + idx;
--- /dev/null
+From 83726330748981372bde86ed5411d7b306612991 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Fri, 29 May 2026 00:01:44 +0100
+Subject: KVM: arm64: Correctly cap ZCR_EL2 provided by a guest hypervisor
+
+From: Mark Brown <broonie@kernel.org>
+
+commit 83726330748981372bde86ed5411d7b306612991 upstream.
+
+ZCR_EL2 can be updated by a VHE guest hypervisor either using ZCR_EL2
+(which traps) or ZCR_EL1 (which does not trap). KVM handles both in
+different way:
+
+- on ZCR_EL2 trap, ZCR_EL2.LEN is immediately capped at the VM's own
+ VL limit. This has the potential to break existing SW that relies
+ on the full LEN field to be stateful.
+
+- on ZCR_EL1 access, we do absolutely nothing.
+
+On restoring the SVE context for an L2 guest, we directly restore the
+guest hypervisor's view of ZCR_EL2 into the physical ZCR_EL2. If the
+guest's view of the register was updated using the ZCR_EL2 accessor,
+the value has already been sanitised (with the caveat mentioned above).
+
+But if the guest used ZCR_EL1, the raw value is written into the HW,
+and the L2 guest can now access VLs that it shouldn't.
+
+Fix all the above by moving the VL capping to the restore points,
+ensuring that:
+
+- the HW is always programmed with a capped value, irrespective of
+ the accessor being used,
+
+- the ZCR_EL2.LEN field is always completely stateful, irrespective
+ of the accessor being used.
+
+Additionally, move ZCR_EL2 to be a sanitised register, ensuring that
+only the LEN field is actually stateful. This requires some creative
+construction of the RES0 mask, as the sysreg generation script does
+not yet generate RAZ/WI fields.
+
+Fixes: b3d29a823099 ("KVM: arm64: nv: Handle ZCR_EL2 traps")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260529-kvm-arm64-fix-zcr-len-nv-v2-1-86cad51992bd@kernel.org
+[maz: rewrote commit message, tidy up access_zcr_el2()]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/kvm_host.h | 2 +-
+ arch/arm64/kvm/hyp/include/hyp/switch.h | 16 ++++++++++------
+ arch/arm64/kvm/nested.c | 5 +++++
+ arch/arm64/kvm/sys_regs.c | 11 +++--------
+ 4 files changed, 19 insertions(+), 15 deletions(-)
+
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -495,7 +495,6 @@ enum vcpu_sysreg {
+ ACTLR_EL2, /* Auxiliary Control Register (EL2) */
+ CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
+ HACR_EL2, /* Hypervisor Auxiliary Control Register */
+- ZCR_EL2, /* SVE Control Register (EL2) */
+ TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
+ TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
+ TCR_EL2, /* Translation Control Register (EL2) */
+@@ -527,6 +526,7 @@ enum vcpu_sysreg {
+ SCTLR2_EL2, /* System Control Register 2 (EL2) */
+ MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
+ CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
++ ZCR_EL2, /* SVE Control Register (EL2) */
+
+ /* Any VNCR-capable reg goes after this point */
+ MARKER(__VNCR_START__),
+--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
++++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
+@@ -431,11 +431,13 @@ static inline bool kvm_hyp_handle_mops(s
+
+ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
+ {
++ u64 zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
++
+ /*
+ * The vCPU's saved SVE state layout always matches the max VL of the
+ * vCPU. Start off with the max VL so we can load the SVE state.
+ */
+- sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
++ sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
+ __sve_restore_state(vcpu_sve_pffr(vcpu),
+ &vcpu->arch.ctxt.fp_regs.fpsr,
+ true);
+@@ -445,8 +447,10 @@ static inline void __hyp_sve_restore_gue
+ * nested guest, as the guest hypervisor could select a smaller VL. Slap
+ * that into hardware before wrapping up.
+ */
+- if (is_nested_ctxt(vcpu))
+- sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
++ if (is_nested_ctxt(vcpu)) {
++ zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
++ sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
++ }
+
+ write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
+ }
+@@ -470,11 +474,11 @@ static inline void fpsimd_lazy_switch_to
+ return;
+
+ if (vcpu_has_sve(vcpu)) {
++ zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
++
+ /* A guest hypervisor may restrict the effective max VL. */
+ if (is_nested_ctxt(vcpu))
+- zcr_el2 = __vcpu_sys_reg(vcpu, ZCR_EL2);
+- else
+- zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
++ zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
+
+ write_sysreg_el2(zcr_el2, SYS_ZCR);
+
+--- a/arch/arm64/kvm/nested.c
++++ b/arch/arm64/kvm/nested.c
+@@ -1825,6 +1825,11 @@ int kvm_init_nv_sysregs(struct kvm_vcpu
+ resx.res1 = VNCR_EL2_RES1;
+ set_sysreg_masks(kvm, VNCR_EL2, resx);
+
++ /* ZCR_EL2 - bits 8:4 are RAZ/WI so treat them as RES0 */
++ resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4);
++ resx.res1 = ZCR_ELx_RES1;
++ set_sysreg_masks(kvm, ZCR_EL2, resx);
++
+ out:
+ for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++)
+ __vcpu_rmw_sys_reg(vcpu, sr, |=, 0);
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -2764,21 +2764,16 @@ static bool access_zcr_el2(struct kvm_vc
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
+ {
+- unsigned int vq;
+-
+ if (guest_hyp_sve_traps_enabled(vcpu)) {
+ kvm_inject_nested_sve_trap(vcpu);
+ return false;
+ }
+
+- if (!p->is_write) {
++ if (!p->is_write)
+ p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2);
+- return true;
+- }
++ else
++ __vcpu_assign_sys_reg(vcpu, ZCR_EL2, p->regval);
+
+- vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
+- vq = min(vq, vcpu_sve_max_vq(vcpu));
+- __vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1);
+ return true;
+ }
+
--- /dev/null
+From 1750ad1388e03fb27068cd1f22c9c8b4590fe936 Mon Sep 17 00:00:00 2001
+From: Qiang Ma <maqianga@uniontech.com>
+Date: Tue, 26 May 2026 15:46:40 +0800
+Subject: KVM: arm64: PMU: Preserve AArch32 counter low bits
+
+From: Qiang Ma <maqianga@uniontech.com>
+
+commit 1750ad1388e03fb27068cd1f22c9c8b4590fe936 upstream.
+
+AArch32 writes to PMU event counters cannot update the top 32 bits,
+even when PMUv3p5 makes the counters 64-bit. KVM therefore needs to
+preserve the existing high half and only update the low half written by
+the guest, unless the caller explicitly forces a full reset through
+PMCR.P.
+
+The current code masks @val down to the old high half before taking
+lower_32_bits(val), which means the low half is always zero. As a
+result, AArch32 writes to event counters discard the guest-provided low
+32 bits instead of storing them.
+
+Build the new value from the old high 32 bits and the low 32 bits of
+the value supplied by the guest.
+
+Fixes: 26d2d0594d70 ("KVM: arm64: PMU: Do not let AArch32 change the counters' top 32 bits")
+Signed-off-by: Qiang Ma <maqianga@uniontech.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://patch.msgid.link/20260526074640.791991-1-maqianga@uniontech.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/pmu-emul.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kvm/pmu-emul.c
++++ b/arch/arm64/kvm/pmu-emul.c
+@@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct
+ * action is to use PMCR.P, which will reset them to
+ * 0 (the only use of the 'force' parameter).
+ */
+- val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32);
+- val |= lower_32_bits(val);
++ val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) |
++ lower_32_bits(val);
+ }
+
+ __vcpu_assign_sys_reg(vcpu, reg, val);
--- /dev/null
+From 121d88de56bc5c0ba0ce2f6381af67f948a7e7c1 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:34 -0700
+Subject: KVM: SEV: Check PSC request indices against the actual size of the buffer
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 121d88de56bc5c0ba0ce2f6381af67f948a7e7c1 upstream.
+
+When processing Page State Change (PSC) requests, validate the PSC buffer
+against the effective size of the scratch area, which could be less than
+the maximum size if the guest provided a pointer that isn't exactly at the
+start of the GHCB shared buffer.
+
+Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Michael Roth <michael.roth@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-10-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3857,7 +3857,7 @@ static int snp_begin_psc(struct vcpu_svm
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct psc_hdr *hdr = &psc->hdr;
+ struct psc_entry entry_start;
+- u16 idx, idx_start, idx_end;
++ u16 idx, idx_start, idx_end, max_nr_entries;
+ int npages;
+ bool huge;
+ u64 gfn;
+@@ -3867,6 +3867,19 @@ static int snp_begin_psc(struct vcpu_svm
+ return 1;
+ }
+
++ /*
++ * GHCB v2 requires the scratch area to reside within the GHCB itself,
++ * and PSC requests are only supported for GHCB v2+. Thus it should be
++ * impossible to exceed the max PSC entry count (which is derived from
++ * the size of the shared GHCB buffer).
++ */
++ max_nr_entries = (sev_es->ghcb_sa_len - sizeof(struct psc_hdr)) /
++ sizeof(struct psc_entry);
++ if (WARN_ON_ONCE(max_nr_entries > VMGEXIT_PSC_MAX_COUNT)) {
++ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
++ return 1;
++ }
++
+ next_range:
+ /* There should be no other PSCs in-flight at this point. */
+ if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) {
+@@ -3882,7 +3895,7 @@ next_range:
+ idx_start = hdr->cur_entry;
+ idx_end = hdr->end_entry;
+
+- if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {
++ if (idx_end >= max_nr_entries) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
+ return 1;
+ }
--- /dev/null
+From 5867d7e202e09f037cefe77f7af4413c7c0fa088 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:31 -0700
+Subject: KVM: SEV: Compute the correct max length of the in-GHCB scratch area
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 5867d7e202e09f037cefe77f7af4413c7c0fa088 upstream.
+
+When setting the length of the GHCB scratch area, and the area is in the
+GHCB shared buffer, set the effective length of the scratch area to the max
+possible size given the start of the guest-provided pointer, and the end of
+the shared buffer.
+
+The code was "fine" when first introduced, as KVM doesn't consult the
+length of the buffer when emulating MMIO, because the passed in @len always
+specifies the *max* size required. But for PSC requests, the incoming @len
+is just the minimum length (to process the header), and KVM needs to know
+the full size of the scratch area to avoid buffer overflows (spoiler alert).
+
+Opportunistically rename @len => @min_len to better reflect its role.
+
+Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Michael Roth <michael.roth@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-7-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3617,7 +3617,7 @@ int pre_sev_run(struct vcpu_svm *svm, in
+ }
+
+ #define GHCB_SCRATCH_AREA_LIMIT (16ULL * PAGE_SIZE)
+-static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 len)
++static int setup_vmgexit_scratch(struct vcpu_svm *svm, bool sync, u64 min_len)
+ {
+ struct vmcb_control_area *control = &svm->vmcb->control;
+ u64 ghcb_scratch_beg, ghcb_scratch_end;
+@@ -3633,10 +3633,10 @@ static int setup_vmgexit_scratch(struct
+ goto e_scratch;
+ }
+
+- scratch_gpa_end = scratch_gpa_beg + len;
++ scratch_gpa_end = scratch_gpa_beg + min_len;
+ if (scratch_gpa_end < scratch_gpa_beg) {
+ pr_err("vmgexit: scratch length (%#llx) not valid for scratch address (%#llx)\n",
+- len, scratch_gpa_beg);
++ min_len, scratch_gpa_beg);
+ goto e_scratch;
+ }
+
+@@ -3660,6 +3660,8 @@ static int setup_vmgexit_scratch(struct
+
+ scratch_va = (void *)svm->sev_es.ghcb;
+ scratch_va += (scratch_gpa_beg - control->ghcb_gpa);
++
++ svm->sev_es.ghcb_sa_len = ghcb_scratch_end - scratch_gpa_beg;
+ } else {
+ /* GHCB v2 requires the scratch area to be within the GHCB. */
+ if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
+@@ -3669,16 +3671,16 @@ static int setup_vmgexit_scratch(struct
+ * The guest memory must be read into a kernel buffer, so
+ * limit the size
+ */
+- if (len > GHCB_SCRATCH_AREA_LIMIT) {
++ if (min_len > GHCB_SCRATCH_AREA_LIMIT) {
+ pr_err("vmgexit: scratch area exceeds KVM limits (%#llx requested, %#llx limit)\n",
+- len, GHCB_SCRATCH_AREA_LIMIT);
++ min_len, GHCB_SCRATCH_AREA_LIMIT);
+ goto e_scratch;
+ }
+- scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);
++ scratch_va = kvzalloc(min_len, GFP_KERNEL_ACCOUNT);
+ if (!scratch_va)
+ return -ENOMEM;
+
+- if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, len)) {
++ if (kvm_read_guest(svm->vcpu.kvm, scratch_gpa_beg, scratch_va, min_len)) {
+ /* Unable to copy scratch area from guest */
+ pr_err("vmgexit: kvm_read_guest for scratch area failed\n");
+
+@@ -3694,11 +3696,10 @@ static int setup_vmgexit_scratch(struct
+ */
+ svm->sev_es.ghcb_sa_sync = sync;
+ svm->sev_es.ghcb_sa_free = true;
++ svm->sev_es.ghcb_sa_len = min_len;
+ }
+
+ svm->sev_es.ghcb_sa = scratch_va;
+- svm->sev_es.ghcb_sa_len = len;
+-
+ return 0;
+
+ e_scratch:
--- /dev/null
+From ebe4b2dc9cfbfb2d8f665667c4d08f4c6c9bec05 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:33 -0700
+Subject: KVM: SEV: Don't explicitly pass PSC buffer to snp_begin_psc()
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit ebe4b2dc9cfbfb2d8f665667c4d08f4c6c9bec05 upstream.
+
+Stop explicitly passing the PSC buffer to snp_begin_psc(): it *must*
+be the scratch area. This will allow fixing a variety of bugs without
+further complicating the code.
+
+No functional change intended.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Michael Roth <michael.roth@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-9-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3796,7 +3796,7 @@ struct psc_buffer {
+ struct psc_entry entries[];
+ } __packed;
+
+-static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc);
++static int snp_begin_psc(struct vcpu_svm *svm);
+
+ static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
+ {
+@@ -3838,7 +3838,6 @@ static void __snp_complete_one_psc(struc
+ static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
+- struct psc_buffer *psc = svm->sev_es.ghcb_sa;
+
+ if (vcpu->run->hypercall.ret) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
+@@ -3848,11 +3847,13 @@ static int snp_complete_one_psc(struct k
+ __snp_complete_one_psc(svm);
+
+ /* Handle the next range (if any). */
+- return snp_begin_psc(svm, psc);
++ return snp_begin_psc(svm);
+ }
+
+-static int snp_begin_psc(struct vcpu_svm *svm, struct psc_buffer *psc)
++static int snp_begin_psc(struct vcpu_svm *svm)
+ {
++ struct vcpu_sev_es_state *sev_es = &svm->sev_es;
++ struct psc_buffer *psc = sev_es->ghcb_sa;
+ struct psc_entry *entries = psc->entries;
+ struct kvm_vcpu *vcpu = &svm->vcpu;
+ struct psc_hdr *hdr = &psc->hdr;
+@@ -4540,7 +4541,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *
+ if (ret)
+ break;
+
+- ret = snp_begin_psc(svm, svm->sev_es.ghcb_sa);
++ ret = snp_begin_psc(svm);
+ break;
+ case SVM_VMGEXIT_AP_CREATION:
+ ret = sev_snp_ap_creation(svm);
--- /dev/null
+From 3988bd2723de407ae90fa7a6f6029b4e60238c58 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:29 -0700
+Subject: KVM: SEV: Ignore Port I/O requests of length '0'
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 3988bd2723de407ae90fa7a6f6029b4e60238c58 upstream.
+
+Explicitly ignore Port I/O requests of length '0' (or count '0'), so that
+setting up the software scratch area (and other code) doesn't have to
+worry about underflowing the length, and to allow for WARNing on trying
+to configure the scratch area with len==0.
+
+Fixes: 291bd20d5d88 ("KVM: SVM: Add initial support for a VMGEXIT VMEXIT")
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-5-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -4545,6 +4545,11 @@ int sev_handle_vmgexit(struct kvm_vcpu *
+ control->exit_info_1, control->exit_info_2);
+ ret = -EINVAL;
+ break;
++ case SVM_EXIT_IOIO:
++ if (!((control->exit_info_1 & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT))
++ return 1;
++
++ fallthrough;
+ default:
+ ret = svm_invoke_exit_handler(vcpu, control->exit_code);
+ }
+@@ -4565,6 +4570,9 @@ int sev_es_string_io(struct vcpu_svm *sv
+ if (unlikely(check_mul_overflow(count, size, &bytes)))
+ return -EINVAL;
+
++ if (!bytes)
++ return 1;
++
+ r = setup_vmgexit_scratch(svm, in, bytes);
+ if (r)
+ return r;
--- /dev/null
+From db3f2195d29344a3cf1e9dd9ab7f21ced7308cf7 Mon Sep 17 00:00:00 2001
+From: Michael Roth <michael.roth@amd.com>
+Date: Fri, 1 May 2026 13:22:26 -0700
+Subject: KVM: SEV: Require in-GHCB scratch area if GHCB v2+ is in use
+
+From: Michael Roth <michael.roth@amd.com>
+
+commit db3f2195d29344a3cf1e9dd9ab7f21ced7308cf7 upstream.
+
+As per the GHCB spec, when using GHCB v2+ require the software scratch area
+to reside in the GHCB's shared buffer. Note, things like Page State Change
+(PSC) requests _rely_ on this behavior, as the guest can't provide a length
+when making the request, i.e. the size of the guest payload is bounded by
+the size of the shared buffer.
+
+Failure to force usage of the GHCB, and a slew of other flaws, lets a
+malicious SNP guest corrupt host kernel heap memory, and leak host heap
+layout information.
+
+setup_vmgexit_scratch() allocates a buffer via kvzalloc(exit_info_2),
+where exit_info_2 is guest-controlled. With exit_info_2=24, this yields
+a 24-byte allocation in kmalloc-cg-32 (32-byte slab objects). The buffer
+holds an 8-byte psc_hdr followed by 8-byte psc_entry structs, so only
+entries[0] and entries[1] are in-bounds.
+
+snp_begin_psc() validates end_entry against VMGEXIT_PSC_MAX_COUNT (253)
+but NOT against the actual buffer size:
+
+ idx_end = hdr->end_entry;
+
+ if (idx_end >= VMGEXIT_PSC_MAX_COUNT) { // checks 253, not buffer
+ snp_complete_psc(svm, ...);
+ return 1;
+ }
+
+ for (idx = idx_start; idx <= idx_end; idx++) {
+ entry_start = entries[idx]; // OOB when idx >= 2
+
+The guest sets end_entry=10+, causing the host to iterate entries[2+]
+which are OOB into adjacent slab objects. For each OOB entry:
+
+ - The host reads 8 bytes (OOB READ / info leak oracle)
+ - If the data passes PSC validation, __snp_complete_one_psc() writes
+ cur_page = 1 or 512 into the entry (OOB WRITE, sev.c:3806)
+ - If validation fails, the error response reveals whether adjacent
+ memory is zero vs non-zero (information disclosure to guest)
+
+The guest controls allocation size (exit_info_2), entry range
+(cur_entry/end_entry), and can fire unlimited VMGEXITs to repeatedly
+hit different slab positions.
+
+By exploiting the variety of bugs, a malicious SEV-SNP guest can:
+ - OOB read adjacent kmalloc-cg-32 objects (heap layout disclosure)
+ - OOB write cur_page bits into adjacent objects (heap corruption)
+ - Trigger use-after-free conditions across VMGEXITs
+
+E.g. with KASAN enabled, a single insmod of the PoC guest module
+produces 73 KASAN reports:
+
+ BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
+ Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199
+
+ BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
+ Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199
+
+ The buggy address belongs to the object at ffff888XXXXXXXXX
+ which belongs to the cache kmalloc-cg-32 of size 32
+ The buggy address is located N bytes to the right of
+ allocated 32-byte region [ffff888XXXXXXXXX, ffff888XXXXXXXXX)
+
+ Breakdown:
+ 62 slab-out-of-bounds (reads + writes past allocation)
+ 7 slab-use-after-free
+ 4 use-after-free
+
+All credit to Stan for the wonderful description and reproducer!
+
+Reported-by: Stan Shaw <shawstan96@gmail.com>
+Cc: Michael Roth <michael.roth@amd.com>
+Cc: Tom Lendacky <thomas.lendacky@amd.com>
+Cc: Peter Gonda <pgonda@google.com>
+Cc: Jacky Li <jackyli@google.com>
+Fixes: 4af663c2f64a ("KVM: SEV: Allow per-guest configuration of GHCB protocol version")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Roth <michael.roth@amd.com>
+[sean: write changelog]
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-2-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3658,6 +3658,10 @@ static int setup_vmgexit_scratch(struct
+ scratch_va = (void *)svm->sev_es.ghcb;
+ scratch_va += (scratch_gpa_beg - control->ghcb_gpa);
+ } else {
++ /* GHCB v2 requires the scratch area to be within the GHCB. */
++ if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
++ goto e_scratch;
++
+ /*
+ * The guest memory must be read into a kernel buffer, so
+ * limit the size
--- /dev/null
+From c8cc238093ca6c99267032f6cfe78f59389f3157 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:35 -0700
+Subject: KVM: SEV: Use READ_ONCE() when reading entries/indices from PSC buffer
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit c8cc238093ca6c99267032f6cfe78f59389f3157 upstream.
+
+Use READ_ONCE() when reading entries/indices from the guest-accessible
+Page State Change buffer to defend against TOCTOU bugs.
+
+Don't bother with READ_ONCE()/WRITE_ONCE() for cases where KVM is writing
+(and not consuming the result!), as the guest isn't supposed to touch the
+buffer while it's being processed. I.e. using READ_ONCE() is all about
+protecting against misbehaving guests.
+
+Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-11-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3827,9 +3827,9 @@ static void __snp_complete_one_psc(struc
+ */
+ for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
+ svm->sev_es.psc_inflight--, idx++) {
+- struct psc_entry *entry = &entries[idx];
++ struct psc_entry entry = READ_ONCE(entries[idx]);
+
+- entry->cur_page = entry->pagesize ? 512 : 1;
++ entries[idx].cur_page = entry.pagesize ? 512 : 1;
+ }
+
+ hdr->cur_entry = idx;
+@@ -3892,8 +3892,8 @@ next_range:
+ * validation, so take care to only use validated copies of values used
+ * for things like array indexing.
+ */
+- idx_start = hdr->cur_entry;
+- idx_end = hdr->end_entry;
++ idx_start = READ_ONCE(hdr->cur_entry);
++ idx_end = READ_ONCE(hdr->end_entry);
+
+ if (idx_end >= max_nr_entries) {
+ snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
+@@ -3902,7 +3902,7 @@ next_range:
+
+ /* Find the start of the next range which needs processing. */
+ for (idx = idx_start; idx <= idx_end; idx++, hdr->cur_entry++) {
+- entry_start = entries[idx];
++ entry_start = READ_ONCE(entries[idx]);
+
+ gfn = entry_start.gfn;
+ huge = entry_start.pagesize;
+@@ -3946,7 +3946,7 @@ next_range:
+ * KVM_HC_MAP_GPA_RANGE exit.
+ */
+ while (++idx <= idx_end) {
+- struct psc_entry entry = entries[idx];
++ struct psc_entry entry = READ_ONCE(entries[idx]);
+
+ if (entry.operation != entry_start.operation ||
+ entry.gfn != entry_start.gfn + npages ||
--- /dev/null
+From 2be54670bdc017004c4a4b8bddb6ff02ebe7dbe2 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:30 -0700
+Subject: KVM: SEV: Use the size of the PSC header as the minimum size for PSC requests
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 2be54670bdc017004c4a4b8bddb6ff02ebe7dbe2 upstream.
+
+When handling a Page State Change (PSC) #VMGEXIT use the size of the PSC
+header as the minimum size for the scratch area. Per the GHCB spec, PSC
+requests do NOT provide the length, i.e. using control->exit_info_2 for the
+length is completely made up behavior. The existing code "works", e.g.
+even though Linux-as-a-guest always passes '0', because KVM doesn't do
+anything with the length when the request is in the GHCB's shared buffer.
+
+Use the header as the min length. Once the header is retrieved, KVM can
+use the specified indices to compute the full size of the request.
+
+Fixes: 9b54e248d264 ("KVM: SEV: Add support to handle Page State Change VMGEXIT")
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Michael Roth <michael.roth@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-6-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -4519,7 +4519,7 @@ int sev_handle_vmgexit(struct kvm_vcpu *
+ vcpu->run->system_event.data[0] = control->ghcb_gpa;
+ break;
+ case SVM_VMGEXIT_PSC:
+- ret = setup_vmgexit_scratch(svm, true, control->exit_info_2);
++ ret = setup_vmgexit_scratch(svm, true, sizeof(struct psc_hdr));
+ if (ret)
+ break;
+
--- /dev/null
+From f185e05dce6f170f83c4ba602e969b1c3c7a22e6 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 1 May 2026 13:22:32 -0700
+Subject: KVM: SEV: WARN if KVM attempts to setup scratch area with min_len==0
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit f185e05dce6f170f83c4ba602e969b1c3c7a22e6 upstream.
+
+Now that all paths in KVM properly validate the length needed for the
+scratch area, and are guaranteed to pass in a non-zero length, WARN if KVM
+attempts to configured the scratch area with min_len==0 to guard against
+future bugs.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Michael Roth <michael.roth@amd.com>
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20260501202250.2115252-8-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/sev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -3624,6 +3624,9 @@ static int setup_vmgexit_scratch(struct
+ u64 scratch_gpa_beg, scratch_gpa_end;
+ void *scratch_va;
+
++ if (WARN_ON_ONCE(!min_len))
++ goto e_scratch;
++
+ scratch_gpa_beg = svm->sev_es.sw_scratch;
+ if (!scratch_gpa_beg) {
+ pr_err("vmgexit: scratch gpa not provided\n");
--- /dev/null
+From a9e18aa3263f356edae305e29830e5fe63d8597a Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 15 May 2026 10:15:36 -0700
+Subject: KVM: SVM: Flush the current TLB when transitioning from xAVIC => x2AVIC
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit a9e18aa3263f356edae305e29830e5fe63d8597a upstream.
+
+Flush the current TLB when xAVIC *or* x2AVIC is activated, as KVM is
+(apparently) responsible for purging TLB entries when transitioning from
+xAVIC to x2AVIC. The APM says a whole lot of nothing about TLB flushing
+with respect to (x2)AVIC, but empirical data strongly suggests hardware
+also does a whole lot of nothing.
+
+Failure to flush the TLB when enabling x2AVIC can lead to guest accesses
+to the APIC base address getting incorrectly redirected to the virtual
+APIC page. The flaw most visibly manifests as failures in KVM-Unit-Test's
+verify_disabled_apic_mmio() testcase when x2APIC is enabled (though for
+reasons unknown, the test only reliably fails with EFI builds).
+
+Fixes: 0ccf3e7cb95a ("KVM: SVM: Flush the "current" TLB when activating AVIC")
+Fixes: 4d1d7942e36a ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode")
+Cc: stable@vger.kernel.org
+Cc: Naveen N Rao (AMD) <naveen@kernel.org>
+Link: https://patch.msgid.link/20260515171536.1841645-1-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/avic.c | 35 +++++++++++++++++++++++++++++------
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kvm/svm/avic.c
++++ b/arch/x86/kvm/svm/avic.c
+@@ -196,6 +196,35 @@ static void avic_activate_vmcb(struct vc
+ svm_clr_intercept(svm, INTERCEPT_CR8_WRITE);
+
+ /*
++ * Flush the TLB when enabling (x2)AVIC and when transitioning between
++ * xAVIC and x2AVIC, as the CPU may have inserted a TLB entry for the
++ * "wrong" mapping.
++ *
++ * KVM uses a per-VM "scratch" page to back the APIC memslot, because
++ * KVM also uses per-VM page tables *and* maintains the page table (NPT
++ * or shadow page) mappings for said memslot even if one or more vCPUs
++ * have their local APIC hardware-disabled or are in x2APIC mode, i.e.
++ * even if one or more vCPUs' APIC MMIO BAR is effectively disabled.
++ *
++ * If xAVIC is fully enabled, hardware ignores the physical address in
++ * KVM's page tables, i.e. in the leaf SPTE for the APIC memslot, and
++ * instead redirects the access to the AVIC backing page, i.e. to the
++ * vCPU's virtual APIC page. If xAVIC is not enabled (APIC is either
++ * hardware-disabled or in x2APIC mode), then guest accesses will use
++ * the page table mapping verbatim, i.e. will access the per-VM scratch
++ * page, as normal memory.
++ *
++ * In both cases, the CPU is allowed to cache TLB entries for the APIC
++ * base GPA. So, KVM needs to flush the TLB when enabling xAVIC, as
++ * accesses need to be redirected to the virtual APIC page, but the TLB
++ * may contain entries pointing at the scratch page. KVM also needs to
++ * flush the TLB when enabling x2AVIC, as accesses need to go to the
++ * scratch page, but the TLB may contain entries tagged as xAVIC, i.e.
++ * entries pointing to the vCPU's virtual APIC page.
++ */
++ kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu);
++
++ /*
+ * Note: KVM supports hybrid-AVIC mode, where KVM emulates x2APIC MSR
+ * accesses, while interrupt injection to a running vCPU can be
+ * achieved using AVIC doorbell. KVM disables the APIC access page
+@@ -208,12 +237,6 @@ static void avic_activate_vmcb(struct vc
+ /* Disabling MSR intercept for x2APIC registers */
+ avic_set_x2apic_msr_interception(svm, false);
+ } else {
+- /*
+- * Flush the TLB, the guest may have inserted a non-APIC
+- * mapping into the TLB while AVIC was disabled.
+- */
+- kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, &svm->vcpu);
+-
+ /* Enabling MSR intercept for x2APIC registers */
+ avic_set_x2apic_msr_interception(svm, true);
+ }
--- /dev/null
+From 3b041514cb6eae45869b020f743c14d983363222 Mon Sep 17 00:00:00 2001
+From: "Pratyush Yadav (Google)" <pratyush@kernel.org>
+Date: Tue, 5 May 2026 15:39:20 +0200
+Subject: memfd: deny writeable mappings when implying SEAL_WRITE
+
+From: Pratyush Yadav (Google) <pratyush@kernel.org>
+
+commit 3b041514cb6eae45869b020f743c14d983363222 upstream.
+
+When SEAL_EXEC is added, SEAL_WRITE is implied to make W^X. But the
+implied seal is set after the check that makes sure the memfd can not have
+any writable mappings. This means one can use SEAL_EXEC to apply
+SEAL_WRITE while having writeable mappings.
+
+This breaks the contract that SEAL_WRITE provides and can be used by an
+attacker to pass a memfd that appears to be write sealed but can still be
+modified arbitrarily.
+
+Fix this by adding the implied seals before the call for
+mapping_deny_writable() is done.
+
+Link: https://lore.kernel.org/20260505133922.797635-1-pratyush@kernel.org
+Fixes: c4f75bc8bd6b ("mm/memfd: add write seals when apply SEAL_EXEC to executable memfd")
+Signed-off-by: Pratyush Yadav (Google) <pratyush@kernel.org>
+Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
+Acked-by: Jeff Xu <jeffxu@google.com>
+Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Brendan Jackman <jackmanb@google.com>
+Cc: Greg Thelen <gthelen@google.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Kees Cook <kees@kernel.org>
+Cc: "David Hildenbrand (Arm)" <david@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memfd.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/mm/memfd.c
++++ b/mm/memfd.c
+@@ -283,6 +283,12 @@ static int memfd_add_seals(struct file *
+ goto unlock;
+ }
+
++ /*
++ * SEAL_EXEC implies SEAL_WRITE, making W^X from the start.
++ */
++ if (seals & F_SEAL_EXEC && inode->i_mode & 0111)
++ seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE;
++
+ if ((seals & F_SEAL_WRITE) && !(*file_seals & F_SEAL_WRITE)) {
+ error = mapping_deny_writable(file->f_mapping);
+ if (error)
+@@ -295,12 +301,6 @@ static int memfd_add_seals(struct file *
+ }
+ }
+
+- /*
+- * SEAL_EXEC implies SEAL_WRITE, making W^X from the start.
+- */
+- if (seals & F_SEAL_EXEC && inode->i_mode & 0111)
+- seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE;
+-
+ *file_seals |= seals;
+ error = 0;
+
--- /dev/null
+From 441f92f7d386b85bad16de49db95a307cba048a2 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Mon, 18 May 2026 08:25:58 -0700
+Subject: mm/damon/sysfs-schemes: delete tried region in regions_rmdirs()
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 441f92f7d386b85bad16de49db95a307cba048a2 upstream.
+
+DAMON sysfs maintains the DAMOS tried region directory objects via a
+linked list. When the user requests refresh of the directories, DAMON
+sysfs removes all the region directories first, and then generate updated
+regions directory on the empty space. The removal function
+(damon_sysfs_scheme_regions_rm_dirs()) only puts the kobj objects.
+Deletion of the container region object from the linked list is done
+inside the kobj release callback function.
+
+If somehow the callback invocation is delayed, the list will contain
+regions list that gonna be freed. If the updated region directories
+creation is started in this situation, the list can be corrupted and
+use-after-free can happen.
+
+Because the kobj objects are managed by only DAMON sysfs, the issue cannot
+happen in normal situation. But, such delays can be made on kernels that
+built with CONFIG_DEBUG_KOBJECT_RELEASE. On the kernel, the issue can
+indeed be reproduced like below.
+
+ # damo start --damos_action stat
+ # cd /sys/kernel/mm/damon/admin/kdamonds/0/
+ # for i in {1..10}; do echo update_schemes_tried_regions > state; done
+ # dmesg | grep underflow
+ [ 89.296152] refcount_t: underflow; use-after-free.
+
+Fix the issue by removing the region object from the list when
+decrementing the reference count.
+
+Also update damos_sysfs_populate_region_dir() to add the region object to
+the list only after the kobject_init_and_add() is success, so that fail of
+kobject_init_and_add() is not leaving the deallocated object on the list.
+
+The issue was discovered [1] by Sashiko.
+
+Link: https://lore.kernel.org/20260518152559.93038-1-sj@kernel.org
+Link: https://lore.kernel.org/20260513011920.119183-1-sj@kernel.org [1]
+Fixes: 9277d0367ba1 ("mm/damon/sysfs-schemes: implement scheme region directory")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.2.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/sysfs-schemes.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/mm/damon/sysfs-schemes.c
++++ b/mm/damon/sysfs-schemes.c
+@@ -88,7 +88,6 @@ static void damon_sysfs_scheme_region_re
+ struct damon_sysfs_scheme_region *region = container_of(kobj,
+ struct damon_sysfs_scheme_region, kobj);
+
+- list_del(®ion->list);
+ kfree(region);
+ }
+
+@@ -164,7 +163,7 @@ static void damon_sysfs_scheme_regions_r
+ struct damon_sysfs_scheme_region *r, *next;
+
+ list_for_each_entry_safe(r, next, ®ions->regions_list, list) {
+- /* release function deletes it from the list */
++ list_del(&r->list);
+ kobject_put(&r->kobj);
+ regions->nr_regions--;
+ }
+@@ -2870,14 +2869,15 @@ void damos_sysfs_populate_region_dir(str
+ if (!region)
+ return;
+ region->sz_filter_passed = sz_filter_passed;
+- list_add_tail(®ion->list, &sysfs_regions->regions_list);
+- sysfs_regions->nr_regions++;
+ if (kobject_init_and_add(®ion->kobj,
+ &damon_sysfs_scheme_region_ktype,
+ &sysfs_regions->kobj, "%d",
+ sysfs_regions->nr_regions++)) {
+ kobject_put(®ion->kobj);
++ return;
+ }
++ list_add_tail(®ion->list, &sysfs_regions->regions_list);
++ sysfs_regions->nr_regions++;
+ }
+
+ int damon_sysfs_schemes_clear_regions(
--- /dev/null
+From e16f17a9c5af50221184d1ef4be4056bf3c4209e Mon Sep 17 00:00:00 2001
+From: Alexandre Ghiti <alex@ghiti.fr>
+Date: Mon, 18 May 2026 10:28:19 +0200
+Subject: mm: memcontrol: propagate NMI slab stats to memcg vmstats
+
+From: Alexandre Ghiti <alex@ghiti.fr>
+
+commit e16f17a9c5af50221184d1ef4be4056bf3c4209e upstream.
+
+flush_nmi_stats() drains per-node NMI slab atomics into the per-node
+lruvec_stats, but does not propagate them to the memcg-level vmstats.
+
+For non NMI case, account_slab_nmi_safe() calls mod_memcg_lruvec_state()
+which updates both per-node lruvec_stats and memcg-level vmstats, so
+flush_nmi_stats() needs to flush to per-node lruvec_stats as well as
+memcg-level vmstats.
+
+So fix this by flushing to the memcg-level vmstats for NMI too.
+
+Link: https://lore.kernel.org/20260518082830.599102-1-alex@ghiti.fr
+Fixes: 940b01fc8dc1 ("memcg: nmi safe memcg stats for specific archs")
+Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
+Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Reviewed-by: Harry Yoo (Oracle) <harry@kernel.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Roman Gushchin <roman.gushchin@linux.dev>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memcontrol.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4085,6 +4085,9 @@ static void flush_nmi_stats(struct mem_c
+ lstats->state[index] += slab;
+ if (plstats)
+ plstats->state_pending[index] += slab;
++ memcg->vmstats->state[index] += slab;
++ if (parent)
++ parent->vmstats->state_pending[index] += slab;
+ }
+ if (atomic_read(&pn->slab_unreclaimable)) {
+ int slab = atomic_xchg(&pn->slab_unreclaimable, 0);
+@@ -4093,6 +4096,9 @@ static void flush_nmi_stats(struct mem_c
+ lstats->state[index] += slab;
+ if (plstats)
+ plstats->state_pending[index] += slab;
++ memcg->vmstats->state[index] += slab;
++ if (parent)
++ parent->vmstats->state_pending[index] += slab;
+ }
+ }
+ }
--- /dev/null
+From 2c6f81d58741349298f51ff697d988cb42881453 Mon Sep 17 00:00:00 2001
+From: Sunny Patel <nueralspacetech@gmail.com>
+Date: Fri, 1 May 2026 17:21:16 +0530
+Subject: mm/migrate_device: fix pgtable leak in migrate_vma_insert_huge_pmd_page
+
+From: Sunny Patel <nueralspacetech@gmail.com>
+
+commit 2c6f81d58741349298f51ff697d988cb42881453 upstream.
+
+When migrate_vma_insert_huge_pmd_page() jumps to unlock_abort due
+to a PMD check failure, the pgtable allocated earlier via
+pte_alloc_one() is never freed, causing a memory leak.
+
+Added free_abort label to release the pgtable in error path.
+
+Link: https://lore.kernel.org/20260501115122.23288-1-nueralspacetech@gmail.com
+Fixes: a30b48bf1b24 ("mm/migrate_device: implement THP migration of zone device pages")
+Signed-off-by: Sunny Patel <nueralspacetech@gmail.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Huang Ying <ying.huang@linux.alibaba.com>
+Cc: Alistair Popple <apopple@nvidia.com>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: Byungchul Park <byungchul@sk.com>
+Cc: Gregory Price <gourry@gourry.net>
+Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Rakie Kim <rakie.kim@sk.com>
+Cc: Zi Yan <ziy@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/migrate_device.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/mm/migrate_device.c
++++ b/mm/migrate_device.c
+@@ -846,7 +846,7 @@ static int migrate_vma_insert_huge_pmd_p
+ } else {
+ if (folio_is_zone_device(folio) &&
+ !folio_is_device_coherent(folio)) {
+- goto abort;
++ goto free_abort;
+ }
+ entry = folio_mk_pmd(folio, vma->vm_page_prot);
+ if (vma->vm_flags & VM_WRITE)
+@@ -899,6 +899,8 @@ static int migrate_vma_insert_huge_pmd_p
+
+ unlock_abort:
+ spin_unlock(ptl);
++free_abort:
++ pte_free(vma->vm_mm, pgtable);
+ abort:
+ for (i = 0; i < HPAGE_PMD_NR; i++)
+ src[i] &= ~MIGRATE_PFN_MIGRATE;
--- /dev/null
+From 3f8968e9cbf95d5d87d32218906cab0b9b9eddbe Mon Sep 17 00:00:00 2001
+From: Dev Jain <dev.jain@arm.com>
+Date: Mon, 18 May 2026 12:06:56 +0530
+Subject: mm/rmap: initialize nr_pages to 1 at loop start in try_to_unmap_one
+
+From: Dev Jain <dev.jain@arm.com>
+
+commit 3f8968e9cbf95d5d87d32218906cab0b9b9eddbe upstream.
+
+Initialize nr_pages to 1 at the start of each loop iteration, like
+folio_referenced_one() does.
+
+Without this, nr_pages computed by a previous folio_unmap_pte_batch() call
+can be reused on a later iteration that does not run
+folio_unmap_pte_batch() again.
+
+mmap a 64K large folio with MAP_ANONYMOUS | MAP_DROPPABLE, then call
+madvise(MADV_FREE), then make the last page device-exclusive via
+HMM_DMIRROR_EXCLUSIVE.
+
+Trigger node reclaim through sysfs. Now, in try_to_unmap_one(), we will
+first clear the first 15 out of 16 entries mapping the lazyfree folio.
+This will set nr_pages to 15. In the next pvmw walk, this nr_pages gets
+reused on a device-exclusive pte, thus potentially corrupting folio
+refcount/mapcount.
+
+At the moment, I have a userspace program which can make the kernel spit
+out a trace, but the blow up is in folio_referenced_one(), because there
+are existing bugs in the interaction between device-private and rmap
+(which too I am investigating). I did a one liner kernel change to avoid
+going into folio_referenced_one(), and the kernel blows up at
+folio_remove_rmap_ptes in try_to_unmap_one which is what I wanted.
+
+Note that the bug is there not since file folio batching but lazyfree
+folio batching, since device-exclusive only works for anonymous folios.
+
+Userspace visible effect is simply kernel crashing somewhere due to
+refcount/mapcount corruption.
+
+Link: https://lore.kernel.org/20260518063656.3721056-1-dev.jain@arm.com
+Fixes: 354dffd29575 ("mm: support batched unmap for lazyfree large folios during reclamation")
+Signed-off-by: Dev Jain <dev.jain@arm.com>
+Acked-by: Barry Song <baohua@kernel.org>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Anshuman Khandual <anshuman.khandual@arm.com>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Dev Jain <dev.jain@arm.com>
+Cc: Harry Yoo <harry@kernel.org>
+Cc: Jann Horn <jannh@google.com>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Rik van Riel <riel@surriel.com>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/rmap.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -2024,6 +2024,8 @@ static bool try_to_unmap_one(struct foli
+ mmu_notifier_invalidate_range_start(&range);
+
+ while (page_vma_mapped_walk(&pvmw)) {
++ nr_pages = 1;
++
+ /*
+ * If the folio is in an mlock()d vma, we must not swap it out.
+ */
--- /dev/null
+From 04aa71da5f35aacdc9ae9cb5150947daa624f641 Mon Sep 17 00:00:00 2001
+From: "Uladzislau Rezki (Sony)" <urezki@gmail.com>
+Date: Fri, 15 May 2026 17:30:09 +0200
+Subject: mm/vmalloc: do not trigger BUG() on BH disabled context
+
+From: Uladzislau Rezki (Sony) <urezki@gmail.com>
+
+commit 04aa71da5f35aacdc9ae9cb5150947daa624f641 upstream.
+
+__get_vm_area_node() currently triggers a BUG() if in_interrupt() returns
+true. However, in_interrupt() also reports true when BH are disabled.
+
+The bridge code can call rhashtable_lookup_insert_fast() with bottom
+halves disabled:
+
+__vlan_add()
+ -> br_fdb_add_local()
+ spin_lock_bh(&br->hash_lock); <-- Disable BH
+ -> fdb_add_local()
+ -> fdb_create()
+ -> rhashtable_lookup_insert_fast()
+ -> kvmalloc()
+ -> vmalloc()
+ -> __get_vm_area_node()
+ -> BUG_ON(in_interrupt())
+ spin_unlock_bh(&br->hash_lock)
+
+this triggers the BUG() despite the caller not being in NMI or
+hard IRQ context.
+
+Replace the in_interrupt() check with in_nmi() || in_hardirq().
+
+Link: https://lore.kernel.org/20260515153009.2296191-1-urezki@gmail.com
+Fixes: c6307674ed82 ("mm: kvmalloc: add non-blocking support for vmalloc")
+Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
+Cc: Ido Schimmel <idosch@nvidia.com>
+Reported-by: syzbot+8b12fc6e0fb139765b58@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/69ff8c7c.050a0220.1036b8.000b.GAE@google.com/
+Reviewed-by: Baoquan He <baoquan.he@linux.dev>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/vmalloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -3209,7 +3209,7 @@ struct vm_struct *__get_vm_area_node(uns
+ struct vm_struct *area;
+ unsigned long requested_size = size;
+
+- BUG_ON(in_interrupt());
++ BUG_ON(in_nmi() || in_hardirq());
+ size = ALIGN(size, 1ul << shift);
+ if (unlikely(!size))
+ return NULL;
--- /dev/null
+From ef15ccbb3e8640a723c42ad90eaf81d66ae02017 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <benh@debian.org>
+Date: Tue, 5 May 2026 20:45:12 +0200
+Subject: parport: Fix race between port and client registration
+
+From: Ben Hutchings <benh@debian.org>
+
+commit ef15ccbb3e8640a723c42ad90eaf81d66ae02017 upstream.
+
+The parport subsystem registers port devices before they are fully
+initialised, resulting in a race condition where client drivers such
+as lp can attach to ports that are not completely initialised or even
+being torn down.
+
+When the port and client drivers are built as modules and loaded
+around the same time during boot, this occasionally results in a
+crash. I was able to make this happen reliably in a VM with a
+PC-style parallel port by patching parport_pc to fail probing:
+
+> --- a/drivers/parport/parport_pc.c
+> +++ b/drivers/parport/parport_pc.c
+> @@ -2069,7 +2069,7 @@ static struct parport *__parport_pc_probe_port(unsigned long int base,
+> if (!p)
+> goto out3;
+>
+> - base_res = request_region(base, 3, p->name);
+> + base_res = NULL;
+> if (!base_res)
+> goto out4;
+>
+
+and then running:
+
+ while true; do
+ modprobe lp & modprobe parport_pc
+ wait
+ rmmod lp parport_pc
+ done
+
+for a few seconds.
+
+In the long term I think port registration should be changed to put
+the call to device_add() inside parport_announce_port(), but since the
+latter currently cannot fail this will require changing all port
+drivers.
+
+For now, add a flag to indicate whether a port has been "announced"
+and only try to attach client drivers to ports when the flag is set.
+
+Fixes: 6fa45a226897 ("parport: add device-model to parport subsystem")
+Closes: https://bugs.debian.org/1130365
+Closes: https://lore.kernel.org/all/6ba903ad-9897-42bb-8c2d-337385cc3746@molgen.mpg.de/
+Cc: stable <stable@kernel.org>
+Signed-off-by: Ben Hutchings <benh@debian.org>
+Acked-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Link: https://patch.msgid.link/afo6uBv68GDevbMD@decadent.org.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/parport/share.c | 11 +++++++++--
+ include/linux/parport.h | 1 +
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/parport/share.c
++++ b/drivers/parport/share.c
+@@ -214,10 +214,14 @@ static void get_lowlevel_driver(void)
+ static int port_check(struct device *dev, void *dev_drv)
+ {
+ struct parport_driver *drv = dev_drv;
++ struct parport *port;
+
+ /* only send ports, do not send other devices connected to bus */
+- if (is_parport(dev))
+- drv->match_port(to_parport_dev(dev));
++ if (is_parport(dev)) {
++ port = to_parport_dev(dev);
++ if (test_bit(PARPORT_ANNOUNCED, &port->devflags))
++ drv->match_port(port);
++ }
+ return 0;
+ }
+
+@@ -532,6 +536,7 @@ void parport_announce_port(struct parpor
+ if (slave)
+ attach_driver_chain(slave);
+ }
++ set_bit(PARPORT_ANNOUNCED, &port->devflags);
+ mutex_unlock(®istration_lock);
+ }
+ EXPORT_SYMBOL(parport_announce_port);
+@@ -561,6 +566,8 @@ void parport_remove_port(struct parport
+
+ mutex_lock(®istration_lock);
+
++ clear_bit(PARPORT_ANNOUNCED, &port->devflags);
++
+ /* Spread the word. */
+ detach_driver_chain(port);
+
+--- a/include/linux/parport.h
++++ b/include/linux/parport.h
+@@ -240,6 +240,7 @@ struct parport {
+
+ unsigned long devflags;
+ #define PARPORT_DEVPROC_REGISTERED 0
++#define PARPORT_ANNOUNCED 1
+ struct pardevice *proc_device; /* Currently register proc device */
+
+ struct list_head full_list;
--- /dev/null
+From 4c19719eb8b8df08c5bec7c499f73ddaea6f09fc Mon Sep 17 00:00:00 2001
+From: Alice Ryhl <aliceryhl@google.com>
+Date: Tue, 14 Apr 2026 12:02:34 +0000
+Subject: rust_binder: avoid calling pending_oneway_finished() on TF_UPDATE_TXN
+
+From: Alice Ryhl <aliceryhl@google.com>
+
+commit 4c19719eb8b8df08c5bec7c499f73ddaea6f09fc upstream.
+
+When an outdated transaction is removed from `oneway_todo` due to
+`TF_UPDATE_TXN`, its `Allocation` is dropped. The current implementation
+of `Allocation::drop` calls `pending_oneway_finished()`, assuming the
+transaction was executed. This leads to premature execution of the next
+queued one-way transaction.
+
+Fix this by taking the `oneway_node` from the `Allocation` of the
+outdated transaction before it is dropped. This prevents
+`Allocation::drop` from signaling completion.
+
+We do not call `take_oneway_node()` from `Transaction::cancel` because
+it's actually correct to call `pending_oneway_finished()` on cancel if
+the transaction did not come from `oneway_todo`. This ensures that if
+`BINDER_THREAD_EXIT` is invoked and cancels a oneway transaction, then
+the next transaction is taken from `oneway_todo`.
+
+This bug does not lead to any issues in the kernel, but may lead to
+Binder delivering transactions to userspace earlier than userspace
+expected to receive them.
+
+Cc: stable <stable@kernel.org>
+Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
+Assisted-by: Antigravity:gemini
+Signed-off-by: Alice Ryhl <aliceryhl@google.com>
+Acked-by: Carlos Llamas <cmllamas@google.com>
+Link: https://patch.msgid.link/20260414-tf-update-txn-fix-v1-1-d2b83303acc9@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder/allocation.rs | 8 ++++++++
+ drivers/android/binder/transaction.rs | 11 ++++++++++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+--- a/drivers/android/binder/allocation.rs
++++ b/drivers/android/binder/allocation.rs
+@@ -160,6 +160,14 @@ impl Allocation {
+ self.get_or_init_info().target_node = Some(target_node);
+ }
+
++ pub(crate) fn take_oneway_node(&mut self) -> Option<DArc<Node>> {
++ if let Some(info) = self.allocation_info.as_mut() {
++ info.oneway_node.take()
++ } else {
++ None
++ }
++ }
++
+ /// Reserve enough space to push at least `num_fds` fds.
+ pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result {
+ self.get_or_init_info()
+--- a/drivers/android/binder/transaction.rs
++++ b/drivers/android/binder/transaction.rs
+@@ -250,7 +250,8 @@ impl Transaction {
+ /// Not used for replies.
+ pub(crate) fn submit(self: DLArc<Self>) -> BinderResult {
+ // Defined before `process_inner` so that the destructor runs after releasing the lock.
+- let mut _t_outdated;
++ let _t_outdated;
++ let _oneway_node;
+
+ let oneway = self.flags & TF_ONE_WAY != 0;
+ let process = self.to.clone();
+@@ -267,6 +268,14 @@ impl Transaction {
+ if let Some(t_outdated) =
+ target_node.take_outdated_transaction(&self, &mut process_inner)
+ {
++ let mut alloc_guard = t_outdated.allocation.lock();
++ if let Some(alloc) = (*alloc_guard).as_mut() {
++ // Take the oneway node to prevent `Allocation::drop` from calling
++ // `pending_oneway_finished()`, which would be incorrect as this
++ // transaction is not being submitted.
++ _oneway_node = alloc.take_oneway_node();
++ }
++ drop(alloc_guard);
+ // Save the transaction to be dropped after locks are released.
+ _t_outdated = t_outdated;
+ }
--- /dev/null
+From f6d8fea9e3953151a4adb4f603503dc3dc9c69da Mon Sep 17 00:00:00 2001
+From: Matthew Maurer <mmaurer@google.com>
+Date: Fri, 3 Apr 2026 18:18:58 +0000
+Subject: rust_binder: Avoid holding lock when dropping delivered_death
+
+From: Matthew Maurer <mmaurer@google.com>
+
+commit f6d8fea9e3953151a4adb4f603503dc3dc9c69da upstream.
+
+In 6c37bebd8c926, we switched to looping over the list and dropping each
+individual node, ostensibly without the lock held in the loop body.
+
+If the kernel were using Rust Edition 2024, the comment would be
+accurate, and the lock would not be held across the drop. However, the
+kernel is currently using 2021, so tail expression lifetime extension
+results in the lock being held across the drop. Explicitly binding the
+expression result to a variable makes the lockguard no longer part of a
+tail expression, causing the lock to be dropped before entering the loop
+body.
+
+This was detected via `CONFIG_PROVE_LOCKING` identifying an invalid wait
+context at the drop site.
+
+Reported-by: David Stevens <stevensd@google.com>
+Signed-off-by: Matthew Maurer <mmaurer@google.com>
+Cc: stable <stable@kernel.org>
+Fixes: 6c37bebd8c92 ("rust_binder: avoid mem::take on delivered_deaths")
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Acked-by: Carlos Llamas <cmllamas@google.com>
+Link: https://patch.msgid.link/20260403-lockhold-v1-1-c332b56cd8ae@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/android/binder/process.rs | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/android/binder/process.rs
++++ b/drivers/android/binder/process.rs
+@@ -1402,7 +1402,12 @@ impl Process {
+ // Clear delivered_deaths list.
+ //
+ // Scope ensures that MutexGuard is dropped while executing the body.
+- while let Some(delivered_death) = { self.inner.lock().delivered_deaths.pop_front() } {
++ while let Some(delivered_death) = {
++ // Explicitly bind to avoid tail expression lifetime extension of the lockguard
++ // Can be removed when the kernel moves to edition 2024
++ let maybe_death = self.inner.lock().delivered_deaths.pop_front();
++ maybe_death
++ } {
+ drop(delivered_death);
+ }
+
usb-serial-cypress_m8-fix-memory-corruption-with-small-endpoint.patch
hid-quirks-add-always_poll-quirk-for-sigmachip-usb-mouse.patch
bluetooth-btusb-allow-firmware-re-download-when-version-matches.patch
+mm-vmalloc-do-not-trigger-bug-on-bh-disabled-context.patch
+hpfs-fix-a-crash-if-hpfs_map_dnode_bitmap-fails.patch
+mm-damon-sysfs-schemes-delete-tried-region-in-regions_rmdirs.patch
+ipc-limit-next_id-allocation-to-the-valid-id-range.patch
+mm-memcontrol-propagate-nmi-slab-stats-to-memcg-vmstats.patch
+mm-migrate_device-fix-pgtable-leak-in-migrate_vma_insert_huge_pmd_page.patch
+memfd-deny-writeable-mappings-when-implying-seal_write.patch
+zram-fix-use-after-free-in-zram_writeback_endio.patch
+mm-rmap-initialize-nr_pages-to-1-at-loop-start-in-try_to_unmap_one.patch
+auxdisplay-line-display-fix-oob-read-on-zero-length-message_store.patch
+smb-client-fix-uninitialized-variable-in-smb2_writev_callback.patch
+bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch
+bluetooth-l2cap-fix-chan-ref-leak-in-l2cap_chan_timeout-on-conn.patch
+bluetooth-hidp-fix-missing-length-checks-in-hidp_input_report.patch
+bluetooth-iso-fix-uaf-in-iso_recv_frame.patch
+bluetooth-iso-serialize-iso_sock_clear_timer-with-socket-lock.patch
+bluetooth-hci_conn-fix-memory-leak-in-hci_le_big_terminate.patch
+bluetooth-hci_qca-use-100-ms-ssr-delay-for-rampatch-and-nvm-loading.patch
+bluetooth-hci_sync-fix-uaf-in-hci_le_create_cis_sync.patch
+input-xpad-fix-out-of-bounds-access-for-share-button.patch
+parport-fix-race-between-port-and-client-registration.patch
+rust_binder-avoid-holding-lock-when-dropping-delivered_death.patch
+rust_binder-avoid-calling-pending_oneway_finished-on-tf_update_txn.patch
+usb-cdc-acm-fix-bit-overlap-and-move-quirk-definitions-to-header.patch
+kvm-arm64-correctly-cap-zcr_el2-provided-by-a-guest-hypervisor.patch
+kvm-arm64-pmu-preserve-aarch32-counter-low-bits.patch
+kvm-svm-flush-the-current-tlb-when-transitioning-from-xavic-x2avic.patch
+kvm-sev-require-in-ghcb-scratch-area-if-ghcb-v2-is-in-use.patch
+kvm-sev-ignore-port-i-o-requests-of-length-0.patch
+kvm-sev-use-the-size-of-the-psc-header-as-the-minimum-size-for-psc-requests.patch
+kvm-sev-warn-if-kvm-attempts-to-setup-scratch-area-with-min_len-0.patch
+kvm-sev-compute-the-correct-max-length-of-the-in-ghcb-scratch-area.patch
+kvm-sev-check-psc-request-indices-against-the-actual-size-of-the-buffer.patch
+kvm-sev-use-read_once-when-reading-entries-indices-from-psc-buffer.patch
+kvm-sev-don-t-explicitly-pass-psc-buffer-to-snp_begin_psc.patch
+gpio-shared-undo-the-vote-of-the-proxy-on-gpio-free.patch
+gpio-shared-fix-deadlock-on-shared-proxy-s-parent-removal.patch
+gpio-shared-fix-lockdep-false-positive-by-removing-unneeded-lock.patch
+disable-wattribute-alias-for-clang-23-and-newer.patch
+iio-adc-xilinx-xadc-fix-sequencer-mode-in-postdisable-for-dual-mux.patch
+iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
+iio-dac-ad3530r-fix-ad3531-ad3531r-powerdown-mode-strings.patch
+iio-dac-max5821-fix-return-value-check-in-powerdown-sync.patch
+iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
+iio-dac-ad5686-fix-input-raw-value-check.patch
+iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch
+iio-dac-ad5686-fix-powerdown-control-on-dual-channel-devices.patch
+iio-adc-mt6359-fix-unchecked-return-value-in-mt6358_read_imp.patch
+iio-adc-viperboard-fix-error-handling-in-vprbrd_iio_read_raw.patch
+iio-adc-ad4695-fix-call-ordering-in-offload-buffer-postenable.patch
+iio-adc-nxp-sar-adc-fix-division-by-zero-in-write_raw.patch
+iio-adc-nxp-sar-adc-avoid-division-by-zero.patch
+iio-adc-nxp-sar-adc-zero-initialize-dma_slave_config.patch
+iio-gyro-itg3200-fix-i2c-read-into-the-wrong-stack-location.patch
+iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
+iio-ssp_sensors-cancel-delayed-work_refresh-on-remove.patch
+iio-temperature-tsys01-fix-broken-prom-checksum-validation.patch
+iio-magnetometer-st_magn-fix-default-drdy-pin-selection-for-lis2mdl.patch
+iio-light-veml6070-fix-resource-leak-in-probe-error-path.patch
+iio-fix-iio_multiply_value-use-in-iio_read_channel_processed_scale.patch
+iio-chemical-mhz19b-reject-oversized-serial-replies.patch
+iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
+iio-light-cm3323-fix-reg_conf-not-being-initialized-correctly.patch
+iio-buffer-hw-consumer-fix-use-after-free-in-error-path.patch
+iio-buffer-fix-dma-fence-leak-in-iio_buffer_enqueue_dmabuf.patch
+usb-serial-omninet-fix-memory-corruption-with-small-endpoint.patch
+usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch
+usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch
+usb-cdns3-plat-fix-unbalanced-pm_runtime_forbid-call-permanently-leaks-the-runtime-pm-usage-counter-across-bind-unbind-cycles.patch
+usb-dwc2-fix-use-after-free-in-debug-code.patch
+input-elan_i2c-validate-firmware-size-before-use.patch
+i2c-davinci-fix-division-by-zero-on-missing-clock-frequency.patch
+x86-ftrace-relocate-rip-relative-percpu-refs-in-dynamic-trampolines.patch
--- /dev/null
+From 9d2491197a00acf8c423512078458c2855102b66 Mon Sep 17 00:00:00 2001
+From: Steve French <stfrench@microsoft.com>
+Date: Fri, 22 May 2026 18:28:49 -0500
+Subject: smb: client: fix uninitialized variable in smb2_writev_callback
+
+From: Steve French <stfrench@microsoft.com>
+
+commit 9d2491197a00acf8c423512078458c2855102b66 upstream.
+
+compiling with W=2 pointed out that "written may be used uninitialized"
+
+Fixes: 20d72b00ca81 ("netfs: Fix the request's work item to not require a ref")
+Cc: stable@vger.kernel.org
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2pdu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -4943,7 +4943,7 @@ smb2_writev_callback(struct TCP_Server_I
+ unsigned int rreq_debug_id = wdata->rreq->debug_id;
+ unsigned int subreq_debug_index = wdata->subreq.debug_index;
+ ssize_t result = 0;
+- size_t written;
++ size_t written = 0;
+
+ WARN_ONCE(wdata->server != server,
+ "wdata server %p != mid server %p",
--- /dev/null
+From 5eb070769ea5e18405535609d1d3f6886f3755bd Mon Sep 17 00:00:00 2001
+From: Wentao Guan <guanwentao@uniontech.com>
+Date: Fri, 22 May 2026 17:13:58 +0800
+Subject: USB: cdc-acm: Fix bit overlap and move quirk definitions to header
+
+From: Wentao Guan <guanwentao@uniontech.com>
+
+commit 5eb070769ea5e18405535609d1d3f6886f3755bd upstream.
+
+The VENDOR_CLASS_DATA_IFACE and ALWAYS_POLL_CTRL quirk flags added in
+commit f58752ebcb35 ("USB: cdc-acm: Add quirks for Yoga Book 9 14IAH10
+INGENIC touchscreen") were placed inside the acm_ctrl_msg() function
+rather than in the header with the other quirk flags. Then, their
+values (BIT(9) and BIT(10)) collided with NO_UNION_12 which is already
+BIT(9).
+
+Move the definitions to drivers/usb/class/cdc-acm.h where they belong
+and shift them to BIT(10) and BIT(11) to avoid the overlap.
+
+Fixes: f58752ebcb35 ("USB: cdc-acm: Add quirks for Yoga Book 9 14IAH10 INGENIC touchscreen")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Link: https://patch.msgid.link/20260522091357.1301196-1-guanwentao@uniontech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c | 2 --
+ drivers/usb/class/cdc-acm.h | 2 ++
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -114,8 +114,6 @@ static int acm_ctrl_msg(struct acm *acm,
+ int retval;
+
+ retval = usb_autopm_get_interface(acm->control);
+-#define VENDOR_CLASS_DATA_IFACE BIT(9) /* data interface uses vendor-specific class */
+-#define ALWAYS_POLL_CTRL BIT(10) /* keep ctrl URB active even without an open TTY */
+ if (retval)
+ return retval;
+
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -115,3 +115,5 @@ struct acm {
+ #define DISABLE_ECHO BIT(7)
+ #define MISSING_CAP_BRK BIT(8)
+ #define NO_UNION_12 BIT(9)
++#define VENDOR_CLASS_DATA_IFACE BIT(10) /* data interface uses vendor-specific class */
++#define ALWAYS_POLL_CTRL BIT(11) /* keep ctrl URB active even without an open TTY */
--- /dev/null
+From c8778ff817a7047d6848fefba99dcb27b1bf01fe Mon Sep 17 00:00:00 2001
+From: Yongchao Wu <yongchao.wu@autochips.com>
+Date: Thu, 14 May 2026 00:00:12 +0800
+Subject: usb: cdns3: gadget: fix request skipping after clearing halt
+
+From: Yongchao Wu <yongchao.wu@autochips.com>
+
+commit c8778ff817a7047d6848fefba99dcb27b1bf01fe upstream.
+
+According to the cdns3 datasheet, the EPRST (Endpoint Reset) command
+causes the DMA engine to reposition its internal pointer to the next
+Transfer Descriptor (TD) if it was already processing one.
+
+This issue is consistently observed during the ADB identification
+process on macOS hosts, where the host issues a Clear_Halt. Although
+commit 4bf2dd65135a ("usb: cdns3: gadget: toggle cycle bit before reset
+endpoint") attempted to avoid DMA advance by toggling the cycle bit,
+trace logs show that on certain hosts like macOS, the DMA pointer
+(EP_TRADDR) still shifts after EPRST:
+
+ cdns3_ctrl_req: Clear Endpoint Feature(Halt ep1out)
+ cdns3_doorbell_epx: ep1out, ep_trbaddr f9c04030 <-- Should be f9c04000
+ cdns3_gadget_giveback: ep1out: req: ... length: 16384/16384
+
+As shown above, the DMA pointer jumped to the next TD, causing
+the controller to skip the initial TRBs of the request. This leads to
+data misalignment and ADB protocol hangs on macOS.
+
+Fix this by manually restoring the EP_TRADDR register to the starting
+physical address of the current request after the EPRST operation is
+complete.
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Cc: stable <stable@kernel.org>
+Cc: Peter Chen <peter.chen@kernel.org>
+Signed-off-by: Yongchao Wu <yongchao.wu@autochips.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://patch.msgid.link/20260513160012.2547894-1-yongchao.wu@autochips.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-gadget.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/cdns3-gadget.c
++++ b/drivers/usb/cdns3/cdns3-gadget.c
+@@ -2817,9 +2817,19 @@ int __cdns3_gadget_ep_clear_halt(struct
+ priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING);
+
+ if (request) {
+- if (trb)
++ if (trb) {
+ *trb = trb_tmp;
+
++ /*
++ * Per datasheet, EPRST causes DMA to reposition to the next TD.
++ * Manually reset EP_TRADDR to the current TRB to prevent
++ * the hardware from skipping the interrupted request.
++ */
++ writel(EP_TRADDR_TRADDR(priv_ep->trb_pool_dma +
++ priv_req->start_trb * TRB_SIZE),
++ &priv_dev->regs->ep_traddr);
++ }
++
+ cdns3_rearm_transfer(priv_ep, 1);
+ }
+
--- /dev/null
+From e6970cda63fd4b4546aeed9d0e2f53a7c95cd09c Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@cixtech.com>
+Date: Wed, 13 May 2026 16:53:09 +0800
+Subject: usb: cdns3: plat: fix leaked usb2_phy initialization on usb3_phy acquisition failure
+
+From: Peter Chen <peter.chen@cixtech.com>
+
+commit e6970cda63fd4b4546aeed9d0e2f53a7c95cd09c upstream.
+
+Move usb2_phy initialization after usb3_phy acquisition.
+
+Fixes: f738957277ba ("usb: cdns3: Split core.c into cdns3-plat and core.c file")
+Cc: stable <stable@kernel.org>
+Reported-by: sashiko-bot <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/linux-devicetree/agKaEePSFknhDBg2@nchen-desktop/T/#m21e1d9c1574eb127ce03c0c2a1a49002ce435b52
+Signed-off-by: Peter Chen <peter.chen@cixtech.com>
+Link: https://patch.msgid.link/20260513085310.2217547-2-peter.chen@cixtech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-plat.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/cdns3/cdns3-plat.c
++++ b/drivers/usb/cdns3/cdns3-plat.c
+@@ -126,15 +126,15 @@ static int cdns3_plat_probe(struct platf
+ return dev_err_probe(dev, PTR_ERR(cdns->usb2_phy),
+ "Failed to get cdn3,usb2-phy\n");
+
+- ret = phy_init(cdns->usb2_phy);
+- if (ret)
+- return ret;
+-
+ cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy");
+ if (IS_ERR(cdns->usb3_phy))
+ return dev_err_probe(dev, PTR_ERR(cdns->usb3_phy),
+ "Failed to get cdn3,usb3-phy\n");
+
++ ret = phy_init(cdns->usb2_phy);
++ if (ret)
++ return ret;
++
+ ret = phy_init(cdns->usb3_phy);
+ if (ret)
+ goto err_phy3_init;
--- /dev/null
+From ae6f3b82324e4f39ad8443c9020787e6fc889637 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@cixtech.com>
+Date: Wed, 13 May 2026 16:53:10 +0800
+Subject: usb: cdns3: plat: fix unbalanced pm_runtime_forbid() call permanently leaks the runtime PM usage counter across bind/unbind cycles
+
+From: Peter Chen <peter.chen@cixtech.com>
+
+commit ae6f3b82324e4f39ad8443c9020787e6fc889637 upstream.
+
+Call pm_runtime_allow(dev) conditionally at cdns3_plat_remove.
+
+Fixes: f738957277ba ("usb: cdns3: Split core.c into cdns3-plat and core.c file")
+Cc: stable <stable@kernel.org>
+Reported-by: sashiko-bot <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/linux-devicetree/agKaEePSFknhDBg2@nchen-desktop/T/#m21e1d9c1574eb127ce03c0c2a1a49002ce435b52
+Signed-off-by: Peter Chen <peter.chen@cixtech.com>
+Link: https://patch.msgid.link/20260513085310.2217547-3-peter.chen@cixtech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-plat.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/cdns3/cdns3-plat.c
++++ b/drivers/usb/cdns3/cdns3-plat.c
+@@ -186,6 +186,9 @@ static void cdns3_plat_remove(struct pla
+ struct device *dev = cdns->dev;
+
+ pm_runtime_get_sync(dev);
++ if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)))
++ pm_runtime_allow(dev);
++
+ pm_runtime_disable(dev);
+ pm_runtime_put_noidle(dev);
+ cdns_remove(cdns);
--- /dev/null
+From 9ea06a3fbf9f16e0d98c52cb3b99642be15ec281 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Wed, 20 May 2026 08:59:28 +0300
+Subject: usb: dwc2: Fix use after free in debug code
+
+From: Dan Carpenter <error27@gmail.com>
+
+commit 9ea06a3fbf9f16e0d98c52cb3b99642be15ec281 upstream.
+
+We're not allowed to dereference "urb" after calling
+usb_hcd_giveback_urb() so save the urb->status ahead of time.
+
+Fixes: 7359d482eb4d ("staging: HCD files for the DWC2 driver")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Link: https://patch.msgid.link/ag1NwBpqT4IEQcdJ@stanley.mountain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/hcd.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc2/hcd.c
++++ b/drivers/usb/dwc2/hcd.c
+@@ -4804,6 +4804,7 @@ static int _dwc2_hcd_urb_dequeue(struct
+ struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
+ int rc;
+ unsigned long flags;
++ int urb_status;
+
+ dev_dbg(hsotg->dev, "DWC OTG HCD URB Dequeue\n");
+ dwc2_dump_urb_info(hcd, urb, "urb_dequeue");
+@@ -4828,11 +4829,12 @@ static int _dwc2_hcd_urb_dequeue(struct
+
+ /* Higher layer software sets URB status */
+ spin_unlock(&hsotg->lock);
++ urb_status = urb->status;
+ usb_hcd_giveback_urb(hcd, urb, status);
+ spin_lock(&hsotg->lock);
+
+ dev_dbg(hsotg->dev, "Called usb_hcd_giveback_urb()\n");
+- dev_dbg(hsotg->dev, " urb->status = %d\n", urb->status);
++ dev_dbg(hsotg->dev, " urb->status = %d\n", urb_status);
+ out:
+ spin_unlock_irqrestore(&hsotg->lock, flags);
+
--- /dev/null
+From 60df93d30f9bdd27db17c4d80ed80ef718d7226b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 22 May 2026 16:20:58 +0200
+Subject: USB: serial: omninet: fix memory corruption with small endpoint
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 60df93d30f9bdd27db17c4d80ed80ef718d7226b upstream.
+
+Make sure that the bulk-out buffers are at least as large as the
+hardcoded transfer size to avoid user-controlled slab corruption should
+a malicious device report a smaller endpoint max packet size than
+expected.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/omninet.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/omninet.c
++++ b/drivers/usb/serial/omninet.c
+@@ -30,6 +30,10 @@
+ /* This one seems to be a re-branded ZyXEL device */
+ #define BT_IGNITIONPRO_ID 0x2000
+
++#define OMNINET_HEADERLEN 4
++#define OMNINET_BULKOUTSIZE 64
++#define OMNINET_PAYLOADSIZE (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN)
++
+ /* function prototypes */
+ static void omninet_process_read_urb(struct urb *urb);
+ static int omninet_prepare_write_buffer(struct usb_serial_port *port,
+@@ -54,6 +58,7 @@ static struct usb_serial_driver zyxel_om
+ .description = "ZyXEL - omni.net usb",
+ .id_table = id_table,
+ .num_bulk_out = 2,
++ .bulk_out_size = OMNINET_BULKOUTSIZE,
+ .calc_num_ports = omninet_calc_num_ports,
+ .port_probe = omninet_port_probe,
+ .port_remove = omninet_port_remove,
+@@ -130,10 +135,6 @@ static void omninet_port_remove(struct u
+ kfree(od);
+ }
+
+-#define OMNINET_HEADERLEN 4
+-#define OMNINET_BULKOUTSIZE 64
+-#define OMNINET_PAYLOADSIZE (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN)
+-
+ static void omninet_process_read_urb(struct urb *urb)
+ {
+ struct usb_serial_port *port = urb->context;
--- /dev/null
+From a17dc12bfed8868e6a86f3b45c16065a70641acb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alexis=20Lothor=C3=A9=20=28eBPF=20Foundation=29?=
+ <alexis.lothore@bootlin.com>
+Date: Wed, 27 May 2026 21:12:31 +0200
+Subject: x86/ftrace: Relocate %rip-relative percpu refs in dynamic trampolines
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
+
+commit a17dc12bfed8868e6a86f3b45c16065a70641acb upstream.
+
+With CONFIG_CALL_DEPTH_TRACKING enabled on an x86 retbleed-affected platform
+(eg: Skylake), with retbleed=stuff, registering a dynamic ftrace trampoline
+crashes on the first call into the traced function:
+
+ BUG: unable to handle page fault for address: ffff88817ae18880
+ #PF: supervisor write access in kernel mode
+ #PF: error_code(0x0002) - not-present page
+ PGD 4b53067 P4D 4b53067 PUD 0
+ Oops: Oops: 0002 [#1] SMP PTI
+ CPU: 3 UID: 0 PID: 187 Comm: usleep Not tainted 7.0.10 #243 PREEMPT(full)
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014
+ Code: 24 78 00 00 00 00 48 89 ea 48 89 54 24 20 48 8b b4 24 b8 00 00 00 48 8b bc 24 b0 00 00 00 48 89 bc 24 80 00 00 00 48 83 ef 05 <65> 48 c1 3d 1f a8 b6 02 05 48 8b 15 f6 00 00 00 4c 89 3c 24 4c 89
+ Call Trace:
+ <TASK>
+ ? find_held_lock
+ ? exc_page_fault
+ ? lock_release
+ ? __x64_sys_clock_nanosleep
+ ? lockdep_hardirqs_on_prepare
+ ? trace_hardirqs_on
+ __x64_sys_clock_nanosleep
+ do_syscall_64
+ ? exc_page_fault
+ ? call_depth_return_thunk
+ entry_SYSCALL_64_after_hwframe
+ ...
+ Kernel panic - not syncing: Fatal exception
+
+This small reproducer allows to easily trigger the crash:
+
+ # echo 'p __x64_sys_clock_nanosleep' > /sys/kernel/tracing/kprobe_events
+ # echo 1 > /sys/kernel/tracing/events/kprobes/p___x64_sys_clock_nanosleep_0/enable
+ # usleep 1
+
+Monitoring the crash under GDB points to the exact instruction in charge of
+incrementing the call depth:
+
+ sarq $5, %gs:__x86_call_depth(%rip)
+
+This instruction matches the one inserted by the ftrace_regs_caller from
+ftrace_64.S. This emitted code was likely working fine until the introduction
+of
+
+ 59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()"):
+
+it has made the call depth accounting addressing relative to $rip, instead of
+being based on an absolute address.
+
+As this code exact location depends on where the trampoline lives in memory,
+the corresponding displacement needs to be adjusted at runtime to actually
+correctly find the per-cpu __x86_call_depth value, otherwise the targeted
+address is wrong, leading to the page fault seen above.
+
+Fix the %rip-relative displacement of the copied CALL_DEPTH_ACCOUNT
+instruction (from ftrace_regs_caller) by calling text_poke_apply_relocation(),
+as it is done for example by the x86 BPF JIT compiler through
+x86_call_depth_emit_accounting(). This corrects both CALL_DEPTH_ACCOUNT slots,
+in ftrace_caller and ftrace_regs_caller.
+
+ [ bp: Massage. ]
+
+Fixes: 59bec00ace28 ("x86/percpu: Introduce %rip-relative addressing to PER_CPU_VAR()")
+Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Steven Rostedt <rostedt@goodmis.org>
+Cc: <stable@kernel.org>
+Link: https://patch.msgid.link/20260527-fix_call_depth_in_trampoline-v1-1-1c1abc8ae310@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/ftrace.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -376,6 +376,13 @@ create_trampoline(struct ftrace_ops *ops
+ }
+
+ /*
++ * Generated trampoline may contain rIP-relative addressing which
++ * displacement needs to be fixed.
++ */
++ text_poke_apply_relocation(trampoline, trampoline, size,
++ (void *)start_offset, size);
++
++ /*
+ * The address of the ftrace_ops that is used for this trampoline
+ * is stored at the end of the trampoline. This will be used to
+ * load the third parameter for the callback. Basically, that
--- /dev/null
+From bf62f69574b19720ae5fbbbcdf24a0c4e3e05e43 Mon Sep 17 00:00:00 2001
+From: Richard Chang <richardycc@google.com>
+Date: Tue, 12 May 2026 07:49:18 +0000
+Subject: zram: fix use-after-free in zram_writeback_endio
+
+From: Richard Chang <richardycc@google.com>
+
+commit bf62f69574b19720ae5fbbbcdf24a0c4e3e05e43 upstream.
+
+A crash was observed in zram_writeback_endio due to a NULL pointer
+dereference in wake_up. The root cause is a race condition between the
+bio completion handler (zram_writeback_endio) and the writeback task.
+
+In zram_writeback_endio, wake_up() is called on &wb_ctl->done_wait after
+releasing wb_ctl->done_lock. This creates a race window where the
+writeback task can see num_inflight become 0, return, and free wb_ctl
+before zram_writeback_endio calls wake_up().
+
+CPU 0 (zram_writeback_endio) CPU 1 (writeback_store)
+============================ ============================
+ zram_writeback_slots
+ zram_submit_wb_request
+ zram_submit_wb_request
+ wait_event(wb_ctl->done_wait)
+spin_lock(&wb_ctl->done_lock);
+list_add(&req->entry, &wb_ctl->done_reqs);
+spin_unlock(&wb_ctl->done_lock);
+wake_up(&wb_ctl->done_wait);
+ zram_complete_done_reqs
+spin_lock(&wb_ctl->done_lock);
+list_add(&req->entry, &wb_ctl->done_reqs);
+spin_unlock(&wb_ctl->done_lock);
+ while (num_inflight) > 0)
+ spin_lock(&wb_ctl->done_lock);
+ list_del(&req->entry);
+ spin_unlock(&wb_ctl->done_lock);
+ // num_inflight becomes 0
+ atomic_dec(num_inflight);
+
+ // Leave zram_writeback_slots
+ // Free wb_ctl
+ release_wb_ctl(wb_ctl);
+// UAF crash!
+wake_up(&wb_ctl->done_wait);
+
+This patch fixes this race by using RCU. By protecting wb_ctl with
+rcu_read_lock() in zram_writeback_endio and using kfree_rcu() to free it,
+we ensure that wb_ctl remains valid during the execution of
+zram_writeback_endio.
+
+Link: https://lore.kernel.org/20260512074918.2606208-1-richardycc@google.com
+Fixes: f405066a1f0d ("zram: introduce writeback bio batching")
+Signed-off-by: Richard Chang <richardycc@google.com>
+Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Suggested-by: Minchan Kim <minchan@kernel.org>
+Acked-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Acked-by: Minchan Kim <minchan@kernel.org>
+Cc: Brian Geffon <bgeffon@google.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Martin Liu <liumartin@google.com>
+Cc: wang wei <a929244872@163.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/zram/zram_drv.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index aebc710f0d6a..07111455eecf 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -33,6 +33,7 @@
+ #include <linux/cpuhotplug.h>
+ #include <linux/part_stat.h>
+ #include <linux/kernel_read_file.h>
++#include <linux/rcupdate.h>
+
+ #include "zram_drv.h"
+
+@@ -504,6 +505,7 @@ struct zram_wb_ctl {
+ wait_queue_head_t done_wait;
+ spinlock_t done_lock;
+ atomic_t num_inflight;
++ struct rcu_head rcu;
+ };
+
+ struct zram_wb_req {
+@@ -847,7 +849,7 @@ static void release_wb_ctl(struct zram_wb_ctl *wb_ctl)
+ release_wb_req(req);
+ }
+
+- kfree(wb_ctl);
++ kfree_rcu(wb_ctl, rcu);
+ }
+
+ static struct zram_wb_ctl *init_wb_ctl(struct zram *zram)
+@@ -964,11 +966,13 @@ static void zram_writeback_endio(struct bio *bio)
+ struct zram_wb_ctl *wb_ctl = bio->bi_private;
+ unsigned long flags;
+
++ rcu_read_lock();
+ spin_lock_irqsave(&wb_ctl->done_lock, flags);
+ list_add(&req->entry, &wb_ctl->done_reqs);
+ spin_unlock_irqrestore(&wb_ctl->done_lock, flags);
+
+ wake_up(&wb_ctl->done_wait);
++ rcu_read_unlock();
+ }
+
+ static void zram_submit_wb_request(struct zram *zram,
+--
+2.54.0
+