[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Embedded-pv-devel] [PATCH RFC 6/6] libxl: implementation of PV RPMSG device interface



From: Pavlo Suikov <pavlo.suikov@xxxxxxxxxxxxxxx>

Signed-off-by: Pavlo Suikov <pavlo.suikov@xxxxxxxxxxxxxxx>
Signed-off-by: Iurii Konovalenko <iurii.konovalenko@xxxxxxxxxxxxxxx>
Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@xxxxxxxxxxxxxxx>
---
 tools/libxl/libxl.c                  | 282 +++++++++++++++++++++++++++++++++++
 tools/libxl/libxl.h                  |  17 +++
 tools/libxl/libxl_create.c           |  40 ++++-
 tools/libxl/libxl_device.c           |   2 +
 tools/libxl/libxl_internal.h         |  13 +-
 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            |  21 ++-
 11 files changed, 554 insertions(+), 8 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index ccb0411..871061d 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2873,6 +2873,276 @@ exit:
 
 
/******************************************************************************/
 
+int libxl__device_vrpmsg_setdefault(libxl__gc *gc, libxl_device_vrpmsg *vrpmsg)
+{
+    int rc;
+
+    rc = libxl__resolve_domid(gc, vrpmsg->backend_domname, 
&vrpmsg->backend_domid);
+
+    return rc;
+}
+
+static int libxl__device_from_vrpmsg(libxl__gc *gc, uint32_t domid, 
libxl_device_vrpmsg *vrpmsg, libxl__device *device)
+{
+   device->backend_devid   = vrpmsg->devid;
+   device->backend_domid   = vrpmsg->backend_domid;
+   device->backend_kind    = LIBXL__DEVICE_KIND_VRPMSG;
+   device->devid           = vrpmsg->devid;
+   device->domid           = domid;
+   device->kind            = LIBXL__DEVICE_KIND_VRPMSG;
+
+   return 0;
+}
+
+static int libxl__device_vrpmsg_from_xs_be(libxl__gc *gc,
+                                        const char *be_path,
+                                        libxl_device_vrpmsg *vrpmsg)
+{
+    const char *tmp;
+    int rc;
+
+    libxl_device_vrpmsg_init(vrpmsg);
+
+    tmp = READ_BACKEND(gc, "device-id");
+    if (tmp)
+        vrpmsg->devid = atoi(tmp);
+    else
+        vrpmsg->devid = 0;
+
+    rc = 0;
+ out:
+    return rc;
+}
+
+int libxl_devid_to_device_vrpmsg(libxl_ctx *ctx, uint32_t domid,
+                              int devid, libxl_device_vrpmsg *vrpmsg)
+{
+    GC_INIT(ctx);
+    char *dompath, *path;
+    int rc = ERROR_FAIL;
+
+    libxl_device_vrpmsg_init(vrpmsg);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    if (!dompath)
+        goto out;
+
+    path = libxl__xs_read(gc, XBT_NULL,
+                          libxl__sprintf(gc, "%s/device/vrpmsg/%d/backend",
+                                         dompath, devid));
+    if (!path)
+        goto out;
+
+    rc = libxl__device_vrpmsg_from_xs_be(gc, path, vrpmsg);
+    if (rc) goto out;
+
+    rc = 0;
+out:
+    GC_FREE;
+    return rc;
+}
+
+void libxl__device_vrpmsg_add(libxl__egc *egc, uint32_t domid, 
libxl_device_vrpmsg *vrpmsg, 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_vrpmsg vrpmsg_saved;
+    libxl__domain_userdata_lock *lock = NULL;
+
+    libxl_domain_config_init(&d_config);
+    libxl_device_vrpmsg_init(&vrpmsg_saved);
+    libxl_device_vrpmsg_copy(CTX, &vrpmsg_saved, vrpmsg);
+
+    rc = libxl__device_vrpmsg_setdefault(gc, vrpmsg);
+    if (rc) goto out;
+
+    front = flexarray_make(gc, 16, 1);
+    back = flexarray_make(gc, 32, 1);
+
+    if ((vrpmsg->devid = libxl__device_nextid(gc, domid, "vrpmsg")) < 0) {
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    GCNEW(device);
+    rc = libxl__device_from_vrpmsg(gc, domid, vrpmsg, device);
+    if ( rc != 0 ) goto out;
+
+    flexarray_append(back, "device-id");
+    flexarray_append(back, GCSPRINTF("%d", vrpmsg->devid));
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, GCSPRINTF("%d", domid));
+    flexarray_append(back, "device");
+    flexarray_append(back, vrpmsg->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", vrpmsg->devid));
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, GCSPRINTF("%d", vrpmsg->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(vrpmsg, vrpmsgs, domid, &vrpmsg_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_vrpmsg_dispose(&vrpmsg_saved);
+    libxl_domain_config_dispose(&d_config);
+    aodev->rc = rc;
+    if(rc) aodev->callback(egc, aodev);
+    return;
+
+}
+
+libxl_device_vrpmsg *libxl_device_vrpmsg_list(libxl_ctx *ctx, uint32_t domid, 
int *num)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vrpmsg* vrpmsgs = NULL;
+    char* fe_path = NULL;
+    char** dir = NULL;
+    unsigned int ndirs = 0;
+
+    *num = 0;
+
+    fe_path = libxl__sprintf(gc, "%s/device/vrpmsg", libxl__xs_get_dompath(gc, 
domid));
+    dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs);
+    if (dir && ndirs) {
+       vrpmsgs = malloc(sizeof(*vrpmsgs) * ndirs);
+       libxl_device_vrpmsg* vrpmsg;
+       libxl_device_vrpmsg* end = vrpmsgs + ndirs;
+       for(vrpmsg = vrpmsgs; vrpmsg < end; ++vrpmsg, ++dir) {
+          char* tmp;
+
+          libxl_device_vrpmsg_init(vrpmsg);
+
+          vrpmsg->devid = atoi(*dir);
+
+          tmp = libxl__xs_read(gc, XBT_NULL,
+                GCSPRINTF("%s/%s/backend-id",
+                   fe_path, *dir));
+          vrpmsg->backend_domid = atoi(tmp);
+       }
+    }
+    *num = ndirs;
+
+    GC_FREE;
+    return vrpmsgs;
+}
+
+int libxl_device_vrpmsg_getinfo(libxl_ctx *ctx, uint32_t domid, 
libxl_device_vrpmsg *vrpmsg, libxl_vrpmsginfo *vrpmsginfo)
+{
+    GC_INIT(ctx);
+    char *dompath, *vrpmsgpath;
+    char *val;
+    int rc = 0;
+
+    libxl_vrpmsginfo_init(vrpmsginfo);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    vrpmsginfo->devid = vrpmsg->devid;
+
+    vrpmsgpath = GCSPRINTF("%s/device/vrpmsg/%d", dompath, vrpmsginfo->devid);
+    vrpmsginfo->backend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/backend", vrpmsgpath), NULL);
+
+    if (!vrpmsginfo->backend) {
+        goto err;
+    }
+
+    if(!libxl__xs_read(gc, XBT_NULL, vrpmsginfo->backend)) {
+       goto err;
+    }
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/backend-id", vrpmsgpath));
+    vrpmsginfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/state", vrpmsgpath));
+    vrpmsginfo->state = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/event-channel", vrpmsgpath));
+    vrpmsginfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/ring-ref", vrpmsgpath));
+    vrpmsginfo->rref = val ? strtoul(val, NULL, 10) : -1;
+
+    vrpmsginfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/frontend", vrpmsginfo->backend), NULL);
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/frontend-id", vrpmsginfo->backend));
+    vrpmsginfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    goto exit;
+err:
+    rc = ERROR_FAIL;
+exit:
+    GC_FREE;
+    return rc;
+}
+
+/******************************************************************************/
+
 int libxl__device_vtty_setdefault(libxl__gc *gc, libxl_device_vtty *vtty)
 {
     int rc;
@@ -5573,6 +5843,8 @@ exit:
  * libxl_device_vrtc_destroy
  * libxl_device_vdrm_remove
  * libxl_device_vdrm_destroy
+ * libxl_device_vrpmsg_remove
+ * libxl_device_vrpmsg_destroy
  * libxl_device_vsnd_remove
  * libxl_device_vsnd_destroy
  * libxl_device_vtty_remove
@@ -5637,6 +5909,10 @@ DEFINE_DEVICE_REMOVE(vrtc, destroy, 1)
 DEFINE_DEVICE_REMOVE(vdrm, remove, 0)
 DEFINE_DEVICE_REMOVE(vdrm, destroy, 1)
 
+/* vrpmsg */
+DEFINE_DEVICE_REMOVE(vrpmsg, remove, 0)
+DEFINE_DEVICE_REMOVE(vrpmsg, destroy, 1)
+
 /* vsnd */
 DEFINE_DEVICE_REMOVE(vsnd, remove, 0)
 DEFINE_DEVICE_REMOVE(vsnd, destroy, 1)
@@ -5664,6 +5940,7 @@ DEFINE_DEVICE_REMOVE(vevent, destroy, 1)
  * libxl_device_vtpm_add
  * libxl_device_vrtc_add
  * libxl_device_vdrm_add
+ * libxl_device_vrpmsg_add
  * libxl_device_vsnd_add
  * libxl_device_vtty_add
  * libxl_device_vevent_add
@@ -5704,6 +5981,9 @@ DEFINE_DEVICE_ADD(vrtc)
 /* vdrm */
 DEFINE_DEVICE_ADD(vdrm)
 
+/* vrpmsg */
+DEFINE_DEVICE_ADD(vrpmsg)
+
 /* vsnd */
 DEFINE_DEVICE_ADD(vsnd)
 
@@ -8232,6 +8512,8 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, 
uint32_t domid,
 
     MERGE(vdrm, vdrms, COMPARE_DEVID, {});
 
+    MERGE(vrpmsg, vrpmsgs, COMPARE_DEVID, {});
+
     MERGE(vsnd, vsnds, COMPARE_DEVID, {});
 
     MERGE(pci, pcidevs, COMPARE_PCI, {});
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 57f3e03..fb2f8d4 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1469,6 +1469,23 @@ libxl_device_vdrm *libxl_device_vdrm_list(libxl_ctx 
*ctx, uint32_t domid, int *n
 int libxl_device_vdrm_getinfo(libxl_ctx *ctx, uint32_t domid,
                               libxl_device_vdrm *vdrm, libxl_vdrminfo 
*vdrminfo);
 
+/* RPMSG */
+int libxl_device_vrpmsg_add(libxl_ctx *ctx, uint32_t domid, 
libxl_device_vrpmsg *vrpmsg,
+                          const libxl_asyncop_how *ao_how)
+                          LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vrpmsg_remove(libxl_ctx *ctx, uint32_t domid,
+                             libxl_device_vrpmsg *vrpmsg,
+                             const libxl_asyncop_how *ao_how)
+                             LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vrpmsg_destroy(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vrpmsg *vrpmsg,
+                              const libxl_asyncop_how *ao_how)
+                              LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_vrpmsg *libxl_device_vrpmsg_list(libxl_ctx *ctx, uint32_t domid, 
int *num);
+int libxl_device_vrpmsg_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vrpmsg *vrpmsg, libxl_vrpmsginfo 
*vrpmsginfo);
+
 /* Audio */
 int libxl_device_vsnd_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vsnd 
*vsnd,
                           const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 6e1c0d8..11ae349 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -738,6 +738,8 @@ static void domcreate_attach_vrtcs(libxl__egc *egc, 
libxl__multidev *multidev,
                                    int ret);
 static void domcreate_attach_vdrms(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
+static void domcreate_attach_vrpmsgs(libxl__egc *egc, libxl__multidev 
*multidev,
+                                     int ret);
 static void domcreate_attach_vttys(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
 static void domcreate_attach_vsnds(libxl__egc *egc, libxl__multidev *multidev,
@@ -1468,13 +1470,13 @@ static void domcreate_attach_vdrms(libxl__egc *egc,
    if (d_config->num_vdrms > 0) {
        /* Attach vdrms */
        libxl__multidev_begin(ao, &dcs->multidev);
-       dcs->multidev.callback = domcreate_attach_vttys;
+       dcs->multidev.callback = domcreate_attach_vrpmsgs;
        libxl__add_vdrms(egc, ao, domid, d_config, &dcs->multidev);
        libxl__multidev_prepared(egc, &dcs->multidev, 0);
        return;
    }
 
-   domcreate_attach_vttys(egc, multidev, 0);
+   domcreate_attach_vrpmsgs(egc, multidev, 0);
    return;
 
 error_out:
@@ -1482,6 +1484,38 @@ error_out:
    domcreate_complete(egc, dcs, ret);
 }
 
+static void domcreate_attach_vrpmsgs(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 vdrm devices");
+       goto error_out;
+   }
+
+    /* Plug vrpmsg devices */
+   if (d_config->num_vrpmsgs > 0) {
+       /* Attach vrpmsgs */
+       libxl__multidev_begin(ao, &dcs->multidev);
+       dcs->multidev.callback = domcreate_attach_vttys;
+       libxl__add_vrpmsgs(egc, ao, domid, d_config, &dcs->multidev);
+       libxl__multidev_prepared(egc, &dcs->multidev, 0);
+       return;
+   }
+
+   domcreate_attach_vttys(egc, multidev, 0);
+   return;
+
+error_out:
+   assert(ret);
+   domcreate_complete(egc, dcs, ret);
+}
 
 static void domcreate_attach_vttys(libxl__egc *egc,
                                    libxl__multidev *multidev,
@@ -1494,7 +1528,7 @@ static void domcreate_attach_vttys(libxl__egc *egc,
    libxl_domain_config* const d_config = dcs->guest_config;
 
    if(ret) {
-       LOG(ERROR, "unable to add vdrm devices");
+       LOG(ERROR, "unable to add vrpmsg devices");
        goto error_out;
    }
 
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 13c4a7b..1949dd4 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -546,6 +546,7 @@ void libxl__multidev_prepared(libxl__egc *egc,
  * libxl__add_vtpms
  * libxl__add_vrtcs
  * libxl__add_vdrms
+ * libxl__add_vrpmsgs
  * libxl__add_vsnds
  * libxl__add_vttys
  * libxl__add_vevents
@@ -570,6 +571,7 @@ DEFINE_DEVICES_ADD(nic)
 DEFINE_DEVICES_ADD(vtpm)
 DEFINE_DEVICES_ADD(vrtc)
 DEFINE_DEVICES_ADD(vdrm)
+DEFINE_DEVICES_ADD(vrpmsg)
 DEFINE_DEVICES_ADD(vsnd)
 DEFINE_DEVICES_ADD(vtty)
 DEFINE_DEVICES_ADD(vevent)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 80754df..fb9e858 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -481,7 +481,8 @@ typedef struct {
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VSND || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VTTY || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VEVENT || \
-    (dev)->backend_kind == LIBXL__DEVICE_KIND_VDRM)
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VDRM || \
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VRPMSG)
 
 #define XC_PCI_BDF             "0x%x, 0x%x, 0x%x, 0x%x"
 #define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
@@ -1193,6 +1194,7 @@ _hidden int libxl__device_nic_setdefault(libxl__gc *gc, 
libxl_device_nic *nic,
 _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_vdrm_setdefault(libxl__gc *gc, libxl_device_vdrm 
*vdrm);
+_hidden int libxl__device_vrpmsg_setdefault(libxl__gc *gc, libxl_device_vrpmsg 
*vrpmsg);
 _hidden int libxl__device_vsnd_setdefault(libxl__gc *gc, libxl_device_vsnd 
*vsnd);
 _hidden int libxl__device_vtty_setdefault(libxl__gc *gc, libxl_device_vtty 
*vtty);
 _hidden int libxl__device_vfb_setdefault(libxl__gc *gc, libxl_device_vfb *vfb);
@@ -2585,6 +2587,11 @@ _hidden void libxl__device_vdrm_add(libxl__egc *egc, 
uint32_t domid,
                                     libxl_device_vdrm *vdrm,
                                     libxl__ao_device *aodev);
 
+/* AO operation to connect an rpmsg device */
+_hidden void libxl__device_vrpmsg_add(libxl__egc *egc, uint32_t domid,
+                                      libxl_device_vrpmsg *vrpmsg,
+                                      libxl__ao_device *aodev);
+
 /* AO operation to connect a sound device */
 _hidden void libxl__device_vsnd_add(libxl__egc *egc, uint32_t domid,
                                     libxl_device_vsnd *vsnd,
@@ -3324,6 +3331,10 @@ _hidden void libxl__add_vdrms(libxl__egc *egc, libxl__ao 
*ao, uint32_t domid,
                               libxl_domain_config *d_config,
                               libxl__multidev *multidev);
 
+_hidden void libxl__add_vrpmsgs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                                libxl_domain_config *d_config,
+                                libxl__multidev *multidev);
+
 _hidden void libxl__add_vttys(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                               libxl_domain_config *d_config,
                               libxl__multidev *multidev);
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 27583cc..a422350 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -569,6 +569,13 @@ libxl_device_vdrm = Struct("device_vdrm", [
     ("mode1", string),
     ])
 
+libxl_device_vrpmsg = Struct("device_vrpmsg", [
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("device", string),
+    ])
+
 libxl_device_vsnd = Struct("device_vsnd", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
@@ -686,6 +693,7 @@ libxl_domain_config = Struct("domain_config", [
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
     ("vrtcs", Array(libxl_device_vrtc, "num_vrtcs")),
     ("vdrms", Array(libxl_device_vdrm, "num_vdrms")),
+    ("vrpmsgs", Array(libxl_device_vrpmsg, "num_vrpmsgs")),
     ("vsnds", Array(libxl_device_vsnd, "num_vsnds")),
     ("vttys", Array(libxl_device_vtty, "num_vttys")),
     # a channel manifests as a console with a name,
@@ -755,6 +763,17 @@ libxl_vdrminfo = Struct("vdrminfo", [
     ("rref", integer),
     ], dir=DIR_OUT)
 
+libxl_vrpmsginfo = Struct("vrpmsginfo", [
+    ("backend", string),
+    ("backend_id", uint32),
+    ("frontend", string),
+    ("frontend_id", uint32),
+    ("devid", libxl_devid),
+    ("state", integer),
+    ("evtch", integer),
+    ("rref", integer),
+    ], dir=DIR_OUT)
+
 libxl_vsndinfo = Struct("vsndinfo", [
     ("backend", string),
     ("backend_id", uint32),
diff --git a/tools/libxl/libxl_types_internal.idl 
b/tools/libxl/libxl_types_internal.idl
index 9a68700..d5ca05e 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -27,6 +27,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (11, "VTTY"),
     (12, "VEVENT"),
     (13, "VDRM"),
+    (14, "VRPMSG"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index e1532a2..04a88fd 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -83,6 +83,9 @@ int libxl_devid_to_device_vrtc(libxl_ctx *ctx, uint32_t domid,
 int libxl_devid_to_device_vdrm(libxl_ctx *ctx, uint32_t domid,
                                int devid, libxl_device_vdrm *vdrm);
 
+int libxl_devid_to_device_vrpmsg(libxl_ctx *ctx, uint32_t domid,
+                                 int devid, libxl_device_vrpmsg *vrpmsg);
+
 int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
                                int devid, libxl_device_vsnd *vsnd);
 
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 7c0082c..93892da 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -88,6 +88,9 @@ int main_vrtcdetach(int argc, char **argv);
 int main_vdrmattach(int argc, char **argv);
 int main_vdrmlist(int argc, char **argv);
 int main_vdrmdetach(int argc, char **argv);
+int main_vrpmsgattach(int argc, char **argv);
+int main_vrpmsglist(int argc, char **argv);
+int main_vrpmsgdetach(int argc, char **argv);
 int main_vsndattach(int argc, char **argv);
 int main_vsndlist(int argc, char **argv);
 int main_vsnddetach(int argc, char **argv);
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index df9ebd2..bc6e89f 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1272,7 +1272,7 @@ static void parse_config_data(const char *config_source,
     long l, vcpus = 0;
     XLU_Config *config;
     XLU_ConfigList *cpus, *cpuids, *vbds, *nics, *pcis;
-    XLU_ConfigList *cvfbs, *vevents, *vtpms, *vrtcs, *vttys, *vsnds, *vdrms;
+    XLU_ConfigList *cvfbs, *vevents, *vtpms, *vrtcs, *vttys, *vsnds, *vdrms, 
*vrpmsgs;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
@@ -1954,6 +1954,54 @@ static void parse_config_data(const char *config_source,
         }
     }
 
+    if (!xlu_cfg_get_list(config, "vrpmsg", &vrpmsgs, 0, 0)) {
+        d_config->num_vrpmsgs = 0;
+        d_config->vrpmsgs = NULL;
+        while ((buf = xlu_cfg_get_listitem(vrpmsgs, d_config->num_vrpmsgs)) != 
NULL) {
+            libxl_device_vrpmsg *vrpmsg;
+            libxl_string_list pairs;
+            char *path = NULL;
+            int len;
+
+            vrpmsg = ARRAY_EXTEND_INIT(d_config->vrpmsgs, 
d_config->num_vrpmsgs,
+                                     libxl_device_vrpmsg_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 vrpmsg configuration: %s",
+                            pairs[i]);
+                    exit(1);
+                }
+                trim(isspace, key_untrimmed, &key);
+                trim(isspace, value_untrimmed, &value);
+
+                if (!strcmp(key, "backendid")) {
+                    vrpmsg->backend_domid = atoi(value);
+                } else if (!strcmp(key, "backend")) {
+                    replace_string(&vrpmsg->backend_domname, value);
+                } else if (!strcmp(key, "devid")) {
+                    vrpmsg->devid = atoi(value);
+                } else if (!strcmp(key, "device")) {
+                    replace_string(&vrpmsg->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, "vtty", &vttys, 0, 0)) {
         d_config->num_vttys = 0;
         d_config->vttys = NULL;
@@ -7247,6 +7295,117 @@ int main_vdrmdetach(int argc, char **argv)
     return rc;
 }
 
+int main_vrpmsgattach(int argc, char **argv)
+{
+
+    int opt;
+    uint32_t fe_domid;
+    libxl_device_vrpmsg vrpmsg;
+    /*  XLU_Config *config = 0; */
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vrpmsg-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(&vrpmsg.device, argv[optind]);
+    }
+    optind++;
+
+/* TODO: fix this temporary hardcode */
+    vrpmsg.backend_domname = "Domain-D";
+    vrpmsg.backend_domid = 1;
+
+    if (dryrun_only) {
+        char *json = libxl_device_vrpmsg_to_json(ctx, &vrpmsg);
+        printf("vrpmsg: %s\n", json);
+        free(json);
+        if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+        return 0;
+    }
+
+    if (libxl_device_vrpmsg_add(ctx, fe_domid, &vrpmsg, 0)) {
+        fprintf(stderr, "libxl_device_vrpmsg_add failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int main_vrpmsglist(int argc, char **argv)
+{
+       int opt;
+       int i, nb;
+       libxl_device_vrpmsg *vrpmsgs;
+       libxl_vrpmsginfo vrpmsginfo;
+
+       SWITCH_FOREACH_OPT(opt, "", NULL, "vrpmsg-list", 1) {
+               /* No options */
+       }
+
+       /* vrpmsginfo.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;
+               }
+               vrpmsgs = libxl_device_vrpmsg_list(ctx, domid, &nb);
+               if (!vrpmsgs) {
+                       continue;
+               }
+               for (i=0; i<nb; i++) {
+                       if (!libxl_device_vrpmsg_getinfo(ctx, domid, 
&vrpmsgs[i], &vrpmsginfo)) {
+                               /*      Vdev BE   hdl  st   evch rref BE-path 
FE-path UUID */
+                               printf("%-5d %-3d %-6d %-5d %-6d %-8d %-40s 
%-40s\n",
+                                               vrpmsginfo.devid, 
vrpmsginfo.backend_id, vrpmsginfo.frontend_id,
+                                               vrpmsginfo.state, 
vrpmsginfo.evtch, vrpmsginfo.rref, vrpmsginfo.backend,
+                                               vrpmsginfo.frontend);
+                               libxl_vrpmsginfo_dispose(&vrpmsginfo);
+                       }
+                       libxl_device_vrpmsg_dispose(&vrpmsgs[i]);
+               }
+               free(vrpmsgs);
+       }
+       return 0;
+}
+
+int main_vrpmsgdetach(int argc, char **argv)
+{
+    uint32_t domid, devid;
+    int opt, rc = 0;
+    libxl_device_vrpmsg vrpmsg;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vrpmsg-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    devid = atoi(argv[optind+1]);
+
+    if (libxl_devid_to_device_vrpmsg(ctx, domid, devid, &vrpmsg)) {
+        fprintf(stderr, "Error: Device %s not connected.\n", argv[optind+1]);
+        return 1;
+    }
+
+    rc = libxl_device_vrpmsg_remove(ctx, domid, &vrpmsg, 0);
+    if (rc) {
+        fprintf(stderr, "libxl_device_vrpmsg_remove failed.\n");
+        return 1;
+    }
+
+    libxl_device_vrpmsg_dispose(&vrpmsg);
+    return rc;
+}
+
 int main_vsndattach(int argc, char **argv)
 {
     int opt;
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index daa07d7..bc90cd7 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -368,17 +368,32 @@ struct cmd_spec cmd_table[] = {
     },
     { "vdrm-attach",
       &main_vdrmattach, 1, 1,
-      "Create a new virtual rtc device",
+      "Create a new virtual drm device",
       "<Domain> <Device>",
     },
     { "vdrm-list",
       &main_vdrmlist, 0, 0,
-      "List virtual rtc devices for a domain",
+      "List virtual drm devices for a domain",
       "<Domain(s)>",
     },
     { "vdrm-detach",
       &main_vdrmdetach, 0, 1,
-      "Destroy a domain's virtual rtc device",
+      "Destroy a domain's virtual drm device",
+      "<Domain> <DevId>",
+    },
+    { "vrpmsg-attach",
+      &main_vrpmsgattach, 1, 1,
+      "Create a new virtual rpmsg device",
+      "<Domain> <Device>",
+    },
+    { "vrpmsg-list",
+      &main_vrpmsglist, 0, 0,
+      "List virtual rpmsg devices for a domain",
+      "<Domain(s)>",
+    },
+    { "vrpmsg-detach",
+      &main_vrpmsgdetach, 0, 1,
+      "Destroy a domain's virtual rpmsg device",
       "<Domain> <DevId>",
     },
     { "vsnd-attach",
-- 
2.8.2


_______________________________________________
Embedded-pv-devel mailing list
Embedded-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/embedded-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.