* [PATCH] env: Leave invalid env for nowhere location
@ 2021-05-12 14:09 Kunihiko Hayashi
2021-05-16 17:19 ` Marek Vasut
2021-05-25 7:35 ` Marek Vasut
0 siblings, 2 replies; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-05-12 14:09 UTC (permalink / raw)
To: u-boot
When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
to gd->env_valid, and sets default_environment before relocation to
gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
by the previous fix.
If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
default_environment, however, env_get_char() returns gd->env_addr before
relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
will cause a fault.
This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
Cc: Marek Vasut <marex@denx.de>
Fixes: 5557eec01cbf ("env: Fix invalid env handling in env_init()")
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
---
env/env.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/env/env.c b/env/env.c
index e534008..3233172 100644
--- a/env/env.c
+++ b/env/env.c
@@ -336,7 +336,8 @@ int env_init(void)
debug("%s: Environment %s init done (ret=%d)\n", __func__,
drv->name, ret);
- if (gd->env_valid == ENV_INVALID)
+ if (gd->env_valid == ENV_INVALID
+ && drv->location != ENVL_NOWHERE)
ret = -ENOENT;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] env: Leave invalid env for nowhere location
2021-05-12 14:09 [PATCH] env: Leave invalid env for nowhere location Kunihiko Hayashi
@ 2021-05-16 17:19 ` Marek Vasut
2021-05-25 6:30 ` Kunihiko Hayashi
2021-05-25 7:35 ` Marek Vasut
1 sibling, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2021-05-16 17:19 UTC (permalink / raw)
To: u-boot
On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
> to gd->env_valid, and sets default_environment before relocation to
> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
> by the previous fix.
>
> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
> default_environment, however, env_get_char() returns gd->env_addr before
> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
> will cause a fault.
>
> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
>
> Cc: Marek Vasut <marex@denx.de>
> Fixes: 5557eec01cbf ("env: Fix invalid env handling in env_init()")
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
> ---
> env/env.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/env/env.c b/env/env.c
> index e534008..3233172 100644
> --- a/env/env.c
> +++ b/env/env.c
> @@ -336,7 +336,8 @@ int env_init(void)
> debug("%s: Environment %s init done (ret=%d)\n", __func__,
> drv->name, ret);
>
> - if (gd->env_valid == ENV_INVALID)
> + if (gd->env_valid == ENV_INVALID
> + && drv->location != ENVL_NOWHERE)
> ret = -ENOENT;
> }
I'm CCing Tim, it would be good to get a TB from him.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-05-16 17:19 ` Marek Vasut
@ 2021-05-25 6:30 ` Kunihiko Hayashi
0 siblings, 0 replies; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-05-25 6:30 UTC (permalink / raw)
To: Tim Harvey; +Cc: u-boot, Joe Hershberger, Marek Vasut, Masami Hiramatsu
Hi Tim,
How about this fix?
You already tested Marek's patch, and I'd like to hear your comment
about this patch, or know whether it occurs the issue with
CONFIG_ENV_IS_NOWHERE if possible.
Thank you,
On 2021/05/17 2:19, Marek Vasut wrote:
> On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
>> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
>> to gd->env_valid, and sets default_environment before relocation to
>> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
>> by the previous fix.
>>
>> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
>> default_environment, however, env_get_char() returns gd->env_addr before
>> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
>> will cause a fault.
>>
>> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
>>
>> Cc: Marek Vasut <marex@denx.de>
>> Fixes: 5557eec01cbf ("env: Fix invalid env handling in env_init()")
>> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
>> ---
>> env/env.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/env/env.c b/env/env.c
>> index e534008..3233172 100644
>> --- a/env/env.c
>> +++ b/env/env.c
>> @@ -336,7 +336,8 @@ int env_init(void)
>> debug("%s: Environment %s init done (ret=%d)\n", __func__,
>> drv->name, ret);
>>
>> - if (gd->env_valid == ENV_INVALID)
>> + if (gd->env_valid == ENV_INVALID
>> + && drv->location != ENVL_NOWHERE)
>> ret = -ENOENT;
>> }
>
> I'm CCing Tim, it would be good to get a TB from him.
>
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-05-12 14:09 [PATCH] env: Leave invalid env for nowhere location Kunihiko Hayashi
2021-05-16 17:19 ` Marek Vasut
@ 2021-05-25 7:35 ` Marek Vasut
2021-06-03 16:15 ` Kunihiko Hayashi
1 sibling, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2021-05-25 7:35 UTC (permalink / raw)
To: Kunihiko Hayashi; +Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini
On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
> to gd->env_valid, and sets default_environment before relocation to
> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
> by the previous fix.
>
> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
> default_environment, however, env_get_char() returns gd->env_addr before
> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
> will cause a fault.
>
> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
So do I understand this correctly that _after_ relocation, env_init() is
called and env_init() does not update gd->env_addr to the relocated one?
I would expect that after relocation, if all you have is env_nowhere
driver, the env_nowhere_init() is called again from the first for() loop
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
that for() loop would exit with ret = -ENOENT [2], so then the last part
of env_init() would check for ret == -ENOENT and update gd->env_addr to
relocated default_environment [3].
324 int env_init(void)
325 {
326 struct env_driver *drv;
327 int ret = -ENOENT;
328 int prio;
329
330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
/* Part [1] */
331 if (!drv->init || !(ret = drv->init()))
332 env_set_inited(drv->location);
333 if (ret == -ENOENT)
334 env_set_inited(drv->location);
335
336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
337 drv->name, ret);
338
/* Part [2] */
339 if (gd->env_valid == ENV_INVALID)
340 ret = -ENOENT;
341 }
342
343 if (!prio)
344 return -ENODEV;
345
/* Part [3] */
346 if (ret == -ENOENT) {
/* This should be relocated default_environment address */
347 gd->env_addr = (ulong)&default_environment[0];
348 gd->env_valid = ENV_VALID;
349
350 return 0;
351 }
352
353 return ret;
354 }
Or am I missing something obvious ?
> diff --git a/env/env.c b/env/env.c
> index e534008..3233172 100644
> --- a/env/env.c
> +++ b/env/env.c
> @@ -336,7 +336,8 @@ int env_init(void)
> debug("%s: Environment %s init done (ret=%d)\n", __func__,
> drv->name, ret);
>
> - if (gd->env_valid == ENV_INVALID)
> + if (gd->env_valid == ENV_INVALID
> + && drv->location != ENVL_NOWHERE)
> ret = -ENOENT;
> }
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-05-25 7:35 ` Marek Vasut
@ 2021-06-03 16:15 ` Kunihiko Hayashi
2021-06-06 18:08 ` Marek Vasut
0 siblings, 1 reply; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-06-03 16:15 UTC (permalink / raw)
To: Marek Vasut; +Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini
Hi Marek,
Sorry for rate reply.
On 2021/05/25 16:35, Marek Vasut wrote:
> On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
>> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
>> to gd->env_valid, and sets default_environment before relocation to
>> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
>> by the previous fix.
>>
>> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
>> default_environment, however, env_get_char() returns gd->env_addr before
>> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
>> will cause a fault.
>>
>> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
>
> So do I understand this correctly that _after_ relocation, env_init() is
> called and env_init() does not update gd->env_addr to the relocated one?
In my understandings, env_init() belongs to init_sequence_f[]
and env_init() is called before relocation.
> I would expect that after relocation, if all you have is env_nowhere
> driver, the env_nowhere_init() is called again from the first for() loop
> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
> that for() loop would exit with ret = -ENOENT [2], so then the last part
> of env_init() would check for ret == -ENOENT and update gd->env_addr to
> relocated default_environment [3].
>
> 324 int env_init(void)
> 325 {
> 326 struct env_driver *drv;
> 327 int ret = -ENOENT;
> 328 int prio;
> 329
> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
> /* Part [1] */
> 331 if (!drv->init || !(ret = drv->init()))
> 332 env_set_inited(drv->location);
> 333 if (ret == -ENOENT)
> 334 env_set_inited(drv->location);
> 335
> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
> 337 drv->name, ret);
> 338
> /* Part [2] */
> 339 if (gd->env_valid == ENV_INVALID)
> 340 ret = -ENOENT;
> 341 }
> 342
> 343 if (!prio)
> 344 return -ENODEV;
> 345
> /* Part [3] */
> 346 if (ret == -ENOENT) {
> /* This should be relocated default_environment address */
> 347 gd->env_addr = (ulong)&default_environment[0];
> 348 gd->env_valid = ENV_VALID;
> 349
> 350 return 0;
> 351 }
> 352
> 353 return ret;
> 354 }
>
> Or am I missing something obvious ?
These are called before relocation, and update gd->env_addr to non-relocated
default_environment by [3].
After that, gd->env_addr is relocated in initr_reloc_global_data()
if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
| #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
| /*
| * Relocate the early env_addr pointer unless we know it is not inside
| * the binary. Some systems need this and for the rest, it doesn't hurt.
| */
| gd->env_addr += gd->reloc_off;
| #endif
However, I misunderstood my situation.
gd->reloc_off doesn't have the proper value because CONFIG_SYS_TEXT_BASE
is zero due to CONFIG_POSITION_INDENENDENT=y.
gd->reloc_off is calculated with CONFIG_SYS_TEXT_BASE in setup_reloc().
| gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
gd->env_addr is added with gd->reloc_off (== gd->relocaddr - 0),
as a result, gd->env_addr has wrong address.
In this case, I think the proper solution is to undefine
CONFIG_SYS_RELOC_GD_ENV_ADDR.
My patch isn't necessary no longer and your patch also works with
"nowhere".
Thank you,
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-03 16:15 ` Kunihiko Hayashi
@ 2021-06-06 18:08 ` Marek Vasut
2021-06-07 7:54 ` Kunihiko Hayashi
0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2021-06-06 18:08 UTC (permalink / raw)
To: Kunihiko Hayashi; +Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini
On 6/3/21 6:15 PM, Kunihiko Hayashi wrote:
> Hi Marek,
Hi,
> Sorry for rate reply.
No worries, same here.
> On 2021/05/25 16:35, Marek Vasut wrote:
>> On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
>>> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets
>>> ENV_INVALID
>>> to gd->env_valid, and sets default_environment before relocation to
>>> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
>>> by the previous fix.
>>>
>>> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
>>> default_environment, however, env_get_char() returns gd->env_addr before
>>> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
>>> will cause a fault.
>>>
>>> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
>>
>> So do I understand this correctly that _after_ relocation, env_init() is
>> called and env_init() does not update gd->env_addr to the relocated one?
>
> In my understandings, env_init() belongs to init_sequence_f[]
> and env_init() is called before relocation.
You're right.
So the env update after relocation should then be done in env_relocate().
>> I would expect that after relocation, if all you have is env_nowhere
>> driver, the env_nowhere_init() is called again from the first for() loop
>> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
>> that for() loop would exit with ret = -ENOENT [2], so then the last part
>> of env_init() would check for ret == -ENOENT and update gd->env_addr to
>> relocated default_environment [3].
>>
>> 324 int env_init(void)
>> 325 {
>> 326 struct env_driver *drv;
>> 327 int ret = -ENOENT;
>> 328 int prio;
>> 329
>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio));
>> prio++) {
>> /* Part [1] */
>> 331 if (!drv->init || !(ret = drv->init()))
>> 332 env_set_inited(drv->location);
>> 333 if (ret == -ENOENT)
>> 334 env_set_inited(drv->location);
>> 335
>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>> 337 drv->name, ret);
>> 338
>> /* Part [2] */
>> 339 if (gd->env_valid == ENV_INVALID)
>> 340 ret = -ENOENT;
>> 341 }
>> 342
>> 343 if (!prio)
>> 344 return -ENODEV;
>> 345
>> /* Part [3] */
>> 346 if (ret == -ENOENT) {
>> /* This should be relocated default_environment address */
>> 347 gd->env_addr = (ulong)&default_environment[0];
>> 348 gd->env_valid = ENV_VALID;
>> 349
>> 350 return 0;
>> 351 }
>> 352
>> 353 return ret;
>> 354 }
>>
>> Or am I missing something obvious ?
>
> These are called before relocation, and update gd->env_addr to
> non-relocated
> default_environment by [3].
>
> After that, gd->env_addr is relocated in initr_reloc_global_data()
> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>
> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
> | /*
> | * Relocate the early env_addr pointer unless we know it is not
> inside
> | * the binary. Some systems need this and for the rest, it doesn't
> hurt.
> | */
> | gd->env_addr += gd->reloc_off;
> | #endif
>
Shouldn't the post-relocation env update happen in env_relocate() ?
> However, I misunderstood my situation.
> gd->reloc_off doesn't have the proper value because CONFIG_SYS_TEXT_BASE
> is zero due to CONFIG_POSITION_INDENENDENT=y.
>
> gd->reloc_off is calculated with CONFIG_SYS_TEXT_BASE in setup_reloc().
>
> | gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>
> gd->env_addr is added with gd->reloc_off (== gd->relocaddr - 0),
> as a result, gd->env_addr has wrong address.
>
> In this case, I think the proper solution is to undefine
> CONFIG_SYS_RELOC_GD_ENV_ADDR.
>
> My patch isn't necessary no longer and your patch also works with
> "nowhere".
OK
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-06 18:08 ` Marek Vasut
@ 2021-06-07 7:54 ` Kunihiko Hayashi
2021-06-07 17:33 ` Marek Vasut
0 siblings, 1 reply; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-06-07 7:54 UTC (permalink / raw)
To: Marek Vasut; +Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini
Hi Marek,
On 2021/06/07 3:08, Marek Vasut wrote:
> On 6/3/21 6:15 PM, Kunihiko Hayashi wrote:
>> Hi Marek,
>
> Hi,
>
>> Sorry for rate reply.
>
> No worries, same here.
>
>> On 2021/05/25 16:35, Marek Vasut wrote:
>>> On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
>>>> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
>>>> to gd->env_valid, and sets default_environment before relocation to
>>>> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
>>>> by the previous fix.
>>>>
>>>> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
>>>> default_environment, however, env_get_char() returns gd->env_addr before
>>>> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
>>>> will cause a fault.
>>>>
>>>> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.
>>>
>>> So do I understand this correctly that _after_ relocation, env_init() is
>>> called and env_init() does not update gd->env_addr to the relocated one?
>>
>> In my understandings, env_init() belongs to init_sequence_f[]
>> and env_init() is called before relocation.
>
> You're right.
>
> So the env update after relocation should then be done in env_relocate().
Yes. I understand that the relocated gd->env_addr is used in env_relocate().
>>> I would expect that after relocation, if all you have is env_nowhere
>>> driver, the env_nowhere_init() is called again from the first for() loop
>>> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
>>> that for() loop would exit with ret = -ENOENT [2], so then the last part
>>> of env_init() would check for ret == -ENOENT and update gd->env_addr to
>>> relocated default_environment [3].
>>>
>>> 324 int env_init(void)
>>> 325 {
>>> 326 struct env_driver *drv;
>>> 327 int ret = -ENOENT;
>>> 328 int prio;
>>> 329
>>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
>>> /* Part [1] */
>>> 331 if (!drv->init || !(ret = drv->init()))
>>> 332 env_set_inited(drv->location);
>>> 333 if (ret == -ENOENT)
>>> 334 env_set_inited(drv->location);
>>> 335
>>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>>> 337 drv->name, ret);
>>> 338
>>> /* Part [2] */
>>> 339 if (gd->env_valid == ENV_INVALID)
>>> 340 ret = -ENOENT;
>>> 341 }
>>> 342
>>> 343 if (!prio)
>>> 344 return -ENODEV;
>>> 345
>>> /* Part [3] */
>>> 346 if (ret == -ENOENT) {
>>> /* This should be relocated default_environment address */
>>> 347 gd->env_addr = (ulong)&default_environment[0];
>>> 348 gd->env_valid = ENV_VALID;
>>> 349
>>> 350 return 0;
>>> 351 }
>>> 352
>>> 353 return ret;
>>> 354 }
>>>
>>> Or am I missing something obvious ?
>>
>> These are called before relocation, and update gd->env_addr to non-relocated
>> default_environment by [3].
>>
>> After that, gd->env_addr is relocated in initr_reloc_global_data()
>> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>>
>> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
>> | /*
>> | * Relocate the early env_addr pointer unless we know it is not inside
>> | * the binary. Some systems need this and for the rest, it doesn't hurt.
>> | */
>> | gd->env_addr += gd->reloc_off;
>> | #endif
>>
>
> Shouldn't the post-relocation env update happen in env_relocate() ?
Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
It's no problem.
If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.
>
>> However, I misunderstood my situation.
>> gd->reloc_off doesn't have the proper value because CONFIG_SYS_TEXT_BASE
>> is zero due to CONFIG_POSITION_INDENENDENT=y.
>>
>> gd->reloc_off is calculated with CONFIG_SYS_TEXT_BASE in setup_reloc().
>>
>> | gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>>
>> gd->env_addr is added with gd->reloc_off (== gd->relocaddr - 0),
>> as a result, gd->env_addr has wrong address.
>>
>> In this case, I think the proper solution is to undefine
>> CONFIG_SYS_RELOC_GD_ENV_ADDR.
>>
>> My patch isn't necessary no longer and your patch also works with
>> "nowhere".
> OK
Thank you,
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-07 7:54 ` Kunihiko Hayashi
@ 2021-06-07 17:33 ` Marek Vasut
2021-06-08 7:54 ` Kunihiko Hayashi
0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2021-06-07 17:33 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini, Michal Simek
On 6/7/21 9:54 AM, Kunihiko Hayashi wrote:
Hi,
[...]
>>>> I would expect that after relocation, if all you have is env_nowhere
>>>> driver, the env_nowhere_init() is called again from the first for()
>>>> loop
>>>> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1],
>>>> and
>>>> that for() loop would exit with ret = -ENOENT [2], so then the last
>>>> part
>>>> of env_init() would check for ret == -ENOENT and update gd->env_addr to
>>>> relocated default_environment [3].
>>>>
>>>> 324 int env_init(void)
>>>> 325 {
>>>> 326 struct env_driver *drv;
>>>> 327 int ret = -ENOENT;
>>>> 328 int prio;
>>>> 329
>>>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio));
>>>> prio++) {
>>>> /* Part [1] */
>>>> 331 if (!drv->init || !(ret = drv->init()))
>>>> 332 env_set_inited(drv->location);
>>>> 333 if (ret == -ENOENT)
>>>> 334 env_set_inited(drv->location);
>>>> 335
>>>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>>>> 337 drv->name, ret);
>>>> 338
>>>> /* Part [2] */
>>>> 339 if (gd->env_valid == ENV_INVALID)
>>>> 340 ret = -ENOENT;
>>>> 341 }
>>>> 342
>>>> 343 if (!prio)
>>>> 344 return -ENODEV;
>>>> 345
>>>> /* Part [3] */
>>>> 346 if (ret == -ENOENT) {
>>>> /* This should be relocated default_environment address */
>>>> 347 gd->env_addr = (ulong)&default_environment[0];
>>>> 348 gd->env_valid = ENV_VALID;
>>>> 349
>>>> 350 return 0;
>>>> 351 }
>>>> 352
>>>> 353 return ret;
>>>> 354 }
>>>>
>>>> Or am I missing something obvious ?
>>>
>>> These are called before relocation, and update gd->env_addr to
>>> non-relocated
>>> default_environment by [3].
>>>
>>> After that, gd->env_addr is relocated in initr_reloc_global_data()
>>> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>>>
>>> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
>>> | /*
>>> | * Relocate the early env_addr pointer unless we know it is not
>>> inside
>>> | * the binary. Some systems need this and for the rest, it
>>> doesn't hurt.
>>> | */
>>> | gd->env_addr += gd->reloc_off;
>>> | #endif
>>>
>>
>> Shouldn't the post-relocation env update happen in env_relocate() ?
>
> Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
> It's no problem.
>
> If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
> CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.
But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be
relocated or how should it behave ?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-07 17:33 ` Marek Vasut
@ 2021-06-08 7:54 ` Kunihiko Hayashi
2021-06-10 1:07 ` Marek Vasut
0 siblings, 1 reply; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-06-08 7:54 UTC (permalink / raw)
To: Marek Vasut; +Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini, Michal Simek
Hi Marek,
On 2021/06/08 2:33, Marek Vasut wrote:
> On 6/7/21 9:54 AM, Kunihiko Hayashi wrote:
>
> Hi,
>
> [...]
>
>>>>> I would expect that after relocation, if all you have is env_nowhere
>>>>> driver, the env_nowhere_init() is called again from the first for() loop
>>>>> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
>>>>> that for() loop would exit with ret = -ENOENT [2], so then the last part
>>>>> of env_init() would check for ret == -ENOENT and update gd->env_addr to
>>>>> relocated default_environment [3].
>>>>>
>>>>> 324 int env_init(void)
>>>>> 325 {
>>>>> 326 struct env_driver *drv;
>>>>> 327 int ret = -ENOENT;
>>>>> 328 int prio;
>>>>> 329
>>>>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
>>>>> /* Part [1] */
>>>>> 331 if (!drv->init || !(ret = drv->init()))
>>>>> 332 env_set_inited(drv->location);
>>>>> 333 if (ret == -ENOENT)
>>>>> 334 env_set_inited(drv->location);
>>>>> 335
>>>>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>>>>> 337 drv->name, ret);
>>>>> 338
>>>>> /* Part [2] */
>>>>> 339 if (gd->env_valid == ENV_INVALID)
>>>>> 340 ret = -ENOENT;
>>>>> 341 }
>>>>> 342
>>>>> 343 if (!prio)
>>>>> 344 return -ENODEV;
>>>>> 345
>>>>> /* Part [3] */
>>>>> 346 if (ret == -ENOENT) {
>>>>> /* This should be relocated default_environment address */
>>>>> 347 gd->env_addr = (ulong)&default_environment[0];
>>>>> 348 gd->env_valid = ENV_VALID;
>>>>> 349
>>>>> 350 return 0;
>>>>> 351 }
>>>>> 352
>>>>> 353 return ret;
>>>>> 354 }
>>>>>
>>>>> Or am I missing something obvious ?
>>>>
>>>> These are called before relocation, and update gd->env_addr to non-relocated
>>>> default_environment by [3].
>>>>
>>>> After that, gd->env_addr is relocated in initr_reloc_global_data()
>>>> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>>>>
>>>> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
>>>> | /*
>>>> | * Relocate the early env_addr pointer unless we know it is not inside
>>>> | * the binary. Some systems need this and for the rest, it doesn't hurt.
>>>> | */
>>>> | gd->env_addr += gd->reloc_off;
>>>> | #endif
>>>>
>>>
>>> Shouldn't the post-relocation env update happen in env_relocate() ?
>>
>> Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
>> It's no problem.
>>
>> If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
>> CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.
Sorry this isn't wrong.
> But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be relocated or how should it behave ?
I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y
regardless of CONFIG_SYS_TEXT_BASE.
If CONFIG_POSITION_INDEPENDENT=y and CONFIG_SYS_TEXT_BASE is zero,
there is something wrong with the calculation of the relocation address about env.
gd->reloc_off is relocated address offset from zero, however,
gd->env_addr has still non-relocated address.
>>>> | gd->env_addr += gd->reloc_off;
I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
But this code sets gd->env_addr incorrectly.
In that case, there is a non-relocated <textbase> address instead of
CONFIG_SYS_TEXT_BASE.
This should be "gd->env_addr = (gd->env_addr - <textbase>) + gd->reloc_off",
However, I'm not sure how we get non-relocated <textbase> address.
Thank you,
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-08 7:54 ` Kunihiko Hayashi
@ 2021-06-10 1:07 ` Marek Vasut
2021-06-10 8:25 ` Kunihiko Hayashi
0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2021-06-10 1:07 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini, Michal Simek,
Andre Przywara
On 6/8/21 9:54 AM, Kunihiko Hayashi wrote:
Hi,
[...]
>>>>>> I would expect that after relocation, if all you have is env_nowhere
>>>>>> driver, the env_nowhere_init() is called again from the first
>>>>>> for() loop
>>>>>> of env_init() [1], which would set gd->env_valid to ENV_INVALID
>>>>>> [1], and
>>>>>> that for() loop would exit with ret = -ENOENT [2], so then the
>>>>>> last part
>>>>>> of env_init() would check for ret == -ENOENT and update
>>>>>> gd->env_addr to
>>>>>> relocated default_environment [3].
>>>>>>
>>>>>> 324 int env_init(void)
>>>>>> 325 {
>>>>>> 326 struct env_driver *drv;
>>>>>> 327 int ret = -ENOENT;
>>>>>> 328 int prio;
>>>>>> 329
>>>>>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio));
>>>>>> prio++) {
>>>>>> /* Part [1] */
>>>>>> 331 if (!drv->init || !(ret = drv->init()))
>>>>>> 332 env_set_inited(drv->location);
>>>>>> 333 if (ret == -ENOENT)
>>>>>> 334 env_set_inited(drv->location);
>>>>>> 335
>>>>>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>>>>>> 337 drv->name, ret);
>>>>>> 338
>>>>>> /* Part [2] */
>>>>>> 339 if (gd->env_valid == ENV_INVALID)
>>>>>> 340 ret = -ENOENT;
>>>>>> 341 }
>>>>>> 342
>>>>>> 343 if (!prio)
>>>>>> 344 return -ENODEV;
>>>>>> 345
>>>>>> /* Part [3] */
>>>>>> 346 if (ret == -ENOENT) {
>>>>>> /* This should be relocated default_environment address */
>>>>>> 347 gd->env_addr = (ulong)&default_environment[0];
>>>>>> 348 gd->env_valid = ENV_VALID;
>>>>>> 349
>>>>>> 350 return 0;
>>>>>> 351 }
>>>>>> 352
>>>>>> 353 return ret;
>>>>>> 354 }
>>>>>>
>>>>>> Or am I missing something obvious ?
>>>>>
>>>>> These are called before relocation, and update gd->env_addr to
>>>>> non-relocated
>>>>> default_environment by [3].
>>>>>
>>>>> After that, gd->env_addr is relocated in initr_reloc_global_data()
>>>>> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>>>>>
>>>>> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
>>>>> | /*
>>>>> | * Relocate the early env_addr pointer unless we know it is
>>>>> not inside
>>>>> | * the binary. Some systems need this and for the rest, it
>>>>> doesn't hurt.
>>>>> | */
>>>>> | gd->env_addr += gd->reloc_off;
>>>>> | #endif
>>>>>
>>>>
>>>> Shouldn't the post-relocation env update happen in env_relocate() ?
>>>
>>> Usually env_relocate() calls env_load() that uses relocated
>>> gd->env_addr.
>>> It's no problem.
>>>
>>> If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
>>> CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.
>
> Sorry this isn't wrong.
>
>> But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be
>> relocated or how should it behave ?
>
> I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> regardless of CONFIG_SYS_TEXT_BASE.
>
> If CONFIG_POSITION_INDEPENDENT=y and CONFIG_SYS_TEXT_BASE is zero,
> there is something wrong with the calculation of the relocation address
> about env.
Ah, got it.
> gd->reloc_off is relocated address offset from zero, however,
> gd->env_addr has still non-relocated address.
>
> >>>> | gd->env_addr += gd->reloc_off;
>
> I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
> But this code sets gd->env_addr incorrectly.
>
> In that case, there is a non-relocated <textbase> address instead of
> CONFIG_SYS_TEXT_BASE.
>
> This should be "gd->env_addr = (gd->env_addr - <textbase>) +
> gd->reloc_off",
> However, I'm not sure how we get non-relocated <textbase> address.
Maybe what you need to do is store current $pc register when you enter
U-Boot very early on, in _start function, and then use it here ?
Although, I am not entirely sure whether this is still possible on arm64.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-10 1:07 ` Marek Vasut
@ 2021-06-10 8:25 ` Kunihiko Hayashi
2021-06-10 13:28 ` Marek Vasut
0 siblings, 1 reply; 12+ messages in thread
From: Kunihiko Hayashi @ 2021-06-10 8:25 UTC (permalink / raw)
To: Marek Vasut
Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini, Michal Simek,
Andre Przywara
Hi Marek,
On 2021/06/10 10:07, Marek Vasut wrote:
> On 6/8/21 9:54 AM, Kunihiko Hayashi wrote:
>
> Hi,
>
> [...]
>
>>>>>>> I would expect that after relocation, if all you have is env_nowhere
>>>>>>> driver, the env_nowhere_init() is called again from the first for() loop
>>>>>>> of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and
>>>>>>> that for() loop would exit with ret = -ENOENT [2], so then the last part
>>>>>>> of env_init() would check for ret == -ENOENT and update gd->env_addr to
>>>>>>> relocated default_environment [3].
>>>>>>>
>>>>>>> 324 int env_init(void)
>>>>>>> 325 {
>>>>>>> 326 struct env_driver *drv;
>>>>>>> 327 int ret = -ENOENT;
>>>>>>> 328 int prio;
>>>>>>> 329
>>>>>>> 330 for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
>>>>>>> /* Part [1] */
>>>>>>> 331 if (!drv->init || !(ret = drv->init()))
>>>>>>> 332 env_set_inited(drv->location);
>>>>>>> 333 if (ret == -ENOENT)
>>>>>>> 334 env_set_inited(drv->location);
>>>>>>> 335
>>>>>>> 336 debug("%s: Environment %s init done (ret=%d)\n", __func__,
>>>>>>> 337 drv->name, ret);
>>>>>>> 338
>>>>>>> /* Part [2] */
>>>>>>> 339 if (gd->env_valid == ENV_INVALID)
>>>>>>> 340 ret = -ENOENT;
>>>>>>> 341 }
>>>>>>> 342
>>>>>>> 343 if (!prio)
>>>>>>> 344 return -ENODEV;
>>>>>>> 345
>>>>>>> /* Part [3] */
>>>>>>> 346 if (ret == -ENOENT) {
>>>>>>> /* This should be relocated default_environment address */
>>>>>>> 347 gd->env_addr = (ulong)&default_environment[0];
>>>>>>> 348 gd->env_valid = ENV_VALID;
>>>>>>> 349
>>>>>>> 350 return 0;
>>>>>>> 351 }
>>>>>>> 352
>>>>>>> 353 return ret;
>>>>>>> 354 }
>>>>>>>
>>>>>>> Or am I missing something obvious ?
>>>>>>
>>>>>> These are called before relocation, and update gd->env_addr to non-relocated
>>>>>> default_environment by [3].
>>>>>>
>>>>>> After that, gd->env_addr is relocated in initr_reloc_global_data()
>>>>>> if CONFIG_SYS_RELOC_GD_ENV_ADDR is defined.
>>>>>>
>>>>>> | #ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
>>>>>> | /*
>>>>>> | * Relocate the early env_addr pointer unless we know it is not inside
>>>>>> | * the binary. Some systems need this and for the rest, it doesn't hurt.
>>>>>> | */
>>>>>> | gd->env_addr += gd->reloc_off;
>>>>>> | #endif
>>>>>>
>>>>>
>>>>> Shouldn't the post-relocation env update happen in env_relocate() ?
>>>>
>>>> Usually env_relocate() calls env_load() that uses relocated gd->env_addr.
>>>> It's no problem.
>>>>
>>>> If CONFIG_SYS_TEXT_BASE is zero, gd->reloc_off becomes illegal.
>>>> CONFIG_SYS_RELOC_GD_ENV_ADDR should be disabled in that case.
>>
>> Sorry this isn't wrong.
>>
>>> But then, if CONFIG_SYS_TEXT_BASE is zero, the env shouldn't be relocated or how should it
>>> behave ?
>>
>> I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y
>> regardless of CONFIG_SYS_TEXT_BASE.
>>
>> If CONFIG_POSITION_INDEPENDENT=y and CONFIG_SYS_TEXT_BASE is zero,
>> there is something wrong with the calculation of the relocation address about env.
>
> Ah, got it.
>
>> gd->reloc_off is relocated address offset from zero, however,
>> gd->env_addr has still non-relocated address.
>>
>> >>>> | gd->env_addr += gd->reloc_off;
>>
>> I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
>> But this code sets gd->env_addr incorrectly.
>>
>> In that case, there is a non-relocated <textbase> address instead of
>> CONFIG_SYS_TEXT_BASE.
>>
>> This should be "gd->env_addr = (gd->env_addr - <textbase>) + gd->reloc_off",
>> However, I'm not sure how we get non-relocated <textbase> address.
>
> Maybe what you need to do is store current $pc register when you enter U-Boot very early on, in
> _start function, and then use it here ? Although, I am not entirely sure whether this is still
> possible on arm64.
Exactly. I guess it's reasonable to fix gd->env_addr when POSITION_INDEPENDENT=y
before relocation. I'll try it.
Thank you,
---
Best Regards
Kunihiko Hayashi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] env: Leave invalid env for nowhere location
2021-06-10 8:25 ` Kunihiko Hayashi
@ 2021-06-10 13:28 ` Marek Vasut
0 siblings, 0 replies; 12+ messages in thread
From: Marek Vasut @ 2021-06-10 13:28 UTC (permalink / raw)
To: Kunihiko Hayashi
Cc: u-boot, Joe Hershberger, Tim Harvey, Tom Rini, Michal Simek,
Andre Przywara
On 6/10/21 10:25 AM, Kunihiko Hayashi wrote:
Hi,
[...]
>>> gd->reloc_off is relocated address offset from zero, however,
>>> gd->env_addr has still non-relocated address.
>>>
>>> >>>> | gd->env_addr += gd->reloc_off;
>>>
>>> I think the env should be relocated if CONFIG_SYS_RELOC_GD_ENV_ADDR=y.
>>> But this code sets gd->env_addr incorrectly.
>>>
>>> In that case, there is a non-relocated <textbase> address instead of
>>> CONFIG_SYS_TEXT_BASE.
>>>
>>> This should be "gd->env_addr = (gd->env_addr - <textbase>) +
>>> gd->reloc_off",
>>> However, I'm not sure how we get non-relocated <textbase> address.
>>
>> Maybe what you need to do is store current $pc register when you enter
>> U-Boot very early on, in _start function, and then use it here ?
>> Although, I am not entirely sure whether this is still possible on arm64.
>
> Exactly. I guess it's reasonable to fix gd->env_addr when
> POSITION_INDEPENDENT=y
> before relocation. I'll try it.
That sounds good, thank you !
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-06-10 13:28 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-12 14:09 [PATCH] env: Leave invalid env for nowhere location Kunihiko Hayashi
2021-05-16 17:19 ` Marek Vasut
2021-05-25 6:30 ` Kunihiko Hayashi
2021-05-25 7:35 ` Marek Vasut
2021-06-03 16:15 ` Kunihiko Hayashi
2021-06-06 18:08 ` Marek Vasut
2021-06-07 7:54 ` Kunihiko Hayashi
2021-06-07 17:33 ` Marek Vasut
2021-06-08 7:54 ` Kunihiko Hayashi
2021-06-10 1:07 ` Marek Vasut
2021-06-10 8:25 ` Kunihiko Hayashi
2021-06-10 13:28 ` Marek Vasut
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.