[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 01/13] x86/boot: add cmdline to struct boot_domain
On Thu, Apr 17, 2025 at 01:48:23PM +0100, Alejandro Vallejo wrote: > From: "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx> > > Add a container for the "cooked" command line for a domain. This > provides for the backing memory to be directly associated with the > domain being constructed. This is done in anticipation that the domain > construction path may need to be invoked multiple times, thus ensuring > each instance had a distinct memory allocation. > > Signed-off-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx> > Signed-off-by: Alejandro Vallejo <agarciav@xxxxxxx> Reviewed-by: Denis Mukhin <dmukhin@xxxxxxxx> > --- > v4: > * Manually nullify bd->cmdline before xfree()ing cmdline. > * const-ify arguments of domain_cmdline_size() > * Add cmdline_len to pvh_load_kernel() > --- > xen/arch/x86/hvm/dom0_build.c | 31 ++++++++-------- > xen/arch/x86/include/asm/boot-domain.h | 1 + > xen/arch/x86/pv/dom0_build.c | 4 +- > xen/arch/x86/setup.c | 51 ++++++++++++++++++++------ > 4 files changed, 57 insertions(+), 30 deletions(-) > > diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c > index 2a094b3145..49832f921c 100644 > --- a/xen/arch/x86/hvm/dom0_build.c > +++ b/xen/arch/x86/hvm/dom0_build.c > @@ -653,7 +653,7 @@ static int __init pvh_load_kernel( > void *image_start = image_base + image->headroom; > unsigned long image_len = image->size; > unsigned long initrd_len = initrd ? initrd->size : 0; > - const char *cmdline = image->cmdline_pa ? __va(image->cmdline_pa) : NULL; > + unsigned long cmdline_len = bd->cmdline ? strlen(bd->cmdline) + 1 : 0; > const char *initrd_cmdline = NULL; > struct elf_binary elf; > struct elf_dom_parms parms; > @@ -736,8 +736,7 @@ static int __init pvh_load_kernel( > initrd = NULL; > } > > - if ( cmdline ) > - extra_space += elf_round_up(&elf, strlen(cmdline) + 1); > + extra_space += elf_round_up(&elf, cmdline_len); > > last_addr = find_memory(d, &elf, extra_space); > if ( last_addr == INVALID_PADDR ) > @@ -778,21 +777,21 @@ static int __init pvh_load_kernel( > /* Free temporary buffers. */ > free_boot_modules(); > > - if ( cmdline != NULL ) > + rc = hvm_copy_to_guest_phys(last_addr, bd->cmdline, cmdline_len, v); > + if ( rc ) > { > - rc = hvm_copy_to_guest_phys(last_addr, cmdline, strlen(cmdline) + 1, > v); > - if ( rc ) > - { > - printk("Unable to copy guest command line\n"); > - return rc; > - } > - start_info.cmdline_paddr = last_addr; > - /* > - * Round up to 32/64 bits (depending on the guest kernel bitness) so > - * the modlist/start_info is aligned. > - */ > - last_addr += elf_round_up(&elf, strlen(cmdline) + 1); > + printk("Unable to copy guest command line\n"); Side note: I think it makes sense to add domain ID to all printouts in pvh_load_kernel(). E.g. block under elf_xen_parse() logs domain ID. > + return rc; > } > + > + start_info.cmdline_paddr = cmdline_len ? last_addr : 0; > + > + /* > + * Round up to 32/64 bits (depending on the guest kernel bitness) so > + * the modlist/start_info is aligned. > + */ > + last_addr += elf_round_up(&elf, cmdline_len); > + > if ( initrd != NULL ) > { > rc = hvm_copy_to_guest_phys(last_addr, &mod, sizeof(mod), v); > diff --git a/xen/arch/x86/include/asm/boot-domain.h > b/xen/arch/x86/include/asm/boot-domain.h > index fcbedda0f0..d7c6042e25 100644 > --- a/xen/arch/x86/include/asm/boot-domain.h > +++ b/xen/arch/x86/include/asm/boot-domain.h > @@ -15,6 +15,7 @@ struct boot_domain { > > struct boot_module *kernel; > struct boot_module *module; > + const char *cmdline; > > struct domain *d; > }; > diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c > index b485eea05f..e1b78d47c2 100644 > --- a/xen/arch/x86/pv/dom0_build.c > +++ b/xen/arch/x86/pv/dom0_build.c > @@ -972,8 +972,8 @@ static int __init dom0_construct(const struct boot_domain > *bd) > } > > memset(si->cmd_line, 0, sizeof(si->cmd_line)); > - if ( image->cmdline_pa ) > - strlcpy((char *)si->cmd_line, __va(image->cmdline_pa), > sizeof(si->cmd_line)); > + if ( bd->cmdline ) > + strlcpy((char *)si->cmd_line, bd->cmdline, sizeof(si->cmd_line)); > > #ifdef CONFIG_VIDEO > if ( !pv_shim && fill_console_start_info((void *)(si + 1)) ) > diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c > index 3c257f0bad..4df012460d 100644 > --- a/xen/arch/x86/setup.c > +++ b/xen/arch/x86/setup.c > @@ -978,10 +978,30 @@ static unsigned int __init copy_bios_e820(struct > e820entry *map, unsigned int li > return n; > } > > -static struct domain *__init create_dom0(struct boot_info *bi) > +static size_t __init domain_cmdline_size(const struct boot_info *bi, > + const struct boot_domain *bd) > { > - static char __initdata cmdline[MAX_GUEST_CMDLINE]; > + size_t s = bi->kextra ? strlen(bi->kextra) : 0; > + > + s += bd->kernel->cmdline_pa ? strlen(__va(bd->kernel->cmdline_pa)) : 0; > > + if ( s == 0 ) > + return s; > + > + /* > + * Certain parameters from the Xen command line may be added to the dom0 > + * command line. Add additional space for the possible cases along with > one > + * extra char to hold \0. > + */ > + s += strlen(" noapic") + strlen(" acpi=") + sizeof(acpi_param) + 1; > + > + return s; > +} > + > +static struct domain *__init create_dom0(struct boot_info *bi) > +{ > + char *cmdline = NULL; > + size_t cmdline_size; > struct xen_domctl_createdomain dom0_cfg = { > .flags = IS_ENABLED(CONFIG_TBOOT) ? XEN_DOMCTL_CDF_s3_integrity : 0, > .max_evtchn_port = -1, > @@ -1020,20 +1040,24 @@ static struct domain *__init create_dom0(struct > boot_info *bi) > if ( alloc_dom0_vcpu0(d) == NULL ) > panic("Error creating %pdv0\n", d); > > - /* Grab the DOM0 command line. */ > - if ( bd->kernel->cmdline_pa || bi->kextra ) > + cmdline_size = domain_cmdline_size(bi, bd); > + if ( cmdline_size ) > { > + if ( !(cmdline = xzalloc_array(char, cmdline_size)) ) > + panic("Error allocating cmdline buffer for %pd\n", d); > + > if ( bd->kernel->cmdline_pa ) > - safe_strcpy(cmdline, > - cmdline_cook(__va(bd->kernel->cmdline_pa), > bi->loader)); > + strlcpy(cmdline, > + cmdline_cook(__va(bd->kernel->cmdline_pa), bi->loader), > + cmdline_size); > > if ( bi->kextra ) > /* kextra always includes exactly one leading space. */ > - safe_strcat(cmdline, bi->kextra); > + strlcat(cmdline, bi->kextra, cmdline_size); > > /* Append any extra parameters. */ > if ( skip_ioapic_setup && !strstr(cmdline, "noapic") ) > - safe_strcat(cmdline, " noapic"); > + strlcat(cmdline, " noapic", cmdline_size); > > if ( (strlen(acpi_param) == 0) && acpi_disabled ) > { > @@ -1043,17 +1067,20 @@ static struct domain *__init create_dom0(struct > boot_info *bi) > > if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") ) > { > - safe_strcat(cmdline, " acpi="); > - safe_strcat(cmdline, acpi_param); > + strlcat(cmdline, " acpi=", cmdline_size); > + strlcat(cmdline, acpi_param, cmdline_size); > } > - > - bd->kernel->cmdline_pa = __pa(cmdline); > + bd->kernel->cmdline_pa = 0; > + bd->cmdline = cmdline; > } > > bd->d = d; > if ( construct_dom0(bd) != 0 ) > panic("Could not construct domain 0\n"); > > + bd->cmdline = NULL; > + xfree(cmdline); > + > return d; > } > > -- > 2.43.0 > >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |