From dde22055ac3aa45eb9ec4b297874638c2a25c320 Mon Sep 17 00:00:00 2001 From: Matthew Fioravante Date: Tue, 13 Nov 2012 10:46:59 +0000 Subject: libxl: add vtpm support This patch adds vtpm support to libxl. It adds vtpm parsing to config files and 3 new xl commands: vtpm-attach vtpm-detach vtpm-list Signed-off-by: Matthew Fioravante Acked-by: Ian Campbell Committed-by: Ian Campbell --- tools/libxl/libxl.c | 247 +++++++++++++++++++++++++++++++++++ tools/libxl/libxl.h | 23 +++- tools/libxl/libxl_create.c | 43 +++++- tools/libxl/libxl_device.c | 2 + tools/libxl/libxl_internal.h | 9 ++ tools/libxl/libxl_types.idl | 18 +++ tools/libxl/libxl_types_internal.idl | 1 + tools/libxl/libxl_utils.c | 43 ++++++ tools/libxl/libxl_utils.h | 5 + tools/libxl/xl.h | 3 + tools/libxl/xl_cmdimpl.c | 184 +++++++++++++++++++++++++- tools/libxl/xl_cmdtable.c | 15 +++ 12 files changed, 586 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 665385b318..be457f4765 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -1709,6 +1709,243 @@ out: return; } +/******************************************************************************/ +int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm) +{ + if(libxl_uuid_is_nil(&vtpm->uuid)) { + libxl_uuid_generate(&vtpm->uuid); + } + return 0; +} + +static int libxl__device_from_vtpm(libxl__gc *gc, uint32_t domid, + libxl_device_vtpm *vtpm, + libxl__device *device) +{ + device->backend_devid = vtpm->devid; + device->backend_domid = vtpm->backend_domid; + device->backend_kind = LIBXL__DEVICE_KIND_VTPM; + device->devid = vtpm->devid; + device->domid = domid; + device->kind = LIBXL__DEVICE_KIND_VTPM; + + return 0; +} + +void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid, + libxl_device_vtpm *vtpm, + libxl__ao_device *aodev) +{ + STATE_AO_GC(aodev->ao); + flexarray_t *front; + flexarray_t *back; + libxl__device *device; + char *dompath, **l; + unsigned int nb, rc; + + rc = libxl__device_vtpm_setdefault(gc, vtpm); + if (rc) goto out; + + front = flexarray_make(gc, 16, 1); + back = flexarray_make(gc, 16, 1); + + if(vtpm->devid == -1) { + if (!(dompath = libxl__xs_get_dompath(gc, domid))) { + rc = ERROR_FAIL; + goto out; + } + l = libxl__xs_directory(gc, XBT_NULL, + GCSPRINTF("%s/device/vtpm", dompath), &nb); + if(l == NULL || nb == 0) { + vtpm->devid = 0; + } else { + vtpm->devid = strtoul(l[nb - 1], NULL, 10) + 1; + } + } + + GCNEW(device); + rc = libxl__device_from_vtpm(gc, domid, vtpm, device); + if ( rc != 0 ) goto out; + + flexarray_append(back, "frontend-id"); + flexarray_append(back, GCSPRINTF("%d", domid)); + flexarray_append(back, "online"); + flexarray_append(back, "1"); + flexarray_append(back, "state"); + flexarray_append(back, GCSPRINTF("%d", 1)); + flexarray_append(back, "handle"); + flexarray_append(back, GCSPRINTF("%d", vtpm->devid)); + + flexarray_append(back, "uuid"); + flexarray_append(back, GCSPRINTF(LIBXL_UUID_FMT, LIBXL_UUID_BYTES(vtpm->uuid))); + flexarray_append(back, "resume"); + flexarray_append(back, "False"); + + flexarray_append(front, "backend-id"); + flexarray_append(front, GCSPRINTF("%d", vtpm->backend_domid)); + flexarray_append(front, "state"); + flexarray_append(front, GCSPRINTF("%d", 1)); + flexarray_append(front, "handle"); + flexarray_append(front, GCSPRINTF("%d", vtpm->devid)); + + libxl__device_generic_add(gc, XBT_NULL, device, + libxl__xs_kvs_of_flexarray(gc, back, back->count), + libxl__xs_kvs_of_flexarray(gc, front, front->count)); + + aodev->dev = device; + aodev->action = DEVICE_CONNECT; + libxl__wait_device_connection(egc, aodev); + + rc = 0; +out: + aodev->rc = rc; + if(rc) aodev->callback(egc, aodev); + return; +} + +libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *num) +{ + GC_INIT(ctx); + + libxl_device_vtpm* vtpms = NULL; + char* fe_path = NULL; + char** dir = NULL; + unsigned int ndirs = 0; + + *num = 0; + + fe_path = libxl__sprintf(gc, "%s/device/vtpm", libxl__xs_get_dompath(gc, domid)); + dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs); + if(dir) { + vtpms = malloc(sizeof(*vtpms) * ndirs); + libxl_device_vtpm* vtpm; + libxl_device_vtpm* end = vtpms + ndirs; + for(vtpm = vtpms; vtpm < end; ++vtpm, ++dir) { + char* tmp; + const char* be_path = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/%s/backend", + fe_path, *dir)); + + vtpm->devid = atoi(*dir); + + tmp = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/%s/backend_id", + fe_path, *dir)); + vtpm->backend_domid = atoi(tmp); + + tmp = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/uuid", be_path)); + if(tmp) { + if(libxl_uuid_from_string(&(vtpm->uuid), tmp)) { + LOG(ERROR, "%s/uuid is a malformed uuid?? (%s) Probably a bug!!\n", be_path, tmp); + exit(1); + } + } + } + } + *num = ndirs; + + GC_FREE; + return vtpms; +} + +int libxl_device_vtpm_getinfo(libxl_ctx *ctx, + uint32_t domid, + libxl_device_vtpm *vtpm, + libxl_vtpminfo *vtpminfo) +{ + GC_INIT(ctx); + char *dompath, *vtpmpath; + char *val; + int rc = 0; + + libxl_vtpminfo_init(vtpminfo); + dompath = libxl__xs_get_dompath(gc, domid); + vtpminfo->devid = vtpm->devid; + + vtpmpath = GCSPRINTF("%s/device/vtpm/%d", dompath, vtpminfo->devid); + vtpminfo->backend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/backend", vtpmpath), NULL); + if (!vtpminfo->backend) { + goto err; + } + if(!libxl__xs_read(gc, XBT_NULL, vtpminfo->backend)) { + goto err; + } + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/backend-id", vtpmpath)); + vtpminfo->backend_id = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/state", vtpmpath)); + vtpminfo->state = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/event-channel", vtpmpath)); + vtpminfo->evtch = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/ring-ref", vtpmpath)); + vtpminfo->rref = val ? strtoul(val, NULL, 10) : -1; + + vtpminfo->frontend = xs_read(ctx->xsh, XBT_NULL, + GCSPRINTF("%s/frontend", vtpminfo->backend), NULL); + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/frontend-id", vtpminfo->backend)); + vtpminfo->frontend_id = val ? strtoul(val, NULL, 10) : -1; + + val = libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/uuid", vtpminfo->backend)); + if(val == NULL) { + LOG(ERROR, "%s/uuid does not exist!\n", vtpminfo->backend); + goto err; + } + if(libxl_uuid_from_string(&(vtpminfo->uuid), val)) { + LOG(ERROR, + "%s/uuid is a malformed uuid?? (%s) Probably a bug!\n", + vtpminfo->backend, val); + goto err; + } + + goto exit; +err: + rc = ERROR_FAIL; +exit: + GC_FREE; + return rc; +} + +int libxl_devid_to_device_vtpm(libxl_ctx *ctx, + uint32_t domid, + int devid, + libxl_device_vtpm *vtpm) +{ + libxl_device_vtpm *vtpms; + int nb, i; + int rc; + + vtpms = libxl_device_vtpm_list(ctx, domid, &nb); + if (!vtpms) + return ERROR_FAIL; + + memset(vtpm, 0, sizeof (libxl_device_vtpm)); + rc = 1; + for (i = 0; i < nb; ++i) { + if(devid == vtpms[i].devid) { + vtpm->backend_domid = vtpms[i].backend_domid; + vtpm->devid = vtpms[i].devid; + libxl_uuid_copy(&vtpm->uuid, &vtpms[i].uuid); + rc = 0; + break; + } + } + + libxl_device_vtpm_list_free(vtpms, nb); + return rc; +} + + /******************************************************************************/ int libxl__device_disk_setdefault(libxl__gc *gc, libxl_device_disk *disk) @@ -3046,6 +3283,8 @@ out: * libxl_device_disk_destroy * libxl_device_nic_remove * libxl_device_nic_destroy + * libxl_device_vtpm_remove + * libxl_device_vtpm_destroy * libxl_device_vkb_remove * libxl_device_vkb_destroy * libxl_device_vfb_remove @@ -3097,6 +3336,10 @@ DEFINE_DEVICE_REMOVE(vkb, destroy, 1) DEFINE_DEVICE_REMOVE(vfb, remove, 0) DEFINE_DEVICE_REMOVE(vfb, destroy, 1) +/* vtpm */ +DEFINE_DEVICE_REMOVE(vtpm, remove, 0) +DEFINE_DEVICE_REMOVE(vtpm, destroy, 1) + #undef DEFINE_DEVICE_REMOVE /******************************************************************************/ @@ -3105,6 +3348,7 @@ DEFINE_DEVICE_REMOVE(vfb, destroy, 1) /* The following functions are defined: * libxl_device_disk_add * libxl_device_nic_add + * libxl_device_vtpm_add */ #define DEFINE_DEVICE_ADD(type) \ @@ -3131,6 +3375,9 @@ DEFINE_DEVICE_ADD(disk) /* nic */ DEFINE_DEVICE_ADD(nic) +/* vtpm */ +DEFINE_DEVICE_ADD(vtpm) + #undef DEFINE_DEVICE_ADD /******************************************************************************/ diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 7a7c4193ef..e2ba5495d4 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -478,13 +478,14 @@ typedef struct { libxl_domain_create_info c_info; libxl_domain_build_info b_info; - int num_disks, num_nics, num_pcidevs, num_vfbs, num_vkbs; + int num_disks, num_nics, num_pcidevs, num_vfbs, num_vkbs, num_vtpms; libxl_device_disk *disks; libxl_device_nic *nics; libxl_device_pci *pcidevs; libxl_device_vfb *vfbs; libxl_device_vkb *vkbs; + libxl_device_vtpm *vtpms; libxl_action_on_shutdown on_poweroff; libxl_action_on_shutdown on_reboot; @@ -645,6 +646,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, int *nb_vcpu, int *nr_vcpus_out); void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus); +void libxl_device_vtpm_list_free(libxl_device_vtpm*, int nr_vtpms); +void libxl_vtpminfo_list_free(libxl_vtpminfo *, int nr_vtpms); + /* * Devices * ======= @@ -745,6 +749,23 @@ libxl_device_nic *libxl_device_nic_list(libxl_ctx *ctx, uint32_t domid, int *num int libxl_device_nic_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic, libxl_nicinfo *nicinfo); +/* Virtual TPMs */ +int libxl_device_vtpm_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vtpm *vtpm, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_vtpm_remove(libxl_ctx *ctx, uint32_t domid, + libxl_device_vtpm *vtpm, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; +int libxl_device_vtpm_destroy(libxl_ctx *ctx, uint32_t domid, + libxl_device_vtpm *vtpm, + const libxl_asyncop_how *ao_how) + LIBXL_EXTERNAL_CALLERS_ONLY; + +libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *num); +int libxl_device_vtpm_getinfo(libxl_ctx *ctx, uint32_t domid, + libxl_device_vtpm *vtpm, libxl_vtpminfo *vtpminfo); + /* Keyboard */ int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb, const libxl_asyncop_how *ao_how) diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index e81747b2bc..9d20086347 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -55,6 +55,8 @@ void libxl_domain_config_dispose(libxl_domain_config *d_config) libxl_device_vkb_dispose(&d_config->vkbs[i]); free(d_config->vkbs); + libxl_device_vtpm_list_free(d_config->vtpms, d_config->num_vtpms); + libxl_domain_create_info_dispose(&d_config->c_info); libxl_domain_build_info_dispose(&d_config->b_info); } @@ -601,6 +603,8 @@ static void domcreate_bootloader_done(libxl__egc *egc, static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *aodevs, int ret); +static void domcreate_attach_vtpms(libxl__egc *egc, libxl__multidev *multidev, + int ret); static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *aodevs, int ret); @@ -1085,13 +1089,13 @@ static void domcreate_devmodel_started(libxl__egc *egc, if (d_config->num_nics > 0) { /* Attach nics */ libxl__multidev_begin(ao, &dcs->multidev); - dcs->multidev.callback = domcreate_attach_pci; + dcs->multidev.callback = domcreate_attach_vtpms; libxl__add_nics(egc, ao, domid, d_config, &dcs->multidev); libxl__multidev_prepared(egc, &dcs->multidev, 0); return; } - domcreate_attach_pci(egc, &dcs->multidev, 0); + domcreate_attach_vtpms(egc, &dcs->multidev, 0); return; error_out: @@ -1099,6 +1103,39 @@ error_out: domcreate_complete(egc, dcs, ret); } +static void domcreate_attach_vtpms(libxl__egc *egc, + libxl__multidev *multidev, + int ret) +{ + libxl__domain_create_state *dcs = CONTAINER_OF(multidev, *dcs, multidev); + STATE_AO_GC(dcs->ao); + int domid = dcs->guest_domid; + + libxl_domain_config* const d_config = dcs->guest_config; + + if(ret) { + LOG(ERROR, "unable to add nic devices"); + goto error_out; + } + + /* Plug vtpm devices */ + if (d_config->num_vtpms > 0) { + /* Attach vtpms */ + libxl__multidev_begin(ao, &dcs->multidev); + dcs->multidev.callback = domcreate_attach_pci; + libxl__add_vtpms(egc, ao, domid, d_config, &dcs->multidev); + libxl__multidev_prepared(egc, &dcs->multidev, 0); + return; + } + + domcreate_attach_pci(egc, multidev, 0); + return; + +error_out: + assert(ret); + domcreate_complete(egc, dcs, ret); +} + static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev, int ret) { @@ -1112,7 +1149,7 @@ static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *multidev, libxl_domain_config *const d_config = dcs->guest_config; if (ret) { - LOG(ERROR, "unable to add nic devices"); + LOG(ERROR, "unable to add vtpm devices"); goto error_out; } diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index c3283f1d88..51dd06e483 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -497,6 +497,7 @@ void libxl__multidev_prepared(libxl__egc *egc, * The following functions are defined: * libxl__add_disks * libxl__add_nics + * libxl__add_vtpms */ #define DEFINE_DEVICES_ADD(type) \ @@ -515,6 +516,7 @@ void libxl__multidev_prepared(libxl__egc *egc, DEFINE_DEVICES_ADD(disk) DEFINE_DEVICES_ADD(nic) +DEFINE_DEVICES_ADD(vtpm) #undef DEFINE_DEVICES_ADD diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 8f220cb05b..cba3616f75 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -958,6 +958,7 @@ _hidden int libxl__device_disk_setdefault(libxl__gc *gc, libxl_device_disk *disk); _hidden int libxl__device_nic_setdefault(libxl__gc *gc, libxl_device_nic *nic, uint32_t domid); +_hidden int libxl__device_vtpm_setdefault(libxl__gc *gc, libxl_device_vtpm *vtpm); _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb); _hidden int libxl__device_vkb_setdefault(libxl__gc *gc, libxl_device_vkb *vkb); _hidden int libxl__device_pci_setdefault(libxl__gc *gc, libxl_device_pci *pci); @@ -2007,6 +2008,10 @@ _hidden void libxl__device_nic_add(libxl__egc *egc, uint32_t domid, libxl_device_nic *nic, libxl__ao_device *aodev); +_hidden void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid, + libxl_device_vtpm *vtpm, + libxl__ao_device *aodev); + /* Internal function to connect a vkb device */ _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid, libxl_device_vkb *vkb); @@ -2439,6 +2444,10 @@ _hidden void libxl__add_nics(libxl__egc *egc, libxl__ao *ao, uint32_t domid, libxl_domain_config *d_config, libxl__multidev *multidev); +_hidden void libxl__add_vtpms(libxl__egc *egc, libxl__ao *ao, uint32_t domid, + libxl_domain_config *d_config, + libxl__multidev *multidev); + /*----- device model creation -----*/ /* First layer; wraps libxl__spawn_spawn. */ diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index de111a6b5c..7eac4a8709 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -395,6 +395,12 @@ libxl_device_pci = Struct("device_pci", [ ("permissive", bool), ]) +libxl_device_vtpm = Struct("device_vtpm", [ + ("backend_domid", libxl_domid), + ("devid", libxl_devid), + ("uuid", libxl_uuid), +]) + libxl_diskinfo = Struct("diskinfo", [ ("backend", string), ("backend_id", uint32), @@ -418,6 +424,18 @@ libxl_nicinfo = Struct("nicinfo", [ ("rref_rx", integer), ], dir=DIR_OUT) +libxl_vtpminfo = Struct("vtpminfo", [ + ("backend", string), + ("backend_id", uint32), + ("frontend", string), + ("frontend_id", uint32), + ("devid", libxl_devid), + ("state", integer), + ("evtch", integer), + ("rref", integer), + ("uuid", libxl_uuid), + ], dir=DIR_OUT) + libxl_vcpuinfo = Struct("vcpuinfo", [ ("vcpuid", uint32), ("cpu", uint32), diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl index 5ac8c9cf56..c40120e9d6 100644 --- a/tools/libxl/libxl_types_internal.idl +++ b/tools/libxl/libxl_types_internal.idl @@ -19,6 +19,7 @@ libxl__device_kind = Enumeration("device_kind", [ (5, "VFB"), (6, "VKBD"), (7, "CONSOLE"), + (8, "VTPM"), ]) libxl__console_backend = Enumeration("console_backend", [ diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index 55cd29981b..8f7879060f 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -463,6 +463,33 @@ int libxl_pipe(libxl_ctx *ctx, int pipes[2]) return 0; } +int libxl_uuid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid, + libxl_uuid* uuid, libxl_device_vtpm *vtpm) +{ + libxl_device_vtpm *vtpms; + int nb, i; + int rc; + + vtpms = libxl_device_vtpm_list(ctx, domid, &nb); + if (!vtpms) + return ERROR_FAIL; + + memset(vtpm, 0, sizeof (libxl_device_vtpm)); + rc = 1; + for (i = 0; i < nb; ++i) { + if(!libxl_uuid_compare(uuid, &vtpms[i].uuid)) { + vtpm->backend_domid = vtpms[i].backend_domid; + vtpm->devid = vtpms[i].devid; + libxl_uuid_copy(&vtpm->uuid, &vtpms[i].uuid); + rc = 0; + break; + } + } + + libxl_device_vtpm_list_free(vtpms, nb); + return rc; +} + int libxl_mac_to_device_nic(libxl_ctx *ctx, uint32_t domid, const char *mac, libxl_device_nic *nic) { @@ -819,6 +846,22 @@ void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nr) free(list); } +void libxl_vtpminfo_list_free(libxl_vtpminfo* list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_vtpminfo_dispose(&list[i]); + free(list); +} + +void libxl_device_vtpm_list_free(libxl_device_vtpm* list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_device_vtpm_dispose(&list[i]); + free(list); +} + int libxl_domid_valid_guest(uint32_t domid) { /* returns 1 if the value _could_ be a valid guest domid, 0 otherwise diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h index 83aaac7414..40f3f3027c 100644 --- a/tools/libxl/libxl_utils.h +++ b/tools/libxl/libxl_utils.h @@ -64,6 +64,11 @@ int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid, int devid, int libxl_vdev_to_device_disk(libxl_ctx *ctx, uint32_t domid, const char *vdev, libxl_device_disk *disk); +int libxl_uuid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid, + libxl_uuid *uuid, libxl_device_vtpm *vtpm); +int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid, + int devid, libxl_device_vtpm *vtpm); + int libxl_bitmap_alloc(libxl_ctx *ctx, libxl_bitmap *bitmap, int n_bits); /* Allocated bimap is from malloc, libxl_bitmap_dispose() to be * called by the application when done. */ diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index 0b2f848f90..be6f38b2fa 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -79,6 +79,9 @@ int main_networkdetach(int argc, char **argv); int main_blockattach(int argc, char **argv); int main_blocklist(int argc, char **argv); int main_blockdetach(int argc, char **argv); +int main_vtpmattach(int argc, char **argv); +int main_vtpmlist(int argc, char **argv); +int main_vtpmdetach(int argc, char **argv); int main_uptime(int argc, char **argv); int main_tmem_list(int argc, char **argv); int main_tmem_freeze(int argc, char **argv); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 95ce8255bb..5d444a88d6 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -573,7 +573,7 @@ static void parse_config_data(const char *config_source, const char *buf; long l; XLU_Config *config; - XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids; + XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms; XLU_ConfigList *ioports, *irqs, *iomem; int num_ioports, num_irqs, num_iomem; int pci_power_mgmt = 0; @@ -1048,6 +1048,58 @@ static void parse_config_data(const char *config_source, } } + if (!xlu_cfg_get_list(config, "vtpm", &vtpms, 0, 0)) { + d_config->num_vtpms = 0; + d_config->vtpms = NULL; + while ((buf = xlu_cfg_get_listitem (vtpms, d_config->num_vtpms)) != NULL) { + libxl_device_vtpm *vtpm; + char * buf2 = strdup(buf); + char *p, *p2; + bool got_backend = false; + + d_config->vtpms = (libxl_device_vtpm *) realloc(d_config->vtpms, + sizeof(libxl_device_vtpm) * (d_config->num_vtpms+1)); + vtpm = d_config->vtpms + d_config->num_vtpms; + libxl_device_vtpm_init(vtpm); + vtpm->devid = d_config->num_vtpms; + + p = strtok(buf2, ","); + if(p) { + do { + while(*p == ' ') + ++p; + if ((p2 = strchr(p, '=')) == NULL) + break; + *p2 = '\0'; + if (!strcmp(p, "backend")) { + if(domain_qualifier_to_domid(p2 + 1, &(vtpm->backend_domid), 0)) + { + fprintf(stderr, + "Specified vtpm backend domain `%s' does not exist!\n", p2 + 1); + exit(1); + } + got_backend = true; + } else if(!strcmp(p, "uuid")) { + if( libxl_uuid_from_string(&vtpm->uuid, p2 + 1) ) { + fprintf(stderr, + "Failed to parse vtpm UUID: %s\n", p2 + 1); + exit(1); + } + } else { + fprintf(stderr, "Unknown string `%s' in vtpm spec\n", p); + exit(1); + } + } while ((p = strtok(NULL, ",")) != NULL); + } + if(!got_backend) { + fprintf(stderr, "vtpm spec missing required backend field!\n"); + exit(1); + } + free(buf2); + d_config->num_vtpms++; + } + } + if (!xlu_cfg_get_list (config, "vif", &nics, 0, 0)) { d_config->num_nics = 0; d_config->nics = NULL; @@ -1073,7 +1125,7 @@ static void parse_config_data(const char *config_source, p = strtok(buf2, ","); if (!p) - goto skip; + goto skip_nic; do { while (*p == ' ') p++; @@ -1137,7 +1189,7 @@ static void parse_config_data(const char *config_source, fprintf(stderr, "the accel parameter for vifs is currently not supported\n"); } } while ((p = strtok(NULL, ",")) != NULL); -skip: +skip_nic: free(buf2); d_config->num_nics++; } @@ -5634,6 +5686,132 @@ int main_blockdetach(int argc, char **argv) return rc; } +int main_vtpmattach(int argc, char **argv) +{ + int opt; + libxl_device_vtpm vtpm; + char *oparg; + unsigned int val; + uint32_t domid; + + if ((opt = def_getopt(argc, argv, "", "vtpm-attach", 1)) != -1) + return opt; + + if (domain_qualifier_to_domid(argv[optind], &domid, 0) < 0) { + fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]); + return 1; + } + ++optind; + + libxl_device_vtpm_init(&vtpm); + for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) { + if (MATCH_OPTION("uuid", *argv, oparg)) { + if(libxl_uuid_from_string(&(vtpm.uuid), oparg)) { + fprintf(stderr, "Invalid uuid specified (%s)\n", oparg); + return 1; + } + } else if (MATCH_OPTION("backend", *argv, oparg)) { + if(domain_qualifier_to_domid(oparg, &val, 0)) { + fprintf(stderr, + "Specified backend domain does not exist, defaulting to Dom0\n"); + val = 0; + } + vtpm.backend_domid = val; + } else { + fprintf(stderr, "unrecognized argument `%s'\n", *argv); + return 1; + } + } + + if(dryrun_only) { + char* json = libxl_device_vtpm_to_json(ctx, &vtpm); + printf("vtpm: %s\n", json); + free(json); + libxl_device_vtpm_dispose(&vtpm); + if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); } + return 0; + } + + if (libxl_device_vtpm_add(ctx, domid, &vtpm, 0)) { + fprintf(stderr, "libxl_device_vtpm_add failed.\n"); + return 1; + } + libxl_device_vtpm_dispose(&vtpm); + return 0; +} + +int main_vtpmlist(int argc, char **argv) +{ + int opt; + libxl_device_vtpm *vtpms; + libxl_vtpminfo vtpminfo; + int nb, i; + + if ((opt = def_getopt(argc, argv, "", "vtpm-list", 1)) != -1) + return opt; + + /* Idx BE UUID Hdl Sta evch rref BE-path */ + printf("%-3s %-2s %-36s %-6s %-5s %-6s %-5s %-10s\n", + "Idx", "BE", "Uuid", "handle", "state", "evt-ch", "ring-ref", "BE-path"); + for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) { + uint32_t domid; + if (domain_qualifier_to_domid(*argv, &domid, 0) < 0) { + fprintf(stderr, "%s is an invalid domain identifier\n", *argv); + continue; + } + if (!(vtpms = libxl_device_vtpm_list(ctx, domid, &nb))) { + continue; + } + for (i = 0; i < nb; ++i) { + if(!libxl_device_vtpm_getinfo(ctx, domid, &vtpms[i], &vtpminfo)) { + /* Idx BE UUID Hdl Sta evch rref BE-path*/ + printf("%-3d %-2d " LIBXL_UUID_FMT " %6d %5d %6d %8d %-30s\n", + vtpminfo.devid, vtpminfo.backend_id, + LIBXL_UUID_BYTES(vtpminfo.uuid), + vtpminfo.devid, vtpminfo.state, vtpminfo.evtch, + vtpminfo.rref, vtpminfo.backend); + + libxl_vtpminfo_dispose(&vtpminfo); + } + libxl_device_vtpm_dispose(&vtpms[i]); + } + free(vtpms); + } + return 0; +} + +int main_vtpmdetach(int argc, char **argv) +{ + uint32_t domid; + int opt, rc=0; + libxl_device_vtpm vtpm; + libxl_uuid uuid; + + if ((opt = def_getopt(argc, argv, "", "vtpm-detach", 2)) != -1) + return opt; + + domid = find_domain(argv[optind]); + + if ( libxl_uuid_from_string(&uuid, argv[optind+1])) { + if (libxl_devid_to_device_vtpm(ctx, domid, atoi(argv[optind+1]), &vtpm)) { + fprintf(stderr, "Unknown device %s.\n", argv[optind+1]); + return 1; + } + } else { + if (libxl_uuid_to_device_vtpm(ctx, domid, &uuid, &vtpm)) { + fprintf(stderr, "Unknown device %s.\n", argv[optind+1]); + return 1; + } + } + rc = libxl_device_vtpm_remove(ctx, domid, &vtpm, 0); + if (rc) { + fprintf(stderr, "libxl_device_vtpm_remove failed.\n"); + } + libxl_device_vtpm_dispose(&vtpm); + return rc; +} + + static char *uptime_to_string(unsigned long uptime, int short_mode) { int sec, min, hour, day; diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index d3a215d247..ac586420bf 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -341,6 +341,21 @@ struct cmd_spec cmd_table[] = { "Destroy a domain's virtual block device", " ", }, + { "vtpm-attach", + &main_vtpmattach, 1, 1, + "Create a new virtual TPM device", + " [uuid=] [backend=]", + }, + { "vtpm-list", + &main_vtpmlist, 0, 0, + "List virtual TPM devices for a domain", + "", + }, + { "vtpm-detach", + &main_vtpmdetach, 0, 1, + "Destroy a domain's virtual TPM device", + " ", + }, { "uptime", &main_uptime, 0, 0, "Print uptime for all/some domains", -- cgit v1.2.3