[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 4/7] vTPM: add vTPM device for HVM virtual machine
On Tue, Mar 10, 2015 at 08:13:59AM -0400, Quan Xu wrote: > refactor libxl__device_vtpm_add to call the right helpers > libxl__device_vtpm_add_{pv,hvm}. For HVM virtual machine, > it does not support hot-plug and hot-unplug, as it requires > SeaBios to initalize ACPI and virtual MMIO space for TPM > TIS when virtual machine starts. > > Signed-off-by: Quan Xu <quan.xu@xxxxxxxxx> > --- > tools/libxl/libxl.c | 176 > +++++++++++++++++++++++++++++++++++++++++-- > tools/libxl/libxl.h | 7 +- > tools/libxl/libxl_create.c | 32 +++++--- > tools/libxl/libxl_device.c | 38 +++++++++- > tools/libxl/libxl_dm.c | 12 +++ > tools/libxl/libxl_internal.h | 6 +- > tools/libxl/xl_cmdimpl.c | 4 +- > 7 files changed, 253 insertions(+), 22 deletions(-) > > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c > index 18561fb..c2d4baa 100644 > --- a/tools/libxl/libxl.c > +++ b/tools/libxl/libxl.c > @@ -1904,6 +1904,25 @@ out: > return; > } > > +static int libxl__frontend_device_nextid(libxl__gc *gc, uint32_t domid, char > *device) Line too line. > +{ > + char *dompath, **l; > + unsigned int nb; > + int nextid = -1; > + > + if (!(dompath = libxl__xs_get_dompath(gc, domid))) > + return nextid; > + > + l = libxl__xs_directory(gc, XBT_NULL, > + GCSPRINTF("/local/domain/0/frontend/%s/%u", device, domid), &nb); Please don't use hardcode /local/domain/0. And I suspect this will be wrong mostly of the time since this function is not Dom0 only. > + if (l == NULL || nb == 0) > + nextid = 0; > + else > + nextid = strtoul(l[nb - 1], NULL, 10) + 1; > + > + return nextid; > +} And this function looks very much like libxl__device_nextid. The only difference is the xenstore path, right? Please factor out the common bits of both function to a helper. > + > /* common function to get next device id */ > static int libxl__device_nextid(libxl__gc *gc, uint32_t domid, char *device) > { > @@ -1957,9 +1976,9 @@ static int libxl__device_from_vtpm(libxl__gc *gc, > uint32_t domid, > return 0; > } > > -void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid, > - libxl_device_vtpm *vtpm, > - libxl__ao_device *aodev) > +void libxl__device_vtpm_add_pv(libxl__egc *egc, uint32_t domid, > + libxl_device_vtpm *vtpm, > + libxl__ao_device *aodev) > { > STATE_AO_GC(aodev->ao); > flexarray_t *front; > @@ -2073,6 +2092,134 @@ out: > return; > } > > +void libxl__device_vtpm_add_hvm(libxl__egc *egc, uint32_t domid, > + libxl_device_vtpm *vtpm, > + libxl__ao_device *aodev) > +{ [...] > + libxl_device_vtpm_dispose(&vtpm_saved); > + libxl_domain_config_dispose(&d_config); > + aodev->rc = rc; > + if (rc) > + aodev->callback(egc, aodev); > + return; > +} > + This looks repetitive as well. I think the only difference between _pv and _hvm is the xenstore nodes they write to. You need to do some refactoring as well. > libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, > int *num) > { > GC_INIT(ctx); > @@ -4179,11 +4326,28 @@ DEFINE_DEVICE_ADD(disk) > /* nic */ > DEFINE_DEVICE_ADD(nic) > > -/* vtpm */ > -DEFINE_DEVICE_ADD(vtpm) > - > #undef DEFINE_DEVICE_ADD > > +#define DEFINE_VTPM_ADD_PV(type) \ > + int libxl_device_##type##_add_pv(libxl_ctx *ctx, \ > + uint32_t domid, libxl_device_##type *type, \ > + const libxl_asyncop_how *ao_how) \ > + { \ > + AO_CREATE(ctx, domid, ao_how); \ > + libxl__ao_device *aodev; \ > + \ > + GCNEW(aodev); \ > + libxl__prepare_ao_device(ao, aodev); \ > + aodev->callback = device_addrm_aocomplete; \ > + aodev->update_json = true; \ > + libxl__device_##type##_add_pv(egc, domid, type, aodev); \ > + \ > + return AO_INPROGRESS; \ > + } > + > +/* vtpm */ > +DEFINE_VTPM_ADD_PV(vtpm) No need to define a macro for this, since there is only one user of this. But after looking further down I think you're doing it wrong. There should still be a unified libxl_device_vtpm_add function that works for both PV and HVM (if this is the case because your change). > + > > /******************************************************************************/ > > /* > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h > index c3451bd..38d3542 100644 > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > @@ -1183,9 +1183,10 @@ int libxl_device_channel_getinfo(libxl_ctx *ctx, > uint32_t domid, > libxl_channelinfo *channelinfo); > > /* 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_add_pv(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) > diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c > index ffb124a..b88e1cb 100644 > --- a/tools/libxl/libxl_create.c > +++ b/tools/libxl/libxl_create.c > @@ -901,6 +901,14 @@ static void initiate_domain_create(libxl__egc *egc, > d_config->nics[i].devid = ++last_devid; > } > > + if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) { > + for (i = 0; i < d_config->num_vtpms; i++) { > + ret = libxl__device_vtpm_setdefault(gc, &d_config->vtpms[i]); > + if (ret) > + goto error_out; > + } > + } > + Why do you not need to call libxl__device_vtpm_setdefault for PV guest? > if (restore_fd >= 0) { > LOG(DEBUG, "restoring, not running bootloader"); > domcreate_bootloader_done(egc, &dcs->bl, 0); > @@ -1244,6 +1252,13 @@ static void domcreate_launch_dm(libxl__egc *egc, > libxl__multidev *multidev, > libxl__device_vkb_add(gc, domid, &vkb); > libxl_device_vkb_dispose(&vkb); > > + /* > + * Plug vtpm devices. dcs->multidev.callback is NULL, no need to call > + * libxl__multidev_prepared(). > + */ > + libxl__multidev_begin(ao, &dcs->multidev); > + libxl__add_vtpms(egc, ao, domid, d_config, &dcs->multidev); > + Why is vtpms added here instead of its usual location? I.e. the place you stubbed out in previous patch. That is ... > dcs->dmss.dm.guest_domid = domid; > if (libxl_defbool_val(d_config->b_info.device_model_stubdomain)) > libxl__spawn_stub_dm(egc, &dcs->dmss); > @@ -1361,15 +1376,14 @@ static void domcreate_attach_vtpms(libxl__egc *egc, > goto error_out; > } > > - /* > - * Plug vtpm devices only for PV guest. The xenstore directory is very > - * different for PV guest and HVM guest, but it is still call it for > - * creating HVM guest, and xl should create xenstore directory before > - * spawning QEMU. So try to make it only for PV guest. > - */ > - if (d_config->num_vtpms > 0 && > - d_config->b_info.type == LIBXL_DOMAIN_TYPE_PV) { > - > + /* > + * Plug vtpm devices only for PV guest. The xenstore directory is very > + * different for PV guest and HVM guest, but it is still call it for > + * creating HVM guest, and xl should create xenstore directory before > + * spawning QEMU. So try to make it only for PV guest. > + */ > + if (d_config->num_vtpms > 0 && > + d_config->b_info.type == LIBXL_DOMAIN_TYPE_PV) { ... here? BTW this hunk doesn't have meaningful changes... > /* Attach vtpms */ > libxl__multidev_begin(ao, &dcs->multidev); > dcs->multidev.callback = domcreate_attach_pci; > diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c > index 4b51ded..b1a71fe 100644 > --- a/tools/libxl/libxl_device.c > +++ b/tools/libxl/libxl_device.c > @@ -26,6 +26,13 @@ char *libxl__device_frontend_path(libxl__gc *gc, > libxl__device *device) > if (device->kind == LIBXL__DEVICE_KIND_CONSOLE && device->devid == 0) > return GCSPRINTF("%s/console", dom_path); > > + /* vTPM for HVM virtual machine is a special case */ > + else if (device->backend_kind == LIBXL__DEVICE_KIND_VTPM && > + device->domid == 0) > + return GCSPRINTF("/local/domain/0/frontend/%s/%u/%d", > + libxl__device_kind_to_string(device->backend_kind), > + device->backend_domid, device->devid); > + You need to define xenstore protocol first. And, why is it special? I don't know because you haven't defined what the protocol looks like. > return GCSPRINTF("%s/device/%s/%d", dom_path, > libxl__device_kind_to_string(device->kind), > device->devid); > @@ -560,10 +567,39 @@ void libxl__multidev_prepared(libxl__egc *egc, > > DEFINE_DEVICES_ADD(disk) > DEFINE_DEVICES_ADD(nic) > -DEFINE_DEVICES_ADD(vtpm) > > #undef DEFINE_DEVICES_ADD > > +#define DEFINE_VTPM_ADD(_type) \ > + void libxl__add_##_type##s(libxl__egc *egc, libxl__ao *ao, \ > + uint32_t domid, \ > + libxl_domain_config *d_config, \ > + libxl__multidev *multidev) \ > + { \ > + AO_GC; \ > + int i; \ > + for (i = 0; i < d_config->num_##_type##s; i++) { \ > + libxl__ao_device *aodev = libxl__multidev_prepare(multidev); \ > + switch(d_config->c_info.type) { \ > + case LIBXL_DOMAIN_TYPE_PV: \ > + libxl__device_##_type##_add_pv(egc, domid, \ > + &d_config->_type##s[i], \ > + aodev); \ > + break; \ > + case LIBXL_DOMAIN_TYPE_HVM: \ > + libxl__device_##_type##_add_hvm(egc, domid, \ > + &d_config->_type##s[i], \ > + aodev); \ > + break; \ > + default: \ > + break; \ > + } \ > + } \ > + } > + > +DEFINE_VTPM_ADD(vtpm) > + It's fine by me that you just hand code this function without using this macro. But, I don't think the function body as-is is correct. There should not be a loop. This function should only handle one device. > +#undef DEFINE_VTPM_ADD > > /******************************************************************************/ > > int libxl__device_destroy(libxl__gc *gc, libxl__device *dev) > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c > index 3e191c3..183910c 100644 > --- a/tools/libxl/libxl_dm.c > +++ b/tools/libxl/libxl_dm.c > @@ -414,6 +414,7 @@ static char ** > libxl__build_device_model_args_new(libxl__gc *gc, > const libxl_device_nic *nics = guest_config->nics; > const int num_disks = guest_config->num_disks; > const int num_nics = guest_config->num_nics; > + const int num_vtpms = guest_config->num_vtpms; > const libxl_vnc_info *vnc = libxl__dm_vnc(guest_config); > const libxl_sdl_info *sdl = dm_sdl(guest_config); > const char *keymap = dm_keymap(guest_config); > @@ -747,6 +748,17 @@ static char ** > libxl__build_device_model_args_new(libxl__gc *gc, > abort(); > } > > + /* Add vTPM parameters for HVM virtual machine */ > + if (b_info->type == LIBXL_DOMAIN_TYPE_HVM && > + num_vtpms > 0) { > + flexarray_vappend(dm_args, "-tpmdev", > + libxl__sprintf(gc, "xenstubdoms,id=xenvtpm%d", > + guest_domid), NULL); Please use GCSPRINTF. > + flexarray_vappend(dm_args,"-device", > + libxl__sprintf(gc, "tpm-tis,tpmdev=xenvtpm%d", > + guest_domid), NULL); > + } > + > ram_size = libxl__sizekb_to_mb(b_info->max_memkb - b_info->video_memkb); > flexarray_append(dm_args, "-m"); > flexarray_append(dm_args, libxl__sprintf(gc, "%"PRId64, ram_size)); > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index 4361421..c6c82dd 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -2384,10 +2384,14 @@ _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, > +_hidden void libxl__device_vtpm_add_pv(libxl__egc *egc, uint32_t domid, > libxl_device_vtpm *vtpm, > libxl__ao_device *aodev); > > +void libxl__device_vtpm_add_hvm(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); > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index 3c9f146..e01d341 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -6490,8 +6490,8 @@ int main_vtpmattach(int argc, char **argv) > return 0; > } > > - if (libxl_device_vtpm_add(ctx, domid, &vtpm, 0)) { > - fprintf(stderr, "libxl_device_vtpm_add failed.\n"); > + if (libxl_device_vtpm_add_pv(ctx, domid, &vtpm, 0)) { > + fprintf(stderr, "libxl_device_vtpm_add_pv failed.\n"); How do you add vtpm for hvm guest? Wei. > return 1; > } > libxl_device_vtpm_dispose(&vtpm); > -- > 1.8.3.2 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |