* [PATCH AUTOSEL 6.14 02/31] usb: host: max3421-hcd: Add missing spi_device_id table
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 03/31] usb: typec: ucsi: return CCI and message from sync_control callback Sasha Levin
` (28 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Alexander Stein, Greg Kroah-Hartman, Sasha Levin, mark.tomlinson,
linux-usb
From: Alexander Stein <alexander.stein@mailbox.org>
[ Upstream commit 41d5e3806cf589f658f92c75195095df0b66f66a ]
"maxim,max3421" DT compatible is missing its SPI device ID entry, not
allowing module autoloading and leading to the following message:
"SPI driver max3421-hcd has no spi_device_id for maxim,max3421"
Fix this by adding the spi_device_id table.
Signed-off-by: Alexander Stein <alexander.stein@mailbox.org>
Link: https://lore.kernel.org/r/20250128195114.56321-1-alexander.stein@mailbox.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/max3421-hcd.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0881fdd1823e0..dcf31a592f5d1 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1946,6 +1946,12 @@ max3421_remove(struct spi_device *spi)
usb_put_hcd(hcd);
}
+static const struct spi_device_id max3421_spi_ids[] = {
+ { "max3421" },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, max3421_spi_ids);
+
static const struct of_device_id max3421_of_match_table[] = {
{ .compatible = "maxim,max3421", },
{},
@@ -1955,6 +1961,7 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table);
static struct spi_driver max3421_driver = {
.probe = max3421_probe,
.remove = max3421_remove,
+ .id_table = max3421_spi_ids,
.driver = {
.name = "max3421-hcd",
.of_match_table = max3421_of_match_table,
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 03/31] usb: typec: ucsi: return CCI and message from sync_control callback
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 02/31] usb: host: max3421-hcd: Add missing spi_device_id table Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 04/31] usb: typec: ucsi: ccg: move command quirks to ucsi_ccg_sync_control() Sasha Levin
` (27 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Dmitry Baryshkov, Łukasz Bartosik, Greg Kroah-Hartman,
Sasha Levin, abhishekpandit, jthies, akuchynski, heikki.krogerus,
bleung, lumag, pooja.katiyar, diogo.ivo, madhu.m, lk,
saranya.gopal, u.kleine-koenig, dan.carpenter, mario.limonciello,
gongruiqi1, chrome-platform, linux-usb
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[ Upstream commit 667ecac55861281c1f5e107c8550ae893b3984f6 ]
Some of the drivers emulate or handle some of the commands in the
platform-specific way. The code ends up being split between several
callbacks, which complicates emulation.
In preparation to reworking such drivers, move read_cci() and
read_message_in() calls into ucsi_sync_control_common().
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Łukasz Bartosik <ukaszb@chromium.org>
Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-1-462a1ec22ecc@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/cros_ec_ucsi.c | 5 +++--
drivers/usb/typec/ucsi/ucsi.c | 19 +++++++++++--------
drivers/usb/typec/ucsi/ucsi.h | 6 ++++--
drivers/usb/typec/ucsi/ucsi_acpi.c | 5 +++--
drivers/usb/typec/ucsi/ucsi_ccg.c | 5 +++--
5 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
index c605c86167268..744f0709a40ed 100644
--- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c
+++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c
@@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd)
return 0;
}
-static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd)
+static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci,
+ void *data, size_t size)
{
struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi);
int ret;
- ret = ucsi_sync_control_common(ucsi, cmd);
+ ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size);
switch (ret) {
case -EBUSY:
/* EC may return -EBUSY if CCI.busy is set.
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
index 2a2915b0a645f..e8c7e9dc49309 100644
--- a/drivers/usb/typec/ucsi/ucsi.c
+++ b/drivers/usb/typec/ucsi/ucsi.c
@@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci)
}
EXPORT_SYMBOL_GPL(ucsi_notify_common);
-int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
+int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size)
{
bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI;
int ret;
@@ -80,6 +81,13 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command)
else
clear_bit(COMMAND_PENDING, &ucsi->flags);
+ if (!ret && cci)
+ ret = ucsi->ops->read_cci(ucsi, cci);
+
+ if (!ret && data &&
+ (*cci & UCSI_CCI_COMMAND_COMPLETE))
+ ret = ucsi->ops->read_message_in(ucsi, data, size);
+
return ret;
}
EXPORT_SYMBOL_GPL(ucsi_sync_control_common);
@@ -95,7 +103,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
ctrl |= UCSI_ACK_CONNECTOR_CHANGE;
}
- return ucsi->ops->sync_control(ucsi, ctrl);
+ return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0);
}
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
@@ -108,9 +116,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
if (size > UCSI_MAX_DATA_LENGTH(ucsi))
return -EINVAL;
- ret = ucsi->ops->sync_control(ucsi, command);
- if (ucsi->ops->read_cci(ucsi, cci))
- return -EIO;
+ ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
if (*cci & UCSI_CCI_BUSY)
return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY;
@@ -127,9 +133,6 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
else
err = 0;
- if (!err && data && UCSI_CCI_LENGTH(*cci))
- err = ucsi->ops->read_message_in(ucsi, data, size);
-
/*
* Don't ACK connection change if there was an error.
*/
diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
index 28780acc4af2e..892bcf8dbcd50 100644
--- a/drivers/usb/typec/ucsi/ucsi.h
+++ b/drivers/usb/typec/ucsi/ucsi.h
@@ -79,7 +79,8 @@ struct ucsi_operations {
int (*read_cci)(struct ucsi *ucsi, u32 *cci);
int (*poll_cci)(struct ucsi *ucsi, u32 *cci);
int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len);
- int (*sync_control)(struct ucsi *ucsi, u64 command);
+ int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size);
int (*async_control)(struct ucsi *ucsi, u64 command);
bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig,
struct ucsi_altmode *updated);
@@ -531,7 +532,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con);
int ucsi_resume(struct ucsi *ucsi);
void ucsi_notify_common(struct ucsi *ucsi, u32 cci);
-int ucsi_sync_control_common(struct ucsi *ucsi, u64 command);
+int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size);
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
int ucsi_register_port_psy(struct ucsi_connector *con);
diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
index ac1ebb5d95272..0ac6e5ce4a288 100644
--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
+++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
@@ -128,12 +128,13 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le
return ret;
}
-static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command)
+static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size)
{
struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi);
int ret;
- ret = ucsi_sync_control_common(ucsi, command);
+ ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
if (ret < 0)
return ret;
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 4b1668733a4be..254c391618521 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -628,7 +628,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command)
return ccg_write(uc, reg, (u8 *)&command, sizeof(command));
}
-static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
+static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
+ void *data, size_t size)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
struct ucsi_connector *con;
@@ -652,7 +653,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command)
ucsi_ccg_update_set_new_cam_cmd(uc, con, &command);
}
- ret = ucsi_sync_control_common(ucsi, command);
+ ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
err_put:
pm_runtime_put_sync(uc->dev);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 04/31] usb: typec: ucsi: ccg: move command quirks to ucsi_ccg_sync_control()
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 02/31] usb: host: max3421-hcd: Add missing spi_device_id table Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 03/31] usb: typec: ucsi: return CCI and message from sync_control callback Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 05/31] iio: adc: ad4695: make ad4695_exit_conversion_mode() more robust Sasha Levin
` (26 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Dmitry Baryshkov, Heikki Krogerus, Greg Kroah-Hartman,
Sasha Levin, lumag, dan.carpenter, mario.limonciello, viro, lk,
linux-usb
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
[ Upstream commit 7f82635494ef3391ff6b542249793c7febf99c3f ]
It is easier to keep all command-specific quirks in a single place. Move
them to ucsi_ccg_sync_control() as the code now allows us to return
modified messages data.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-2-462a1ec22ecc@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/typec/ucsi/ucsi_ccg.c | 62 +++++++++++++++----------------
1 file changed, 29 insertions(+), 33 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c
index 254c391618521..618d585905a02 100644
--- a/drivers/usb/typec/ucsi/ucsi_ccg.c
+++ b/drivers/usb/typec/ucsi/ucsi_ccg.c
@@ -222,7 +222,6 @@ struct ucsi_ccg {
u16 fw_build;
struct work_struct pm_work;
- u64 last_cmd_sent;
bool has_multiple_dp;
struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES];
struct ucsi_ccg_altmode updated[UCSI_MAX_ALTMODES];
@@ -538,9 +537,10 @@ static void ucsi_ccg_update_set_new_cam_cmd(struct ucsi_ccg *uc,
* first and then vdo=0x3
*/
static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc,
- struct ucsi_altmode *alt)
+ struct ucsi_altmode *alt,
+ u64 command)
{
- switch (UCSI_ALTMODE_OFFSET(uc->last_cmd_sent)) {
+ switch (UCSI_ALTMODE_OFFSET(command)) {
case NVIDIA_FTB_DP_OFFSET:
if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DBG_VDO)
alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DP_VDO |
@@ -578,37 +578,11 @@ static int ucsi_ccg_read_cci(struct ucsi *ucsi, u32 *cci)
static int ucsi_ccg_read_message_in(struct ucsi *ucsi, void *val, size_t val_len)
{
struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
- struct ucsi_capability *cap;
- struct ucsi_altmode *alt;
spin_lock(&uc->op_lock);
memcpy(val, uc->op_data.message_in, val_len);
spin_unlock(&uc->op_lock);
- switch (UCSI_COMMAND(uc->last_cmd_sent)) {
- case UCSI_GET_CURRENT_CAM:
- if (uc->has_multiple_dp)
- ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)val);
- break;
- case UCSI_GET_ALTERNATE_MODES:
- if (UCSI_ALTMODE_RECIPIENT(uc->last_cmd_sent) ==
- UCSI_RECIPIENT_SOP) {
- alt = val;
- if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
- ucsi_ccg_nvidia_altmode(uc, alt);
- }
- break;
- case UCSI_GET_CAPABILITY:
- if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
- cap = val;
- cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
- }
- break;
- default:
- break;
- }
- uc->last_cmd_sent = 0;
-
return 0;
}
@@ -639,11 +613,9 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
mutex_lock(&uc->lock);
pm_runtime_get_sync(uc->dev);
- uc->last_cmd_sent = command;
-
- if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM &&
+ if (UCSI_COMMAND(command) == UCSI_SET_NEW_CAM &&
uc->has_multiple_dp) {
- con_index = (uc->last_cmd_sent >> 16) &
+ con_index = (command >> 16) &
UCSI_CMD_CONNECTOR_MASK;
if (con_index == 0) {
ret = -EINVAL;
@@ -655,6 +627,30 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
+ switch (UCSI_COMMAND(command)) {
+ case UCSI_GET_CURRENT_CAM:
+ if (uc->has_multiple_dp)
+ ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data);
+ break;
+ case UCSI_GET_ALTERNATE_MODES:
+ if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) {
+ struct ucsi_altmode *alt = data;
+
+ if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
+ ucsi_ccg_nvidia_altmode(uc, alt, command);
+ }
+ break;
+ case UCSI_GET_CAPABILITY:
+ if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
+ struct ucsi_capability *cap = data;
+
+ cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
+ }
+ break;
+ default:
+ break;
+ }
+
err_put:
pm_runtime_put_sync(uc->dev);
mutex_unlock(&uc->lock);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 05/31] iio: adc: ad4695: make ad4695_exit_conversion_mode() more robust
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (2 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 04/31] usb: typec: ucsi: ccg: move command quirks to ucsi_ccg_sync_control() Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 06/31] fs/ntfs3: Keep write operations atomic Sasha Levin
` (25 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Trevor Gamblin, David Lechner, Jonathan Cameron, Sasha Levin,
lars, Michael.Hennerich, nuno.sa, jic23, linux-iio
From: Trevor Gamblin <tgamblin@baylibre.com>
[ Upstream commit 998d20e4e99d909f14d96fdf0bdcf860f7efe3ef ]
Ensure that conversion mode is successfully exited when the command is
issued by adding an extra transfer beforehand, matching the minimum CNV
high and low times from the AD4695 datasheet. The AD4695 has a quirk
where the exit command only works during a conversion, so guarantee this
happens by triggering a conversion in ad4695_exit_conversion_mode().
Then make this even more robust by ensuring that the exit command is run
at AD4695_REG_ACCESS_SCLK_HZ rather than the bus maximum.
Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com>
Reviewed-by: David Lechner <dlechner@baylibre.com>
Tested-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20241113-tgamblin-ad4695_improvements-v2-2-b6bb7c758fc4@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/ad4695.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c
index b79d135a54718..22fdc454b0cea 100644
--- a/drivers/iio/adc/ad4695.c
+++ b/drivers/iio/adc/ad4695.c
@@ -92,6 +92,8 @@
#define AD4695_T_REFBUF_MS 100
#define AD4695_T_REGCONFIG_NS 20
#define AD4695_T_SCK_CNV_DELAY_NS 80
+#define AD4695_T_CNVL_NS 80
+#define AD4695_T_CNVH_NS 10
#define AD4695_REG_ACCESS_SCLK_HZ (10 * MEGA)
/* Max number of voltage input channels. */
@@ -364,11 +366,31 @@ static int ad4695_enter_advanced_sequencer_mode(struct ad4695_state *st, u32 n)
*/
static int ad4695_exit_conversion_mode(struct ad4695_state *st)
{
- struct spi_transfer xfer = {
- .tx_buf = &st->cnv_cmd2,
- .len = 1,
- .delay.value = AD4695_T_REGCONFIG_NS,
- .delay.unit = SPI_DELAY_UNIT_NSECS,
+ /*
+ * An extra transfer is needed to trigger a conversion here so
+ * that we can be 100% sure the command will be processed by the
+ * ADC, rather than relying on it to be in the correct state
+ * when this function is called (this chip has a quirk where the
+ * command only works when reading a conversion, and if the
+ * previous conversion was already read then it won't work). The
+ * actual conversion command is then run at the slower
+ * AD4695_REG_ACCESS_SCLK_HZ speed to guarantee this works.
+ */
+ struct spi_transfer xfers[] = {
+ {
+ .delay.value = AD4695_T_CNVL_NS,
+ .delay.unit = SPI_DELAY_UNIT_NSECS,
+ .cs_change = 1,
+ .cs_change_delay.value = AD4695_T_CNVH_NS,
+ .cs_change_delay.unit = SPI_DELAY_UNIT_NSECS,
+ },
+ {
+ .speed_hz = AD4695_REG_ACCESS_SCLK_HZ,
+ .tx_buf = &st->cnv_cmd2,
+ .len = 1,
+ .delay.value = AD4695_T_REGCONFIG_NS,
+ .delay.unit = SPI_DELAY_UNIT_NSECS,
+ },
};
/*
@@ -377,7 +399,7 @@ static int ad4695_exit_conversion_mode(struct ad4695_state *st)
*/
st->cnv_cmd2 = AD4695_CMD_EXIT_CNV_MODE << 3;
- return spi_sync_transfer(st->spi, &xfer, 1);
+ return spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
}
static int ad4695_set_ref_voltage(struct ad4695_state *st, int vref_mv)
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 06/31] fs/ntfs3: Keep write operations atomic
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (3 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 05/31] iio: adc: ad4695: make ad4695_exit_conversion_mode() more robust Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 07/31] fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size Sasha Levin
` (24 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Lizhi Xu, syzbot+5d0bdc98770e6c55a0fd, Konstantin Komarov,
Sasha Levin, ntfs3
From: Lizhi Xu <lizhi.xu@windriver.com>
[ Upstream commit 285cec318bf5a7a6c8ba999b2b6ec96f9a20590f ]
syzbot reported a NULL pointer dereference in __generic_file_write_iter. [1]
Before the write operation is completed, the user executes ioctl[2] to clear
the compress flag of the file, which causes the is_compressed() judgment to
return 0, further causing the program to enter the wrong process and call the
wrong ops ntfs_aops_cmpr, which triggers the null pointer dereference of
write_begin.
Use inode lock to synchronize ioctl and write to avoid this case.
[1]
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Mem abort info:
ESR = 0x0000000086000006
EC = 0x21: IABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x06: level 2 translation fault
user pgtable: 4k pages, 48-bit VAs, pgdp=000000011896d000
[0000000000000000] pgd=0800000118b44403, p4d=0800000118b44403, pud=0800000117517403, pmd=0000000000000000
Internal error: Oops: 0000000086000006 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 UID: 0 PID: 6427 Comm: syz-executor347 Not tainted 6.13.0-rc3-syzkaller-g573067a5a685 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : 0x0
lr : generic_perform_write+0x29c/0x868 mm/filemap.c:4055
sp : ffff80009d4978a0
x29: ffff80009d4979c0 x28: dfff800000000000 x27: ffff80009d497bc8
x26: 0000000000000000 x25: ffff80009d497960 x24: ffff80008ba71c68
x23: 0000000000000000 x22: ffff0000c655dac0 x21: 0000000000001000
x20: 000000000000000c x19: 1ffff00013a92f2c x18: ffff0000e183aa1c
x17: 0004060000000014 x16: ffff800083275834 x15: 0000000000000001
x14: 0000000000000000 x13: 0000000000000001 x12: ffff0000c655dac0
x11: 0000000000ff0100 x10: 0000000000ff0100 x9 : 0000000000000000
x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000
x5 : ffff80009d497980 x4 : ffff80009d497960 x3 : 0000000000001000
x2 : 0000000000000000 x1 : ffff0000e183a928 x0 : ffff0000d60b0fc0
Call trace:
0x0 (P)
__generic_file_write_iter+0xfc/0x204 mm/filemap.c:4156
ntfs_file_write_iter+0x54c/0x630 fs/ntfs3/file.c:1267
new_sync_write fs/read_write.c:586 [inline]
vfs_write+0x920/0xcf4 fs/read_write.c:679
ksys_write+0x15c/0x26c fs/read_write.c:731
__do_sys_write fs/read_write.c:742 [inline]
__se_sys_write fs/read_write.c:739 [inline]
__arm64_sys_write+0x7c/0x90 fs/read_write.c:739
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49
el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744
el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762
[2]
ioctl$FS_IOC_SETFLAGS(r0, 0x40086602, &(0x7f00000000c0)=0x20)
Reported-by: syzbot+5d0bdc98770e6c55a0fd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5d0bdc98770e6c55a0fd
Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/file.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 3f96a11804c90..d3a31bad21f9d 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -1228,21 +1228,22 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
ssize_t ret;
int err;
- err = check_write_restriction(inode);
- if (err)
- return err;
-
- if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
- ntfs_inode_warn(inode, "direct i/o + compressed not supported");
- return -EOPNOTSUPP;
- }
-
if (!inode_trylock(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
inode_lock(inode);
}
+ ret = check_write_restriction(inode);
+ if (ret)
+ goto out;
+
+ if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) {
+ ntfs_inode_warn(inode, "direct i/o + compressed not supported");
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
ret = generic_write_checks(iocb, from);
if (ret <= 0)
goto out;
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 07/31] fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (4 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 06/31] fs/ntfs3: Keep write operations atomic Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY Sasha Levin
` (23 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Edward Adam Davis, syzbot+e37dd1dfc814b10caa55,
Konstantin Komarov, Sasha Levin, ntfs3
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit ff355926445897cc9fdea3b00611e514232c213c ]
Syzbot reported a WARNING in ntfs_extend_initialized_size.
The data type of in->i_valid and to is u64 in ntfs_file_mmap().
If their values are greater than LLONG_MAX, overflow will occur because
the data types of the parameters valid and new_valid corresponding to
the function ntfs_extend_initialized_size() are loff_t.
Before calling ntfs_extend_initialized_size() in the ntfs_file_mmap(),
the "ni->i_valid < to" has been determined, so the same WARN_ON determination
is not required in ntfs_extend_initialized_size().
Just execute the ntfs_extend_initialized_size() in ntfs_extend() to make
a WARN_ON check.
Reported-and-tested-by: syzbot+e37dd1dfc814b10caa55@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e37dd1dfc814b10caa55
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/file.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index d3a31bad21f9d..4d9d84cc3c6f5 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -412,6 +412,7 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count,
}
if (extend_init && !is_compressed(ni)) {
+ WARN_ON(ni->i_valid >= pos);
err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos);
if (err)
goto out;
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (5 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 07/31] fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-10 7:05 ` Johan Hovold
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 09/31] usb: dwc3: gadget: Refactor loop to avoid NULL endpoints Sasha Levin
` (22 subsequent siblings)
29 siblings, 1 reply; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Konrad Dybcio, Dmitry Baryshkov, Jens Glathe, Vinod Koul,
Sasha Levin, kishon, lumag, abel.vesa, neil.armstrong,
quic_qianyu, quic_ziyuzhan, quic_devipriy, quic_krichai,
manivannan.sadhasivam, johan+linaro, linux-arm-msm, linux-phy
From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
[ Upstream commit 0d8db251dd15d2e284f5a6a53bc2b869f3eca711 ]
Add a new, common configuration for Gen4x4 V6 PHYs without an init
sequence.
The bootloader configures the hardware once and the OS retains that
configuration by using the NOCSR reset line (which doesn't drop
register state on assert) in place of the "full reset" one.
Use this new configuration for X1P42100's Gen4x4 PHY.
Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250203-topic-x1p4_dts-v2-3-72cd4cdc767b@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 018bbb3008303..6726bbe4ad15d 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -4156,6 +4156,21 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x8_pciephy_cfg = {
.has_nocsr_reset = true,
};
+static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = {
+ .lanes = 4,
+
+ .offsets = &qmp_pcie_offsets_v6_20,
+
+ .reset_list = sdm845_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
+ .vreg_list = qmp_phy_vreg_l,
+ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
+ .regs = pciephy_v6_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS_4_20,
+};
+
static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls)
{
const struct qmp_phy_cfg *cfg = qmp->cfg;
@@ -4960,6 +4975,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,x1e80100-qmp-gen4x8-pcie-phy",
.data = &x1e80100_qmp_gen4x8_pciephy_cfg,
+ }, {
+ .compatible = "qcom,x1p42100-qmp-gen4x4-pcie-phy",
+ .data = &qmp_v6_gen4x4_pciephy_cfg,
},
{ },
};
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY Sasha Levin
@ 2025-04-10 7:05 ` Johan Hovold
2025-04-28 0:00 ` Sasha Levin
0 siblings, 1 reply; 35+ messages in thread
From: Johan Hovold @ 2025-04-10 7:05 UTC (permalink / raw)
To: Sasha Levin
Cc: linux-kernel, stable, Konrad Dybcio, Dmitry Baryshkov,
Jens Glathe, Vinod Koul, kishon, lumag, abel.vesa, neil.armstrong,
quic_qianyu, quic_ziyuzhan, quic_devipriy, quic_krichai,
manivannan.sadhasivam, johan+linaro, linux-arm-msm, linux-phy
On Mon, Apr 07, 2025 at 02:10:24PM -0400, Sasha Levin wrote:
> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> [ Upstream commit 0d8db251dd15d2e284f5a6a53bc2b869f3eca711 ]
>
> Add a new, common configuration for Gen4x4 V6 PHYs without an init
> sequence.
>
> The bootloader configures the hardware once and the OS retains that
> configuration by using the NOCSR reset line (which doesn't drop
> register state on assert) in place of the "full reset" one.
>
> Use this new configuration for X1P42100's Gen4x4 PHY.
>
> Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Link: https://lore.kernel.org/r/20250203-topic-x1p4_dts-v2-3-72cd4cdc767b@oss.qualcomm.com
> Signed-off-by: Vinod Koul <vkoul@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Support for this SoC is not even in mainline yet so there is really no
need to backport this one.
Please drop from all stable queues.
Johan
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY
2025-04-10 7:05 ` Johan Hovold
@ 2025-04-28 0:00 ` Sasha Levin
0 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-28 0:00 UTC (permalink / raw)
To: Johan Hovold
Cc: linux-kernel, stable, Konrad Dybcio, Dmitry Baryshkov,
Jens Glathe, Vinod Koul, kishon, lumag, abel.vesa, neil.armstrong,
quic_qianyu, quic_ziyuzhan, quic_devipriy, quic_krichai,
manivannan.sadhasivam, johan+linaro, linux-arm-msm, linux-phy
On Thu, Apr 10, 2025 at 09:05:52AM +0200, Johan Hovold wrote:
>On Mon, Apr 07, 2025 at 02:10:24PM -0400, Sasha Levin wrote:
>> From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> [ Upstream commit 0d8db251dd15d2e284f5a6a53bc2b869f3eca711 ]
>>
>> Add a new, common configuration for Gen4x4 V6 PHYs without an init
>> sequence.
>>
>> The bootloader configures the hardware once and the OS retains that
>> configuration by using the NOCSR reset line (which doesn't drop
>> register state on assert) in place of the "full reset" one.
>>
>> Use this new configuration for X1P42100's Gen4x4 PHY.
>>
>> Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
>> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>> Link: https://lore.kernel.org/r/20250203-topic-x1p4_dts-v2-3-72cd4cdc767b@oss.qualcomm.com
>> Signed-off-by: Vinod Koul <vkoul@kernel.org>
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>
>Support for this SoC is not even in mainline yet so there is really no
>need to backport this one.
>
>Please drop from all stable queues.
Will do, thanks!
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH AUTOSEL 6.14 09/31] usb: dwc3: gadget: Refactor loop to avoid NULL endpoints
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (6 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 08/31] phy: qcom: qmp-pcie: Add X1P42100 Gen4x4 PHY Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 10/31] usb: dwc3: gadget: Avoid using reserved endpoints on Intel Merrifield Sasha Levin
` (21 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andy Shevchenko, Ferry Toth, Thinh Nguyen, Greg Kroah-Hartman,
Sasha Levin, linux-usb
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit eafba0205426091354f050381c32ad1567c35844 ]
Prepare the gadget driver to handle the reserved endpoints that will be
not allocated at the initialisation time.
While at it, add a warning where the NULL endpoint should never happen.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Ferry Toth <fntoth@gmail.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20250212193116.2487289-3-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/dwc3/gadget.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 89a4dc8ebf948..1c3d153ea73f7 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -547,6 +547,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
{
struct dwc3_gadget_ep_cmd_params params;
+ struct dwc3_ep *dep;
u32 cmd;
int i;
int ret;
@@ -563,8 +564,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index)
return ret;
/* Reset resource allocation flags */
- for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++)
- dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
+ for (i = resource_index; i < dwc->num_eps; i++) {
+ dep = dwc->eps[i];
+ if (!dep)
+ continue;
+
+ dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED;
+ }
return 0;
}
@@ -751,9 +757,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
dwc->last_fifo_depth = fifo_depth;
/* Clear existing TXFIFO for all IN eps except ep0 */
- for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM);
- num += 2) {
+ for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) {
dep = dwc->eps[num];
+ if (!dep)
+ continue;
+
/* Don't change TXFRAMNUM on usb31 version */
size = DWC3_IP_IS(DWC3) ? 0 :
dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) &
@@ -3703,6 +3711,8 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
dep = dwc->eps[i];
+ if (!dep)
+ continue;
if (!(dep->flags & DWC3_EP_ENABLED))
continue;
@@ -3852,6 +3862,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
u8 epnum = event->endpoint_number;
dep = dwc->eps[epnum];
+ if (!dep) {
+ dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum);
+ return;
+ }
if (!(dep->flags & DWC3_EP_ENABLED)) {
if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 10/31] usb: dwc3: gadget: Avoid using reserved endpoints on Intel Merrifield
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (7 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 09/31] usb: dwc3: gadget: Refactor loop to avoid NULL endpoints Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 11/31] sound/virtio: Fix cancel_sync warnings on uninitialized work_structs Sasha Levin
` (20 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andy Shevchenko, Ferry Toth, Thinh Nguyen, Greg Kroah-Hartman,
Sasha Levin, linux-usb
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 461f24bff86808ee5fbfe74751a825f8a7ab24e0 ]
Intel Merrifield SoC uses these endpoints for tracing and they cannot
be re-allocated if being used because the side band flow control signals
are hard wired to certain endpoints:
• 1 High BW Bulk IN (IN#1) (RTIT)
• 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
In device mode, since RTIT (EP#1) and EXI/RunControl (EP#8) uses
External Buffer Control (EBC) mode, these endpoints are to be mapped to
EBC mode (to be done by EXI target driver). Additionally TRB for RTIT
and EXI are maintained in STM (System Trace Module) unit and the EXI
target driver will as well configure the TRB location for EP #1 IN
and EP#8 (IN and OUT). Since STM/PTI and EXI hardware blocks manage
these endpoints and interface to OTG3 controller through EBC interface,
there is no need to enable any events (such as XferComplete etc)
for these end points.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Ferry Toth <fntoth@gmail.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/20250212193116.2487289-5-andriy.shevchenko@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/dwc3/dwc3-pci.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 052852f801467..54a4ee2b90b7f 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -148,11 +148,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = {
{}
};
+/*
+ * Intel Merrifield SoC uses these endpoints for tracing and they cannot
+ * be re-allocated if being used because the side band flow control signals
+ * are hard wired to certain endpoints:
+ * - 1 High BW Bulk IN (IN#1) (RTIT)
+ * - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
+ */
+static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 };
+
static const struct property_entry dwc3_pci_mrfld_properties[] = {
PROPERTY_ENTRY_STRING("dr_mode", "otg"),
PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints),
PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
{}
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 11/31] sound/virtio: Fix cancel_sync warnings on uninitialized work_structs
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (8 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 10/31] usb: dwc3: gadget: Avoid using reserved endpoints on Intel Merrifield Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 12/31] dmaengine: bcm2835-dma: fix warning when CONFIG_PM=n Sasha Levin
` (19 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: John Stultz, Anton Yakovlev, Michael S. Tsirkin, Jaroslav Kysela,
Takashi Iwai, virtualization, linux-sound, kernel-team,
Betty Zhou, Takashi Iwai, Sasha Levin
From: John Stultz <jstultz@google.com>
[ Upstream commit 3c7df2e27346eb40a0e86230db1ccab195c97cfe ]
Betty reported hitting the following warning:
[ 8.709131][ T221] WARNING: CPU: 2 PID: 221 at kernel/workqueue.c:4182
...
[ 8.713282][ T221] Call trace:
[ 8.713365][ T221] __flush_work+0x8d0/0x914
[ 8.713468][ T221] __cancel_work_sync+0xac/0xfc
[ 8.713570][ T221] cancel_work_sync+0x24/0x34
[ 8.713667][ T221] virtsnd_remove+0xa8/0xf8 [virtio_snd ab15f34d0dd772f6d11327e08a81d46dc9c36276]
[ 8.713868][ T221] virtsnd_probe+0x48c/0x664 [virtio_snd ab15f34d0dd772f6d11327e08a81d46dc9c36276]
[ 8.714035][ T221] virtio_dev_probe+0x28c/0x390
[ 8.714139][ T221] really_probe+0x1bc/0x4c8
...
It seems we're hitting the error path in virtsnd_probe(), which
triggers a virtsnd_remove() which iterates over the substreams
calling cancel_work_sync() on the elapsed_period work_struct.
Looking at the code, from earlier in:
virtsnd_probe()->virtsnd_build_devs()->virtsnd_pcm_parse_cfg()
We set snd->nsubstreams, allocate the snd->substreams, and if
we then hit an error on the info allocation or something in
virtsnd_ctl_query_info() fails, we will exit without having
initialized the elapsed_period work_struct.
When that error path unwinds we then call virtsnd_remove()
which as long as the substreams array is allocated, will iterate
through calling cancel_work_sync() on the uninitialized work
struct hitting this warning.
Takashi Iwai suggested this fix, which initializes the substreams
structure right after allocation, so that if we hit the error
paths we avoid trying to cleanup uninitialized data.
Note: I have not yet managed to reproduce the issue myself, so
this patch has had limited testing.
Feedback or thoughts would be appreciated!
Cc: Anton Yakovlev <anton.yakovlev@opensynergy.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: virtualization@lists.linux.dev
Cc: linux-sound@vger.kernel.org
Cc: kernel-team@android.com
Reported-by: Betty Zhou <bettyzhou@google.com>
Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: John Stultz <jstultz@google.com>
Message-Id: <20250116194114.3375616-1-jstultz@google.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/virtio/virtio_pcm.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c
index 967e4c45be9bb..2f7c5e709f075 100644
--- a/sound/virtio/virtio_pcm.c
+++ b/sound/virtio/virtio_pcm.c
@@ -339,6 +339,21 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
if (!snd->substreams)
return -ENOMEM;
+ /*
+ * Initialize critical substream fields early in case we hit an
+ * error path and end up trying to clean up uninitialized structures
+ * elsewhere.
+ */
+ for (i = 0; i < snd->nsubstreams; ++i) {
+ struct virtio_pcm_substream *vss = &snd->substreams[i];
+
+ vss->snd = snd;
+ vss->sid = i;
+ INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
+ init_waitqueue_head(&vss->msg_empty);
+ spin_lock_init(&vss->lock);
+ }
+
info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
@@ -352,12 +367,6 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd)
struct virtio_pcm_substream *vss = &snd->substreams[i];
struct virtio_pcm *vpcm;
- vss->snd = snd;
- vss->sid = i;
- INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed);
- init_waitqueue_head(&vss->msg_empty);
- spin_lock_init(&vss->lock);
-
rc = virtsnd_pcm_build_hw(vss, &info[i]);
if (rc)
goto on_exit;
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 12/31] dmaengine: bcm2835-dma: fix warning when CONFIG_PM=n
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (9 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 11/31] sound/virtio: Fix cancel_sync warnings on uninitialized work_structs Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 13/31] usb: xhci: Complete 'error mid TD' transfers when handling Missed Service Sasha Levin
` (18 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Stefan Wahren, kernel test robot, Florian Fainelli, Vinod Koul,
Sasha Levin, rjui, sbranden, dmaengine, linux-rpi-kernel,
linux-arm-kernel
From: Stefan Wahren <wahrenst@gmx.net>
[ Upstream commit 95032938c7c9b2e5ebb69f0ee10ebe340fa3af53 ]
The old SET_LATE_SYSTEM_SLEEP_PM_OPS macro cause a build warning
when CONFIG_PM is disabled:
warning: 'bcm2835_dma_suspend_late' defined but not used [-Wunused-function]
Change this to the modern replacement.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202501071533.yrFb156H-lkp@intel.com/
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://lore.kernel.org/r/20250222095028.48818-1-wahrenst@gmx.net
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/bcm2835-dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index 20b10c15c6967..0117bb2e8591b 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -893,7 +893,7 @@ static int bcm2835_dma_suspend_late(struct device *dev)
}
static const struct dev_pm_ops bcm2835_dma_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
+ LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL)
};
static int bcm2835_dma_probe(struct platform_device *pdev)
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 13/31] usb: xhci: Complete 'error mid TD' transfers when handling Missed Service
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (10 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 12/31] dmaengine: bcm2835-dma: fix warning when CONFIG_PM=n Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 14/31] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling Sasha Levin
` (17 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Michal Pecio, Mathias Nyman, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb
From: Michal Pecio <michal.pecio@gmail.com>
[ Upstream commit bfa8459942822bdcc86f0e87f237c0723ae64948 ]
Missed Service Error after an error mid TD means that the failed TD has
already been passed by the xHC without acknowledgment of the final TRB,
a known hardware bug. So don't wait any more and give back the TD.
Reproduced on NEC uPD720200 under conditions of ludicrously bad USB link
quality, confirmed to behave as expected using dynamic debug.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250306144954.3507700-5-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci-ring.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 965bffce301e2..af6c4c4cbe1cc 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2789,7 +2789,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_dbg(xhci,
"Miss service interval error for slot %u ep %u, set skip flag\n",
slot_id, ep_index);
- return 0;
+ break;
case COMP_NO_PING_RESPONSE_ERROR:
ep->skip = true;
xhci_dbg(xhci,
@@ -2837,6 +2837,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_dequeue_td(xhci, td, ep_ring, td->status);
}
+ /* Missed TDs will be skipped on the next event */
+ if (trb_comp_code == COMP_MISSED_SERVICE_ERROR)
+ return 0;
+
if (list_empty(&ep_ring->td_list)) {
/*
* Don't print wanings if ring is empty due to a stopped endpoint generating an
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 14/31] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (11 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 13/31] usb: xhci: Complete 'error mid TD' transfers when handling Missed Service Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 15/31] xhci: Handle spurious events on Etron host isoc enpoints Sasha Levin
` (16 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Michal Pecio, Mathias Nyman, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb
From: Michal Pecio <michal.pecio@gmail.com>
[ Upstream commit 906dec15b9b321b546fd31a3c99ffc13724c7af4 ]
The TRB pointer of these events points at enqueue at the time of error
occurrence on xHCI 1.1+ HCs or it's NULL on older ones. By the time we
are handling the event, a new TD may be queued at this ring position.
I can trigger this race by rising interrupt moderation to increase IRQ
handling delay. Similar delay may occur naturally due to system load.
If this ever happens after a Missed Service Error, missed TDs will be
skipped and the new TD processed as if it matched the event. It could
be given back prematurely, risking data loss or buffer UAF by the xHC.
Don't complete TDs on xrun events and don't warn if queued TDs don't
match the event's TRB pointer, which can be NULL or a link/no-op TRB.
Don't warn if there are no queued TDs at all.
Now that it's safe, also handle xrun events if the skip flag is clear.
This ensures completion of any TD stuck in 'error mid TD' state right
before the xrun event, which could happen if a driver submits a finite
number of URBs to a buggy HC and then an error occurs on the last TD.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250306144954.3507700-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci-ring.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index af6c4c4cbe1cc..26d95d3c80b0a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2664,6 +2664,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
int status = -EINPROGRESS;
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
+ bool ring_xrun_event = false;
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -2770,14 +2771,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
* Underrun Event for OUT Isoch endpoint.
*/
xhci_dbg(xhci, "Underrun event on slot %u ep %u\n", slot_id, ep_index);
- if (ep->skip)
- break;
- return 0;
+ ring_xrun_event = true;
+ break;
case COMP_RING_OVERRUN:
xhci_dbg(xhci, "Overrun event on slot %u ep %u\n", slot_id, ep_index);
- if (ep->skip)
- break;
- return 0;
+ ring_xrun_event = true;
+ break;
case COMP_MISSED_SERVICE_ERROR:
/*
* When encounter missed service error, one or more isoc tds
@@ -2850,6 +2849,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
if (trb_comp_code != COMP_STOPPED &&
trb_comp_code != COMP_STOPPED_LENGTH_INVALID &&
+ !ring_xrun_event &&
!ep_ring->last_td_was_short) {
xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n",
slot_id, ep_index);
@@ -2880,6 +2880,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
goto check_endpoint_halted;
}
+ /* TD was queued after xrun, maybe xrun was on a link, don't panic yet */
+ if (ring_xrun_event)
+ return 0;
+
/*
* Skip the Force Stopped Event. The 'ep_trb' of FSE is not in the current
* TD pointed by 'ep_ring->dequeue' because that the hardware dequeue
@@ -2926,6 +2930,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
} while (ep->skip);
+ /* Get out if a TD was queued at enqueue after the xrun occurred */
+ if (ring_xrun_event)
+ return 0;
+
if (trb_comp_code == COMP_SHORT_PACKET)
ep_ring->last_td_was_short = true;
else
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 15/31] xhci: Handle spurious events on Etron host isoc enpoints
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (12 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 14/31] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 16/31] i3c: master: svc: Add support for Nuvoton npcm845 i3c Sasha Levin
` (15 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Mathias Nyman, Kuangyi Chiang, Michal Pecio, Greg Kroah-Hartman,
Sasha Levin, mathias.nyman, linux-usb
From: Mathias Nyman <mathias.nyman@linux.intel.com>
[ Upstream commit b331a3d8097fad4e541d212684192f21fedbd6e5 ]
Unplugging a USB3.0 webcam from Etron hosts while streaming results
in errors like this:
[ 2.646387] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13
[ 2.646446] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8630 trb-start 000000002fdf8640 trb-end 000000002fdf8650
[ 2.646560] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13
[ 2.646568] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8660 trb-start 000000002fdf8670 trb-end 000000002fdf8670
Etron xHC generates two transfer events for the TRB if an error is
detected while processing the last TRB of an isoc TD.
The first event can be any sort of error (like USB Transaction or
Babble Detected, etc), and the final event is Success.
The xHCI driver will handle the TD after the first event and remove it
from its internal list, and then print an "Transfer event TRB DMA ptr
not part of current TD" error message after the final event.
Commit 5372c65e1311 ("xhci: process isoc TD properly when there was a
transaction error mid TD.") is designed to address isoc transaction
errors, but unfortunately it doesn't account for this scenario.
This issue is similar to the XHCI_SPURIOUS_SUCCESS case where a success
event follows a 'short transfer' event, but the TD the event points to
is already given back.
Expand the spurious success 'short transfer' event handling to cover
the spurious success after error on Etron hosts.
Kuangyi Chiang reported this issue and submitted a different solution
based on using error_mid_td. This commit message is mostly taken
from that patch.
Reported-by: Kuangyi Chiang <ki.chiang65@gmail.com>
Closes: https://lore.kernel.org/linux-usb/20241028025337.6372-6-ki.chiang65@gmail.com/
Tested-by: Kuangyi Chiang <ki.chiang65@gmail.com>
Tested-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250306144954.3507700-16-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci-ring.c | 38 ++++++++++++++++++++++++------------
drivers/usb/host/xhci.h | 2 +-
2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 26d95d3c80b0a..d3dd1ecaf6208 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2644,6 +2644,22 @@ static int handle_transferless_tx_event(struct xhci_hcd *xhci, struct xhci_virt_
return 0;
}
+static bool xhci_spurious_success_tx_event(struct xhci_hcd *xhci,
+ struct xhci_ring *ring)
+{
+ switch (ring->old_trb_comp_code) {
+ case COMP_SHORT_PACKET:
+ return xhci->quirks & XHCI_SPURIOUS_SUCCESS;
+ case COMP_USB_TRANSACTION_ERROR:
+ case COMP_BABBLE_DETECTED_ERROR:
+ case COMP_ISOCH_BUFFER_OVERRUN:
+ return xhci->quirks & XHCI_ETRON_HOST &&
+ ring->type == TYPE_ISOC;
+ default:
+ return false;
+ }
+}
+
/*
* If this function returns an error condition, it means it got a Transfer
* event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
@@ -2698,8 +2714,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
case COMP_SUCCESS:
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
trb_comp_code = COMP_SHORT_PACKET;
- xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n",
- slot_id, ep_index, ep_ring->last_td_was_short);
+ xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td comp code %d\n",
+ slot_id, ep_index, ep_ring->old_trb_comp_code);
}
break;
case COMP_SHORT_PACKET:
@@ -2850,7 +2866,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (trb_comp_code != COMP_STOPPED &&
trb_comp_code != COMP_STOPPED_LENGTH_INVALID &&
!ring_xrun_event &&
- !ep_ring->last_td_was_short) {
+ !xhci_spurious_success_tx_event(xhci, ep_ring)) {
xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n",
slot_id, ep_index);
}
@@ -2898,11 +2914,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/*
* Some hosts give a spurious success event after a short
- * transfer. Ignore it.
+ * transfer or error on last TRB. Ignore it.
*/
- if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&
- ep_ring->last_td_was_short) {
- ep_ring->last_td_was_short = false;
+ if (xhci_spurious_success_tx_event(xhci, ep_ring)) {
+ xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n",
+ &ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code);
+ ep_ring->old_trb_comp_code = trb_comp_code;
return 0;
}
@@ -2930,15 +2947,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
*/
} while (ep->skip);
+ ep_ring->old_trb_comp_code = trb_comp_code;
+
/* Get out if a TD was queued at enqueue after the xrun occurred */
if (ring_xrun_event)
return 0;
- if (trb_comp_code == COMP_SHORT_PACKET)
- ep_ring->last_td_was_short = true;
- else
- ep_ring->last_td_was_short = false;
-
ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)];
trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb, ep_trb_dma);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 779b01dee068f..b7109e5ec93db 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1371,7 +1371,7 @@ struct xhci_ring {
unsigned int num_trbs_free; /* used only by xhci DbC */
unsigned int bounce_buf_len;
enum xhci_ring_type type;
- bool last_td_was_short;
+ u32 old_trb_comp_code;
struct radix_tree_root *trb_address_map;
};
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 16/31] i3c: master: svc: Add support for Nuvoton npcm845 i3c
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (13 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 15/31] xhci: Handle spurious events on Etron host isoc enpoints Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 17/31] dmaengine: dmatest: Fix dmatest waiting less when interrupted Sasha Levin
` (14 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Stanley Chu, Frank Li, Alexandre Belloni, Sasha Levin,
miquel.raynal, linux-i3c, imx
From: Stanley Chu <yschu@nuvoton.com>
[ Upstream commit 98d87600a04e42282797631aa6b98dd43999e274 ]
Nuvoton npcm845 SoC uses an older IP version, which has specific
hardware issues that need to be addressed with a different compatible
string.
Add driver data for different compatible strings to define platform
specific quirks.
Add compatible string for npcm845 to define its own driver data.
Signed-off-by: Stanley Chu <yschu@nuvoton.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20250306075429.2265183-3-yschu@nuvoton.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i3c/master/svc-i3c-master.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c
index d6057d8c7dec4..40269b692aa87 100644
--- a/drivers/i3c/master/svc-i3c-master.c
+++ b/drivers/i3c/master/svc-i3c-master.c
@@ -158,6 +158,10 @@ struct svc_i3c_regs_save {
u32 mdynaddr;
};
+struct svc_i3c_drvdata {
+ u32 quirks;
+};
+
/**
* struct svc_i3c_master - Silvaco I3C Master structure
* @base: I3C master controller
@@ -183,6 +187,7 @@ struct svc_i3c_regs_save {
* @ibi.tbq_slot: To be queued IBI slot
* @ibi.lock: IBI lock
* @lock: Transfer lock, protect between IBI work thread and callbacks from master
+ * @drvdata: Driver data
* @enabled_events: Bit masks for enable events (IBI, HotJoin).
* @mctrl_config: Configuration value in SVC_I3C_MCTRL for setting speed back.
*/
@@ -214,6 +219,7 @@ struct svc_i3c_master {
spinlock_t lock;
} ibi;
struct mutex lock;
+ const struct svc_i3c_drvdata *drvdata;
u32 enabled_events;
u32 mctrl_config;
};
@@ -1817,6 +1823,10 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
if (!master)
return -ENOMEM;
+ master->drvdata = of_device_get_match_data(dev);
+ if (!master->drvdata)
+ return -EINVAL;
+
master->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(master->regs))
return PTR_ERR(master->regs);
@@ -1958,8 +1968,13 @@ static const struct dev_pm_ops svc_i3c_pm_ops = {
svc_i3c_runtime_resume, NULL)
};
+static const struct svc_i3c_drvdata npcm845_drvdata = {};
+
+static const struct svc_i3c_drvdata svc_default_drvdata = {};
+
static const struct of_device_id svc_i3c_master_of_match_tbl[] = {
- { .compatible = "silvaco,i3c-master-v1"},
+ { .compatible = "nuvoton,npcm845-i3c", .data = &npcm845_drvdata },
+ { .compatible = "silvaco,i3c-master-v1", .data = &svc_default_drvdata },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 17/31] dmaengine: dmatest: Fix dmatest waiting less when interrupted
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (14 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 16/31] i3c: master: svc: Add support for Nuvoton npcm845 i3c Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 18/31] usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running Sasha Levin
` (13 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Vinicius Costa Gomes, kernel test robot, Dave Jiang, Vinod Koul,
Sasha Levin, dmaengine
From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
[ Upstream commit e87ca16e99118ab4e130a41bdf12abbf6a87656c ]
Change the "wait for operation finish" logic to take interrupts into
account.
When using dmatest with idxd DMA engine, it's possible that during
longer tests, the interrupt notifying the finish of an operation
happens during wait_event_freezable_timeout(), which causes dmatest to
cleanup all the resources, some of which might still be in use.
This fix ensures that the wait logic correctly handles interrupts,
preventing premature cleanup of resources.
Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202502171134.8c403348-lkp@intel.com
Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20250305230007.590178-1-vinicius.gomes@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/dmatest.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 91b2fbc0b8647..d891dfca358e2 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -841,9 +841,9 @@ static int dmatest_func(void *data)
} else {
dma_async_issue_pending(chan);
- wait_event_freezable_timeout(thread->done_wait,
- done->done,
- msecs_to_jiffies(params->timeout));
+ wait_event_timeout(thread->done_wait,
+ done->done,
+ msecs_to_jiffies(params->timeout));
status = dma_async_is_tx_complete(chan, cookie, NULL,
NULL);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 18/31] usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (15 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 17/31] dmaengine: dmatest: Fix dmatest waiting less when interrupted Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 19/31] phy: rockchip: usbdp: Avoid call hpd_event_trigger in dp_phy_init Sasha Levin
` (12 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Michal Pecio, Mathias Nyman, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb
From: Michal Pecio <michal.pecio@gmail.com>
[ Upstream commit 28a76fcc4c85dd39633fb96edb643c91820133e3 ]
Nothing prevents a broken HC from claiming that an endpoint is Running
and repeatedly rejecting Stop Endpoint with Context State Error.
Avoid infinite retries and give back cancelled TDs.
No such cases known so far, but HCs have bugs.
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20250311154551.4035726-4-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci-ring.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d3dd1ecaf6208..076c4c397ca4a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1198,16 +1198,19 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,
* Stopped state, but it will soon change to Running.
*
* Assume this bug on unexpected Stop Endpoint failures.
- * Keep retrying until the EP starts and stops again, on
- * chips where this is known to help. Wait for 100ms.
+ * Keep retrying until the EP starts and stops again.
*/
- if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
- break;
fallthrough;
case EP_STATE_RUNNING:
/* Race, HW handled stop ep cmd before ep was running */
xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n",
GET_EP_CTX_STATE(ep_ctx));
+ /*
+ * Don't retry forever if we guessed wrong or a defective HC never starts
+ * the EP or says 'Running' but fails the command. We must give back TDs.
+ */
+ if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100)))
+ break;
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
if (!command) {
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 19/31] phy: rockchip: usbdp: Avoid call hpd_event_trigger in dp_phy_init
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (16 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 18/31] usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 20/31] usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev() Sasha Levin
` (11 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Andy Yan, Vinod Koul, Sasha Levin, kishon, heiko, linux-phy,
linux-arm-kernel, linux-rockchip
From: Andy Yan <andy.yan@rock-chips.com>
[ Upstream commit 28dc672a1a877c77b000c896abd8f15afcdc1b0c ]
Function rk_udphy_dp_hpd_event_trigger will set vogrf let it
trigger HPD interrupt to DP by Type-C. This configuration is only
required when the DP work in Alternate Mode, and called by
typec_mux_set. In standard DP mode, such settings will prevent
the DP from receiving HPD interrupts.
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Link: https://lore.kernel.org/r/20250302115257.188774-1-andyshrk@163.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c
index 5b1e8a3806ed4..c04cf64f8a35d 100644
--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
+++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
@@ -1045,7 +1045,6 @@ static int rk_udphy_dp_phy_init(struct phy *phy)
mutex_lock(&udphy->mutex);
udphy->dp_in_use = true;
- rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
mutex_unlock(&udphy->mutex);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 20/31] usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev()
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (17 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 19/31] phy: rockchip: usbdp: Avoid call hpd_event_trigger in dp_phy_init Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 21/31] usb: host: xhci-plat: mvebu: use ->quirks instead of ->init_quirk() func Sasha Levin
` (10 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Chenyuan Yang, Greg Kroah-Hartman, Sasha Levin, joel, andrew,
richardcochran, linux-usb, linux-arm-kernel, linux-aspeed, netdev
From: Chenyuan Yang <chenyuan0y@gmail.com>
[ Upstream commit 8c75f3e6a433d92084ad4e78b029ae680865420f ]
The variable d->name, returned by devm_kasprintf(), could be NULL.
A pointer check is added to prevent potential NULL pointer dereference.
This is similar to the fix in commit 3027e7b15b02
("ice: Fix some null pointer dereference issues in ice_ptp.c").
This issue is found by our static analysis tool
Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
Link: https://lore.kernel.org/r/20250311012705.1233829-1-chenyuan0y@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/udc/aspeed-vhub/dev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
index 573109ca5b799..a09f72772e6e9 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
@@ -548,6 +548,9 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
d->vhub = vhub;
d->index = idx;
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
+ if (!d->name)
+ return -ENOMEM;
+
d->regs = vhub->regs + 0x100 + 0x10 * idx;
ast_vhub_init_ep0(vhub, &d->ep0, d);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 21/31] usb: host: xhci-plat: mvebu: use ->quirks instead of ->init_quirk() func
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (18 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 20/31] usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev() Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 22/31] thunderbolt: Scan retimers after device router has been enumerated Sasha Levin
` (9 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Théo Lebrun, Greg Kroah-Hartman, Sasha Levin, mathias.nyman,
linux-usb
From: Théo Lebrun <theo.lebrun@bootlin.com>
[ Upstream commit 64eb182d5f7a5ec30227bce4f6922ff663432f44 ]
Compatible "marvell,armada3700-xhci" match data uses the
struct xhci_plat_priv::init_quirk() function pointer to add
XHCI_RESET_ON_RESUME as quirk on XHCI.
Instead, use the struct xhci_plat_priv::quirks field.
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://lore.kernel.org/r/20250205-s2r-cdns-v7-1-13658a271c3c@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/xhci-mvebu.c | 10 ----------
drivers/usb/host/xhci-mvebu.h | 6 ------
drivers/usb/host/xhci-plat.c | 2 +-
3 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c
index 87f1597a0e5ab..257e4d79971fd 100644
--- a/drivers/usb/host/xhci-mvebu.c
+++ b/drivers/usb/host/xhci-mvebu.c
@@ -73,13 +73,3 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
return 0;
}
-
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
-{
- struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-
- /* Without reset on resume, the HC won't work at all */
- xhci->quirks |= XHCI_RESET_ON_RESUME;
-
- return 0;
-}
diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h
index 3be021793cc8b..9d26e22c48422 100644
--- a/drivers/usb/host/xhci-mvebu.h
+++ b/drivers/usb/host/xhci-mvebu.h
@@ -12,16 +12,10 @@ struct usb_hcd;
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU)
int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd);
-int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd);
#else
static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
{
return 0;
}
-
-static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd)
-{
- return 0;
-}
#endif
#endif /* __LINUX_XHCI_MVEBU_H */
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index d85ffa9ffaa70..ff813dca2d1d3 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -106,7 +106,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = {
};
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = {
- .init_quirk = xhci_mvebu_a3700_init_quirk,
+ .quirks = XHCI_RESET_ON_RESUME,
};
static const struct xhci_plat_priv xhci_plat_brcm = {
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 22/31] thunderbolt: Scan retimers after device router has been enumerated
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (19 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 21/31] usb: host: xhci-plat: mvebu: use ->quirks instead of ->init_quirk() func Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 23/31] um: work around sched_yield not yielding in time-travel mode Sasha Levin
` (8 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Mika Westerberg, Thomas Lynema, Mario Limonciello, Sasha Levin,
andreas.noever, michael.jamet, westeri, YehezkelShB, linux-usb
From: Mika Westerberg <mika.westerberg@linux.intel.com>
[ Upstream commit 75749d2c1d8cef439f8b69fa1f4f36d0fc3193e6 ]
Thomas reported connection issues on AMD system with Pluggable UD-4VPD
dock. After some experiments it looks like the device has some sort of
internal timeout that triggers reconnect. This is completely against the
USB4 spec, as there is no requirement for the host to enumerate the
device right away or even at all.
In Linux case the delay is caused by scanning of retimers on the link so
we can work this around by doing the scanning after the device router
has been enumerated.
Reported-by: Thomas Lynema <lyz27@yahoo.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219748
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/thunderbolt/tb.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 390abcfe71882..8c527af989271 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -1305,11 +1305,15 @@ static void tb_scan_port(struct tb_port *port)
goto out_rpm_put;
}
- tb_retimer_scan(port, true);
-
sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
tb_downstream_route(port));
if (IS_ERR(sw)) {
+ /*
+ * Make the downstream retimers available even if there
+ * is no router connected.
+ */
+ tb_retimer_scan(port, true);
+
/*
* If there is an error accessing the connected switch
* it may be connected to another domain. Also we allow
@@ -1359,6 +1363,14 @@ static void tb_scan_port(struct tb_port *port)
upstream_port = tb_upstream_port(sw);
tb_configure_link(port, upstream_port, sw);
+ /*
+ * Scan for downstream retimers. We only scan them after the
+ * router has been enumerated to avoid issues with certain
+ * Pluggable devices that expect the host to enumerate them
+ * within certain timeout.
+ */
+ tb_retimer_scan(port, true);
+
/*
* CL0s and CL1 are enabled and supported together.
* Silently ignore CLx enabling in case CLx is not supported.
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 23/31] um: work around sched_yield not yielding in time-travel mode
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (20 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 22/31] thunderbolt: Scan retimers after device router has been enumerated Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 24/31] iommu/arm-smmu-v3: Set MEV bit in nested STE for DoS mitigations Sasha Levin
` (7 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Benjamin Berg, Johannes Berg, Sasha Levin, richard, anton.ivanov,
johannes, linux-um
From: Benjamin Berg <benjamin.berg@intel.com>
[ Upstream commit 887c5c12e80c8424bd471122d2e8b6b462e12874 ]
sched_yield by a userspace may not actually cause scheduling in
time-travel mode as no time has passed. In the case seen it appears to
be a badly implemented userspace spinlock in ASAN. Unfortunately, with
time-travel it causes an extreme slowdown or even deadlock depending on
the kernel configuration (CONFIG_UML_MAX_USERSPACE_ITERATIONS).
Work around it by accounting time to the process whenever it executes a
sched_yield syscall.
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20250314130815.226872-1-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/um/include/linux/time-internal.h | 2 ++
arch/um/kernel/skas/syscall.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h
index b22226634ff60..138908b999d76 100644
--- a/arch/um/include/linux/time-internal.h
+++ b/arch/um/include/linux/time-internal.h
@@ -83,6 +83,8 @@ extern void time_travel_not_configured(void);
#define time_travel_del_event(...) time_travel_not_configured()
#endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
+extern unsigned long tt_extra_sched_jiffies;
+
/*
* Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used,
* which is intentional since we really shouldn't link it in that case.
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index b09e85279d2b8..a5beaea2967ec 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -31,6 +31,17 @@ void handle_syscall(struct uml_pt_regs *r)
goto out;
syscall = UPT_SYSCALL_NR(r);
+
+ /*
+ * If no time passes, then sched_yield may not actually yield, causing
+ * broken spinlock implementations in userspace (ASAN) to hang for long
+ * periods of time.
+ */
+ if ((time_travel_mode == TT_MODE_INFCPU ||
+ time_travel_mode == TT_MODE_EXTERNAL) &&
+ syscall == __NR_sched_yield)
+ tt_extra_sched_jiffies += 1;
+
if (syscall >= 0 && syscall < __NR_syscalls) {
unsigned long ret = EXECUTE_SYSCALL(syscall, regs);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 24/31] iommu/arm-smmu-v3: Set MEV bit in nested STE for DoS mitigations
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (21 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 23/31] um: work around sched_yield not yielding in time-travel mode Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 25/31] um: Switch to the pthread-based helper in sigio workaround Sasha Levin
` (6 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Nicolin Chen, Jason Gunthorpe, Pranjal Shrivastava, Will Deacon,
Sasha Levin, joro, jgg, kevin.tian, nathan, peterz, yi.l.liu,
jsnitsel, mshavit, zhangzekun11, linux-arm-kernel, iommu
From: Nicolin Chen <nicolinc@nvidia.com>
[ Upstream commit da0c56520e880441d0503d0cf0d6853dcfb5f1a4 ]
There is a DoS concern on the shared hardware event queue among devices
passed through to VMs, that too many translation failures that belong to
VMs could overflow the shared hardware event queue if those VMs or their
VMMs don't handle/recover the devices properly.
The MEV bit in the STE allows to configure the SMMU HW to merge similar
event records, though there is no guarantee. Set it in a nested STE for
DoS mitigations.
In the future, we might want to enable the MEV for non-nested cases too
such as domain->type == IOMMU_DOMAIN_UNMANAGED or even IOMMU_DOMAIN_DMA.
Link: https://patch.msgid.link/r/8ed12feef67fc65273d0f5925f401a81f56acebe.1741719725.git.nicolinc@nvidia.com
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Pranjal Shrivastava <praan@google.com>
Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 2 ++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++--
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 +
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 5aa2e7af58b47..34a0be59cd919 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -43,6 +43,8 @@ static void arm_smmu_make_nested_cd_table_ste(
target->data[0] |= nested_domain->ste[0] &
~cpu_to_le64(STRTAB_STE_0_CFG);
target->data[1] |= nested_domain->ste[1];
+ /* Merge events for DoS mitigations on eventq */
+ target->data[1] |= cpu_to_le64(STRTAB_STE_1_MEV);
}
/*
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 358072b4e293e..59749e8180afc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1052,7 +1052,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR |
STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH |
STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW |
- STRTAB_STE_1_EATS);
+ STRTAB_STE_1_EATS | STRTAB_STE_1_MEV);
used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
/*
@@ -1068,7 +1068,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits)
if (cfg & BIT(1)) {
used_bits[1] |=
cpu_to_le64(STRTAB_STE_1_S2FWB | STRTAB_STE_1_EATS |
- STRTAB_STE_1_SHCFG);
+ STRTAB_STE_1_SHCFG | STRTAB_STE_1_MEV);
used_bits[2] |=
cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR |
STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI |
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index bd9d7c85576a2..7290bd4c2bb0a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -266,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
#define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4)
#define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
+#define STRTAB_STE_1_MEV (1UL << 19)
#define STRTAB_STE_1_S2FWB (1UL << 25)
#define STRTAB_STE_1_S1STALLD (1UL << 27)
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 25/31] um: Switch to the pthread-based helper in sigio workaround
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (22 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 24/31] iommu/arm-smmu-v3: Set MEV bit in nested STE for DoS mitigations Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-08 4:29 ` Tiwei Bie
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 26/31] um: Rewrite the sigio workaround based on epoll and tgkill Sasha Levin
` (5 subsequent siblings)
29 siblings, 1 reply; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Tiwei Bie, Johannes Berg, Sasha Levin, richard, anton.ivanov,
johannes, linux-um
From: Tiwei Bie <tiwei.btw@antgroup.com>
[ Upstream commit d295beeed2552a987796d627ba7d0985b1e2d72f ]
The write_sigio thread and UML kernel thread share the same errno,
which can lead to conflicts when both call syscalls concurrently.
Switch to the pthread-based helper to address this issue.
Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com>
Link: https://patch.msgid.link/20250319135523.97050-4-tiwei.btw@antgroup.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/um/os-Linux/sigio.c | 44 +++++++++++++++++-----------------------
1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 9aac8def4d635..61b348a2ea974 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -21,8 +21,7 @@
* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
*/
-static int write_sigio_pid = -1;
-static unsigned long write_sigio_stack;
+static struct os_helper_thread *write_sigio_td;
/*
* These arrays are initialized before the sigio thread is started, and
@@ -48,15 +47,15 @@ static struct pollfds current_poll;
static struct pollfds next_poll;
static struct pollfds all_sigio_fds;
-static int write_sigio_thread(void *unused)
+static void *write_sigio_thread(void *unused)
{
struct pollfds *fds, tmp;
struct pollfd *p;
int i, n, respond_fd;
char c;
- os_set_pdeathsig();
- os_fix_helper_signals();
+ os_fix_helper_thread_signals();
+
fds = ¤t_poll;
while (1) {
n = poll(fds->poll, fds->used, -1);
@@ -98,7 +97,7 @@ static int write_sigio_thread(void *unused)
}
}
- return 0;
+ return NULL;
}
static int need_poll(struct pollfds *polls, int n)
@@ -152,11 +151,10 @@ static void update_thread(void)
return;
fail:
/* Critical section start */
- if (write_sigio_pid != -1) {
- os_kill_process(write_sigio_pid, 1);
- free_stack(write_sigio_stack, 0);
+ if (write_sigio_td) {
+ os_kill_helper_thread(write_sigio_td);
+ write_sigio_td = NULL;
}
- write_sigio_pid = -1;
close(sigio_private[0]);
close(sigio_private[1]);
close(write_sigio_fds[0]);
@@ -220,7 +218,7 @@ int __ignore_sigio_fd(int fd)
* sigio_cleanup has already run, then update_thread will hang
* or fail because the thread is no longer running.
*/
- if (write_sigio_pid == -1)
+ if (!write_sigio_td)
return -EIO;
for (i = 0; i < current_poll.used; i++) {
@@ -279,14 +277,14 @@ static void write_sigio_workaround(void)
int err;
int l_write_sigio_fds[2];
int l_sigio_private[2];
- int l_write_sigio_pid;
+ struct os_helper_thread *l_write_sigio_td;
/* We call this *tons* of times - and most ones we must just fail. */
sigio_lock();
- l_write_sigio_pid = write_sigio_pid;
+ l_write_sigio_td = write_sigio_td;
sigio_unlock();
- if (l_write_sigio_pid != -1)
+ if (l_write_sigio_td)
return;
err = os_pipe(l_write_sigio_fds, 1, 1);
@@ -312,7 +310,7 @@ static void write_sigio_workaround(void)
* Did we race? Don't try to optimize this, please, it's not so likely
* to happen, and no more than once at the boot.
*/
- if (write_sigio_pid != -1)
+ if (write_sigio_td)
goto out_free;
current_poll = ((struct pollfds) { .poll = p,
@@ -325,18 +323,15 @@ static void write_sigio_workaround(void)
memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
- write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
- CLONE_FILES | CLONE_VM,
- &write_sigio_stack);
-
- if (write_sigio_pid < 0)
+ err = os_run_helper_thread(&write_sigio_td, write_sigio_thread, NULL);
+ if (err < 0)
goto out_clear;
sigio_unlock();
return;
out_clear:
- write_sigio_pid = -1;
+ write_sigio_td = NULL;
write_sigio_fds[0] = -1;
write_sigio_fds[1] = -1;
sigio_private[0] = -1;
@@ -394,12 +389,11 @@ void maybe_sigio_broken(int fd)
static void sigio_cleanup(void)
{
- if (write_sigio_pid == -1)
+ if (!write_sigio_td)
return;
- os_kill_process(write_sigio_pid, 1);
- free_stack(write_sigio_stack, 0);
- write_sigio_pid = -1;
+ os_kill_helper_thread(write_sigio_td);
+ write_sigio_td = NULL;
}
__uml_exitcall(sigio_cleanup);
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH AUTOSEL 6.14 25/31] um: Switch to the pthread-based helper in sigio workaround
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 25/31] um: Switch to the pthread-based helper in sigio workaround Sasha Levin
@ 2025-04-08 4:29 ` Tiwei Bie
0 siblings, 0 replies; 35+ messages in thread
From: Tiwei Bie @ 2025-04-08 4:29 UTC (permalink / raw)
To: Sasha Levin, linux-kernel, stable
Cc: Johannes Berg, richard, anton.ivanov, johannes, linux-um
On 2025/4/8 02:10, Sasha Levin wrote:
> From: Tiwei Bie <tiwei.btw@antgroup.com>
>
> [ Upstream commit d295beeed2552a987796d627ba7d0985b1e2d72f ]
>
> The write_sigio thread and UML kernel thread share the same errno,
> which can lead to conflicts when both call syscalls concurrently.
> Switch to the pthread-based helper to address this issue.
>
> Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com>
> Link: https://patch.msgid.link/20250319135523.97050-4-tiwei.btw@antgroup.com
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> arch/um/os-Linux/sigio.c | 44 +++++++++++++++++-----------------------
> 1 file changed, 19 insertions(+), 25 deletions(-)
This patch depends on the helpers introduced by the below patch:
https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4f087eafdcef24b7160b097ddb9704084767b77a
So it can't be backported to the stable branch alone. Please drop
it. It is more of a preparation for the new features to be added
in the future. If it turns out later that it is also necessary for
the stable branch, I will submit a separate patchset specifically
targeting it.
Regards,
Tiwei
>
> diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
> index 9aac8def4d635..61b348a2ea974 100644
> --- a/arch/um/os-Linux/sigio.c
> +++ b/arch/um/os-Linux/sigio.c
> @@ -21,8 +21,7 @@
> * Protected by sigio_lock(), also used by sigio_cleanup, which is an
> * exitcall.
> */
> -static int write_sigio_pid = -1;
> -static unsigned long write_sigio_stack;
> +static struct os_helper_thread *write_sigio_td;
>
> /*
> * These arrays are initialized before the sigio thread is started, and
> @@ -48,15 +47,15 @@ static struct pollfds current_poll;
> static struct pollfds next_poll;
> static struct pollfds all_sigio_fds;
>
> -static int write_sigio_thread(void *unused)
> +static void *write_sigio_thread(void *unused)
> {
> struct pollfds *fds, tmp;
> struct pollfd *p;
> int i, n, respond_fd;
> char c;
>
> - os_set_pdeathsig();
> - os_fix_helper_signals();
> + os_fix_helper_thread_signals();
> +
> fds = ¤t_poll;
> while (1) {
> n = poll(fds->poll, fds->used, -1);
> @@ -98,7 +97,7 @@ static int write_sigio_thread(void *unused)
> }
> }
>
> - return 0;
> + return NULL;
> }
>
> static int need_poll(struct pollfds *polls, int n)
> @@ -152,11 +151,10 @@ static void update_thread(void)
> return;
> fail:
> /* Critical section start */
> - if (write_sigio_pid != -1) {
> - os_kill_process(write_sigio_pid, 1);
> - free_stack(write_sigio_stack, 0);
> + if (write_sigio_td) {
> + os_kill_helper_thread(write_sigio_td);
> + write_sigio_td = NULL;
> }
> - write_sigio_pid = -1;
> close(sigio_private[0]);
> close(sigio_private[1]);
> close(write_sigio_fds[0]);
> @@ -220,7 +218,7 @@ int __ignore_sigio_fd(int fd)
> * sigio_cleanup has already run, then update_thread will hang
> * or fail because the thread is no longer running.
> */
> - if (write_sigio_pid == -1)
> + if (!write_sigio_td)
> return -EIO;
>
> for (i = 0; i < current_poll.used; i++) {
> @@ -279,14 +277,14 @@ static void write_sigio_workaround(void)
> int err;
> int l_write_sigio_fds[2];
> int l_sigio_private[2];
> - int l_write_sigio_pid;
> + struct os_helper_thread *l_write_sigio_td;
>
> /* We call this *tons* of times - and most ones we must just fail. */
> sigio_lock();
> - l_write_sigio_pid = write_sigio_pid;
> + l_write_sigio_td = write_sigio_td;
> sigio_unlock();
>
> - if (l_write_sigio_pid != -1)
> + if (l_write_sigio_td)
> return;
>
> err = os_pipe(l_write_sigio_fds, 1, 1);
> @@ -312,7 +310,7 @@ static void write_sigio_workaround(void)
> * Did we race? Don't try to optimize this, please, it's not so likely
> * to happen, and no more than once at the boot.
> */
> - if (write_sigio_pid != -1)
> + if (write_sigio_td)
> goto out_free;
>
> current_poll = ((struct pollfds) { .poll = p,
> @@ -325,18 +323,15 @@ static void write_sigio_workaround(void)
> memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
> memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
>
> - write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
> - CLONE_FILES | CLONE_VM,
> - &write_sigio_stack);
> -
> - if (write_sigio_pid < 0)
> + err = os_run_helper_thread(&write_sigio_td, write_sigio_thread, NULL);
> + if (err < 0)
> goto out_clear;
>
> sigio_unlock();
> return;
>
> out_clear:
> - write_sigio_pid = -1;
> + write_sigio_td = NULL;
> write_sigio_fds[0] = -1;
> write_sigio_fds[1] = -1;
> sigio_private[0] = -1;
> @@ -394,12 +389,11 @@ void maybe_sigio_broken(int fd)
>
> static void sigio_cleanup(void)
> {
> - if (write_sigio_pid == -1)
> + if (!write_sigio_td)
> return;
>
> - os_kill_process(write_sigio_pid, 1);
> - free_stack(write_sigio_stack, 0);
> - write_sigio_pid = -1;
> + os_kill_helper_thread(write_sigio_td);
> + write_sigio_td = NULL;
> }
>
> __uml_exitcall(sigio_cleanup);
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH AUTOSEL 6.14 26/31] um: Rewrite the sigio workaround based on epoll and tgkill
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (23 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 25/31] um: Switch to the pthread-based helper in sigio workaround Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-08 4:36 ` Tiwei Bie
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 27/31] objtool: Silence more KCOV warnings Sasha Levin
` (4 subsequent siblings)
29 siblings, 1 reply; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Tiwei Bie, Johannes Berg, Sasha Levin, richard, anton.ivanov,
johannes, benjamin.berg, linux-um
From: Tiwei Bie <tiwei.btw@antgroup.com>
[ Upstream commit 33c9da5dfb18c2ff5a88d01aca2cf253cd0ac3bc ]
The existing sigio workaround implementation removes FDs from the
poll when events are triggered, requiring users to re-add them via
add_sigio_fd() after processing. This introduces a potential race
condition between FD removal in write_sigio_thread() and next_poll
update in __add_sigio_fd(), and is inefficient due to frequent FD
removal and re-addition. Rewrite the implementation based on epoll
and tgkill for improved efficiency and reliability.
Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com>
Link: https://patch.msgid.link/20250315161910.4082396-2-tiwei.btw@antgroup.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/um/drivers/random.c | 2 +-
arch/um/drivers/rtc_user.c | 2 +-
arch/um/include/shared/os.h | 2 +-
arch/um/include/shared/sigio.h | 1 -
arch/um/kernel/sigio.c | 26 ---
arch/um/os-Linux/sigio.c | 330 +++++----------------------------
6 files changed, 47 insertions(+), 316 deletions(-)
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index da985e0dc69a5..ca08c91f47a37 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -79,7 +79,7 @@ static int __init rng_init (void)
if (err < 0)
goto err_out_cleanup_hw;
- sigio_broken(random_fd);
+ sigio_broken();
hwrng.name = RNG_MODULE_NAME;
hwrng.read = rng_dev_read;
diff --git a/arch/um/drivers/rtc_user.c b/arch/um/drivers/rtc_user.c
index 7c3cec4c68cff..51e79f3148cd4 100644
--- a/arch/um/drivers/rtc_user.c
+++ b/arch/um/drivers/rtc_user.c
@@ -39,7 +39,7 @@ int uml_rtc_start(bool timetravel)
}
/* apparently timerfd won't send SIGIO, use workaround */
- sigio_broken(uml_rtc_irq_fds[0]);
+ sigio_broken();
err = add_sigio_fd(uml_rtc_irq_fds[0]);
if (err < 0) {
close(uml_rtc_irq_fds[0]);
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 5babad8c5f75e..92868f398457a 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -310,7 +310,7 @@ extern void um_irqs_resume(void);
extern int add_sigio_fd(int fd);
extern int ignore_sigio_fd(int fd);
extern void maybe_sigio_broken(int fd);
-extern void sigio_broken(int fd);
+extern void sigio_broken(void);
/*
* unlocked versions for IRQ controller code.
*
diff --git a/arch/um/include/shared/sigio.h b/arch/um/include/shared/sigio.h
index e60c8b2278449..c6c2edce1f6d2 100644
--- a/arch/um/include/shared/sigio.h
+++ b/arch/um/include/shared/sigio.h
@@ -6,7 +6,6 @@
#ifndef __SIGIO_H__
#define __SIGIO_H__
-extern int write_sigio_irq(int fd);
extern void sigio_lock(void);
extern void sigio_unlock(void);
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index 5085a50c3b8c8..4fc04742048ab 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -8,32 +8,6 @@
#include <os.h>
#include <sigio.h>
-/* Protected by sigio_lock() called from write_sigio_workaround */
-static int sigio_irq_fd = -1;
-
-static irqreturn_t sigio_interrupt(int irq, void *data)
-{
- char c;
-
- os_read_file(sigio_irq_fd, &c, sizeof(c));
- return IRQ_HANDLED;
-}
-
-int write_sigio_irq(int fd)
-{
- int err;
-
- err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
- 0, "write sigio", NULL);
- if (err < 0) {
- printk(KERN_ERR "write_sigio_irq : um_request_irq failed, "
- "err = %d\n", err);
- return -1;
- }
- sigio_irq_fd = fd;
- return 0;
-}
-
/* These are called from os-Linux/sigio.c to protect its pollfds arrays. */
static DEFINE_MUTEX(sigio_mutex);
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 61b348a2ea974..a05a6ecee7561 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -11,6 +11,7 @@
#include <sched.h>
#include <signal.h>
#include <string.h>
+#include <sys/epoll.h>
#include <kern_util.h>
#include <init.h>
#include <os.h>
@@ -23,180 +24,49 @@
*/
static struct os_helper_thread *write_sigio_td;
-/*
- * These arrays are initialized before the sigio thread is started, and
- * the descriptors closed after it is killed. So, it can't see them change.
- * On the UML side, they are changed under the sigio_lock.
- */
-#define SIGIO_FDS_INIT {-1, -1}
-
-static int write_sigio_fds[2] = SIGIO_FDS_INIT;
-static int sigio_private[2] = SIGIO_FDS_INIT;
+static int epollfd = -1;
-struct pollfds {
- struct pollfd *poll;
- int size;
- int used;
-};
+#define MAX_EPOLL_EVENTS 64
-/*
- * Protected by sigio_lock(). Used by the sigio thread, but the UML thread
- * synchronizes with it.
- */
-static struct pollfds current_poll;
-static struct pollfds next_poll;
-static struct pollfds all_sigio_fds;
+static struct epoll_event epoll_events[MAX_EPOLL_EVENTS];
static void *write_sigio_thread(void *unused)
{
- struct pollfds *fds, tmp;
- struct pollfd *p;
- int i, n, respond_fd;
- char c;
+ int pid = getpid();
+ int r;
os_fix_helper_thread_signals();
- fds = ¤t_poll;
while (1) {
- n = poll(fds->poll, fds->used, -1);
- if (n < 0) {
+ r = epoll_wait(epollfd, epoll_events, MAX_EPOLL_EVENTS, -1);
+ if (r < 0) {
if (errno == EINTR)
continue;
- printk(UM_KERN_ERR "write_sigio_thread : poll returned "
- "%d, errno = %d\n", n, errno);
+ printk(UM_KERN_ERR "%s: epoll_wait failed, errno = %d\n",
+ __func__, errno);
}
- for (i = 0; i < fds->used; i++) {
- p = &fds->poll[i];
- if (p->revents == 0)
- continue;
- if (p->fd == sigio_private[1]) {
- CATCH_EINTR(n = read(sigio_private[1], &c,
- sizeof(c)));
- if (n != sizeof(c))
- printk(UM_KERN_ERR
- "write_sigio_thread : "
- "read on socket failed, "
- "err = %d\n", errno);
- tmp = current_poll;
- current_poll = next_poll;
- next_poll = tmp;
- respond_fd = sigio_private[1];
- }
- else {
- respond_fd = write_sigio_fds[1];
- fds->used--;
- memmove(&fds->poll[i], &fds->poll[i + 1],
- (fds->used - i) * sizeof(*fds->poll));
- }
-
- CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
- if (n != sizeof(c))
- printk(UM_KERN_ERR "write_sigio_thread : "
- "write on socket failed, err = %d\n",
- errno);
- }
- }
-
- return NULL;
-}
-
-static int need_poll(struct pollfds *polls, int n)
-{
- struct pollfd *new;
-
- if (n <= polls->size)
- return 0;
-
- new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
- if (new == NULL) {
- printk(UM_KERN_ERR "need_poll : failed to allocate new "
- "pollfds\n");
- return -ENOMEM;
- }
-
- memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
- kfree(polls->poll);
-
- polls->poll = new;
- polls->size = n;
- return 0;
-}
-
-/*
- * Must be called with sigio_lock held, because it's needed by the marked
- * critical section.
- */
-static void update_thread(void)
-{
- unsigned long flags;
- int n;
- char c;
-
- flags = um_set_signals_trace(0);
- CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c)));
- if (n != sizeof(c)) {
- printk(UM_KERN_ERR "update_thread : write failed, err = %d\n",
- errno);
- goto fail;
- }
- CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
- if (n != sizeof(c)) {
- printk(UM_KERN_ERR "update_thread : read failed, err = %d\n",
- errno);
- goto fail;
+ CATCH_EINTR(r = tgkill(pid, pid, SIGIO));
+ if (r < 0)
+ printk(UM_KERN_ERR "%s: tgkill failed, errno = %d\n",
+ __func__, errno);
}
- um_set_signals_trace(flags);
- return;
- fail:
- /* Critical section start */
- if (write_sigio_td) {
- os_kill_helper_thread(write_sigio_td);
- write_sigio_td = NULL;
- }
- close(sigio_private[0]);
- close(sigio_private[1]);
- close(write_sigio_fds[0]);
- close(write_sigio_fds[1]);
- /* Critical section end */
- um_set_signals_trace(flags);
+ return NULL;
}
int __add_sigio_fd(int fd)
{
- struct pollfd *p;
- int err, i, n;
-
- for (i = 0; i < all_sigio_fds.used; i++) {
- if (all_sigio_fds.poll[i].fd == fd)
- break;
- }
- if (i == all_sigio_fds.used)
- return -ENOSPC;
-
- p = &all_sigio_fds.poll[i];
-
- for (i = 0; i < current_poll.used; i++) {
- if (current_poll.poll[i].fd == fd)
- return 0;
- }
-
- n = current_poll.used;
- err = need_poll(&next_poll, n + 1);
- if (err)
- return err;
-
- memcpy(next_poll.poll, current_poll.poll,
- current_poll.used * sizeof(struct pollfd));
- next_poll.poll[n] = *p;
- next_poll.used = n + 1;
- update_thread();
-
- return 0;
+ struct epoll_event event = {
+ .data.fd = fd,
+ .events = EPOLLIN | EPOLLET,
+ };
+ int r;
+
+ CATCH_EINTR(r = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event));
+ return r < 0 ? -errno : 0;
}
-
int add_sigio_fd(int fd)
{
int err;
@@ -210,38 +80,11 @@ int add_sigio_fd(int fd)
int __ignore_sigio_fd(int fd)
{
- struct pollfd *p;
- int err, i, n = 0;
-
- /*
- * This is called from exitcalls elsewhere in UML - if
- * sigio_cleanup has already run, then update_thread will hang
- * or fail because the thread is no longer running.
- */
- if (!write_sigio_td)
- return -EIO;
-
- for (i = 0; i < current_poll.used; i++) {
- if (current_poll.poll[i].fd == fd)
- break;
- }
- if (i == current_poll.used)
- return -ENOENT;
-
- err = need_poll(&next_poll, current_poll.used - 1);
- if (err)
- return err;
+ struct epoll_event event;
+ int r;
- for (i = 0; i < current_poll.used; i++) {
- p = ¤t_poll.poll[i];
- if (p->fd != fd)
- next_poll.poll[n++] = *p;
- }
- next_poll.used = current_poll.used - 1;
-
- update_thread();
-
- return 0;
+ CATCH_EINTR(r = epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &event));
+ return r < 0 ? -errno : 0;
}
int ignore_sigio_fd(int fd)
@@ -255,122 +98,37 @@ int ignore_sigio_fd(int fd)
return err;
}
-static struct pollfd *setup_initial_poll(int fd)
-{
- struct pollfd *p;
-
- p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
- if (p == NULL) {
- printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
- "poll\n");
- return NULL;
- }
- *p = ((struct pollfd) { .fd = fd,
- .events = POLLIN,
- .revents = 0 });
- return p;
-}
-
static void write_sigio_workaround(void)
{
- struct pollfd *p;
int err;
- int l_write_sigio_fds[2];
- int l_sigio_private[2];
- struct os_helper_thread *l_write_sigio_td;
-
- /* We call this *tons* of times - and most ones we must just fail. */
- sigio_lock();
- l_write_sigio_td = write_sigio_td;
- sigio_unlock();
-
- if (l_write_sigio_td)
- return;
-
- err = os_pipe(l_write_sigio_fds, 1, 1);
- if (err < 0) {
- printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, "
- "err = %d\n", -err);
- return;
- }
- err = os_pipe(l_sigio_private, 1, 1);
- if (err < 0) {
- printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, "
- "err = %d\n", -err);
- goto out_close1;
- }
-
- p = setup_initial_poll(l_sigio_private[1]);
- if (!p)
- goto out_close2;
sigio_lock();
-
- /*
- * Did we race? Don't try to optimize this, please, it's not so likely
- * to happen, and no more than once at the boot.
- */
if (write_sigio_td)
- goto out_free;
-
- current_poll = ((struct pollfds) { .poll = p,
- .used = 1,
- .size = 1 });
-
- if (write_sigio_irq(l_write_sigio_fds[0]))
- goto out_clear_poll;
+ goto out;
- memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
- memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
+ epollfd = epoll_create(MAX_EPOLL_EVENTS);
+ if (epollfd < 0) {
+ printk(UM_KERN_ERR "%s: epoll_create failed, errno = %d\n",
+ __func__, errno);
+ goto out;
+ }
err = os_run_helper_thread(&write_sigio_td, write_sigio_thread, NULL);
- if (err < 0)
- goto out_clear;
-
- sigio_unlock();
- return;
+ if (err < 0) {
+ printk(UM_KERN_ERR "%s: os_run_helper_thread failed, errno = %d\n",
+ __func__, -err);
+ close(epollfd);
+ epollfd = -1;
+ goto out;
+ }
-out_clear:
- write_sigio_td = NULL;
- write_sigio_fds[0] = -1;
- write_sigio_fds[1] = -1;
- sigio_private[0] = -1;
- sigio_private[1] = -1;
-out_clear_poll:
- current_poll = ((struct pollfds) { .poll = NULL,
- .size = 0,
- .used = 0 });
-out_free:
+out:
sigio_unlock();
- kfree(p);
-out_close2:
- close(l_sigio_private[0]);
- close(l_sigio_private[1]);
-out_close1:
- close(l_write_sigio_fds[0]);
- close(l_write_sigio_fds[1]);
}
-void sigio_broken(int fd)
+void sigio_broken(void)
{
- int err;
-
write_sigio_workaround();
-
- sigio_lock();
- err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
- if (err) {
- printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd "
- "for descriptor %d\n", fd);
- goto out;
- }
-
- all_sigio_fds.poll[all_sigio_fds.used++] =
- ((struct pollfd) { .fd = fd,
- .events = POLLIN,
- .revents = 0 });
-out:
- sigio_unlock();
}
/* Changed during early boot */
@@ -384,7 +142,7 @@ void maybe_sigio_broken(int fd)
if (pty_output_sigio)
return;
- sigio_broken(fd);
+ sigio_broken();
}
static void sigio_cleanup(void)
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* Re: [PATCH AUTOSEL 6.14 26/31] um: Rewrite the sigio workaround based on epoll and tgkill
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 26/31] um: Rewrite the sigio workaround based on epoll and tgkill Sasha Levin
@ 2025-04-08 4:36 ` Tiwei Bie
0 siblings, 0 replies; 35+ messages in thread
From: Tiwei Bie @ 2025-04-08 4:36 UTC (permalink / raw)
To: Sasha Levin, linux-kernel, stable
Cc: Johannes Berg, richard, anton.ivanov, johannes, benjamin.berg,
linux-um
On 2025/4/8 02:10, Sasha Levin wrote:
> From: Tiwei Bie <tiwei.btw@antgroup.com>
>
> [ Upstream commit 33c9da5dfb18c2ff5a88d01aca2cf253cd0ac3bc ]
>
> The existing sigio workaround implementation removes FDs from the
> poll when events are triggered, requiring users to re-add them via
> add_sigio_fd() after processing. This introduces a potential race
> condition between FD removal in write_sigio_thread() and next_poll
> update in __add_sigio_fd(), and is inefficient due to frequent FD
> removal and re-addition. Rewrite the implementation based on epoll
> and tgkill for improved efficiency and reliability.
>
> Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com>
> Link: https://patch.msgid.link/20250315161910.4082396-2-tiwei.btw@antgroup.com
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> arch/um/drivers/random.c | 2 +-
> arch/um/drivers/rtc_user.c | 2 +-
> arch/um/include/shared/os.h | 2 +-
> arch/um/include/shared/sigio.h | 1 -
> arch/um/kernel/sigio.c | 26 ---
> arch/um/os-Linux/sigio.c | 330 +++++----------------------------
> 6 files changed, 47 insertions(+), 316 deletions(-)
Please drop this patch. Thanks! Details can be found here:
https://lore.kernel.org/linux-um/ffa0b6af-523d-4e3e-9952-92f5b04b82b3@antgroup.com/
Regards,
Tiwei
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH AUTOSEL 6.14 27/31] objtool: Silence more KCOV warnings
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (24 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 26/31] um: Rewrite the sigio workaround based on epoll and tgkill Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 28/31] objtool, panic: Disable SMAP in __stack_chk_fail() Sasha Levin
` (3 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Josh Poimboeuf, Ingo Molnar, kernel test robot, Linus Torvalds,
Sasha Levin, peterz
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit 6b023c7842048c4bbeede802f3cf36b96c7a8b25 ]
In the past there were issues with KCOV triggering unreachable
instruction warnings, which is why unreachable warnings are now disabled
with CONFIG_KCOV.
Now some new KCOV warnings are showing up with GCC 14:
vmlinux.o: warning: objtool: cpuset_write_resmask() falls through to next function cpuset_update_active_cpus.cold()
drivers/usb/core/driver.o: error: objtool: usb_deregister() falls through to next function usb_match_device()
sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section
All are caused by GCC KCOV not finishing an optimization, leaving behind
a never-taken conditional branch to a basic block which falls through to
the next function (or end of section).
At a high level this is similar to the unreachable warnings mentioned
above, in that KCOV isn't fully removing dead code. Treat it the same
way by adding these to the list of warnings to ignore with CONFIG_KCOV.
Reported-by: Ingo Molnar <mingo@kernel.org>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/66a61a0b65d74e072d3dc02384e395edb2adc3c5.1742852846.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/Z9iTsI09AEBlxlHC@gmail.com
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/objtool/check.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ce973d9d8e6d8..9b5852299957e 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3488,6 +3488,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
!strncmp(func->name, "__pfx_", 6))
return 0;
+ if (file->ignore_unreachables)
+ return 0;
+
WARN("%s() falls through to next function %s()",
func->name, insn_func(insn)->name);
return 1;
@@ -3707,6 +3710,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
if (!next_insn) {
if (state.cfi.cfa.base == CFI_UNDEFINED)
return 0;
+ if (file->ignore_unreachables)
+ return 0;
+
WARN("%s: unexpected end of section", sec->name);
return 1;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 28/31] objtool, panic: Disable SMAP in __stack_chk_fail()
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (25 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 27/31] objtool: Silence more KCOV warnings Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 29/31] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler() Sasha Levin
` (2 subsequent siblings)
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Josh Poimboeuf, Ingo Molnar, Kees Cook, Andrew Morton,
Linus Torvalds, Sasha Levin, peterz, pmladek, jani.nikula, gregkh,
john.ogness, joel.granados, jfalempe, takakura
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit 72c774aa9d1e16bfd247096935e7dae194d84929 ]
__stack_chk_fail() can be called from uaccess-enabled code. Make sure
uaccess gets disabled before calling panic().
Fixes the following warning:
kernel/trace/trace_branch.o: error: objtool: ftrace_likely_update+0x1ea: call to __stack_chk_fail() with UACCESS enabled
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/a3e97e0119e1b04c725a8aa05f7bc83d98e657eb.1742852847.git.jpoimboe@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/panic.c | 6 ++++++
tools/objtool/check.c | 5 ++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/kernel/panic.c b/kernel/panic.c
index d8635d5cecb25..f9f0c5148f6aa 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -832,9 +832,15 @@ device_initcall(register_warn_debugfs);
*/
__visible noinstr void __stack_chk_fail(void)
{
+ unsigned long flags;
+
instrumentation_begin();
+ flags = user_access_save();
+
panic("stack-protector: Kernel stack is corrupted in: %pB",
__builtin_return_address(0));
+
+ user_access_restore(flags);
instrumentation_end();
}
EXPORT_SYMBOL(__stack_chk_fail);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 9b5852299957e..192554116f5d8 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1188,12 +1188,15 @@ static const char *uaccess_safe_builtin[] = {
"__ubsan_handle_load_invalid_value",
/* STACKLEAK */
"stackleak_track_stack",
+ /* TRACE_BRANCH_PROFILING */
+ "ftrace_likely_update",
+ /* STACKPROTECTOR */
+ "__stack_chk_fail",
/* misc */
"csum_partial_copy_generic",
"copy_mc_fragile",
"copy_mc_fragile_handle_tail",
"copy_mc_enhanced_fast_string",
- "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */
"rep_stos_alternative",
"rep_movs_alternative",
"__copy_user_nocache",
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 29/31] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (26 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 28/31] objtool, panic: Disable SMAP in __stack_chk_fail() Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 30/31] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc() Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 31/31] objtool, lkdtm: Obfuscate the do_nothing() pointer Sasha Levin
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Josh Poimboeuf, kernel test robot, Ingo Molnar, Mark Brown,
Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Linus Torvalds, Sasha Levin, nathan, linux-sound, linux-arm-msm,
llvm
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit 060aed9c0093b341480770457093449771cf1496 ]
If 'port_id' is negative, the shift counts in wcd934x_slim_irq_handler()
also become negative, resulting in undefined behavior due to shift out
of bounds.
If I'm reading the code correctly, that appears to be not possible, but
with KCOV enabled, Clang's range analysis isn't always able to determine
that and generates undefined behavior.
As a result the code generation isn't optimal, and undefined behavior
should be avoided regardless. Improve code generation and remove the
undefined behavior by converting the signed variables to unsigned.
Fixes the following warning with UBSAN:
sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/7e863839ec7301bf9c0f429a03873d44e484c31c.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/wcd934x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
index 910852eb9698c..c7f1b28f3b230 100644
--- a/sound/soc/codecs/wcd934x.c
+++ b/sound/soc/codecs/wcd934x.c
@@ -2273,7 +2273,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data)
{
struct wcd934x_codec *wcd = data;
unsigned long status = 0;
- int i, j, port_id;
+ unsigned int i, j, port_id;
unsigned int val, int_val = 0;
irqreturn_t ret = IRQ_NONE;
bool tx;
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 30/31] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (27 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 29/31] objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler() Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 31/31] objtool, lkdtm: Obfuscate the do_nothing() pointer Sasha Levin
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Josh Poimboeuf, kernel test robot, Ingo Molnar, Mark Brown,
Liam Girdwood, Linus Torvalds, Sasha Levin
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit 29c578c848402a34e8c8e115bf66cb6008b77062 ]
If 'ctr_bit' is negative, the shift counts become negative, causing a
shift of bounds and undefined behavior.
Presumably that's not possible in normal operation, but the code
generation isn't optimal. And undefined behavior should be avoided
regardless.
Improve code generation and remove the undefined behavior by converting
the signed variables to unsigned.
Fixes the following warning with an UBSAN kernel:
vmlinux.o: warning: objtool: rk806_set_mode_dcdc() falls through to next function rk806_get_mode_dcdc()
vmlinux.o: warning: objtool: .text.rk806_set_mode_dcdc: unexpected end of section
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/2023abcddf3f524ba478d64339996f25dc4097d2.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503182350.52KeHGD4-lkp@intel.com/
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/regulator/rk808-regulator.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 7d82bd1b36dfc..1e8142479656a 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
{
- int rid = rdev_get_id(rdev);
- int ctr_bit, reg;
+ unsigned int rid = rdev_get_id(rdev);
+ unsigned int ctr_bit, reg;
reg = RK806_POWER_FPWM_EN0 + rid / 8;
ctr_bit = rid % 8;
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread* [PATCH AUTOSEL 6.14 31/31] objtool, lkdtm: Obfuscate the do_nothing() pointer
2025-04-07 18:10 [PATCH AUTOSEL 6.14 01/31] staging: gpib: Use min for calculating transfer length Sasha Levin
` (28 preceding siblings ...)
2025-04-07 18:10 ` [PATCH AUTOSEL 6.14 30/31] objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc() Sasha Levin
@ 2025-04-07 18:10 ` Sasha Levin
29 siblings, 0 replies; 35+ messages in thread
From: Sasha Levin @ 2025-04-07 18:10 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Josh Poimboeuf, kernel test robot, Ingo Molnar, Kees Cook,
Arnd Bergmann, Greg Kroah-Hartman, Linus Torvalds, Sasha Levin
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit 05026ea01e95ffdeb0e5ac8fb7fb1b551e3a8726 ]
If execute_location()'s memcpy of do_nothing() gets inlined and unrolled
by the compiler, it copies one word at a time:
mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x1374
mov %rax,0x38(%rbx)
mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x136c
mov %rax,0x30(%rbx)
...
Those .text references point to the middle of the function, causing
objtool to complain about their lack of ENDBR.
Prevent that by resolving the function pointer at runtime rather than
build time. This fixes the following warning:
drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/lkdtm/perms.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 5b861dbff27e9..6c24426104ba6 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
+/*
+ * This is a pointer to do_nothing() which is initialized at runtime rather
+ * than build time to avoid objtool IBT validation warnings caused by an
+ * inlined unrolled memcpy() in execute_location().
+ */
+static void __ro_after_init *do_nothing_ptr;
+
/*
* This just returns to the caller. It is designed to be copied into
* non-executable memory regions.
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
{
void (*func)(void);
func_desc_t fdesc;
- void *do_nothing_text = dereference_function_descriptor(do_nothing);
- pr_info("attempting ok execution at %px\n", do_nothing_text);
+ pr_info("attempting ok execution at %px\n", do_nothing_ptr);
do_nothing();
if (write == CODE_WRITE) {
- memcpy(dst, do_nothing_text, EXEC_SIZE);
+ memcpy(dst, do_nothing_ptr, EXEC_SIZE);
flush_icache_range((unsigned long)dst,
(unsigned long)dst + EXEC_SIZE);
}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
void __init lkdtm_perms_init(void)
{
+ do_nothing_ptr = dereference_function_descriptor(do_nothing);
+
/* Make sure we can write to __ro_after_init values during __init */
ro_after_init |= 0xAA;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 35+ messages in thread