Re: [PATCH v1 2/2] device property: Don't clear secondary pointer for shared primary firmware node
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 Signed-off-by: Andy Shevchenko FWIW: Reviewed-by: Heikki Krogerus Tested-by: Ferry Toth --- 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
Re: [PATCH v1 2/2] device property: Don't clear secondary pointer for shared primary firmware node
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 Signed-off-by: Andy Shevchenko FWIW: Reviewed-by: Heikki Krogerus Tested-by: Ferry Toth --- 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
Re: [PATCH v1 2/2] device property: Don't clear secondary pointer for shared primary firmware node
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 > Signed-off-by: Andy Shevchenko FWIW: Reviewed-by: Heikki Krogerus > --- > 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 -- heikki
[PATCH v1 2/2] device property: Don't clear secondary pointer for shared primary firmware node
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 Signed-off-by: Andy Shevchenko --- 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