From: Heikki Krogerus Date: Tue, 6 Aug 2024 11:20:29 +0000 (+0300) Subject: usb: typec: ucsi: Fix a deadlock in ucsi_send_command_common() X-Git-Tag: v6.11-rc3~4^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=65ba8cef0416816b912c04850fc2468329994353;p=thirdparty%2Fkernel%2Flinux.git usb: typec: ucsi: Fix a deadlock in ucsi_send_command_common() The function returns with the ppm_lock held if the PPM is busy or there's an error. Reported-and-tested-by: Luciano Coelho Fixes: 5e9c1662a89b ("usb: typec: ucsi: rework command execution functions") Signed-off-by: Heikki Krogerus Reported-by: Luciano Coelho Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/20240806112029.2984319-1-heikki.krogerus@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index dcd3765cc1f53..432a2d6266d71 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -238,13 +238,10 @@ static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, mutex_lock(&ucsi->ppm_lock); ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack); - if (cci & UCSI_CCI_BUSY) { - ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false); - return ret ? ret : -EBUSY; - } - - if (cci & UCSI_CCI_ERROR) - return ucsi_read_error(ucsi, connector_num); + if (cci & UCSI_CCI_BUSY) + ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false) ?: -EBUSY; + else if (cci & UCSI_CCI_ERROR) + ret = ucsi_read_error(ucsi, connector_num); mutex_unlock(&ucsi->ppm_lock); return ret;