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;
+ size_t cmdline_len = bd->cmdline ? strlen(bd->cmdline) + 1 : 0;
const char *initrd_cmdline = NULL;
struct elf_binary elf;
struct elf_dom_parms parms;
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 )
/* 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");
+ 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);
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,
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 )
{
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;
}