[PATCH v3] board_f.c: Insure gd->new_bootstage alignment
Patrick DELAUNAY
patrick.delaunay at st.com
Wed Dec 18 10:10:14 CET 2019
Hi Simon,
> From: Simon Glass <sjg at chromium.org>
> Sent: mardi 17 décembre 2019 16:46
>
> Hi Patrice,
>
> On Wed, 27 Nov 2019 at 02:11, Patrice Chotard <patrice.chotard at st.com> wrote:
> >
> > In reserve_bootstage(), in case size is odd, gd->new_bootstage is not
> > aligned. In bootstage_relocate(), the platform hangs when getting
> > access to data->record[i].name.
> > To avoid this issue, make gd->new_bootstage 16 byte aligned.
> >
> > To insure that new_bootstage is 16 byte aligned (at least needed for
> > x86_64 and ARMv8) and new_bootstage starts down to get enough space,
> > ALIGN_DOWN macro is used.
> >
> > Fixes: ac9cd4805c8b ("bootstage: Correct relocation algorithm")
> >
> > Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
> > Reviewed-by: Vikas MANOCHA <vikas.manocha at st.com>
> > Reviewed-by: Patrick Delaunay <patrick.delaunay at st.com>
> > Tested-by: Patrick Delaunay <patrick.delaunay at st.com>
For information, Patrice is absent for personal reason up to beginning next year.
Don't wait a fast answer.
> For this patch I think it would be better to update reserve_fdt() to keep things
> aligned, assuming that is the problem.
I don't sure that solve the issue,
for me the problem is only for the bootstage struct (gd->bootstage)
And reserve_fdt() already alligne size on 32 bytes
If I remember the Patrice analysis:
1- bootstage_get_size return a odd value (or at least not 16 bytes aligned I don't remember).
2- In reserve_bootstage()
int size = bootstage_get_size();
gd->start_addr_sp -= size
=> it is a unaligned address even if gd->start_addr_sp is 32 bytes alligned
gd->new_bootstage = map_sysmem(gd->start_addr_sp, size);
=> also unaligned
3- Then during relocation, in reloc_bootstage()
gd->bootstage = gd->new_bootstage;
4- crash occur because in next bootstage function beaucse the boostage address don't respect pointer to struct allignement...
struct bootstage_data *data = gd->bootstage
> At some point we should also document that reservations must keep things
> aligned.
>
> Perhaps this should be handled by a separate function called from all these
> places, which subtracts gd->start_addr_sp and ensures 16-byte alignment.
Yes that can be a improvement, but perhaps ia a second step / second serie....
Do you think about a function called in all reversed_ functions (when start_addr_sp is modified)...
static int reserved_allign_check(void)
{
/* make stack pointer 16-byte aligned */
if (gd->start_addr_sp & 0xf) {
gd->start_addr_sp -= 16;
gd->start_addr_sp &= ~0xf;
}
}
I prefer a function to reserved a size wich replace in any reserve_ function the line :
gd->start_addr_sp -= ...
/* reserve size and make stack pointer 16-byte aligned */
static int reserve(size_t size)
{
gd->start_addr_sp -= size;
/* make stack pointer 16-byte aligned */
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp, 16);
}
I think I will push it, when the patrice patch will be accepted.
> Regards,
> Simon
Regards
Patrick
More information about the U-Boot
mailing list