linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] regulator: core: Request GPIO before creating sysfs entries
@ 2016-02-22  8:24 Krzysztof Adamski
       [not found] ` <56CC5D1E.6010101@nvidia.com>
  0 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-22  8:24 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, linux-kernel; +Cc: Krzysztof Adamski

regulator_attr_is_visible (which is a .is_visible callback of
regulator_dev_group attribute_grpup) checks rdev->ena_pin to decide if
"status" file should be present in sysfs. This field is set at the end
of regulator_ena_gpio_request so it has to be called before
device_register() otherwise this test will always fail, causing "status"
file to not be visible.

Since regulator_attr_is_visible also tests for is_enabled() op, this
problem is only visible for regulators that does not define this
callback, like regulator-fixed.c.

Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
---
 drivers/regulator/core.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 4405be1..6ee9ba4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3913,6 +3913,16 @@ regulator_register(const struct regulator_desc *regulator_desc,
 			goto clean;
 	}
 
+	if ((config->ena_gpio || config->ena_gpio_initialized) &&
+	    gpio_is_valid(config->ena_gpio)) {
+		ret = regulator_ena_gpio_request(rdev, config);
+		if (ret != 0) {
+			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
+				 config->ena_gpio, ret);
+			goto wash;
+		}
+	}
+
 	/* register with sysfs */
 	rdev->dev.class = &regulator_class;
 	rdev->dev.parent = dev;
@@ -3926,16 +3936,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
 
 	dev_set_drvdata(&rdev->dev, rdev);
 
-	if ((config->ena_gpio || config->ena_gpio_initialized) &&
-	    gpio_is_valid(config->ena_gpio)) {
-		ret = regulator_ena_gpio_request(rdev, config);
-		if (ret != 0) {
-			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
-				 config->ena_gpio, ret);
-			goto wash;
-		}
-	}
-
 	/* set regulator constraints */
 	if (init_data)
 		constraints = &init_data->constraints;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: regulator: core: Request GPIO before creating sysfs entries
       [not found]   ` <20160223135650.GA19954@box2.japko.eu>
@ 2016-02-23 14:15     ` Jon Hunter
  2016-02-23 14:34       ` Krzysztof Adamski
  2016-02-23 14:47       ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Krzysztof Adamski
  0 siblings, 2 replies; 12+ messages in thread
From: Jon Hunter @ 2016-02-23 14:15 UTC (permalink / raw)
  To: Krzysztof Adamski
  Cc: Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List

Hi Krzysztof,

On 23/02/16 13:56, Krzysztof Adamski wrote:
> On Tue, Feb 23, 2016 at 01:22:38PM +0000, Jon Hunter wrote:
>> Hi Mark, Krzysztof,
>>
>> It appears that commit daad134d6649 ("regulator: core: Request GPIO
>> before creating sysfs entries") breaks boot on tegra124-nyan-big in
>> -next today.
>>
>> Looking at the change, it does not appear that the exit path has been
>> updated correctly and so if a regulator is deferred then there is a
>> crash in the exit path. I am not sure that there is a simple way to
>> workaround this because of fix from commit 53032dafc6b9 ("regulator
>> core: fix double-free in regulator_register() error path") unless we
>> move regulator_ena_gpio_free() into regulator_dev_release().
> 
> Hi Jon,
> 
> You are totally right about the problem but I can't see why changing
> "goto wash" to "goto clean" in error path of regulator_ena_gpio_request
> is not enough. What am I missing?

So device_unregister() will call regulator_dev_release() which will free
rdev (see commit 53032dafc6b9). However, rdev is needed by
regulator_ena_gpio_free() and therefore, we need to call
regulator_ena_gpio_free() before we call device_unregister(). So
swapping the order will cause other problems.

One possibility would be to move regulator_ena_gpio_free() into
regulator_dev_release(). If did we could remove the
regulator_ena_gpio_free() from regulator_unregister(). However, I have
not looked at that in great detail. May be Mark can comment if that
would be ok.

Cheers
Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: regulator: core: Request GPIO before creating sysfs entries
  2016-02-23 14:15     ` Jon Hunter
@ 2016-02-23 14:34       ` Krzysztof Adamski
  2016-02-23 14:47       ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Krzysztof Adamski
  1 sibling, 0 replies; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-23 14:34 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List

On Tue, Feb 23, 2016 at 02:15:21PM +0000, Jon Hunter wrote:
>Hi Krzysztof,
>
>On 23/02/16 13:56, Krzysztof Adamski wrote:
>> On Tue, Feb 23, 2016 at 01:22:38PM +0000, Jon Hunter wrote:
>>> Hi Mark, Krzysztof,
>>>
>>> It appears that commit daad134d6649 ("regulator: core: Request GPIO
>>> before creating sysfs entries") breaks boot on tegra124-nyan-big in
>>> -next today.
>>>
>>> Looking at the change, it does not appear that the exit path has been
>>> updated correctly and so if a regulator is deferred then there is a
>>> crash in the exit path. I am not sure that there is a simple way to
>>> workaround this because of fix from commit 53032dafc6b9 ("regulator
>>> core: fix double-free in regulator_register() error path") unless we
>>> move regulator_ena_gpio_free() into regulator_dev_release().
>>
>> Hi Jon,
>>
>> You are totally right about the problem but I can't see why changing
>> "goto wash" to "goto clean" in error path of regulator_ena_gpio_request
>> is not enough. What am I missing?
>
>So device_unregister() will call regulator_dev_release() which will free
>rdev (see commit 53032dafc6b9). However, rdev is needed by
>regulator_ena_gpio_free() and therefore, we need to call
>regulator_ena_gpio_free() before we call device_unregister(). So
>swapping the order will cause other problems.
>
>One possibility would be to move regulator_ena_gpio_free() into
>regulator_dev_release(). If did we could remove the
>regulator_ena_gpio_free() from regulator_unregister(). However, I have
>not looked at that in great detail. May be Mark can comment if that
>would be ok.

But in case of regulator_ena_gpio_free() failure, we shouldn't call 
device_unregister() at all, since it was not yet registered and that is 
exactly what "clean" does.

Best regards,
Krzysztof Adamski

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-23 14:15     ` Jon Hunter
  2016-02-23 14:34       ` Krzysztof Adamski
@ 2016-02-23 14:47       ` Krzysztof Adamski
  2016-02-23 15:18         ` Jon Hunter
  1 sibling, 1 reply; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-23 14:47 UTC (permalink / raw)
  To: Jon Hunter, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List
  Cc: Krzysztof Adamski

This problem was introduced by:
commit daad134d6649 ("regulator: core: Request GPIO before creating
sysfs entries")

The error path was not updated correctly and in case
regulator_ena_gpio_free failed, device_unregister was called even though
it was not registered yet.

Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
Reported-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/regulator/core.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ee9ba4..d1e7859 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 		if (ret != 0) {
 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
 				 config->ena_gpio, ret);
-			goto wash;
+			goto clean;
 		}
 	}
 
@@ -3942,7 +3942,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 
 	ret = set_machine_constraints(rdev, constraints);
 	if (ret < 0)
-		goto scrub;
+		goto wash;
 
 	if (init_data && init_data->supply_regulator)
 		rdev->supply_name = init_data->supply_regulator;
@@ -3972,10 +3972,8 @@ out:
 unset_supplies:
 	unset_regulator_supplies(rdev);
 
-scrub:
-	regulator_ena_gpio_free(rdev);
-
 wash:
+	regulator_ena_gpio_free(rdev);
 	device_unregister(&rdev->dev);
 	/* device core frees rdev */
 	rdev = ERR_PTR(ret);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-23 14:47       ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Krzysztof Adamski
@ 2016-02-23 15:18         ` Jon Hunter
  2016-02-24  8:26           ` Krzysztof Adamski
  2016-02-24  8:27           ` Krzysztof Adamski
  0 siblings, 2 replies; 12+ messages in thread
From: Jon Hunter @ 2016-02-23 15:18 UTC (permalink / raw)
  To: Krzysztof Adamski, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List


On 23/02/16 14:47, Krzysztof Adamski wrote:
> This problem was introduced by:
> commit daad134d6649 ("regulator: core: Request GPIO before creating
> sysfs entries")
> 
> The error path was not updated correctly and in case
> regulator_ena_gpio_free failed, device_unregister was called even though
> it was not registered yet.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
> Reported-by: Jon Hunter <jonathanh@nvidia.com>

Nit ... I think that order of the above should be reversed.

> ---
>  drivers/regulator/core.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 6ee9ba4..d1e7859 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>  		if (ret != 0) {
>  			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
>  				 config->ena_gpio, ret);
> -			goto wash;
> +			goto clean;
>  		}
>  	}
>  
> @@ -3942,7 +3942,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>  
>  	ret = set_machine_constraints(rdev, constraints);
>  	if (ret < 0)
> -		goto scrub;
> +		goto wash;
>  
>  	if (init_data && init_data->supply_regulator)
>  		rdev->supply_name = init_data->supply_regulator;
> @@ -3972,10 +3972,8 @@ out:
>  unset_supplies:
>  	unset_regulator_supplies(rdev);
>  
> -scrub:
> -	regulator_ena_gpio_free(rdev);
> -
>  wash:
> +	regulator_ena_gpio_free(rdev);
>  	device_unregister(&rdev->dev);
>  	/* device core frees rdev */
>  	rdev = ERR_PTR(ret);

What about the case where device_register() fails? I think you still
call clean and so you will leak the gpio?

Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-23 15:18         ` Jon Hunter
@ 2016-02-24  8:26           ` Krzysztof Adamski
  2016-02-24  9:03             ` Jon Hunter
  2016-02-24  8:27           ` Krzysztof Adamski
  1 sibling, 1 reply; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-24  8:26 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List

On Tue, Feb 23, 2016 at 03:18:59PM +0000, Jon Hunter wrote:
>
>On 23/02/16 14:47, Krzysztof Adamski wrote:
>> Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
>> Reported-by: Jon Hunter <jonathanh@nvidia.com>
>
>Nit ... I think that order of the above should be reversed.
>

Couldn't find any reference stating proper order of those tags and 
briefly looking at other commit messages shows this order as quite 
common.

>> ---
>>  drivers/regulator/core.c | 8 +++-----
>>  1 file changed, 3 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>> index 6ee9ba4..d1e7859 100644
>> --- a/drivers/regulator/core.c
>> +++ b/drivers/regulator/core.c
>> @@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>>  		if (ret != 0) {
>>  			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
>>  				 config->ena_gpio, ret);
>> -			goto wash;
>> +			goto clean;
>>  		}
>>  	}
>>
>> @@ -3942,7 +3942,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>>
>>  	ret = set_machine_constraints(rdev, constraints);
>>  	if (ret < 0)
>> -		goto scrub;
>> +		goto wash;
>>
>>  	if (init_data && init_data->supply_regulator)
>>  		rdev->supply_name = init_data->supply_regulator;
>> @@ -3972,10 +3972,8 @@ out:
>>  unset_supplies:
>>  	unset_regulator_supplies(rdev);
>>
>> -scrub:
>> -	regulator_ena_gpio_free(rdev);
>> -
>>  wash:
>> +	regulator_ena_gpio_free(rdev);
>>  	device_unregister(&rdev->dev);
>>  	/* device core frees rdev */
>>  	rdev = ERR_PTR(ret);
>
>What about the case where device_register() fails? I think you still
>call clean and so you will leak the gpio?
>
>Jon
>
True. I couldn't find anything more clever than calling 
regulator_ena_gpio_free() in two paths like in an upcomming v2. Putting 
it inside of regulator_dev_release() won't entirely fix the problem 
either as this won't be called in this particular case 
(device_register() fail). I personally still prefer calling 
regulator_ena_gpio_free() inside of regulator_register insted of 
deffering it to regulator_dev_release() as it seems to be clearer to me.

Best regards,
Krzysztof Adamski

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-23 15:18         ` Jon Hunter
  2016-02-24  8:26           ` Krzysztof Adamski
@ 2016-02-24  8:27           ` Krzysztof Adamski
  2016-02-24  9:18             ` Jon Hunter
  2016-02-24  9:20             ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Jon Hunter
  1 sibling, 2 replies; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-24  8:27 UTC (permalink / raw)
  To: Jon Hunter, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List
  Cc: Krzysztof Adamski

This problem was introduced by:
commit daad134d6649 ("regulator: core: Request GPIO before creating
sysfs entries")

The error path was not updated correctly and in case
regulator_ena_gpio_free failed, device_unregister was called even though
it was not registered yet.

Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
Reported-by: Jon Hunter <jonathanh@nvidia.com>
---
 drivers/regulator/core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ee9ba4..055f8c1 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 		if (ret != 0) {
 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
 				 config->ena_gpio, ret);
-			goto wash;
+			goto clean;
 		}
 	}
 
@@ -3931,7 +3931,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 	ret = device_register(&rdev->dev);
 	if (ret != 0) {
 		put_device(&rdev->dev);
-		goto clean;
+		goto wash;
 	}
 
 	dev_set_drvdata(&rdev->dev, rdev);
@@ -3974,13 +3974,13 @@ unset_supplies:
 
 scrub:
 	regulator_ena_gpio_free(rdev);
-
-wash:
 	device_unregister(&rdev->dev);
 	/* device core frees rdev */
 	rdev = ERR_PTR(ret);
 	goto out;
 
+wash:
+	regulator_ena_gpio_free(rdev);
 clean:
 	kfree(rdev);
 	rdev = ERR_PTR(ret);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-24  8:26           ` Krzysztof Adamski
@ 2016-02-24  9:03             ` Jon Hunter
  0 siblings, 0 replies; 12+ messages in thread
From: Jon Hunter @ 2016-02-24  9:03 UTC (permalink / raw)
  To: Krzysztof Adamski
  Cc: Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List


On 24/02/16 08:26, Krzysztof Adamski wrote:
> On Tue, Feb 23, 2016 at 03:18:59PM +0000, Jon Hunter wrote:
>>
>> On 23/02/16 14:47, Krzysztof Adamski wrote:
>>> Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
>>> Reported-by: Jon Hunter <jonathanh@nvidia.com>
>>
>> Nit ... I think that order of the above should be reversed.
>>
> 
> Couldn't find any reference stating proper order of those tags and
> briefly looking at other commit messages shows this order as quite common.
> 
>>> ---
>>>  drivers/regulator/core.c | 8 +++-----
>>>  1 file changed, 3 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
>>> index 6ee9ba4..d1e7859 100644
>>> --- a/drivers/regulator/core.c
>>> +++ b/drivers/regulator/core.c
>>> @@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc
>>> *regulator_desc,
>>>          if (ret != 0) {
>>>              rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
>>>                   config->ena_gpio, ret);
>>> -            goto wash;
>>> +            goto clean;
>>>          }
>>>      }
>>>
>>> @@ -3942,7 +3942,7 @@ regulator_register(const struct regulator_desc
>>> *regulator_desc,
>>>
>>>      ret = set_machine_constraints(rdev, constraints);
>>>      if (ret < 0)
>>> -        goto scrub;
>>> +        goto wash;
>>>
>>>      if (init_data && init_data->supply_regulator)
>>>          rdev->supply_name = init_data->supply_regulator;
>>> @@ -3972,10 +3972,8 @@ out:
>>>  unset_supplies:
>>>      unset_regulator_supplies(rdev);
>>>
>>> -scrub:
>>> -    regulator_ena_gpio_free(rdev);
>>> -
>>>  wash:
>>> +    regulator_ena_gpio_free(rdev);
>>>      device_unregister(&rdev->dev);
>>>      /* device core frees rdev */
>>>      rdev = ERR_PTR(ret);
>>
>> What about the case where device_register() fails? I think you still
>> call clean and so you will leak the gpio?
>>
>> Jon
>>
> True. I couldn't find anything more clever than calling
> regulator_ena_gpio_free() in two paths like in an upcomming v2. Putting
> it inside of regulator_dev_release() won't entirely fix the problem
> either as this won't be called in this particular case
> (device_register() fail). I personally still prefer calling
> regulator_ena_gpio_free() inside of regulator_register insted of
> deffering it to regulator_dev_release() as it seems to be clearer to me.

Yes if you were to put regulator_ena_gpio_free() inside the
regulator_dev_release(), you would still need to call
regulator_ena_gpio_free() if the device_register fails. I see the way
you have it now there are two places you call regulator_ena_gpio_free()
in the error path. It is not a big deal, really either way.

Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-24  8:27           ` Krzysztof Adamski
@ 2016-02-24  9:18             ` Jon Hunter
  2016-02-24 10:52               ` [PATCH v3] regulator: core: fix crash in error path of regulator_register Krzysztof Adamski
  2016-02-24  9:20             ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Jon Hunter
  1 sibling, 1 reply; 12+ messages in thread
From: Jon Hunter @ 2016-02-24  9:18 UTC (permalink / raw)
  To: Krzysztof Adamski, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List


On 24/02/16 08:27, Krzysztof Adamski wrote:
> This problem was introduced by:
> commit daad134d6649 ("regulator: core: Request GPIO before creating
> sysfs entries")

I think you need to be more specific about what the "problem" is. The
subject does not really explain it either. I would suggest you change
the subject to "fix crash in error path of regulator_register()" as
it is not really regulator_ena_gpio_free() that is a problem.

I would like to point out that this problem breaks the boot on all 
Tegra 32-bit devices because it is quite common for the regulator
registration to be deferred on boot and this will trigger a crash.
So it is very common and I am not sure what other platforms are
impacted by this. Therefore, it would be good to get this fixed soon.

Mark mentioned included a boot log of the crash. Here is one from
Tegra124-TK1, but unfortunately, it is not too useful, although the
crash does happen right after the regulator registration deferral.
Nonetheless I have bisected the kernel and found the commit that was
responsible and verified that reverting it fixes the crash.


[    0.505924] +USB0_VBUS_SW: Failed to request enable GPIO108: -517
[    0.510196] Unable to handle kernel NULL pointer dereference at virtual address 00000044
[    0.518360] pgd = c0004000
[    0.521108] [00000044] *pgd=00000000
[    0.524752] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[    0.530121] Modules linked in:
[    0.533247] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.5.0-rc5-next-20160224-75670-g96aa086 #1
[    0.541995] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[    0.548322] task: ee85b380 ti: ee85c000 task.ti: ee85c000
[    0.553786] PC is at kernfs_find_ns+0x8/0xf4
[    0.558117] LR is at kernfs_find_and_get_ns+0x30/0x48
[    0.563232] pc : [<c024afe8>]    lr : [<c024b1a4>]    psr: 60000013
[    0.563232] sp : ee85dd4c  ip : 00000001  fp : c0c1857c
[    0.574842] r10: eefeca70  r9 : c0b3b83c  r8 : ee9cdc60
[    0.580129] r7 : c0857730  r6 : 00000000  r5 : 00000000  r4 : c0c10718
[    0.586715] r3 : ee85b380  r2 : 00000000  r1 : c0857730  r0 : 00000000
[    0.593304] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    0.600496] Control: 10c5387d  Table: 8000406a  DAC: 00000051
[    0.606302] Process swapper/0 (pid: 1, stack limit = 0xee85c210)
[    0.612369] Stack: (0xee85dd4c to 0xee85e000)
[    0.616792] dd40:                            c0c10718 00000000 00000000 c0857730 c024b1a4
[    0.625027] dd60: 00000000 c0c2654c ee9cdc68 ee9cdc60 ee9926d0 c024df1c 00000000 c0c26510
[    0.633260] dd80: ee9cdc68 c0439938 ee9cdc60 ee9cdc60 00000000 c042f9d0 00000000 c01a927c
[    0.641493] dda0: 00000008 ee9926d0 ee9c9490 ee9cdc60 fffffdfb c0c18730 ee9926d0 c042fb80
[    0.649727] ddc0: ee99dc10 c03abe90 00000002 ee9a0210 ee9ccb50 ee800000 c03add80 ee9c9bc0
[    0.657960] dde0: ee9cdc60 00000001 eefeca70 c01eb2f8 ee85de34 ee85de34 ee9c9410 ee9a0210
[    0.666193] de00: ee99dc10 ee9a0200 c0b3b83c eefeca70 00000000 c03add98 ee9ccb50 ee9c94d0
[    0.674426] de20: ee99dc10 00000000 ee9a0210 c03aebb4 00000000 ee9a0210 ee9ccb50 ee99dc10
[    0.682660] de40: eefeca70 00000000 00000001 0000006c 00000000 00000008 ee9a0210 fffffffe
[    0.690893] de60: ee9a0210 fffffdfb c0c188b8 c0c188b8 00000000 c0434080 c0434030 ee9a0210
[    0.699126] de80: c0caa264 c0caa26c 00000000 c0432aac 00000000 ee9a0210 c0c188b8 ee9a0244
[    0.707360] dea0: 00000000 c0b1bc2c 00000000 c0432c14 00000000 c0c188b8 c0432b68 c04310d0
[    0.715593] dec0: ee81a55c ee997b34 c0c188b8 ee9c6700 c0c25f68 c04320a0 c09cc320 c0c188b8
[    0.723826] dee0: c0c065c8 c0c188b8 c0c065c8 ee9bbdc0 c0c60000 c0433410 c0433d14 c0c065c8
[    0.732059] df00: c0c065c8 c0101768 c0802898 00000014 00000000 00000000 c0c0c400 c0c0c488
[    0.740293] df20: 00000000 c0c0a998 efffcc66 c0820554 00000101 c01378d4 00000000 c099ce50
[    0.748526] df40: c0a70794 00000000 00000004 00000004 c0c0a960 efffcc00 c0b4f748 00000004
[    0.756760] df60: c0b3b828 c0c60000 00000101 c0b3b83c c0b00598 c0b00dd8 00000004 00000004
[    0.764993] df80: 00000000 c0b00598 00000000 c07d4ec8 00000000 00000000 00000000 00000000
[    0.773226] dfa0: 00000000 c07d4ed0 00000000 c0107938 00000000 00000000 00000000 00000000
[    0.781459] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.789693] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 dfffffff ffffbfff
[    0.797933] [<c024afe8>] (kernfs_find_ns) from [<ee9cdc68>] (0xee9cdc68)
[    0.804687] Code: e5832028 e8bd8038 e92d40f0 e1a06002 (e1d024b4) 
[    0.810868] ---[ end trace 7d0e5449506e9287 ]---

 
> The error path was not updated correctly and in case
> regulator_ena_gpio_free failed, device_unregister was called even though
> it was not registered yet.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
> Reported-by: Jon Hunter <jonathanh@nvidia.com>
> ---
>  drivers/regulator/core.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index 6ee9ba4..055f8c1 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>  		if (ret != 0) {
>  			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
>  				 config->ena_gpio, ret);
> -			goto wash;
> +			goto clean;
>  		}
>  	}
>  
> @@ -3931,7 +3931,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
>  	ret = device_register(&rdev->dev);
>  	if (ret != 0) {
>  		put_device(&rdev->dev);
> -		goto clean;
> +		goto wash;
>  	}
>  
>  	dev_set_drvdata(&rdev->dev, rdev);
> @@ -3974,13 +3974,13 @@ unset_supplies:
>  
>  scrub:
>  	regulator_ena_gpio_free(rdev);
> -
> -wash:
>  	device_unregister(&rdev->dev);
>  	/* device core frees rdev */
>  	rdev = ERR_PTR(ret);
>  	goto out;
>  
> +wash:
> +	regulator_ena_gpio_free(rdev);
>  clean:
>  	kfree(rdev);
>  	rdev = ERR_PTR(ret);
> 

Otherwise ...

Acked-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>

Cheers
Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-24  8:27           ` Krzysztof Adamski
  2016-02-24  9:18             ` Jon Hunter
@ 2016-02-24  9:20             ` Jon Hunter
  2016-02-25  1:46               ` Mark Brown
  1 sibling, 1 reply; 12+ messages in thread
From: Jon Hunter @ 2016-02-24  9:20 UTC (permalink / raw)
  To: Krzysztof Adamski, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List


On 24/02/16 08:27, Krzysztof Adamski wrote:
> This problem was introduced by:
> commit daad134d6649 ("regulator: core: Request GPIO before creating
> sysfs entries")
> 
> The error path was not updated correctly and in case
> regulator_ena_gpio_free failed, device_unregister was called even though
> it was not registered yet.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
> Reported-by: Jon Hunter <jonathanh@nvidia.com>

Make sure you tag the patch as V2, etc, so that Mark knows which version
to pick up.

Jon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3] regulator: core: fix crash in error path of regulator_register
  2016-02-24  9:18             ` Jon Hunter
@ 2016-02-24 10:52               ` Krzysztof Adamski
  0 siblings, 0 replies; 12+ messages in thread
From: Krzysztof Adamski @ 2016-02-24 10:52 UTC (permalink / raw)
  To: Jon Hunter, Mark Brown, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List
  Cc: Krzysztof Adamski

This problem was introduced by:
commit daad134d6649 ("regulator: core: Request GPIO before creating
sysfs entries")

The error path was not updated correctly after moving GPIO registration
code and in case regulator_ena_gpio_free failed, device_unregister() was
called even though device_register() was not yet called.

This problem breaks the boot at least on all Tegra 32-bit devices. It
will also crash each device that specifices GPIO that is unavaiable at
regulator_register call. Here's error log I've got when forced GPIO to
be invalid:

[    1.116612] usb-otg-vbus-reg: Failed to request enable GPIO10: -22
[    1.122794] Unable to handle kernel NULL pointer dereference at
virtual address 00000044
[    1.130894] pgd = c0004000
[    1.133598] [00000044] *pgd=00000000
[    1.137205] Internal error: Oops: 5 [#1] SMP ARM

and here's backtrace from KDB:

Exception stack(0xef11fbd0 to 0xef11fc18)
fbc0:                                     00000000 c0738a14 00000000 00000000
fbe0: c0b2a0b0 00000000 00000000 c0738a14 c0b5fdf8 00000001 ef7f6074 ef11fc4c
fc00: ef11fc50 ef11fc20 c02a8344 c02a7f1c 60000013 ffffffff
[<c010cee0>] (__dabt_svc) from [<c02a7f1c>] (kernfs_find_ns+0x18/0xf8)
[<c02a7f1c>] (kernfs_find_ns) from [<c02a8344>] (kernfs_find_and_get_ns+0x40/0x58)
[<c02a8344>] (kernfs_find_and_get_ns) from [<c02ac4a4>] (sysfs_unmerge_group+0x28/0x68)
[<c02ac4a4>] (sysfs_unmerge_group) from [<c044389c>] (dpm_sysfs_remove+0x30/0x5c)
[<c044389c>] (dpm_sysfs_remove) from [<c0436ba8>] (device_del+0x48/0x1f4)
[<c0436ba8>] (device_del) from [<c0436d84>] (device_unregister+0x30/0x6c)
[<c0436d84>] (device_unregister) from [<c0403910>] (regulator_register+0x6d0/0xdac)
[<c0403910>] (regulator_register) from [<c04052d4>] (devm_regulator_register+0x50/0x84)
[<c04052d4>] (devm_regulator_register) from [<c0406298>] (reg_fixed_voltage_probe+0x25c/0x3c0)
[<c0406298>] (reg_fixed_voltage_probe) from [<c043d21c>] (platform_drv_probe+0x60/0xb0)
[<c043d21c>] (platform_drv_probe) from [<c043b078>] (driver_probe_device+0x24c/0x440)
[<c043b078>] (driver_probe_device) from [<c043b5e8>] (__device_attach_driver+0xc0/0x120)
[<c043b5e8>] (__device_attach_driver) from [<c043901c>] (bus_for_each_drv+0x6c/0x98)
[<c043901c>] (bus_for_each_drv) from [<c043ad20>] (__device_attach+0xac/0x138)
[<c043ad20>] (__device_attach) from [<c043b664>] (device_initial_probe+0x1c/0x20)
[<c043b664>] (device_initial_probe) from [<c043a074>] (bus_probe_device+0x94/0x9c)
[<c043a074>] (bus_probe_device) from [<c043a610>] (deferred_probe_work_func+0x80/0xcc)
[<c043a610>] (deferred_probe_work_func) from [<c01381d0>] (process_one_work+0x158/0x454)
[<c01381d0>] (process_one_work) from [<c013854c>] (worker_thread+0x38/0x510)
[<c013854c>] (worker_thread) from [<c013e154>] (kthread+0xe8/0x104)
[<c013e154>] (kthread) from [<c0108638>] (ret_from_fork+0x14/0x3c)

Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
Reported-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
---

Changes compared to v2:
- Extended commit message

Changes compared to v1:
- Fixed error path of device_register too, as noticed by Jon


 drivers/regulator/core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ee9ba4..055f8c1 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3919,7 +3919,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 		if (ret != 0) {
 			rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
 				 config->ena_gpio, ret);
-			goto wash;
+			goto clean;
 		}
 	}
 
@@ -3931,7 +3931,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 	ret = device_register(&rdev->dev);
 	if (ret != 0) {
 		put_device(&rdev->dev);
-		goto clean;
+		goto wash;
 	}
 
 	dev_set_drvdata(&rdev->dev, rdev);
@@ -3974,13 +3974,13 @@ unset_supplies:
 
 scrub:
 	regulator_ena_gpio_free(rdev);
-
-wash:
 	device_unregister(&rdev->dev);
 	/* device core frees rdev */
 	rdev = ERR_PTR(ret);
 	goto out;
 
+wash:
+	regulator_ena_gpio_free(rdev);
 clean:
 	kfree(rdev);
 	rdev = ERR_PTR(ret);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] regulator: core: fix error path of regulator_ena_gpio_free
  2016-02-24  9:20             ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Jon Hunter
@ 2016-02-25  1:46               ` Mark Brown
  0 siblings, 0 replies; 12+ messages in thread
From: Mark Brown @ 2016-02-25  1:46 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Krzysztof Adamski, linux-tegra@vger.kernel.org,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 352 bytes --]

On Wed, Feb 24, 2016 at 09:20:19AM +0000, Jon Hunter wrote:

> Make sure you tag the patch as V2, etc, so that Mark knows which version
> to pick up.

Versioning is nice but not totally essential.  What really helps is not
burying new patches in the middle of threads, especially if it's a
multi-patch series (not the case here but people do do that).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-02-25  1:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-22  8:24 [PATCH] regulator: core: Request GPIO before creating sysfs entries Krzysztof Adamski
     [not found] ` <56CC5D1E.6010101@nvidia.com>
     [not found]   ` <20160223135650.GA19954@box2.japko.eu>
2016-02-23 14:15     ` Jon Hunter
2016-02-23 14:34       ` Krzysztof Adamski
2016-02-23 14:47       ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Krzysztof Adamski
2016-02-23 15:18         ` Jon Hunter
2016-02-24  8:26           ` Krzysztof Adamski
2016-02-24  9:03             ` Jon Hunter
2016-02-24  8:27           ` Krzysztof Adamski
2016-02-24  9:18             ` Jon Hunter
2016-02-24 10:52               ` [PATCH v3] regulator: core: fix crash in error path of regulator_register Krzysztof Adamski
2016-02-24  9:20             ` [PATCH] regulator: core: fix error path of regulator_ena_gpio_free Jon Hunter
2016-02-25  1:46               ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).