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-changelog

[Xen-changelog] [xen-unstable] vt-d: Detect and report failure to assign

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vt-d: Detect and report failure to assign a pass-thru PCI device.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 20 Oct 2007 05:50:18 -0700
Delivery-date: Sat, 20 Oct 2007 05:52:27 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1192782663 -3600
# Node ID bc4afcd4c612afcee7f2fa2fc0ca400c26758876
# Parent  3ad0080ad9b56a8eb19433c61f6e3c5644fb6f2e
vt-d: Detect and report failure to assign a pass-thru PCI device.
Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 tools/ioemu/hw/pass-through.c           |   93 ++++++++++++++++----------------
 tools/python/xen/lowlevel/xc/xc.c       |   88 ++++++++++++++++++++++++++++++
 tools/python/xen/xend/XendDomainInfo.py |   14 ++++
 3 files changed, 149 insertions(+), 46 deletions(-)

diff -r 3ad0080ad9b5 -r bc4afcd4c612 tools/ioemu/hw/pass-through.c
--- a/tools/ioemu/hw/pass-through.c     Fri Oct 19 09:28:21 2007 +0100
+++ b/tools/ioemu/hw/pass-through.c     Fri Oct 19 09:31:03 2007 +0100
@@ -28,40 +28,52 @@
 #include "pci/pci.h"
 
 extern FILE *logfile;
-char *token;
-
-int pci_devs(const char *direct_pci)
-{
-    int count = 0;
-    const char *c;
-
-    /* skip first "[" character */
-    c = direct_pci + 1;
-    while ((c = strchr(c, '[')) != NULL) {
-        c++;
-        count++;
-    }
-    return (count);
-}
-
-int next_token(char *direct_pci)
-{
-    if (token == NULL)
-        token = strtok(direct_pci, ",");
-    else 
-        token = strtok(NULL, ",");
+
+static int token_value(char *token)
+{
     token = strchr(token, 'x');
     token = token + 1;
+
     return ((int) strtol(token, NULL, 16));
 }
 
-void next_bdf(char *direct_pci, int *seg,
-              int *bus, int *dev, int *func)
-{
-    *seg  = next_token(direct_pci);
-    *bus  = next_token(direct_pci);
-    *dev  = next_token(direct_pci);
-    *func = next_token(direct_pci);
+static int first_bdf(char *pci_str, char **last,
+                     int *seg, int *bus, int *dev, int *func)
+{
+    char *token;
+
+    token = strtok_r(pci_str, ",", last);
+    if ( !token )
+        return 0;
+
+    *seg  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *bus  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *dev  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *func  = token_value(token);
+
+    return 1;
+}
+
+static int next_bdf(char **last, int *seg, int *bus, int *dev, int *func)
+{
+    char *token;
+
+    token = strtok_r(NULL, ",", last);
+    if ( !token )
+        return 0;
+
+    *seg  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *bus  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *dev  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *func  = token_value(token);
+
+    return 1;
 }
 
 uint8_t find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
@@ -333,7 +345,6 @@ struct pt_dev * register_real_device(PCI
     int rc, i;
     struct pt_dev *assigned_device = NULL;
     struct pci_dev *pci_dev;
-    struct pci_config_cf8 machine_bdf;
     uint8_t e_device, e_intx;
 
     PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
@@ -367,15 +378,6 @@ struct pt_dev * register_real_device(PCI
 
     /* Issue PCIe FLR */
     pdev_flr(pci_dev);
-
-    /* Tell XEN vmm to change iommu settings */
-    machine_bdf.reg = 0;
-    machine_bdf.bus = r_bus;
-    machine_bdf.dev = r_dev;
-    machine_bdf.func = r_func;
-    rc = xc_assign_device(xc_handle, domid, machine_bdf.value);
-    if ( rc < 0 )
-        PT_LOG("Error: xc_domain_assign_device error %d\n", rc);
 
     /* Initialize virtualized PCI configuration (Extended 256 Bytes) */
     for ( i = 0; i < PCI_CONFIG_SIZE; i++ )
@@ -417,11 +419,11 @@ struct pt_dev * register_real_device(PCI
 
 int pt_init(PCIBus *e_bus, char *direct_pci)
 {
-    int i;
     int seg, b, d, f;
     struct pt_dev *pt_dev;
     struct pci_access *pci_access;
-    int dev_count = pci_devs(direct_pci);
+    int get_bdf;
+    char *last = NULL;
 
     /* Initialize libpci */
     pci_access = pci_alloc();
@@ -434,11 +436,10 @@ int pt_init(PCIBus *e_bus, char *direct_
     pci_scan_bus(pci_access);
 
     /* Assign given devices to guest */
-    for ( i = 0; i < dev_count; i++ )
-    {
-        /* Get next device bdf (bus, device, function) */
-        next_bdf(direct_pci, &seg, &b, &d, &f);
-
+    for ( get_bdf = first_bdf(direct_pci, &last, &seg, &b, &d, &f);
+          get_bdf;
+          get_bdf = next_bdf(&last, &seg, &b, &d, &f) )
+    {
         /* Register real device with the emulated bus */
         pt_dev = register_real_device(e_bus, "DIRECT PCI", PT_VIRT_DEVFN_AUTO,
             b, d, f, PT_MACHINE_IRQ_AUTO, pci_access);
diff -r 3ad0080ad9b5 -r bc4afcd4c612 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Fri Oct 19 09:28:21 2007 +0100
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri Oct 19 09:31:03 2007 +0100
@@ -529,6 +529,86 @@ static PyObject *pyxc_set_hvm_param(XcOb
     return zero;
 }
 
+static int token_value(char *token)
+{
+    token = strchr(token, 'x');
+    token = token + 1;
+
+    return ((int) strtol(token, NULL, 16));
+}
+
+static int first_bdf(char *pci_str, char **last,
+                     int *seg, int *bus, int *dev, int *func)
+{
+    char *token;
+
+    token = strtok_r(pci_str, ",", last);
+    if ( !token )
+        return 0;
+
+    *seg  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *bus  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *dev  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *func  = token_value(token);
+
+    return 1;
+}
+
+static int next_bdf(char **last, int *seg, int *bus, int *dev, int *func)
+{
+    char *token;
+
+    token = strtok_r(NULL, ",", last);
+    if ( !token )
+        return 0;
+
+    *seg  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *bus  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *dev  = token_value(token);
+    token = strtok_r(NULL, ",", last);
+    *func  = token_value(token);
+
+    return 1;
+}
+
+static PyObject *pyxc_assign_device(XcObject *self,
+                                    PyObject *args,
+                                    PyObject *kwds)
+{
+    uint32_t dom;
+    char *pci_str;
+    uint32_t bdf = 0;
+    int seg, bus, dev, func;
+    int get_bdf;
+    char *last = NULL;
+
+    static char *kwd_list[] = { "domid", "pci", NULL };
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|s", kwd_list,
+                                      &dom, &pci_str) )
+        return NULL;
+
+    for ( get_bdf = first_bdf(pci_str, &last, &seg, &bus, &dev, &func);
+          get_bdf;
+          get_bdf = next_bdf(&last, &seg, &bus, &dev, &func) )
+    {
+        bdf |= (bus & 0xff) << 16;
+        bdf |= (dev & 0x1f) << 11;
+        bdf |= (func & 0x7) << 8;
+
+        if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
+            break;
+
+        bdf = 0;
+    }
+
+    return Py_BuildValue("i", bdf);
+}
+
 #ifdef __ia64__
 static PyObject *pyxc_nvram_init(XcObject *self,
                                  PyObject *args)
@@ -1349,6 +1429,14 @@ static PyMethodDef pyxc_methods[] = {
       " value   [long]:     Value of param.\n"
       "Returns: [int] 0 on success.\n" },
 
+     { "assign_device",
+       (PyCFunction)pyxc_assign_device,
+       METH_VARARGS | METH_KEYWORDS, "\n"
+       "assign device with VT-d.\n"
+       " dom     [int]:      Identifier of domain to build into.\n"
+       " pci_str [str]:      PCI devices.\n"
+       "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" 
},
+  
     { "sched_id_get",
       (PyCFunction)pyxc_sched_id_get,
       METH_NOARGS, "\n"
diff -r 3ad0080ad9b5 -r bc4afcd4c612 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Oct 19 09:28:21 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Oct 19 09:31:03 2007 +0100
@@ -1586,6 +1586,20 @@ class XendDomainInfo:
         # Set maximum number of vcpus in domain
         xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
 
+        # Assign devices with VT-d
+        pci_str = str(self.info["platform"].get("pci"))
+        if hvm and pci_str:
+            bdf = xc.assign_device(self.domid, pci_str)
+            if bdf != 0:
+                bus = (bdf >> 16) & 0xff
+                devfn = (bdf >> 8) & 0xff
+                dev = (devfn >> 3) & 0x1f
+                func = devfn & 0x7
+                raise VmError("Fail to assign device(%x:%x.%x): maybe VT-d is "
+                              "not enabled, or the device is not exist, or it "
+                              "has already been assigned to other domain"
+                              % (bus, dev, func))
+
         # register the domain in the list 
         from xen.xend import XendDomain
         XendDomain.instance().add_domain(self)

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] vt-d: Detect and report failure to assign a pass-thru PCI device., Xen patchbot-unstable <=