On Tuesday, April 8th, 2025 at 9:07 AM, Alejandro Vallejo <agarc...@amd.com> wrote:
> > > From: "Daniel P. Smith" dpsm...@apertussolutions.com > > > Add support to read the command line from the hyperlauunch device tree. > The device tree command line is located in the "bootargs" property of the > "multiboot,kernel" node. > > A boot loader command line, e.g. a grub module string field, takes > precendence ove the device tree one since it is easier to modify. > > Signed-off-by: Daniel P. Smith dpsm...@apertussolutions.com > > Signed-off-by: Jason Andryuk jason.andr...@amd.com > > --- > v3: > * Rename to fdt_get_prop_offset() > * Remove size_t cast from builder_get_cmdline_size() > * fdt_get_prop_offset() use strcmp() > * fdt_get_prop_offset() return bool > --- > xen/arch/x86/domain-builder/core.c | 28 +++++++++++++++++++++++ > xen/arch/x86/domain-builder/fdt.c | 6 +++++ > xen/arch/x86/domain-builder/fdt.h | 25 ++++++++++++++++++++ > xen/arch/x86/include/asm/bootinfo.h | 6 +++-- > xen/arch/x86/include/asm/domain-builder.h | 4 ++++ > xen/arch/x86/setup.c | 12 +++++++--- > xen/include/xen/libfdt/libfdt-xen.h | 23 +++++++++++++++++++ > 7 files changed, 99 insertions(+), 5 deletions(-) > > diff --git a/xen/arch/x86/domain-builder/core.c > b/xen/arch/x86/domain-builder/core.c > index eda7fa7a8f..510a74a675 100644 > --- a/xen/arch/x86/domain-builder/core.c > +++ b/xen/arch/x86/domain-builder/core.c > @@ -8,9 +8,37 @@ > #include <xen/lib.h> > > > #include <asm/bootinfo.h> > > +#include <asm/setup.h> > > > #include "fdt.h" > > +size_t __init builder_get_cmdline_size(struct boot_info *bi, int offset) > +{ > +#ifdef CONFIG_DOMAIN_BUILDER > + const void *fdt = bootstrap_map_bm(&bi->mods[HYPERLAUNCH_MODULE_IDX]); > > + int size = fdt_cmdline_prop_size(fdt, offset); > + > + bootstrap_unmap(); > + return size < 0 ? 0 : size; > +#else > + return 0; > +#endif > +} > + > +int __init builder_get_cmdline( > + struct boot_info *bi, int offset, char *cmdline, size_t size) > +{ > +#ifdef CONFIG_DOMAIN_BUILDER > + const void *fdt = bootstrap_map_bm(&bi->mods[HYPERLAUNCH_MODULE_IDX]); > > + int ret = fdt_cmdline_prop_copy(fdt, offset, cmdline, size); > + > + bootstrap_unmap(); > + return ret; > +#else > + return 0; > +#endif > +} > + > void __init builder_init(struct boot_info *bi) > { > if ( IS_ENABLED(CONFIG_DOMAIN_BUILDER) ) > diff --git a/xen/arch/x86/domain-builder/fdt.c > b/xen/arch/x86/domain-builder/fdt.c > index a037c8b6cb..bc9903a9de 100644 > --- a/xen/arch/x86/domain-builder/fdt.c > +++ b/xen/arch/x86/domain-builder/fdt.c > @@ -189,6 +189,12 @@ static int __init process_domain_node( > printk(" kernel: boot module %d\n", idx); > bi->mods[idx].type = BOOTMOD_KERNEL; > > bd->kernel = &bi->mods[idx]; > > + > + /* If bootloader didn't set cmdline, see if FDT provides one. */ > + if ( bd->kernel->cmdline_pa && > > + !((char *)__va(bd->kernel->cmdline_pa))[0] ) > > + bd->kernel->fdt_cmdline = fdt_get_prop_offset( > > + fdt, node, "bootargs", &bd->kernel->cmdline_pa); > > } > } > > diff --git a/xen/arch/x86/domain-builder/fdt.h > b/xen/arch/x86/domain-builder/fdt.h > index e8769dc51c..91f665c8fd 100644 > --- a/xen/arch/x86/domain-builder/fdt.h > +++ b/xen/arch/x86/domain-builder/fdt.h > @@ -12,6 +12,31 @@ struct boot_info; > #define HYPERLAUNCH_MODULE_IDX 0 > > #ifdef CONFIG_DOMAIN_BUILDER > + > +static inline int __init fdt_cmdline_prop_size(const void *fdt, int offset) > +{ > + int ret; > + > + fdt_get_property_by_offset(fdt, offset, &ret); > + > + return ret; > +} > + > +static inline int __init fdt_cmdline_prop_copy( > + const void *fdt, int offset, char *cmdline, size_t size) > +{ > + int ret; > + const struct fdt_property *prop = > + fdt_get_property_by_offset(fdt, offset, &ret); > + > + if ( ret < 0 ) > + return ret; > + > + ASSERT(size > ret); > > + > + return strlcpy(cmdline, prop->data, ret); > > +} > + > int has_hyperlaunch_fdt(const struct boot_info *bi); > int walk_hyperlaunch_fdt(struct boot_info bi); > #else > diff --git a/xen/arch/x86/include/asm/bootinfo.h > b/xen/arch/x86/include/asm/bootinfo.h > index 1e3d582e45..5b2c93b1ef 100644 > --- a/xen/arch/x86/include/asm/bootinfo.h > +++ b/xen/arch/x86/include/asm/bootinfo.h > @@ -35,11 +35,13 @@ struct boot_module { > > / > * Module State Flags: > - * relocated: indicates module has been relocated in memory. > - * released: indicates module's pages have been freed. > + * relocated: indicates module has been relocated in memory. > + * released: indicates module's pages have been freed. > + * fdt_cmdline: indicates module's cmdline is in the FDT. > / > bool relocated:1; > bool released:1; > + bool fdt_cmdline:1; > > / > * A boot module may need decompressing by Xen. Headroom is an estimate of > diff --git a/xen/arch/x86/include/asm/domain-builder.h > b/xen/arch/x86/include/asm/domain-builder.h > index b6d9ba94de..7518b6ddf3 100644 > --- a/xen/arch/x86/include/asm/domain-builder.h > +++ b/xen/arch/x86/include/asm/domain-builder.h > @@ -3,6 +3,10 @@ > > struct boot_info; > > +size_t __init builder_get_cmdline_size(struct boot_info *bi, int offset); > +int __init builder_get_cmdline( > + struct boot_info *bi, int offset, char *cmdline, size_t size); > + > void builder_init(struct boot_info *bi); > > #endif > diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c > index 00e8c8a2a3..ca4415d020 100644 > --- a/xen/arch/x86/setup.c > +++ b/xen/arch/x86/setup.c > @@ -984,7 +984,10 @@ static size_t __init domain_cmdline_size( > { > size_t s = bi->kextra ? strlen(bi->kextra) : 0; > > > - s += bd->kernel->cmdline_pa ? strlen(__va(bd->kernel->cmdline_pa)) : 0; > > + if ( bd->kernel->fdt_cmdline ) > > + s += builder_get_cmdline_size(bi, bd->kernel->cmdline_pa); > > + else > + s += strlen(__va(bd->kernel->cmdline_pa)); > > > if ( s == 0 ) > return s; > @@ -1047,9 +1050,12 @@ static struct domain *__init create_dom0(struct > boot_info *bi) > if ( !(cmdline = xzalloc_array(char, cmdline_size)) ) > panic("Error allocating cmdline buffer for %pd\n", d); > > - if ( bd->kernel->cmdline_pa ) > > + if ( bd->kernel->fdt_cmdline ) > > + builder_get_cmdline( > + bi, bd->kernel->cmdline_pa, cmdline, cmdline_size); > > + else > strlcpy(cmdline, > - cmdline_cook(__va(bd->kernel->cmdline_pa), bi->loader), > > + cmdline_cook(__va(bd->kernel->cmdline_pa),bi->loader), Add extra space before bi->loader? > > cmdline_size); > > if ( bi->kextra ) > > diff --git a/xen/include/xen/libfdt/libfdt-xen.h > b/xen/include/xen/libfdt/libfdt-xen.h > index 2259c09a6a..e473fbaf0c 100644 > --- a/xen/include/xen/libfdt/libfdt-xen.h > +++ b/xen/include/xen/libfdt/libfdt-xen.h > @@ -23,6 +23,29 @@ static inline uint64_t __init fdt_cell_as_u64(const > fdt32_t *cell) > return ((uint64_t)fdt32_to_cpu(cell[0]) << 32) | fdt32_to_cpu(cell[1]); > } > > +static inline bool __init fdt_get_prop_offset( > + const void *fdt, int node, const char *name, unsigned long *offset) > +{ > + int ret, poffset; > + const char *pname; > + > + fdt_for_each_property_offset(poffset, fdt, node) > + { > + fdt_getprop_by_offset(fdt, poffset, &pname, &ret); Return value is not checked. > + > + if ( ret < 0 ) > + continue; > + > + if ( strcmp(pname, name) == 0 ) I got an impression that the preferred form is if ( !strcmp(pname, name) ) > + { > + offset = poffset; > + return true; > + } > + } > + > + return false; > +} > + > / > * Property: reg > * > -- > 2.43.0