@@ -317,17 +317,31 @@ static int hvm_set_mca_capabilities(libxl__gc *gc, uint32_t domid,
static void hvm_set_conf_params(xc_interface *handle, uint32_t domid,
libxl_domain_build_info *const info)
{
- xc_hvm_param_set(handle, domid, HVM_PARAM_PAE_ENABLED,
- libxl_defbool_val(info->u.hvm.pae));
+ switch(info->type) {
+ case LIBXL_DOMAIN_TYPE_PVH:
+ xc_hvm_param_set(handle, domid, HVM_PARAM_PAE_ENABLED, true);
+ xc_hvm_param_set(handle, domid, HVM_PARAM_TIMER_MODE,
+ timer_mode(info));
+ xc_hvm_param_set(handle, domid, HVM_PARAM_NESTEDHVM,
+ libxl_defbool_val(info->nested_hvm));
+ break;
+ case LIBXL_DOMAIN_TYPE_HVM:
+ xc_hvm_param_set(handle, domid, HVM_PARAM_PAE_ENABLED,
+ libxl_defbool_val(info->u.hvm.pae));
#if defined(__i386__) || defined(__x86_64__)
- xc_hvm_param_set(handle, domid, HVM_PARAM_HPET_ENABLED,
- libxl_defbool_val(info->u.hvm.hpet));
+ xc_hvm_param_set(handle, domid, HVM_PARAM_HPET_ENABLED,
+ libxl_defbool_val(info->u.hvm.hpet));
#endif
- xc_hvm_param_set(handle, domid, HVM_PARAM_TIMER_MODE, timer_mode(info));
- xc_hvm_param_set(handle, domid, HVM_PARAM_VPT_ALIGN,
- libxl_defbool_val(info->u.hvm.vpt_align));
- xc_hvm_param_set(handle, domid, HVM_PARAM_NESTEDHVM,
- libxl_defbool_val(info->nested_hvm));
+ xc_hvm_param_set(handle, domid, HVM_PARAM_TIMER_MODE,
+ timer_mode(info));
+ xc_hvm_param_set(handle, domid, HVM_PARAM_VPT_ALIGN,
+ libxl_defbool_val(info->u.hvm.vpt_align));
+ xc_hvm_param_set(handle, domid, HVM_PARAM_NESTEDHVM,
+ libxl_defbool_val(info->nested_hvm));
+ break;
+ default:
+ abort();
+ }
}
int libxl__build_pre(libxl__gc *gc, uint32_t domid,
@@ -467,9 +481,11 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
- if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
+ if (info->type != LIBXL_DOMAIN_TYPE_PV)
hvm_set_conf_params(ctx->xch, domid, info);
+
#if defined(__i386__) || defined(__x86_64__)
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
rc = hvm_set_viridian_features(gc, domid, info);
if (rc)
return rc;
@@ -477,10 +493,10 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
rc = hvm_set_mca_capabilities(gc, domid, info);
if (rc)
return rc;
-#endif
}
+#endif
- /* Alternate p2m support on x86 is available only for HVM guests. */
+ /* Alternate p2m support on x86 is available only for PVH/HVM guests. */
if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
/* The config parameter "altp2m" replaces the parameter "altp2mhvm". For
* legacy reasons, both parameters are accepted on x86 HVM guests.
@@ -494,6 +510,9 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
else
xc_hvm_param_set(ctx->xch, domid, HVM_PARAM_ALTP2M,
info->altp2m);
+ } else if (info->type == LIBXL_DOMAIN_TYPE_PVH) {
+ xc_hvm_param_set(ctx->xch, domid, HVM_PARAM_ALTP2M,
+ info->altp2m);
}
rc = libxl__arch_domain_create(gc, d_config, domid);
@@ -847,7 +866,7 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
uint64_t str_mfn, cons_mfn;
int i;
- if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE) {
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
va_map = xc_map_foreign_range(handle, domid,
XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
HVM_INFO_PFN);
@@ -903,7 +922,7 @@ static int hvm_build_set_xs_values(libxl__gc *gc,
/* Only one module can be passed. PVHv2 guests do not support this. */
if (dom->acpi_modules[0].guest_addr_out &&
- info->device_model_version !=LIBXL_DEVICE_MODEL_VERSION_NONE) {
+ info->type == LIBXL_DOMAIN_TYPE_HVM) {
path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_ADDRESS, domid);
ret = libxl__xs_printf(gc, XBT_NULL, path, "0x%"PRIx64,
@@ -964,6 +983,7 @@ out:
static int libxl__domain_firmware(libxl__gc *gc,
libxl_domain_build_info *info,
+ libxl__domain_build_state *state,
struct xc_dom_image *dom)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -973,39 +993,64 @@ static int libxl__domain_firmware(libxl__gc *gc,
void *data;
const char *bios_filename = NULL;
- if (info->u.hvm.firmware)
- firmware = info->u.hvm.firmware;
- else {
- switch (info->device_model_version)
- {
- case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
- firmware = "hvmloader";
- break;
- case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
- firmware = "hvmloader";
- break;
- case LIBXL_DEVICE_MODEL_VERSION_NONE:
- if (info->kernel == NULL) {
- LOG(ERROR, "no device model requested without a kernel");
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
+ if (info->u.hvm.firmware) {
+ firmware = info->u.hvm.firmware;
+ } else {
+ switch (info->device_model_version)
+ {
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ firmware = "hvmloader";
+ break;
+ default:
+ LOG(ERROR, "invalid device model version %d",
+ info->device_model_version);
rc = ERROR_FAIL;
goto out;
}
- break;
- default:
- LOG(ERROR, "invalid device model version %d",
- info->device_model_version);
- rc = ERROR_FAIL;
- goto out;
}
}
- if (info->kernel != NULL &&
- info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) {
+ if (state->pv_kernel.path != NULL && info->type == LIBXL_DOMAIN_TYPE_PVH) {
/* Try to load a kernel instead of the firmware. */
- rc = xc_dom_kernel_file(dom, info->kernel);
- if (rc == 0 && info->ramdisk != NULL)
- rc = xc_dom_ramdisk_file(dom, info->ramdisk);
+ if (state->pv_kernel.mapped) {
+ rc = xc_dom_kernel_mem(dom, state->pv_kernel.data,
+ state->pv_kernel.size);
+ if (rc) {
+ LOGE(ERROR, "xc_dom_kernel_mem failed");
+ goto out;
+ }
+ } else {
+ rc = xc_dom_kernel_file(dom, state->pv_kernel.path);
+ if (rc) {
+ LOGE(ERROR, "xc_dom_kernel_file failed");
+ goto out;
+ }
+ }
+
+ if (state->pv_ramdisk.path && strlen(state->pv_ramdisk.path)) {
+ if (state->pv_ramdisk.mapped) {
+ rc = xc_dom_ramdisk_mem(dom, state->pv_ramdisk.data,
+ state->pv_ramdisk.size);
+ if (rc) {
+ LOGE(ERROR, "xc_dom_ramdisk_mem failed");
+ goto out;
+ }
+ } else {
+ rc = xc_dom_ramdisk_file(dom, state->pv_ramdisk.path);
+ if (rc) {
+ LOGE(ERROR, "xc_dom_ramdisk_file failed");
+ goto out;
+ }
+ }
+ }
} else {
+ /*
+ * Only HVM guests should get here, PVH should always have a set
+ * kernel at this point.
+ */
+ assert(info->type == LIBXL_DOMAIN_TYPE_HVM);
rc = xc_dom_kernel_file(dom, libxl__abs_path(gc, firmware,
libxl__xenfirmwaredir_path()));
}
@@ -1015,7 +1060,8 @@ static int libxl__domain_firmware(libxl__gc *gc,
goto out;
}
- if (info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
if (info->u.hvm.system_firmware) {
bios_filename = info->u.hvm.system_firmware;
} else {
@@ -1039,7 +1085,8 @@ static int libxl__domain_firmware(libxl__gc *gc,
if (rc) goto out;
}
- if (info->u.hvm.smbios_firmware) {
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ info->u.hvm.smbios_firmware) {
data = NULL;
e = libxl_read_file_contents(ctx, info->u.hvm.smbios_firmware,
&data, &datalen);
@@ -1057,14 +1104,8 @@ static int libxl__domain_firmware(libxl__gc *gc,
}
}
- if (info->u.hvm.acpi_firmware) {
-
- if (info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) {
- LOGE(ERROR, "PVH guests do not allow loading ACPI modules");
- rc = ERROR_FAIL;
- goto out;
- }
-
+ if (info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ info->u.hvm.acpi_firmware) {
data = NULL;
e = libxl_read_file_contents(ctx, info->u.hvm.acpi_firmware,
&data, &datalen);
@@ -1097,13 +1138,12 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
uint64_t mmio_start, lowmem_end, highmem_end, mem_size;
libxl_domain_build_info *const info = &d_config->b_info;
struct xc_dom_image *dom = NULL;
- bool device_model =
- info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_NONE ?
- true : false;
+ bool device_model = info->type == LIBXL_DOMAIN_TYPE_HVM ? true : false;
xc_dom_loginit(ctx->xch);
- dom = xc_dom_allocate(ctx->xch, info->cmdline, NULL);
+ dom = xc_dom_allocate(ctx->xch, info->type == LIBXL_DOMAIN_TYPE_PVH ?
+ state->pv_cmdline : info->cmdline, NULL);
if (!dom) {
LOGE(ERROR, "xc_dom_allocate failed");
rc = ERROR_NOMEM;
@@ -1128,7 +1168,7 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
dom->mmio_size = info->u.hvm.mmio_hole_memkb << 10;
}
- rc = libxl__domain_firmware(gc, info, dom);
+ rc = libxl__domain_firmware(gc, info, state, dom);
if (rc != 0) {
LOG(ERROR, "initializing domain firmware failed");
goto out;
And remove device model "none" support. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> --- Cc: Ian Jackson <ian.jackson@eu.citrix.com> Cc: Wei Liu <wei.liu2@citrix.com> --- tools/libxl/libxl_dom.c | 148 ++++++++++++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 54 deletions(-)