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 4/6] libxl: implementation of PV event device interface
Date: Thu, 19 May 2016 17:37:33 +0300	[thread overview]
Message-ID: <1463668655-16778-5-git-send-email-iurii.mykhalskyi@globallogic.com> (raw)
In-Reply-To: <1463668655-16778-1-git-send-email-iurii.mykhalskyi@globallogic.com>

From: Pavlo Suikov <pavlo.suikov@globallogic.com>

Touchscreen events device configuration support. Can be further
extended to support any event device whatsoever.

Signed-off-by: Pavlo Suikov <pavlo.suikov@globallogic.com>
Signed-off-by: Iurii Konovalenko <iurii.konovalenko@globallogic.com>
Signed-off-by: Iurii Mykhalskyi <iurii.mykhalskyi@globallogic.com>
---
 tools/libxl/libxl.c                  | 289 ++++++++++++++++++++++++++++++++++-
 tools/libxl/libxl.h                  |  17 +++
 tools/libxl/libxl_create.c           |  39 ++++-
 tools/libxl/libxl_device.c           |   2 +
 tools/libxl/libxl_internal.c         |   4 +
 tools/libxl/libxl_internal.h         |  20 ++-
 tools/libxl/libxl_types.idl          |  21 +++
 tools/libxl/libxl_types_internal.idl |   1 +
 tools/libxl/libxl_utils.h            |   4 +
 tools/libxl/xl.h                     |   3 +
 tools/libxl/xl_cmdimpl.c             | 170 ++++++++++++++++++++-
 tools/libxl/xl_cmdtable.c            |  15 ++
 12 files changed, 580 insertions(+), 5 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 1426bf6..b64815e 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -5003,6 +5003,282 @@ out:
 
 /******************************************************************************/
 
+int libxl__device_vevent_setdefault(libxl__gc *gc, libxl_device_vevent *vevent)
+{
+    int rc;
+    rc = libxl__resolve_domid(gc, vevent->backend_domname, &vevent->backend_domid);
+    return rc;
+}
+
+static int libxl__device_from_vevent(libxl__gc *gc, uint32_t domid,
+                                     libxl_device_vevent *vevent,
+                                     libxl__device *device)
+{
+    device->backend_devid = vevent->devid;
+    device->backend_domid = vevent->backend_domid;
+    device->backend_kind = LIBXL__DEVICE_KIND_VEVENT;
+    device->devid = vevent->devid;
+    device->domid = domid;
+    device->kind = LIBXL__DEVICE_KIND_VEVENT;
+
+    return 0;
+}
+
+static int libxl__device_vevent_from_xs_be(libxl__gc *gc,
+                                           const char *be_path,
+                                           libxl_device_vevent *vevent)
+{
+    const char *tmp;
+    int rc;
+
+    libxl_device_vevent_init(vevent);
+
+    tmp = READ_BACKEND(gc, "device-id");
+    if (tmp)
+        vevent->devid = atoi(tmp);
+    else
+        vevent->devid = 0;
+
+    rc = 0;
+out:
+    return rc;
+}
+
+int libxl_devid_to_device_vevent(libxl_ctx *ctx, uint32_t domid,
+                                 int devid, libxl_device_vevent *vevent)
+{
+    GC_INIT(ctx);
+    char *dompath, *path;
+    int rc = ERROR_FAIL;
+
+    libxl_device_vevent_init(vevent);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    if (!dompath)
+        goto out;
+
+    path = libxl__xs_read(gc, XBT_NULL,
+                          libxl__sprintf(gc, "%s/device/vevent/%d/backend",
+                                         dompath, devid));
+    if (!path)
+        goto out;
+
+    rc = libxl__device_vevent_from_xs_be(gc, path, vevent);
+    if (rc) goto out;
+
+    rc = 0;
+out:
+    GC_FREE;
+    return rc;
+}
+
+void libxl__device_vevent_add(libxl__egc *egc, uint32_t domid,
+                              libxl_device_vevent *vevent,
+                              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_vevent vevent_saved;
+    libxl__domain_userdata_lock *lock = NULL;
+
+    libxl_domain_config_init(&d_config);
+    libxl_device_vevent_init(&vevent_saved);
+    libxl_device_vevent_copy(CTX, &vevent_saved, vevent);
+
+    rc = libxl__device_vevent_setdefault(gc, vevent);
+    if (rc) goto out;
+
+    front = flexarray_make(gc, 16, 1);
+    back = flexarray_make(gc, 16, 1);
+    if (vevent->devid == -1) {
+        if ((vevent->devid = libxl__device_nextid(gc, domid, "vevent")) < 0) {
+            rc = ERROR_FAIL;
+            goto out;
+        }
+    }
+
+    libxl__update_config_vevent(gc, &vevent_saved, vevent);
+
+    GCNEW(device);
+    rc = libxl__device_from_vevent(gc, domid, vevent, device);
+    if ( rc != 0 ) goto out;
+
+    flexarray_append(back, "feature-abs-pointer");
+    flexarray_append(back, libxl__sprintf(gc, "%d", vevent->feature_abs_pointer));
+    flexarray_append(back, "abs-width");
+    flexarray_append(back, libxl__sprintf(gc, "%d", vevent->abs_width));
+    flexarray_append(back, "abs-height");
+    flexarray_append(back, libxl__sprintf(gc, "%d", vevent->abs_height));
+    flexarray_append(back, "frontend-id");
+    flexarray_append(back, libxl__sprintf(gc, "%d", domid));
+    flexarray_append(back, "online");
+    flexarray_append(back, "1");
+    flexarray_append(back, "state");
+    flexarray_append(back, libxl__sprintf(gc, "%d", 1));
+
+    flexarray_append(front, "device-id");
+    flexarray_append(front, GCSPRINTF("%d", vevent->devid));
+    flexarray_append(front, "backend-id");
+    flexarray_append(front, libxl__sprintf(gc, "%d", vevent->backend_domid));
+    flexarray_append(front, "state");
+    flexarray_append(front, libxl__sprintf(gc, "%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(vevent, vevents, domid, &vevent_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_vevent_dispose(&vevent_saved);
+    libxl_domain_config_dispose(&d_config);
+    aodev->rc = rc;
+    if(rc) aodev->callback(egc, aodev);
+    return;
+}
+
+libxl_device_vevent *libxl_device_vevent_list(libxl_ctx *ctx, uint32_t domid, int *num)
+{
+    GC_INIT(ctx);
+
+    libxl_device_vevent* vevents = NULL;
+    char* fe_path = NULL;
+    char** dir = NULL;
+    unsigned int ndirs = 0;
+
+    *num = 0;
+
+    fe_path = libxl__sprintf(gc, "%s/device/vevent", libxl__xs_get_dompath(gc, domid));
+    dir = libxl__xs_directory(gc, XBT_NULL, fe_path, &ndirs);
+    if (dir && ndirs) {
+       vevents = malloc(sizeof(*vevents) * ndirs);
+       libxl_device_vevent* vevent;
+       libxl_device_vevent* end = vevents + ndirs;
+       for(vevent = vevents; vevent < end; ++vevent, ++dir) {
+          char* tmp;
+
+          libxl_device_vevent_init(vevent);
+
+          vevent->devid = atoi(*dir);
+
+          tmp = libxl__xs_read(gc, XBT_NULL,
+                GCSPRINTF("%s/%s/backend-id",
+                   fe_path, *dir));
+          vevent->backend_domid = atoi(tmp);
+       }
+    }
+    *num = ndirs;
+
+    GC_FREE;
+    return vevents;
+}
+
+int libxl_device_vevent_getinfo(libxl_ctx *ctx, uint32_t domid, libxl_device_vevent *vevent, libxl_veventinfo *veventinfo)
+{
+    GC_INIT(ctx);
+    char *dompath, *veventpath;
+    char *val;
+    int rc = 0;
+
+    libxl_veventinfo_init(veventinfo);
+    dompath = libxl__xs_get_dompath(gc, domid);
+    veventinfo->devid = vevent->devid;
+
+    veventpath = GCSPRINTF("%s/device/vevent/%d", dompath, veventinfo->devid);
+    veventinfo->backend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/backend", veventpath), NULL);
+
+    if (!veventinfo->backend) {
+        goto err;
+    }
+
+    if(!libxl__xs_read(gc, XBT_NULL, veventinfo->backend)) {
+       goto err;
+    }
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/backend-id", veventpath));
+    veventinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/state", veventpath));
+    veventinfo->state = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/event-channel", veventpath));
+    veventinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/ring-ref", veventpath));
+    veventinfo->rref = val ? strtoul(val, NULL, 10) : -1;
+
+    veventinfo->frontend = xs_read(ctx->xsh, XBT_NULL,
+          GCSPRINTF("%s/frontend", veventinfo->backend), NULL);
+
+    val = libxl__xs_read(gc, XBT_NULL,
+          GCSPRINTF("%s/frontend-id", veventinfo->backend));
+    veventinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
+
+    goto exit;
+err:
+    rc = ERROR_FAIL;
+exit:
+    GC_FREE;
+    return rc;
+}
+
+/******************************************************************************/
+
 /* Macro for defining device remove/destroy functions in a compact way */
 /* The following functions are defined:
  * libxl_device_disk_remove
@@ -5021,6 +5297,8 @@ out:
  * libxl_device_vsnd_destroy
  * libxl_device_vtty_remove
  * libxl_device_vtty_destroy
+ * libxl_device_vevent_remove
+ * libxl_device_vevent_destroy
  */
 #define DEFINE_DEVICE_REMOVE(type, removedestroy, f)                    \
     int libxl_device_##type##_##removedestroy(libxl_ctx *ctx,           \
@@ -5064,7 +5342,6 @@ DEFINE_DEVICE_REMOVE(vkb, remove, 0)
 DEFINE_DEVICE_REMOVE(vkb, destroy, 1)
 
 /* vfb */
-
 DEFINE_DEVICE_REMOVE(vfb, remove, 0)
 DEFINE_DEVICE_REMOVE(vfb, destroy, 1)
 
@@ -5084,6 +5361,10 @@ DEFINE_DEVICE_REMOVE(vsnd, destroy, 1)
 DEFINE_DEVICE_REMOVE(vtty, remove, 0)
 DEFINE_DEVICE_REMOVE(vtty, destroy, 1)
 
+/* vevent */
+DEFINE_DEVICE_REMOVE(vevent, remove, 0)
+DEFINE_DEVICE_REMOVE(vevent, 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. */
@@ -5100,6 +5381,7 @@ DEFINE_DEVICE_REMOVE(vtty, destroy, 1)
  * libxl_device_vrtc_add
  * libxl_device_vsnd_add
  * libxl_device_vtty_add
+ * libxl_device_vevent_add
  */
 
 #define DEFINE_DEVICE_ADD(type)                                         \
@@ -5140,6 +5422,9 @@ DEFINE_DEVICE_ADD(vsnd)
 /* vtty */
 DEFINE_DEVICE_ADD(vtty)
 
+/* vevent */
+DEFINE_DEVICE_ADD(vevent)
+
 #undef DEFINE_DEVICE_ADD
 
 /******************************************************************************/
@@ -7663,6 +7948,8 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, uint32_t domid,
 
     MERGE(vtty, vttys, COMPARE_DEVID, {});
 
+    MERGE(vevent, vevents, COMPARE_DEVID, {});
+
     /* Take care of removable device. We maintain invariant in the
      * insert / remove operation so that:
      * 1. if xenstore is "empty" while JSON is not, the result
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 47829dd..7799374 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1511,6 +1511,23 @@ int libxl_device_vfb_destroy(libxl_ctx *ctx, uint32_t domid,
                              const libxl_asyncop_how *ao_how)
                              LIBXL_EXTERNAL_CALLERS_ONLY;
 
+/* Event device (e.g. touchscreen) */
+int libxl_device_vevent_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vevent *vevent,
+                            const libxl_asyncop_how *ao_how)
+                            LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vevent_remove(libxl_ctx *ctx, uint32_t domid,
+                               libxl_device_vevent *vevent,
+                               const libxl_asyncop_how *ao_how)
+                               LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vevent_destroy(libxl_ctx *ctx, uint32_t domid,
+                                libxl_device_vevent *vevent,
+                                const libxl_asyncop_how *ao_how)
+                                LIBXL_EXTERNAL_CALLERS_ONLY;
+
+libxl_device_vevent *libxl_device_vevent_list(libxl_ctx *ctx, uint32_t domid, int *num);
+int libxl_device_vevent_getinfo(libxl_ctx *ctx, uint32_t domid,
+                              libxl_device_vevent *vevent, libxl_veventinfo *veventinfo);
+
 /* PCI Passthrough */
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid,
                          libxl_device_pci *pcidev,
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 38d9b12..1752499 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -740,6 +740,8 @@ static void domcreate_attach_vttys(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
 static void domcreate_attach_vsnds(libxl__egc *egc, libxl__multidev *multidev,
                                    int ret);
+static void domcreate_attach_vevents(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,
@@ -1497,12 +1499,45 @@ static void domcreate_attach_vsnds(libxl__egc *egc,
    if (d_config->num_vsnds > 0) {
        /* Attach vsnds */
        libxl__multidev_begin(ao, &dcs->multidev);
-       dcs->multidev.callback = domcreate_attach_pci;
+       dcs->multidev.callback = domcreate_attach_vevents;
        libxl__add_vsnds(egc, ao, domid, d_config, &dcs->multidev);
        libxl__multidev_prepared(egc, &dcs->multidev, 0);
        return;
    }
 
+    domcreate_attach_vevents(egc, multidev, 0);
+   return;
+
+error_out:
+   assert(ret);
+   domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_attach_vevents(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 vsnd devices");
+       goto error_out;
+   }
+
+    /* Plug vevent devices */
+   if (d_config->num_vevents > 0) {
+       /* Attach vevents */
+       libxl__multidev_begin(ao, &dcs->multidev);
+       dcs->multidev.callback = domcreate_attach_pci;
+       libxl__add_vevents(egc, ao, domid, d_config, &dcs->multidev);
+       libxl__multidev_prepared(egc, &dcs->multidev, 0);
+       return;
+   }
+
    domcreate_attach_pci(egc, multidev, 0);
    return;
 
@@ -1524,7 +1559,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 vsnd devices");
+        LOG(ERROR, "unable to add vevent devices");
         goto error_out;
     }
 
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index df50fdb..65569e1 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -547,6 +547,7 @@ void libxl__multidev_prepared(libxl__egc *egc,
  * libxl__add_vrtcs
  * libxl__add_vsnds
  * libxl__add_vttys
+ * libxl__add_vevents
  */
 
 #define DEFINE_DEVICES_ADD(type)                                        \
@@ -569,6 +570,7 @@ DEFINE_DEVICES_ADD(vtpm)
 DEFINE_DEVICES_ADD(vrtc)
 DEFINE_DEVICES_ADD(vsnd)
 DEFINE_DEVICES_ADD(vtty)
+DEFINE_DEVICES_ADD(vevent)
 
 #undef DEFINE_DEVICES_ADD
 
diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index f75840d..32ce8bd 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -551,6 +551,10 @@ void libxl__update_domain_configuration(libxl__gc *gc,
     for (i = 0; i < src->num_vsnds; i++)
         libxl__update_config_vsnd(gc, &dst->vsnds[i], &src->vsnds[i]);
 
+    /* update vevent information */
+    for (i = 0; i < src->num_vevents; i++)
+        libxl__update_config_vevent(gc, &dst->vevents[i], &src->vevents[i]);
+
     /* update guest UUID */
     libxl_uuid_copy(CTX, &dst->c_info.uuid, &src->c_info.uuid);
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 1bacc73..330d56f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -479,7 +479,8 @@ typedef struct {
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VKBD || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VRTC || \
     (dev)->backend_kind == LIBXL__DEVICE_KIND_VSND || \
-    (dev)->backend_kind == LIBXL__DEVICE_KIND_VTTY)
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VTTY || \
+    (dev)->backend_kind == LIBXL__DEVICE_KIND_VEVENT)
 
 #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_vrtc_setdefault(libxl__gc *gc, libxl_device_vrtc *vrtc
 _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);
+_hidden int libxl__device_vevent_setdefault(libxl__gc *gc, libxl_device_vevent *vevent);
 _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);
 _hidden void libxl__rdm_setdefault(libxl__gc *gc,
@@ -2594,6 +2596,11 @@ _hidden int libxl__device_vkb_add(libxl__gc *gc, uint32_t domid,
 _hidden int libxl__device_vfb_add(libxl__gc *gc, uint32_t domid,
                                   libxl_device_vfb *vfb);
 
+/* AO operation to connect a vevent device */
+_hidden void libxl__device_vevent_add(libxl__egc *egc, uint32_t domid,
+                                      libxl_device_vevent *vevent,
+                                      libxl__ao_device *aodev);
+
 /* Waits for the passed device to reach state XenbusStateInitWait.
  * This is not really useful by itself, but is important when executing
  * hotplug scripts, since we need to be sure the device is in the correct
@@ -3313,6 +3320,10 @@ _hidden void libxl__add_vttys(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
 _hidden void libxl__add_vsnds(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                              libxl_domain_config *d_config,
                              libxl__multidev *multidev);
+
+_hidden void libxl__add_vevents(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. */
@@ -3983,6 +3994,13 @@ static inline void libxl__update_config_vsnd(libxl__gc *gc,
     dst->devid = src->devid;
 }
 
+static inline void libxl__update_config_vevent(libxl__gc *gc,
+                                               libxl_device_vevent *dst,
+                                               libxl_device_vevent *src)
+{
+    dst->devid = src->devid;
+}
+
 /* Macros used to compare device identifier. Returns true if the two
  * devices have same identifier. */
 #define COMPARE_DEVID(a, b) ((a)->devid == (b)->devid)
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 4477297..23fcf50 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -538,6 +538,15 @@ libxl_device_vfb = Struct("device_vfb", [
     ("keymap",        string),
     ])
 
+libxl_device_vevent = Struct("device_vevent", [
+    ("backend_domid", libxl_domid),
+    ("backend_domname", string),
+    ("devid", libxl_devid),
+    ("feature_abs_pointer", integer),
+    ("abs_width", integer),
+    ("abs_height", integer),
+    ])
+
 libxl_device_vkb = Struct("device_vkb", [
     ("backend_domid", libxl_domid),
     ("backend_domname", string),
@@ -663,6 +672,7 @@ libxl_domain_config = Struct("domain_config", [
     ("rdms", Array(libxl_device_rdm, "num_rdms")),
     ("dtdevs", Array(libxl_device_dtdev, "num_dtdevs")),
     ("vfbs", Array(libxl_device_vfb, "num_vfbs")),
+    ("vevents", Array(libxl_device_vevent, "num_vevents")),
     ("vkbs", Array(libxl_device_vkb, "num_vkbs")),
     ("vtpms", Array(libxl_device_vtpm, "num_vtpms")),
     ("vrtcs", Array(libxl_device_vrtc, "num_vrtcs")),
@@ -746,6 +756,17 @@ libxl_vttyinfo = Struct("vttyinfo", [
     ("rref", integer),
     ], dir=DIR_OUT)
 
+libxl_veventinfo = Struct("veventinfo", [
+    ("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 182aeee..a86325c 100644
--- a/tools/libxl/libxl_types_internal.idl
+++ b/tools/libxl/libxl_types_internal.idl
@@ -25,6 +25,7 @@ libxl__device_kind = Enumeration("device_kind", [
     (9, "VRTC"),
     (10, "VSND"),
     (11, "VTTY"),
+    (12, "VEVENT"),
     ])
 
 libxl__console_backend = Enumeration("console_backend", [
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 3d47534..24a8205 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -86,6 +86,10 @@ int libxl_devid_to_device_vsnd(libxl_ctx *ctx, uint32_t domid,
 int libxl_devid_to_device_vtty(libxl_ctx *ctx, uint32_t domid,
                                int devid, libxl_device_vtty *vtty);
 
+int libxl_devid_to_device_vevent(libxl_ctx *ctx, uint32_t domid,
+                                 int devid, libxl_device_vevent *vevent);
+
+
 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 cc990c1..905276d 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -91,6 +91,9 @@ int main_vsnddetach(int argc, char **argv);
 int main_vttyattach(int argc, char **argv);
 int main_vttylist(int argc, char **argv);
 int main_vttydetach(int argc, char **argv);
+int main_veventattach(int argc, char **argv);
+int main_veventlist(int argc, char **argv);
+int main_veventdetach(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 5ac9b81..f8f9edf 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1271,7 +1271,8 @@ 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, *vrtcs, *vttys, *vsnds;
+    XLU_ConfigList *cpus, *cpuids, *vbds, *nics, *pcis;
+    XLU_ConfigList *cvfbs, *vevents, *vtpms, *vrtcs, *vttys, *vsnds;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian;
     int pci_power_mgmt = 0;
@@ -2195,6 +2196,61 @@ skip_vfb:
         }
     }
 
+    if (!xlu_cfg_get_list(config, "vevent", &vevents, 0, 0)) {
+        d_config->num_vevents = 0;
+        d_config->vevents = NULL;
+        while ((buf = xlu_cfg_get_listitem(vevents, d_config->num_vevents)) != NULL) {
+            libxl_device_vevent *vevent;
+            libxl_string_list pairs;
+            char *path = NULL;
+            int len;
+
+            vevent = ARRAY_EXTEND_INIT(d_config->vevents, d_config->num_vevents,
+                                       libxl_device_vevent_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 vevent configuration: %s",
+                            pairs[i]);
+                    exit(1);
+                }
+                trim(isspace, key_untrimmed, &key);
+                trim(isspace, value_untrimmed, &value);
+
+                if (!strcmp(key, "backendid")) {
+                    vevent->backend_domid = atoi(value);
+                } else if (!strcmp(key, "backend")) {
+                    replace_string(&vevent->backend_domname, value);
+                } else if (!strcmp(key, "devid")) {
+                    vevent->devid = atoi(value);
+                } else if (!strcmp(key, "featureabsptr")) {
+                    vevent->feature_abs_pointer = atoi(value);
+                } else if (!strcmp(key, "abswidth")) {
+                    vevent->abs_width = atoi(value);
+                } else if (!strcmp(key, "absheight")) {
+                    vevent->abs_height = atoi(value);
+                } else {
+                    fprintf(stderr, "unknown vevent parameter '%s',"
+                                  " ignoring\n", key);
+                }
+                free(key);
+                free(key_untrimmed);
+                free(value);
+                free(value_untrimmed);
+            }
+            libxl_string_list_dispose(&pairs);
+            free(path);
+        }
+    }
+
     if (!xlu_cfg_get_long (config, "pci_msitranslate", &l, 0))
         pci_msitranslate = l;
 
@@ -7279,6 +7335,118 @@ int main_vttydetach(int argc, char **argv)
     return rc;
 }
 
+int main_veventattach(int argc, char **argv)
+{
+    int opt;
+    uint32_t fe_domid;
+    libxl_device_vevent vevent;
+    char *oparg;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vevent-attach", 1) {
+        /* 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++;
+
+    for (argv += optind+1, argc -= optind+1; argc > 0; ++argv, --argc) {
+        if (MATCH_OPTION("backend", *argv, oparg)) {
+            replace_string(&vevent.backend_domname, oparg);
+        } else if (MATCH_OPTION("devid", *argv, oparg)) {
+            vevent.devid = atoi(oparg);
+        } else {
+            fprintf(stderr, "unrecognized argument `%s'\n", *argv);
+            return 1;
+        }
+    }
+
+    if (dryrun_only) {
+        char *json = libxl_device_vevent_to_json(ctx, &vevent);
+        printf("vevent: %s\n", json);
+        free(json);
+        if (ferror(stdout) || fflush(stdout)) { perror("stdout"); exit(-1); }
+        return 0;
+    }
+
+    if (libxl_device_vevent_add(ctx, fe_domid, &vevent, 0)) {
+        fprintf(stderr, "libxl_device_vevent_add failed.\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+int main_veventlist(int argc, char **argv)
+{
+    int opt;
+    int i, nb;
+    libxl_device_vevent *vevents;
+    libxl_veventinfo veventinfo;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vevent-list", 1) {
+        /* No options */
+    }
+
+    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;
+        }
+        vevents = libxl_device_vevent_list(ctx, domid, &nb);
+        if (!vevents) {
+            continue;
+        }
+        for (i=0; i<nb; i++) {
+            if (!libxl_device_vevent_getinfo(ctx, domid, &vevents[i], &veventinfo)) {
+                /*      Vdev BE   hdl  st   evch rref BE-path FE-path */
+                printf("%-5d %-3d %-6d %-5d %-6d %-8d %-40s %-40s\n",
+                       veventinfo.devid, veventinfo.backend_id, veventinfo.frontend_id,
+                       veventinfo.state, veventinfo.evtch, veventinfo.rref,
+                       veventinfo.backend, veventinfo.frontend);
+                libxl_veventinfo_dispose(&veventinfo);
+            }
+            libxl_device_vevent_dispose(&vevents[i]);
+        }
+        free(vevents);
+    }
+
+    return 0;
+}
+
+int main_veventdetach(int argc, char **argv)
+{
+    uint32_t domid, devid;
+    int opt, rc = 0;
+    libxl_device_vevent vevent;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vevent-detach", 2) {
+        /* No options */
+    }
+
+    domid = find_domain(argv[optind]);
+    devid = atoi(argv[optind+1]);
+
+    if (libxl_devid_to_device_vevent(ctx, domid, devid, &vevent)) {
+        fprintf(stderr, "Error: Device %s not connected.\n", argv[optind+1]);
+        return 1;
+    }
+
+    rc = libxl_device_vevent_remove(ctx, domid, &vevent, 0);
+    if (rc) {
+        fprintf(stderr, "libxl_device_vevent_remove failed.\n");
+        return 1;
+    }
+    libxl_device_vevent_dispose(&vevent);
+    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 7e3a8eb..bb410ca 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -401,6 +401,21 @@ struct cmd_spec cmd_table[] = {
       "Destroy a domain's virtual rtc device",
       "<Domain> <DevId>",
     },
+    { "vevent-attach",
+      &main_veventattach, 1, 1,
+      "Create a new virtual event device",
+      "<Domain> [backend=<BackDomain>] [devid=<DeviceId>]",
+    },
+    { "vevent-list",
+      &main_veventlist, 0, 0,
+      "List virtual event devices for a domain",
+      "<Domain(s)>",
+    },
+    { "vevent-detach",
+      &main_veventdetach, 0, 1,
+      "Destroy a domain's virtual event 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

  parent 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 ` [PATCH RFC 1/6] libxl: implementation of PV rtc device interface Iurii Mykhalskyi
2016-05-23 16:45   ` 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 ` Iurii Mykhalskyi [this message]
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-5-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.