diff mbox series

[01/10] x86 setup: move x86 boot module counting into a new boot_info struct

Message ID 20230701071835.41599-2-christopher.w.clark@gmail.com (mailing list archive)
State New, archived
Headers show
Series v3: Boot modules for Hyperlaunch | expand

Commit Message

Christopher Clark July 1, 2023, 7:18 a.m. UTC
An initial step towards a non-multiboot internal representation of boot
modules for common code, starting with x86 setup and converting the
fields that are accessed for the startup calculations.

Introduce a new header, <xen/bootinfo.h>, and populate it with a new
boot_info structure initially containing a count of the number of boot
modules.

The naming of the header, structure and fields is intended to respect
the boot structures on Arm -- see arm/include/asm/setup.h -- as part of
work towards aligning common architecture-neutral boot logic and
structures.

No functional change intended.

Signed-off-by: Christopher Clark <christopher.w.clark@gmail.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>

---
Changes since v1: patch is a subset of v1 series patches 2 and 3.

 xen/arch/x86/setup.c       | 58 +++++++++++++++++++++++---------------
 xen/include/xen/bootinfo.h | 20 +++++++++++++
 2 files changed, 55 insertions(+), 23 deletions(-)
 create mode 100644 xen/include/xen/bootinfo.h

Comments

Stefano Stabellini July 8, 2023, 6:30 p.m. UTC | #1
On Sat, 1 Jul 2023, Christopher Clark wrote:
> An initial step towards a non-multiboot internal representation of boot
> modules for common code, starting with x86 setup and converting the
> fields that are accessed for the startup calculations.
> 
> Introduce a new header, <xen/bootinfo.h>, and populate it with a new
> boot_info structure initially containing a count of the number of boot
> modules.
> 
> The naming of the header, structure and fields is intended to respect
> the boot structures on Arm -- see arm/include/asm/setup.h -- as part of
> work towards aligning common architecture-neutral boot logic and
> structures.

Thanks for aligning the two archs. At some point we should also have ARM
use the common headers.


> No functional change intended.
> 
> Signed-off-by: Christopher Clark <christopher.w.clark@gmail.com>
> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
> 
> ---
> Changes since v1: patch is a subset of v1 series patches 2 and 3.
> 
>  xen/arch/x86/setup.c       | 58 +++++++++++++++++++++++---------------
>  xen/include/xen/bootinfo.h | 20 +++++++++++++
>  2 files changed, 55 insertions(+), 23 deletions(-)
>  create mode 100644 xen/include/xen/bootinfo.h
> 
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 74e3915a4d..708639b236 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -1,3 +1,4 @@
> +#include <xen/bootinfo.h>
>  #include <xen/init.h>
>  #include <xen/lib.h>
>  #include <xen/err.h>
> @@ -268,7 +269,16 @@ static int __init cf_check parse_acpi_param(const char *s)
>  custom_param("acpi", parse_acpi_param);
>  
>  static const module_t *__initdata initial_images;
> -static unsigned int __initdata nr_initial_images;
> +static struct boot_info __initdata *boot_info;

Why can't this be not a pointer?


> +static void __init multiboot_to_bootinfo(multiboot_info_t *mbi)
> +{
> +    static struct boot_info __initdata info;

Then we don't need this


> +    info.nr_mods = mbi->mods_count;
> +
> +    boot_info = &info;

And we could just do:

  boot_info.nr_mods = mbi->mods_count;

?


> +}
>  
>  unsigned long __init initial_images_nrpages(nodeid_t node)
>  {
> @@ -277,7 +287,7 @@ unsigned long __init initial_images_nrpages(nodeid_t node)
>      unsigned long nr;
>      unsigned int i;
>  
> -    for ( nr = i = 0; i < nr_initial_images; ++i )
> +    for ( nr = i = 0; i < boot_info->nr_mods; ++i )
>      {
>          unsigned long start = initial_images[i].mod_start;
>          unsigned long end = start + PFN_UP(initial_images[i].mod_end);
> @@ -293,7 +303,7 @@ void __init discard_initial_images(void)
>  {
>      unsigned int i;
>  
> -    for ( i = 0; i < nr_initial_images; ++i )
> +    for ( i = 0; i < boot_info->nr_mods; ++i )
>      {
>          uint64_t start = (uint64_t)initial_images[i].mod_start << PAGE_SHIFT;
>  
> @@ -301,7 +311,7 @@ void __init discard_initial_images(void)
>                             start + PAGE_ALIGN(initial_images[i].mod_end));
>      }
>  
> -    nr_initial_images = 0;
> +    boot_info->nr_mods = 0;
>      initial_images = NULL;
>  }
>  
> @@ -1020,6 +1030,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          mod = __va(mbi->mods_addr);
>      }
>  
> +    multiboot_to_bootinfo(mbi);
> +
>      loader = (mbi->flags & MBI_LOADERNAME)
>          ? (char *)__va(mbi->boot_loader_name) : "unknown";
>  
> @@ -1127,18 +1139,18 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>             bootsym(boot_edd_info_nr));
>  
>      /* Check that we have at least one Multiboot module. */
> -    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
> +    if ( !(mbi->flags & MBI_MODULES) || (boot_info->nr_mods == 0) )
>          panic("dom0 kernel not specified. Check bootloader configuration\n");
>  
>      /* Check that we don't have a silly number of modules. */
> -    if ( mbi->mods_count > sizeof(module_map) * 8 )
> +    if ( boot_info->nr_mods > sizeof(module_map) * 8 )
>      {
> -        mbi->mods_count = sizeof(module_map) * 8;
> +        boot_info->nr_mods = sizeof(module_map) * 8;
>          printk("Excessive multiboot modules - using the first %u only\n",
> -               mbi->mods_count);
> +               boot_info->nr_mods);
>      }
>  
> -    bitmap_fill(module_map, mbi->mods_count);
> +    bitmap_fill(module_map, boot_info->nr_mods);
>      __clear_bit(0, module_map); /* Dom0 kernel is always first */
>  
>      if ( pvh_boot )
> @@ -1311,9 +1323,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      kexec_reserve_area(&boot_e820);
>  
>      initial_images = mod;
> -    nr_initial_images = mbi->mods_count;
> +    boot_info->nr_mods = boot_info->nr_mods;
>  
> -    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
> +    for ( i = 0; !efi_enabled(EFI_LOADER) && i < boot_info->nr_mods; i++ )
>      {
>          if ( mod[i].mod_start & (PAGE_SIZE - 1) )
>              panic("Bootloader didn't honor module alignment request\n");
> @@ -1337,8 +1349,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>           * respective reserve_e820_ram() invocation below. No need to
>           * query efi_boot_mem_unused() here, though.
>           */
> -        mod[mbi->mods_count].mod_start = virt_to_mfn(_stext);
> -        mod[mbi->mods_count].mod_end = __2M_rwdata_end - _stext;
> +        mod[boot_info->nr_mods].mod_start = virt_to_mfn(_stext);
> +        mod[boot_info->nr_mods].mod_end = __2M_rwdata_end - _stext;
>      }
>  
>      modules_headroom = bzimage_headroom(bootstrap_map(mod), mod->mod_end);
> @@ -1398,7 +1410,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          {
>              /* Don't overlap with modules. */
>              end = consider_modules(s, e, reloc_size + mask,
> -                                   mod, mbi->mods_count, -1);
> +                                   mod, boot_info->nr_mods, -1);
>              end &= ~mask;
>          }
>          else
> @@ -1419,7 +1431,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          }
>  
>          /* Is the region suitable for relocating the multiboot modules? */
> -        for ( j = mbi->mods_count - 1; j >= 0; j-- )
> +        for ( j = boot_info->nr_mods - 1; j >= 0; j-- )
>          {
>              unsigned long headroom = j ? 0 : modules_headroom;
>              unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end);
> @@ -1429,7 +1441,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>              /* Don't overlap with other modules (or Xen itself). */
>              end = consider_modules(s, e, size, mod,
> -                                   mbi->mods_count + relocated, j);
> +                                   boot_info->nr_mods + relocated, j);
>  
>              if ( highmem_start && end > highmem_start )
>                  continue;
> @@ -1456,7 +1468,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          {
>              /* Don't overlap with modules (or Xen itself). */
>              e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), mod,
> -                                 mbi->mods_count + relocated, -1);
> +                                 boot_info->nr_mods + relocated, -1);
>              if ( s >= e )
>                  break;
>              if ( e > kexec_crash_area_limit )
> @@ -1471,7 +1483,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>  
>      if ( modules_headroom && !mod->reserved )
>          panic("Not enough memory to relocate the dom0 kernel image\n");
> -    for ( i = 0; i < mbi->mods_count; ++i )
> +    for ( i = 0; i < boot_info->nr_mods; ++i )
>      {
>          uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
>  
> @@ -1540,7 +1552,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                      ASSERT(j);
>                  }
>                  map_e = boot_e820.map[j].addr + boot_e820.map[j].size;
> -                for ( j = 0; j < mbi->mods_count; ++j )
> +                for ( j = 0; j < boot_info->nr_mods; ++j )
>                  {
>                      uint64_t end = pfn_to_paddr(mod[j].mod_start) +
>                                     mod[j].mod_end;
> @@ -1616,7 +1628,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          }
>      }
>  
> -    for ( i = 0; i < mbi->mods_count; ++i )
> +    for ( i = 0; i < boot_info->nr_mods; ++i )
>      {
>          set_pdx_range(mod[i].mod_start,
>                        mod[i].mod_start + PFN_UP(mod[i].mod_end));
> @@ -1999,8 +2011,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>             cpu_has_nx ? XENLOG_INFO : XENLOG_WARNING "Warning: ",
>             cpu_has_nx ? "" : "not ");
>  
> -    initrdidx = find_first_bit(module_map, mbi->mods_count);
> -    if ( bitmap_weight(module_map, mbi->mods_count) > 1 )
> +    initrdidx = find_first_bit(module_map, boot_info->nr_mods);
> +    if ( bitmap_weight(module_map, boot_info->nr_mods) > 1 )
>          printk(XENLOG_WARNING
>                 "Multiple initrd candidates, picking module #%u\n",
>                 initrdidx);
> @@ -2010,7 +2022,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * above our heap. The second module, if present, is an initrd ramdisk.
>       */
>      dom0 = create_dom0(mod, modules_headroom,
> -                       initrdidx < mbi->mods_count ? mod + initrdidx : NULL,
> +                       initrdidx < boot_info->nr_mods ? mod + initrdidx : NULL,
>                         kextra, loader);
>      if ( !dom0 )
>          panic("Could not set up DOM0 guest OS\n");
> diff --git a/xen/include/xen/bootinfo.h b/xen/include/xen/bootinfo.h
> new file mode 100644
> index 0000000000..6a7d55d20e
> --- /dev/null
> +++ b/xen/include/xen/bootinfo.h
> @@ -0,0 +1,20 @@
> +#ifndef __XEN_BOOTINFO_H__
> +#define __XEN_BOOTINFO_H__
> +
> +#include <xen/types.h>

I don't think you need types.h right now


> +struct boot_info {

This is what we call struct bootmodules on ARM right? Would it help if
we used the same name?

I am not asking to make the ARM code common because I think that would
probably be a lot more work.


> +    unsigned int nr_mods;
> +};
> +
> +#endif
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> -- 
> 2.25.1
> 
>
Christopher Clark July 20, 2023, 9:46 p.m. UTC | #2
On Sat, Jul 8, 2023 at 11:30 AM Stefano Stabellini <sstabellini@kernel.org>
wrote:

> On Sat, 1 Jul 2023, Christopher Clark wrote:
> > An initial step towards a non-multiboot internal representation of boot
> > modules for common code, starting with x86 setup and converting the
> > fields that are accessed for the startup calculations.
> >
> > Introduce a new header, <xen/bootinfo.h>, and populate it with a new
> > boot_info structure initially containing a count of the number of boot
> > modules.
> >
> > The naming of the header, structure and fields is intended to respect
> > the boot structures on Arm -- see arm/include/asm/setup.h -- as part of
> > work towards aligning common architecture-neutral boot logic and
> > structures.
>
> Thanks for aligning the two archs. At some point we should also have ARM
> use the common headers.
>
>
> > No functional change intended.
> >
> > Signed-off-by: Christopher Clark <christopher.w.clark@gmail.com>
> > Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
> >
> > ---
> > Changes since v1: patch is a subset of v1 series patches 2 and 3.
> >
> >  xen/arch/x86/setup.c       | 58 +++++++++++++++++++++++---------------
> >  xen/include/xen/bootinfo.h | 20 +++++++++++++
> >  2 files changed, 55 insertions(+), 23 deletions(-)
> >  create mode 100644 xen/include/xen/bootinfo.h
> >
> > diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> > index 74e3915a4d..708639b236 100644
> > --- a/xen/arch/x86/setup.c
> > +++ b/xen/arch/x86/setup.c
> > @@ -1,3 +1,4 @@
> > +#include <xen/bootinfo.h>
> >  #include <xen/init.h>
> >  #include <xen/lib.h>
> >  #include <xen/err.h>
> > @@ -268,7 +269,16 @@ static int __init cf_check parse_acpi_param(const
> char *s)
> >  custom_param("acpi", parse_acpi_param);
> >
> >  static const module_t *__initdata initial_images;
> > -static unsigned int __initdata nr_initial_images;
> > +static struct boot_info __initdata *boot_info;
>
> Why can't this be not a pointer?
>

In a later patch (10/10 in the same series posted), the boot_info pointer
is passed as an argument to start_xen. On x86 there are currently three
different entry points to this that have different environments which must
all be made to behave the same, and passing the argument as a pointer is a
lowest-common-denominater due to the 32bit x86 multiboot entry point.
Additionally another entry point will be coming soon for TrenchBoot.

Defining it as a pointer now where this logic is introduced saves having to
do a conversion of all accesses when the later change is made.

I can add a note about this to the commit message.



>
>
> > +static void __init multiboot_to_bootinfo(multiboot_info_t *mbi)
> > +{
> > +    static struct boot_info __initdata info;
>
> Then we don't need this
>

(see above)

>
>
> > +    info.nr_mods = mbi->mods_count;
> > +
> > +    boot_info = &info;
>
> And we could just do:
>
>   boot_info.nr_mods = mbi->mods_count;
>
> ?
>

(see above)



>
>
> > +}
> >
> >  unsigned long __init initial_images_nrpages(nodeid_t node)
> >  {
> > @@ -277,7 +287,7 @@ unsigned long __init initial_images_nrpages(nodeid_t
> node)
> >      unsigned long nr;
> >      unsigned int i;
> >
> > -    for ( nr = i = 0; i < nr_initial_images; ++i )
> > +    for ( nr = i = 0; i < boot_info->nr_mods; ++i )
> >      {
> >          unsigned long start = initial_images[i].mod_start;
> >          unsigned long end = start + PFN_UP(initial_images[i].mod_end);
> > @@ -293,7 +303,7 @@ void __init discard_initial_images(void)
> >  {
> >      unsigned int i;
> >
> > -    for ( i = 0; i < nr_initial_images; ++i )
> > +    for ( i = 0; i < boot_info->nr_mods; ++i )
> >      {
> >          uint64_t start = (uint64_t)initial_images[i].mod_start <<
> PAGE_SHIFT;
> >
> > @@ -301,7 +311,7 @@ void __init discard_initial_images(void)
> >                             start +
> PAGE_ALIGN(initial_images[i].mod_end));
> >      }
> >
> > -    nr_initial_images = 0;
> > +    boot_info->nr_mods = 0;
> >      initial_images = NULL;
> >  }
> >
> > @@ -1020,6 +1030,8 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >          mod = __va(mbi->mods_addr);
> >      }
> >
> > +    multiboot_to_bootinfo(mbi);
> > +
> >      loader = (mbi->flags & MBI_LOADERNAME)
> >          ? (char *)__va(mbi->boot_loader_name) : "unknown";
> >
> > @@ -1127,18 +1139,18 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >             bootsym(boot_edd_info_nr));
> >
> >      /* Check that we have at least one Multiboot module. */
> > -    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
> > +    if ( !(mbi->flags & MBI_MODULES) || (boot_info->nr_mods == 0) )
> >          panic("dom0 kernel not specified. Check bootloader
> configuration\n");
> >
> >      /* Check that we don't have a silly number of modules. */
> > -    if ( mbi->mods_count > sizeof(module_map) * 8 )
> > +    if ( boot_info->nr_mods > sizeof(module_map) * 8 )
> >      {
> > -        mbi->mods_count = sizeof(module_map) * 8;
> > +        boot_info->nr_mods = sizeof(module_map) * 8;
> >          printk("Excessive multiboot modules - using the first %u
> only\n",
> > -               mbi->mods_count);
> > +               boot_info->nr_mods);
> >      }
> >
> > -    bitmap_fill(module_map, mbi->mods_count);
> > +    bitmap_fill(module_map, boot_info->nr_mods);
> >      __clear_bit(0, module_map); /* Dom0 kernel is always first */
> >
> >      if ( pvh_boot )
> > @@ -1311,9 +1323,9 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >      kexec_reserve_area(&boot_e820);
> >
> >      initial_images = mod;
> > -    nr_initial_images = mbi->mods_count;
> > +    boot_info->nr_mods = boot_info->nr_mods;
> >
> > -    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
> > +    for ( i = 0; !efi_enabled(EFI_LOADER) && i < boot_info->nr_mods;
> i++ )
> >      {
> >          if ( mod[i].mod_start & (PAGE_SIZE - 1) )
> >              panic("Bootloader didn't honor module alignment request\n");
> > @@ -1337,8 +1349,8 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >           * respective reserve_e820_ram() invocation below. No need to
> >           * query efi_boot_mem_unused() here, though.
> >           */
> > -        mod[mbi->mods_count].mod_start = virt_to_mfn(_stext);
> > -        mod[mbi->mods_count].mod_end = __2M_rwdata_end - _stext;
> > +        mod[boot_info->nr_mods].mod_start = virt_to_mfn(_stext);
> > +        mod[boot_info->nr_mods].mod_end = __2M_rwdata_end - _stext;
> >      }
> >
> >      modules_headroom = bzimage_headroom(bootstrap_map(mod),
> mod->mod_end);
> > @@ -1398,7 +1410,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >          {
> >              /* Don't overlap with modules. */
> >              end = consider_modules(s, e, reloc_size + mask,
> > -                                   mod, mbi->mods_count, -1);
> > +                                   mod, boot_info->nr_mods, -1);
> >              end &= ~mask;
> >          }
> >          else
> > @@ -1419,7 +1431,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >          }
> >
> >          /* Is the region suitable for relocating the multiboot modules?
> */
> > -        for ( j = mbi->mods_count - 1; j >= 0; j-- )
> > +        for ( j = boot_info->nr_mods - 1; j >= 0; j-- )
> >          {
> >              unsigned long headroom = j ? 0 : modules_headroom;
> >              unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end);
> > @@ -1429,7 +1441,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >
> >              /* Don't overlap with other modules (or Xen itself). */
> >              end = consider_modules(s, e, size, mod,
> > -                                   mbi->mods_count + relocated, j);
> > +                                   boot_info->nr_mods + relocated, j);
> >
> >              if ( highmem_start && end > highmem_start )
> >                  continue;
> > @@ -1456,7 +1468,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >          {
> >              /* Don't overlap with modules (or Xen itself). */
> >              e = consider_modules(s, e,
> PAGE_ALIGN(kexec_crash_area.size), mod,
> > -                                 mbi->mods_count + relocated, -1);
> > +                                 boot_info->nr_mods + relocated, -1);
> >              if ( s >= e )
> >                  break;
> >              if ( e > kexec_crash_area_limit )
> > @@ -1471,7 +1483,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >
> >      if ( modules_headroom && !mod->reserved )
> >          panic("Not enough memory to relocate the dom0 kernel image\n");
> > -    for ( i = 0; i < mbi->mods_count; ++i )
> > +    for ( i = 0; i < boot_info->nr_mods; ++i )
> >      {
> >          uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
> >
> > @@ -1540,7 +1552,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >                      ASSERT(j);
> >                  }
> >                  map_e = boot_e820.map[j].addr + boot_e820.map[j].size;
> > -                for ( j = 0; j < mbi->mods_count; ++j )
> > +                for ( j = 0; j < boot_info->nr_mods; ++j )
> >                  {
> >                      uint64_t end = pfn_to_paddr(mod[j].mod_start) +
> >                                     mod[j].mod_end;
> > @@ -1616,7 +1628,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >          }
> >      }
> >
> > -    for ( i = 0; i < mbi->mods_count; ++i )
> > +    for ( i = 0; i < boot_info->nr_mods; ++i )
> >      {
> >          set_pdx_range(mod[i].mod_start,
> >                        mod[i].mod_start + PFN_UP(mod[i].mod_end));
> > @@ -1999,8 +2011,8 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >             cpu_has_nx ? XENLOG_INFO : XENLOG_WARNING "Warning: ",
> >             cpu_has_nx ? "" : "not ");
> >
> > -    initrdidx = find_first_bit(module_map, mbi->mods_count);
> > -    if ( bitmap_weight(module_map, mbi->mods_count) > 1 )
> > +    initrdidx = find_first_bit(module_map, boot_info->nr_mods);
> > +    if ( bitmap_weight(module_map, boot_info->nr_mods) > 1 )
> >          printk(XENLOG_WARNING
> >                 "Multiple initrd candidates, picking module #%u\n",
> >                 initrdidx);
> > @@ -2010,7 +2022,7 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> >       * above our heap. The second module, if present, is an initrd
> ramdisk.
> >       */
> >      dom0 = create_dom0(mod, modules_headroom,
> > -                       initrdidx < mbi->mods_count ? mod + initrdidx :
> NULL,
> > +                       initrdidx < boot_info->nr_mods ? mod + initrdidx
> : NULL,
> >                         kextra, loader);
> >      if ( !dom0 )
> >          panic("Could not set up DOM0 guest OS\n");
> > diff --git a/xen/include/xen/bootinfo.h b/xen/include/xen/bootinfo.h
> > new file mode 100644
> > index 0000000000..6a7d55d20e
> > --- /dev/null
> > +++ b/xen/include/xen/bootinfo.h
> > @@ -0,0 +1,20 @@
> > +#ifndef __XEN_BOOTINFO_H__
> > +#define __XEN_BOOTINFO_H__
> > +
> > +#include <xen/types.h>
>
> I don't think you need types.h right now
>

Ack - thanks


>
>
> > +struct boot_info {
>
> This is what we call struct bootmodules on ARM right? Would it help if
> we used the same name?
>
> I am not asking to make the ARM code common because I think that would
> probably be a lot more work.
>

It becomes clearer to see by the end of the full hyperlaunch v1 series with
the domain builder implemented, but it is also evident by the end of this
series: the core/common boot info for Xen is more than just a set of
bootmodules. This first patch is part of adding functionality to common
incrementally, as a starting point, and reducing this boot info to just a
bootmodules structure is going to be limiting it in this context.

Christopher


>
>
> > +    unsigned int nr_mods;
> > +};
> > +
> > +#endif
> > +
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * tab-width: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
> > --
> > 2.25.1
> >
> >
>
Stefano Stabellini July 21, 2023, 11:24 p.m. UTC | #3
(You might want to check your email settings because it looks like you
sent an html email)

On Thu, 20 Jul 2023, Christopher Clark wrote:
>       > +struct boot_info {
> 
>       This is what we call struct bootmodules on ARM right? Would it help if
>       we used the same name?
> 
>       I am not asking to make the ARM code common because I think that would
>       probably be a lot more work.

This comment was wrong


> It becomes clearer to see by the end of the full hyperlaunch v1 series with the domain builder implemented, but it is also evident by the
> end of this series: the core/common boot info for Xen is more than just a set of bootmodules. This first patch is part of adding
> functionality to common incrementally, as a starting point, and reducing this boot info to just a bootmodules structure is going to be
> limiting it in this context.

After having read the whole series, it is clear that you made such a
fantastic progress toward unifying all the interfaces, both ARM and x86.
You managed to introduce interfaces so similar to the existing ARM
interfaces, that they are almost the same already. This is way better
than I expected when I wrote that comment to the first patch.

I think we should go the extra mile and move the ARM interfaces to
common, and make any changes needed by x86 there in common and
reflecting the changes back to ARM.

This will also allow us to move more dom0less init code from ARM to
common with fewer changes later on.
Jan Beulich Sept. 19, 2023, 1:04 p.m. UTC | #4
On 01.07.2023 09:18, Christopher Clark wrote:
> @@ -1127,18 +1139,18 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>             bootsym(boot_edd_info_nr));
>  
>      /* Check that we have at least one Multiboot module. */
> -    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
> +    if ( !(mbi->flags & MBI_MODULES) || (boot_info->nr_mods == 0) )
>          panic("dom0 kernel not specified. Check bootloader configuration\n");
>  
>      /* Check that we don't have a silly number of modules. */
> -    if ( mbi->mods_count > sizeof(module_map) * 8 )
> +    if ( boot_info->nr_mods > sizeof(module_map) * 8 )
>      {
> -        mbi->mods_count = sizeof(module_map) * 8;
> +        boot_info->nr_mods = sizeof(module_map) * 8;

As long as you don't replace all consumers of mbi->mods_count (see in
particular the call trees down from early_microcode_init() and down from
xsm_multiboot_init()), I don't think you can drop the original assignment.

>          printk("Excessive multiboot modules - using the first %u only\n",
> -               mbi->mods_count);
> +               boot_info->nr_mods);
>      }
>  
> -    bitmap_fill(module_map, mbi->mods_count);
> +    bitmap_fill(module_map, boot_info->nr_mods);
>      __clear_bit(0, module_map); /* Dom0 kernel is always first */
>  
>      if ( pvh_boot )
> @@ -1311,9 +1323,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      kexec_reserve_area(&boot_e820);
>  
>      initial_images = mod;
> -    nr_initial_images = mbi->mods_count;
> +    boot_info->nr_mods = boot_info->nr_mods;

Overly mechanical change? To prevent such going unnoticed, maybe
boot_info should be pointer-to-const? Would of course require the
bounding to occur earlier, so you truly don't need to write the struct
after filling it in multiboot_to_bootinfo(). Or you move the call to
that function down a little. Yet other options also exist.

> -    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
> +    for ( i = 0; !efi_enabled(EFI_LOADER) && i < boot_info->nr_mods; i++ )

Seeing all sorts of changes of this kind - did you consider naming the
pointer variable (which will become a function parameter as to what I
understood from your reply to Stefano) just "bi"? (I wouldn't suggest
this if the variable was to remain file-scope.)

Jan
diff mbox series

Patch

diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 74e3915a4d..708639b236 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1,3 +1,4 @@ 
+#include <xen/bootinfo.h>
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/err.h>
@@ -268,7 +269,16 @@  static int __init cf_check parse_acpi_param(const char *s)
 custom_param("acpi", parse_acpi_param);
 
 static const module_t *__initdata initial_images;
-static unsigned int __initdata nr_initial_images;
+static struct boot_info __initdata *boot_info;
+
+static void __init multiboot_to_bootinfo(multiboot_info_t *mbi)
+{
+    static struct boot_info __initdata info;
+
+    info.nr_mods = mbi->mods_count;
+
+    boot_info = &info;
+}
 
 unsigned long __init initial_images_nrpages(nodeid_t node)
 {
@@ -277,7 +287,7 @@  unsigned long __init initial_images_nrpages(nodeid_t node)
     unsigned long nr;
     unsigned int i;
 
-    for ( nr = i = 0; i < nr_initial_images; ++i )
+    for ( nr = i = 0; i < boot_info->nr_mods; ++i )
     {
         unsigned long start = initial_images[i].mod_start;
         unsigned long end = start + PFN_UP(initial_images[i].mod_end);
@@ -293,7 +303,7 @@  void __init discard_initial_images(void)
 {
     unsigned int i;
 
-    for ( i = 0; i < nr_initial_images; ++i )
+    for ( i = 0; i < boot_info->nr_mods; ++i )
     {
         uint64_t start = (uint64_t)initial_images[i].mod_start << PAGE_SHIFT;
 
@@ -301,7 +311,7 @@  void __init discard_initial_images(void)
                            start + PAGE_ALIGN(initial_images[i].mod_end));
     }
 
-    nr_initial_images = 0;
+    boot_info->nr_mods = 0;
     initial_images = NULL;
 }
 
@@ -1020,6 +1030,8 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         mod = __va(mbi->mods_addr);
     }
 
+    multiboot_to_bootinfo(mbi);
+
     loader = (mbi->flags & MBI_LOADERNAME)
         ? (char *)__va(mbi->boot_loader_name) : "unknown";
 
@@ -1127,18 +1139,18 @@  void __init noreturn __start_xen(unsigned long mbi_p)
            bootsym(boot_edd_info_nr));
 
     /* Check that we have at least one Multiboot module. */
-    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
+    if ( !(mbi->flags & MBI_MODULES) || (boot_info->nr_mods == 0) )
         panic("dom0 kernel not specified. Check bootloader configuration\n");
 
     /* Check that we don't have a silly number of modules. */
-    if ( mbi->mods_count > sizeof(module_map) * 8 )
+    if ( boot_info->nr_mods > sizeof(module_map) * 8 )
     {
-        mbi->mods_count = sizeof(module_map) * 8;
+        boot_info->nr_mods = sizeof(module_map) * 8;
         printk("Excessive multiboot modules - using the first %u only\n",
-               mbi->mods_count);
+               boot_info->nr_mods);
     }
 
-    bitmap_fill(module_map, mbi->mods_count);
+    bitmap_fill(module_map, boot_info->nr_mods);
     __clear_bit(0, module_map); /* Dom0 kernel is always first */
 
     if ( pvh_boot )
@@ -1311,9 +1323,9 @@  void __init noreturn __start_xen(unsigned long mbi_p)
     kexec_reserve_area(&boot_e820);
 
     initial_images = mod;
-    nr_initial_images = mbi->mods_count;
+    boot_info->nr_mods = boot_info->nr_mods;
 
-    for ( i = 0; !efi_enabled(EFI_LOADER) && i < mbi->mods_count; i++ )
+    for ( i = 0; !efi_enabled(EFI_LOADER) && i < boot_info->nr_mods; i++ )
     {
         if ( mod[i].mod_start & (PAGE_SIZE - 1) )
             panic("Bootloader didn't honor module alignment request\n");
@@ -1337,8 +1349,8 @@  void __init noreturn __start_xen(unsigned long mbi_p)
          * respective reserve_e820_ram() invocation below. No need to
          * query efi_boot_mem_unused() here, though.
          */
-        mod[mbi->mods_count].mod_start = virt_to_mfn(_stext);
-        mod[mbi->mods_count].mod_end = __2M_rwdata_end - _stext;
+        mod[boot_info->nr_mods].mod_start = virt_to_mfn(_stext);
+        mod[boot_info->nr_mods].mod_end = __2M_rwdata_end - _stext;
     }
 
     modules_headroom = bzimage_headroom(bootstrap_map(mod), mod->mod_end);
@@ -1398,7 +1410,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         {
             /* Don't overlap with modules. */
             end = consider_modules(s, e, reloc_size + mask,
-                                   mod, mbi->mods_count, -1);
+                                   mod, boot_info->nr_mods, -1);
             end &= ~mask;
         }
         else
@@ -1419,7 +1431,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         }
 
         /* Is the region suitable for relocating the multiboot modules? */
-        for ( j = mbi->mods_count - 1; j >= 0; j-- )
+        for ( j = boot_info->nr_mods - 1; j >= 0; j-- )
         {
             unsigned long headroom = j ? 0 : modules_headroom;
             unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end);
@@ -1429,7 +1441,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
 
             /* Don't overlap with other modules (or Xen itself). */
             end = consider_modules(s, e, size, mod,
-                                   mbi->mods_count + relocated, j);
+                                   boot_info->nr_mods + relocated, j);
 
             if ( highmem_start && end > highmem_start )
                 continue;
@@ -1456,7 +1468,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         {
             /* Don't overlap with modules (or Xen itself). */
             e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size), mod,
-                                 mbi->mods_count + relocated, -1);
+                                 boot_info->nr_mods + relocated, -1);
             if ( s >= e )
                 break;
             if ( e > kexec_crash_area_limit )
@@ -1471,7 +1483,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
 
     if ( modules_headroom && !mod->reserved )
         panic("Not enough memory to relocate the dom0 kernel image\n");
-    for ( i = 0; i < mbi->mods_count; ++i )
+    for ( i = 0; i < boot_info->nr_mods; ++i )
     {
         uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
 
@@ -1540,7 +1552,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
                     ASSERT(j);
                 }
                 map_e = boot_e820.map[j].addr + boot_e820.map[j].size;
-                for ( j = 0; j < mbi->mods_count; ++j )
+                for ( j = 0; j < boot_info->nr_mods; ++j )
                 {
                     uint64_t end = pfn_to_paddr(mod[j].mod_start) +
                                    mod[j].mod_end;
@@ -1616,7 +1628,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
         }
     }
 
-    for ( i = 0; i < mbi->mods_count; ++i )
+    for ( i = 0; i < boot_info->nr_mods; ++i )
     {
         set_pdx_range(mod[i].mod_start,
                       mod[i].mod_start + PFN_UP(mod[i].mod_end));
@@ -1999,8 +2011,8 @@  void __init noreturn __start_xen(unsigned long mbi_p)
            cpu_has_nx ? XENLOG_INFO : XENLOG_WARNING "Warning: ",
            cpu_has_nx ? "" : "not ");
 
-    initrdidx = find_first_bit(module_map, mbi->mods_count);
-    if ( bitmap_weight(module_map, mbi->mods_count) > 1 )
+    initrdidx = find_first_bit(module_map, boot_info->nr_mods);
+    if ( bitmap_weight(module_map, boot_info->nr_mods) > 1 )
         printk(XENLOG_WARNING
                "Multiple initrd candidates, picking module #%u\n",
                initrdidx);
@@ -2010,7 +2022,7 @@  void __init noreturn __start_xen(unsigned long mbi_p)
      * above our heap. The second module, if present, is an initrd ramdisk.
      */
     dom0 = create_dom0(mod, modules_headroom,
-                       initrdidx < mbi->mods_count ? mod + initrdidx : NULL,
+                       initrdidx < boot_info->nr_mods ? mod + initrdidx : NULL,
                        kextra, loader);
     if ( !dom0 )
         panic("Could not set up DOM0 guest OS\n");
diff --git a/xen/include/xen/bootinfo.h b/xen/include/xen/bootinfo.h
new file mode 100644
index 0000000000..6a7d55d20e
--- /dev/null
+++ b/xen/include/xen/bootinfo.h
@@ -0,0 +1,20 @@ 
+#ifndef __XEN_BOOTINFO_H__
+#define __XEN_BOOTINFO_H__
+
+#include <xen/types.h>
+
+struct boot_info {
+    unsigned int nr_mods;
+};
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */