Message ID | 20201022184100.71659-2-andriy.shevchenko@linux.intel.com |
---|---|
State | Accepted |
Commit | 99aed9227073fb34ce2880cbc7063e04185a65e1 |
Headers | show |
Series | None | expand |
On Thu, Oct 22, 2020 at 09:41:00PM +0300, Andy Shevchenko wrote: > It appears that firmware nodes can be shared between devices. In such case > when a (child) device is about to be deleted, its firmware node may be shared > and ACPI_COMPANION_SET(..., NULL) call for it breaks the secondary link > of the shared primary firmware node. > > In order to prevent that, check, if the device has a parent and parent's > firmware node is shared with its child, and avoid crashing the link. > > Fixes: c15e1bdda436 ("device property: Fix the secondary firmware node handling in set_primary_fwnode()") > Reported-by: Ferry Toth <fntoth@gmail.com> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> FWIW: Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/base/core.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/base/core.c b/drivers/base/core.c > index 41feab679fa1..78114ddac755 100644 > --- a/drivers/base/core.c > +++ b/drivers/base/core.c > @@ -4264,6 +4264,7 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) > */ > void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) > { > + struct device *parent = dev->parent; > struct fwnode_handle *fn = dev->fwnode; > > if (fwnode) { > @@ -4278,7 +4279,8 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) > } else { > if (fwnode_is_primary(fn)) { > dev->fwnode = fn->secondary; > - fn->secondary = ERR_PTR(-ENODEV); > + if (!(parent && fn == parent->fwnode)) > + fn->secondary = ERR_PTR(-ENODEV); > } else { > dev->fwnode = NULL; > } > -- > 2.28.0
Hi Op 23-10-2020 om 14:35 schreef Heikki Krogerus: > On Thu, Oct 22, 2020 at 09:41:00PM +0300, Andy Shevchenko wrote: >> It appears that firmware nodes can be shared between devices. In such case >> when a (child) device is about to be deleted, its firmware node may be shared >> and ACPI_COMPANION_SET(..., NULL) call for it breaks the secondary link >> of the shared primary firmware node. >> >> In order to prevent that, check, if the device has a parent and parent's >> firmware node is shared with its child, and avoid crashing the link. >> >> Fixes: c15e1bdda436 ("device property: Fix the secondary firmware node handling in set_primary_fwnode()") >> Reported-by: Ferry Toth <fntoth@gmail.com> >> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > FWIW: > > Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Tested-by: Ferry Toth <fntoth@gmail.com> >> --- >> drivers/base/core.c | 4 +++- >> 1 file changed, 3 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/base/core.c b/drivers/base/core.c >> index 41feab679fa1..78114ddac755 100644 >> --- a/drivers/base/core.c >> +++ b/drivers/base/core.c >> @@ -4264,6 +4264,7 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) >> */ >> void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) >> { >> + struct device *parent = dev->parent; >> struct fwnode_handle *fn = dev->fwnode; >> >> if (fwnode) { >> @@ -4278,7 +4279,8 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) >> } else { >> if (fwnode_is_primary(fn)) { >> dev->fwnode = fn->secondary; >> - fn->secondary = ERR_PTR(-ENODEV); >> + if (!(parent && fn == parent->fwnode)) >> + fn->secondary = ERR_PTR(-ENODEV); >> } else { >> dev->fwnode = NULL; >> } >> -- >> 2.28.0
Hi Op 23-10-2020 om 14:35 schreef Heikki Krogerus: > On Thu, Oct 22, 2020 at 09:41:00PM +0300, Andy Shevchenko wrote: >> It appears that firmware nodes can be shared between devices. In such >> case >> when a (child) device is about to be deleted, its firmware node may >> be shared >> and ACPI_COMPANION_SET(..., NULL) call for it breaks the secondary link >> of the shared primary firmware node. >> >> In order to prevent that, check, if the device has a parent and parent's >> firmware node is shared with its child, and avoid crashing the link. >> >> Fixes: c15e1bdda436 ("device property: Fix the secondary firmware >> node handling in set_primary_fwnode()") >> Reported-by: Ferry Toth <fntoth@gmail.com> >> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > FWIW: > > Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Tested-by: Ferry Toth <fntoth@gmail.com> >> --- >> drivers/base/core.c | 4 +++- >> 1 file changed, 3 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/base/core.c b/drivers/base/core.c >> index 41feab679fa1..78114ddac755 100644 >> --- a/drivers/base/core.c >> +++ b/drivers/base/core.c >> @@ -4264,6 +4264,7 @@ static inline bool fwnode_is_primary(struct >> fwnode_handle *fwnode) >> */ >> void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) >> { >> + struct device *parent = dev->parent; >> struct fwnode_handle *fn = dev->fwnode; >> if (fwnode) { >> @@ -4278,7 +4279,8 @@ void set_primary_fwnode(struct device *dev, >> struct fwnode_handle *fwnode) >> } else { >> if (fwnode_is_primary(fn)) { >> dev->fwnode = fn->secondary; >> - fn->secondary = ERR_PTR(-ENODEV); >> + if (!(parent && fn == parent->fwnode)) >> + fn->secondary = ERR_PTR(-ENODEV); >> } else { >> dev->fwnode = NULL; >> } >> -- 2.28.0
diff --git a/drivers/base/core.c b/drivers/base/core.c index 41feab679fa1..78114ddac755 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -4264,6 +4264,7 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) */ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) { + struct device *parent = dev->parent; struct fwnode_handle *fn = dev->fwnode; if (fwnode) { @@ -4278,7 +4279,8 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) } else { if (fwnode_is_primary(fn)) { dev->fwnode = fn->secondary; - fn->secondary = ERR_PTR(-ENODEV); + if (!(parent && fn == parent->fwnode)) + fn->secondary = ERR_PTR(-ENODEV); } else { dev->fwnode = NULL; }
It appears that firmware nodes can be shared between devices. In such case when a (child) device is about to be deleted, its firmware node may be shared and ACPI_COMPANION_SET(..., NULL) call for it breaks the secondary link of the shared primary firmware node. In order to prevent that, check, if the device has a parent and parent's firmware node is shared with its child, and avoid crashing the link. Fixes: c15e1bdda436 ("device property: Fix the secondary firmware node handling in set_primary_fwnode()") Reported-by: Ferry Toth <fntoth@gmail.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> --- drivers/base/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)