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 V3 10/13] libxl_qmp: Introduce libxl__qmp_pci_add.

To: QEMU-devel <qemu-devel@xxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH V3 10/13] libxl_qmp: Introduce libxl__qmp_pci_add.
From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Date: Tue, 1 Nov 2011 16:07:23 +0000
Cc: Anthony PERARD <anthony.perard@xxxxxxxxxx>, Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 01 Nov 2011 09:12:30 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1320163646-24291-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: <1320163646-24291-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      |   95 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 09e0c51..718a417 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"
@@ -446,6 +449,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 6d80538..07ccf7a 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,
@@ -618,6 +619,100 @@ int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
                                 NULL, qmp->timeout);
 }
 
+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 = 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, NULL, qmp->timeout);
+    if (rc == 0) {
+        rc = qmp_synchronous_send(qmp, "query-pci", NULL,
+                                  pci_add_callback, pcidev, qmp->timeout);
+    }
+
+    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>