diff mbox series

[v3,02/10] usb: roles: Handle driver reference counting

Message ID 20180904112219.89287-3-heikki.krogerus@linux.intel.com (mailing list archive)
State Deferred, archived
Delegated to: Andy Shevchenko
Headers show
Series usb: typec: A few more improvements for Intel CHT | expand

Commit Message

Heikki Krogerus Sept. 4, 2018, 11:22 a.m. UTC
This fixes potential "BUG: unable to handle kernel paging
request at ..." from happening.

Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches")
Cc: <stable@vger.kernel.org>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
---
 drivers/usb/common/roles.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

Comments

Hans de Goede Sept. 6, 2018, 8:59 p.m. UTC | #1
HI,

On 04-09-18 13:22, Heikki Krogerus wrote:
> This fixes potential "BUG: unable to handle kernel paging
> request at ..." from happening.
> 
> Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> ---
>   drivers/usb/common/roles.c | 15 ++++++++++++---
>   1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c
> index 15cc76e22123..3d8a776e55ee 100644
> --- a/drivers/usb/common/roles.c
> +++ b/drivers/usb/common/roles.c
> @@ -109,8 +109,15 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
>    */
>   struct usb_role_switch *usb_role_switch_get(struct device *dev)
>   {
> -	return device_connection_find_match(dev, "usb-role-switch", NULL,
> -					    usb_role_switch_match);
> +	struct usb_role_switch *sw;
> +
> +	sw = device_connection_find_match(dev, "usb-role-switch", NULL,
> +					  usb_role_switch_match);
> +
> +	if (!IS_ERR(sw))
> +		WARN_ON(!try_module_get(sw->dev.parent->driver->owner));

While testing I found a bug, so sorry but this is going to need a v4,
device_connection_find_match() may return NULL here, so this needs
to be if (!IS_ERR_OR_NULL(sw)) to avoid an oops.

Note I'm also seeing some other issues which I need to debug I will
do so tomorrow morning so you may want to wait a bit with v4.

Regards,

Hans


> +
> +	return sw;
>   }
>   EXPORT_SYMBOL_GPL(usb_role_switch_get);
>   
> @@ -122,8 +129,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
>    */
>   void usb_role_switch_put(struct usb_role_switch *sw)
>   {
> -	if (!IS_ERR_OR_NULL(sw))
> +	if (!IS_ERR_OR_NULL(sw)) {
>   		put_device(&sw->dev);
> +		module_put(sw->dev.parent->driver->owner);
> +	}
>   }
>   EXPORT_SYMBOL_GPL(usb_role_switch_put);
>   
>
Heikki Krogerus Sept. 7, 2018, 9:48 a.m. UTC | #2
On Thu, Sep 06, 2018 at 10:59:34PM +0200, Hans de Goede wrote:
> HI,
> 
> On 04-09-18 13:22, Heikki Krogerus wrote:
> > This fixes potential "BUG: unable to handle kernel paging
> > request at ..." from happening.
> > 
> > Fixes: fde0aa6c175a ("usb: common: Small class for USB role switches")
> > Cc: <stable@vger.kernel.org>
> > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > ---
> >   drivers/usb/common/roles.c | 15 ++++++++++++---
> >   1 file changed, 12 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c
> > index 15cc76e22123..3d8a776e55ee 100644
> > --- a/drivers/usb/common/roles.c
> > +++ b/drivers/usb/common/roles.c
> > @@ -109,8 +109,15 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
> >    */
> >   struct usb_role_switch *usb_role_switch_get(struct device *dev)
> >   {
> > -	return device_connection_find_match(dev, "usb-role-switch", NULL,
> > -					    usb_role_switch_match);
> > +	struct usb_role_switch *sw;
> > +
> > +	sw = device_connection_find_match(dev, "usb-role-switch", NULL,
> > +					  usb_role_switch_match);
> > +
> > +	if (!IS_ERR(sw))
> > +		WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
> 
> While testing I found a bug, so sorry but this is going to need a v4,
> device_connection_find_match() may return NULL here, so this needs
> to be if (!IS_ERR_OR_NULL(sw)) to avoid an oops.
> 
> Note I'm also seeing some other issues which I need to debug I will
> do so tomorrow morning so you may want to wait a bit with v4.

Np. Take your time. And thanks for testing these.


Cheers,
diff mbox series

Patch

diff --git a/drivers/usb/common/roles.c b/drivers/usb/common/roles.c
index 15cc76e22123..3d8a776e55ee 100644
--- a/drivers/usb/common/roles.c
+++ b/drivers/usb/common/roles.c
@@ -109,8 +109,15 @@  static void *usb_role_switch_match(struct device_connection *con, int ep,
  */
 struct usb_role_switch *usb_role_switch_get(struct device *dev)
 {
-	return device_connection_find_match(dev, "usb-role-switch", NULL,
-					    usb_role_switch_match);
+	struct usb_role_switch *sw;
+
+	sw = device_connection_find_match(dev, "usb-role-switch", NULL,
+					  usb_role_switch_match);
+
+	if (!IS_ERR(sw))
+		WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
+
+	return sw;
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get);
 
@@ -122,8 +129,10 @@  EXPORT_SYMBOL_GPL(usb_role_switch_get);
  */
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
-	if (!IS_ERR_OR_NULL(sw))
+	if (!IS_ERR_OR_NULL(sw)) {
 		put_device(&sw->dev);
+		module_put(sw->dev.parent->driver->owner);
+	}
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);