@@ -6,6 +6,7 @@
#include <xen/bootdomain.h>
#include <xen/bootinfo.h>
+#include <xen/domain_builder.h>
#include <xen/init.h>
#include <xen/iocap.h>
#include <xen/libelf.h>
@@ -556,31 +557,32 @@ int __init dom0_setup_permissions(struct domain *d)
return rc;
}
-int __init construct_dom0(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline)
+int __init construct_domain(struct boot_domain *bd)
{
- int rc;
+ int rc = 0;
/* Sanity! */
- BUG_ON(!pv_shim && d->domain_id != 0);
- BUG_ON(d->vcpu[0] == NULL);
- BUG_ON(d->vcpu[0]->is_initialised);
+ BUG_ON(!pv_shim && bd->domid != 0);
+ BUG_ON(bd->domain->vcpu[0] == NULL);
+ BUG_ON(bd->domain->vcpu[0]->is_initialised);
process_pending_softirqs();
- if ( is_hvm_domain(d) )
- rc = dom0_construct_pvh(d, image, initrd, cmdline);
- else if ( is_pv_domain(d) )
- rc = dom0_construct_pv(d, image, initrd, cmdline);
- else
- panic("Cannot construct Dom0. No guest interface available\n");
+ if ( builder_is_initdom(bd) )
+ {
+ if ( is_hvm_domain(bd->domain) )
+ rc = dom0_construct_pvh(bd);
+ else if ( is_pv_domain(bd->domain) )
+ rc = dom0_construct_pv(bd);
+ else
+ panic("Cannot construct Dom0. No guest interface available\n");
+ }
if ( rc )
return rc;
/* Sanity! */
- BUG_ON(!d->vcpu[0]->is_initialised);
+ BUG_ON(!bd->domain->vcpu[0]->is_initialised);
return 0;
}
@@ -19,6 +19,7 @@
*/
#include <xen/acpi.h>
+#include <xen/bootdomain.h>
#include <xen/bootinfo.h>
#include <xen/init.h>
#include <xen/libelf.h>
@@ -1217,10 +1218,9 @@ static void __hwdom_init pvh_setup_mmcfg(struct domain *d)
}
}
-int __init dom0_construct_pvh(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline)
+int __init dom0_construct_pvh(struct boot_domain *bd)
{
+ struct domain *d = bd->domain;
paddr_t entry, start_info;
int rc;
@@ -1249,8 +1249,8 @@ int __init dom0_construct_pvh(
return rc;
}
- rc = pvh_load_kernel(d, image, initrd, bootstrap_map(image),
- cmdline, &entry, &start_info);
+ rc = pvh_load_kernel(d, bd->kernel, bd->ramdisk, bootstrap_map(bd->kernel),
+ bd->kernel->string.bytes, &entry, &start_info);
if ( rc )
{
printk("Failed to load Dom0 kernel\n");
@@ -14,13 +14,9 @@ unsigned long dom0_compute_nr_pages(struct domain *d,
unsigned long initrd_len);
int dom0_setup_permissions(struct domain *d);
-int __init dom0_construct_pv(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline);
+int dom0_construct_pv(struct boot_domain *bd);
-int __init dom0_construct_pvh(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline);
+int dom0_construct_pvh(struct boot_domain *bd);
unsigned long dom0_paging_pages(const struct domain *d,
unsigned long nr_pages);
@@ -33,9 +33,8 @@ void vesa_init(void);
static inline void vesa_init(void) {};
#endif
-int construct_dom0(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline);
+int construct_domain(struct boot_domain *bd);
+
void setup_io_bitmap(struct domain *d);
unsigned long initial_images_nrpages(nodeid_t node);
@@ -4,6 +4,7 @@
* Copyright (c) 2002-2005, K A Fraser
*/
+#include <xen/bootdomain.h>
#include <xen/bootinfo.h>
#include <xen/console.h>
#include <xen/domain.h>
@@ -295,9 +296,7 @@ static struct page_info * __init alloc_chunk(struct domain *d,
return page;
}
-int __init dom0_construct_pv(
- struct domain *d, const struct boot_module *image,
- struct boot_module *initrd, char *cmdline)
+int __init dom0_construct_pv(struct boot_domain *bd)
{
int i, rc, order, machine;
bool compatible, compat;
@@ -311,11 +310,12 @@ int __init dom0_construct_pv(
unsigned long count;
struct page_info *page = NULL;
start_info_t *si;
+ struct domain *d = bd->domain;
struct vcpu *v = d->vcpu[0];
- void *image_base = bootstrap_map(image);
- unsigned long image_len = image->size;
- void *image_start = image_base + image->arch->headroom;
- unsigned long initrd_len = initrd ? initrd->size : 0;
+ void *image_base = bootstrap_map(bd->kernel);
+ unsigned long image_len = bd->kernel->size;
+ void *image_start = image_base + bd->kernel->arch->headroom;
+ unsigned long initrd_len = bd->ramdisk ? bd->ramdisk->size : 0;
l4_pgentry_t *l4tab = NULL, *l4start = NULL;
l3_pgentry_t *l3tab = NULL, *l3start = NULL;
l2_pgentry_t *l2tab = NULL, *l2start = NULL;
@@ -355,7 +355,7 @@ int __init dom0_construct_pv(
d->max_pages = ~0U;
if ( (rc =
- bzimage_parse(image_base, &image_start, image->arch->headroom,
+ bzimage_parse(image_base, &image_start, bd->kernel->arch->headroom,
&image_len)) != 0 )
return rc;
@@ -545,7 +545,7 @@ int __init dom0_construct_pv(
initrd_pfn = vinitrd_start ?
(vinitrd_start - v_start) >> PAGE_SHIFT :
domain_tot_pages(d);
- initrd_mfn = mfn = mfn_x(initrd->mfn);
+ initrd_mfn = mfn = mfn_x(bd->ramdisk->mfn);
count = PFN_UP(initrd_len);
if ( d->arch.physaddr_bitsize &&
((mfn + count - 1) >> (d->arch.physaddr_bitsize - PAGE_SHIFT)) )
@@ -560,13 +560,13 @@ int __init dom0_construct_pv(
free_domheap_pages(page, order);
page += 1UL << order;
}
- memcpy(page_to_virt(page), maddr_to_virt(initrd->start),
+ memcpy(page_to_virt(page), maddr_to_virt(bd->ramdisk->start),
initrd_len);
- mpt_alloc = initrd->start;
+ mpt_alloc = bd->ramdisk->start;
init_domheap_pages(mpt_alloc,
mpt_alloc + PAGE_ALIGN(initrd_len));
- bootmodule_update_mfn(initrd, page_to_mfn(page));
- initrd_mfn = mfn_x(initrd->mfn);
+ bootmodule_update_mfn(bd->ramdisk, page_to_mfn(page));
+ initrd_mfn = mfn_x(bd->ramdisk->mfn);
}
else
{
@@ -574,7 +574,7 @@ int __init dom0_construct_pv(
if ( assign_pages(mfn_to_page(_mfn(mfn++)), 1, d, 0) )
BUG();
}
- initrd->size = 0;
+ bd->ramdisk->size = 0;
}
printk("PHYSICAL MEMORY ARRANGEMENT:\n"
@@ -583,9 +583,9 @@ int __init dom0_construct_pv(
if ( domain_tot_pages(d) < nr_pages )
printk(" (%lu pages to be allocated)",
nr_pages - domain_tot_pages(d));
- if ( initrd )
+ if ( bd->ramdisk )
{
- mpt_alloc = initrd->start;
+ mpt_alloc = bd->ramdisk->start;
printk("\n Init. ramdisk: %"PRIpaddr"->%"PRIpaddr,
mpt_alloc, mpt_alloc + initrd_len);
}
@@ -806,7 +806,7 @@ int __init dom0_construct_pv(
if ( pfn >= initrd_pfn )
{
if ( pfn < initrd_pfn + PFN_UP(initrd_len) )
- mfn = mfn_x(initrd->mfn) + (pfn - initrd_pfn);
+ mfn = mfn_x(bd->ramdisk->mfn) + (pfn - initrd_pfn);
else
mfn -= PFN_UP(initrd_len);
}
@@ -866,8 +866,9 @@ int __init dom0_construct_pv(
}
memset(si->cmd_line, 0, sizeof(si->cmd_line));
- if ( cmdline != NULL )
- strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line));
+ if ( strlen(bd->kernel->string.bytes) > 0 )
+ strlcpy((char *)si->cmd_line, bd->kernel->string.bytes,
+ sizeof(si->cmd_line));
#ifdef CONFIG_VIDEO
if ( !pv_shim && fill_console_start_info((void *)(si + 1)) )
@@ -45,7 +45,6 @@
#include <asm/edd.h>
#include <xsm/xsm.h>
#include <asm/tboot.h>
-#include <asm/bzimage.h> /* for bzimage_headroom */
#include <asm/mach-generic/mach_apic.h> /* for generic_apic_probe */
#include <asm/setup.h>
#include <xen/cpu.h>
@@ -272,6 +271,24 @@ static int __init cf_check parse_acpi_param(const char *s)
}
custom_param("acpi", parse_acpi_param);
+void __init arch_builder_apply_cmdline(
+ struct boot_info *info, struct boot_domain *bd)
+{
+ if ( skip_ioapic_setup && !strstr(bd->kernel->string.bytes, "noapic") )
+ strlcat(bd->kernel->string.bytes, " noapic", MAX_GUEST_CMDLINE);
+ if ( (strlen(acpi_param) == 0) && acpi_disabled )
+ {
+ printk("ACPI is disabled, notifying Domain 0 (acpi=off)\n");
+ strlcpy(acpi_param, "off", sizeof(acpi_param));
+ }
+ if ( (strlen(acpi_param) != 0) &&
+ !strstr(bd->kernel->string.bytes, "acpi=") )
+ {
+ strlcat(bd->kernel->string.bytes, " acpi=", MAX_GUEST_CMDLINE);
+ strlcat(bd->kernel->string.bytes, acpi_param, MAX_GUEST_CMDLINE);
+ }
+}
+
struct boot_info __initdata *boot_info;
unsigned long __init initial_images_nrpages(nodeid_t node)
@@ -728,7 +745,8 @@ static unsigned int __init copy_bios_e820(struct e820entry *map, unsigned int li
return n;
}
-static struct domain *__init create_dom0(const struct boot_info *bi)
+static struct domain *__init create_dom0(
+ const struct boot_info *bi, struct boot_domain *bd)
{
struct xen_domctl_createdomain dom0_cfg = {
.flags = IS_ENABLED(CONFIG_TBOOT) ? XEN_DOMCTL_CDF_s3_integrity : 0,
@@ -741,14 +759,10 @@ static struct domain *__init create_dom0(const struct boot_info *bi)
.misc_flags = opt_dom0_msr_relaxed ? XEN_X86_MSR_RELAXED : 0,
},
};
- struct boot_module *image = bootmodule_next_by_kind(bi, BOOTMOD_KERNEL, 0);
- struct boot_module *initrd = bootmodule_next_by_kind(bi, BOOTMOD_RAMDISK, 0);
- struct domain *d;
char *cmdline;
- domid_t domid = 0;
- if ( image == NULL )
- panic("Error creating d%uv0\n", domid);
+ if ( bd->kernel == NULL )
+ panic("Error creating d%uv0\n", bd->domid);
if ( opt_dom0_pvh )
{
@@ -764,45 +778,46 @@ static struct domain *__init create_dom0(const struct boot_info *bi)
dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
/* Create initial domain. Not d0 for pvshim. */
- domid = get_initial_domain_id();
- d = domain_create(domid, &dom0_cfg, pv_shim ? 0 : CDF_privileged);
- if ( IS_ERR(d) )
- panic("Error creating d%u: %ld\n", domid, PTR_ERR(d));
+ bd->domid = get_initial_domain_id();
+ bd->domain = domain_create(bd->domid, &dom0_cfg, pv_shim ?
+ 0 : CDF_privileged);
+ if ( IS_ERR(bd->domain) )
+ panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(bd->domain));
- init_dom0_cpuid_policy(d);
+ init_dom0_cpuid_policy(bd->domain);
- if ( alloc_dom0_vcpu0(d) == NULL )
- panic("Error creating d%uv0\n", domid);
+ if ( alloc_dom0_vcpu0(bd->domain) == NULL )
+ panic("Error creating d%uv0\n", bd->domid);
/* Grab the DOM0 command line. */
- cmdline = (image->string.kind == BOOTSTR_CMDLINE) ?
- image->string.bytes : NULL;
+ cmdline = (bd->kernel->string.kind == BOOTSTR_CMDLINE) ?
+ bd->kernel->string.bytes : NULL;
if ( cmdline || bi->arch->kextra )
{
- static char __initdata dom0_cmdline[MAX_GUEST_CMDLINE];
+ char dom0_cmdline[MAX_GUEST_CMDLINE];
cmdline = arch_prepare_cmdline(cmdline, bi->arch);
- safe_strcpy(dom0_cmdline, cmdline);
+ strlcpy(dom0_cmdline, cmdline, MAX_GUEST_CMDLINE);
if ( bi->arch->kextra )
/* kextra always includes exactly one leading space. */
- safe_strcat(dom0_cmdline, bi->arch->kextra);
+ strlcat(dom0_cmdline, bi->arch->kextra, MAX_GUEST_CMDLINE);
/* Append any extra parameters. */
if ( skip_ioapic_setup && !strstr(dom0_cmdline, "noapic") )
- safe_strcat(dom0_cmdline, " noapic");
+ strlcat(dom0_cmdline, " noapic", MAX_GUEST_CMDLINE);
if ( (strlen(acpi_param) == 0) && acpi_disabled )
{
printk("ACPI is disabled, notifying Domain 0 (acpi=off)\n");
- safe_strcpy(acpi_param, "off");
+ strlcpy(acpi_param, "off", sizeof(acpi_param));
}
if ( (strlen(acpi_param) != 0) && !strstr(dom0_cmdline, "acpi=") )
{
- safe_strcat(dom0_cmdline, " acpi=");
- safe_strcat(dom0_cmdline, acpi_param);
+ strlcat(dom0_cmdline, " acpi=", MAX_GUEST_CMDLINE);
+ strlcat(dom0_cmdline, acpi_param, MAX_GUEST_CMDLINE);
}
- cmdline = dom0_cmdline;
+ strlcpy(bd->kernel->string.bytes, dom0_cmdline, MAX_GUEST_CMDLINE);
}
/*
@@ -816,7 +831,7 @@ static struct domain *__init create_dom0(const struct boot_info *bi)
write_cr4(read_cr4() & ~X86_CR4_SMAP);
}
- if ( construct_dom0(d, image, initrd, cmdline) != 0 )
+ if ( construct_domain(bd) != 0 )
panic("Could not construct domain 0\n");
if ( cpu_has_smap )
@@ -825,14 +840,14 @@ static struct domain *__init create_dom0(const struct boot_info *bi)
cr4_pv32_mask |= X86_CR4_SMAP;
}
- return d;
+ return bd->domain;
}
void __init arch_create_dom(
const struct boot_info *bi, struct boot_domain *bd)
{
if ( builder_is_initdom(bd) )
- create_dom0(bi);
+ create_dom0(bi, bd);
}
/* How much of the directmap is prebuilt at compile time. */
@@ -1010,10 +1025,7 @@ void __init noreturn __start_xen(unsigned long bi_p)
boot_info->nr_mods);
}
- /* Dom0 kernel is the first boot module */
- boot_info->mods[0].kind = BOOTMOD_KERNEL;
- if ( boot_info->mods[0].string.len )
- boot_info->mods[0].string.kind = BOOTSTR_CMDLINE;
+ builder_init(boot_info);
if ( pvh_boot )
{
@@ -1168,11 +1180,6 @@ void __init noreturn __start_xen(unsigned long bi_p)
boot_info->mods[boot_info->nr_mods].size = __2M_rwdata_end - _stext;
}
- boot_info->mods[0].arch->headroom = bzimage_headroom(
- bootstrap_map(&boot_info->mods[0]),
- boot_info->mods[0].size);
- bootstrap_map(NULL);
-
#ifndef highmem_start
/* Don't allow split below 4Gb. */
if ( highmem_start < GB(4) )
@@ -1905,22 +1912,29 @@ void __init noreturn __start_xen(unsigned long bi_p)
cpu_has_nx ? XENLOG_INFO : XENLOG_WARNING "Warning: ",
cpu_has_nx ? "" : "not ");
- initrdidx = bootmodule_next_idx_by_kind(boot_info, BOOTMOD_UNKNOWN, 0);
- if ( initrdidx < boot_info->nr_mods )
- boot_info->mods[initrdidx].kind = BOOTMOD_RAMDISK;
-
- if ( bootmodule_count_by_kind(boot_info, BOOTMOD_UNKNOWN) > 1 )
- printk(XENLOG_WARNING
- "Multiple initrd candidates, picking module #%u\n",
- initrdidx);
-
/*
- * We're going to setup domain0 using the module(s) that we stashed safely
- * above our heap. The second module, if present, is an initrd ramdisk.
+ * Boot description not provided, check to see if there are any remaining
+ * boot modules, the first one found will be provided as the ramdisk.
*/
- dom0 = create_dom0(boot_info);
+ if ( ! boot_info->builder->fdt_enabled )
+ {
+ initrdidx = bootmodule_next_idx_by_kind(boot_info, BOOTMOD_UNKNOWN, 0);
+ if ( initrdidx < boot_info->nr_mods )
+ {
+ boot_info->builder->domains[0].ramdisk = &boot_info->mods[initrdidx];
+ boot_info->mods[initrdidx].kind = BOOTMOD_RAMDISK;
+ }
+ if ( bootmodule_count_by_kind(boot_info, BOOTMOD_UNKNOWN) > 1 )
+ printk(XENLOG_WARNING
+ "Multiple initrd candidates, picking module #%u\n",
+ initrdidx);
+ }
+
+ builder_create_domains(boot_info);
+
+ dom0 = builder_get_hwdom(boot_info);
if ( !dom0 )
- panic("Could not set up DOM0 guest OS\n");
+ panic("No hardware domain was built\n");
heap_init_late();