WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH V2 10/11] libxl_qmp, Introduce libxl__qmp_pci_add.

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH V2 10/11] libxl_qmp, Introduce libxl__qmp_pci_add.
From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Date: Thu, 20 Oct 2011 18:59:32 +0100
Cc: Anthony PERARD <anthony.perard@xxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Thu, 20 Oct 2011 11:16:49 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1319133573-25891-1-git-send-email-anthony.perard@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1319133573-25891-1-git-send-email-anthony.perard@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
This function insert a PCI passthrough device in qemu.

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 tools/libxl/libxl_internal.h |    4 ++
 tools/libxl/libxl_qmp.c      |  107 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 849b251..09f618f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -119,6 +119,9 @@ typedef struct {
 } libxl__device;
 
 #define XC_PCI_BDF             "0x%x, 0x%x, 0x%x, 0x%x"
+#define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn)         (((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn)         ((devfn) & 0x07)
 #define AUTO_PHP_SLOT          0x100
 #define SYSFS_PCI_DEV          "/sys/bus/pci/devices"
 #define SYSFS_PCIBACK_DRIVER   "/sys/bus/pci/drivers/pciback"
@@ -444,6 +447,7 @@ _hidden libxl__qmp_handler *libxl__qmp_initialize(libxl_ctx 
*ctx,
                                                   uint32_t domid);
 /* ask to QEMU the serial port information and store it in xenstore. */
 _hidden int libxl__qmp_query_serial(libxl__qmp_handler *qmp);
+_hidden int libxl__qmp_pci_add(libxl__gc *gc, int d, libxl_device_pci *pcidev);
 /* close and free the QMP handler */
 _hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
 /* remove the socket file, if the file has already been removed,
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 547cd53..bce7e16 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -41,6 +41,7 @@
  */
 
 #define QMP_RECEIVE_BUFFER_SIZE 4096
+#define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x"
 
 typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
                               const libxl__json_object *tree,
@@ -619,6 +620,112 @@ int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
     return rc;
 }
 
+static int pci_add_callback(libxl__qmp_handler *qmp,
+                            const libxl__json_object *response, void *opaque)
+{
+    libxl_device_pci *pcidev = opaque;
+    const libxl__json_object *bus = NULL;
+    libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+    int i, j, rc = -1;
+    char *asked_id = libxl__sprintf(&gc, PCI_PT_QDEV_ID,
+                                    pcidev->bus, pcidev->dev, pcidev->func);
+
+    for (i = 0; (bus = libxl__json_array_get(response, i)); i++) {
+        const libxl__json_object *devices = NULL;
+        const libxl__json_object *device = NULL;
+        const libxl__json_object *o = NULL;
+        const char *id = NULL;
+
+        devices = libxl__json_map_get("devices", bus, JSON_ARRAY);
+
+        for (j = 0; (device = libxl__json_array_get(devices, j)); j++) {
+             o = libxl__json_map_get("qdev_id", device, JSON_STRING);
+             id = libxl__json_object_get_string(o);
+
+             if (id && strcmp(asked_id, id) == 0) {
+                 int dev_slot, dev_func;
+
+                 o = libxl__json_map_get("slot", device, JSON_INTEGER);
+                 if (!o)
+                     goto out;
+                 dev_slot = libxl__json_object_get_integer(o);
+                 o = libxl__json_map_get("function", device, JSON_INTEGER);
+                 if (!o)
+                     goto out;
+                 dev_func = libxl__json_object_get_integer(o);
+
+                 pcidev->vdevfn = PCI_DEVFN(dev_slot, dev_func);
+
+                 rc = 0;
+                 goto out;
+             }
+        }
+    }
+
+
+out:
+    libxl__free_all(&gc);
+    return rc;
+}
+
+int libxl__qmp_pci_add(libxl__gc *gc, int domid, libxl_device_pci *pcidev)
+{
+    libxl__qmp_handler *qmp = NULL;
+    flexarray_t *parameters = NULL;
+    libxl_key_value_list args = NULL;
+    char *hostaddr = NULL;
+    int rc = 0;
+    qmp_request_handle request = {
+        .callback = pci_add_callback,
+        .opaque = pcidev,
+    };
+
+    qmp = libxl__qmp_initialize(libxl__gc_owner(gc), domid);
+    if (!qmp)
+        return -1;
+
+    hostaddr = libxl__sprintf(gc, "%04x:%02x:%02x.%01x", pcidev->domain,
+                              pcidev->bus, pcidev->dev, pcidev->func);
+    if (!hostaddr)
+        return -1;
+
+    parameters = flexarray_make(6, 1);
+    flexarray_append_pair(parameters, "driver", "xen-pci-passthrough");
+    flexarray_append_pair(parameters, "id",
+                          libxl__sprintf(gc, PCI_PT_QDEV_ID,
+                                         pcidev->bus, pcidev->dev,
+                                         pcidev->func));
+    flexarray_append_pair(parameters, "hostaddr", hostaddr);
+    if (pcidev->vdevfn) {
+        flexarray_append_pair(parameters, "addr",
+                              libxl__sprintf(gc, "%x.%x",
+                                             PCI_SLOT(pcidev->vdevfn),
+                                             PCI_FUNC(pcidev->vdevfn)));
+    }
+    args = libxl__xs_kvs_of_flexarray(gc, parameters, parameters->count);
+    if (!args)
+        return -1;
+
+    rc = qmp_synchronous_send(qmp, "device_add", &args, NULL, qmp->timeout);
+    if (rc == 0) {
+        rc = qmp_synchronous_send(qmp, "query-pci", NULL,
+                                  &request, qmp->timeout);
+        if (rc == 0) {
+            rc = request.rc;
+        }
+    }
+
+    flexarray_free(parameters);
+    libxl__qmp_close(qmp);
+    return rc;
+}
+
 int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
 {
     libxl__qmp_handler *qmp = NULL;
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>