Message ID | 20240806112029.2984319-1-heikki.krogerus@linux.intel.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 65ba8cef0416816b912c04850fc2468329994353 |
Headers | show |
Series | usb: typec: ucsi: Fix a deadlock in ucsi_send_command_common() | expand |
On Tue, Aug 06, 2024 at 02:20:29PM +0300, Heikki Krogerus wrote: > The function returns with the ppm_lock held if the PPM is > busy or there's an error. > > Reported-and-tested-by: Luciano Coelho <luciano.coelho@intel.com> > Fixes: 5e9c1662a89b ("usb: typec: ucsi: rework command execution functions") > Cc: stable@vger.kernel.org This does not go to the stable trees after all. The regression is in v6.11-rc1. I'm sorry about that. > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/usb/typec/ucsi/ucsi.c | 11 ++++------- > 1 file changed, 4 insertions(+), 7 deletions(-) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index dcd3765cc1f5..432a2d6266d7 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; > -- > 2.43.0
diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index dcd3765cc1f5..432a2d6266d7 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;
The function returns with the ppm_lock held if the PPM is busy or there's an error. Reported-and-tested-by: Luciano Coelho <luciano.coelho@intel.com> Fixes: 5e9c1662a89b ("usb: typec: ucsi: rework command execution functions") Cc: stable@vger.kernel.org Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> --- drivers/usb/typec/ucsi/ucsi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)