--- /dev/null
+From stable+bounces-260499-greg=kroah.com@vger.kernel.org Thu Jun 4 19:34:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 09:45:38 -0400
+Subject: Bluetooth: L2CAP: use chan timer to close channels in cleanup_listen()
+To: stable@vger.kernel.org
+Cc: Siwei Zhang <oss@fourdim.xyz>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604134538.3463737-2-sashal@kernel.org>
+
+From: Siwei Zhang <oss@fourdim.xyz>
+
+[ Upstream commit 8c8e620467a7b51562dbcefbd1f09f288d7d710d ]
+
+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: Sasha Levin <sashal@kernel.org>
+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
+@@ -1437,6 +1437,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;
+@@ -1454,14 +1458,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 stable+bounces-260546-greg=kroah.com@vger.kernel.org Thu Jun 4 22:52:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 13:11:57 -0400
+Subject: iio: adc: npcm: fix unbalanced clk_disable_unprepare()
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604171157.4039872-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c ]
+
+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: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/npcm_adc.c | 26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -180,7 +180,6 @@ static int npcm_adc_probe(struct platfor
+ u32 reg_con;
+ struct npcm_adc *info;
+ struct iio_dev *indio_dev;
+- struct device *dev = &pdev->dev;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+ if (!indio_dev)
+@@ -197,7 +196,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);
+@@ -210,17 +209,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 = -EINVAL;
+- goto err_disable_clk;
+- }
++ if (irq <= 0)
++ return -EINVAL;
+
+ 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");
+@@ -228,7 +223,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,
+@@ -238,10 +233,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,
+@@ -280,8 +273,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;
+ }
+@@ -298,7 +289,6 @@ static int npcm_adc_remove(struct platfo
+ 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);
+
+ return 0;
+ }
--- /dev/null
+From stable+bounces-260587-greg=kroah.com@vger.kernel.org Fri Jun 5 05:19:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 19:49:00 -0400
+Subject: iio: chemical: scd30: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604234900.2467781-2-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 ]
+
+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: Sasha Levin <sashal@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
+@@ -257,7 +257,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 stable+bounces-260586-greg=kroah.com@vger.kernel.org Fri Jun 5 05:20:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 19:48:59 -0400
+Subject: iio: chemical: scd30: Use guard(mutex) to allow early returns
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, David Lechner <dlechner@baylibre.com>, Tomasz Duszynski <tomasz.duszynski@octakon.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604234900.2467781-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 5feb5532870fbced5d6f450b8061a33f461b88ca ]
+
+Auto cleanup based release of the lock allows for simpler code flow in a
+few functions with large multiplexing style switch statements and no
+common operations following the switch.
+
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Cc: Tomasz Duszynski <tomasz.duszynski@octakon.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250209180624.701140-3-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 5aba4f94b225 ("iio: chemical: scd30: fix division by zero in write_raw")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c | 63 ++++++++++++++++----------------------
+ 1 file changed, 28 insertions(+), 35 deletions(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -5,6 +5,7 @@
+ * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
+ */
+ #include <linux/bits.h>
++#include <linux/cleanup.h>
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+@@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev
+ int *val, int *val2, long mask)
+ {
+ struct scd30_state *state = iio_priv(indio_dev);
+- int ret = -EINVAL;
++ int ret;
+ u16 tmp;
+
+- mutex_lock(&state->lock);
++ guard(mutex)(&state->lock);
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_PROCESSED:
+ if (chan->output) {
+ *val = state->pressure_comp;
+- ret = IIO_VAL_INT;
+- break;
++ return IIO_VAL_INT;
+ }
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+- break;
++ return ret;
+
+ ret = scd30_read(state);
+ if (ret) {
+ iio_device_release_direct_mode(indio_dev);
+- break;
++ return ret;
+ }
+
+ *val = state->meas[chan->address];
+ iio_device_release_direct_mode(indio_dev);
+- ret = IIO_VAL_INT;
+- break;
++ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = 1;
+- ret = IIO_VAL_INT_PLUS_MICRO;
+- break;
++ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp);
+ if (ret)
+- break;
++ return ret;
+
+ *val = 0;
+ *val2 = 1000000000 / tmp;
+- ret = IIO_VAL_INT_PLUS_NANO;
+- break;
++ return IIO_VAL_INT_PLUS_NANO;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp);
+ if (ret)
+- break;
++ return ret;
+
+ *val = tmp;
+- ret = IIO_VAL_INT;
+- break;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
+ }
+- mutex_unlock(&state->lock);
+-
+- return ret;
+ }
+
+ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+ {
+ struct scd30_state *state = iio_priv(indio_dev);
+- int ret = -EINVAL;
++ int ret;
+
+- mutex_lock(&state->lock);
++ guard(mutex)(&state->lock);
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ if (val)
+- break;
++ return -EINVAL;
+
+ val = 1000000000 / val2;
+ if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S)
+- break;
++ return -EINVAL;
+
+ ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
+ if (ret)
+- break;
++ return ret;
+
+ state->meas_interval = val;
+- break;
++ return 0;
+ case IIO_CHAN_INFO_RAW:
+ switch (chan->type) {
+ case IIO_PRESSURE:
+ if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
+ val > SCD30_PRESSURE_COMP_MAX_MBAR)
+- break;
++ return -EINVAL;
+
+ ret = scd30_command_write(state, CMD_START_MEAS, val);
+ if (ret)
+- break;
++ return ret;
+
+ state->pressure_comp = val;
+- break;
++ return 0;
+ default:
+- break;
++ return -EINVAL;
+ }
+- break;
+ case IIO_CHAN_INFO_CALIBBIAS:
+ if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
+- break;
++ return -EINVAL;
+ /*
+ * Manufacturer does not explicitly specify min/max sensible
+ * values hence check is omitted for simplicity.
+ */
+- ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++ return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++ default:
++ return -EINVAL;
+ }
+- mutex_unlock(&state->lock);
+-
+- return ret;
+ }
+
+ static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
--- /dev/null
+From stable+bounces-260533-greg=kroah.com@vger.kernel.org Thu Jun 4 21:26:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 11:49:19 -0400
+Subject: iio: dac: ad5686: acquire lock when doing powerdown control
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604154919.3732423-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit 5237c3175cae5ab05f18878cec3301a04403859e ]
+
+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: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- 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,7 +61,9 @@ static ssize_t ad5686_read_dac_powerdown
+ {
+ struct ad5686_state *st = iio_priv(indio_dev);
+
+- return sprintf(buf, "%d\n", !!(st->pwr_down_mask &
++ 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 stable+bounces-260609-greg=kroah.com@vger.kernel.org Fri Jun 5 07:22:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 21:51:51 -0400
+Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605015151.3131582-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit ecae2ae606d493cf11457946436335bd0e726663 ]
+
+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>
+[ adapted `has_external_vref` to the in-tree equivalent `voltage_uv` variable in the `val =` computation ]
+Signed-off-by: Sasha Levin <sashal@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
+@@ -496,7 +496,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;
+@@ -508,9 +508,9 @@ int ad5686_probe(struct device *dev,
+ goto error_disable_reg;
+ }
+
+- val = (voltage_uv | ref_bit_msk);
++ val = voltage_uv ? ref_bit_msk : 0;
+
+- ret = st->write(st, cmd, 0, !!val);
++ ret = st->write(st, cmd, 0, val);
+ if (ret)
+ goto error_disable_reg;
+
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -44,6 +44,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 stable+bounces-260590-greg=kroah.com@vger.kernel.org Fri Jun 5 05:19:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 19:49:37 -0400
+Subject: iio: gyro: adis16260: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: "Antoniu Miclaus" <antoniu.miclaus@analog.com>, "Nuno Sá" <nuno.sa@analog.com>, Stable@vger.kernel.org, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260604234937.2471947-1-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 761e8b489e6cf166c574034b70637f8a7eadd0ee ]
+
+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: Sasha Levin <sashal@kernel.org>
+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
+@@ -293,6 +293,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;
++
+ mutex_lock(&adis->state_lock);
+ if (spi_get_device_id(adis->spi)->driver_data)
+ t = 256 / val;
--- /dev/null
+From stable+bounces-260764-greg=kroah.com@vger.kernel.org Sat Jun 6 00:10:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 14:31:31 -0400
+Subject: net: skbuff: fix missing zerocopy reference in pskb_carve helpers
+To: stable@vger.kernel.org
+Cc: Minh Nguyen <minhnguyen.080505@gmail.com>, Willem de Bruijn <willemb@google.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605183131.2056525-1-sashal@kernel.org>
+
+From: Minh Nguyen <minhnguyen.080505@gmail.com>
+
+[ Upstream commit 98d0912e9f841e5529a5b89a972805f34cb1c69d ]
+
+pskb_carve_inside_header() and pskb_carve_inside_nonlinear() both copy
+the old skb_shared_info header into a new buffer via memcpy(), which
+includes the destructor_arg pointer (uarg) for MSG_ZEROCOPY skbs.
+Neither function calls net_zcopy_get() for the new shinfo, creating an
+unaccounted holder: every skb_shared_info with destructor_arg set will
+call skb_zcopy_clear() once when freed, but the corresponding
+net_zcopy_get() was never called for the new copy. Repeated calls
+drive uarg->refcnt to zero prematurely, freeing ubuf_info_msgzc while
+TX skbs still hold live destructor_arg pointers.
+
+KASAN reports use-after-free on a freed ubuf_info_msgzc:
+
+ BUG: KASAN: slab-use-after-free in skb_release_data+0x77b/0x810
+ Read of size 8 at addr ffff88801574d3e8 by task poc/220
+
+ Call Trace:
+ skb_release_data+0x77b/0x810
+ kfree_skb_list_reason+0x13e/0x610
+ skb_release_data+0x4cd/0x810
+ sk_skb_reason_drop+0xf3/0x340
+ skb_queue_purge_reason+0x282/0x440
+ rds_tcp_inc_free+0x1e/0x30
+ rds_recvmsg+0x354/0x1780
+ __sys_recvmsg+0xdf/0x180
+
+ Allocated by task 219:
+ msg_zerocopy_realloc+0x157/0x7b0
+ tcp_sendmsg_locked+0x2892/0x3ba0
+
+ Freed by task 219:
+ ip_recv_error+0x74a/0xb10
+ tcp_recvmsg+0x475/0x530
+
+The skb consuming the late access still referenced the same uarg via
+shinfo->destructor_arg copied by pskb_carve_inside_nonlinear() without
+a refcount bump. This has been verified to be reliably exploitable: a
+working proof-of-concept achieves full root privilege escalation from
+an unprivileged local user on a default kernel configuration.
+
+The fix follows the pattern of pskb_expand_head() which has the same
+memcpy/cloned structure. For pskb_carve_inside_header(), net_zcopy_get()
+is placed after skb_orphan_frags() succeeds, so the orphan error path
+needs no cleanup. For pskb_carve_inside_nonlinear(), net_zcopy_get() is
+placed after all failure points and just before skb_release_data(), so
+no error path needs cleanup at all -- matching pskb_expand_head() more
+closely and avoiding the need for a balancing net_zcopy_put().
+
+Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-sonnet-4-6
+Signed-off-by: Minh Nguyen <minhnguyen.080505@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260526041240.329462-1-minhnguyen.080505@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/skbuff.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -6058,6 +6058,8 @@ static int pskb_carve_inside_header(stru
+ kfree(data);
+ return -ENOMEM;
+ }
++ if (skb_zcopy(skb))
++ refcount_inc(&skb_uarg(skb)->refcnt);
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+ skb_frag_ref(skb, i);
+ if (skb_has_frag_list(skb))
+@@ -6210,6 +6212,8 @@ static int pskb_carve_inside_nonlinear(s
+ kfree(data);
+ return -ENOMEM;
+ }
++ if (skb_zcopy(skb))
++ refcount_inc(&skb_uarg(skb)->refcnt);
+ skb_release_data(skb);
+
+ skb->head = data;
--- /dev/null
+From sashal@kernel.org Sat Jun 6 01:08:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 15:38:21 -0400
+Subject: serial: samsung_tty: Use port lock wrappers
+To: stable@vger.kernel.org
+Cc: Thomas Gleixner <tglx@linutronix.de>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-1-sashal@kernel.org>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 97d7a9aeba1d424c2359f1686d02c75d798ad184 ]
+
+When a serial port is used for kernel console output, then all
+modifications to the UART registers which are done from other contexts,
+e.g. getty, termios, are interference points for the kernel console.
+
+So far this has been ignored and the printk output is based on the
+principle of hope. The rework of the console infrastructure which aims to
+support threaded and atomic consoles, requires to mark sections which
+modify the UART registers as unsafe. This allows the atomic write function
+to make informed decisions and eventually to restore operational state. It
+also allows to prevent the regular UART code from modifying UART registers
+while printk output is in progress.
+
+All modifications of UART registers are guarded by the UART port lock,
+which provides an obvious synchronization point with the console
+infrastructure.
+
+To avoid adding this functionality to all UART drivers, wrap the
+spin_[un]lock*() invocations for uart_port::lock into helper functions
+which just contain the spin_[un]lock*() invocations for now. In a
+subsequent step these helpers will gain the console synchronization
+mechanisms.
+
+Converted with coccinelle. No functional change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20230914183831.587273-54-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -245,7 +245,7 @@ static void s3c24xx_serial_rx_enable(str
+ unsigned int ucon, ufcon;
+ int count = 10000;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ while (--count && !s3c24xx_serial_txempty_nofifo(port))
+ udelay(100);
+@@ -259,7 +259,7 @@ static void s3c24xx_serial_rx_enable(str
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ ourport->rx_enabled = 1;
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+@@ -268,14 +268,14 @@ static void s3c24xx_serial_rx_disable(st
+ unsigned long flags;
+ unsigned int ucon;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ ucon = rd_regl(port, S3C2410_UCON);
+ ucon &= ~S3C2410_UCON_RXIRQMODE;
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ ourport->rx_enabled = 0;
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
+@@ -334,7 +334,7 @@ static void s3c24xx_serial_tx_dma_comple
+ dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr,
+ dma->tx_size, DMA_TO_DEVICE);
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ port->icount.tx += count;
+@@ -344,7 +344,7 @@ static void s3c24xx_serial_tx_dma_comple
+ uart_write_wakeup(port);
+
+ s3c24xx_serial_start_next_tx(ourport);
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
+@@ -579,7 +579,7 @@ static void s3c24xx_serial_rx_dma_comple
+ received = dma->rx_bytes_requested - state.residue;
+ async_tx_ack(dma->rx_desc);
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ if (received)
+ s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
+@@ -591,7 +591,7 @@ static void s3c24xx_serial_rx_dma_comple
+
+ s3c64xx_start_rx_dma(ourport);
+
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
+@@ -679,7 +679,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+ utrstat = rd_regl(port, S3C2410_UTRSTAT);
+ rd_regl(port, S3C2410_UFSTAT);
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
+ s3c64xx_start_rx_dma(ourport);
+@@ -708,7 +708,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+ wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
+
+ finish:
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+
+ return IRQ_HANDLED;
+ }
+@@ -806,9 +806,9 @@ static irqreturn_t s3c24xx_serial_rx_cha
+ struct uart_port *port = &ourport->port;
+ unsigned long flags;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+ s3c24xx_serial_rx_drain_fifo(ourport);
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+
+ return IRQ_HANDLED;
+ }
+@@ -956,7 +956,7 @@ static void s3c24xx_serial_break_ctl(str
+ unsigned long flags;
+ unsigned int ucon;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ ucon = rd_regl(port, S3C2410_UCON);
+
+@@ -967,7 +967,7 @@ static void s3c24xx_serial_break_ctl(str
+
+ wr_regl(port, S3C2410_UCON, ucon);
+
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
+@@ -1192,7 +1192,7 @@ static int s3c64xx_serial_startup(struct
+ ourport->tx_enabled = 0;
+ ourport->tx_claimed = 1;
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ ufcon = rd_regl(port, S3C2410_UFCON);
+ ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+@@ -1202,7 +1202,7 @@ static int s3c64xx_serial_startup(struct
+
+ enable_rx_pio(ourport);
+
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+
+ /* Enable Rx Interrupt */
+ s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
+@@ -1479,7 +1479,7 @@ static void s3c24xx_serial_set_termios(s
+ ulcon |= S3C2410_LCON_PNONE;
+ }
+
+- spin_lock_irqsave(&port->lock, flags);
++ uart_port_lock_irqsave(port, &flags);
+
+ dev_dbg(port->dev,
+ "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
+@@ -1537,7 +1537,7 @@ static void s3c24xx_serial_set_termios(s
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |= RXSTAT_DUMMY_READ;
+
+- spin_unlock_irqrestore(&port->lock, flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static const char *s3c24xx_serial_type(struct uart_port *port)
rdma-umem-fix-kernel-doc-warnings.patch
rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
rdma-umem-fix-truncation-for-block-sizes-4g.patch
+bluetooth-l2cap-use-chan-timer-to-close-channels-in-cleanup_listen.patch
+iio-dac-ad5686-acquire-lock-when-doing-powerdown-control.patch
+iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
+usb-cdns3-gadget-fix-request-skipping-after-clearing-halt.patch
+iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
+iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
+iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
+iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
+xfrm-input-hold-netns-during-deferred-transport-reinjection.patch
+net-skbuff-fix-missing-zerocopy-reference-in-pskb_carve-helpers.patch
+serial-samsung_tty-use-port-lock-wrappers.patch
+tty-serial-samsung-use-u32-for-register-interactions.patch
+tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
+usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
+usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
--- /dev/null
+From stable+bounces-260807-greg=kroah.com@vger.kernel.org Sat Jun 6 01:08:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 15:38:23 -0400
+Subject: tty: serial: samsung: Remove redundant port lock acquisition in rx helpers
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, stable <stable@kernel.org>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-3-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit a3bb136bff5e6a5e48cdd813246c9c4686feaaa9 ]
+
+Sashiko identified a deadlock when the console flow is engaged [1].
+
+When console flow control is enabled (UPF_CONS_FLOW),
+s3c24xx_serial_stop_tx() calls s3c24xx_serial_rx_enable() and
+s3c24xx_serial_start_tx() calls s3c24xx_serial_rx_disable().
+
+The serial core framework invokes the .stop_tx() and .start_tx()
+callbacks with the port->lock spinlock already held. Furthermore, all
+internal driver paths that invoke stop_tx (such as the DMA TX
+completion handler s3c24xx_serial_tx_dma_complete() or the PIO TX IRQ
+handler s3c24xx_serial_tx_irq()) also acquire port->lock prior to
+calling it. (Note that s3c24xx_serial_start_tx() is only invoked by the
+serial core).
+
+However, s3c24xx_serial_rx_enable() and s3c24xx_serial_rx_disable()
+unconditionally attempt to acquire port->lock again using
+uart_port_lock_irqsave(). Since spinlocks are not recursive, this
+causes a deadlock on the same CPU when console flow control is engaged.
+
+Remove the redundant lock acquisition from both rx helper functions.
+
+Cc: stable <stable@kernel.org>
+Fixes: b497549a035c ("[ARM] S3C24XX: Split serial driver into core and per-cpu drivers")
+Reported-by: John Ogness <john.ogness@linutronix.de>
+Closes: https://sashiko.dev/#/patchset/20260506121606.5805-1-john.ogness%40linutronix.de [1]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://patch.msgid.link/20260515-samsung-tty-flow-control-deadlock-v1-1-93255edbc9bc@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -241,12 +241,9 @@ static int s3c24xx_serial_has_interrupt_
+ static void s3c24xx_serial_rx_enable(struct uart_port *port)
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+- unsigned long flags;
+ int count = 10000;
+ u32 ucon, ufcon;
+
+- uart_port_lock_irqsave(port, &flags);
+-
+ while (--count && !s3c24xx_serial_txempty_nofifo(port))
+ udelay(100);
+
+@@ -259,23 +256,18 @@ static void s3c24xx_serial_rx_enable(str
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ ourport->rx_enabled = 1;
+- uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+- unsigned long flags;
+ u32 ucon;
+
+- uart_port_lock_irqsave(port, &flags);
+-
+ ucon = rd_regl(port, S3C2410_UCON);
+ ucon &= ~S3C2410_UCON_RXIRQMODE;
+ wr_regl(port, S3C2410_UCON, ucon);
+
+ ourport->rx_enabled = 0;
+- uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
--- /dev/null
+From stable+bounces-260806-greg=kroah.com@vger.kernel.org Sat Jun 6 01:08:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 15:38:22 -0400
+Subject: tty: serial: samsung: use u32 for register interactions
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, Sam Protsenko <semen.protsenko@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193823.2169333-2-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 032a725c16add79332d774348d7ad7d0d4b86479 ]
+
+All registers of the IP have 32 bits. Use u32 variables when reading
+or writing from/to the registers. The purpose of those variables becomes
+clearer.
+
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://lore.kernel.org/r/20240119104526.1221243-9-tudor.ambarus@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c | 67 +++++++++++++++++++--------------------
+ 1 file changed, 34 insertions(+), 33 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -186,7 +186,7 @@ static void wr_reg(struct uart_port *por
+ /* Byte-order aware bit setting/clearing functions. */
+
+ static inline void s3c24xx_set_bit(struct uart_port *port, int idx,
+- unsigned int reg)
++ u32 reg)
+ {
+ unsigned long flags;
+ u32 val;
+@@ -199,7 +199,7 @@ static inline void s3c24xx_set_bit(struc
+ }
+
+ static inline void s3c24xx_clear_bit(struct uart_port *port, int idx,
+- unsigned int reg)
++ u32 reg)
+ {
+ unsigned long flags;
+ u32 val;
+@@ -242,8 +242,8 @@ static void s3c24xx_serial_rx_enable(str
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+ unsigned long flags;
+- unsigned int ucon, ufcon;
+ int count = 10000;
++ u32 ucon, ufcon;
+
+ uart_port_lock_irqsave(port, &flags);
+
+@@ -266,7 +266,7 @@ static void s3c24xx_serial_rx_disable(st
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+ unsigned long flags;
+- unsigned int ucon;
++ u32 ucon;
+
+ uart_port_lock_irqsave(port, &flags);
+
+@@ -551,7 +551,7 @@ static inline struct s3c2410_uartcfg
+ }
+
+ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
+- unsigned long ufstat)
++ u32 ufstat)
+ {
+ struct s3c24xx_uart_info *info = ourport->info;
+
+@@ -623,7 +623,7 @@ static void s3c64xx_start_rx_dma(struct
+ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
+ {
+ struct uart_port *port = &ourport->port;
+- unsigned int ucon;
++ u32 ucon;
+
+ /* set Rx mode to DMA mode */
+ ucon = rd_regl(port, S3C2410_UCON);
+@@ -646,7 +646,7 @@ static void enable_rx_dma(struct s3c24xx
+ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
+ {
+ struct uart_port *port = &ourport->port;
+- unsigned int ucon;
++ u32 ucon;
+
+ /* set Rx mode to DMA mode */
+ ucon = rd_regl(port, S3C2410_UCON);
+@@ -667,7 +667,6 @@ static void s3c24xx_serial_rx_drain_fifo
+
+ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
+ {
+- unsigned int utrstat, received;
+ struct s3c24xx_uart_port *ourport = dev_id;
+ struct uart_port *port = &ourport->port;
+ struct s3c24xx_uart_dma *dma = ourport->dma;
+@@ -675,6 +674,8 @@ static irqreturn_t s3c24xx_serial_rx_cha
+ struct tty_port *t = &port->state->port;
+ unsigned long flags;
+ struct dma_tx_state state;
++ unsigned int received;
++ u32 utrstat;
+
+ utrstat = rd_regl(port, S3C2410_UTRSTAT);
+ rd_regl(port, S3C2410_UFSTAT);
+@@ -716,9 +717,10 @@ finish:
+ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
+ {
+ struct uart_port *port = &ourport->port;
+- unsigned int ufcon, ch, flag, ufstat, uerstat;
++ unsigned int ch, flag;
+ unsigned int fifocnt = 0;
+ int max_count = port->fifosize;
++ u32 ufcon, ufstat, uerstat;
+
+ while (max_count-- > 0) {
+ /*
+@@ -898,7 +900,7 @@ static irqreturn_t s3c64xx_serial_handle
+ {
+ struct s3c24xx_uart_port *ourport = id;
+ struct uart_port *port = &ourport->port;
+- unsigned int pend = rd_regl(port, S3C64XX_UINTP);
++ u32 pend = rd_regl(port, S3C64XX_UINTP);
+ irqreturn_t ret = IRQ_HANDLED;
+
+ if (pend & S3C64XX_UINTM_RXD_MSK) {
+@@ -915,8 +917,8 @@ static irqreturn_t s3c64xx_serial_handle
+ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
+ {
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+- unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
+- unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
++ u32 ufstat = rd_regl(port, S3C2410_UFSTAT);
++ u32 ufcon = rd_regl(port, S3C2410_UFCON);
+
+ if (ufcon & S3C2410_UFCON_FIFOMODE) {
+ if ((ufstat & info->tx_fifomask) != 0 ||
+@@ -931,7 +933,7 @@ static unsigned int s3c24xx_serial_tx_em
+ /* no modem control lines */
+ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
+ {
+- unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
++ u32 umstat = rd_reg(port, S3C2410_UMSTAT);
+
+ if (umstat & S3C2410_UMSTAT_CTS)
+ return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+@@ -941,7 +943,7 @@ static unsigned int s3c24xx_serial_get_m
+
+ static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+- unsigned int umcon = rd_regl(port, S3C2410_UMCON);
++ u32 umcon = rd_regl(port, S3C2410_UMCON);
+
+ if (mctrl & TIOCM_RTS)
+ umcon |= S3C2410_UMCOM_RTS_LOW;
+@@ -954,7 +956,7 @@ static void s3c24xx_serial_set_mctrl(str
+ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
+ {
+ unsigned long flags;
+- unsigned int ucon;
++ u32 ucon;
+
+ uart_port_lock_irqsave(port, &flags);
+
+@@ -1167,7 +1169,7 @@ static int s3c64xx_serial_startup(struct
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+ unsigned long flags;
+- unsigned int ufcon;
++ u32 ufcon;
+ int ret;
+
+ wr_regl(port, S3C64XX_UINTM, 0xf);
+@@ -1210,6 +1212,7 @@ static int s3c64xx_serial_startup(struct
+ return ret;
+ }
+
++
+ /* power power management control */
+
+ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
+@@ -1261,7 +1264,7 @@ static void s3c24xx_serial_pm(struct uar
+ static inline int s3c24xx_serial_getsource(struct uart_port *port)
+ {
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+- unsigned int ucon;
++ u32 ucon;
+
+ if (info->num_clks == 1)
+ return 0;
+@@ -1275,7 +1278,7 @@ static void s3c24xx_serial_setsource(str
+ unsigned int clk_sel)
+ {
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+- unsigned int ucon;
++ u32 ucon;
+
+ if (info->num_clks == 1)
+ return;
+@@ -1394,9 +1397,8 @@ static void s3c24xx_serial_set_termios(s
+ struct clk *clk = ERR_PTR(-EINVAL);
+ unsigned long flags;
+ unsigned int baud, quot, clk_sel = 0;
+- unsigned int ulcon;
+- unsigned int umcon;
+ unsigned int udivslot = 0;
++ u32 ulcon, umcon;
+
+ /*
+ * We don't support modem control lines.
+@@ -1712,7 +1714,7 @@ static void s3c24xx_serial_resetport(str
+ struct s3c2410_uartcfg *cfg)
+ {
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+- unsigned long ucon = rd_regl(port, S3C2410_UCON);
++ u32 ucon = rd_regl(port, S3C2410_UCON);
+ unsigned int ucon_mask;
+
+ ucon_mask = info->clksel_mask;
+@@ -2150,7 +2152,7 @@ static int s3c24xx_serial_resume_noirq(s
+ if (port) {
+ /* restore IRQ mask */
+ if (s3c24xx_serial_has_interrupt_mask(port)) {
+- unsigned int uintm = 0xf;
++ u32 uintm = 0xf;
+
+ if (ourport->tx_enabled)
+ uintm &= ~S3C64XX_UINTM_TXD_MSK;
+@@ -2188,10 +2190,10 @@ static const struct dev_pm_ops s3c24xx_s
+ static struct uart_port *cons_uart;
+
+ static int
+-s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
++s3c24xx_serial_console_txrdy(struct uart_port *port, u32 ufcon)
+ {
+ struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+- unsigned long ufstat, utrstat;
++ u32 ufstat, utrstat;
+
+ if (ufcon & S3C2410_UFCON_FIFOMODE) {
+ /* fifo mode - check amount of data in fifo registers... */
+@@ -2207,7 +2209,7 @@ s3c24xx_serial_console_txrdy(struct uart
+ }
+
+ static bool
+-s3c24xx_port_configured(unsigned int ucon)
++s3c24xx_port_configured(u32 ucon)
+ {
+ /* consider the serial port configured if the tx/rx mode set */
+ return (ucon & 0xf) != 0;
+@@ -2222,7 +2224,7 @@ s3c24xx_port_configured(unsigned int uco
+ static int s3c24xx_serial_get_poll_char(struct uart_port *port)
+ {
+ struct s3c24xx_uart_port *ourport = to_ourport(port);
+- unsigned int ufstat;
++ u32 ufstat;
+
+ ufstat = rd_regl(port, S3C2410_UFSTAT);
+ if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
+@@ -2234,8 +2236,8 @@ static int s3c24xx_serial_get_poll_char(
+ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
+ unsigned char c)
+ {
+- unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
+- unsigned int ucon = rd_regl(port, S3C2410_UCON);
++ u32 ufcon = rd_regl(port, S3C2410_UFCON);
++ u32 ucon = rd_regl(port, S3C2410_UCON);
+
+ /* not possible to xmit on unconfigured port */
+ if (!s3c24xx_port_configured(ucon))
+@@ -2251,7 +2253,7 @@ static void s3c24xx_serial_put_poll_char
+ static void
+ s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
+ {
+- unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
++ u32 ufcon = rd_regl(port, S3C2410_UFCON);
+
+ while (!s3c24xx_serial_console_txrdy(port, ufcon))
+ cpu_relax();
+@@ -2262,7 +2264,7 @@ static void
+ s3c24xx_serial_console_write(struct console *co, const char *s,
+ unsigned int count)
+ {
+- unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
++ u32 ucon = rd_regl(cons_uart, S3C2410_UCON);
+
+ /* not possible to xmit on unconfigured port */
+ if (!s3c24xx_port_configured(ucon))
+@@ -2276,11 +2278,9 @@ s3c24xx_serial_get_options(struct uart_p
+ int *parity, int *bits)
+ {
+ struct clk *clk;
+- unsigned int ulcon;
+- unsigned int ucon;
+- unsigned int ubrdiv;
+ unsigned long rate;
+ unsigned int clk_sel;
++ u32 ulcon, ucon, ubrdiv;
+ char clk_name[MAX_CLK_NAME_LENGTH];
+
+ ulcon = rd_regl(port, S3C2410_ULCON);
+@@ -2677,6 +2677,7 @@ static void samsung_early_write(struct c
+ uart_console_write(&dev->port, s, n, samsung_early_putc);
+ }
+
++
+ static int __init samsung_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+ {
--- /dev/null
+From sashal@kernel.org Fri Jun 5 01:15:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jun 2026 15:45:00 -0400
+Subject: usb: cdns3: gadget: fix request skipping after clearing halt
+To: stable@vger.kernel.org
+Cc: Yongchao Wu <yongchao.wu@autochips.com>, stable <stable@kernel.org>, Peter Chen <peter.chen@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604194501.920866-1-sashal@kernel.org>
+
+From: Yongchao Wu <yongchao.wu@autochips.com>
+
+[ Upstream commit c8778ff817a7047d6848fefba99dcb27b1bf01fe ]
+
+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: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/gadget.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2798,9 +2798,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 stable+bounces-260813-greg=kroah.com@vger.kernel.org Sat Jun 6 01:16:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 15:46:20 -0400
+Subject: usb: gadget: f_hid: fix device reference leak in hidg_alloc()
+To: stable@vger.kernel.org
+Cc: Guangshuo Li <lgs201920130244@gmail.com>, stable <stable@kernel.org>, Johan Hovold <johan@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605194620.2186017-2-sashal@kernel.org>
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+[ Upstream commit 4f88d65def6f3c90121601b4f62a4c967f3063a6 ]
+
+hidg_alloc() initializes hidg->dev with device_initialize() before
+calling dev_set_name(). If dev_set_name() fails, the function currently
+jumps to err_unlock and returns without calling put_device().
+
+This leaves the device reference unbalanced and prevents hidg_release()
+from being called. Calling put_device() here is also safe, since
+hidg_release() only frees resources owned by hidg.
+
+The issue was identified by a static analysis tool I developed and
+confirmed by manual review.
+
+Route the dev_set_name() failure path through err_put_device so the
+device reference is dropped properly.
+
+Fixes: 89ff3dfac604 ("usb: gadget: f_hid: fix f_hidg lifetime vs cdev")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Reviewed-by: Johan Hovold johan@kernel.org
+Link: https://patch.msgid.link/20260413142119.2977716-1-lgs201920130244@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1278,7 +1278,7 @@ static struct usb_function *hidg_alloc(s
+ hidg->dev.devt = MKDEV(major, opts->minor);
+ ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+ if (ret)
+- goto err_unlock;
++ goto err_put_device;
+
+ hidg->bInterfaceSubClass = opts->subclass;
+ hidg->bInterfaceProtocol = opts->protocol;
+@@ -1313,7 +1313,6 @@ static struct usb_function *hidg_alloc(s
+
+ err_put_device:
+ put_device(&hidg->dev);
+-err_unlock:
+ mutex_unlock(&opts->lock);
+ return ERR_PTR(ret);
+ }
--- /dev/null
+From stable+bounces-260812-greg=kroah.com@vger.kernel.org Sat Jun 6 01:16:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 15:46:19 -0400
+Subject: usb: gadget: f_hid: tidy error handling in hidg_alloc
+To: stable@vger.kernel.org
+Cc: John Keeping <john@metanate.com>, Lee Jones <lee@kernel.org>, Andrzej Pietrasiewicz <andrzej.p@collabora.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605194620.2186017-1-sashal@kernel.org>
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 ]
+
+Unify error handling at the end of the function, reducing the risk of
+missing something on one of the error paths.
+
+Moving the increment of opts->refcnt later means there is no need to
+decrement it on the error path and is safe as this is guarded by
+opts->lock which is held for this entire section.
+
+Tested-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Signed-off-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20221122123523.3068034-4-john@metanate.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 4f88d65def6f ("usb: gadget: f_hid: fix device reference leak in hidg_alloc()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1265,7 +1265,6 @@ static struct usb_function *hidg_alloc(s
+ opts = container_of(fi, struct f_hid_opts, func_inst);
+
+ mutex_lock(&opts->lock);
+- ++opts->refcnt;
+
+ spin_lock_init(&hidg->write_spinlock);
+ spin_lock_init(&hidg->read_spinlock);
+@@ -1278,11 +1277,8 @@ static struct usb_function *hidg_alloc(s
+ hidg->dev.class = hidg_class;
+ hidg->dev.devt = MKDEV(major, opts->minor);
+ ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+- if (ret) {
+- --opts->refcnt;
+- mutex_unlock(&opts->lock);
+- return ERR_PTR(ret);
+- }
++ if (ret)
++ goto err_unlock;
+
+ hidg->bInterfaceSubClass = opts->subclass;
+ hidg->bInterfaceProtocol = opts->protocol;
+@@ -1293,14 +1289,13 @@ static struct usb_function *hidg_alloc(s
+ opts->report_desc_length,
+ GFP_KERNEL);
+ if (!hidg->report_desc) {
+- put_device(&hidg->dev);
+- --opts->refcnt;
+- mutex_unlock(&opts->lock);
+- return ERR_PTR(-ENOMEM);
++ ret = -ENOMEM;
++ goto err_put_device;
+ }
+ }
+ hidg->use_out_ep = !opts->no_out_endpoint;
+
++ ++opts->refcnt;
+ mutex_unlock(&opts->lock);
+
+ hidg->func.name = "hid";
+@@ -1315,6 +1310,12 @@ static struct usb_function *hidg_alloc(s
+ hidg->qlen = 4;
+
+ return &hidg->func;
++
++err_put_device:
++ put_device(&hidg->dev);
++err_unlock:
++ mutex_unlock(&opts->lock);
++ return ERR_PTR(ret);
+ }
+
+ DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc);
--- /dev/null
+From stable+bounces-260691-greg=kroah.com@vger.kernel.org Fri Jun 5 18:36:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jun 2026 09:05:13 -0400
+Subject: xfrm: input: hold netns during deferred transport reinjection
+To: stable@vger.kernel.org
+Cc: Zhengchuan Liang <zcliangcn@gmail.com>, stable@kernel.org, Yuan Tan <yuantan098@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Luxing Yin <tr0jan@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605130513.410471-1-sashal@kernel.org>
+
+From: Zhengchuan Liang <zcliangcn@gmail.com>
+
+[ Upstream commit c16f74dc1d75d0e2e7670076d5375deda110ebeb ]
+
+Transport-mode reinjection stores a struct net pointer in skb->cb and
+uses it later from xfrm_trans_reinject(). That pointer must stay valid
+until the deferred callback runs.
+
+Take a netns reference when queueing deferred reinjection work and drop
+it after the callback completes. Use maybe_get_net() so the queueing
+path does not revive a namespace that is already being torn down.
+
+This keeps the existing workqueue design and fixes the netns lifetime
+handling in one place for all users of xfrm_trans_queue_net().
+
+Fixes: 7b3801927e52 ("xfrm: introduce xfrm_trans_queue_net")
+Cc: stable@kernel.org
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Co-developed-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Luxing Yin <tr0jan@lzu.edu.cn>
+Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Assisted-by: Codex:gpt-5.4
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_input.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -777,9 +777,12 @@ static void xfrm_trans_reinject(unsigned
+ __skb_queue_head_init(&queue);
+ skb_queue_splice_init(&trans->queue, &queue);
+
+- while ((skb = __skb_dequeue(&queue)))
+- XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
+- NULL, skb);
++ while ((skb = __skb_dequeue(&queue))) {
++ struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
++
++ XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
++ put_net(net);
++ }
+ }
+
+ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+@@ -787,6 +790,7 @@ int xfrm_trans_queue_net(struct net *net
+ struct sk_buff *))
+ {
+ struct xfrm_trans_tasklet *trans;
++ struct net *hold_net;
+
+ trans = this_cpu_ptr(&xfrm_trans_tasklet);
+
+@@ -795,8 +799,12 @@ int xfrm_trans_queue_net(struct net *net
+
+ BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
+
++ hold_net = maybe_get_net(net);
++ if (!hold_net)
++ return -ENODEV;
++
+ XFRM_TRANS_SKB_CB(skb)->finish = finish;
+- XFRM_TRANS_SKB_CB(skb)->net = net;
++ XFRM_TRANS_SKB_CB(skb)->net = hold_net;
+ __skb_queue_tail(&trans->queue, skb);
+ tasklet_schedule(&trans->tasklet);
+ return 0;