[PATCH] lib: sbi_domain: Avoid overwriting coldboot hart's scratch->arg1
Anup Patel
anup at brainfault.org
Fri Jan 13 04:42:13 PST 2023
On Fri, Dec 30, 2022 at 9:56 PM Samuel Holland <samuel at sholland.org> wrote:
>
> Hi Bin,
>
> On 12/29/22 22:26, Bin Meng wrote:
> > In sbi_domain_finalize(), when locating the coldboot hart's domain,
> > the coldboot hart's scratch->arg1 will be overwritten by the domain
> > configuration. scratch->arg1 holds the FDT address of the coldboot
> > hart, and in later boot process OpenSBI codes still read the FDT
> > here and there, which leads to a crash.
>
> It sounds to me like the bug is in fdt_get_address(), not here. We
> should save off the FDT address in some global variable, and not
> continue getting it from next_arg1. Then there is no problem updating
> next_arg1 from the domain configuration.
I agree with your suggestion.
The fdt_get_address() should return root domains next_arg1 as the
FDT pointer.
@Bin, will you be sending a v2 patch ?
Regards,
Anup
>
> Regards,
> Samuel
>
> > To fix this, we save the next booting stage arg1 for the coldboot
> > domain instance for the caller to use later.
> >
> > Resolves: https://github.com/riscv-software-src/opensbi/issues/281
> > Fixes: b1678af210dc ("lib: sbi: Add initial domain support")
> > Reported-by: Marouene Boubakri <marouene.boubakri at nxp.com>
> > Signed-off-by: Bin Meng <bmeng at tinylab.org>
> > ---
> >
> > include/sbi/sbi_domain.h | 3 ++-
> > lib/sbi/sbi_domain.c | 15 +++++++++++++--
> > lib/sbi/sbi_init.c | 7 ++++++-
> > 3 files changed, 21 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> > index 5553d21..0370d48 100644
> > --- a/include/sbi/sbi_domain.h
> > +++ b/include/sbi/sbi_domain.h
> > @@ -195,7 +195,8 @@ int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
> > unsigned long align, unsigned long region_flags);
> >
> > /** Finalize domain tables and startup non-root domains */
> > -int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid);
> > +int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid,
> > + bool *coldboot_domain, unsigned long *next_arg1);
> >
> > /** Initialize domains */
> > int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
> > diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> > index 3205595..bdef99f 100644
> > --- a/lib/sbi/sbi_domain.c
> > +++ b/lib/sbi/sbi_domain.c
> > @@ -552,12 +552,14 @@ int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
> > return 0;
> > }
> >
> > -int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
> > +int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid,
> > + bool *coldboot_domain, unsigned long *next_arg1)
> > {
> > int rc;
> > u32 i, dhart;
> > struct sbi_domain *dom;
> > const struct sbi_platform *plat = sbi_platform_ptr(scratch);
> > + *coldboot_domain = false;
> >
> > /* Initialize and populate domains for the platform */
> > rc = sbi_platform_domains_init(plat);
> > @@ -589,7 +591,16 @@ int sbi_domain_finalize(struct sbi_scratch *scratch, u32 cold_hartid)
> > if (dhart == cold_hartid) {
> > scratch->next_addr = dom->next_addr;
> > scratch->next_mode = dom->next_mode;
> > - scratch->next_arg1 = dom->next_arg1;
> > + /*
> > + * We cannot overwrite the scratch->next_arg1 here
> > + * as it holds the FDT address for the coldboot hart.
> > + *
> > + * Instead, we save the next booting stage arg1 for
> > + * the coldboot domain instance for the caller to
> > + * use later.
> > + */
> > + *coldboot_domain = true;
> > + *next_arg1 = dom->next_arg1;
> > } else {
> > rc = sbi_hsm_hart_start(scratch, NULL, dhart,
> > dom->next_addr,
> > diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
> > index a8500e5..85d211b 100644
> > --- a/lib/sbi/sbi_init.c
> > +++ b/lib/sbi/sbi_init.c
> > @@ -240,6 +240,8 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
> > int rc;
> > unsigned long *init_count;
> > const struct sbi_platform *plat = sbi_platform_ptr(scratch);
> > + bool coldboot_domain;
> > + unsigned long next_arg1;
> >
> > /* Note: This has to be first thing in coldboot init sequence */
> > rc = sbi_scratch_init(scratch);
> > @@ -314,7 +316,8 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
> > * Note: Finalize domains before HART PMP configuration so
> > * that we use correct domain for configuring PMP.
> > */
> > - rc = sbi_domain_finalize(scratch, hartid);
> > + rc = sbi_domain_finalize(scratch, hartid, &coldboot_domain,
> > + &next_arg1);
> > if (rc) {
> > sbi_printf("%s: domain finalize failed (error %d)\n",
> > __func__, rc);
> > @@ -351,6 +354,8 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
> > (*init_count)++;
> >
> > sbi_hsm_prepare_next_jump(scratch, hartid);
> > + if (coldboot_domain)
> > + scratch->next_arg1 = next_arg1;
> > sbi_hart_switch_mode(hartid, scratch->next_arg1, scratch->next_addr,
> > scratch->next_mode, FALSE);
> > }
>
More information about the opensbi
mailing list