aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorRoss Philipson <ross.philipson@citrix.com>2013-02-15 13:32:16 +0000
committerRoss Philipson <ross.philipson@citrix.com>2013-02-15 13:32:16 +0000
commitdcd468855afed1fd205278beb60a4e3df21b3289 (patch)
tree715db917fd8d01be83f1761d63ae18fef894733a /tools
parenta234675150adfca751ed36c0ef68712160ff1ab9 (diff)
downloadxen-dcd468855afed1fd205278beb60a4e3df21b3289.tar.gz
xen-dcd468855afed1fd205278beb60a4e3df21b3289.tar.bz2
xen-dcd468855afed1fd205278beb60a4e3df21b3289.zip
libxl: HVM firmware passthrough support
This patch introduces support for two new parameters in libxl: smbios_firmware=<path_to_smbios_structures_file> acpi_firmware=<path_to_acpi_tables_file> The changes are primarily in the domain building code where the firmware files are read and passed to libxc for loading into the new guest. After the domain building call to libxc, the addresses for the loaded blobs are returned and written to xenstore. LIBXL_HAVE_FIRMWARE_PASSTHROUGH is defined in libxl.h to allow users to determine if the feature is present. This patch also updates the xl.cfg man page with descriptions of the two new parameters for firmware passthrough. Signed-off-by: Ross Philipson <ross.philipson@citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/libxl/libxl.h7
-rw-r--r--tools/libxl/libxl_dom.c132
-rw-r--r--tools/libxl/libxl_types.idl2
-rw-r--r--tools/libxl/xl_cmdimpl.c5
4 files changed, 129 insertions, 17 deletions
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 72e5efb6d1..030aa86d52 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -68,6 +68,13 @@
*/
/*
+ * LIBXL_HAVE_FIRMWARE_PASSTHROUGH indicates the feature for
+ * passing in SMBIOS and ACPI firmware to HVM guests is present
+ * in the library.
+ */
+#define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 33ae5583d8..8fe4fc4d06 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -21,6 +21,7 @@
#include <xc_dom.h>
#include <xen/hvm/hvm_info_table.h>
+#include <xen/hvm/hvm_xs_strings.h>
libxl_domain_type libxl__domain_type(libxl__gc *gc, uint32_t domid)
{
@@ -510,11 +511,61 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
return 0;
}
-static const char *libxl__domain_firmware(libxl__gc *gc,
- libxl_domain_build_info *info)
+static int hvm_build_set_xs_values(libxl__gc *gc,
+ uint32_t domid,
+ struct xc_hvm_build_args *args)
+{
+ char *path = NULL;
+ int ret = 0;
+
+ if (args->smbios_module.guest_addr_out) {
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_ADDRESS, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
+ args->smbios_module.guest_addr_out);
+ if (ret)
+ goto err;
+
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_SMBIOS_PT_LENGTH, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
+ args->smbios_module.length);
+ if (ret)
+ goto err;
+ }
+
+ if (args->acpi_module.guest_addr_out) {
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_ADDRESS, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%"PRIx64,
+ args->acpi_module.guest_addr_out);
+ if (ret)
+ goto err;
+
+ path = GCSPRINTF("/local/domain/%d/"HVM_XS_ACPI_PT_LENGTH, domid);
+
+ ret = libxl__xs_write(gc, XBT_NULL, path, "0x%x",
+ args->acpi_module.length);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+
+err:
+ LOG(ERROR, "failed to write firmware xenstore value, err: %d", ret);
+ return ret;
+}
+
+static int libxl__domain_firmware(libxl__gc *gc,
+ libxl_domain_build_info *info,
+ struct xc_hvm_build_args *args)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
const char *firmware;
+ int e, rc = ERROR_FAIL;
+ int datalen = 0;
+ void *data;
if (info->u.hvm.firmware)
firmware = info->u.hvm.firmware;
@@ -528,13 +579,52 @@ static const char *libxl__domain_firmware(libxl__gc *gc,
firmware = "hvmloader";
break;
default:
- LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "invalid device model version %d",
- info->device_model_version);
- return NULL;
+ LOG(ERROR, "invalid device model version %d",
+ info->device_model_version);
+ return ERROR_FAIL;
break;
}
}
- return libxl__abs_path(gc, firmware, libxl__xenfirmwaredir_path());
+ args->image_file_name = libxl__abs_path(gc, firmware,
+ libxl__xenfirmwaredir_path());
+
+ if (info->u.hvm.smbios_firmware) {
+ data = NULL;
+ e = libxl_read_file_contents(ctx, info->u.hvm.smbios_firmware,
+ &data, &datalen);
+ if (e) {
+ LOGEV(ERROR, e, "failed to read SMBIOS firmware file %s",
+ info->u.hvm.smbios_firmware);
+ goto out;
+ }
+ libxl__ptr_add(gc, data);
+ if (datalen) {
+ /* Only accept non-empty files */
+ args->smbios_module.data = data;
+ args->smbios_module.length = (uint32_t)datalen;
+ }
+ }
+
+ if (info->u.hvm.acpi_firmware) {
+ data = NULL;
+ e = libxl_read_file_contents(ctx, info->u.hvm.acpi_firmware,
+ &data, &datalen);
+ if (e) {
+ LOGEV(ERROR, e, "failed to read ACPI firmware file %s",
+ info->u.hvm.acpi_firmware);
+ goto out;
+ }
+ libxl__ptr_add(gc, data);
+ if (datalen) {
+ /* Only accept non-empty files */
+ args->acpi_module.data = data;
+ args->acpi_module.length = (uint32_t)datalen;
+ }
+ }
+
+ return 0;
+out:
+ return rc;
}
int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
@@ -544,10 +634,6 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
libxl_ctx *ctx = libxl__gc_owner(gc);
struct xc_hvm_build_args args = {};
int ret, rc = ERROR_FAIL;
- const char *firmware = libxl__domain_firmware(gc, info);
-
- if (!firmware)
- goto out;
memset(&args, 0, sizeof(struct xc_hvm_build_args));
/* The params from the configuration file are in Mb, which are then
@@ -557,22 +643,34 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
*/
args.mem_size = (uint64_t)(info->max_memkb - info->video_memkb) << 10;
args.mem_target = (uint64_t)(info->target_memkb - info->video_memkb) << 10;
- args.image_file_name = firmware;
+
+ if (libxl__domain_firmware(gc, info, &args)) {
+ LOG(ERROR, "initializing domain firmware failed");
+ goto out;
+ }
ret = xc_hvm_build(ctx->xch, domid, &args);
if (ret) {
- LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm building failed");
+ LOGEV(ERROR, ret, "hvm building failed");
goto out;
}
+
ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
&state->store_mfn, state->console_port,
&state->console_mfn, state->store_domid,
state->console_domid);
if (ret) {
- LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm build set params failed");
+ LOGEV(ERROR, ret, "hvm build set params failed");
goto out;
}
- rc = 0;
+
+ ret = hvm_build_set_xs_values(gc, domid, &args);
+ if (ret) {
+ LOG(ERROR, "hvm build set xenstore values failed (ret=%d)", ret);
+ goto out;
+ }
+
+ return 0;
out:
return rc;
}
@@ -634,7 +732,7 @@ int libxl__toolstack_restore(uint32_t domid, const uint8_t *buf,
memcpy(&count, ptr, sizeof(count));
ptr += sizeof(count);
-
+
if (size < sizeof(version) + sizeof(count) +
count * (sizeof(struct libxl__physmap_info))) {
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "wrong size");
@@ -848,7 +946,7 @@ static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch *watch,
rc = libxl__xs_rm_checked(gc, t, lds->ret_path);
if (rc) goto out;
- rc = libxl__xs_transaction_commit(gc, &t);
+ rc = libxl__xs_transaction_commit(gc, &t);
if (!rc) break;
if (rc<0) goto out;
}
@@ -1320,7 +1418,7 @@ void libxl__xc_domain_save_done(libxl__egc *egc, void *dss_void,
if (type == LIBXL_DOMAIN_TYPE_HVM) {
rc = libxl__domain_suspend_device_model(gc, dss);
if (rc) goto out;
-
+
libxl__domain_save_device_model(egc, dss, domain_suspend_done);
return;
}
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index acc4bc9d9c..89a80300fe 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -308,6 +308,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
("vpt_align", libxl_defbool),
("timer_mode", libxl_timer_mode),
("nested_hvm", libxl_defbool),
+ ("smbios_firmware", string),
+ ("acpi_firmware", string),
("nographic", libxl_defbool),
("vga", libxl_vga_interface_info),
("vnc", libxl_vnc_info),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index bdd1865bf6..9c554ba040 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -882,6 +882,11 @@ static void parse_config_data(const char *config_source,
}
xlu_cfg_get_defbool(config, "nestedhvm", &b_info->u.hvm.nested_hvm, 0);
+
+ xlu_cfg_replace_string(config, "smbios_firmware",
+ &b_info->u.hvm.smbios_firmware, 0);
+ xlu_cfg_replace_string(config, "acpi_firmware",
+ &b_info->u.hvm.acpi_firmware, 0);
break;
case LIBXL_DOMAIN_TYPE_PV:
{