| From 0c117a4a2113a9a8d0c0f0a9da900e30db5685b5 Mon Sep 17 00:00:00 2001 |
| From: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| Date: Wed, 11 Mar 2020 16:00:06 +0300 |
| Subject: [PATCH] usb: typec: ucsi: displayport: Fix a potential race during |
| registration |
| |
| commit 081da1325d351ea8804cf74e65263ea120834f33 upstream. |
| |
| Locking the connector in ucsi_register_displayport() to make |
| sure that nothing can access the displayport alternate mode |
| before the function has finished and the alternate mode is |
| actually ready. |
| |
| Fixes: af8622f6a585 ("usb: typec: ucsi: Support for DisplayPort alt mode") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| Link: https://lore.kernel.org/r/20200311130006.41288-3-heikki.krogerus@linux.intel.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/typec/ucsi/displayport.c b/drivers/usb/typec/ucsi/displayport.c |
| index 2fee12f748fe..166c2aabb512 100644 |
| --- a/drivers/usb/typec/ucsi/displayport.c |
| +++ b/drivers/usb/typec/ucsi/displayport.c |
| @@ -290,6 +290,8 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, |
| struct typec_altmode *alt; |
| struct ucsi_dp *dp; |
| |
| + mutex_lock(&con->lock); |
| + |
| /* We can't rely on the firmware with the capabilities. */ |
| desc->vdo |= DP_CAP_DP_SIGNALING | DP_CAP_RECEPTACLE; |
| |
| @@ -298,12 +300,15 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, |
| desc->vdo |= all_assignments << 16; |
| |
| alt = typec_port_register_altmode(con->port, desc); |
| - if (IS_ERR(alt)) |
| + if (IS_ERR(alt)) { |
| + mutex_unlock(&con->lock); |
| return alt; |
| + } |
| |
| dp = devm_kzalloc(&alt->dev, sizeof(*dp), GFP_KERNEL); |
| if (!dp) { |
| typec_unregister_altmode(alt); |
| + mutex_unlock(&con->lock); |
| return ERR_PTR(-ENOMEM); |
| } |
| |
| @@ -316,5 +321,7 @@ struct typec_altmode *ucsi_register_displayport(struct ucsi_connector *con, |
| alt->ops = &ucsi_displayport_ops; |
| typec_altmode_set_drvdata(alt, dp); |
| |
| + mutex_unlock(&con->lock); |
| + |
| return alt; |
| } |
| -- |
| 2.7.4 |
| |