[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 05/23] xen/arm: introduce bootcmdlines
On Tue, 9 Oct 2018, Julien Grall wrote: > On 05/10/2018 19:47, Stefano Stabellini wrote: > > Introduce a new array to store the cmdline of each boot module. It is > > separate from struct bootmodules. Remove the cmdline field from struct > > boot_module. This way, kernels and initrds with the same address in > > memory can share struct bootmodule (important because we want them to be > > free'd only once), but they can still have their separate bootcmdline > > entries. > > > > Add a dt_name field to struct bootcmdline to make it easier to find the > > correct entry. Store the name of the "xen,domain" compatible node (for > > example "Dom1"). This is a better choice compared to the name of the > > "multiboot,kernel" compatible node, because their names are not unique. > > For instance there can be more than one "module@0x4c000000" in the > > system, but there can only be one "/chosen/Dom1". > > > > Add a pointer to struct kernel_info to point to the cmdline for a given > > kernel. > > > > Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx> > > > > --- > > > > Changes in v4: > > - check that the multiboot node is under /chosen > > - use cmd and cmds as variable names for struct bootcmdline and struct > > bootcmdline* > > - fix printk > > - use ASSERT instea of panic > > - do not add empty cmdline entries > > - add more debug printks to early_print_info > > - code style fixes > > - add comment on DT_MAX_NAME > > - increase DT_MAX_NAME to 41 > > - make nr_mods unsigned int > > > > Changes in v3: > > - introduce bootcmdlines > > - do not modify boot_fdt_cmdline > > - add comments > > > > Changes in v2: > > - new patch > > --- > > xen/arch/arm/bootfdt.c | 82 > > +++++++++++++++++++++++++++++++++------------ > > xen/arch/arm/domain_build.c | 8 +++-- > > xen/arch/arm/kernel.h | 1 + > > xen/arch/arm/setup.c | 24 +++++++++---- > > xen/include/asm-arm/setup.h | 17 ++++++++-- > > 5 files changed, 99 insertions(+), 33 deletions(-) > > > > diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c > > index 8eba42c..273032b 100644 > > --- a/xen/arch/arm/bootfdt.c > > +++ b/xen/arch/arm/bootfdt.c > > @@ -163,6 +163,37 @@ static void __init process_memory_node(const void *fdt, > > int node, > > } > > } > > +static void __init add_boot_cmdline(const void *fdt, int node, > > + const char *name, bootmodule_kind kind) > > +{ > > + struct bootcmdlines *cmds = &bootinfo.cmdlines; > > + struct bootcmdline *cmd; > > + const struct fdt_property *prop; > > + int len; > > + const char *cmdline; > > + > > + if ( cmds->nr_mods == MAX_MODULES ) > > + { > > + printk("Ignoring %s cmdline (too many)\n", name); > > + return; > > + } > > + > > + prop = fdt_get_property(fdt, node, "bootargs", &len); > > + if ( !prop ) > > + return; > > + > > + cmd = &cmds->cmdline[cmds->nr_mods++]; > > + cmd->kind = kind; > > + > > + ASSERT(strlen(name) <= DT_MAX_NAME); > > + safe_strcpy(cmd->dt_name, name); > > + > > + if ( len > BOOTMOD_MAX_CMDLINE ) > > + panic("module %s command line too long\n", name); > > + cmdline = prop->data; > > + safe_strcpy(cmd->cmdline, cmdline); > > +} > > + > > static void __init process_multiboot_node(const void *fdt, int node, > > const char *name, > > u32 address_cells, u32 > > size_cells) > > @@ -172,8 +203,20 @@ static void __init process_multiboot_node(const void > > *fdt, int node, > > const __be32 *cell; > > bootmodule_kind kind; > > paddr_t start, size; > > - const char *cmdline; > > - int len; > > + int len = sizeof("/chosen"); > > + char path[8]; /* sizeof "/chosen" */ > > + int parent_node; > > + > > + parent_node = fdt_parent_offset(fdt, node); > > + ASSERT(parent_node >= 0); > > + > > + /* Check that the node is under "chosen" */ > > + fdt_get_path(fdt, node, path, len); > > It would be good if you test the code with wrong node. For instance > fdt_get_path may not fill path (i.e if the buffer is too short). So path will > contain garbage. I'll do > > + if ( strncmp(path, "/chosen", len - 1) ) > > + { > > + printk("DEBUG %s %s\n",name,path); > > This looks like a left-over from your debug. I'll remove > > + return; > > + } > As I said in the previous patch, this needs to be fixed first. By that I meant > this should be a separate patch so it could be backported. I'll separate it out > Also, with this patch you change correctly the behavior to deny node not in > chosen. But you don't explain in the commit message that it affects the > current multiboot node. I'll mention it. > However, I still don't think this code is correct. You would allow the > following path /chosen/foo/bar/multiboot. The parent would be "bar" and there > are no guarantee it would be uniq (it is not under /chosen). I think this > could be fixed by taking into account the depth of the node. > AFAICT, the multiboot node should always be at maximum depth 3. I'll add a check. > > prop = fdt_get_property(fdt, node, "reg", &len); > > if ( !prop ) > > @@ -220,17 +263,8 @@ static void __init process_multiboot_node(const void > > *fdt, int node, > > kind = BOOTMOD_XSM; > > } > > - prop = fdt_get_property(fdt, node, "bootargs", &len); > > - if ( prop ) > > - { > > - if ( len > BOOTMOD_MAX_CMDLINE ) > > - panic("module %s command line too long\n", name); > > - cmdline = prop->data; > > - } > > - else > > - cmdline = NULL; > > - > > - add_boot_module(kind, start, size, cmdline); > > + add_boot_module(kind, start, size); > > + add_boot_cmdline(fdt, node, fdt_get_name(fdt, parent_node, &len), > > kind); > > } > > static void __init process_chosen_node(const void *fdt, int node, > > @@ -276,7 +310,7 @@ static void __init process_chosen_node(const void *fdt, > > int node, > > printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end); > > - add_boot_module(BOOTMOD_RAMDISK, start, end-start, NULL); > > + add_boot_module(BOOTMOD_RAMDISK, start, end-start); > > } > > static int __init early_scan_node(const void *fdt, > > @@ -299,6 +333,7 @@ static void __init early_print_info(void) > > { > > struct meminfo *mi = &bootinfo.mem; > > struct bootmodules *mods = &bootinfo.modules; > > + struct bootcmdlines *cmds = &bootinfo.cmdlines; > > int i, nr_rsvd; > > for ( i = 0; i < mi->nr_banks; i++ ) > > @@ -307,12 +342,12 @@ static void __init early_print_info(void) > > mi->bank[i].start + mi->bank[i].size - 1); > > printk("\n"); > > for ( i = 0 ; i < mods->nr_mods; i++ ) > > - printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %-12s %s\n", > > + printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %-12s\n", > > i, > > mods->module[i].start, > > mods->module[i].start + mods->module[i].size, > > - boot_module_kind_as_string(mods->module[i].kind), > > - mods->module[i].cmdline); > > + boot_module_kind_as_string(mods->module[i].kind)); > > + > > nr_rsvd = fdt_num_mem_rsv(device_tree_flattened); > > for ( i = 0; i < nr_rsvd; i++ ) > > { > > @@ -325,6 +360,11 @@ static void __init early_print_info(void) > > i, s, e); > > } > > printk("\n"); > > + for ( i = 0 ; i < cmds->nr_mods; i++ ) > > + printk("CMDLINE[%d]:%s %s\n", i, > > + cmds->cmdline[i].dt_name, > > + &cmds->cmdline[i].cmdline[0]); > > Thank you for adding the command line. However, there are still no way to > associate the command line with a module. For each command line, you should be > able to know the associate module. It is possible once the whole series is committed, by using boot_cmdline_find_by_name and the domU field introduced later in this series. I could move boot_cmdline_find_by_name earlier, but since there are no callers, I would have to #if 0 it. My choice would be to leave things as they are. > > + printk("\n"); > > } > > /** > > @@ -341,7 +381,7 @@ size_t __init boot_fdt_info(const void *fdt, paddr_t > > paddr) > > if ( ret < 0 ) > > panic("No valid device tree\n"); > > - add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), NULL); > > + add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt)); > > device_tree_for_each_node((void *)fdt, early_scan_node, NULL); > > early_print_info(); > > @@ -361,11 +401,11 @@ const char *boot_fdt_cmdline(const void *fdt) > > prop = fdt_get_property(fdt, node, "xen,xen-bootargs", NULL); > > if ( prop == NULL ) > > { > > - struct bootmodule *dom0_mod = > > - boot_module_find_by_kind(BOOTMOD_KERNEL); > > + struct bootcmdline *dom0_cmdline = > > + boot_cmdline_find_by_kind(BOOTMOD_KERNEL); > > if (fdt_get_property(fdt, node, "xen,dom0-bootargs", NULL) || > > - ( dom0_mod && dom0_mod->cmdline[0] ) ) > > + ( dom0_cmdline && dom0_cmdline->cmdline[0] ) ) > > prop = fdt_get_property(fdt, node, "bootargs", NULL); > > } > > if ( prop == NULL ) > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > > index f552154..64f8d6b 100644 > > --- a/xen/arch/arm/domain_build.c > > +++ b/xen/arch/arm/domain_build.c > > @@ -375,7 +375,7 @@ static int __init write_properties(struct domain *d, > > struct kernel_info *kinfo, > > int res = 0; > > int had_dom0_bootargs = 0; > > - const struct bootmodule *kernel = kinfo->kernel_bootmodule; > > + const struct bootcmdline *kernel = > > boot_cmdline_find_by_kind(BOOTMOD_KERNEL); > > Why do you need to lookup the command line here? You have just introduced a > field in kinfo to store command line. good point, I'll use the new field here > > if ( kernel && kernel->cmdline[0] ) > > bootargs = &kernel->cmdline[0]; > > @@ -952,9 +952,9 @@ static int __init make_chosen_node(const struct > > kernel_info *kinfo) > > if ( res ) > > return res; > > - if ( mod && mod->cmdline[0] ) > > + if ( kinfo->cmdline && kinfo->cmdline[0] ) > > { > > - bootargs = &mod->cmdline[0]; > > + bootargs = &kinfo->cmdline[0]; > > res = fdt_property(fdt, "bootargs", bootargs, strlen(bootargs) + > > 1); > > if ( res ) > > return res; > > @@ -2109,6 +2109,7 @@ static void __init find_gnttab_region(struct domain > > *d, > > int __init construct_dom0(struct domain *d) > > { > > + const struct bootcmdline *kernel = > > boot_cmdline_find_by_kind(BOOTMOD_KERNEL); > > struct kernel_info kinfo = {}; > > struct vcpu *saved_current; > > int rc, i, cpu; > > @@ -2154,6 +2155,7 @@ int __init construct_dom0(struct domain *d) > > #endif > > + kinfo.cmdline = kernel != NULL ? &kernel->cmdline[0] : NULL; > > allocate_memory(d, &kinfo); > > find_gnttab_region(d, &kinfo); > > diff --git a/xen/arch/arm/kernel.h b/xen/arch/arm/kernel.h > > index 47eacb5..39b7828 100644 > > --- a/xen/arch/arm/kernel.h > > +++ b/xen/arch/arm/kernel.h > > @@ -29,6 +29,7 @@ struct kernel_info { > > /* boot blob load addresses */ > > const struct bootmodule *kernel_bootmodule, *initrd_bootmodule; > > + const char* cmdline; > > paddr_t dtb_paddr; > > paddr_t initrd_paddr; > > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > > index ea2495a..bc7dd97 100644 > > --- a/xen/arch/arm/setup.c > > +++ b/xen/arch/arm/setup.c > > @@ -201,8 +201,7 @@ void __init dt_unreserved_regions(paddr_t s, paddr_t e, > > } > > struct bootmodule __init *add_boot_module(bootmodule_kind kind, > > - paddr_t start, paddr_t size, > > - const char *cmdline) > > + paddr_t start, paddr_t size) > > { > > struct bootmodules *mods = &bootinfo.modules; > > struct bootmodule *mod; > > @@ -218,10 +217,6 @@ struct bootmodule __init > > *add_boot_module(bootmodule_kind kind, > > mod->kind = kind; > > mod->start = start; > > mod->size = size; > > - if ( cmdline ) > > - safe_strcpy(mod->cmdline, cmdline); > > - else > > - mod->cmdline[0] = 0; > > return mod; > > } > > @@ -240,6 +235,21 @@ struct bootmodule * __init > > boot_module_find_by_kind(bootmodule_kind kind) > > return NULL; > > } > > +struct bootcmdline * __init boot_cmdline_find_by_kind(bootmodule_kind > > kind) > > Functions dealing with a same structure should stick together. I actually > quite dislike that add_bood_cmdline is part of bootfdt.c. There are no need > for it to be there except the fact you moved the FDT lookup in the function. > As I suggested in the previous patch, the lookup could have been left outside > of the function. I'll move add_bood_cmdline to setup.c. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |