All of lore.kernel.org
 help / color / mirror / Atom feed
From: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
To: embedded-pv-devel@lists.xenproject.org
Cc: wei.liu2@citrix.com, stefano.stabellini@eu.citrix.com,
	ian.jackson@eu.citrix.com, ian.campbell@citrix.com,
	xen-devel@lists.xen.org
Subject: [PATCH RFC 1/6] libxl: implementation of PV rtc device interface
Date: Thu, 19 May 2016 17:37:30 +0300	[thread overview]
Message-ID: <1463668655-16778-2-git-send-email-iurii.mykhalskyi@globallogic.com> (raw)
In-Reply-To: <1463668655-16778-1-git-send-email-iurii.mykhalskyi@globallogic.com>

PV rtc device interface is implemented in libxl and xl with
full support for device control. No JSON parser for domain
configuration yet.

Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
Signed-off-by: Glib Golubytskyi <glib.golubytskyi@globallogic.com>
Signed-off-by: Iurii Konovalenko <iurii.konovalenko@globallogic.com>
---
 tools/libxl/libxl.c                  | 287 ++++++++++++++++++++++++++++++++++-
 tools/libxl/libxl.h                  |  17 +++
 tools/libxl/libxl_create.c           |  39 ++++-
 tools/libxl/libxl_device.c           |   2 +
 tools/libxl/libxl_internal.h         |  19 ++-
 tools/libxl/libxl_types.idl          |  19 +++
 tools/libxl/libxl_types_internal.idl |   1 +
 tools/libxl/libxl_utils.h            |   3 +
 tools/libxl/xl.h                     |   3 +
 tools/libxl/xl_cmdimpl.c             | 161 +++++++++++++++++++-
 tools/libxl/xl_cmdtable.c            |  15 ++
 11 files changed, 558 insertions(+), 8 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index ac50bda..09c4bc7 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2323,6 +2323,277 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx,
     return rc;
 }
 
+/******************************************************************************/
+
+int libxl__device_vrtc_setdefault(libxl__gc *gc, libxl_device_vrtc *vrtc)
+{
+    int rc;
+
+    rc = libxl__resolve_domid(gc, vrtc->backend_domname, &vrtc->backend_domid);
+
+    return rc;
+}
+
+static int libxl__device_from_vrtc(libxl__gc *gc, uint32_t domid, libxl_device_vrtc *vrtc, libxl__device *device)
+{
+   device->backend_devid   = vrtc->devid;
+   device->backend_domid   = vrtc->backend_domid;
+   device->backend_kind    = LIBXL__DEVICE_KIND_VRTC;
+   device->devid           = vrtc->devid;
+   device->domid           = domid;
+   device->kind            = LIBXL__DEVICE_KIND_VRTC;
+
+   return 0;
+}
+
+static int libxl__device_vrtc_from_xs_be(libxl__gc *gc,
+                                        const char *be_path,
+                                        libxl_device_vrtc *vrtc)
+{
+    const char *tmp;
+    int rc;
+
+    libxl_device_vrtc_init(vrtc);
+
+    tmp = READ_BACKEND(gc, "device-id");
+    if (tmp)
+        vrtc->devid = atoi(tmp);
+    else
+        vrtc->devid = 0;
+
+    rc = 0;
+ out:
+    return rc;
+}
+
+int libxl_devid_to_device_vrtc(libxl_ctx *ctx, uint32_t domid,
+                              int devid, libxl_device_vrtc *vrtc)
+{
+    GC_INIT(ctx);
+    char *dompath, *path;
+    int rc = ERROR_FAIL;
+
+    libxl_device_vrtc_init(vrtc);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    if (!dompath)
+        goto out;
+
+    path = libxl__xs_read(gc, XBT_NULL,
+                          libxl__sprintf(gc, "%s/device/vrtc/%d/backend",
+                                         dompath, devid));
+    if (!path)
+        goto out;
+
+    rc = libxl__device_vrtc_from_xs_be(gc, path, vrtc);
+    if (rc) goto out;
+
+    rc = 0;
+out:
+    GC_FREE;
+    return rc;
+}
+
+void libxl__device_vrtc_add(libxl__egc *egc, uint32_t domid, libxl_device_vrtc *vrtc, libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    flexarray_t *front;
+    flexarray_t *back;
+    libxl__device *device;
+    int rc;
+    xs_transaction_t t = XBT_NULL;
+    libxl_domain_config d_config;
+    libxl_device_vrtc vrtc_saved;
+    libxl__domain_userdata_lock *lock = NULL;
+
+    libxl_domain_config_init(&d_config);
+    libxl_device_vrtc_init(&vrtc_saved);
+    libxl_device_vrtc_copy(CTX, &vrtc_saved, vrtc);
+
+    rc = libxl__device_vrtc_setdefault(gc, vrtc);
+    if (rc) goto out;
+
+    front = flexarray_make(gc, 16, 1);
+    back = flexarray_make(gc, 32, 1);
+
+    if ((vrtc->devid = libxl__device_nextid(gc, domid, "vrtc")) < 0) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    GCNEW(device);
+    rc = libxl__device_from_vrtc(gc, domid, vrtc, device);
+    if ( rc != 0 ) goto out;
+
+    flexarray_append(back, "device-id");
+    flexarray_append(back, GCSPRINTF("%d", vrtc->devid));
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, GCSPRINTF("%d", domid));
+    flexarray_append(back, "device");
+    flexarray_append(back, vrtc->device);
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, GCSPRINTF("%d", 1));
+
+    flexarray_append(front, "device-id");
+    flexarray_append(front, GCSPRINTF("%d", vrtc->devid));
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, GCSPRINTF("%d", vrtc->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, GCSPRINTF("%d", 1));
+
+    if (aodev->update_json) {
+        lock = libxl__lock_domain_userdata(gc, domid);
+        if (!lock) {
+            rc = ERROR_LOCK_FAIL;
+            goto out;
+        }
+
+        rc = libxl__get_domain_configuration(gc, domid, &d_config);
+        LOG(INFO, "aodev updates JSON, libxl__get_domain_configuration returned %d", rc);
+        if (rc) goto out;
+
+        DEVICE_ADD(vrtc, vrtcs, domid, &vrtc_saved, COMPARE_DEVID, &d_config);
+    }
+
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &t);
+        if (rc) goto out;
+
+        rc = libxl__device_exists(gc, t, device);
+        if (rc < 0) goto out;
+        if (rc == 1) {              /* already exists in xenstore */
+            LOG(ERROR, "device already exists in xenstore");
+            aodev->action = LIBXL__DEVICE_ACTION_ADD; /* for error message */
+            rc = ERROR_DEVICE_EXISTS;
+            goto out;
+        }
+
+        if (aodev->update_json) {
+            rc = libxl__set_domain_configuration(gc, domid, &d_config);
+            if (rc) goto out;
+        }
+
+        libxl__device_generic_add(gc, t, device,
+                                  libxl__xs_kvs_of_flexarray(gc, back,
+                                                             back->count),
+                                  libxl__xs_kvs_of_flexarray(gc, front,
+                                                             front->count),
+                                  NULL);
+
+        rc = libxl__xs_transaction_commit(gc, &t);
+
+        if (!rc) break;
+        if (rc < 0) goto out;
+    }
+
+    aodev->dev = device;
+    aodev->action = LIBXL__DEVICE_ACTION_ADD;
+    libxl__wait_device_connection(egc, aodev);
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &t);
+    if (lock) libxl__unlock_domain_userdata(lock);
+    libxl_device_vrtc_dispose(&vrtc_saved);
+    libxl_domain_config_dispose(&d_config);
+    aodev->rc = rc;
+    if(rc) aodev->callback(egc, aodev);
+    return;
+
+}
+
+libxl_device_vrtc *libxl_device_vrtc_list(libxl_ctx *ctx, uint32_t domid, int *num)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vrtc* vrtcs = NULL;
+    char* fe_path = NULL;
+    char** dir = NULL;
+    unsigned int ndirs = 0;
+
+    *num = 0;
+
+    fe_path = libxl__sprintf(gc, "%s/device/vrtc", libxl__xs_get_dompath(gc, domid));
+    dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs);
+    if (dir && ndirs) {
+       vrtcs = malloc(sizeof(*vrtcs) * ndirs);
+       libxl_device_vrtc* vrtc;
+       libxl_device_vrtc* end = vrtcs + ndirs;
+       for(vrtc = vrtcs; vrtc < end; ++vrtc, ++dir) {
+          char* tmp;
+
+          libxl_device_vrtc_init(vrtc);
+
+          vrtc->devid = atoi(*dir);
+
+          tmp = libxl__xs_read(gc, XBT_NULL,
+                GCSPRINTF("%s/%s/backend-id",
+                   fe_path, *dir));
+          vrtc->backend_domid = atoi(tmp);
+       }
+    }
+    *num = ndirs;
+
+    GC_FREE;
+    return vrtcs;
+}
+
+int libxl_device_vrtc_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_vrtc *vrtc, libxl_vrtcinfo *vrtcinfo)
+{
+    GC_INIT(ctx);
+    char *dompath, *vrtcpath;
+    char *val;
+    int rc = 0;
+
+    libxl_vrtcinfo_init(vrtcinfo);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    vrtcinfo->devid = vrtc->devid;
+
+    vrtcpath = GCSPRINTF("%s/device/vrtc/%d", dompath, vrtcinfo->devid);
+    vrtcinfo->backend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/backend", vrtcpath), NULL);
+
+    if (!vrtcinfo->backend) {
+        goto err;
+    }
+
+    if(!libxl__xs_read(gc, XBT_NULL, vrtcinfo->backend)) {
+       goto err;
+    }
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/backend-id", vrtcpath));
+    vrtcinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/state", vrtcpath));
+    vrtcinfo->state = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/event-channel", vrtcpath));
+    vrtcinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/ring-ref", vrtcpath));
+    vrtcinfo->rref = val ? strtoul(val, NULL, 10) : -1;
+
+    vrtcinfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/frontend", vrtcinfo->backend), NULL);
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/frontend-id", vrtcinfo->backend));
+    vrtcinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    goto exit;
+err:
+    rc = ERROR_FAIL;
+exit:
+    GC_FREE;
+    return rc;
+}
+
+
 
 /******************************************************************************/
 
@@ -4131,12 +4402,14 @@ 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
  * libxl_device_vfb_destroy
+ * libxl_device_vtpm_remove
+ * libxl_device_vtpm_destroy
+ * libxl_device_vrtc_remove
+ * libxl_device_vrtc_destroy
  */
 #define DEFINE_DEVICE_REMOVE(type, removedestroy, f)                    \
     int libxl_device_##type##_##removedestroy(libxl_ctx *ctx,           \
@@ -4188,6 +4461,10 @@ DEFINE_DEVICE_REMOVE(vfb, destroy, 1)
 DEFINE_DEVICE_REMOVE(vtpm, remove, 0)
 DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
 
+/* vrtc */
+DEFINE_DEVICE_REMOVE(vrtc, remove, 0)
+DEFINE_DEVICE_REMOVE(vrtc, destroy, 1)
+
 /* channel/console hotunplug is not implemented. There are 2 possibilities:
  * 1. add support for secondary consoles to xenconsoled
  * 2. dynamically add/remove qemu chardevs via qmp messages. */
@@ -4201,6 +4478,7 @@ DEFINE_DEVICE_REMOVE(vtpm, destroy, 1)
  * libxl_device_disk_add
  * libxl_device_nic_add
  * libxl_device_vtpm_add
+ * libxl_device_vrtc_add
  */
 
 #define DEFINE_DEVICE_ADD(type)                                         \
@@ -4232,6 +4510,9 @@ DEFINE_DEVICE_ADD(nic)
 /* vtpm */
 DEFINE_DEVICE_ADD(vtpm)
 
+/* vrtc */
+DEFINE_DEVICE_ADD(vrtc)
+
 #undef DEFINE_DEVICE_ADD
 
 /******************************************************************************/
@@ -6747,6 +7028,8 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
 
     MERGE(vtpm, vtpms, COMPARE_DEVID, {});
 
+    MERGE(vrtc, vrtcs, COMPARE_DEVID, {});
+
     MERGE(pci, pcidevs, COMPARE_PCI, {});
 
     /* Take care of removable device. We maintain invariant in the
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index fa5aedd..9243b86 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1435,6 +1435,23 @@ libxl_device_vtpm *libxl_device_vtpm_list(libxl_ctx *ctx, uint32_t domid, int *n
 int libxl_device_vtpm_getinfo(libxl_ctx *ctx, uint32_t domid,
                                libxl_device_vtpm *vtpm, libxl_vtpminfo *vtpminfo);
 
+/* RTC */
+int libxl_device_vrtc_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vrtc *vrtc,
+                          const libxl_asyncop_how *ao_how)
+                          LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vrtc_remove(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_vrtc *vrtc,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vrtc_destroy(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vrtc *vrtc,
+                              const libxl_asyncop_how *ao_how)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_vrtc *libxl_device_vrtc_list(libxl_ctx *ctx, uint32_t domid, int *num);
+int libxl_device_vrtc_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vrtc *vrtc, libxl_vrtcinfo *vrtcinfo);
+
 /* 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 1c0579c..1206c34 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -734,6 +734,8 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *aodevs,
 
 static void domcreate_attach_vtpms(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
+static void domcreate_attach_vrtcs(libxl__egc *egc, libxl__multidev *multidev,
+                                   int ret);
 static void domcreate_attach_pci(libxl__egc *egc, libxl__multidev *aodevs,
                                  int ret);
 static void domcreate_attach_dtdev(libxl__egc *egc,
@@ -1392,12 +1394,45 @@ static void domcreate_attach_vtpms(libxl__egc *egc,
    if (d_config->num_vtpms > 0) {
        /* Attach vtpms */
        libxl__multidev_begin(ao, &dcs->multidev);
-       dcs->multidev.callback = domcreate_attach_pci;
+       dcs->multidev.callback = domcreate_attach_vrtcs;
        libxl__add_vtpms(egc, ao, domid, d_config, &dcs->multidev);
        libxl__multidev_prepared(egc, &dcs->multidev, 0);
        return;
    }
 
+   domcreate_attach_vrtcs(egc, multidev, 0);
+   return;
+
+error_out:
+   assert(ret);
+   domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_attach_vrtcs(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 vtpm devices");
+       goto error_out;
+   }
+
+    /* Plug vrtc devices */
+   if (d_config->num_vrtcs > 0) {
+       /* Attach vrtcs */
+       libxl__multidev_begin(ao, &dcs->multidev);
+       dcs->multidev.callback = domcreate_attach_pci;
+       libxl__add_vrtcs(egc, ao, domid, d_config, &dcs->multidev);
+       libxl__multidev_prepared(egc, &dcs->multidev, 0);
+       return;
+   }
+
    domcreate_attach_pci(egc, multidev, 0);
    return;
 
@@ -1419,7 +1454,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 vtpm devices");
+        LOG(ERROR, "unable to add vrtc devices");
         goto error_out;
     }
 
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 8bb5e93..72f09a0 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -544,6 +544,7 @@ void libxl__multidev_prepared(libxl__egc *egc,
  * libxl__add_disks
  * libxl__add_nics
  * libxl__add_vtpms
+ * libxl__add_vrtcs
  */
 
 #define DEFINE_DEVICES_ADD(type)                                        \
@@ -563,6 +564,7 @@ void libxl__multidev_prepared(libxl__egc *egc,
 DEFINE_DEVICES_ADD(disk)
 DEFINE_DEVICES_ADD(nic)
 DEFINE_DEVICES_ADD(vtpm)
+DEFINE_DEVICES_ADD(vrtc)
 
 #undef DEFINE_DEVICES_ADD
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 5b0b50a..2a423b5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -476,7 +476,8 @@ typedef struct {
 #define QEMU_BACKEND(dev) (\
     (dev)->backend_kind == LIBXL__DEVICE_KIND_QDISK || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VFB || \
-    (dev)->backend_kind == LIBXL__DEVICE_KIND_VKBD)
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VKBD || \
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VRTC)
 
 #define XC_PCI_BDF             "0x%x, 0x%x, 0x%x, 0x%x"
 #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
@@ -1186,6 +1187,7 @@ _hidden int libxl__device_disk_setdefault(libxl__gc *gc,
 _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_vrtc_setdefault(libxl__gc *gc, libxl_device_vrtc *vrtc);
 _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);
@@ -2549,6 +2551,8 @@ struct libxl__multidev {
  * xenstore entry afterwards. We have both JSON and xenstore entry,
  * it's a valid state.
  */
+
+/* AO operation to connect a disk device */
 _hidden void libxl__device_disk_add(libxl__egc *egc, uint32_t domid,
                                     libxl_device_disk *disk,
                                     libxl__ao_device *aodev);
@@ -2558,9 +2562,15 @@ _hidden void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
                                    libxl_device_nic *nic,
                                    libxl__ao_device *aodev);
 
+/* AO operation to connect a tpm device */
 _hidden void libxl__device_vtpm_add(libxl__egc *egc, uint32_t domid,
-                                   libxl_device_vtpm *vtpm,
-                                   libxl__ao_device *aodev);
+                                    libxl_device_vtpm *vtpm,
+                                    libxl__ao_device *aodev);
+
+/* AO operation to connect an rtc device */
+_hidden void libxl__device_vrtc_add(libxl__egc *egc, uint32_t domid,
+                                    libxl_device_vrtc *vrtc,
+                                    libxl__ao_device *aodev);
 
 /* Internal function to connect a vkb device */
 _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
@@ -3278,6 +3288,9 @@ _hidden void libxl__add_vtpms(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                              libxl_domain_config *d_config,
                              libxl__multidev *multidev);
 
+_hidden void libxl__add_vrtcs(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 cd12117..27a750c 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -544,6 +544,13 @@ libxl_device_vkb = Struct("device_vkb", [
     ("devid", libxl_devid),
     ])
 
+libxl_device_vrtc = Struct("device_vrtc", [
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("device", string),
+    ])
+
 libxl_device_disk = Struct("device_disk", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
@@ -631,6 +638,7 @@ libxl_domain_config = Struct("domain_config", [
     ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
     ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
+    ("vrtcs", Array(libxl_device_vrtc, "num_vrtcs")),
     # a channel manifests as a console with a name,
     # see docs/misc/channels.txt
     ("channels", Array(libxl_device_channel, "num_channels")),
@@ -676,6 +684,17 @@ libxl_vtpminfo = Struct("vtpminfo", [
     ("uuid", libxl_uuid),
     ], dir=DIR_OUT)
 
+libxl_vrtcinfo = Struct("vrtcinfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("evtch", integer),
+    ("rref", integer),
+    ], 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 5e55685..764efb8 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -22,6 +22,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (6, "VKBD"),
     (7, "CONSOLE"),
     (8, "VTPM"),
+    (9, "VRTC"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 339ebdf..d1b825c 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -77,6 +77,9 @@ int libxl_uuid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
 int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
                                int devid, libxl_device_vtpm *vtpm);
 
+int libxl_devid_to_device_vrtc(libxl_ctx *ctx, uint32_t domid,
+                               int devid, libxl_device_vrtc *vrtc);
+
 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 13bccba..3d46efb 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -82,6 +82,9 @@ int main_channellist(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_vrtcattach(int argc, char **argv);
+int main_vrtclist(int argc, char **argv);
+int main_vrtcdetach(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);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 63a6b17..77701e0 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1262,7 +1262,7 @@ static void parse_config_data(const char *config_source,
     const char *buf;
     long l, vcpus = 0;
     XLU_Config *config;
-    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms;
+    XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, *vrtcs;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
@@ -1844,6 +1844,54 @@ static void parse_config_data(const char *config_source,
         }
     }
 
+    if (!xlu_cfg_get_list(config, "vrtc", &vrtcs, 0, 0)) {
+        d_config->num_vrtcs = 0;
+        d_config->vrtcs = NULL;
+        while ((buf = xlu_cfg_get_listitem(vrtcs, d_config->num_vrtcs)) != NULL) {
+            libxl_device_vrtc *vrtc;
+            libxl_string_list pairs;
+            char *path = NULL;
+            int len;
+
+            vrtc = ARRAY_EXTEND_INIT(d_config->vrtcs, d_config->num_vrtcs,
+                                     libxl_device_vrtc_init);
+
+            split_string_into_string_list(buf, ",", &pairs);
+            len = libxl_string_list_length(&pairs);
+
+            for (i = 0; i < len; i++) {
+                char *key, *key_untrimmed, *value, *value_untrimmed;
+                int rc;
+                rc = split_string_into_pair(pairs[i], "=",
+                                            &key_untrimmed,
+                                            &value_untrimmed);
+                if (rc != 0) {
+                    fprintf(stderr, "failed to parse vrtc configuration: %s",
+                            pairs[i]);
+                    exit(1);
+                }
+                trim(isspace, key_untrimmed, &key);
+                trim(isspace, value_untrimmed, &value);
+
+                if (!strcmp(key, "backendid")) {
+                    vrtc->backend_domid = atoi(value);
+                } else if (!strcmp(key, "backend")) {
+                    replace_string(&vrtc->backend_domname, value);
+                } else if (!strcmp(key, "devid")) {
+                    vrtc->devid = atoi(value);
+                } else if (!strcmp(key, "device")) {
+                    replace_string(&vrtc->device, value);
+                }
+                free(key);
+                free(key_untrimmed);
+                free(value);
+                free(value_untrimmed);
+            }
+            libxl_string_list_dispose(&pairs);
+            free(path);
+        }
+    }
+
     if (!xlu_cfg_get_list (config, "channel", &channels, 0, 0)) {
         d_config->num_channels = 0;
         d_config->channels = NULL;
@@ -6735,6 +6783,117 @@ int main_blockdetach(int argc, char **argv)
     return rc;
 }
 
+int main_vrtcattach(int argc, char **argv)
+{
+
+    int opt;
+    uint32_t fe_domid;
+    libxl_device_vrtc vrtc;
+    /*  XLU_Config *config = 0; */
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vrtc-attach", 2) {
+        /* No options */
+    }
+
+    if (libxl_domain_qualifier_to_domid(ctx, argv[optind], &fe_domid) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
+        return 1;
+    }
+    optind++;
+
+    if (optind < argc) {
+        replace_string(&vrtc.device, argv[optind]);
+    }
+    optind++;
+
+/* TODO: fix this temporary hardcode */
+    vrtc.backend_domname = "Domain-D";
+    vrtc.backend_domid = 1;
+
+    if (dryrun_only) {
+        char *json = libxl_device_vrtc_to_json(ctx, &vrtc);
+        printf("vrtc: %s\n", json);
+        free(json);
+        if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+        return 0;
+    }
+
+    if (libxl_device_vrtc_add(ctx, fe_domid, &vrtc, 0)) {
+        fprintf(stderr, "libxl_device_vrtc_add failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int main_vrtclist(int argc, char **argv)
+{
+	int opt;
+	int i, nb;
+	libxl_device_vrtc *vrtcs;
+	libxl_vrtcinfo vrtcinfo;
+
+	SWITCH_FOREACH_OPT(opt, "", NULL, "vrtc-list", 1) {
+		/* No options */
+	}
+
+	/* vrtcinfo.uuid should be outputted too */
+	printf("%-5s %-3s %-6s %-5s %-6s %-8s %-40s %-40s\n",
+			"Vdev", "BE", "handle", "state", "evt-ch", "ring-ref", "BE-path", "FE-path");
+	for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
+		uint32_t domid;
+		if (libxl_domain_qualifier_to_domid(ctx, *argv, &domid) < 0) {
+			fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
+			continue;
+		}
+		vrtcs = libxl_device_vrtc_list(ctx, domid, &nb);
+		if (!vrtcs) {
+			continue;
+		}
+		for (i=0; i<nb; i++) {
+			if (!libxl_device_vrtc_getinfo(ctx, domid, &vrtcs[i], &vrtcinfo)) {
+				/*      Vdev BE   hdl  st   evch rref BE-path FE-path UUID */
+				printf("%-5d %-3d %-6d %-5d %-6d %-8d %-40s %-40s\n",
+						vrtcinfo.devid, vrtcinfo.backend_id, vrtcinfo.frontend_id,
+						vrtcinfo.state, vrtcinfo.evtch, vrtcinfo.rref, vrtcinfo.backend,
+						vrtcinfo.frontend);
+				libxl_vrtcinfo_dispose(&vrtcinfo);
+			}
+			libxl_device_vrtc_dispose(&vrtcs[i]);
+		}
+		free(vrtcs);
+	}
+	return 0;
+}
+
+int main_vrtcdetach(int argc, char **argv)
+{
+    uint32_t domid, devid;
+    int opt, rc = 0;
+    libxl_device_vrtc vrtc;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vrtc-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    devid = atoi(argv[optind+1]);
+
+    if (libxl_devid_to_device_vrtc(ctx, domid, devid, &vrtc)) {
+        fprintf(stderr, "Error: Device %s not connected.\n", argv[optind+1]);
+        return 1;
+    }
+
+    rc = libxl_device_vrtc_remove(ctx, domid, &vrtc, 0);
+    if (rc) {
+        fprintf(stderr, "libxl_device_vrtc_remove failed.\n");
+        return 1;
+    }
+
+    libxl_device_vrtc_dispose(&vrtc);
+    return rc;
+}
+
 int main_vtpmattach(int argc, char **argv)
 {
     int opt;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index 0071f12..8b8971e 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -351,6 +351,21 @@ struct cmd_spec cmd_table[] = {
       "Destroy a domain's virtual block device",
       "<Domain> <DevId>",
     },
+    { "vrtc-attach",
+      &main_vrtcattach, 1, 1,
+      "Create a new virtual rtc device",
+      "<Domain> <Device>",
+    },
+    { "vrtc-list",
+      &main_vrtclist, 0, 0,
+      "List virtual rtc devices for a domain",
+      "<Domain(s)>",
+    },
+    { "vrtc-detach",
+      &main_vrtcdetach, 0, 1,
+      "Destroy a domain's virtual rtc device",
+      "<Domain> <DevId>",
+    },
     { "vtpm-attach",
       &main_vtpmattach, 1, 1,
       "Create a new virtual TPM device",
-- 
2.8.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  reply	other threads:[~2016-05-19 14:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-19 14:37 [PATCH RFC 0/6] Set of PV drivers used by production project Iurii Mykhalskyi
2016-05-19 14:37 ` Iurii Mykhalskyi [this message]
2016-05-23 16:45   ` [PATCH RFC 1/6] libxl: implementation of PV rtc device interface Olaf Hering
2016-06-06 13:37   ` Wei Liu
2016-05-19 14:37 ` [PATCH RFC 2/6] libxl: implementation of PV audio " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 3/6] libxl: implementation of PV tty " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 4/6] libxl: implementation of PV event " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 5/6] libxl: implementation of PV DRM " Iurii Mykhalskyi
2016-05-19 14:37 ` [PATCH RFC 6/6] libxl: implementation of PV RPMSG " Iurii Mykhalskyi
2016-05-19 17:52 ` [Embedded-pv-devel] [PATCH RFC 0/6] Set of PV drivers used by production project Meng Xu
2016-05-23 11:40 ` Wei Liu
2016-06-02 16:12 ` Wei Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1463668655-16778-2-git-send-email-iurii.mykhalskyi@globallogic.com \
    --to=iurii.mykhalskyi@globallogic.com \
    --cc=embedded-pv-devel@lists.xenproject.org \
    --cc=ian.campbell@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.